Browse Source

Accept `$(force_rebuilding_dep)` to tune the behavior of `$(FULL)`

By default, Erlang.mk only builds dependencies once, the first time the
top-level project is compiled. A forced rebuild of all dependencies can
be forced by setting the `$(FULL)` variable to a non-empty value.

For developers working on the top-level project and one or more
dependencies at the same time, Erlang.mk now accepts a variable/function
called `$(force_rebuilding_dep)` which is called to determine if the
dependency passed as the first argument should be forcibly rebuilt.

It allows a developer to filter the dependencies he works on (so they
are always rebuilt) from other third-party dependencies he never touches
(i.e. they are only built once at the beginning).

The content of `$(force_rebuilding_dep)` is expected to be a shell
one-liner where the `$(1)` Make variable is set to the path to the
dependency.

Here is an example from the testsuite:

    force_rebuilding_dep = test '$(1)' = '$(CURDIR)/deps/cowlib'
Jean-Sébastien Pédron 5 years ago
parent
commit
87cba23745
2 changed files with 37 additions and 1 deletions
  1. 1 1
      core/deps.mk
  2. 36 0
      test/core_deps.mk

+ 1 - 1
core/deps.mk

@@ -130,7 +130,7 @@ ifneq ($(ALL_DEPS_DIRS),)
 			:; \
 		else \
 			echo $$dep >> $(ERLANG_MK_TMP)/deps.log; \
-			if [ -z "$(strip $(FULL))" ] && [ ! -L $$dep ] && [ -f $$dep/ebin/dep_built ]; then \
+			if [ -z "$(strip $(FULL))" ] $(if $(force_rebuilding_dep),&& ($(call force_rebuilding_dep,$$dep)),) && [ ! -L $$dep ] && [ -f $$dep/ebin/dep_built ]; then \
 				:; \
 			elif [ -f $$dep/GNUmakefile ] || [ -f $$dep/makefile ] || [ -f $$dep/Makefile ]; then \
 				$(MAKE) -C $$dep IS_DEP=1; \

+ 36 - 0
test/core_deps.mk

@@ -174,6 +174,42 @@ core-deps-dep-built-full: init
 	$t find $(APP)/deps/cowlib -type f -newer $(APP)/EXPECT | grep -v ".git" | sort | diff $(APP)/EXPECT -
 	$t rm $(APP)/EXPECT
 
+core-deps-dep-built-force-full: init
+
+	$i "Bootstrap a new OTP library named $(APP)"
+	$t mkdir $(APP)/
+	$t cp ../erlang.mk $(APP)/
+	$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
+
+	$i "Add cowlib to the list of dependencies"
+	$t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\n"}' $(APP)/Makefile
+
+	$i "Build the application"
+	$t $(MAKE) -C $(APP) $v
+
+	$i "Touch one cowlib file to mark it for recompilation"
+	$t $(SLEEP)
+	$t touch $(APP)/deps/cowlib/src/cow_http.erl
+
+	$i "Check that cowlib is not rebuilt if \`force_rebuilding_dep\` returns false"
+	$t touch $(APP)/EXPECT
+	$t $(SLEEP)
+	$t $(MAKE) -C $(APP) force_rebuilding_dep='test $$(1) != $(APP)/deps/cowlib' $v
+	$t find $(APP)/deps/cowlib -type f -newer $(APP)/EXPECT | sort | diff $(APP)/EXPECT -
+	$t rm $(APP)/EXPECT
+
+	$i "Check that cowlib is rebuilt if \`force_rebuilding_dep\` returns true"
+	$t printf "%s\n" \
+		$(APP)/deps/cowlib/cowlib.d \
+		$(APP)/deps/cowlib/ebin/cowlib.app \
+		$(APP)/deps/cowlib/ebin/cow_http.beam \
+		$(APP)/deps/cowlib/ebin/dep_built | sort > $(APP)/EXPECT
+	$t $(SLEEP)
+	$t $(MAKE) -C $(APP) force_rebuilding_dep='test $$(1) = $(APP)/deps/cowlib' $v
+# Files in .git might end up modified due to the id generation in the .app file.
+	$t find $(APP)/deps/cowlib -type f -newer $(APP)/EXPECT | grep -v ".git" | sort | diff $(APP)/EXPECT -
+	$t rm $(APP)/EXPECT
+
 core-deps-dep-built-ln: init
 
 	$i "Bootstrap a new OTP library named $(APP)"