diff options
Diffstat (limited to 'core/deps.mk')
-rw-r--r-- | core/deps.mk | 220 |
1 files changed, 212 insertions, 8 deletions
diff --git a/core/deps.mk b/core/deps.mk index 80bedda..5a7f542 100644 --- a/core/deps.mk +++ b/core/deps.mk @@ -1,10 +1,13 @@ -# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]> +# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]> # This file is part of erlang.mk and subject to the terms of the ISC License. .PHONY: distclean-deps distclean-pkg pkg-list pkg-search # Configuration. +AUTOPATCH ?= edown gen_leader gproc +export AUTOPATCH + DEPS_DIR ?= $(CURDIR)/deps export DEPS_DIR @@ -27,28 +30,204 @@ export PKG_FILE2 PKG_FILE_URL ?= https://raw.githubusercontent.com/ninenines/erlang.mk/master/packages.v2.tsv +# Verbosity. + +dep_verbose_0 = @echo " DEP " $(1); +dep_verbose = $(dep_verbose_$(V)) + # Core targets. +ifneq ($(SKIP_DEPS),) +deps:: +else deps:: $(ALL_DEPS_DIRS) @for dep in $(ALL_DEPS_DIRS) ; do \ if [ -f $$dep/GNUmakefile ] || [ -f $$dep/makefile ] || [ -f $$dep/Makefile ] ; then \ - $(MAKE) -C $$dep ; \ + $(MAKE) -C $$dep IS_DEP=1 || exit $$? ; \ else \ - echo "include $(CURDIR)/erlang.mk" | ERLC_OPTS=+debug_info $(MAKE) -f - -C $$dep ; \ + echo "ERROR: No makefile to build dependency $$dep. Consider adding it to AUTOPATCH." ; \ + exit 1 ; \ fi ; \ done +endif distclean:: distclean-deps distclean-pkg # Deps related targets. +# @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. +define dep_autopatch + if [ -f $(DEPS_DIR)/$(1)/Makefile ]; then \ + if [ 0 != `grep -ci rebar $(DEPS_DIR)/$(1)/Makefile` ]; then \ + $(call dep_autopatch2,$(1)); \ + elif [ 0 != `find $(DEPS_DIR)/$(1)/ -type f -name \*.mk -not -name erlang.mk | xargs grep -ci rebar` ]; then \ + $(call dep_autopatch2,$(1)); \ + else \ + $(call dep_autopatch_erlang_mk,$(1)); \ + fi \ + else \ + if [ ! -d $(DEPS_DIR)/$(1)/src/ ]; then \ + $(call dep_autopatch_noop,$(1)); \ + else \ + $(call dep_autopatch2,$(1)); \ + fi \ + fi +endef + +define dep_autopatch2 + if [ ! -f $(DEPS_DIR)/$(1)/rebar.config ]; then \ + $(call dep_autopatch_gen,$(1)); \ + else \ + $(call dep_autopatch_rebar,$(1)); \ + fi +endef + +define dep_autopatch_noop + printf "noop:\n" > $(DEPS_DIR)/$(1)/Makefile +endef + +# Overwrite erlang.mk with the current file by default. +ifeq ($(NO_AUTOPATCH_ERLANG_MK),) +define dep_autopatch_erlang_mk + rm -f $(DEPS_DIR)/$(1)/erlang.mk; \ + cd $(DEPS_DIR)/$(1)/ && ln -s ../../erlang.mk; \ + $(call erlang,$(call dep_autopatch_appsrc.erl,$(1))) +endef +else +define dep_autopatch_erlang_mk + $(call erlang,$(call dep_autopatch_appsrc.erl,$(1))) +endef +endif + +define dep_autopatch_gen + printf "%s\n" \ + "ERLC_OPTS = +debug_info" \ + "include ../../erlang.mk" > $(DEPS_DIR)/$(1)/Makefile; \ + $(call erlang,$(call dep_autopatch_appsrc.erl,$(1))) +endef + +define dep_autopatch_rebar + if [ -f $(DEPS_DIR)/$(1)/Makefile ]; then \ + mv $(DEPS_DIR)/$(1)/Makefile $(DEPS_DIR)/$(1)/Makefile.orig.mk; \ + fi; \ + $(call erlang,$(call dep_autopatch_rebar.erl,$(1))); \ + $(call erlang,$(call dep_autopatch_appsrc.erl,$(1))) +endef + +define dep_autopatch_rebar.erl + {ok, Conf} = file:consult("$(DEPS_DIR)/$(1)/rebar.config"), + Write = fun (Text) -> + file:write_file("$(DEPS_DIR)/$(1)/Makefile", Text, [append]) + end, + Escape = fun (Text) -> + re:replace(Text, "\\\\$$$$", "\$$$$$$$$", [global, {return, list}]) + end, + Write("ERLC_OPTS = +debug_info\n\n"), + fun() -> + File = case lists:keyfind(deps, 1, Conf) of + false -> []; + {_, Deps} -> + [begin + Name = element(1, Dep), + {Method, Repo, Commit} = case element(3, Dep) of + {git, R} -> {git, R, master}; + {M, R, {branch, C}} -> {M, R, C}; + {M, R, {tag, C}} -> {M, R, C}; + {M, R, C} -> {M, R, C} + end, + Write(io_lib:format("DEPS += ~s\ndep_~s = ~s ~s ~s~n", [Name, Name, Method, Repo, Commit])) + end || Dep <- Deps, tuple_size(Dep) > 2] + end + end(), + fun() -> + First = case lists:keyfind(erl_first_files, 1, Conf) of false -> []; {_, Files} -> + Names = [[" ", begin "lre." ++ Elif = lists:reverse(F), lists:reverse(Elif) end] + || "src/" ++ F <- Files], + Write(io_lib:format("COMPILE_FIRST +=~s\n", [Names])) + end + end(), + fun() -> + case lists:keyfind(port_env, 1, Conf) of + {_, Vars} -> + [Write(K ++ " = $$$$\(shell echo " ++ Escape(V) ++ "\)\n") || {K, V} <- Vars], + Write("CFLAGS += $$$$\(DRV_CFLAGS\)\n"), + Write("CXXFLAGS += $$$$\(DRV_CFLAGS\)\n"), + Write("LDFLAGS += $$$$\(DRV_LDFLAGS\)\n"); + _ -> ok + end + end(), + fun() -> + case filelib:is_dir("$(DEPS_DIR)/$(1)/c_src") of + false -> ok; + true -> + Sources = [[" ./c_src/", S] || S <- filelib:wildcard("*.{c,C,cc,cpp}", "$(DEPS_DIR)/$(1)/c_src")], + Write(io_lib:format("SOURCES := ~s\n", [Sources])) + end + end(), + Write("\n\nrebar_dep: pre-deps deps pre-app app\n"), + Write("\npre-deps::\n"), + Write("\npre-app::\n"), + fun() -> + case lists:keyfind(pre_hooks, 1, Conf) of + false -> ok; + {_, Hooks} -> + [case H of + {'get-deps', Command} -> + Write("\npre-deps::\n\t" ++ Escape(Command) ++ "\n"); + {compile, Command} -> + Write("\npre-app::\n\t" ++ Escape(Command) ++ "\n"); + {Regex, compile, Command0} -> + case re:run("$(PLATFORM)", Regex, [{capture, none}]) of + match -> + Command = case Command0 of + "make -C" ++ _ -> Escape(Command0); + "gmake -C" ++ _ -> Escape(Command0); + "make " ++ Command1 -> "make -f Makefile.orig.mk " ++ Escape(Command1); + "gmake " ++ Command1 -> "gmake -f Makefile.orig.mk " ++ Escape(Command1); + _ -> Command0 + end, + Write("\npre-app::\n\t" ++ Command ++ "\n"); + nomatch -> + ok + end; + _ -> ok + end || H <- Hooks] + end + end(), + Write("\ninclude ../../erlang.mk"), + halt() +endef + +define dep_autopatch_appsrc.erl + AppSrcOut = "$(DEPS_DIR)/$(1)/src/$(1).app.src", + AppSrcIn = case filelib:is_regular(AppSrcOut) of false -> "$(DEPS_DIR)/$(1)/ebin/$(1).app"; true -> AppSrcOut end, + case filelib:is_regular(AppSrcIn) of + false -> ok; + true -> + fun() -> + {ok, [{application, $(1), L}]} = file:consult(AppSrcIn), + L2 = case lists:keyfind(modules, 1, L) of {_, _} -> L; false -> [{modules, []}|L] end, + L3 = case lists:keyfind(vsn, 1, L2) of {vsn, git} -> lists:keyreplace(vsn, 1, L2, {vsn, "git"}); _ -> L2 end, + ok = file:write_file(AppSrcOut, io_lib:format("~p.~n", [{application, $(1), L3}])) + end(), + case AppSrcOut of AppSrcIn -> ok; _ -> ok = file:delete(AppSrcIn) end + end, + halt() +endef + define dep_fetch if [ "$$$$VS" = "git" ]; then \ - git clone -n -- $$$$REPO $(DEPS_DIR)/$(1); \ + git clone -q -n -- $$$$REPO $(DEPS_DIR)/$(1); \ cd $(DEPS_DIR)/$(1) && git checkout -q $$$$COMMIT; \ elif [ "$$$$VS" = "hg" ]; then \ - hg clone -U $$$$REPO $(DEPS_DIR)/$(1); \ + hg clone -q -U $$$$REPO $(DEPS_DIR)/$(1); \ cd $(DEPS_DIR)/$(1) && hg update -q $$$$COMMIT; \ + elif [ "$$$$VS" = "svn" ]; then \ + svn checkout -q $$$$REPO $(DEPS_DIR)/$(1); \ + elif [ "$$$$VS" = "cp" ]; then \ + cp -R $$$$REPO $(DEPS_DIR)/$(1); \ else \ echo "Unknown or invalid dependency: $(1). Please consult the erlang.mk README for instructions." >&2; \ exit 78; \ @@ -60,17 +239,42 @@ $(DEPS_DIR)/$(1): @mkdir -p $(DEPS_DIR) ifeq (,$(dep_$(1))) @if [ ! -f $(PKG_FILE2) ]; then $(call core_http_get,$(PKG_FILE2),$(PKG_FILE_URL)); fi - @DEPPKG=$$$$(awk 'BEGIN { FS = "\t" }; $$$$1 == "$(1)" { print $$$$2 " " $$$$3 " " $$$$4 }' $(PKG_FILE2);); \ + $(dep_verbose) DEPPKG=$$$$(awk 'BEGIN { FS = "\t" }; $$$$1 == "$(1)" { print $$$$2 " " $$$$3 " " $$$$4 }' $(PKG_FILE2);); \ VS=$$$$(echo $$$$DEPPKG | cut -d " " -f1); \ REPO=$$$$(echo $$$$DEPPKG | cut -d " " -f2); \ COMMIT=$$$$(echo $$$$DEPPKG | cut -d " " -f3); \ $(call dep_fetch,$(1)) else - @VS=$(word 1,$(dep_$(1))); \ +ifeq (1,$(words $(dep_$(1)))) + $(dep_verbose) VS=git; \ + REPO=$(dep_$(1)); \ + COMMIT=master; \ + $(call dep_fetch,$(1)) +else +ifeq (2,$(words $(dep_$(1)))) + $(dep_verbose) VS=git; \ + REPO=$(word 1,$(dep_$(1))); \ + COMMIT=$(word 2,$(dep_$(1))); \ + $(call dep_fetch,$(1)) +else + $(dep_verbose) VS=$(word 1,$(dep_$(1))); \ REPO=$(word 2,$(dep_$(1))); \ COMMIT=$(word 3,$(dep_$(1))); \ $(call dep_fetch,$(1)) endif +endif +endif + @if [ -f $(DEPS_DIR)/$(1)/configure.ac ]; then \ + echo " AUTO " $(1); \ + cd $(DEPS_DIR)/$(1) && autoreconf -vif; \ + fi + -@if [ -f $(DEPS_DIR)/$(1)/configure ]; then \ + echo " CONF " $(1); \ + cd $(DEPS_DIR)/$(1) && ./configure; \ + fi +ifeq ($(filter $(1),$(NO_AUTOPATCH)),) + @$(call dep_autopatch,$(1)) +endif endef $(foreach dep,$(DEPS),$(eval $(call dep_target,$(dep)))) @@ -99,7 +303,7 @@ pkg-search: $(PKG_FILE2) "Description:\t" $$6 "\n" }' else pkg-search: - $(error Usage: make pkg-search q=STRING) + $(error Usage: $(MAKE) pkg-search q=STRING) endif ifeq ($(PKG_FILE2),$(CURDIR)/.erlang.mk.packages.v2) |