OSDN Git Service

Work around make 3.80 bug with long expansions of $(eval).
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Nov 2010 17:50:06 +0000 (12:50 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Nov 2010 17:50:06 +0000 (12:50 -0500)
3.80 breaks if the expansion of $(eval) is long enough to require expansion
of its internal variable_buffer.  For the purposes of $(recurse) that means
it'll work so long as no single evaluation of _create_recursive_target
produces more than 195 bytes.  We can manage that by looping over
subdirectories outside the call instead of complicating the generated rule.
This coding is simpler and more readable anyway.

Or at least, this works for me.  We'll see if the buildfarm likes it.

src/Makefile.global.in

index d290116..cb5f31c 100644 (file)
@@ -549,37 +549,38 @@ install-strip:
 # allows parallel make across directories and lets make -k and -q work
 # correctly.
 
+# We need the $(eval) function and order-only prerequisites, which are
+# available in GNU make 3.80.  That also happens to be the version
+# where the .VARIABLES variable was introduced, so this is a simple check.
+ifndef .VARIABLES
+$(error GNU make 3.80 or newer is required.  You are using version $(MAKE_VERSION))
+endif
+
 # This function is only for internal use below.  It should be called
-# with $(eval).  It will set up a target so that it recurses into
-# subdirectories.
+# using $(eval).  It will set up a target so that it recurses into
+# a given subdirectory.  Note that to avoid a nasty bug in make 3.80,
+# it is important that the expansion of this function not exceed about
+# 200 bytes.  This is why we make it apply to just one subdirectory at a
+# time, rather than to a list of subdirectories.
 # $1: target name, e.g., all
-# $2: list of subdirs
+# $2: subdir name
 # $3: target to run in subdir, usually same as $1
 define _create_recursive_target
-.PHONY: $(patsubst %,$(1)-%-recursive,$(2))
-$(1): $(patsubst %,$(1)-%-recursive,$(2))
-$(2:%=$(1)-%-recursive):
-       $$(MAKE) -C $$(patsubst $(1)-%-recursive,%,$$@) $(3)
+.PHONY: $(1)-$(2)-recurse
+$(1): $(1)-$(2)-recurse
+$(1)-$(2)-recurse:
+       $$(MAKE) -C $(2) $(3)
 endef
 # Note that the use of $$ on the last line above is important; we want
-# those variables/functions to be evaluated when the rule is run, not
-# when the $(eval) is run to create the rule.  In the case of
-# $$(MAKE), this is necessary to get make -q working.
+# $(MAKE) to be evaluated when the rule is run, not when the $(eval) is run
+# to create the rule.  This is necessary to get make -q working.
 
-# Call this function in a makefile.  In the normal case it doesn't
-# need any arguments.
+# Call this function in a makefile that needs to recurse into subdirectories.
+# In the normal case all arguments can be defaulted.
 # $1: targets to make recursive (defaults to list of standard targets)
 # $2: list of subdirs (defaults to SUBDIRS variable)
-# $3: target to run in subdir (defaults to $1)
-recurse = $(foreach target,$(if $1,$1,$(standard_targets)),$(eval $(call _create_recursive_target,$(target),$(if $2,$2,$(SUBDIRS)),$(if $3,$3,$(target)))))
-
-# We need the $(eval) function and order-only prerequisites, which are
-# available in GNU make 3.80.  That also happens to be the version
-# where the .VARIABLES variable was introduced, so this is a simple
-# check.
-ifndef .VARIABLES
-$(error GNU make 3.80 or newer is required.  You are using version $(MAKE_VERSION))
-endif
+# $3: target to run in subdir (defaults to current element of $1)
+recurse = $(foreach target,$(if $1,$1,$(standard_targets)),$(foreach subdir,$(if $2,$2,$(SUBDIRS)),$(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target))))))
 
 
 ##########################################################################