Просмотр исходного кода

Add NO_MAKEDEP: don't rebuild .d file if it already exists

This is useful only for projects that are stable and rarely
need to rebuild it. Check the guide additions for more info.
Loïc Hoguin 9 лет назад
Родитель
Сommit
6e50b405d7
3 измененных файлов с 130 добавлено и 1 удалено
  1. 2 0
      core/erlc.mk
  2. 20 0
      doc/src/guide/app.asciidoc
  3. 108 1
      test/Makefile

+ 2 - 0
core/erlc.mk

@@ -176,8 +176,10 @@ define makedep.erl
 	halt()
 endef
 
+ifeq ($(if $(NO_MAKEDEP),$(wildcard $(PROJECT).d),),)
 $(PROJECT).d:: $(ERL_FILES) $(call core_find,include/,*.hrl)
 	$(makedep_verbose) $(call erlang,$(call makedep.erl,$@))
+endif
 
 -include $(PROJECT).d
 

+ 20 - 0
doc/src/guide/app.asciidoc

@@ -235,6 +235,26 @@ transforms have changed. Erlang.mk also automatically keeps
 track of which files should be compiled first, for example
 when you have behaviors used by other modules in your project.
 
+If your project is stable, you may want to disable generating
+the dependency tracking file every time you compile. You can
+do this by adding the following line to your 'Makefile':
+
+[source,make]
+NO_MAKEDEP ?= 1
+
+As you can see, the snippet above uses `?=` instead of a
+simple equal sign. This is to allow you to temporarily override
+this value when you do make substantial changes to your project
+(including a new header file, new module with dependencies, etc.)
+and want to rebuild the dependency tracking file. You'll be
+able to use the following command:
+
+[source,bash]
+$ NO_MAKEDEP= make
+
+Otherwise, `make clean app` will of course force the
+recompilation of your project.
+
 Erlang.mk can also keep track of the source files generated
 by other means, for example if you generate code from a data
 file in your repository.

+ 108 - 1
test/Makefile

@@ -77,7 +77,7 @@ clean-core: clean-core-app clean-core-upgrade
 
 # Core: Building applications.
 
-CORE_APP_CASES = asn1 generate-erl generate-erl-include generate-erl-prepend hrl hrl-recursive mib xrl xrl-include yrl yrl-include
+CORE_APP_CASES = asn1 generate-erl generate-erl-include generate-erl-prepend hrl hrl-recursive mib no-makedep xrl xrl-include yrl yrl-include
 CORE_APP_TARGETS = $(addprefix core-app-,$(CORE_APP_CASES))
 CORE_APP_CLEAN_TARGETS = $(addprefix clean-,$(CORE_APP_TARGETS))
 
@@ -737,6 +737,113 @@ core-app-mib: build clean-core-app-mib
 		[{module, M} = code:load_file(M) || M <- Mods], \
 		halt()"
 
+core-app-no-makedep: build clean-core-app-no-makedep
+
+	$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 "Set NO_MAKEDEP ?= 1 in the Makefile"
+	$t sed -i '2iNO_MAKEDEP ?= 1' $(APP)/Makefile
+
+	$i "Generate .hrl files"
+	$t mkdir $(APP)/include/
+	$t touch $(APP)/include/blue.hrl $(APP)/include/red.hrl
+
+	$i "Generate .erl files dependent from headers"
+	$t printf "%s\n" "-module(use_blue)." "-include(\"blue.hrl\")." > $(APP)/src/use_blue.erl
+	$t printf "%s\n" "-module(use_red)." "-include(\"red.hrl\")." > $(APP)/src/use_red.erl
+
+	$i "Build the application"
+	$t $(MAKE) -C $(APP) $v
+
+	$i "Check that all compiled files exist"
+	$t test -f $(APP)/$(APP).d
+	$t test -f $(APP)/ebin/$(APP).app
+	$t test -f $(APP)/ebin/use_blue.beam
+	$t test -f $(APP)/ebin/use_red.beam
+
+	$i "Check that the application was compiled correctly"
+	$t $(ERL) -pa $(APP)/ebin/ -eval " \
+		ok = application:start($(APP)), \
+		{ok, Mods = [use_blue, use_red]} \
+			= application:get_key($(APP), modules), \
+		[{module, M} = code:load_file(M) || M <- Mods], \
+		halt()"
+
+	$i "Touch one .hrl file; check that only required files are rebuilt"
+# The use_red.erl gets touched because of its dependency to red.hrl.
+	$t printf "%s\n" \
+		$(APP)/ebin/$(APP).app \
+		$(APP)/ebin/use_red.beam \
+		$(APP)/src/use_red.erl | sort > $(APP)/EXPECT
+	$t touch $(APP)/include/red.hrl
+	$t $(MAKE) -C $(APP) $v
+	$t find $(APP) -type f -newer $(APP)/include/red.hrl | sort | diff $(APP)/EXPECT -
+	$t rm $(APP)/EXPECT
+
+	$i "Check that the application was compiled correctly"
+	$t $(ERL) -pa $(APP)/ebin/ -eval " \
+		ok = application:start($(APP)), \
+		{ok, Mods = [use_blue, use_red]} \
+			= application:get_key($(APP), modules), \
+		[{module, M} = code:load_file(M) || M <- Mods], \
+		halt()"
+
+	$i "Touch one .hrl file; disable NO_MAKEDEP and check that only required files are rebuilt"
+# The use_red.erl gets touched because of its dependency to red.hrl.
+	$t printf "%s\n" \
+		$(APP)/$(APP).d \
+		$(APP)/ebin/$(APP).app \
+		$(APP)/ebin/use_red.beam \
+		$(APP)/src/use_red.erl | sort > $(APP)/EXPECT
+	$t touch $(APP)/include/red.hrl
+	$t NO_MAKEDEP= $(MAKE) -C $(APP) $v
+	$t find $(APP) -type f -newer $(APP)/include/red.hrl | sort | diff $(APP)/EXPECT -
+	$t rm $(APP)/EXPECT
+
+	$i "Check that the application was compiled correctly"
+	$t $(ERL) -pa $(APP)/ebin/ -eval " \
+		ok = application:start($(APP)), \
+		{ok, Mods = [use_blue, use_red]} \
+			= application:get_key($(APP), modules), \
+		[{module, M} = code:load_file(M) || M <- Mods], \
+		halt()"
+
+	$i "Clean the application"
+	$t $(MAKE) -C $(APP) clean $v
+
+	$i "Check that source files still exist"
+	$t test -f $(APP)/Makefile
+	$t test -f $(APP)/erlang.mk
+	$t test -f $(APP)/include/blue.hrl
+	$t test -f $(APP)/include/red.hrl
+	$t test -f $(APP)/src/$(APP).app.src
+	$t test -f $(APP)/src/use_blue.erl
+	$t test -f $(APP)/src/use_red.erl
+
+	$i "Check that all build artifacts are removed"
+	$t test ! -e $(APP)/$(APP).d
+	$t test ! -e $(APP)/ebin/
+
+	$i "Build the application again"
+	$t $(MAKE) -C $(APP) $v
+
+	$i "Check that all compiled files exist"
+	$t test -f $(APP)/$(APP).d
+	$t test -f $(APP)/ebin/$(APP).app
+	$t test -f $(APP)/ebin/use_blue.beam
+	$t test -f $(APP)/ebin/use_red.beam
+
+	$i "Check that the application was compiled correctly"
+	$t $(ERL) -pa $(APP)/ebin/ -eval " \
+		ok = application:start($(APP)), \
+		{ok, Mods = [use_blue, use_red]} \
+			= application:get_key($(APP), modules), \
+		[{module, M} = code:load_file(M) || M <- Mods], \
+		halt()"
+
 core-app-xrl: build clean-core-app-xrl
 
 	$i "Bootstrap a new OTP library named $(APP)"