It's a common pattern in our Makefile to echo some make variables into a file, but only if they are different from a previous run. This sentinel file can then be used as a dependency to trigger rebuilds when the make variable changes. The code to do this is a bit ugly and repetetive; let's factor it out into a reusable function. Note that this relies on the "call" and "eval" functions of GNU make. We previously avoided using "call", as explained in 39c015c (Fixes for ancient versions of GNU make, 2006-02-18). However, it has been 8 years since then, so perhaps its use is acceptable now. The "call" function dates back to GNU make 3.77.90 (1997-07-21). The "eval" function dates back to 3.80 (2002-07-08). If it's still a problem to use these functions, we can do similar meta-programming with something like: include magic.mak magic.mak: ./generate-magic-rules >$@+ mv $@+ $@ where the rules are generated by a shell (or other) script. Signed-off-by: Jeff King <peff@xxxxxxxx> --- Makefile | 105 ++++++++++++++++++++++++--------------------------------------- 1 file changed, 40 insertions(+), 65 deletions(-) diff --git a/Makefile b/Makefile index 1f3e5d9..50bf252 100644 --- a/Makefile +++ b/Makefile @@ -1561,6 +1561,20 @@ ifneq ("$(PROFILE)","") endif endif +# usage: $(eval $(call make-var,FN,DESC,CONTENTS)) +# +# Create a rule to write $CONTENTS (which should come from a make variable) +# to GIT-$FN, but only if not already there. This can be used to create a +# dependency on a Makefile variable. Prints $DESC to the user. +define make-var +GIT-$1: FORCE + @VALUE='$$(subst ','\'',$3)'; \ + if test x"$$$$VALUE" != x"`cat $$@ 2>/dev/null`"; then \ + echo >&2 " * new $2"; \ + echo "$$$$VALUE" >$$@; \ + fi +endef + # Shell quote (do not use $(call) to accommodate ancient setups); SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER)) @@ -1615,13 +1629,9 @@ SHELL_PATH_CQ_SQ = $(subst ','\'',$(SHELL_PATH_CQ)) BASIC_CFLAGS += -DSHELL_PATH='$(SHELL_PATH_CQ_SQ)' endif -GIT_USER_AGENT_SQ = $(subst ','\'',$(GIT_USER_AGENT)) GIT_USER_AGENT_CQ = "$(subst ",\",$(subst \,\\,$(GIT_USER_AGENT)))" GIT_USER_AGENT_CQ_SQ = $(subst ','\'',$(GIT_USER_AGENT_CQ)) -GIT-USER-AGENT: FORCE - @if test x'$(GIT_USER_AGENT_SQ)' != x"`cat GIT-USER-AGENT 2>/dev/null`"; then \ - echo '$(GIT_USER_AGENT_SQ)' >GIT-USER-AGENT; \ - fi +$(eval $(call make-var,USER-AGENT,user agent string,$(GIT_USER_AGENT))) ifdef DEFAULT_HELP_FORMAT BASIC_CFLAGS += -DDEFAULT_HELP_FORMAT='"$(DEFAULT_HELP_FORMAT)"' @@ -1737,9 +1747,17 @@ common-cmds.h: ./generate-cmdlist.sh command-list.txt common-cmds.h: $(wildcard Documentation/git-*.txt) $(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@ -SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\ - $(localedir_SQ):$(NO_CURL):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\ - $(gitwebdir_SQ):$(PERL_PATH_SQ) +$(eval $(call make-var,SCRIPT-DEFINES,script parameters,\ + :$(SHELL_PATH)\ + :$(DIFF)\ + :$(GIT_VERSION)\ + :$(localedir)\ + :$(NO_CURL)\ + :$(USE_GETTEXT_SCHEME)\ + :$(SANE_TOOL_PATH)\ + :$(gitwebdir)\ + :$(PERL_PATH)\ +)) define cmd_munge_script $(RM) $@ $@+ && \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ @@ -1754,14 +1772,6 @@ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ $@.sh >$@+ endef -GIT-SCRIPT-DEFINES: FORCE - @FLAGS='$(SCRIPT_DEFINES)'; \ - if test x"$$FLAGS" != x"`cat $@ 2>/dev/null`" ; then \ - echo >&2 " * new script parameters"; \ - echo "$$FLAGS" >$@; \ - fi - - $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh GIT-SCRIPT-DEFINES $(QUIET_GEN)$(cmd_munge_script) && \ chmod +x $@+ && \ @@ -1789,7 +1799,10 @@ perl/PM.stamp: FORCE perl/perl.mak: GIT-CFLAGS GIT-PREFIX perl/Makefile perl/Makefile.PL $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F) -PERL_DEFINES = $(PERL_PATH_SQ):$(PERLLIB_EXTRA_SQ) +$(eval $(call make-var,PERL-DEFINES,perl-specific parameters,\ + :$(PERL_PATH)\ + :$(PERLLIB_EXTRA)\ +)) $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl perl/perl.mak GIT-PERL-DEFINES GIT-VERSION-FILE $(QUIET_GEN)$(RM) $@ $@+ && \ INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \ @@ -1807,14 +1820,6 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl perl/perl.mak GIT-PERL-DEFINES G chmod +x $@+ && \ mv $@+ $@ -GIT-PERL-DEFINES: FORCE - @FLAGS='$(PERL_DEFINES)'; \ - if test x"$$FLAGS" != x"`cat $@ 2>/dev/null`" ; then \ - echo >&2 " * new perl-specific parameters"; \ - echo "$$FLAGS" >$@; \ - fi - - .PHONY: gitweb gitweb: $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) all @@ -1835,6 +1840,7 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)) git-instaweb: % : unimplemented.sh endif # NO_PERL ifndef NO_PYTHON +$(eval $(call make-var,PYTHON-VARS,Python interpreter location,$(PYTHON_PATH))) $(SCRIPT_PYTHON_GEN): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS $(SCRIPT_PYTHON_GEN): % : %.py $(QUIET_GEN)$(RM) $@ $@+ && \ @@ -2154,34 +2160,15 @@ cscope: $(RM) cscope* $(FIND_SOURCE_FILES) | xargs cscope -b -### Detect prefix changes -TRACK_PREFIX = $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\ - $(localedir_SQ) - -GIT-PREFIX: FORCE - @FLAGS='$(TRACK_PREFIX)'; \ - if test x"$$FLAGS" != x"`cat GIT-PREFIX 2>/dev/null`" ; then \ - echo >&2 " * new prefix flags"; \ - echo "$$FLAGS" >GIT-PREFIX; \ - fi - -TRACK_CFLAGS = $(CC):$(subst ','\'',$(ALL_CFLAGS)) - -GIT-CFLAGS: FORCE - @FLAGS='$(TRACK_CFLAGS)'; \ - if test x"$$FLAGS" != x"`cat GIT-CFLAGS 2>/dev/null`" ; then \ - echo >&2 " * new build flags"; \ - echo "$$FLAGS" >GIT-CFLAGS; \ - fi - -TRACK_LDFLAGS = $(subst ','\'',$(ALL_LDFLAGS)) - -GIT-LDFLAGS: FORCE - @FLAGS='$(TRACK_LDFLAGS)'; \ - if test x"$$FLAGS" != x"`cat GIT-LDFLAGS 2>/dev/null`" ; then \ - echo >&2 " * new link flags"; \ - echo "$$FLAGS" >GIT-LDFLAGS; \ - fi +$(eval $(call make-var,PREFIX,prefix flags,\ + :$(bindir)\ + :$(gitexecdir)\ + :$(template_dir)\ + :$(prefix)\ + :$(localedir)\ +)) +$(eval $(call make-var,CFLAGS,build flags,$(ALL_CFLAGS))) +$(eval $(call make-var,LDFLAGS,link flags,$(ALL_LDFLAGS))) # We need to apply sq twice, once to protect from the shell # that runs GIT-BUILD-OPTIONS, and then again to protect it @@ -2224,18 +2211,6 @@ ifdef GIT_PERF_MAKE_OPTS @echo GIT_PERF_MAKE_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_MAKE_OPTS)))'\' >>$@ endif -### Detect Python interpreter path changes -ifndef NO_PYTHON -TRACK_PYTHON = $(subst ','\'',-DPYTHON_PATH='$(PYTHON_PATH_SQ)') - -GIT-PYTHON-VARS: FORCE - @VARS='$(TRACK_PYTHON)'; \ - if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \ - echo >&2 " * new Python interpreter location"; \ - echo "$$VARS" >$@; \ - fi -endif - test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X)) all:: $(TEST_PROGRAMS) $(test_bindir_programs) -- 1.8.5.2.500.g8060133 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html