Update Erlang.mk
(cherry picked from commit b34a7227b3
)
# Conflicts:
# erlang.mk
This commit is contained in:
parent
5fa5d22435
commit
f6e170aa23
|
@ -17,7 +17,11 @@
|
|||
ERLANG_MK_FILENAME := $(realpath $(lastword $(MAKEFILE_LIST)))
|
||||
export ERLANG_MK_FILENAME
|
||||
|
||||
<<<<<<< HEAD
|
||||
ERLANG_MK_VERSION = 2022.05.31-72-gb8a27ab-dirty
|
||||
=======
|
||||
ERLANG_MK_VERSION = e13b4c7
|
||||
>>>>>>> b34a7227b (Update Erlang.mk)
|
||||
ERLANG_MK_WITHOUT =
|
||||
|
||||
# Make 3.81 and 3.82 are deprecated.
|
||||
|
@ -3774,6 +3778,7 @@ endif
|
|||
|
||||
# Deps related targets.
|
||||
|
||||
<<<<<<< HEAD
|
||||
# @todo rename GNUmakefile and makefile into Makefile first, if they exist
|
||||
# While Makefile file could be GNUmakefile or makefile,
|
||||
# in practice only Makefile is needed so far.
|
||||
|
@ -3783,6 +3788,26 @@ define dep_autopatch
|
|||
$(call erlang,$(call dep_autopatch_appsrc.erl,$(1))); \
|
||||
$(call dep_autopatch_erlang_mk,$(1)); \
|
||||
elif [ -f $(DEPS_DIR)/$(1)/Makefile ]; then \
|
||||
=======
|
||||
autopatch_verbose_0 = @echo " PATCH " $(subst autopatch-,,$@) "(method: $(AUTOPATCH_METHOD))";
|
||||
autopatch_verbose_2 = set -x;
|
||||
autopatch_verbose = $(autopatch_verbose_$(V))
|
||||
|
||||
define dep_autopatch_detect
|
||||
if [ -f $(DEPS_DIR)/$1/erlang.mk ]; then \
|
||||
echo erlang.mk; \
|
||||
elif [ -f $(DEPS_DIR)/$1/mix.exs -a -d $(DEPS_DIR)/$1/lib ]; then \
|
||||
if [ "$(ELIXIR)" != "disable" ]; then \
|
||||
echo mix; \
|
||||
elif [ -f $(DEPS_DIR)/$1/rebar.lock -o -f $(DEPS_DIR)/$1/rebar.config ]; then \
|
||||
echo rebar3; \
|
||||
elif [ -f $(DEPS_DIR)/$1/Makefile ]; then \
|
||||
echo noop; \
|
||||
else \
|
||||
exit 99; \
|
||||
fi \
|
||||
elif [ -f $(DEPS_DIR)/$1/Makefile ]; then \
|
||||
>>>>>>> b34a7227b (Update Erlang.mk)
|
||||
if [ -f $(DEPS_DIR)/$1/rebar.lock ]; then \
|
||||
$(call dep_autopatch2,$1); \
|
||||
elif [ 0 != `grep -c "include ../\w*\.mk" $(DEPS_DIR)/$(1)/Makefile` ]; then \
|
||||
|
@ -4839,6 +4864,216 @@ clean-app:
|
|||
|
||||
endif
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
# Copyright (c) 2024, Tyler Hughes <tyler@tylerhughes.dev>
|
||||
# Copyright (c) 2024, Loïc Hoguin <essen@ninenines.eu>
|
||||
# This file is part of erlang.mk and subject to the terms of the ISC License.
|
||||
|
||||
# Elixir is automatically enabled in all cases except when
|
||||
# an Erlang project uses an Elixir dependency. In that case
|
||||
# $(ELIXIR) must be set explicitly.
|
||||
ELIXIR ?= $(if $(filter elixir,$(BUILD_DEPS) $(DEPS)),dep,$(if $(EX_FILES),system,disable))
|
||||
export ELIXIR
|
||||
|
||||
ifeq ($(ELIXIR),system)
|
||||
# We expect 'elixir' to be on the path.
|
||||
ELIXIR_BIN ?= $(shell readlink -f `which elixir`)
|
||||
ELIXIR_LIBS ?= $(abspath $(dir $(ELIXIR_BIN))/../lib)
|
||||
# Fallback in case 'elixir' is a shim.
|
||||
ifeq ($(wildcard $(ELIXIR_LIBS)/elixir/),)
|
||||
ELIXIR_LIBS = $(abspath $(shell elixir -e 'IO.puts(:code.lib_dir(:elixir))')/../)
|
||||
endif
|
||||
ELIXIR_LIBS := $(ELIXIR_LIBS)
|
||||
export ELIXIR_LIBS
|
||||
ERL_LIBS := $(ERL_LIBS):$(ELIXIR_LIBS)
|
||||
else
|
||||
ifeq ($(ELIXIR),dep)
|
||||
ERL_LIBS := $(ERL_LIBS):$(DEPS_DIR)/elixir/lib/
|
||||
endif
|
||||
endif
|
||||
|
||||
elixirc_verbose_0 = @echo " EXC $(words $(EX_FILES)) files";
|
||||
elixirc_verbose_2 = set -x;
|
||||
elixirc_verbose = $(elixirc_verbose_$(V))
|
||||
|
||||
# Unfortunately this currently requires Elixir.
|
||||
# https://github.com/jelly-beam/verl is a good choice
|
||||
# for an Erlang implementation, but we already have to
|
||||
# pull hex_core and Rebar3 so adding yet another pull
|
||||
# is annoying, especially one that would be necessary
|
||||
# every time we autopatch Rebar projects. Wait and see.
|
||||
define hex_version_resolver.erl
|
||||
HexVersionResolve = fun(Name, Req) ->
|
||||
application:ensure_all_started(ssl),
|
||||
application:ensure_all_started(inets),
|
||||
Config = $(hex_config.erl),
|
||||
case hex_repo:get_package(Config, atom_to_binary(Name)) of
|
||||
{ok, {200, _RespHeaders, Package}} ->
|
||||
#{releases := List} = Package,
|
||||
{value, #{version := Version}} = lists:search(fun(#{version := Vsn}) ->
|
||||
M = list_to_atom("Elixir.Version"),
|
||||
F = list_to_atom("match?"),
|
||||
M:F(Vsn, Req)
|
||||
end, List),
|
||||
{ok, Version};
|
||||
{ok, {Status, _, Errors}} ->
|
||||
{error, Status, Errors}
|
||||
end
|
||||
end,
|
||||
HexVersionResolveAndPrint = fun(Name, Req) ->
|
||||
case HexVersionResolve(Name, Req) of
|
||||
{ok, Version} ->
|
||||
io:format("~s", [Version]),
|
||||
halt(0);
|
||||
{error, Status, Errors} ->
|
||||
io:format("Error ~b: ~0p~n", [Status, Errors]),
|
||||
halt(77)
|
||||
end
|
||||
end
|
||||
endef
|
||||
|
||||
define dep_autopatch_mix.erl
|
||||
$(call hex_version_resolver.erl),
|
||||
{ok, _} = application:ensure_all_started(elixir),
|
||||
{ok, _} = application:ensure_all_started(mix),
|
||||
MixFile = <<"$(call core_native_path,$(DEPS_DIR)/$1/mix.exs)">>,
|
||||
{Mod, Bin} =
|
||||
case elixir_compiler:file(MixFile, fun(_File, _LexerPid) -> ok end) of
|
||||
[{T = {_, _}, _CheckerPid}] -> T;
|
||||
[T = {_, _}] -> T
|
||||
end,
|
||||
{module, Mod} = code:load_binary(Mod, binary_to_list(MixFile), Bin),
|
||||
Project = Mod:project(),
|
||||
Application = try Mod:application() catch error:undef -> [] end,
|
||||
StartMod = case lists:keyfind(mod, 1, Application) of
|
||||
{mod, {StartMod0, _StartArgs}} ->
|
||||
atom_to_list(StartMod0);
|
||||
_ ->
|
||||
""
|
||||
end,
|
||||
Write = fun (Text) ->
|
||||
file:write_file("$(call core_native_path,$(DEPS_DIR)/$1/Makefile)", Text, [append])
|
||||
end,
|
||||
Write([
|
||||
"PROJECT = ", atom_to_list(proplists:get_value(app, Project)), "\n"
|
||||
"PROJECT_DESCRIPTION = ", proplists:get_value(description, Project, ""), "\n"
|
||||
"PROJECT_VERSION = ", proplists:get_value(version, Project, ""), "\n"
|
||||
"PROJECT_MOD = ", StartMod, "\n"
|
||||
"define PROJECT_ENV\n",
|
||||
io_lib:format("~p", [proplists:get_value(env, Application, [])]), "\n"
|
||||
"endef\n\n"]),
|
||||
ExtraApps = lists:usort([eex, elixir, logger, mix] ++ proplists:get_value(extra_applications, Application, [])),
|
||||
Write(["LOCAL_DEPS += ", lists:join(" ", [atom_to_list(App) || App <- ExtraApps]), "\n\n"]),
|
||||
Deps = proplists:get_value(deps, Project, []) -- [elixir_make],
|
||||
IsRequiredProdDep = fun(Opts) ->
|
||||
(proplists:get_value(optional, Opts) =/= true)
|
||||
andalso
|
||||
case proplists:get_value(only, Opts, prod) of
|
||||
prod -> true;
|
||||
L when is_list(L) -> lists:member(prod, L);
|
||||
_ -> false
|
||||
end
|
||||
end,
|
||||
lists:foreach(fun
|
||||
({Name, Req}) when is_binary(Req) ->
|
||||
{ok, Vsn} = HexVersionResolve(Name, Req),
|
||||
Write(["DEPS += ", atom_to_list(Name), "\n"]),
|
||||
Write(["dep_", atom_to_list(Name), " = hex ", Vsn, " ", atom_to_list(Name), "\n"]);
|
||||
({Name, Opts}) when is_list(Opts) ->
|
||||
Path = proplists:get_value(path, Opts),
|
||||
case IsRequiredProdDep(Opts) of
|
||||
true when Path =/= undefined ->
|
||||
Write(["DEPS += ", atom_to_list(Name), "\n"]),
|
||||
Write(["dep_", atom_to_list(Name), " = ln ", Path, "\n"]);
|
||||
true when Path =:= undefined ->
|
||||
Write(["DEPS += ", atom_to_list(Name), "\n"]),
|
||||
io:format(standard_error, "Warning: No version given for ~p.", [Name]);
|
||||
false ->
|
||||
ok
|
||||
end;
|
||||
({Name, Req, Opts}) ->
|
||||
case IsRequiredProdDep(Opts) of
|
||||
true ->
|
||||
{ok, Vsn} = HexVersionResolve(Name, Req),
|
||||
Write(["DEPS += ", atom_to_list(Name), "\n"]),
|
||||
Write(["dep_", atom_to_list(Name), " = hex ", Vsn, " ", atom_to_list(Name), "\n"]);
|
||||
false ->
|
||||
ok
|
||||
end;
|
||||
(_) ->
|
||||
ok
|
||||
end, Deps),
|
||||
case lists:member(elixir_make, proplists:get_value(compilers, Project, [])) of
|
||||
false ->
|
||||
ok;
|
||||
true ->
|
||||
Write("# https://hexdocs.pm/elixir_make/Mix.Tasks.Compile.ElixirMake.html\n"),
|
||||
MakeVal = fun(Key, Proplist, DefaultVal, DefaultReplacement) ->
|
||||
case proplists:get_value(Key, Proplist, DefaultVal) of
|
||||
DefaultVal -> DefaultReplacement;
|
||||
Value -> Value
|
||||
end
|
||||
end,
|
||||
MakeMakefile = binary_to_list(MakeVal(make_makefile, Project, default, <<"Makefile">>)),
|
||||
MakeExe = MakeVal(make_executable, Project, default, "$$\(MAKE)"),
|
||||
MakeCwd = MakeVal(make_cwd, Project, undefined, <<".">>),
|
||||
MakeTargets = MakeVal(make_targets, Project, [], []),
|
||||
MakeArgs = MakeVal(make_args, Project, undefined, []),
|
||||
case file:rename("$(DEPS_DIR)/$1/" ++ MakeMakefile, "$(DEPS_DIR)/$1/elixir_make.mk") of
|
||||
ok -> ok;
|
||||
Err = {error, _} ->
|
||||
io:format(standard_error, "Failed to copy Makefile with error ~p~n", [Err]),
|
||||
halt(90)
|
||||
end,
|
||||
Write(["app::\n"
|
||||
"\t", MakeExe, " -C ", MakeCwd, " -f $(DEPS_DIR)/$1/elixir_make.mk",
|
||||
lists:join(" ", MakeTargets),
|
||||
lists:join(" ", MakeArgs),
|
||||
"\n\n"]),
|
||||
case MakeVal(make_clean, Project, nil, undefined) of
|
||||
undefined ->
|
||||
ok;
|
||||
Clean ->
|
||||
Write(["clean::\n\t", Clean, "\n\n"])
|
||||
end
|
||||
end,
|
||||
Write("ERLC_OPTS = +debug_info\n\n"),
|
||||
Write("include $$\(if $$\(ERLANG_MK_FILENAME),$$\(ERLANG_MK_FILENAME),erlang.mk)"),
|
||||
halt()
|
||||
endef
|
||||
|
||||
define dep_autopatch_mix
|
||||
sed 's|\(defmodule.*do\)|\1\n try do\n Code.compiler_options(on_undefined_variable: :warn)\n rescue _ -> :ok\n end\n|g' -i $(DEPS_DIR)/$(1)/mix.exs; \
|
||||
$(MAKE) $(DEPS_DIR)/hex_core/ebin/dep_built; \
|
||||
MIX_ENV="$(if $(MIX_ENV),$(strip $(MIX_ENV)),prod)" \
|
||||
$(call erlang,$(call dep_autopatch_mix.erl,$1))
|
||||
endef
|
||||
|
||||
# We change the group leader so the Elixir io:format output
|
||||
# isn't captured as we need to either print the modules on
|
||||
# success, or print _ERROR_ on failure.
|
||||
define compile_ex.erl
|
||||
{ok, _} = application:ensure_all_started(elixir),
|
||||
{ok, _} = application:ensure_all_started(mix),
|
||||
ModCode = list_to_atom("Elixir.Code"),
|
||||
ModCode:put_compiler_option(ignore_module_conflict, true),
|
||||
ModComp = list_to_atom("Elixir.Kernel.ParallelCompiler"),
|
||||
ModMixProject = list_to_atom("Elixir.Mix.Project"),
|
||||
erlang:group_leader(whereis(standard_error), self()),
|
||||
ModMixProject:in_project($(PROJECT), ".", [], fun(_MixFile) ->
|
||||
case ModComp:compile_to_path([$(call comma_list,$(patsubst %,<<"%">>,$1))], <<"ebin/">>) of
|
||||
{ok, Modules, _} ->
|
||||
lists:foreach(fun(E) -> io:format(user, "~p ", [E]) end, Modules),
|
||||
halt(0);
|
||||
{error, _ErroredModules, _WarnedModules} ->
|
||||
io:format(user, "_ERROR_", []),
|
||||
halt(1)
|
||||
end
|
||||
end)
|
||||
endef
|
||||
|
||||
>>>>>>> b34a7227b (Update Erlang.mk)
|
||||
# Copyright (c) 2016, Loïc Hoguin <essen@ninenines.eu>
|
||||
# Copyright (c) 2015, Viktor Söderqvist <viktor@zuiderkwast.se>
|
||||
# This file is part of erlang.mk and subject to the terms of the ISC License.
|
||||
|
|
Loading…
Reference in New Issue