17
17
ERLANG_MK_FILENAME := $(realpath $(lastword $(MAKEFILE_LIST ) ) )
18
18
export ERLANG_MK_FILENAME
19
19
20
+ <<<<<<< HEAD
20
21
ERLANG_MK_VERSION = 2022.05.31-72-gb8a27ab-dirty
22
+ ====== =
23
+ ERLANG_MK_VERSION = e13b4c7
24
+ >>>>>>> b34a7227b (Update Erlang.mk)
21
25
ERLANG_MK_WITHOUT =
22
26
23
27
# Make 3.81 and 3.82 are deprecated.
@@ -3774,6 +3778,7 @@ endif
3774
3778
3775
3779
# Deps related targets.
3776
3780
3781
+ <<<<<<< HEAD
3777
3782
# @todo rename GNUmakefile and makefile into Makefile first, if they exist
3778
3783
# While Makefile file could be GNUmakefile or makefile,
3779
3784
# in practice only Makefile is needed so far.
@@ -3783,6 +3788,26 @@ define dep_autopatch
3783
3788
$(call erlang,$(call dep_autopatch_appsrc.erl,$(1 ) ) ) ; \
3784
3789
$(call dep_autopatch_erlang_mk,$(1 ) ) ; \
3785
3790
elif [ -f $(DEPS_DIR ) /$(1 ) /Makefile ]; then \
3791
+ =======
3792
+ autopatch_verbose_0 = @echo " PATCH " $(subst autopatch-,,$@ ) "(method: $(AUTOPATCH_METHOD ) )";
3793
+ autopatch_verbose_2 = set -x;
3794
+ autopatch_verbose = $(autopatch_verbose_$(V ) )
3795
+
3796
+ define dep_autopatch_detect
3797
+ if [ -f $(DEPS_DIR ) /$1/erlang.mk ]; then \
3798
+ echo erlang.mk; \
3799
+ elif [ -f $(DEPS_DIR ) /$1/mix.exs -a -d $(DEPS_DIR ) /$1/lib ]; then \
3800
+ if [ "$(ELIXIR ) " != "disable" ]; then \
3801
+ echo mix; \
3802
+ elif [ -f $(DEPS_DIR ) /$1/rebar.lock -o -f $(DEPS_DIR ) /$1/rebar.config ]; then \
3803
+ echo rebar3; \
3804
+ elif [ -f $(DEPS_DIR ) /$1/Makefile ]; then \
3805
+ echo noop; \
3806
+ else \
3807
+ exit 99; \
3808
+ fi \
3809
+ elif [ -f $(DEPS_DIR ) /$1/Makefile ]; then \
3810
+ >>>>>>> b34a7227b (Update Erlang.mk)
3786
3811
if [ -f $(DEPS_DIR ) /$1/rebar.lock ]; then \
3787
3812
$(call dep_autopatch2,$1) ; \
3788
3813
elif [ 0 != `grep -c "include ../\w*\.mk" $(DEPS_DIR ) /$(1 ) /Makefile` ]; then \
@@ -4839,6 +4864,216 @@ clean-app:
4839
4864
4840
4865
endif
4841
4866
4867
+ <<<<<<< HEAD
4868
+ =======
4869
+ # Copyright (c) 2024, Tyler Hughes <[email protected] >
4870
+ # Copyright (c) 2024, Loïc Hoguin <[email protected] >
4871
+ # This file is part of erlang.mk and subject to the terms of the ISC License.
4872
+
4873
+ # Elixir is automatically enabled in all cases except when
4874
+ # an Erlang project uses an Elixir dependency. In that case
4875
+ # $(ELIXIR) must be set explicitly.
4876
+ ELIXIR ?= $(if $(filter elixir,$(BUILD_DEPS ) $(DEPS ) ) ,dep,$(if $(EX_FILES ) ,system,disable) )
4877
+ export ELIXIR
4878
+
4879
+ ifeq ($(ELIXIR ) ,system)
4880
+ # We expect 'elixir' to be on the path.
4881
+ ELIXIR_BIN ?= $(shell readlink -f `which elixir`)
4882
+ ELIXIR_LIBS ?= $(abspath $(dir $(ELIXIR_BIN ) ) /../lib)
4883
+ # Fallback in case 'elixir' is a shim.
4884
+ ifeq ($(wildcard $(ELIXIR_LIBS ) /elixir/) ,)
4885
+ ELIXIR_LIBS = $(abspath $(shell elixir -e 'IO.puts(:code.lib_dir(:elixir) ) ')/../)
4886
+ endif
4887
+ ELIXIR_LIBS := $(ELIXIR_LIBS )
4888
+ export ELIXIR_LIBS
4889
+ ERL_LIBS := $(ERL_LIBS ) :$(ELIXIR_LIBS )
4890
+ else
4891
+ ifeq ($(ELIXIR ) ,dep)
4892
+ ERL_LIBS := $(ERL_LIBS ) :$(DEPS_DIR ) /elixir/lib/
4893
+ endif
4894
+ endif
4895
+
4896
+ elixirc_verbose_0 = @echo " EXC $(words $(EX_FILES ) ) files";
4897
+ elixirc_verbose_2 = set -x;
4898
+ elixirc_verbose = $(elixirc_verbose_$(V ) )
4899
+
4900
+ # Unfortunately this currently requires Elixir.
4901
+ # https://github.com/jelly-beam/verl is a good choice
4902
+ # for an Erlang implementation, but we already have to
4903
+ # pull hex_core and Rebar3 so adding yet another pull
4904
+ # is annoying, especially one that would be necessary
4905
+ # every time we autopatch Rebar projects. Wait and see.
4906
+ define hex_version_resolver.erl
4907
+ HexVersionResolve = fun(Name, Req) ->
4908
+ application:ensure_all_started(ssl),
4909
+ application:ensure_all_started(inets),
4910
+ Config = $(hex_config.erl ) ,
4911
+ case hex_repo:get_package(Config, atom_to_binary(Name)) of
4912
+ {ok, {200, _RespHeaders, Package}} ->
4913
+ # {releases := List} = Package,
4914
+ {value, # {version := Version}} = lists:search(fun(#{version := Vsn}) ->
4915
+ M = list_to_atom("Elixir.Version"),
4916
+ F = list_to_atom("match?"),
4917
+ M:F(Vsn, Req)
4918
+ end, List),
4919
+ {ok, Version};
4920
+ {ok, {Status, _, Errors}} ->
4921
+ {error, Status, Errors}
4922
+ end
4923
+ end,
4924
+ HexVersionResolveAndPrint = fun(Name, Req) ->
4925
+ case HexVersionResolve(Name, Req) of
4926
+ {ok, Version} ->
4927
+ io:format("~s", [Version]),
4928
+ halt(0);
4929
+ {error, Status, Errors} ->
4930
+ io:format("Error ~b: ~0p~n", [Status, Errors]),
4931
+ halt(77)
4932
+ end
4933
+ end
4934
+ endef
4935
+
4936
+ define dep_autopatch_mix.erl
4937
+ $(call hex_version_resolver.erl) ,
4938
+ {ok, _} = application:ensure_all_started(elixir),
4939
+ {ok, _} = application:ensure_all_started(mix),
4940
+ MixFile = <<"$(call core_native_path,$(DEPS_DIR ) /$1/mix.exs) ">>,
4941
+ {Mod, Bin} =
4942
+ case elixir_compiler:file(MixFile, fun(_File, _LexerPid) -> ok end) of
4943
+ [{T = {_, _}, _CheckerPid}] -> T;
4944
+ [T = {_, _}] -> T
4945
+ end,
4946
+ {module, Mod} = code:load_binary(Mod, binary_to_list(MixFile), Bin),
4947
+ Project = Mod:project(),
4948
+ Application = try Mod:application() catch error:undef -> [] end,
4949
+ StartMod = case lists:keyfind(mod, 1, Application) of
4950
+ {mod, {StartMod0, _StartArgs}} ->
4951
+ atom_to_list(StartMod0);
4952
+ _ ->
4953
+ ""
4954
+ end,
4955
+ Write = fun (Text) ->
4956
+ file:write_file("$(call core_native_path,$(DEPS_DIR ) /$1/Makefile) ", Text, [append])
4957
+ end,
4958
+ Write([
4959
+ "PROJECT = ", atom_to_list(proplists:get_value(app, Project)), "\n"
4960
+ "PROJECT_DESCRIPTION = ", proplists:get_value(description, Project, ""), "\n"
4961
+ "PROJECT_VERSION = ", proplists:get_value(version, Project, ""), "\n"
4962
+ "PROJECT_MOD = ", StartMod, "\n"
4963
+ "define PROJECT_ENV\n",
4964
+ io_lib:format("~p", [proplists:get_value(env, Application, [])]), "\n"
4965
+ "endef\n\n"]),
4966
+ ExtraApps = lists:usort([eex, elixir, logger, mix] ++ proplists:get_value(extra_applications, Application, [])),
4967
+ Write(["LOCAL_DEPS += ", lists:join(" ", [atom_to_list(App) || App <- ExtraApps]), "\n\n"]),
4968
+ Deps = proplists:get_value(deps, Project, []) -- [elixir_make],
4969
+ IsRequiredProdDep = fun(Opts) ->
4970
+ (proplists:get_value(optional, Opts) =/= true)
4971
+ andalso
4972
+ case proplists:get_value(only, Opts, prod) of
4973
+ prod -> true;
4974
+ L when is_list(L) -> lists:member(prod, L);
4975
+ _ -> false
4976
+ end
4977
+ end,
4978
+ lists:foreach(fun
4979
+ ({Name, Req}) when is_binary(Req) ->
4980
+ {ok, Vsn} = HexVersionResolve(Name, Req),
4981
+ Write(["DEPS += ", atom_to_list(Name), "\n"]),
4982
+ Write(["dep_", atom_to_list(Name), " = hex ", Vsn, " ", atom_to_list(Name), "\n"]);
4983
+ ({Name, Opts}) when is_list(Opts) ->
4984
+ Path = proplists:get_value(path, Opts),
4985
+ case IsRequiredProdDep(Opts) of
4986
+ true when Path =/= undefined ->
4987
+ Write(["DEPS += ", atom_to_list(Name), "\n"]),
4988
+ Write(["dep_", atom_to_list(Name), " = ln ", Path, "\n"]);
4989
+ true when Path =:= undefined ->
4990
+ Write(["DEPS += ", atom_to_list(Name), "\n"]),
4991
+ io:format(standard_error, "Warning: No version given for ~p.", [Name]);
4992
+ false ->
4993
+ ok
4994
+ end;
4995
+ ({Name, Req, Opts}) ->
4996
+ case IsRequiredProdDep(Opts) of
4997
+ true ->
4998
+ {ok, Vsn} = HexVersionResolve(Name, Req),
4999
+ Write(["DEPS += ", atom_to_list(Name), "\n"]),
5000
+ Write(["dep_", atom_to_list(Name), " = hex ", Vsn, " ", atom_to_list(Name), "\n"]);
5001
+ false ->
5002
+ ok
5003
+ end;
5004
+ (_) ->
5005
+ ok
5006
+ end, Deps),
5007
+ case lists:member(elixir_make, proplists:get_value(compilers, Project, [])) of
5008
+ false ->
5009
+ ok;
5010
+ true ->
5011
+ Write("# https://hexdocs.pm/elixir_make/Mix.Tasks.Compile.ElixirMake.html\n"),
5012
+ MakeVal = fun(Key, Proplist, DefaultVal, DefaultReplacement) ->
5013
+ case proplists:get_value(Key, Proplist, DefaultVal) of
5014
+ DefaultVal -> DefaultReplacement;
5015
+ Value -> Value
5016
+ end
5017
+ end,
5018
+ MakeMakefile = binary_to_list(MakeVal(make_makefile, Project, default, <<"Makefile">>)),
5019
+ MakeExe = MakeVal(make_executable, Project, default, "$$\(MAKE)"),
5020
+ MakeCwd = MakeVal(make_cwd, Project, undefined, <<".">>),
5021
+ MakeTargets = MakeVal(make_targets, Project, [], []),
5022
+ MakeArgs = MakeVal(make_args, Project, undefined, []),
5023
+ case file:rename("$(DEPS_DIR ) /$1/" ++ MakeMakefile, "$(DEPS_DIR ) /$1/elixir_make.mk") of
5024
+ ok -> ok;
5025
+ Err = {error, _} ->
5026
+ io:format(standard_error, "Failed to copy Makefile with error ~p~n", [Err]),
5027
+ halt(90)
5028
+ end,
5029
+ Write(["app::\n"
5030
+ "\t", MakeExe, " -C ", MakeCwd, " -f $(DEPS_DIR ) /$1/elixir_make.mk",
5031
+ lists:join(" ", MakeTargets),
5032
+ lists:join(" ", MakeArgs),
5033
+ "\n\n"]),
5034
+ case MakeVal(make_clean, Project, nil, undefined) of
5035
+ undefined ->
5036
+ ok;
5037
+ Clean ->
5038
+ Write(["clean::\n\t", Clean, "\n\n"])
5039
+ end
5040
+ end,
5041
+ Write("ERLC_OPTS = +debug_info\n\n"),
5042
+ Write("include $$\(if $$\(ERLANG_MK_FILENAME),$$\(ERLANG_MK_FILENAME),erlang.mk)"),
5043
+ halt()
5044
+ endef
5045
+
5046
+ define dep_autopatch_mix
5047
+ 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; \
5048
+ $(MAKE ) $(DEPS_DIR ) /hex_core/ebin/dep_built; \
5049
+ MIX_ENV="$(if $(MIX_ENV ) ,$(strip $(MIX_ENV ) ) ,prod) " \
5050
+ $(call erlang,$(call dep_autopatch_mix.erl,$1) )
5051
+ endef
5052
+
5053
+ # We change the group leader so the Elixir io:format output
5054
+ # isn't captured as we need to either print the modules on
5055
+ # success, or print _ERROR_ on failure.
5056
+ define compile_ex.erl
5057
+ {ok, _} = application:ensure_all_started(elixir),
5058
+ {ok, _} = application:ensure_all_started(mix),
5059
+ ModCode = list_to_atom("Elixir.Code"),
5060
+ ModCode:put_compiler_option(ignore_module_conflict, true),
5061
+ ModComp = list_to_atom("Elixir.Kernel.ParallelCompiler"),
5062
+ ModMixProject = list_to_atom("Elixir.Mix.Project"),
5063
+ erlang:group_leader(whereis(standard_error), self()),
5064
+ ModMixProject:in_project($(PROJECT ) , ".", [], fun(_MixFile) ->
5065
+ case ModComp:compile_to_path([$(call comma_list,$(patsubst % ,<<"% ">>,$1) ) ], <<"ebin/">>) of
5066
+ {ok, Modules, _} ->
5067
+ lists:foreach(fun(E) -> io:format(user, "~p ", [E]) end, Modules),
5068
+ halt(0);
5069
+ {error, _ErroredModules, _WarnedModules} ->
5070
+ io:format(user, "_ERROR_", []),
5071
+ halt(1)
5072
+ end
5073
+ end)
5074
+ endef
5075
+
5076
+ >>>>>>> b34a7227b (Update Erlang.mk)
4842
5077
# Copyright (c) 2016, Loïc Hoguin <[email protected] >
4843
5078
# Copyright (c) 2015, Viktor Söderqvist <[email protected] >
4844
5079
# This file is part of erlang.mk and subject to the terms of the ISC License.
0 commit comments