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 <p...@peff.net>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to