--- a/make/common/ZipArchive.gmk Mon Aug 05 15:29:09 2019 +0200
+++ b/make/common/ZipArchive.gmk Mon Aug 05 07:59:42 2019 -0700
@@ -54,14 +54,17 @@
SetupZipArchive = $(NamedParamsMacroTemplate)
define SetupZipArchiveBody
+ # Create a version $1_SRC with a guaranteed trailing slash
+ $1_SRC_SLASH := $$(addsuffix /, $$(patsubst %/, %, $$($1_SRC)))
+
# To avoid running find over too large sets of files, which causes make to crash
# on some configurations (cygwin), use INCLUDES and INCLUDE_FILES to build a set
# of directories to run find in, if available.
ifneq ($$($1_INCLUDES)$$($1_INCLUDE_FILES),)
- $1_FIND_LIST := $$(wildcard $$(foreach i,$$($1_SRC), \
- $$(addprefix $$i/,$$($1_INCLUDES) $$($1_INCLUDE_FILES))))
+ $1_FIND_LIST := $$(wildcard $$(foreach s,$$($1_SRC_SLASH), \
+ $$(addprefix $$s,$$($1_INCLUDES) $$($1_INCLUDE_FILES))))
else
- $1_FIND_LIST := $$($1_SRC)
+ $1_FIND_LIST := $$($1_SRC_SLASH)
endif
# Find all files in the source tree.
@@ -96,15 +99,15 @@
endif
ifneq ($$($1_EXCLUDES),)
$1_ZIP_EXCLUDES := $$(addprefix -x$(SPACE)$(DQUOTE),$$(addsuffix /*$(DQUOTE),$$($1_EXCLUDES)))
- $1_SRC_EXCLUDES := $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$(addsuffix /%,$$($1_EXCLUDES))))
+ $1_SRC_EXCLUDES := $$(foreach s,$$($1_SRC_SLASH),$$(addprefix $$s,$$(addsuffix /%,$$($1_EXCLUDES))))
$1_ALL_SRCS := $$(filter-out $$($1_SRC_EXCLUDES),$$($1_ALL_SRCS))
endif
ifneq ($$($1_EXCLUDE_FILES),)
$1_SRC_EXCLUDE_FILES := $$(addprefix %, $$($1_EXCLUDE_FILES)) $$($1_EXCLUDE_FILES)
$1_ALL_SRCS := $$(filter-out $$($1_SRC_EXCLUDE_FILES), $$($1_ALL_SRCS))
- $$(foreach s, $$($1_SRC), \
+ $$(foreach s, $$($1_SRC_SLASH), \
$$(eval $1_ZIP_EXCLUDES_$$s += \
- $$(addprefix -x$$(SPACE), $$(patsubst $$s/%,%, $$($1_EXCLUDE_FILES))) \
+ $$(addprefix -x$$(SPACE), $$(patsubst $$s%,%, $$($1_EXCLUDE_FILES))) \
) \
)
endif
@@ -113,7 +116,7 @@
$1_ZIP_EXCLUDES += $$(addprefix -x$(SPACE), $$(subst %,\*,$$($1_EXCLUDE_PATTERNS)))
endif
# Rewrite src dir specific exclude patterns to zip excludes
- $$(foreach s, $$($1_SRC), \
+ $$(foreach s, $$($1_SRC_SLASH), \
$$(if $$($1_EXCLUDE_PATTERNS_$$s), \
$$(eval $1_ZIP_EXCLUDES_$$s += \
$$(addprefix -x$$(SPACE), $$(subst %,\*,$$($1_EXCLUDE_PATTERNS_$$s))) \
@@ -134,7 +137,26 @@
$$($1_ZIP) : $$($1_ALL_SRCS) $$($1_EXTRA_DEPS)
$$(call LogWarn, Updating $$($1_NAME))
$$(call MakeTargetDir)
- $$(foreach s,$$($1_SRC), $$(call ExecuteWithLog, \
+ # Find duplicate file names in the SRC and generate excludes for all
+ # instances that should not be included. Run this rather expensive
+ # calculation as part of the recipe to avoid running it when nothing
+ # needs to be rebuilt. The drawback is that we cannot exclude these
+ # files from the make prerequisites list, but the number of files is
+ # usually small so a very rare unnecessary rebuild is worth it.
+ # (The inner most foreach here is used instead of eval to declare a
+ # local variable.)
+ $$(foreach root, $$($1_SRC_SLASH), \
+ $$(foreach file, $$(filter $$(root)%, $$($1_ALL_SRCS)), \
+ $$(foreach relfile, $$(patsubst $$(root)%, %, $$(file)), \
+ $$(if $$($1_relfiles_$$(call DoubleDollar, $$(relfile))), \
+ $$(eval $1_ZIP_EXCLUDES_$$(root) += -x $$(relfile)) \
+ , \
+ $$(eval $1_relfiles_$$(call DoubleDollar, $$(relfile)) := 1) \
+ ) \
+ ) \
+ ) \
+ )
+ $$(foreach s,$$($1_SRC_SLASH), $$(call ExecuteWithLog, \
$$(SUPPORT_OUTPUTDIR)/zip/$$(patsubst $$(OUTPUTDIR)/%,%, $$@), \
(cd $$s && $(ZIPEXE) -qru $$($1_ZIP_OPTIONS) $$@ . \
$$($1_ZIP_INCLUDES) $$($1_ZIP_EXCLUDES) -x \*_the.\* \