aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/core.mk108
-rw-r--r--core/deps.mk220
-rw-r--r--core/docs.mk19
-rw-r--r--core/erlc.mk40
-rw-r--r--core/test.mk48
5 files changed, 400 insertions, 35 deletions
diff --git a/core/core.mk b/core/core.mk
index 0b06f73..497c431 100644
--- a/core/core.mk
+++ b/core/core.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
+# Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.PHONY: all deps app rel docs tests clean distclean help erlang-mk
+.PHONY: all deps app rel docs install-docs tests check clean distclean help erlang-mk
ERLANG_MK_VERSION = 1
@@ -28,12 +28,59 @@ V ?= 0
gen_verbose_0 = @echo " GEN " $@;
gen_verbose = $(gen_verbose_$(V))
+# "erl" command.
+
+ERL = erl +A0 -noinput -boot start_clean
+
+# Platform detection.
+# @todo Add Windows/Cygwin detection eventually.
+
+ifeq ($(PLATFORM),)
+UNAME_S := $(shell uname -s)
+
+ifeq ($(UNAME_S),Linux)
+PLATFORM = linux
+else ifeq ($(UNAME_S),Darwin)
+PLATFORM = darwin
+else ifeq ($(UNAME_S),SunOS)
+PLATFORM = solaris
+else ifeq ($(UNAME_S),GNU)
+PLATFORM = gnu
+else ifeq ($(UNAME_S),FreeBSD)
+PLATFORM = freebsd
+else ifeq ($(UNAME_S),NetBSD)
+PLATFORM = netbsd
+else ifeq ($(UNAME_S),OpenBSD)
+PLATFORM = openbsd
+else
+$(error Unable to detect platform. Please open a ticket with the output of uname -a.)
+endif
+
+export PLATFORM
+endif
+
# Core targets.
-all:: deps app rel
+ifneq ($(words $(MAKECMDGOALS)),1)
+.NOTPARALLEL:
+endif
+
+all:: deps
+ @$(MAKE) --no-print-directory app
+ @$(MAKE) --no-print-directory rel
+
+# Noop to avoid a Make warning when there's nothing to do.
+rel::
+ @echo -n
+
+check:: clean app tests
+
+clean:: clean-crashdump
-clean::
+clean-crashdump:
+ifneq ($(wildcard erl_crash.dump),)
$(gen_verbose) rm -f erl_crash.dump
+endif
distclean:: clean
@@ -42,33 +89,60 @@ help::
"erlang.mk (version $(ERLANG_MK_VERSION)) is distributed under the terms of the ISC License." \
"Copyright (c) 2013-2014 Loïc Hoguin <[email protected]>" \
"" \
- "Usage: [V=1] make [target]" \
+ "Usage: [V=1] $(MAKE) [-jNUM] [target]" \
"" \
"Core targets:" \
- " all Run deps, app and rel targets in that order" \
- " deps Fetch dependencies (if needed) and compile them" \
- " app Compile the project" \
- " rel Build a release for this project, if applicable" \
- " docs Build the documentation for this project" \
- " tests Run the tests for this project" \
- " clean Delete temporary and output files from most targets" \
- " distclean Delete all temporary and output files" \
- " help Display this help and exit" \
+ " all Run deps, app and rel targets in that order" \
+ " deps Fetch dependencies (if needed) and compile them" \
+ " app Compile the project" \
+ " rel Build a release for this project, if applicable" \
+ " docs Build the documentation for this project" \
+ " install-docs Install the man pages for this project" \
+ " tests Run the tests for this project" \
+ " check Compile and run all tests and analysis for this project" \
+ " clean Delete temporary and output files from most targets" \
+ " distclean Delete all temporary and output files" \
+ " help Display this help and exit" \
"" \
"The target clean only removes files that are commonly removed." \
"Dependencies and releases are left untouched." \
"" \
- "Setting V=1 when calling make enables verbose mode."
+ "Setting V=1 when calling $(MAKE) enables verbose mode." \
+ "Parallel execution is supported through the -j $(MAKE) flag."
# Core functions.
+define newline
+
+
+endef
+
+define erlang
+$(ERL) -eval "$(subst $(newline),,$(subst ",\",$(1)))"
+endef
+
ifeq ($(shell which wget 2>/dev/null | wc -l), 1)
define core_http_get
wget --no-check-certificate -O $(1) $(2)|| rm $(1)
endef
else
+define core_http_get.erl
+ ssl:start(),
+ inets:start(),
+ case httpc:request(get, {"$(2)", []}, [{autoredirect, true}], []) of
+ {ok, {{_, 200, _}, _, Body}} ->
+ case file:write_file("$(1)", Body) of
+ ok -> ok;
+ {error, R1} -> halt(R1)
+ end;
+ {error, R2} ->
+ halt(R2)
+ end,
+ halt(0).
+endef
+
define core_http_get
- erl -noshell -eval 'ssl:start(), inets:start(), case httpc:request(get, {"$(2)", []}, [{autoredirect, true}], []) of {ok, {{_, 200, _}, _, Body}} -> case file:write_file("$(1)", Body) of ok -> ok; {error, R1} -> halt(R1) end; {error, R2} -> halt(R2) end, halt(0).'
+ $(call erlang,$(call core_http_get.erl,$(1),$(2)))
endef
endif
@@ -80,6 +154,6 @@ ERLANG_MK_BUILD_DIR ?= .erlang.mk.build
erlang-mk:
git clone https://github.com/ninenines/erlang.mk $(ERLANG_MK_BUILD_DIR)
if [ -f $(ERLANG_MK_BUILD_CONFIG) ]; then cp $(ERLANG_MK_BUILD_CONFIG) $(ERLANG_MK_BUILD_DIR); fi
- cd $(ERLANG_MK_BUILD_DIR) && make
+ cd $(ERLANG_MK_BUILD_DIR) && $(MAKE)
cp $(ERLANG_MK_BUILD_DIR)/erlang.mk ./erlang.mk
rm -rf $(ERLANG_MK_BUILD_DIR)
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)
diff --git a/core/docs.mk b/core/docs.mk
new file mode 100644
index 0000000..e1e2d0e
--- /dev/null
+++ b/core/docs.mk
@@ -0,0 +1,19 @@
+# Copyright (c) 2015, Viktor Söderqvist <[email protected]>
+# This file is part of erlang.mk and subject to the terms of the ISC License.
+
+.PHONY: docs-deps
+
+# Configuration.
+
+ALL_DOC_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(DOC_DEPS))
+
+# Targets.
+
+$(foreach dep,$(DOC_DEPS),$(eval $(call dep_target,$(dep))))
+
+ifneq ($(SKIP_DEPS),)
+doc-deps:
+else
+doc-deps: $(ALL_DOC_DEPS_DIRS)
+ @for dep in $(ALL_DOC_DEPS_DIRS) ; do $(MAKE) -C $$dep; done
+endif
diff --git a/core/erlc.mk b/core/erlc.mk
index 8d720aa..18e8814 100644
--- a/core/erlc.mk
+++ b/core/erlc.mk
@@ -1,4 +1,4 @@
-# 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: clean-app
@@ -28,12 +28,21 @@ erlc_verbose = $(erlc_verbose_$(V))
xyrl_verbose_0 = @echo " XYRL " $(filter %.xrl %.yrl,$(?F));
xyrl_verbose = $(xyrl_verbose_$(V))
+asn1_verbose_0 = @echo " ASN1 " $(filter %.asn1,$(?F));
+asn1_verbose = $(asn1_verbose_$(V))
+
mib_verbose_0 = @echo " MIB " $(filter %.bin %.mib,$(?F));
mib_verbose = $(mib_verbose_$(V))
-# Core targets.
+# Targets.
+
+ifeq ($(wildcard ebin/test),)
+app:: app-build
+else
+app:: clean app-build
+endif
-app:: erlc-include ebin/$(PROJECT).app
+app-build: erlc-include ebin/$(PROJECT).app
$(eval MODULES := $(shell find ebin -type f -name \*.beam \
| sed "s/ebin\//'/;s/\.beam/',/" | sed '$$s/.$$//'))
@if [ -z "$$(grep -E '^[^%]*{modules,' src/$(PROJECT).app.src)" ]; then \
@@ -46,6 +55,11 @@ app:: erlc-include ebin/$(PROJECT).app
| sed "s/{id,[[:space:]]*\"git\"}/{id, \"$(GITDESCRIBE)\"}/" \
> ebin/$(PROJECT).app
+erlc-include:
+ -@if [ -d ebin/ ]; then \
+ find include/ src/ -type f -name \*.hrl -newer ebin -exec touch $(shell find src/ -type f -name "*.erl") \; 2>/dev/null || printf ''; \
+ fi
+
define compile_erl
$(erlc_verbose) erlc -v $(ERLC_OPTS) -o ebin/ \
-pa ebin/ -I include/ $(filter-out $(ERLC_EXCLUDE_PATHS),\
@@ -58,6 +72,13 @@ define compile_xyrl
@rm ebin/*.erl
endef
+define compile_asn1
+ $(asn1_verbose) erlc -v -I include/ -o ebin/ $(1)
+ @mv ebin/*.hrl include/
+ @mv ebin/*.asn1db include/
+ @rm ebin/*.erl
+endef
+
define compile_mib
$(mib_verbose) erlc -v $(ERLC_MIB_OPTS) -o priv/mibs/ \
-I priv/mibs/ $(COMPILE_MIB_FIRST_PATHS) $(1)
@@ -68,6 +89,12 @@ ifneq ($(wildcard src/),)
ebin/$(PROJECT).app::
@mkdir -p ebin/
+ifneq ($(wildcard asn1/),)
+ebin/$(PROJECT).app:: $(shell find asn1 -type f -name \*.asn1)
+ @mkdir -p include
+ $(if $(strip $?),$(call compile_asn1,$?))
+endif
+
ifneq ($(wildcard mibs/),)
ebin/$(PROJECT).app:: $(shell find mibs -type f -name \*.mib)
@mkdir -p priv/mibs/ include
@@ -85,13 +112,6 @@ endif
clean:: clean-app
-# Extra targets.
-
-erlc-include:
- -@if [ -d ebin/ ]; then \
- find include/ src/ -type f -name \*.hrl -newer ebin -exec touch $(shell find src/ -type f -name "*.erl") \; 2>/dev/null || printf ''; \
- fi
-
clean-app:
$(gen_verbose) rm -rf ebin/ priv/mibs/ \
$(addprefix include/,$(addsuffix .hrl,$(notdir $(basename $(wildcard mibs/*.mib)))))
diff --git a/core/test.mk b/core/test.mk
new file mode 100644
index 0000000..7dd5d61
--- /dev/null
+++ b/core/test.mk
@@ -0,0 +1,48 @@
+# Copyright (c) 2015, Loïc Hoguin <[email protected]>
+# This file is part of erlang.mk and subject to the terms of the ISC License.
+
+.PHONY: test-deps test-dir test-build clean-test-dir
+
+# Configuration.
+
+TEST_DIR ?= $(CURDIR)/test
+
+ALL_TEST_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(TEST_DEPS))
+
+TEST_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard
+TEST_ERLC_OPTS += -DTEST=1
+
+# Targets.
+
+$(foreach dep,$(TEST_DEPS),$(eval $(call dep_target,$(dep))))
+
+ifneq ($(SKIP_DEPS),)
+test-deps:
+else
+test-deps: $(ALL_TEST_DEPS_DIRS)
+ @for dep in $(ALL_TEST_DEPS_DIRS) ; do $(MAKE) -C $$dep; done
+endif
+
+ifneq ($(strip $(TEST_DIR)),)
+test-dir:
+ $(gen_verbose) erlc -v $(TEST_ERLC_OPTS) -I include/ -o $(TEST_DIR) \
+ $(wildcard $(TEST_DIR)/*.erl $(TEST_DIR)/*/*.erl) -pa ebin/
+endif
+
+ifeq ($(wildcard ebin/test),)
+test-build:: ERLC_OPTS=$(TEST_ERLC_OPTS)
+test-build:: clean deps test-deps
+ @$(MAKE) --no-print-directory app-build test-dir ERLC_OPTS="$(TEST_ERLC_OPTS)"
+ $(gen_verbose) touch ebin/test
+else
+test-build:: ERLC_OPTS=$(TEST_ERLC_OPTS)
+test-build:: deps test-deps
+ @$(MAKE) --no-print-directory app-build test-dir ERLC_OPTS="$(TEST_ERLC_OPTS)"
+endif
+
+clean:: clean-test-dir
+
+clean-test-dir:
+ifneq ($(wildcard $(TEST_DIR)/*.beam),)
+ $(gen_verbose) rm -f $(TEST_DIR)/*.beam
+endif