{"thread":{"id":"56852","subject":"[PATCH 00/16] Makefiles: dependency correctness & speedup","startedAt":"2021-11-06T21:03:24Z","lastAt":"2021-12-14T00:31:08Z","messageCount":107,"participants":["Ævar Arnfjörð Bjarmason","Eric Sunshine","Junio C Hamano","Mike Hommey"],"isPatch":true,"patchVersion":1,"patchTotal":16},"messages":[{"id":"440589","messageId":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":null,"subject":"[PATCH 00/16] Makefiles: dependency correctness & speedup","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:01Z","receivedAt":"2021-11-06T21:03:24Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This is a series to correct various issues in the Makefile. This goes\non top of my ab/sh-retire-helper-functions sitting in \"next\".\n\nLet's drop the other outstanding Makefile[1] series I have for now\n(not picked up anyway). Unlike that one this is purely Makefile fixes,\nand no breakage or change in CMake behavior etc.\n\nInline comments below:\n\nÆvar Arnfjörð Bjarmason (16):\n  Makefile: don't set up \"perl/build\" rules under NO_PERL=Y\n  Makefile: clean perl/build/ even with NO_PERL=Y\n  Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR\n  Makefile: move Perl-only variable assignments under !NO_PERL\n  Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph\n  Makefile: don't have Perl over-depend on GIT-BUILD-OPTIONS\n  Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"\n\nVarious fixes for Perl dependency issues, and eventual alignment of\nhow we generrate the \"DEFINES\" file for Perl and Python. These are\nstraightforward follow-ups to the Makefile parts of\nab/sh-retire-helper-functions, just for *.perl and *.py instead of\n*.sh.\n\n  Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts\n\nBy not substituting @@GIT_VERSION@@ in the *.perl scripts we don't\nneed to re-build them every time HEAD changes.\n\n  Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it\n\nCreate a shared.mak, to be used by all in-tree Makefiles, to define\ncommon utilities etc.\n\n  Makefile: move $(comma), $(empty) and $(space) to shared.mak\n  Makefile: re-add and use the \"shellquote\" macros\n\nOur quoting is really ugly in Makefiles. This resurrects a 2005-era\ncommit from Junio to make it better, then it relied on GNU make\nfeatures that were too new, but we already hard depend on versions\nolder than that now, so...\n\n  Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}\n\nSince we can use $(call) let's use it to get rid of this particularly\negregious case of copy/pasting...\n\n  Makefile: add \"$(QUIET)\" boilerplate to shared.mak\n  Makefile: use $(wspfx) for $(QUIET...) in shared.mak\n\n...and the $(QUIET) copy/pasting...\n\n  Makefiles: add and use wildcard \"mkdir -p\" template\n\nOptimizes a recent \"mkdir -p\" pattern I added for speed and\nreadability.\n\n  Makefile: don't invoke msgfmt with --statistics\n\nMiscellaneous small output fix tacked at the end.\n\n1. https://lore.kernel.org/git/xmqqtugr3l4r.fsf@gitster.g/T/#m1ab315e3dbb323427d373d1fcee4534b67d6a6dd\n\n .gitignore             |   2 +-\n Documentation/Makefile |  71 ++----------\n Makefile               | 238 +++++++++++++----------------------------\n config.mak.uname       |   1 -\n git-cvsserver.perl     |   6 +-\n git-send-email.perl    |   7 +-\n git-svn.perl           |   2 +-\n shared.mak             | 113 +++++++++++++++++++\n t/Makefile             |  34 +++---\n templates/Makefile     |  19 +---\n 10 files changed, 222 insertions(+), 271 deletions(-)\n create mode 100644 shared.mak\n\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440590","messageId":"patch-02.16-2d8049f792c-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 02/16] Makefile: clean perl/build/ even with NO_PERL=Y","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:03Z","receivedAt":"2021-11-06T21:03:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a regression in 499c29394ce (Makefile: allow building without\nperl, 2009-04-03) where we'd stop cleaning the perl/* directory\nbecause NO_PERL was defined, thus leaving behind litter if the flag at\n\"clean\" time didn't match that of build time.\n\nIn 499c29394ce this was done to avoid relying on the perl/Makefile.PL,\nbut since my 20d2a30f8ff (Makefile: replace perl/Makefile.PL with\nsimple make rules, 2017-12-10) we can clean things in that directory\nunconditionally.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex 9f57c34e954..82eb8ea446b 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -3234,6 +3234,7 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) $(HCC)\n \t$(RM) -r bin-wrappers $(dep_dirs) $(compdb_dir) compile_commands.json\n \t$(RM) -r po/build/\n+\t$(RM) -r perl/build/\n \t$(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope*\n \t$(RM) -r .dist-tmp-dir .doc-tmp-dir\n \t$(RM) $(GIT_TARNAME).tar.gz\n@@ -3242,7 +3243,6 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) Documentation/GIT-EXCLUDED-PROGRAMS\n ifndef NO_PERL\n \t$(MAKE) -C gitweb clean\n-\t$(RM) -r perl/build/\n endif\n \t$(MAKE) -C templates/ clean\n \t$(MAKE) -C t/ clean\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440591","messageId":"patch-01.16-56acc94dfe7-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 01/16] Makefile: don't set up \"perl/build\" rules under NO_PERL=Y","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:02Z","receivedAt":"2021-11-06T21:03:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Do not define LIB_{PERL,CPAN}{,_GEN} if NO_PERL is defined. This\nchanges no functionality, but makes it clear which of these rules are\nneeded under NO_PERL=Y. See 20d2a30f8ff (Makefile: replace\nperl/Makefile.PL with simple make rules, 2017-12-10) for the initial\nimplementation.\n\nWe do for better or worse rely on \"install-doc\" calling\n\"install-man-perl\" regardless of whether NO_PERL=Y is defined or not,\ni.e. we'll always end up with that manual page, even if we don't have\nany of the Perl code installed. Let's add a comment about that\nadjacent to the rules that build perl/build.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 17 +++++++++--------\n 1 file changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex d56c0e4aadc..9f57c34e954 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2684,19 +2684,12 @@ endif\n po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n \t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n \n+ifndef NO_PERL\n LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n-ifndef NO_PERL\n-all:: $(LIB_PERL_GEN)\n-ifndef NO_PERL_CPAN_FALLBACKS\n-all:: $(LIB_CPAN_GEN)\n-endif\n-NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n-endif\n-\n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n@@ -2704,6 +2697,14 @@ perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \\\n \t< $< > $@\n \n+all:: $(LIB_PERL_GEN)\n+ifndef NO_PERL_CPAN_FALLBACKS\n+all:: $(LIB_CPAN_GEN)\n+endif\n+NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n+endif\n+\n+# install-man depends on Git.3pm even with NO_PERL=Y\n perl/build/man/man3/Git.3pm: perl/Git.pm\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tpod2man $< $@\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440592","messageId":"patch-03.16-fa2f10a0cd1-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 03/16] Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:04Z","receivedAt":"2021-11-06T21:03:32Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Since 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\" flag,\n2021-06-29) we don't need to guard the clobbering of $@ with this sort\nof \"mv $@+ $@\" pattern in these cases where we're merely generating a\nfile that'll be used as a dependency for other files, as in this case\nfor GIT-PERL-HEADER.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 82eb8ea446b..009b08152b5 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2349,8 +2349,7 @@ GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n \t    -e 's=@@PERLLIBDIR_REL@@=$(perllibdir_relative_SQ)=g' \\\n \t    -e 's=@@GITEXECDIR_REL@@=$(gitexecdir_relative_SQ)=g' \\\n \t    -e 's=@@LOCALEDIR_REL@@=$(localedir_relative_SQ)=g' \\\n-\t    $< >$@+ && \\\n-\tmv $@+ $@\n+\t    $< >$@\n \n .PHONY: perllibdir\n perllibdir:\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440594","messageId":"patch-04.16-5affe94b05f-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 04/16] Makefile: move Perl-only variable assignments under !NO_PERL","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:05Z","receivedAt":"2021-11-06T21:03:38Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move the assignment to perl_localedir_SQ to be guarded by NO_PERL, and\nfurthermore only assign to it if RUNTIME_PREFIX is in effect. If the\nlatter isn't being used then we'll default to the empty string, so\nthere was no need for the second assignment added in\n07d90eadb50 (Makefile: add Perl runtime prefix support, 2018-04-10).\n\nSimilarly, we can move the PERL_HEADER_TEMPLATE assignment inside the\n\"!NO_PERL\" block, and having simplified all of this let's consolidate\nthree comments on this control flow into one.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 20 +++++++-------------\n 1 file changed, 7 insertions(+), 13 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 009b08152b5..fd4fe6c1045 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2291,12 +2291,7 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n # This makes sure we depend on the NO_PERL setting itself.\n $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n-# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n-# since the locale directory is injected.\n-perl_localedir_SQ = $(localedir_SQ)\n-\n ifndef NO_PERL\n-PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n PERL_DEFINES =\n PERL_DEFINES += $(PERL_PATH_SQ)\n PERL_DEFINES += $(PERLLIB_EXTRA_SQ)\n@@ -2305,16 +2300,15 @@ PERL_DEFINES += $(RUNTIME_PREFIX)\n PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n PERL_DEFINES += $(NO_GETTEXT)\n \n-# Support Perl runtime prefix. In this mode, a different header is installed\n-# into Perl scripts.\n+# Under RUNTIME_PREFIX we inject a header into the Perl scripts; If\n+# NO_GETTEXT is not defined we'll make use of the localedir.\n ifdef RUNTIME_PREFIX\n-\n PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n-\n-# Don't export a fixed $(localedir) path; it will be resolved by the Perl header\n-# at runtime.\n-perl_localedir_SQ =\n-\n+ifndef NO_GETTEXT\n+perl_localedir_SQ = $(localedir_SQ)\n+endif\n+else\n+PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n endif\n \n PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440593","messageId":"patch-05.16-d8e14cb723d-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 05/16] Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:06Z","receivedAt":"2021-11-06T21:03:39Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix several small issues with the dependency graph of the generated\n\"GIT-PERL-DEFINES\" and \"GIT-PERL-HEADER\" files:\n\n1. Folllow-up my 4070c9e09fc (Makefile: don't re-define PERL_DEFINES,\n   2021-05-05) and move the rest of the assignments to PERL_DEFINES to\n   one place, and change it from depending on \"localedir_relative_SQ\"\n   instead of \"localedir\".\n\n   The former is what we'll actually use, and while it's unlikely to\n   matter in practice (we'd just skip re-building these under\n   RUNTIME_PREFIX if the relative path was the same) it makes it\n   clearer what's going on here by bringing us to a 1=1 mapping of\n   these variables and what's subsequently used in the\n   \"GIT-PERL-DEFINES\", \"GIT-PERL-HEADER\" and \"perl/build/lib/%.pm\"\n   rules below.\n\n2. We don't need the substitution of \" \" for \":\" added in\n   07d90eadb50 (Makefile: add Perl runtime prefix support, 2018-04-10),\n   let's drop it. This doesn't matter for the correctness of these files,\n   but makes it clear  that (unlike GIT-BUILD-OPTIONS) they are not\n\n3. Don't have \"GIT-PERL-HEADER\" depend on the \"Makefile\". That was a\n   lazy way to over-declare the dependencies added in\n   f6a0ad4be71 (Makefile: generate Perl header from template file,\n   2018-04-10), now that our dependency graph is correct we can be\n   confident in dropping it.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex fd4fe6c1045..181dc52f152 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2293,6 +2293,9 @@ $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n ifndef NO_PERL\n PERL_DEFINES =\n+PERL_DEFINES += $(gitexecdir_relative_SQ)\n+PERL_DEFINES += $(perllibdir_relative_SQ)\n+PERL_DEFINES += $(localedir_relative_SQ)\n PERL_DEFINES += $(PERL_PATH_SQ)\n PERL_DEFINES += $(PERLLIB_EXTRA_SQ)\n PERL_DEFINES += $(perllibdir_SQ)\n@@ -2311,8 +2314,6 @@ else\n PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n endif\n \n-PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n-\n $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \t$(QUIET_GEN) \\\n \tsed -e '1{' \\\n@@ -2325,7 +2326,6 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n-PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n GIT-PERL-DEFINES: FORCE\n \t@FLAGS='$(PERL_DEFINES)'; \\\n \t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n@@ -2333,7 +2333,7 @@ GIT-PERL-DEFINES: FORCE\n \t\techo \"$$FLAGS\" >$@; \\\n \t    fi\n \n-GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n+GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES\n \t$(QUIET_GEN) \\\n \tINSTLIBDIR='$(perllibdir_SQ)' && \\\n \tINSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \\\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440595","messageId":"patch-06.16-03290125c45-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 06/16] Makefile: don't have Perl over-depend on GIT-BUILD-OPTIONS","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:07Z","receivedAt":"2021-11-06T21:03:40Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the dependency on \"GIT-BUILD-OPTIONS\" used by\ne.g. \"git-send-email\" to be on \"GIT-PERL-DEFINES instead.\n\nThe reason for depending on \"GIT-BUILD-OPTIONS\" was to trigger a\nre-build if NO_PERL=Y was defined, we can instead add that variable to\n\"PERL_DEFINES\", and have \"GIT-PERL-DEFINES\" created and updated if\n\"NO_PERL=Y\" is defined.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 40 +++++++++++++++++++++-------------------\n 1 file changed, 21 insertions(+), 19 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 181dc52f152..354136e30d1 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2288,11 +2288,21 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n \t    $(shell echo $(GIT_VERSION) 0 0 0 0 | tr '.a-zA-Z-' ' '))) \\\n \t  -DGIT_VERSION=\"\\\\\\\"$(GIT_VERSION)\\\\\\\"\" -i $< -o $@\n \n-# This makes sure we depend on the NO_PERL setting itself.\n-$(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n-\n-ifndef NO_PERL\n+# Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n+# on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n PERL_DEFINES =\n+$(SCRIPT_PERL_GEN): GIT-PERL-DEFINES\n+ifdef NO_PERL\n+PERL_DEFINES += $(NO_PERL)\n+\n+$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n+\t$(QUIET_GEN) \\\n+\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n+\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n+\t    unimplemented.sh >$@+ && \\\n+\tchmod +x $@+ && \\\n+\tmv $@+ $@\n+else\n PERL_DEFINES += $(gitexecdir_relative_SQ)\n PERL_DEFINES += $(perllibdir_relative_SQ)\n PERL_DEFINES += $(localedir_relative_SQ)\n@@ -2326,13 +2336,6 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n-GIT-PERL-DEFINES: FORCE\n-\t@FLAGS='$(PERL_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new perl-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n-\n GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES\n \t$(QUIET_GEN) \\\n \tINSTLIBDIR='$(perllibdir_SQ)' && \\\n@@ -2357,16 +2360,15 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \t$(QUIET_GEN)$(cmd_munge_script) && \\\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n-else # NO_PERL\n-$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n-\t$(QUIET_GEN) \\\n-\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n-\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n-\t    unimplemented.sh >$@+ && \\\n-\tchmod +x $@+ && \\\n-\tmv $@+ $@\n endif # NO_PERL\n \n+GIT-PERL-DEFINES: FORCE\n+\t@FLAGS='$(PERL_DEFINES)'; \\\n+\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n+\t\techo >&2 \"    * new perl-specific parameters\"; \\\n+\t\techo \"$$FLAGS\" >$@; \\\n+\t    fi\n+\n # This makes sure we depend on the NO_PYTHON setting itself.\n $(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS\n \n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440597","messageId":"patch-07.16-24c8f42aa7d-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 07/16] Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:08Z","receivedAt":"2021-11-06T21:03:42Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Create a new \"GIT-PYTHON-DEFINES\" file, and untangle the dependency\nissues of the Python by copying over the patterns established for\nbuilding the adjacent Perl code in preceding commits.\n\nAs with Perl, there's no real reason to depend on GIT-BUILD-OPTIONS or\nGIT-CFLAGS when building the Python code, nor did we need\nGIT-PREFIX. Let's instead add those variables we care about to a\n\"GIT-PYTHON-DEFINES\".\n\nThis changes code originally added in ca3bcabf118 (auto-detect changed\nprefix and/or changed build flags, 2006-06-15), and adjusted in\n96a4647fca5 (Makefile: detect when PYTHON_PATH changes, 2012-12-18).\n\nThe relevant code for the \"Perl\" targets was then added in\n07981dce81e (Makefile: rebuild perl scripts when perl paths change,\n2013-11-18), and has been adjusted in preceding commits.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n .gitignore |  2 +-\n Makefile   | 50 +++++++++++++++++++++++++-------------------------\n 2 files changed, 26 insertions(+), 26 deletions(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 054249b20a8..845e5d0c355 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -8,7 +8,7 @@\n /GIT-PREFIX\n /GIT-PERL-DEFINES\n /GIT-PERL-HEADER\n-/GIT-PYTHON-VARS\n+/GIT-PYTHON-DEFINES\n /GIT-SCRIPT-DEFINES\n /GIT-USER-AGENT\n /GIT-VERSION-FILE\ndiff --git a/Makefile b/Makefile\nindex 354136e30d1..42eb15dc09c 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2369,18 +2369,14 @@ GIT-PERL-DEFINES: FORCE\n \t\techo \"$$FLAGS\" >$@; \\\n \t    fi\n \n-# This makes sure we depend on the NO_PYTHON setting itself.\n-$(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS\n+# Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n+# on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n+PYTHON_DEFINES =\n+$(SCRIPT_PYTHON_GEN): GIT-PYTHON-DEFINES\n+ifdef NO_PYTHON\n+PYTHON_DEFINES += $(SHELL_PATH_SQ)\n+PYTHON_DEFINES += $(NO_PYTHON)\n \n-ifndef NO_PYTHON\n-$(SCRIPT_PYTHON_GEN): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS\n-$(SCRIPT_PYTHON_GEN): % : %.py\n-\t$(QUIET_GEN) \\\n-\tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n-\t    $< >$@+ && \\\n-\tchmod +x $@+ && \\\n-\tmv $@+ $@\n-else # NO_PYTHON\n $(SCRIPT_PYTHON_GEN): % : unimplemented.sh\n \t$(QUIET_GEN) \\\n \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2388,7 +2384,23 @@ $(SCRIPT_PYTHON_GEN): % : unimplemented.sh\n \t    unimplemented.sh >$@+ && \\\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n-endif # NO_PYTHON\n+else\n+PYTHON_DEFINES += $(PYTHON_PATH_SQ)\n+\n+$(SCRIPT_PYTHON_GEN): % : %.py\n+\t$(QUIET_GEN) \\\n+\tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n+\t    $< >$@+ && \\\n+\tchmod +x $@+ && \\\n+\tmv $@+ $@\n+endif # PYTHON\n+\n+GIT-PYTHON-DEFINES: FORCE\n+\t@FLAGS='$(PYTHON_DEFINES)'; \\\n+\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n+\t\techo >&2 \"    * new python-specific parameters\"; \\\n+\t\techo \"$$FLAGS\" >$@; \\\n+\t    fi\n \n CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t\t\tconfigure.ac >configure.ac+ && \\\n@@ -2839,18 +2851,6 @@ else\n endif\n \t@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi\n \n-### Detect Python interpreter path changes\n-ifndef NO_PYTHON\n-TRACK_PYTHON = $(subst ','\\'',-DPYTHON_PATH='$(PYTHON_PATH_SQ)')\n-\n-GIT-PYTHON-VARS: FORCE\n-\t@VARS='$(TRACK_PYTHON)'; \\\n-\t    if test x\"$$VARS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new Python interpreter location\"; \\\n-\t\techo \"$$VARS\" >$@; \\\n-            fi\n-endif\n-\n test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))\n \n all:: $(TEST_PROGRAMS) $(test_bindir_programs)\n@@ -3247,7 +3247,7 @@ ifndef NO_TCLTK\n endif\n \t$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS\n \t$(RM) GIT-USER-AGENT GIT-PREFIX\n-\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS\n+\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-DEFINES\n ifdef MSVC\n \t$(RM) $(patsubst %.o,%.o.pdb,$(OBJECTS))\n \t$(RM) $(patsubst %.exe,%.pdb,$(OTHER_PROGRAMS))\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440596","messageId":"patch-08.16-e3b52cf8da5-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 08/16] Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:09Z","receivedAt":"2021-11-06T21:03:43Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the hardcoding of @@GIT_VERSION@@ in generated *.perl scripts\nto instead shell out to \"git version\". This means that we can stop\nre-building during development every time the HEAD changes.\n\nThese codepaths are not \"hot\", so shelling out to get the version\nshouldn't matter to users, in the one case where it potentially would\nin send-email (the loop for each E-Mail we send) we now cache the\nvalue, so we'll only retrieve it once.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile            | 2 +-\n git-cvsserver.perl  | 6 +++---\n git-send-email.perl | 7 ++-----\n git-svn.perl        | 2 +-\n 4 files changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 42eb15dc09c..b2970c6ded9 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2324,7 +2324,7 @@ else\n PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n endif\n \n-$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n+$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER\n \t$(QUIET_GEN) \\\n \tsed -e '1{' \\\n \t    -e '\ts|#!.*perl|#!$(PERL_PATH_SQ)|' \\\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 64319bed43f..76f0e8bbbef 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -26,8 +26,6 @@\n use File::Basename;\n use Getopt::Long qw(:config require_order no_ignore_case);\n \n-my $VERSION = '@@GIT_VERSION@@';\n-\n my $log = GITCVS::log->new();\n my $cfg;\n \n@@ -126,7 +124,9 @@\n     or die $usage;\n \n if ($state->{version}) {\n-    print \"git-cvsserver version $VERSION\\n\";\n+    my $version = qx[git version];\n+    $version =~ s/^(git)\\b/$1-cvsserver/;\n+    print $version;\n     exit;\n }\n if ($state->{help}) {\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 5262d88ee32..041cd2fb96d 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -1468,6 +1468,7 @@ sub file_name_is_absolute {\n #\n # If an error occurs sending the email, this just dies.\n \n+my $gitversion;\n sub send_message {\n \tmy @recipients = unique_email_list(@to);\n \t@cc = (grep { my $cc = extract_valid_address_or_die($_);\n@@ -1478,11 +1479,6 @@ sub send_message {\n \t@recipients = unique_email_list(@recipients,@cc,@initial_bcc);\n \t@recipients = (map { extract_valid_address_or_die($_) } @recipients);\n \tmy $date = format_2822_time($time++);\n-\tmy $gitversion = '@@GIT_VERSION@@';\n-\tif ($gitversion =~ m/..GIT_VERSION../) {\n-\t    $gitversion = Git::version();\n-\t}\n-\n \tmy $cc = join(\",\\n\\t\", unique_email_list(@cc));\n \tmy $ccline = \"\";\n \tif ($cc ne '') {\n@@ -1497,6 +1493,7 @@ sub send_message {\n Message-Id: $message_id\n \";\n \tif ($use_xmailer) {\n+\t\t$gitversion ||= Git::version();\n \t\t$header .= \"X-Mailer: git-send-email $gitversion\\n\";\n \t}\n \tif ($in_reply_to) {\ndiff --git a/git-svn.perl b/git-svn.perl\nindex be987e316f9..727431412be 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -9,7 +9,6 @@\n \t\t$_revision $_repository\n \t\t$_q $_authors $_authors_prog %users/;\n $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';\n-$VERSION = '@@GIT_VERSION@@';\n \n use Carp qw/croak/;\n use File::Basename qw/dirname basename/;\n@@ -47,6 +46,7 @@\n \tcommand_close_bidi_pipe\n \tget_record\n );\n+$VERSION = Git::version();\n \n BEGIN {\n \tMemoize::memoize 'Git::config';\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440598","messageId":"patch-09.16-e23663bfb20-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 09/16] Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:10Z","receivedAt":"2021-11-06T21:03:50Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We have various behavior that's shared across our Makefiles, or that\nreally should be (e.g. via defined templates). Let's create a\ntop-level \"shared.mak\" to house those sorts of things, and start by\nadding the \".DELETE_ON_ERROR\" flag to it.\n\nSee my own 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\"\nflag, 2021-06-29) and db10fc6c09f (doc: simplify Makefile using\n.DELETE_ON_ERROR, 2021-05-21) for the addition and use of the\n\".DELETE_ON_ERROR\" flag.\n\nThis does have the potential downside that if e.g. templates/Makefile\nwould like to include this \"shared.mak\" in the future the semantics of\nsuch a Makefile will change, but as noted in the above commits (and\nGNU make's own documentation) any such change would be for the better,\nso it's safe to do this.\n\nThis also doesn't introduce a bug by e.g. having this\n\".DELETE_ON_ERROR\" flag only apply to this new shared.mak, Makefiles\nhave no such scoping semantics.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile |  6 +++---\n Makefile               | 13 +++----------\n shared.mak             |  9 +++++++++\n 3 files changed, 15 insertions(+), 13 deletions(-)\n create mode 100644 shared.mak\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ed656db2ae9..ba27456c86a 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # Guard against environment variables\n MAN1_TXT =\n MAN5_TXT =\n@@ -524,7 +527,4 @@ doc-l10n install-l10n::\n \t$(MAKE) -C po $@\n endif\n \n-# Delete the target file on error\n-.DELETE_ON_ERROR:\n-\n .PHONY: FORCE\ndiff --git a/Makefile b/Makefile\nindex b2970c6ded9..e65d346e7cd 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include shared.mak\n+\n # The default target of this Makefile is...\n all::\n \n@@ -2158,16 +2161,6 @@ shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell\n strip: $(PROGRAMS) git$X\n \t$(STRIP) $(STRIP_OPTS) $^\n \n-### Flags affecting all rules\n-\n-# A GNU make extension since gmake 3.72 (released in late 1994) to\n-# remove the target of rules if commands in those rules fail. The\n-# default is to only do that if make itself receives a signal. Affects\n-# all targets, see:\n-#\n-#    info make --index-search=.DELETE_ON_ERROR\n-.DELETE_ON_ERROR:\n-\n ### Target-specific flags and dependencies\n \n # The generic compilation pattern rule and automatically\ndiff --git a/shared.mak b/shared.mak\nnew file mode 100644\nindex 00000000000..0170bb397ae\n--- /dev/null\n+++ b/shared.mak\n@@ -0,0 +1,9 @@\n+### Flags affecting all rules\n+\n+# A GNU make extension since gmake 3.72 (released in late 1994) to\n+# remove the target of rules if commands in those rules fail. The\n+# default is to only do that if make itself receives a signal. Affects\n+# all targets, see:\n+#\n+#    info make --index-search=.DELETE_ON_ERROR\n+.DELETE_ON_ERROR:\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440599","messageId":"patch-10.16-67ba72dc2e6-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 10/16] Makefile: move $(comma), $(empty) and $(space) to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:11Z","receivedAt":"2021-11-06T21:03:51Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move these variables over to the shared.max, we'll make use of them in\na subsequent commit. There was no reason for these to be \"simply\nexpanded variables\", so let's use the normal lazy \"=\" assignment here.\n\nSee 425ca6710b2 (Makefile: allow combining UBSan with other\nsanitizers, 2017-07-15) for the commit that introduced these.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile   | 4 ----\n shared.mak | 8 ++++++++\n 2 files changed, 8 insertions(+), 4 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex e65d346e7cd..f3ad497fcb1 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1252,10 +1252,6 @@ endif\n ALL_CFLAGS = $(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS)\n ALL_LDFLAGS = $(LDFLAGS)\n \n-comma := ,\n-empty :=\n-space := $(empty) $(empty)\n-\n ifdef SANITIZE\n SANITIZERS := $(foreach flag,$(subst $(comma),$(space),$(SANITIZE)),$(flag))\n BASIC_CFLAGS += -fsanitize=$(SANITIZE) -fno-sanitize-recover=$(SANITIZE)\ndiff --git a/shared.mak b/shared.mak\nindex 0170bb397ae..2d597ef7603 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -7,3 +7,11 @@\n #\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n+\n+### Global variables\n+\n+## comma, empty, space: handy variables as these tokens are either\n+## special or can be hard to spot among other Makefile syntax.\n+comma = ,\n+empty =\n+space = $(empty) $(empty)\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440600","messageId":"patch-11.16-67dbad03c14-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 11/16] Makefile: re-add and use the \"shellquote\" macros","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:12Z","receivedAt":"2021-11-06T21:03:52Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Re-add and use, and expand on \"shellquote\" macros added in\n4769948afe7 (Deal with $(bindir) and friends with whitespaces.,\n2005-10-10).\n\nWe avoided using them due to the \"$(call)\" feature of GNU make being\nrelatively new at the time, but it isn't anymore. We hard depend on\nGNU make versions that have it.\n\nThe use of \"$(call)\" was removed in 39c015c556f (Fixes for ancient\nversions of GNU make, 2006-02-18) and 7ffe7098dca (Fix installation of\ntemplates on ancient systems., 2006-07-29) due to those\nincompatibilities with older GNU make versions, and we've used the\nmore verbose *_SQ pattern ever since.\n\nThe \"$(call)\" feature was introduced in GNU make version 3.78,\nreleased on the 22nd of September, 1999. That release also introduced\n\"$(error)\" and \"$(warning)\", which we've been making use of since\nf2fabbf76e4 (Teach Makefile to check header dependencies, 2010-01-26).\n\nThis extends upon the macros added in 4769948afe7: We now have macros\nfor quoting a ' inside '', and a ' with no surrounding '' as before.\n\nAdditionally provide and use a \"shelldquote\" macro along with\n\"shellquote\" for the common case of wanting to quote a C string we\npass to the compiler with a -D flag.\n\nThis doesn't get rid of all of our shell quoting. We've still got some\nin the main Makefile, let's leave most of it to avoid in-flight\nconflicts. I've fully converted \"templates/Makefile\" and \"t/Makefile\"\nthough.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile           | 15 +++++----------\n shared.mak         | 14 ++++++++++++++\n t/Makefile         | 34 +++++++++++++++-------------------\n templates/Makefile | 14 +++++---------\n 4 files changed, 39 insertions(+), 38 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex f3ad497fcb1..baf815c48b4 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1996,11 +1996,7 @@ ifneq (\"$(PROFILE)\",\"\")\n endif\n endif\n \n-# Shell quote (do not use $(call) to accommodate ancient setups);\n-\n-ETC_GITCONFIG_SQ = $(subst ','\\'',$(ETC_GITCONFIG))\n-ETC_GITATTRIBUTES_SQ = $(subst ','\\'',$(ETC_GITATTRIBUTES))\n-\n+# Shell quote, should be changed to use $(call shellquote,...)\n DESTDIR_SQ = $(subst ','\\'',$(DESTDIR))\n NO_GETTEXT_SQ = $(subst ','\\'',$(NO_GETTEXT))\n bindir_SQ = $(subst ','\\'',$(bindir))\n@@ -2525,11 +2521,11 @@ builtin/init-db.sp builtin/init-db.s builtin/init-db.o: EXTRA_CPPFLAGS = \\\n \n config.sp config.s config.o: GIT-PREFIX\n config.sp config.s config.o: EXTRA_CPPFLAGS = \\\n-\t-DETC_GITCONFIG='\"$(ETC_GITCONFIG_SQ)\"'\n+\t-DETC_GITCONFIG=$(call shelldquote,$(ETC_GITCONFIG))\n \n attr.sp attr.s attr.o: GIT-PREFIX\n attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \\\n-\t-DETC_GITATTRIBUTES='\"$(ETC_GITATTRIBUTES_SQ)\"'\n+\t-DETC_GITATTRIBUTES=$(call shelldquote,$(ETC_GITATTRIBUTES))\n \n gettext.sp gettext.s gettext.o: GIT-PREFIX\n gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \\\n@@ -2690,14 +2686,13 @@ perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n \t    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \\\n-\t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \\\n+\t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(call shq,$(NO_PERL_CPAN_FALLBACKS))|g' \\\n \t< $< > $@\n \n all:: $(LIB_PERL_GEN)\n ifndef NO_PERL_CPAN_FALLBACKS\n all:: $(LIB_CPAN_GEN)\n endif\n-NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n endif\n \n # install-man depends on Git.3pm even with NO_PERL=Y\n@@ -3011,7 +3006,7 @@ else\n \t$(INSTALL) $(vcpkg_dbg_bin)/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'\n endif\n endif\n-\t$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install\n+\t$(MAKE) -C templates DESTDIR=$(call shellquote,$(DESTDIR)) install\n \t$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'\n \t$(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'\n ifndef NO_GETTEXT\ndiff --git a/shared.mak b/shared.mak\nindex 2d597ef7603..ef03c2bc094 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -8,6 +8,20 @@\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n \n+### Quoting helpers\n+\n+## Quote a ' inside a '': FOO='$(call shq,$(BAR))'\n+shq = $(subst ','\\'',$(1))\n+\n+## Quote a ' and provide a '': FOO=$(call shq,$(BAR))\n+shellquote = '$(call shq,$(1))'\n+\n+## Quote a \" inside a \"\"\n+shdq = $(subst \",\\\",$(1))\n+\n+## Quote ' for the shell, and embedded \" for C: -DFOO=$(call shelldquote,$(BAR))\n+shelldquote = '\"$(call shdq,$(call shq,$(1)))\"'\n+\n ### Global variables\n \n ## comma, empty, space: handy variables as these tokens are either\ndiff --git a/t/Makefile b/t/Makefile\nindex 882d26eee30..4168b5c6ce6 100644\n--- a/t/Makefile\n+++ b/t/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # Run tests\n #\n # Copyright (c) 2005 Junio C Hamano\n@@ -24,13 +27,6 @@ TEST_RESULTS_DIRECTORY = test-results\n CHAINLINTTMP = chainlinttmp\n endif\n \n-# Shell quote;\n-SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n-TEST_SHELL_PATH_SQ = $(subst ','\\'',$(TEST_SHELL_PATH))\n-PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n-TEST_RESULTS_DIRECTORY_SQ = $(subst ','\\'',$(TEST_RESULTS_DIRECTORY))\n-CHAINLINTTMP_SQ = $(subst ','\\'',$(CHAINLINTTMP))\n-\n T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))\n TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh))\n THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh)))\n@@ -44,38 +40,38 @@ test: pre-clean check-chainlint $(TEST_LINT)\n \t$(MAKE) aggregate-results-and-cleanup\n \n failed:\n-\t@failed=$$(cd '$(TEST_RESULTS_DIRECTORY_SQ)' && \\\n+\t@failed=$$(cd $(call shellquote,$(TEST_RESULTS_DIRECTORY)) && \\\n \t\tgrep -l '^failed [1-9]' *.counts | \\\n \t\tsed -n 's/\\.counts$$/.sh/p') && \\\n \ttest -z \"$$failed\" || $(MAKE) $$failed\n \n prove: pre-clean check-chainlint $(TEST_LINT)\n-\t@echo \"*** prove ***\"; $(PROVE) --exec '$(TEST_SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n+\t@echo \"*** prove ***\"; $(PROVE) --exec $(call shellquote,$(SHELL_PATH)) $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n \t$(MAKE) clean-except-prove-cache\n \n $(T):\n-\t@echo \"*** $@ ***\"; '$(TEST_SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)\n+\t@echo \"*** $@ ***\"; $(call shellquote,$(SHELL_PATH)) $@ $(GIT_TEST_OPTS)\n \n pre-clean:\n-\t$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'\n+\t$(RM) -r $(call shellquote,$(TEST_RESULTS_DIRECTORY))\n \n clean-except-prove-cache: clean-chainlint\n-\t$(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)'\n+\t$(RM) -r 'trash directory'.* $(call shellquote,$(TEST_RESULTS_DIRECTORY))\n \t$(RM) -r valgrind/bin\n \n clean: clean-except-prove-cache\n \t$(RM) .prove\n \n clean-chainlint:\n-\t$(RM) -r '$(CHAINLINTTMP_SQ)'\n+\t$(RM) -r $(call shellquote,$(CHAINLINTTMP))\n \n check-chainlint:\n-\t@mkdir -p '$(CHAINLINTTMP_SQ)' && \\\n+\t@mkdir -p $(call shellquote,$(CHAINLINTTMP)) && \\\n \terr=0 && \\\n \tfor i in $(CHAINLINTTESTS); do \\\n \t\t$(CHAINLINT) <chainlint/$$i.test | \\\n-\t\tsed -e '/^# LINT: /d' >'$(CHAINLINTTMP_SQ)'/$$i.actual && \\\n-\t\tdiff -u chainlint/$$i.expect '$(CHAINLINTTMP_SQ)'/$$i.actual || err=1; \\\n+\t\tsed -e '/^# LINT: /d' >$(call shellquote,$(CHAINLINTTMP))/$$i.actual && \\\n+\t\tdiff -u chainlint/$$i.expect $(call shellquote,$(CHAINLINTTMP))/$$i.actual || err=1; \\\n \tdone && exit $$err\n \n test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \\\n@@ -92,7 +88,7 @@ test-lint-executable:\n \t\techo >&2 \"non-executable tests:\" $$bad; exit 1; }\n \n test-lint-shell-syntax:\n-\t@'$(PERL_PATH_SQ)' check-non-portable-shell.pl $(T) $(THELPERS) $(TPERF)\n+\t@$(call shellquote,$(PERL_PATH)) check-non-portable-shell.pl $(T) $(THELPERS) $(TPERF)\n \n test-lint-filenames:\n \t@# We do *not* pass a glob to ls-files but use grep instead, to catch\n@@ -107,9 +103,9 @@ aggregate-results-and-cleanup: $(T)\n \t$(MAKE) clean\n \n aggregate-results:\n-\tfor f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \\\n+\tfor f in $(call shellquote,$(TEST_RESULTS_DIRECTORY))/t*-*.counts; do \\\n \t\techo \"$$f\"; \\\n-\tdone | '$(SHELL_PATH_SQ)' ./aggregate-results.sh\n+\tdone | $(call shellquote,$(SHELL_PATH)) ./aggregate-results.sh\n \n gitweb-test:\n \t$(MAKE) $(TGITWEB)\ndiff --git a/templates/Makefile b/templates/Makefile\nindex d22a71a3999..c9251a96622 100644\n--- a/templates/Makefile\n+++ b/templates/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # make and install sample templates\n \n ifndef V\n@@ -18,13 +21,6 @@ ifndef PERL_PATH\n \tPERL_PATH = perl\n endif\n \n-SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n-PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n-\n-# Shell quote (do not use $(call) to accommodate ancient setups);\n-DESTDIR_SQ = $(subst ','\\'',$(DESTDIR))\n-template_instdir_SQ = $(subst ','\\'',$(template_instdir))\n-\n all: boilerplates.made custom\n \n # Put templates that can be copied straight from the source\n@@ -61,6 +57,6 @@ clean:\n \t$(RM) -r blt boilerplates.made\n \n install: all\n-\t$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(template_instdir_SQ)'\n+\t$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(template_instdir))\n \t(cd blt && $(TAR) cf - .) | \\\n-\t(cd '$(DESTDIR_SQ)$(template_instdir_SQ)' && umask 022 && $(TAR) xof -)\n+\t(cd $(call shellquote,$(DESTDIR)$(template_instdir)) && umask 022 && $(TAR) xof -)\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440602","messageId":"patch-12.16-5930a08cb4e-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 12/16] Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:13Z","receivedAt":"2021-11-06T21:03:53Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move the mostly copy/pasted code in the \"Makefile\" and\n\"Documentation/Makefile\" which FORCE-generates a file based on a\nvariable in play in the Makefile to use a template.\n\nThis will make it easier later on to move these to rules that aren't\nFORCE-run using optional gmake 4.2+ features, but for now just getting\nrid of the repetition is worth it.\n\nThe message for the new generated rule will say whether or not we're\ngenerating the file for the first time, as opposed to the old messages\nsaying \"new\" whether we had flag modifications, or were building for\nthe first time.\n\nExample output before:\n\n    $ make clean\n    [...]\n    $ make\n    GIT_VERSION = 2.34.0-rc1-dev\n        * new build flags\n        CC grep.o\n    $ make CFLAGS=-I$RANDOM grep.o\n        * new build flags\n        CC grep.o\n\nAfter:\n\n    $ make clean\n    [...]\n    $ make grep.o\n    GIT_VERSION = 2.34.0-rc1-dev\n        GIT-CFLAGS PARAMETERS (new)\n        CC grep.o\n    $ make CFLAGS=-I$RANDOM grep.o\n        GIT-CFLAGS PARAMETERS (changed)\n        CC grep.o\n\nNote: It's important that \"@FLAGS\" here be defined as '$$($(2))', and\nnot the eagerly expanded '$($(2))'. The latter will break if\ne.g. curl-config isn't installed, since we'll end up recursively\nexpanding that part of the variable even if NO_CURL isn't defined,\nwhich happens e.g. for the \"check-docs\" target in CI.\n\nWe're also introducing a $(wspfx) variable here to control the\nwhitespace prefixing. It matches the $(QUIET...) variables, who'll be\nusing these variables in a subsequent commit. Note that it's important\nthat we call the shell quote escaping macros inline (or equivalent),\nbecause if we'd like variables to be overridable we need to support e.g.:\n\n    $ make CFLAGS=-I$RANDOM grep.o wspfx='$(space)->'\n     -> GIT-CFLAGS PARAMETERS (changed)\n        CC grep.o\n\nIf we simply quoted and used $(wspfx) then the user would need to\nprovide us with a quoted version, so there's still some use-cases for\nthese $(*_sq) variables. It could also be done inline, but that's a\nlot more verbose.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile |  8 +------\n Makefile               | 51 ++++++------------------------------------\n shared.mak             | 22 ++++++++++++++++++\n 3 files changed, 30 insertions(+), 51 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ba27456c86a..4a939cc2c25 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -343,13 +343,7 @@ mergetools-list.made: ../git-mergetool--lib.sh $(wildcard ../mergetools/*)\n \tdate >$@\n \n TRACK_ASCIIDOCFLAGS = $(subst ','\\'',$(ASCIIDOC_COMMON):$(ASCIIDOC_HTML):$(ASCIIDOC_DOCBOOK))\n-\n-GIT-ASCIIDOCFLAGS: FORCE\n-\t@FLAGS='$(TRACK_ASCIIDOCFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-ASCIIDOCFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new asciidoc flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-ASCIIDOCFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-ASCIIDOCFLAGS,TRACK_ASCIIDOCFLAGS))\n \n clean:\n \t$(RM) -rf .build/\ndiff --git a/Makefile b/Makefile\nindex baf815c48b4..c1ad99a5399 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2087,10 +2087,7 @@ endif\n GIT_USER_AGENT_SQ = $(subst ','\\'',$(GIT_USER_AGENT))\n GIT_USER_AGENT_CQ = \"$(subst \",\\\",$(subst \\,\\\\,$(GIT_USER_AGENT)))\"\n GIT_USER_AGENT_CQ_SQ = $(subst ','\\'',$(GIT_USER_AGENT_CQ))\n-GIT-USER-AGENT: FORCE\n-\t@if test x'$(GIT_USER_AGENT_SQ)' != x\"`cat GIT-USER-AGENT 2>/dev/null`\"; then \\\n-\t\techo '$(GIT_USER_AGENT_SQ)' >GIT-USER-AGENT; \\\n-\tfi\n+$(eval $(call TRACK_template,GIT-USER-AGENT,GIT_USER_AGENT_SQ))\n \n ifdef DEFAULT_HELP_FORMAT\n BASIC_CFLAGS += -DDEFAULT_HELP_FORMAT='\"$(DEFAULT_HELP_FORMAT)\"'\n@@ -2238,12 +2235,7 @@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\\\n \t$(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n \t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(PAGER_ENV):\\\n \t$(perllibdir_SQ)\n-GIT-SCRIPT-DEFINES: FORCE\n-\t@FLAGS='$(SCRIPT_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new script parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-SCRIPT-DEFINES,SCRIPT_DEFINES))\n \n define cmd_munge_script\n sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2346,13 +2338,7 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n endif # NO_PERL\n-\n-GIT-PERL-DEFINES: FORCE\n-\t@FLAGS='$(PERL_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new perl-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n+$(eval $(call TRACK_template,GIT-PERL-DEFINES,PERL_DEFINES))\n \n # Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n # on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n@@ -2380,12 +2366,7 @@ $(SCRIPT_PYTHON_GEN): % : %.py\n \tmv $@+ $@\n endif # PYTHON\n \n-GIT-PYTHON-DEFINES: FORCE\n-\t@FLAGS='$(PYTHON_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new python-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n+$(eval $(call TRACK_template,GIT-PYTHON-DEFINES,PYTHON_DEFINES))\n \n CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t\t\tconfigure.ac >configure.ac+ && \\\n@@ -2741,31 +2722,13 @@ cscope: cscope.out\n ### Detect prefix changes\n TRACK_PREFIX = $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\\\n \t\t$(localedir_SQ)\n-\n-GIT-PREFIX: FORCE\n-\t@FLAGS='$(TRACK_PREFIX)'; \\\n-\tif test x\"$$FLAGS\" != x\"`cat GIT-PREFIX 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new prefix flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-PREFIX; \\\n-\tfi\n+$(eval $(call TRACK_template,GIT-PREFIX,TRACK_PREFIX))\n \n TRACK_CFLAGS = $(CC):$(subst ','\\'',$(ALL_CFLAGS)):$(USE_GETTEXT_SCHEME)\n-\n-GIT-CFLAGS: FORCE\n-\t@FLAGS='$(TRACK_CFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-CFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new build flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-CFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-CFLAGS,TRACK_CFLAGS))\n \n TRACK_LDFLAGS = $(subst ','\\'',$(ALL_LDFLAGS))\n-\n-GIT-LDFLAGS: FORCE\n-\t@FLAGS='$(TRACK_LDFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-LDFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new link flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-LDFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-LDFLAGS,TRACK_LDFLAGS))\n \n # We need to apply sq twice, once to protect from the shell\n # that runs GIT-BUILD-OPTIONS, and then again to protect it\ndiff --git a/shared.mak b/shared.mak\nindex ef03c2bc094..3b4163e652a 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -29,3 +29,25 @@ shelldquote = '\"$(call shdq,$(call shq,$(1)))\"'\n comma = ,\n empty =\n space = $(empty) $(empty)\n+\n+## wspfx: the whitespace prefix padding for $(QUIET...) and similarly\n+## aligned output.\n+wspfx = $(space)$(space)$(space)\n+wspfx_sq = $(call shellquote,$(wspfx))\n+\n+### Templates\n+\n+## Template for making a GIT-SOMETHING, which changes if a\n+## TRACK_SOMETHING variable changes.\n+define TRACK_template\n+.PHONY: FORCE\n+$(1): FORCE\n+\t@FLAGS='$$($(2))'; \\\n+\tif ! test -f $(1) ; then \\\n+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (new)\" $@; \\\n+\t\techo \"$$$$FLAGS\" >$(1); \\\n+\telif test x\"$$$$FLAGS\" != x\"`cat $(1) 2>/dev/null`\" ; then \\\n+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (changed)\" $@; \\\n+\t\techo \"$$$$FLAGS\" >$(1); \\\n+\tfi\n+endef\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440601","messageId":"patch-13.16-d927202fb89-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 13/16] Makefile: add \"$(QUIET)\" boilerplate to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:14Z","receivedAt":"2021-11-06T21:03:55Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"The $(QUIET) variables we define are largely duplicated between our\nvarious Makefiles, let's define them in the new \"shared.mak\" instead.\n\nSince we're not using the environment to pass these around we don't\nneed to export the \"QUIET_GEN\" and \"QUIET_BUILT_IN\" variables\nanymore. The \"QUIET_GEN\" variable is used in \"git-gui/Makefile\" and\n\"gitweb/Makefile\", but they've got their own definition for those. The\n\"QUIET_BUILT_IN\" variable is only used in the top-level \"Makefile\". We\nstill need to export the \"V\" variable.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile | 32 -------------------------\n Makefile               | 33 --------------------------\n config.mak.uname       |  1 -\n shared.mak             | 53 ++++++++++++++++++++++++++++++++++++++++++\n templates/Makefile     |  5 ----\n 5 files changed, 53 insertions(+), 71 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex 4a939cc2c25..69a9af35397 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -218,38 +218,6 @@ DEFAULT_EDITOR_SQ = $(subst ','\\'',$(DEFAULT_EDITOR))\n ASCIIDOC_EXTRA += -a 'git-default-editor=$(DEFAULT_EDITOR_SQ)'\n endif\n \n-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n-QUIET_SUBDIR1  =\n-\n-ifneq ($(findstring $(MAKEFLAGS),w),w)\n-PRINT_DIR = --no-print-directory\n-else # \"make -w\"\n-NO_SUBDIR = :\n-endif\n-\n-ifneq ($(findstring $(MAKEFLAGS),s),s)\n-ifndef V\n-\tQUIET\t\t= @\n-\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n-\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n-\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n-\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n-\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n-\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n-\tQUIET_GEN\t= @echo '   ' GEN $@;\n-\tQUIET_STDERR\t= 2> /dev/null\n-\tQUIET_SUBDIR0\t= +@subdir=\n-\tQUIET_SUBDIR1\t= ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n-\t\t\t  $(MAKE) $(PRINT_DIR) -C $$subdir\n-\n-\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n-\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n-\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n-\n-\texport V\n-endif\n-endif\n-\n all: html man\n \n html: $(DOC_HTML)\ndiff --git a/Makefile b/Makefile\nindex c1ad99a5399..cd7727ebe39 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1939,39 +1939,6 @@ ifndef PAGER_ENV\n PAGER_ENV = LESS=FRX LV=-c\n endif\n \n-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n-QUIET_SUBDIR1  =\n-\n-ifneq ($(findstring w,$(MAKEFLAGS)),w)\n-PRINT_DIR = --no-print-directory\n-else # \"make -w\"\n-NO_SUBDIR = :\n-endif\n-\n-ifneq ($(findstring s,$(MAKEFLAGS)),s)\n-ifndef V\n-\tQUIET_CC       = @echo '   ' CC $@;\n-\tQUIET_AR       = @echo '   ' AR $@;\n-\tQUIET_LINK     = @echo '   ' LINK $@;\n-\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n-\tQUIET_GEN      = @echo '   ' GEN $@;\n-\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n-\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n-\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n-\tQUIET_GCOV     = @echo '   ' GCOV $@;\n-\tQUIET_SP       = @echo '   ' SP $<;\n-\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n-\tQUIET_RC       = @echo '   ' RC $@;\n-\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n-\tQUIET_SUBDIR0  = +@subdir=\n-\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n-\t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n-\texport V\n-\texport QUIET_GEN\n-\texport QUIET_BUILT_IN\n-endif\n-endif\n-\n ifdef NO_INSTALL_HARDLINKS\n \texport NO_INSTALL_HARDLINKS\n endif\ndiff --git a/config.mak.uname b/config.mak.uname\nindex d0701f9beb0..1a12d8c635f 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -715,7 +715,6 @@ vcxproj:\n \tgit diff-index --cached --quiet HEAD --\n \n \t# Make .vcxproj files and add them\n-\tunset QUIET_GEN QUIET_BUILT_IN; \\\n \tperl contrib/buildsystems/generate -g Vcxproj\n \tgit add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj\n \ndiff --git a/shared.mak b/shared.mak\nindex 3b4163e652a..850ce1f6a0f 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -51,3 +51,56 @@ $(1): FORCE\n \t\techo \"$$$$FLAGS\" >$(1); \\\n \tfi\n endef\n+\n+### Quieting\n+## common\n+QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n+QUIET_SUBDIR1  =\n+\n+ifneq ($(findstring w,$(MAKEFLAGS)),w)\n+PRINT_DIR = --no-print-directory\n+else # \"make -w\"\n+NO_SUBDIR = :\n+endif\n+\n+ifneq ($(findstring s,$(MAKEFLAGS)),s)\n+ifndef V\n+## common\n+\tQUIET_SUBDIR0  = +@subdir=\n+\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n+\t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n+\n+\tQUIET          = @\n+\tQUIET_GEN      = @echo '   ' GEN $@;\n+\n+## Used in \"Makefile\"\n+\tQUIET_CC       = @echo '   ' CC $@;\n+\tQUIET_AR       = @echo '   ' AR $@;\n+\tQUIET_LINK     = @echo '   ' LINK $@;\n+\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n+\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n+\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n+\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n+\tQUIET_GCOV     = @echo '   ' GCOV $@;\n+\tQUIET_SP       = @echo '   ' SP $<;\n+\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n+\tQUIET_RC       = @echo '   ' RC $@;\n+\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n+\n+## Used in \"Documentation/Makefile\"\n+\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n+\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n+\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n+\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n+\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n+\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n+\tQUIET_GEN\t= @echo '   ' GEN $@;\n+\tQUIET_STDERR\t= 2> /dev/null\n+\n+\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n+\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n+\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n+\n+\texport V\n+endif\n+endif\ndiff --git a/templates/Makefile b/templates/Makefile\nindex c9251a96622..b056e710b7e 100644\n--- a/templates/Makefile\n+++ b/templates/Makefile\n@@ -2,11 +2,6 @@\n include ../shared.mak\n \n # make and install sample templates\n-\n-ifndef V\n-\tQUIET = @\n-endif\n-\n INSTALL ?= install\n TAR ?= tar\n RM ?= rm -f\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440603","messageId":"patch-14.16-2966218d6c8-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 14/16] Makefile: use $(wspfx) for $(QUIET...) in shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:15Z","receivedAt":"2021-11-06T21:04:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the mostly move-only change in the preceding commit to use the\n$(wspfx) variable for defining the QUIET padding, to guarantee that\nit's consistent with the \"TRACK_template\" template.\n\n    $ make CFLAGS=-I$RANDOM grep.o wspfx='$(space)->'\n     -> GIT-CFLAGS PARAMETERS (changed)\n     -> CC grep.o\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n shared.mak | 48 ++++++++++++++++++++++++------------------------\n 1 file changed, 24 insertions(+), 24 deletions(-)\n\ndiff --git a/shared.mak b/shared.mak\nindex 850ce1f6a0f..566eb70cf2a 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -67,39 +67,39 @@ ifneq ($(findstring s,$(MAKEFLAGS)),s)\n ifndef V\n ## common\n \tQUIET_SUBDIR0  = +@subdir=\n-\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n+\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo $(wspfx_sq) SUBDIR $$subdir; \\\n \t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n \n \tQUIET          = @\n-\tQUIET_GEN      = @echo '   ' GEN $@;\n+\tQUIET_GEN      = @echo $(wspfx_sq) GEN $@;\n \n ## Used in \"Makefile\"\n-\tQUIET_CC       = @echo '   ' CC $@;\n-\tQUIET_AR       = @echo '   ' AR $@;\n-\tQUIET_LINK     = @echo '   ' LINK $@;\n-\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n-\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n-\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n-\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n-\tQUIET_GCOV     = @echo '   ' GCOV $@;\n-\tQUIET_SP       = @echo '   ' SP $<;\n-\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n-\tQUIET_RC       = @echo '   ' RC $@;\n-\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n+\tQUIET_CC       = @echo $(wspfx_sq) CC $@;\n+\tQUIET_AR       = @echo $(wspfx_sq) AR $@;\n+\tQUIET_LINK     = @echo $(wspfx_sq) LINK $@;\n+\tQUIET_BUILT_IN = @echo $(wspfx_sq) BUILTIN $@;\n+\tQUIET_LNCP     = @echo $(wspfx_sq) LN/CP $@;\n+\tQUIET_XGETTEXT = @echo $(wspfx_sq) XGETTEXT $@;\n+\tQUIET_MSGFMT   = @echo $(wspfx_sq) MSGFMT $@;\n+\tQUIET_GCOV     = @echo $(wspfx_sq) GCOV $@;\n+\tQUIET_SP       = @echo $(wspfx_sq) SP $<;\n+\tQUIET_HDR      = @echo $(wspfx_sq) HDR $(<:hcc=h);\n+\tQUIET_RC       = @echo $(wspfx_sq) RC $@;\n+\tQUIET_SPATCH   = @echo $(wspfx_sq) SPATCH $<;\n \n ## Used in \"Documentation/Makefile\"\n-\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n-\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n-\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n-\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n-\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n-\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n-\tQUIET_GEN\t= @echo '   ' GEN $@;\n+\tQUIET_ASCIIDOC\t= @echo $(wspfx_sq) ASCIIDOC $@;\n+\tQUIET_XMLTO\t= @echo $(wspfx_sq) XMLTO $@;\n+\tQUIET_DB2TEXI\t= @echo $(wspfx_sq) DB2TEXI $@;\n+\tQUIET_MAKEINFO\t= @echo $(wspfx_sq) MAKEINFO $@;\n+\tQUIET_DBLATEX\t= @echo $(wspfx_sq) DBLATEX $@;\n+\tQUIET_XSLTPROC\t= @echo $(wspfx_sq) XSLTPROC $@;\n+\tQUIET_GEN\t= @echo $(wspfx_sq) GEN $@;\n \tQUIET_STDERR\t= 2> /dev/null\n \n-\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n-\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n-\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n+\tQUIET_LINT_GITLINK\t= @echo $(wspfx_sq) LINT GITLINK $<;\n+\tQUIET_LINT_MANSEC\t= @echo $(wspfx_sq) LINT MAN SEC $<;\n+\tQUIET_LINT_MANEND\t= @echo $(wspfx_sq) LINT MAN END $<;\n \n \texport V\n endif\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440604","messageId":"patch-15.16-412a11f63a3-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 15/16] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:16Z","receivedAt":"2021-11-06T21:04:07Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\nfor us, and use it for the \"make lint-docs\" targets I added in\n8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n\nAs seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\ndependency, 2021-10-26) maintaining these manual lists of parent\ndirectory dependencies is fragile, in addition to being obviously\nverbose.\n\nI used this pattern at the time because I couldn't find another method\nthan \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\nevery file being created, which as noted in [1] would be significantly\nslower.\n\nBut as it turns out we can use this neat trick of only doing a \"mkdir\n-p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\nof the performance test I noted downthread of [1] in [2] shows that\nthis is faster, in addition to being less verbose and more reliable:\n\n    $ hyperfine --warmup 5 -m 30 -L s \",~\" -p 'git checkout HEAD{s} -- Makefile; rm -rf .build' 'make -j8 lint-docs R={s}'\n     -c 'git checkout HEAD -- Makefile'\n    Benchmark #1: make -j8 lint-docs R=\n      Time (mean ± σ):     537.5 ms ±   7.1 ms    [User: 2.412 s, System: 0.460 s]\n      Range (min … max):   530.2 ms … 564.9 ms    30 runs\n\n    Benchmark #2: make -j8 lint-docs R=~\n      Time (mean ± σ):     645.7 ms ±   7.1 ms    [User: 3.083 s, System: 0.630 s]\n      Range (min … max):   637.4 ms … 675.2 ms    30 runs\n\n    Summary\n      'make -j8 lint-docs R=' ran\n        1.20 ± 0.02 times faster than 'make -j8 lint-docs R=~'\n\nSo let's use that pattern both for the \"lint-docs\" target, and a few\nmiscellaneous other targets.\n\nThis method of creating parent directories is explicitly racy in that\nwe don't know if we're going to say always create a \"foo\" followed by\na \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n\"foo/bar\" first. In this case it doesn't matter for anything except\nthat we aren't guaranteed to get the same number of rules firing when\nrunning make in parallel.\n\n1. https://lore.kernel.org/git/211028.861r45y3pt.gmgdl@evledraar.gmail.com/\n2. https://lore.kernel.org/git/211028.86o879vvtp.gmgdl@evledraar.gmail.com/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile | 25 +++----------------------\n Makefile               | 12 +++++++-----\n shared.mak             |  7 +++++++\n 3 files changed, 17 insertions(+), 27 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex 69a9af35397..d16b653394c 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -428,25 +428,11 @@ quick-install-html: require-htmlrepo\n print-man1:\n \t@for i in $(MAN1_TXT); do echo $$i; done\n \n-## Lint: Common\n-.build:\n-\t$(QUIET)mkdir $@\n-.build/lint-docs: | .build\n-\t$(QUIET)mkdir $@\n-\n ## Lint: gitlink\n-.build/lint-docs/gitlink: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n-.build/lint-docs/gitlink/howto: | .build/lint-docs/gitlink\n-\t$(QUIET)mkdir $@\n-.build/lint-docs/gitlink/config: | .build/lint-docs/gitlink\n-\t$(QUIET)mkdir $@\n LINT_DOCS_GITLINK = $(patsubst %.txt,.build/lint-docs/gitlink/%.ok,$(HOWTO_TXT) $(DOC_DEP_TXT))\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/howto\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/config\n $(LINT_DOCS_GITLINK): lint-gitlink.perl\n $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_GITLINK)$(PERL_PATH) lint-gitlink.perl \\\n \t\t$< \\\n \t\t$(HOWTO_TXT) $(DOC_DEP_TXT) \\\n@@ -457,23 +443,18 @@ $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt\n lint-docs-gitlink: $(LINT_DOCS_GITLINK)\n \n ## Lint: man-end-blurb\n-.build/lint-docs/man-end-blurb: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n LINT_DOCS_MAN_END_BLURB = $(patsubst %.txt,.build/lint-docs/man-end-blurb/%.ok,$(MAN_TXT))\n-$(LINT_DOCS_MAN_END_BLURB): | .build/lint-docs/man-end-blurb\n $(LINT_DOCS_MAN_END_BLURB): lint-man-end-blurb.perl\n $(LINT_DOCS_MAN_END_BLURB): .build/lint-docs/man-end-blurb/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_MANEND)$(PERL_PATH) lint-man-end-blurb.perl $< >$@\n .PHONY: lint-docs-man-end-blurb\n-lint-docs-man-end-blurb: $(LINT_DOCS_MAN_END_BLURB)\n \n ## Lint: man-section-order\n-.build/lint-docs/man-section-order: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n LINT_DOCS_MAN_SECTION_ORDER = $(patsubst %.txt,.build/lint-docs/man-section-order/%.ok,$(MAN_TXT))\n-$(LINT_DOCS_MAN_SECTION_ORDER): | .build/lint-docs/man-section-order\n $(LINT_DOCS_MAN_SECTION_ORDER): lint-man-section-order.perl\n $(LINT_DOCS_MAN_SECTION_ORDER): .build/lint-docs/man-section-order/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_MANSEC)$(PERL_PATH) lint-man-section-order.perl $< >$@\n .PHONY: lint-docs-man-section-order\n lint-docs-man-section-order: $(LINT_DOCS_MAN_SECTION_ORDER)\ndiff --git a/Makefile b/Makefile\nindex cd7727ebe39..141a87371fe 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2622,7 +2622,8 @@ all:: $(MOFILES)\n endif\n \n po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n-\t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_MSGFMT)$(MSGFMT) -o $@ $<\n \n ifndef NO_PERL\n LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n@@ -2631,7 +2632,8 @@ LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n-\t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_GEN) \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n \t    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \\\n \t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(call shq,$(NO_PERL_CPAN_FALLBACKS))|g' \\\n@@ -2645,8 +2647,8 @@ endif\n \n # install-man depends on Git.3pm even with NO_PERL=Y\n perl/build/man/man3/Git.3pm: perl/Git.pm\n-\t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n-\tpod2man $< $@\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_GEN)pod2man $< $@\n \n FIND_SOURCE_FILES = ( \\\n \tgit ls-files \\\n@@ -2770,7 +2772,7 @@ test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(\n all:: $(TEST_PROGRAMS) $(test_bindir_programs)\n \n bin-wrappers/%: wrap-for-bin.sh\n-\t@mkdir -p bin-wrappers\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n \t     -e 's|@@BUILD_DIR@@|$(shell pwd)|' \\\n \t     -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \\\ndiff --git a/shared.mak b/shared.mak\nindex 566eb70cf2a..ced88924ea3 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -73,6 +73,8 @@ ifndef V\n \tQUIET          = @\n \tQUIET_GEN      = @echo $(wspfx_sq) GEN $@;\n \n+\tQUIET_MKDIR_P_PARENT  = @echo $(wspfx_sq) MKDIR -p $(@D);\n+\n ## Used in \"Makefile\"\n \tQUIET_CC       = @echo $(wspfx_sq) CC $@;\n \tQUIET_AR       = @echo $(wspfx_sq) AR $@;\n@@ -104,3 +106,8 @@ ifndef V\n \texport V\n endif\n endif\n+\n+## Helpers\n+define mkdir_p_parent_template\n+$(if $(wildcard $(@D)),,$(QUIET_MKDIR_P_PARENT)$(shell mkdir -p $(@D)))\n+endef\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440605","messageId":"patch-16.16-7f1081651ed-20211106T205717Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH 16/16] Makefile: don't invoke msgfmt with --statistics","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-06T21:03:17Z","receivedAt":"2021-11-06T21:04:09Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the --statistics flag that I added in 5e9637c6297 (i18n: add\ninfrastructure for translating Git with gettext, 2011-11-18). Our\nMakefile output is good about reducing verbosity by default, except in\nthis case:\n\n    $ rm -rf po/build/locale/e*; time make -j $(nproc) all\n        SUBDIR templates\n        MKDIR -p po/build/locale/el/LC_MESSAGES\n        MSGFMT po/build/locale/el/LC_MESSAGES/git.mo\n        MKDIR -p po/build/locale/es/LC_MESSAGES\n        MSGFMT po/build/locale/es/LC_MESSAGES/git.mo\n    1038 translated messages, 3325 untranslated messages.\n    5230 translated messages.\n\nI didn't have any good reason for using --statistics at the time other\nthan ad-hoc eyeballing of the output. We don't need to spew out\nexactly how many messages we've got translated every time. Now we'll\ninstead emit:\n\n    $ rm -rf po/build/locale/e*; time make -j $(nproc) all\n        SUBDIR templates\n        MKDIR -p po/build/locale/el/LC_MESSAGES\n        MSGFMT po/build/locale/el/LC_MESSAGES/git.mo\n        MKDIR -p po/build/locale/es/LC_MESSAGES\n        MSGFMT po/build/locale/es/LC_MESSAGES/git.mo\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex 141a87371fe..51b9e4b6c84 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1869,7 +1869,7 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT\n endif\n \n ifndef NO_MSGFMT_EXTENDED_OPTIONS\n-\tMSGFMT += --check --statistics\n+\tMSGFMT += --check\n endif\n \n ifdef HAVE_CLOCK_GETTIME\n-- \n2.34.0.rc1.741.gab7bfd97031\n\n"},{"id":"440631","messageId":"CAPig+cT5PbT0k7AdZSc_4WA4=hpvsCyUxNXc_PzE41ok_V5XMQ@mail.gmail.com","threadId":"56852","inReplyTo":"patch-05.16-d8e14cb723d-20211106T205717Z-avarab@gmail.com","subject":"Re: [PATCH 05/16] Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-11-07T01:51:11Z","receivedAt":"2021-11-07T01:51:25Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sat, Nov 6, 2021 at 5:03 PM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n> Fix several small issues with the dependency graph of the generated\n> \"GIT-PERL-DEFINES\" and \"GIT-PERL-HEADER\" files:\n>\n> 1. Folllow-up my 4070c9e09fc (Makefile: don't re-define PERL_DEFINES,\n>    2021-05-05) and move the rest of the assignments to PERL_DEFINES to\n>    one place, and change it from depending on \"localedir_relative_SQ\"\n>    instead of \"localedir\".\n>\n>    The former is what we'll actually use, and while it's unlikely to\n>    matter in practice (we'd just skip re-building these under\n>    RUNTIME_PREFIX if the relative path was the same) it makes it\n>    clearer what's going on here by bringing us to a 1=1 mapping of\n>    these variables and what's subsequently used in the\n>    \"GIT-PERL-DEFINES\", \"GIT-PERL-HEADER\" and \"perl/build/lib/%.pm\"\n>    rules below.\n>\n> 2. We don't need the substitution of \" \" for \":\" added in\n>    07d90eadb50 (Makefile: add Perl runtime prefix support, 2018-04-10),\n>    let's drop it. This doesn't matter for the correctness of these files,\n>    but makes it clear  that (unlike GIT-BUILD-OPTIONS) they are not\n\nToo many spaces between \"clear\" and \"that\".\n\nIs the last sentence of this paragraph incomplete?\n\n> 3. Don't have \"GIT-PERL-HEADER\" depend on the \"Makefile\". That was a\n>    lazy way to over-declare the dependencies added in\n>    f6a0ad4be71 (Makefile: generate Perl header from template file,\n>    2018-04-10), now that our dependency graph is correct we can be\n>    confident in dropping it.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n"},{"id":"440632","messageId":"CAPig+cScGUVDnApjQUz90Pm3_MTiUwD1HgX_DP2gc=TQ3ChkeQ@mail.gmail.com","threadId":"56852","inReplyTo":"patch-07.16-24c8f42aa7d-20211106T205717Z-avarab@gmail.com","subject":"Re: [PATCH 07/16] Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-11-07T01:55:10Z","receivedAt":"2021-11-07T01:55:24Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sat, Nov 6, 2021 at 5:03 PM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n> Create a new \"GIT-PYTHON-DEFINES\" file, and untangle the dependency\n> issues of the Python by copying over the patterns established for\n> building the adjacent Perl code in preceding commits.\n>\n> As with Perl, there's no real reason to depend on GIT-BUILD-OPTIONS or\n> GIT-CFLAGS when building the Python code, nor did we need\n> GIT-PREFIX. Let's instead add those variables we care about to a\n> \"GIT-PYTHON-DEFINES\".\n> [...]\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n> diff --git a/Makefile b/Makefile\n> @@ -2369,18 +2369,14 @@ GIT-PERL-DEFINES: FORCE\n> +# Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n> +# on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n> +PYTHON_DEFINES =\n> +$(SCRIPT_PYTHON_GEN): GIT-PYTHON-DEFINES\n> +ifdef NO_PYTHON\n> +PYTHON_DEFINES += $(SHELL_PATH_SQ)\n> +PYTHON_DEFINES += $(NO_PYTHON)\n\nThe comment above this new Python-related goop is talking about PERL?\nIs that intentional?\n"},{"id":"440778","messageId":"xmqqwnlhylgi.fsf@gitster.g","threadId":"56852","inReplyTo":"patch-02.16-2d8049f792c-20211106T205717Z-avarab@gmail.com","subject":"Re: [PATCH 02/16] Makefile: clean perl/build/ even with NO_PERL=Y","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-11-09T23:10:21Z","receivedAt":"2021-11-09T23:10:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Fix a regression in 499c29394ce (Makefile: allow building without\n> perl, 2009-04-03) where we'd stop cleaning the perl/* directory\n> because NO_PERL was defined, thus leaving behind litter if the flag at\n> \"clean\" time didn't match that of build time.\n>\n> In 499c29394ce this was done to avoid relying on the perl/Makefile.PL,\n> but since my 20d2a30f8ff (Makefile: replace perl/Makefile.PL with\n> simple make rules, 2017-12-10) we can clean things in that directory\n> unconditionally.\n\nNicely analyzed. And it is a nice touch to move the removal next to\nwhere we remove the Python stuff.\n\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  Makefile | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/Makefile b/Makefile\n> index 9f57c34e954..82eb8ea446b 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -3234,6 +3234,7 @@ clean: profile-clean coverage-clean cocciclean\n>  \t$(RM) $(HCC)\n>  \t$(RM) -r bin-wrappers $(dep_dirs) $(compdb_dir) compile_commands.json\n>  \t$(RM) -r po/build/\n> +\t$(RM) -r perl/build/\n>  \t$(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope*\n>  \t$(RM) -r .dist-tmp-dir .doc-tmp-dir\n>  \t$(RM) $(GIT_TARNAME).tar.gz\n> @@ -3242,7 +3243,6 @@ clean: profile-clean coverage-clean cocciclean\n>  \t$(RM) Documentation/GIT-EXCLUDED-PROGRAMS\n>  ifndef NO_PERL\n>  \t$(MAKE) -C gitweb clean\n> -\t$(RM) -r perl/build/\n>  endif\n>  \t$(MAKE) -C templates/ clean\n>  \t$(MAKE) -C t/ clean\n"},{"id":"440783","messageId":"xmqqo86szzg1.fsf@gitster.g","threadId":"56852","inReplyTo":"patch-04.16-5affe94b05f-20211106T205717Z-avarab@gmail.com","subject":"Re: [PATCH 04/16] Makefile: move Perl-only variable assignments under !NO_PERL","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-11-09T23:22:54Z","receivedAt":"2021-11-09T23:23:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> -# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n> -# since the locale directory is injected.\n> -perl_localedir_SQ = $(localedir_SQ)\n> -\n\nSo, we used to unconditionally define this even if we had NO_PERL;\nthe patch is going to move it inside \"ifndef NO_PERL\", which makes\nsense.\n\n>  ifndef NO_PERL\n> -PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n>  PERL_DEFINES =\n>  PERL_DEFINES += $(PERL_PATH_SQ)\n>  PERL_DEFINES += $(PERLLIB_EXTRA_SQ)\n> @@ -2305,16 +2300,15 @@ PERL_DEFINES += $(RUNTIME_PREFIX)\n>  PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n>  PERL_DEFINES += $(NO_GETTEXT)\n>  \n> -# Support Perl runtime prefix. In this mode, a different header is installed\n> -# into Perl scripts.\n> +# Under RUNTIME_PREFIX we inject a header into the Perl scripts; If\n> +# NO_GETTEXT is not defined we'll make use of the localedir.\n\n * The second sentence after ';' should not begin with capital.  \n\n * \"if X we do Y\" wants a comma before the latter sentence.\n\n * \"if NO_FOO is not defined\" has too many negations.\n\nTaking them together, I wonder if this would be more readable.\n\n    ... into the Perl scripts; unless NO_GETTEXT is defined, we'll\n    make use of ...\n\n>  ifdef RUNTIME_PREFIX\n> -\n>  PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n> -\n> -# Don't export a fixed $(localedir) path; it will be resolved by the Perl header\n> -# at runtime.\n> -perl_localedir_SQ =\n\nIs it a good idea to lose this?  We would get affected by a stray\nenvironment variable of the same name without it, no?\n\n> +ifndef NO_GETTEXT\n> +perl_localedir_SQ = $(localedir_SQ)\n> +endif\n\n\n> +else\n\nThis \"else\" pairs with... ah, RUNTIME_PREFIX.  And of course we will\nuse the \"fixed\" variant only when RUNTIME_PREFIX is not in use.\n\n> +PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n>  endif\n\nNice. now we have one HEADER_TEMPLATE definition on each branch\nbetween \"using runtime-prefix\" and \"not using runtime-prefix\", which\nmakes sense.\n\n"},{"id":"441003","messageId":"patch-v2-01.18-75ebf7b04e5-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 01/18] Makefile: don't invoke msgfmt with --statistics","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:45Z","receivedAt":"2021-11-12T21:49:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the --statistics flag that I added in 5e9637c6297 (i18n: add\ninfrastructure for translating Git with gettext, 2011-11-18). Our\nMakefile output is good about reducing verbosity by default, except in\nthis case:\n\n    $ rm -rf po/build/locale/e*; time make -j $(nproc) all\n        SUBDIR templates\n        MKDIR -p po/build/locale/el/LC_MESSAGES\n        MSGFMT po/build/locale/el/LC_MESSAGES/git.mo\n        MKDIR -p po/build/locale/es/LC_MESSAGES\n        MSGFMT po/build/locale/es/LC_MESSAGES/git.mo\n    1038 translated messages, 3325 untranslated messages.\n    5230 translated messages.\n\nI didn't have any good reason for using --statistics at the time other\nthan ad-hoc eyeballing of the output. We don't need to spew out\nexactly how many messages we've got translated every time. Now we'll\ninstead emit:\n\n    $ rm -rf po/build/locale/e*; time make -j $(nproc) all\n        SUBDIR templates\n        MKDIR -p po/build/locale/el/LC_MESSAGES\n        MSGFMT po/build/locale/el/LC_MESSAGES/git.mo\n        MKDIR -p po/build/locale/es/LC_MESSAGES\n        MSGFMT po/build/locale/es/LC_MESSAGES/git.mo\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex d56c0e4aadc..11da97de233 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1870,7 +1870,7 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT\n endif\n \n ifndef NO_MSGFMT_EXTENDED_OPTIONS\n-\tMSGFMT += --check --statistics\n+\tMSGFMT += --check\n endif\n \n ifdef HAVE_CLOCK_GETTIME\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441004","messageId":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com","subject":"[PATCH v2 00/18] Makefiles: dependency correctness & speedup","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:44Z","receivedAt":"2021-11-12T21:49:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This is a series to correct various issues in the Makefile. This goes\non top of my ab/sh-retire-helper-functions sitting in \"next\". For a\nmore (and mostly-up-to-date) generic summary see v1 at [1]. Changes\nnoted below.\n\nAs noted in 18/18 there's a noticable speedup and simplification in\nthis series.\n\n1. https://lore.kernel.org/git/cover-00.16-00000000000-20211106T205717Z-avarab@gmail.com/\n\nÆvar Arnfjörð Bjarmason (18):\n  Makefile: don't invoke msgfmt with --statistics\n  Makefile: don't set up \"perl/build\" rules under NO_PERL=Y\n  Makefile: use \"=\" not \":=\" for po/* and perl/*\n  Makefile: clean perl/build/ even with NO_PERL=Y\n  Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR\n  Makefile: guard Perl-only variable assignments\n  Makefile: change \"ifndef NO_PERL\" to \"ifdef NO_PERL\"\n  Makefile: adjust Perl-related comments & whitespace\n  Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph\n  Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"\n\nI corrected pointed-out issues here, dropped some of the changes to\nreduce churn, and split up other things to reduce the diff size.\n\nThe issue with perl_localedir_SQ being overridable from the\nenvironment is fixed here.\n\nI also inverted an if condition in v1 so we'd inject the \"localedir\"\ninto the Perl scripts in cases where we shouldn't. It didn't end up\nmattering since since we'd ignore it anyway with RUN_PREFIX, but let's\nnot do that.\n\n  Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts\n  Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it\n  Makefile: move $(comma), $(empty) and $(space) to shared.mak\n  Makefile: re-add and use the \"shellquote\" macros\n  Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}\n  Makefile: add \"$(QUIET)\" boilerplate to shared.mak\n  Makefile: use $(wspfx) for $(QUIET...) in shared.mak\n  Makefiles: add and use wildcard \"mkdir -p\" template\n\n .gitignore             |   2 +-\n Documentation/Makefile |  71 ++----------\n Makefile               | 254 ++++++++++++++---------------------------\n config.mak.uname       |   1 -\n git-cvsserver.perl     |   6 +-\n git-send-email.perl    |   7 +-\n git-svn.perl           |   2 +-\n shared.mak             | 113 ++++++++++++++++++\n t/Makefile             |  34 +++---\n templates/Makefile     |  19 +--\n 10 files changed, 235 insertions(+), 274 deletions(-)\n create mode 100644 shared.mak\n\nRange-diff against v1:\n16:  7f1081651ed =  1:  75ebf7b04e5 Makefile: don't invoke msgfmt with --statistics\n 1:  56acc94dfe7 =  2:  138f60ba37b Makefile: don't set up \"perl/build\" rules under NO_PERL=Y\n -:  ----------- >  3:  472e1eb74bd Makefile: use \"=\" not \":=\" for po/* and perl/*\n 2:  2d8049f792c =  4:  a5ce2dce164 Makefile: clean perl/build/ even with NO_PERL=Y\n 3:  fa2f10a0cd1 =  5:  04dbc1d2809 Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR\n 4:  5affe94b05f !  6:  eea89794493 Makefile: move Perl-only variable assignments under !NO_PERL\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    Makefile: move Perl-only variable assignments under !NO_PERL\n    +    Makefile: guard Perl-only variable assignments\n     \n    -    Move the assignment to perl_localedir_SQ to be guarded by NO_PERL, and\n    -    furthermore only assign to it if RUNTIME_PREFIX is in effect. If the\n    -    latter isn't being used then we'll default to the empty string, so\n    -    there was no need for the second assignment added in\n    -    07d90eadb50 (Makefile: add Perl runtime prefix support, 2018-04-10).\n    -\n    -    Similarly, we can move the PERL_HEADER_TEMPLATE assignment inside the\n    -    \"!NO_PERL\" block, and having simplified all of this let's consolidate\n    -    three comments on this control flow into one.\n    +    Move the \"ifndef NO_PERL\" a few lines earlier to encompass the\n    +    \"perl_localedir_SQ\" variable. We'll only use it under !NO_PERL.\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    @@ Makefile: git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n      # This makes sure we depend on the NO_PERL setting itself.\n      $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n      \n    --# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n    --# since the locale directory is injected.\n    --perl_localedir_SQ = $(localedir_SQ)\n    --\n    - ifndef NO_PERL\n    --PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n    ++ifndef NO_PERL\n    + # Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n    + # since the locale directory is injected.\n    + perl_localedir_SQ = $(localedir_SQ)\n    + \n    +-ifndef NO_PERL\n    + PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n      PERL_DEFINES =\n      PERL_DEFINES += $(PERL_PATH_SQ)\n    - PERL_DEFINES += $(PERLLIB_EXTRA_SQ)\n    -@@ Makefile: PERL_DEFINES += $(RUNTIME_PREFIX)\n    - PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n    - PERL_DEFINES += $(NO_GETTEXT)\n    - \n    --# Support Perl runtime prefix. In this mode, a different header is installed\n    --# into Perl scripts.\n    -+# Under RUNTIME_PREFIX we inject a header into the Perl scripts; If\n    -+# NO_GETTEXT is not defined we'll make use of the localedir.\n    - ifdef RUNTIME_PREFIX\n    --\n    - PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n    --\n    --# Don't export a fixed $(localedir) path; it will be resolved by the Perl header\n    --# at runtime.\n    --perl_localedir_SQ =\n    --\n    -+ifndef NO_GETTEXT\n    -+perl_localedir_SQ = $(localedir_SQ)\n    -+endif\n    -+else\n    -+PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n    - endif\n    - \n    - PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n -:  ----------- >  7:  e06732d4639 Makefile: change \"ifndef NO_PERL\" to \"ifdef NO_PERL\"\n 5:  d8e14cb723d !  8:  a9502a23989 Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph\n    +    Makefile: adjust Perl-related comments & whitespace\n     \n    -    Fix several small issues with the dependency graph of the generated\n    -    \"GIT-PERL-DEFINES\" and \"GIT-PERL-HEADER\" files:\n    -\n    -    1. Folllow-up my 4070c9e09fc (Makefile: don't re-define PERL_DEFINES,\n    -       2021-05-05) and move the rest of the assignments to PERL_DEFINES to\n    -       one place, and change it from depending on \"localedir_relative_SQ\"\n    -       instead of \"localedir\".\n    -\n    -       The former is what we'll actually use, and while it's unlikely to\n    -       matter in practice (we'd just skip re-building these under\n    -       RUNTIME_PREFIX if the relative path was the same) it makes it\n    -       clearer what's going on here by bringing us to a 1=1 mapping of\n    -       these variables and what's subsequently used in the\n    -       \"GIT-PERL-DEFINES\", \"GIT-PERL-HEADER\" and \"perl/build/lib/%.pm\"\n    -       rules below.\n    -\n    -    2. We don't need the substitution of \" \" for \":\" added in\n    -       07d90eadb50 (Makefile: add Perl runtime prefix support, 2018-04-10),\n    -       let's drop it. This doesn't matter for the correctness of these files,\n    -       but makes it clear  that (unlike GIT-BUILD-OPTIONS) they are not\n    -\n    -    3. Don't have \"GIT-PERL-HEADER\" depend on the \"Makefile\". That was a\n    -       lazy way to over-declare the dependencies added in\n    -       f6a0ad4be71 (Makefile: generate Perl header from template file,\n    -       2018-04-10), now that our dependency graph is correct we can be\n    -       confident in dropping it.\n    +    Folllow-up my 4070c9e09fc (Makefile: don't re-define PERL_DEFINES,\n    +    2021-05-05) and move the rest of the assignments to PERL_DEFINES to\n    +    one place.\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Makefile ##\n    -@@ Makefile: $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n    +@@ Makefile: PERL_DEFINES += $(perllibdir_SQ)\n    + PERL_DEFINES += $(RUNTIME_PREFIX)\n    + PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n    + PERL_DEFINES += $(NO_GETTEXT)\n    ++PERL_DEFINES += $(gitexecdir)\n    ++PERL_DEFINES += $(perllibdir)\n    ++PERL_DEFINES += $(localedir)\n    ++PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n      \n    - ifndef NO_PERL\n    - PERL_DEFINES =\n    -+PERL_DEFINES += $(gitexecdir_relative_SQ)\n    -+PERL_DEFINES += $(perllibdir_relative_SQ)\n    -+PERL_DEFINES += $(localedir_relative_SQ)\n    - PERL_DEFINES += $(PERL_PATH_SQ)\n    - PERL_DEFINES += $(PERLLIB_EXTRA_SQ)\n    - PERL_DEFINES += $(perllibdir_SQ)\n    -@@ Makefile: else\n    - PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n    +-# Support Perl runtime prefix. In this mode, a different header is installed\n    +-# into Perl scripts.\n    + ifdef RUNTIME_PREFIX\n    +-\n    + PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n    + \n    +-# Don't export a fixed $(localedir) path; it will be resolved by the Perl header\n    +-# at runtime.\n    ++# The RUNTIME_PREFIX header defines $Git::I18N::TEXTDOMAINDIR, so\n    ++# $(perl_localedir_SQ) won't be needed\n    + perl_localedir_SQ =\n    +-\n      endif\n      \n     -PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n    @@ Makefile: $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VE\n      GIT-PERL-DEFINES: FORCE\n      \t@FLAGS='$(PERL_DEFINES)'; \\\n      \t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n    -@@ Makefile: GIT-PERL-DEFINES: FORCE\n    - \t\techo \"$$FLAGS\" >$@; \\\n    - \t    fi\n    - \n    --GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n    -+GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES\n    - \t$(QUIET_GEN) \\\n    - \tINSTLIBDIR='$(perllibdir_SQ)' && \\\n    - \tINSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \\\n 6:  03290125c45 !  9:  c1336fc0a56 Makefile: don't have Perl over-depend on GIT-BUILD-OPTIONS\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    Makefile: don't have Perl over-depend on GIT-BUILD-OPTIONS\n    +    Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph\n     \n    -    Change the dependency on \"GIT-BUILD-OPTIONS\" used by\n    -    e.g. \"git-send-email\" to be on \"GIT-PERL-DEFINES instead.\n    +    Fix several small issues with the dependency graph of the generated\n    +    \"GIT-PERL-DEFINES\" and \"GIT-PERL-HEADER\" files:\n     \n    -    The reason for depending on \"GIT-BUILD-OPTIONS\" was to trigger a\n    -    re-build if NO_PERL=Y was defined, we can instead add that variable to\n    -    \"PERL_DEFINES\", and have \"GIT-PERL-DEFINES\" created and updated if\n    -    \"NO_PERL=Y\" is defined.\n    +    1. Don't have \"GIT-PERL-HEADER\" depend on the \"Makefile\". That was a\n    +       lazy way to over-declare the dependencies added in\n    +       f6a0ad4be71 (Makefile: generate Perl header from template file,\n    +       2018-04-10). Let's correct our dependency graph instead.\n    +\n    +    2. Don't have $(SCRIPT_PERL_GEN) (such as \"git-send-email\") depend on\n    +       GIT-BUILD-OPTIONS. Let's instead use GIT-PERL-DEFINES.\n    +\n    +       The reason for depending on \"GIT-BUILD-OPTIONS\" was to trigger a\n    +       re-build if NO_PERL=Y was defined. We can instead add that variable\n    +       to \"PERL_DEFINES\", and have \"GIT-PERL-DEFINES\" created and updated\n    +       if \"NO_PERL=Y\" is defined.\n    +\n    +    3. Due to #2 we'll need to have GIT-PERL-DEFINES be generated even\n    +       under NO_PERL, since that variable will be used by the\n    +       \"unimplemented.sh\" script.\n    +\n    +    4. Don't depend on $(gitexecdir), $(perllibdir) and $(localedir),\n    +       instead depend on the $(*_relative_SQ) versions of those.\n    +\n    +       The latter is what we'll actually use, while it's unlikely to\n    +       matter in practice (we'd just skip re-building these under\n    +       RUNTIME_PREFIX if the relative path was the same) it makes the code\n    +       easier to read.\n    +\n    +       That's because this brings us to a 1=1 mapping of these variables\n    +       and what's subsequently used in the \"GIT-PERL-DEFINES\",\n    +       \"GIT-PERL-HEADER\" and \"perl/build/lib/%.pm\" rules below.\n    +\n    +    5. We don't need the substitution of \" \" for \":\" added in\n    +       07d90eadb50 (Makefile: add Perl runtime prefix support,\n    +       2018-04-10), let's drop it. This doesn't matter for the correctness\n    +       of these files, because unlike GIT-BUILD-OPTIONS nothing is\n    +       consuming them except the Makefile itself.\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    @@ Makefile: git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n      \n     -# This makes sure we depend on the NO_PERL setting itself.\n     -$(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n    --\n    --ifndef NO_PERL\n     +# Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n     +# on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n    - PERL_DEFINES =\n    ++PERL_DEFINES =\n     +$(SCRIPT_PERL_GEN): GIT-PERL-DEFINES\n    -+ifdef NO_PERL\n    + \n    + ifdef NO_PERL\n     +PERL_DEFINES += $(NO_PERL)\n     +\n    -+$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n    -+\t$(QUIET_GEN) \\\n    -+\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n    -+\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n    -+\t    unimplemented.sh >$@+ && \\\n    -+\tchmod +x $@+ && \\\n    -+\tmv $@+ $@\n    + $(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n    + \t$(QUIET_GEN) \\\n    + \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n    +@@ Makefile: $(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n    + \tchmod +x $@+ && \\\n    + \tmv $@+ $@\n    + else # NO_PERL\n    +-# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n    +-# since the locale directory is injected.\n    ++# The localedir is only used in Perl modules if !NO_GETTEXT\n    ++ifndef NO_GETTEXT\n    + perl_localedir_SQ = $(localedir_SQ)\n    ++endif\n    + \n    + PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n    +-PERL_DEFINES =\n    ++\n    + PERL_DEFINES += $(PERL_PATH_SQ)\n    + PERL_DEFINES += $(PERLLIB_EXTRA_SQ)\n    + PERL_DEFINES += $(perllibdir_SQ)\n    + PERL_DEFINES += $(RUNTIME_PREFIX)\n    + PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n    + PERL_DEFINES += $(NO_GETTEXT)\n    +-PERL_DEFINES += $(gitexecdir)\n    +-PERL_DEFINES += $(perllibdir)\n    +-PERL_DEFINES += $(localedir)\n    +-PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n    ++ifdef RUNTIME_PREFIX\n    ++PERL_DEFINES += $(gitexecdir_relative_SQ)\n    ++PERL_DEFINES += $(perllibdir_relative_SQ)\n    ++PERL_DEFINES += $(localedir_relative_SQ)\n     +else\n    - PERL_DEFINES += $(gitexecdir_relative_SQ)\n    - PERL_DEFINES += $(perllibdir_relative_SQ)\n    - PERL_DEFINES += $(localedir_relative_SQ)\n    ++PERL_DEFINES += $(perllocaledir_SQ)\n    ++endif\n    + \n    + ifdef RUNTIME_PREFIX\n    + PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n     @@ Makefile: $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n      \tchmod +x $@+ && \\\n      \tmv $@+ $@\n    @@ Makefile: $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VE\n     -\t\techo \"$$FLAGS\" >$@; \\\n     -\t    fi\n     -\n    - GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES\n    +-GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n    ++GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES\n      \t$(QUIET_GEN) \\\n      \tINSTLIBDIR='$(perllibdir_SQ)' && \\\n    + \tINSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \\\n     @@ Makefile: git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n    - \t$(QUIET_GEN)$(cmd_munge_script) && \\\n    - \tchmod +x $@+ && \\\n      \tmv $@+ $@\n    --else # NO_PERL\n    --$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n    --\t$(QUIET_GEN) \\\n    --\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n    --\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n    --\t    unimplemented.sh >$@+ && \\\n    --\tchmod +x $@+ && \\\n    --\tmv $@+ $@\n      endif # NO_PERL\n      \n     +GIT-PERL-DEFINES: FORCE\n 7:  24c8f42aa7d ! 10:  41f65a12205 Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"\n    @@ Commit message\n         As with Perl, there's no real reason to depend on GIT-BUILD-OPTIONS or\n         GIT-CFLAGS when building the Python code, nor did we need\n         GIT-PREFIX. Let's instead add those variables we care about to a\n    -    \"GIT-PYTHON-DEFINES\".\n    +    \"GIT-PYTHON-DEFINES\" and depend on that.\n     \n         This changes code originally added in ca3bcabf118 (auto-detect changed\n         prefix and/or changed build flags, 2006-06-15), and adjusted in\n    @@ Makefile: GIT-PERL-DEFINES: FORCE\n      \n     -# This makes sure we depend on the NO_PYTHON setting itself.\n     -$(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS\n    -+# Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n    -+# on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n    ++# As with NO_PERL=Y we'll still make GIT-PYTHON-DEFINES if \"NO_PYTHON\"\n    ++# is defined, for creating the \"unimplemented.sh\" scripts.\n     +PYTHON_DEFINES =\n     +$(SCRIPT_PYTHON_GEN): GIT-PYTHON-DEFINES\n    ++\n     +ifdef NO_PYTHON\n     +PYTHON_DEFINES += $(SHELL_PATH_SQ)\n     +PYTHON_DEFINES += $(NO_PYTHON)\n    @@ Makefile: $(SCRIPT_PYTHON_GEN): % : unimplemented.sh\n      \t    unimplemented.sh >$@+ && \\\n      \tchmod +x $@+ && \\\n      \tmv $@+ $@\n    --endif # NO_PYTHON\n    -+else\n    ++else # NO_PYTHON\n     +PYTHON_DEFINES += $(PYTHON_PATH_SQ)\n     +\n    -+$(SCRIPT_PYTHON_GEN): % : %.py\n    ++$(SCRIPT_PYTHON_GEN): % : %.py GIT-PYTHON-DEFINES\n     +\t$(QUIET_GEN) \\\n     +\tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n     +\t    $< >$@+ && \\\n     +\tchmod +x $@+ && \\\n     +\tmv $@+ $@\n    -+endif # PYTHON\n    -+\n    + endif # NO_PYTHON\n    + \n     +GIT-PYTHON-DEFINES: FORCE\n     +\t@FLAGS='$(PYTHON_DEFINES)'; \\\n     +\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n     +\t\techo >&2 \"    * new python-specific parameters\"; \\\n     +\t\techo \"$$FLAGS\" >$@; \\\n     +\t    fi\n    - \n    ++\n      CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n      \t\t\tconfigure.ac >configure.ac+ && \\\n    + \t\t   autoconf -o configure configure.ac+ && \\\n     @@ Makefile: else\n      endif\n      \t@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi\n 8:  e3b52cf8da5 ! 11:  bfa15059d60 Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts\n    @@ Commit message\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Makefile ##\n    -@@ Makefile: else\n    - PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n    +@@ Makefile: PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n    + perl_localedir_SQ =\n      endif\n      \n     -$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n 9:  e23663bfb20 = 12:  656d02ab641 Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it\n10:  67ba72dc2e6 = 13:  6e25ac71cbc Makefile: move $(comma), $(empty) and $(space) to shared.mak\n11:  67dbad03c14 = 14:  64296e6e8e5 Makefile: re-add and use the \"shellquote\" macros\n12:  5930a08cb4e ! 15:  5654d7f7f29 Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}\n    @@ Makefile: git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n     -\t    fi\n     +$(eval $(call TRACK_template,GIT-PERL-DEFINES,PERL_DEFINES))\n      \n    - # Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n    - # on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n    -@@ Makefile: $(SCRIPT_PYTHON_GEN): % : %.py\n    + # As with NO_PERL=Y we'll still make GIT-PYTHON-DEFINES if \"NO_PYTHON\"\n    + # is defined, for creating the \"unimplemented.sh\" scripts.\n    +@@ Makefile: $(SCRIPT_PYTHON_GEN): % : %.py GIT-PYTHON-DEFINES\n      \tmv $@+ $@\n    - endif # PYTHON\n    + endif # NO_PYTHON\n      \n     -GIT-PYTHON-DEFINES: FORCE\n     -\t@FLAGS='$(PYTHON_DEFINES)'; \\\n13:  d927202fb89 ! 16:  0a348b54491 Makefile: add \"$(QUIET)\" boilerplate to shared.mak\n    @@ config.mak.uname: vcxproj:\n      \n     \n      ## shared.mak ##\n    -@@ shared.mak: $(1): FORCE\n    - \t\techo \"$$$$FLAGS\" >$(1); \\\n    - \tfi\n    - endef\n    -+\n    +@@ shared.mak: space = $(empty) $(empty)\n    + wspfx = $(space)$(space)$(space)\n    + wspfx_sq = $(call shellquote,$(wspfx))\n    + \n     +### Quieting\n     +## common\n     +QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n    @@ shared.mak: $(1): FORCE\n     +\texport V\n     +endif\n     +endif\n    ++\n    + ### Templates\n    + \n    + ## Template for making a GIT-SOMETHING, which changes if a\n     \n      ## templates/Makefile ##\n     @@\n14:  2966218d6c8 = 17:  34f692144d1 Makefile: use $(wspfx) for $(QUIET...) in shared.mak\n15:  412a11f63a3 ! 18:  5b3986bc4a8 Makefiles: add and use wildcard \"mkdir -p\" template\n    @@ Commit message\n     \n         But as it turns out we can use this neat trick of only doing a \"mkdir\n         -p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\n    -    of the performance test I noted downthread of [1] in [2] shows that\n    -    this is faster, in addition to being less verbose and more reliable:\n    +    of a performance test similar to thatnoted downthread of [1] in [2]\n    +    shows that this is faster, in addition to being less verbose and more\n    +    reliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n     \n    -        $ hyperfine --warmup 5 -m 30 -L s \",~\" -p 'git checkout HEAD{s} -- Makefile; rm -rf .build' 'make -j8 lint-docs R={s}'\n    -         -c 'git checkout HEAD -- Makefile'\n    -        Benchmark #1: make -j8 lint-docs R=\n    -          Time (mean ± σ):     537.5 ms ±   7.1 ms    [User: 2.412 s, System: 0.460 s]\n    -          Range (min … max):   530.2 ms … 564.9 ms    30 runs\n    +        $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n    +        Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n    +          Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n    +          Range (min … max):    2.121 s …  2.158 s    10 runs\n     \n    -        Benchmark #2: make -j8 lint-docs R=~\n    -          Time (mean ± σ):     645.7 ms ±   7.1 ms    [User: 3.083 s, System: 0.630 s]\n    -          Range (min … max):   637.4 ms … 675.2 ms    30 runs\n    +        Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n    +          Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n    +          Range (min … max):    2.657 s …  2.662 s    10 runs\n     \n             Summary\n    -          'make -j8 lint-docs R=' ran\n    -            1.20 ± 0.02 times faster than 'make -j8 lint-docs R=~'\n    +          'make -C Documentation lint-docs' in 'HEAD~0' ran\n    +            1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n     \n         So let's use that pattern both for the \"lint-docs\" target, and a few\n         miscellaneous other targets.\n    @@ Commit message\n     \n         1. https://lore.kernel.org/git/211028.861r45y3pt.gmgdl@evledraar.gmail.com/\n         2. https://lore.kernel.org/git/211028.86o879vvtp.gmgdl@evledraar.gmail.com/\n    +    3. https://gitlab.com/avar/git-hyperfine/\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    @@ Makefile: all:: $(MOFILES)\n     +\t$(QUIET_MSGFMT)$(MSGFMT) -o $@ $<\n      \n      ifndef NO_PERL\n    - LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n    -@@ Makefile: LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n    - LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n    + LIB_PERL = $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n    +@@ Makefile: LIB_CPAN = $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n    + LIB_CPAN_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n      \n      perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n     -\t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n    @@ shared.mak: ifndef V\n      \tQUIET_CC       = @echo $(wspfx_sq) CC $@;\n      \tQUIET_AR       = @echo $(wspfx_sq) AR $@;\n     @@ shared.mak: ifndef V\n    - \texport V\n      endif\n      endif\n    -+\n    + \n     +## Helpers\n     +define mkdir_p_parent_template\n     +$(if $(wildcard $(@D)),,$(QUIET_MKDIR_P_PARENT)$(shell mkdir -p $(@D)))\n     +endef\n    ++\n    + ### Templates\n    + \n    + ## Template for making a GIT-SOMETHING, which changes if a\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441005","messageId":"patch-v2-02.18-138f60ba37b-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 02/18] Makefile: don't set up \"perl/build\" rules under NO_PERL=Y","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:46Z","receivedAt":"2021-11-12T21:49:21Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Do not define LIB_{PERL,CPAN}{,_GEN} if NO_PERL is defined. This\nchanges no functionality, but makes it clear which of these rules are\nneeded under NO_PERL=Y. See 20d2a30f8ff (Makefile: replace\nperl/Makefile.PL with simple make rules, 2017-12-10) for the initial\nimplementation.\n\nWe do for better or worse rely on \"install-doc\" calling\n\"install-man-perl\" regardless of whether NO_PERL=Y is defined or not,\ni.e. we'll always end up with that manual page, even if we don't have\nany of the Perl code installed. Let's add a comment about that\nadjacent to the rules that build perl/build.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 17 +++++++++--------\n 1 file changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 11da97de233..06405825a24 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2684,19 +2684,12 @@ endif\n po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n \t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n \n+ifndef NO_PERL\n LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n-ifndef NO_PERL\n-all:: $(LIB_PERL_GEN)\n-ifndef NO_PERL_CPAN_FALLBACKS\n-all:: $(LIB_CPAN_GEN)\n-endif\n-NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n-endif\n-\n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n@@ -2704,6 +2697,14 @@ perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \\\n \t< $< > $@\n \n+all:: $(LIB_PERL_GEN)\n+ifndef NO_PERL_CPAN_FALLBACKS\n+all:: $(LIB_CPAN_GEN)\n+endif\n+NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n+endif\n+\n+# install-man depends on Git.3pm even with NO_PERL=Y\n perl/build/man/man3/Git.3pm: perl/Git.pm\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tpod2man $< $@\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441006","messageId":"patch-v2-03.18-472e1eb74bd-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 03/18] Makefile: use \"=\" not \":=\" for po/* and perl/*","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:47Z","receivedAt":"2021-11-12T21:49:22Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change these variable definitions from being simply-expanded to be\nrecursively expanded instead. I.e. they'll be lazily expanded when\nused.\n\nI added these in 5e9637c6297 (i18n: add infrastructure for translating\nGit with gettext, 2011-11-18) and 20d2a30f8ff (Makefile: replace\nperl/Makefile.PL with simple make rules, 2017-12-10), the reason for\nusing \":=\" over \"=\" was that I didn't know the difference in 2011 (I\nthink I copied some POC code), and in 2017 I used the 2011 commit for\nreference.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 16 ++++++++--------\n 1 file changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 06405825a24..6b77702e102 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2672,11 +2672,11 @@ po/git.pot: $(GENERATED_H) FORCE\n pot: po/git.pot\n \n ifdef NO_GETTEXT\n-POFILES :=\n-MOFILES :=\n+POFILES =\n+MOFILES =\n else\n-POFILES := $(wildcard po/*.po)\n-MOFILES := $(patsubst po/%.po,po/build/locale/%/LC_MESSAGES/git.mo,$(POFILES))\n+POFILES = $(wildcard po/*.po)\n+MOFILES = $(patsubst po/%.po,po/build/locale/%/LC_MESSAGES/git.mo,$(POFILES))\n \n all:: $(MOFILES)\n endif\n@@ -2685,10 +2685,10 @@ po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n \t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n \n ifndef NO_PERL\n-LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n-LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n-LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n-LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n+LIB_PERL = $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n+LIB_PERL_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n+LIB_CPAN = $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n+LIB_CPAN_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441007","messageId":"patch-v2-04.18-a5ce2dce164-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 04/18] Makefile: clean perl/build/ even with NO_PERL=Y","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:48Z","receivedAt":"2021-11-12T21:49:24Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a regression in 499c29394ce (Makefile: allow building without\nperl, 2009-04-03) where we'd stop cleaning the perl/* directory\nbecause NO_PERL was defined, thus leaving behind litter if the flag at\n\"clean\" time didn't match that of build time.\n\nIn 499c29394ce this was done to avoid relying on the perl/Makefile.PL,\nbut since my 20d2a30f8ff (Makefile: replace perl/Makefile.PL with\nsimple make rules, 2017-12-10) we can clean things in that directory\nunconditionally.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex 6b77702e102..a71fba15e30 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -3234,6 +3234,7 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) $(HCC)\n \t$(RM) -r bin-wrappers $(dep_dirs) $(compdb_dir) compile_commands.json\n \t$(RM) -r po/build/\n+\t$(RM) -r perl/build/\n \t$(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope*\n \t$(RM) -r .dist-tmp-dir .doc-tmp-dir\n \t$(RM) $(GIT_TARNAME).tar.gz\n@@ -3242,7 +3243,6 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) Documentation/GIT-EXCLUDED-PROGRAMS\n ifndef NO_PERL\n \t$(MAKE) -C gitweb clean\n-\t$(RM) -r perl/build/\n endif\n \t$(MAKE) -C templates/ clean\n \t$(MAKE) -C t/ clean\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441008","messageId":"patch-v2-05.18-04dbc1d2809-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 05/18] Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:49Z","receivedAt":"2021-11-12T21:49:25Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Since 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\" flag,\n2021-06-29) we don't need to guard the clobbering of $@ with this sort\nof \"mv $@+ $@\" pattern in these cases where we're merely generating a\nfile that'll be used as a dependency for other files, as in this case\nfor GIT-PERL-HEADER.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex a71fba15e30..284725099c9 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2349,8 +2349,7 @@ GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n \t    -e 's=@@PERLLIBDIR_REL@@=$(perllibdir_relative_SQ)=g' \\\n \t    -e 's=@@GITEXECDIR_REL@@=$(gitexecdir_relative_SQ)=g' \\\n \t    -e 's=@@LOCALEDIR_REL@@=$(localedir_relative_SQ)=g' \\\n-\t    $< >$@+ && \\\n-\tmv $@+ $@\n+\t    $< >$@\n \n .PHONY: perllibdir\n perllibdir:\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441009","messageId":"patch-v2-07.18-e06732d4639-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 07/18] Makefile: change \"ifndef NO_PERL\" to \"ifdef NO_PERL\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:51Z","receivedAt":"2021-11-12T21:49:26Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the NO_PERL variable assignments so that they declare the much\nsmaller fallback condition first.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 18 +++++++++---------\n 1 file changed, 9 insertions(+), 9 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 0cb10f00ebb..288f4834db8 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2291,7 +2291,15 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n # This makes sure we depend on the NO_PERL setting itself.\n $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n-ifndef NO_PERL\n+ifdef NO_PERL\n+$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n+\t$(QUIET_GEN) \\\n+\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n+\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n+\t    unimplemented.sh >$@+ && \\\n+\tchmod +x $@+ && \\\n+\tmv $@+ $@\n+else # NO_PERL\n # Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n # since the locale directory is injected.\n perl_localedir_SQ = $(localedir_SQ)\n@@ -2363,14 +2371,6 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \t$(QUIET_GEN)$(cmd_munge_script) && \\\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n-else # NO_PERL\n-$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n-\t$(QUIET_GEN) \\\n-\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n-\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n-\t    unimplemented.sh >$@+ && \\\n-\tchmod +x $@+ && \\\n-\tmv $@+ $@\n endif # NO_PERL\n \n # This makes sure we depend on the NO_PYTHON setting itself.\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441010","messageId":"patch-v2-09.18-c1336fc0a56-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 09/18] Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:53Z","receivedAt":"2021-11-12T21:49:27Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix several small issues with the dependency graph of the generated\n\"GIT-PERL-DEFINES\" and \"GIT-PERL-HEADER\" files:\n\n1. Don't have \"GIT-PERL-HEADER\" depend on the \"Makefile\". That was a\n   lazy way to over-declare the dependencies added in\n   f6a0ad4be71 (Makefile: generate Perl header from template file,\n   2018-04-10). Let's correct our dependency graph instead.\n\n2. Don't have $(SCRIPT_PERL_GEN) (such as \"git-send-email\") depend on\n   GIT-BUILD-OPTIONS. Let's instead use GIT-PERL-DEFINES.\n\n   The reason for depending on \"GIT-BUILD-OPTIONS\" was to trigger a\n   re-build if NO_PERL=Y was defined. We can instead add that variable\n   to \"PERL_DEFINES\", and have \"GIT-PERL-DEFINES\" created and updated\n   if \"NO_PERL=Y\" is defined.\n\n3. Due to #2 we'll need to have GIT-PERL-DEFINES be generated even\n   under NO_PERL, since that variable will be used by the\n   \"unimplemented.sh\" script.\n\n4. Don't depend on $(gitexecdir), $(perllibdir) and $(localedir),\n   instead depend on the $(*_relative_SQ) versions of those.\n\n   The latter is what we'll actually use, while it's unlikely to\n   matter in practice (we'd just skip re-building these under\n   RUNTIME_PREFIX if the relative path was the same) it makes the code\n   easier to read.\n\n   That's because this brings us to a 1=1 mapping of these variables\n   and what's subsequently used in the \"GIT-PERL-DEFINES\",\n   \"GIT-PERL-HEADER\" and \"perl/build/lib/%.pm\" rules below.\n\n5. We don't need the substitution of \" \" for \":\" added in\n   07d90eadb50 (Makefile: add Perl runtime prefix support,\n   2018-04-10), let's drop it. This doesn't matter for the correctness\n   of these files, because unlike GIT-BUILD-OPTIONS nothing is\n   consuming them except the Makefile itself.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 42 +++++++++++++++++++++++++-----------------\n 1 file changed, 25 insertions(+), 17 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex ab78f8dd42e..361abff2402 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2288,10 +2288,14 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n \t    $(shell echo $(GIT_VERSION) 0 0 0 0 | tr '.a-zA-Z-' ' '))) \\\n \t  -DGIT_VERSION=\"\\\\\\\"$(GIT_VERSION)\\\\\\\"\" -i $< -o $@\n \n-# This makes sure we depend on the NO_PERL setting itself.\n-$(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n+# Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n+# on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n+PERL_DEFINES =\n+$(SCRIPT_PERL_GEN): GIT-PERL-DEFINES\n \n ifdef NO_PERL\n+PERL_DEFINES += $(NO_PERL)\n+\n $(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n \t$(QUIET_GEN) \\\n \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2300,22 +2304,26 @@ $(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n else # NO_PERL\n-# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n-# since the locale directory is injected.\n+# The localedir is only used in Perl modules if !NO_GETTEXT\n+ifndef NO_GETTEXT\n perl_localedir_SQ = $(localedir_SQ)\n+endif\n \n PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n-PERL_DEFINES =\n+\n PERL_DEFINES += $(PERL_PATH_SQ)\n PERL_DEFINES += $(PERLLIB_EXTRA_SQ)\n PERL_DEFINES += $(perllibdir_SQ)\n PERL_DEFINES += $(RUNTIME_PREFIX)\n PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n PERL_DEFINES += $(NO_GETTEXT)\n-PERL_DEFINES += $(gitexecdir)\n-PERL_DEFINES += $(perllibdir)\n-PERL_DEFINES += $(localedir)\n-PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n+ifdef RUNTIME_PREFIX\n+PERL_DEFINES += $(gitexecdir_relative_SQ)\n+PERL_DEFINES += $(perllibdir_relative_SQ)\n+PERL_DEFINES += $(localedir_relative_SQ)\n+else\n+PERL_DEFINES += $(perllocaledir_SQ)\n+endif\n \n ifdef RUNTIME_PREFIX\n PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n@@ -2337,14 +2345,7 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n-GIT-PERL-DEFINES: FORCE\n-\t@FLAGS='$(PERL_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new perl-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n-\n-GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n+GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES\n \t$(QUIET_GEN) \\\n \tINSTLIBDIR='$(perllibdir_SQ)' && \\\n \tINSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \\\n@@ -2370,6 +2371,13 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \tmv $@+ $@\n endif # NO_PERL\n \n+GIT-PERL-DEFINES: FORCE\n+\t@FLAGS='$(PERL_DEFINES)'; \\\n+\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n+\t\techo >&2 \"    * new perl-specific parameters\"; \\\n+\t\techo \"$$FLAGS\" >$@; \\\n+\t    fi\n+\n # This makes sure we depend on the NO_PYTHON setting itself.\n $(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS\n \n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441011","messageId":"patch-v2-06.18-eea89794493-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 06/18] Makefile: guard Perl-only variable assignments","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:50Z","receivedAt":"2021-11-12T21:49:29Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move the \"ifndef NO_PERL\" a few lines earlier to encompass the\n\"perl_localedir_SQ\" variable. We'll only use it under !NO_PERL.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex 284725099c9..0cb10f00ebb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2291,11 +2291,11 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n # This makes sure we depend on the NO_PERL setting itself.\n $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n+ifndef NO_PERL\n # Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n # since the locale directory is injected.\n perl_localedir_SQ = $(localedir_SQ)\n \n-ifndef NO_PERL\n PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n PERL_DEFINES =\n PERL_DEFINES += $(PERL_PATH_SQ)\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441019","messageId":"patch-v2-08.18-a9502a23989-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 08/18] Makefile: adjust Perl-related comments & whitespace","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:52Z","receivedAt":"2021-11-12T21:49:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Folllow-up my 4070c9e09fc (Makefile: don't re-define PERL_DEFINES,\n2021-05-05) and move the rest of the assignments to PERL_DEFINES to\none place.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 15 ++++++---------\n 1 file changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 288f4834db8..ab78f8dd42e 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2312,21 +2312,19 @@ PERL_DEFINES += $(perllibdir_SQ)\n PERL_DEFINES += $(RUNTIME_PREFIX)\n PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n PERL_DEFINES += $(NO_GETTEXT)\n+PERL_DEFINES += $(gitexecdir)\n+PERL_DEFINES += $(perllibdir)\n+PERL_DEFINES += $(localedir)\n+PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n \n-# Support Perl runtime prefix. In this mode, a different header is installed\n-# into Perl scripts.\n ifdef RUNTIME_PREFIX\n-\n PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n \n-# Don't export a fixed $(localedir) path; it will be resolved by the Perl header\n-# at runtime.\n+# The RUNTIME_PREFIX header defines $Git::I18N::TEXTDOMAINDIR, so\n+# $(perl_localedir_SQ) won't be needed\n perl_localedir_SQ =\n-\n endif\n \n-PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n-\n $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \t$(QUIET_GEN) \\\n \tsed -e '1{' \\\n@@ -2339,7 +2337,6 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n-PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n GIT-PERL-DEFINES: FORCE\n \t@FLAGS='$(PERL_DEFINES)'; \\\n \t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441015","messageId":"patch-v2-10.18-41f65a12205-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 10/18] Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:54Z","receivedAt":"2021-11-12T21:49:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Create a new \"GIT-PYTHON-DEFINES\" file, and untangle the dependency\nissues of the Python by copying over the patterns established for\nbuilding the adjacent Perl code in preceding commits.\n\nAs with Perl, there's no real reason to depend on GIT-BUILD-OPTIONS or\nGIT-CFLAGS when building the Python code, nor did we need\nGIT-PREFIX. Let's instead add those variables we care about to a\n\"GIT-PYTHON-DEFINES\" and depend on that.\n\nThis changes code originally added in ca3bcabf118 (auto-detect changed\nprefix and/or changed build flags, 2006-06-15), and adjusted in\n96a4647fca5 (Makefile: detect when PYTHON_PATH changes, 2012-12-18).\n\nThe relevant code for the \"Perl\" targets was then added in\n07981dce81e (Makefile: rebuild perl scripts when perl paths change,\n2013-11-18), and has been adjusted in preceding commits.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n .gitignore |  2 +-\n Makefile   | 49 +++++++++++++++++++++++++------------------------\n 2 files changed, 26 insertions(+), 25 deletions(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 054249b20a8..845e5d0c355 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -8,7 +8,7 @@\n /GIT-PREFIX\n /GIT-PERL-DEFINES\n /GIT-PERL-HEADER\n-/GIT-PYTHON-VARS\n+/GIT-PYTHON-DEFINES\n /GIT-SCRIPT-DEFINES\n /GIT-USER-AGENT\n /GIT-VERSION-FILE\ndiff --git a/Makefile b/Makefile\nindex 361abff2402..c698c5b058a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2378,18 +2378,15 @@ GIT-PERL-DEFINES: FORCE\n \t\techo \"$$FLAGS\" >$@; \\\n \t    fi\n \n-# This makes sure we depend on the NO_PYTHON setting itself.\n-$(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS\n+# As with NO_PERL=Y we'll still make GIT-PYTHON-DEFINES if \"NO_PYTHON\"\n+# is defined, for creating the \"unimplemented.sh\" scripts.\n+PYTHON_DEFINES =\n+$(SCRIPT_PYTHON_GEN): GIT-PYTHON-DEFINES\n+\n+ifdef NO_PYTHON\n+PYTHON_DEFINES += $(SHELL_PATH_SQ)\n+PYTHON_DEFINES += $(NO_PYTHON)\n \n-ifndef NO_PYTHON\n-$(SCRIPT_PYTHON_GEN): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS\n-$(SCRIPT_PYTHON_GEN): % : %.py\n-\t$(QUIET_GEN) \\\n-\tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n-\t    $< >$@+ && \\\n-\tchmod +x $@+ && \\\n-\tmv $@+ $@\n-else # NO_PYTHON\n $(SCRIPT_PYTHON_GEN): % : unimplemented.sh\n \t$(QUIET_GEN) \\\n \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2397,8 +2394,24 @@ $(SCRIPT_PYTHON_GEN): % : unimplemented.sh\n \t    unimplemented.sh >$@+ && \\\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n+else # NO_PYTHON\n+PYTHON_DEFINES += $(PYTHON_PATH_SQ)\n+\n+$(SCRIPT_PYTHON_GEN): % : %.py GIT-PYTHON-DEFINES\n+\t$(QUIET_GEN) \\\n+\tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n+\t    $< >$@+ && \\\n+\tchmod +x $@+ && \\\n+\tmv $@+ $@\n endif # NO_PYTHON\n \n+GIT-PYTHON-DEFINES: FORCE\n+\t@FLAGS='$(PYTHON_DEFINES)'; \\\n+\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n+\t\techo >&2 \"    * new python-specific parameters\"; \\\n+\t\techo \"$$FLAGS\" >$@; \\\n+\t    fi\n+\n CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t\t\tconfigure.ac >configure.ac+ && \\\n \t\t   autoconf -o configure configure.ac+ && \\\n@@ -2848,18 +2861,6 @@ else\n endif\n \t@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi\n \n-### Detect Python interpreter path changes\n-ifndef NO_PYTHON\n-TRACK_PYTHON = $(subst ','\\'',-DPYTHON_PATH='$(PYTHON_PATH_SQ)')\n-\n-GIT-PYTHON-VARS: FORCE\n-\t@VARS='$(TRACK_PYTHON)'; \\\n-\t    if test x\"$$VARS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new Python interpreter location\"; \\\n-\t\techo \"$$VARS\" >$@; \\\n-            fi\n-endif\n-\n test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))\n \n all:: $(TEST_PROGRAMS) $(test_bindir_programs)\n@@ -3256,7 +3257,7 @@ ifndef NO_TCLTK\n endif\n \t$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS\n \t$(RM) GIT-USER-AGENT GIT-PREFIX\n-\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS\n+\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-DEFINES\n ifdef MSVC\n \t$(RM) $(patsubst %.o,%.o.pdb,$(OBJECTS))\n \t$(RM) $(patsubst %.exe,%.pdb,$(OTHER_PROGRAMS))\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441012","messageId":"patch-v2-12.18-656d02ab641-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 12/18] Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:56Z","receivedAt":"2021-11-12T21:49:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We have various behavior that's shared across our Makefiles, or that\nreally should be (e.g. via defined templates). Let's create a\ntop-level \"shared.mak\" to house those sorts of things, and start by\nadding the \".DELETE_ON_ERROR\" flag to it.\n\nSee my own 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\"\nflag, 2021-06-29) and db10fc6c09f (doc: simplify Makefile using\n.DELETE_ON_ERROR, 2021-05-21) for the addition and use of the\n\".DELETE_ON_ERROR\" flag.\n\nThis does have the potential downside that if e.g. templates/Makefile\nwould like to include this \"shared.mak\" in the future the semantics of\nsuch a Makefile will change, but as noted in the above commits (and\nGNU make's own documentation) any such change would be for the better,\nso it's safe to do this.\n\nThis also doesn't introduce a bug by e.g. having this\n\".DELETE_ON_ERROR\" flag only apply to this new shared.mak, Makefiles\nhave no such scoping semantics.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile |  6 +++---\n Makefile               | 13 +++----------\n shared.mak             |  9 +++++++++\n 3 files changed, 15 insertions(+), 13 deletions(-)\n create mode 100644 shared.mak\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ed656db2ae9..ba27456c86a 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # Guard against environment variables\n MAN1_TXT =\n MAN5_TXT =\n@@ -524,7 +527,4 @@ doc-l10n install-l10n::\n \t$(MAKE) -C po $@\n endif\n \n-# Delete the target file on error\n-.DELETE_ON_ERROR:\n-\n .PHONY: FORCE\ndiff --git a/Makefile b/Makefile\nindex 8205614c6ec..5ae7d012cfb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include shared.mak\n+\n # The default target of this Makefile is...\n all::\n \n@@ -2158,16 +2161,6 @@ shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell\n strip: $(PROGRAMS) git$X\n \t$(STRIP) $(STRIP_OPTS) $^\n \n-### Flags affecting all rules\n-\n-# A GNU make extension since gmake 3.72 (released in late 1994) to\n-# remove the target of rules if commands in those rules fail. The\n-# default is to only do that if make itself receives a signal. Affects\n-# all targets, see:\n-#\n-#    info make --index-search=.DELETE_ON_ERROR\n-.DELETE_ON_ERROR:\n-\n ### Target-specific flags and dependencies\n \n # The generic compilation pattern rule and automatically\ndiff --git a/shared.mak b/shared.mak\nnew file mode 100644\nindex 00000000000..0170bb397ae\n--- /dev/null\n+++ b/shared.mak\n@@ -0,0 +1,9 @@\n+### Flags affecting all rules\n+\n+# A GNU make extension since gmake 3.72 (released in late 1994) to\n+# remove the target of rules if commands in those rules fail. The\n+# default is to only do that if make itself receives a signal. Affects\n+# all targets, see:\n+#\n+#    info make --index-search=.DELETE_ON_ERROR\n+.DELETE_ON_ERROR:\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441013","messageId":"patch-v2-13.18-6e25ac71cbc-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 13/18] Makefile: move $(comma), $(empty) and $(space) to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:57Z","receivedAt":"2021-11-12T21:49:34Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move these variables over to the shared.max, we'll make use of them in\na subsequent commit. There was no reason for these to be \"simply\nexpanded variables\", so let's use the normal lazy \"=\" assignment here.\n\nSee 425ca6710b2 (Makefile: allow combining UBSan with other\nsanitizers, 2017-07-15) for the commit that introduced these.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile   | 4 ----\n shared.mak | 8 ++++++++\n 2 files changed, 8 insertions(+), 4 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 5ae7d012cfb..7130e32a251 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1252,10 +1252,6 @@ endif\n ALL_CFLAGS = $(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS)\n ALL_LDFLAGS = $(LDFLAGS)\n \n-comma := ,\n-empty :=\n-space := $(empty) $(empty)\n-\n ifdef SANITIZE\n SANITIZERS := $(foreach flag,$(subst $(comma),$(space),$(SANITIZE)),$(flag))\n BASIC_CFLAGS += -fsanitize=$(SANITIZE) -fno-sanitize-recover=$(SANITIZE)\ndiff --git a/shared.mak b/shared.mak\nindex 0170bb397ae..2d597ef7603 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -7,3 +7,11 @@\n #\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n+\n+### Global variables\n+\n+## comma, empty, space: handy variables as these tokens are either\n+## special or can be hard to spot among other Makefile syntax.\n+comma = ,\n+empty =\n+space = $(empty) $(empty)\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441014","messageId":"patch-v2-14.18-64296e6e8e5-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 14/18] Makefile: re-add and use the \"shellquote\" macros","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:58Z","receivedAt":"2021-11-12T21:49:35Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Re-add and use, and expand on \"shellquote\" macros added in\n4769948afe7 (Deal with $(bindir) and friends with whitespaces.,\n2005-10-10).\n\nWe avoided using them due to the \"$(call)\" feature of GNU make being\nrelatively new at the time, but it isn't anymore. We hard depend on\nGNU make versions that have it.\n\nThe use of \"$(call)\" was removed in 39c015c556f (Fixes for ancient\nversions of GNU make, 2006-02-18) and 7ffe7098dca (Fix installation of\ntemplates on ancient systems., 2006-07-29) due to those\nincompatibilities with older GNU make versions, and we've used the\nmore verbose *_SQ pattern ever since.\n\nThe \"$(call)\" feature was introduced in GNU make version 3.78,\nreleased on the 22nd of September, 1999. That release also introduced\n\"$(error)\" and \"$(warning)\", which we've been making use of since\nf2fabbf76e4 (Teach Makefile to check header dependencies, 2010-01-26).\n\nThis extends upon the macros added in 4769948afe7: We now have macros\nfor quoting a ' inside '', and a ' with no surrounding '' as before.\n\nAdditionally provide and use a \"shelldquote\" macro along with\n\"shellquote\" for the common case of wanting to quote a C string we\npass to the compiler with a -D flag.\n\nThis doesn't get rid of all of our shell quoting. We've still got some\nin the main Makefile, let's leave most of it to avoid in-flight\nconflicts. I've fully converted \"templates/Makefile\" and \"t/Makefile\"\nthough.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile           | 15 +++++----------\n shared.mak         | 14 ++++++++++++++\n t/Makefile         | 34 +++++++++++++++-------------------\n templates/Makefile | 14 +++++---------\n 4 files changed, 39 insertions(+), 38 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 7130e32a251..b458c24d95e 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1996,11 +1996,7 @@ ifneq (\"$(PROFILE)\",\"\")\n endif\n endif\n \n-# Shell quote (do not use $(call) to accommodate ancient setups);\n-\n-ETC_GITCONFIG_SQ = $(subst ','\\'',$(ETC_GITCONFIG))\n-ETC_GITATTRIBUTES_SQ = $(subst ','\\'',$(ETC_GITATTRIBUTES))\n-\n+# Shell quote, should be changed to use $(call shellquote,...)\n DESTDIR_SQ = $(subst ','\\'',$(DESTDIR))\n NO_GETTEXT_SQ = $(subst ','\\'',$(NO_GETTEXT))\n bindir_SQ = $(subst ','\\'',$(bindir))\n@@ -2535,11 +2531,11 @@ builtin/init-db.sp builtin/init-db.s builtin/init-db.o: EXTRA_CPPFLAGS = \\\n \n config.sp config.s config.o: GIT-PREFIX\n config.sp config.s config.o: EXTRA_CPPFLAGS = \\\n-\t-DETC_GITCONFIG='\"$(ETC_GITCONFIG_SQ)\"'\n+\t-DETC_GITCONFIG=$(call shelldquote,$(ETC_GITCONFIG))\n \n attr.sp attr.s attr.o: GIT-PREFIX\n attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \\\n-\t-DETC_GITATTRIBUTES='\"$(ETC_GITATTRIBUTES_SQ)\"'\n+\t-DETC_GITATTRIBUTES=$(call shelldquote,$(ETC_GITATTRIBUTES))\n \n gettext.sp gettext.s gettext.o: GIT-PREFIX\n gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \\\n@@ -2700,14 +2696,13 @@ perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n \t    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \\\n-\t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \\\n+\t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(call shq,$(NO_PERL_CPAN_FALLBACKS))|g' \\\n \t< $< > $@\n \n all:: $(LIB_PERL_GEN)\n ifndef NO_PERL_CPAN_FALLBACKS\n all:: $(LIB_CPAN_GEN)\n endif\n-NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n endif\n \n # install-man depends on Git.3pm even with NO_PERL=Y\n@@ -3021,7 +3016,7 @@ else\n \t$(INSTALL) $(vcpkg_dbg_bin)/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'\n endif\n endif\n-\t$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install\n+\t$(MAKE) -C templates DESTDIR=$(call shellquote,$(DESTDIR)) install\n \t$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'\n \t$(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'\n ifndef NO_GETTEXT\ndiff --git a/shared.mak b/shared.mak\nindex 2d597ef7603..ef03c2bc094 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -8,6 +8,20 @@\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n \n+### Quoting helpers\n+\n+## Quote a ' inside a '': FOO='$(call shq,$(BAR))'\n+shq = $(subst ','\\'',$(1))\n+\n+## Quote a ' and provide a '': FOO=$(call shq,$(BAR))\n+shellquote = '$(call shq,$(1))'\n+\n+## Quote a \" inside a \"\"\n+shdq = $(subst \",\\\",$(1))\n+\n+## Quote ' for the shell, and embedded \" for C: -DFOO=$(call shelldquote,$(BAR))\n+shelldquote = '\"$(call shdq,$(call shq,$(1)))\"'\n+\n ### Global variables\n \n ## comma, empty, space: handy variables as these tokens are either\ndiff --git a/t/Makefile b/t/Makefile\nindex 882d26eee30..4168b5c6ce6 100644\n--- a/t/Makefile\n+++ b/t/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # Run tests\n #\n # Copyright (c) 2005 Junio C Hamano\n@@ -24,13 +27,6 @@ TEST_RESULTS_DIRECTORY = test-results\n CHAINLINTTMP = chainlinttmp\n endif\n \n-# Shell quote;\n-SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n-TEST_SHELL_PATH_SQ = $(subst ','\\'',$(TEST_SHELL_PATH))\n-PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n-TEST_RESULTS_DIRECTORY_SQ = $(subst ','\\'',$(TEST_RESULTS_DIRECTORY))\n-CHAINLINTTMP_SQ = $(subst ','\\'',$(CHAINLINTTMP))\n-\n T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))\n TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh))\n THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh)))\n@@ -44,38 +40,38 @@ test: pre-clean check-chainlint $(TEST_LINT)\n \t$(MAKE) aggregate-results-and-cleanup\n \n failed:\n-\t@failed=$$(cd '$(TEST_RESULTS_DIRECTORY_SQ)' && \\\n+\t@failed=$$(cd $(call shellquote,$(TEST_RESULTS_DIRECTORY)) && \\\n \t\tgrep -l '^failed [1-9]' *.counts | \\\n \t\tsed -n 's/\\.counts$$/.sh/p') && \\\n \ttest -z \"$$failed\" || $(MAKE) $$failed\n \n prove: pre-clean check-chainlint $(TEST_LINT)\n-\t@echo \"*** prove ***\"; $(PROVE) --exec '$(TEST_SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n+\t@echo \"*** prove ***\"; $(PROVE) --exec $(call shellquote,$(SHELL_PATH)) $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n \t$(MAKE) clean-except-prove-cache\n \n $(T):\n-\t@echo \"*** $@ ***\"; '$(TEST_SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)\n+\t@echo \"*** $@ ***\"; $(call shellquote,$(SHELL_PATH)) $@ $(GIT_TEST_OPTS)\n \n pre-clean:\n-\t$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'\n+\t$(RM) -r $(call shellquote,$(TEST_RESULTS_DIRECTORY))\n \n clean-except-prove-cache: clean-chainlint\n-\t$(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)'\n+\t$(RM) -r 'trash directory'.* $(call shellquote,$(TEST_RESULTS_DIRECTORY))\n \t$(RM) -r valgrind/bin\n \n clean: clean-except-prove-cache\n \t$(RM) .prove\n \n clean-chainlint:\n-\t$(RM) -r '$(CHAINLINTTMP_SQ)'\n+\t$(RM) -r $(call shellquote,$(CHAINLINTTMP))\n \n check-chainlint:\n-\t@mkdir -p '$(CHAINLINTTMP_SQ)' && \\\n+\t@mkdir -p $(call shellquote,$(CHAINLINTTMP)) && \\\n \terr=0 && \\\n \tfor i in $(CHAINLINTTESTS); do \\\n \t\t$(CHAINLINT) <chainlint/$$i.test | \\\n-\t\tsed -e '/^# LINT: /d' >'$(CHAINLINTTMP_SQ)'/$$i.actual && \\\n-\t\tdiff -u chainlint/$$i.expect '$(CHAINLINTTMP_SQ)'/$$i.actual || err=1; \\\n+\t\tsed -e '/^# LINT: /d' >$(call shellquote,$(CHAINLINTTMP))/$$i.actual && \\\n+\t\tdiff -u chainlint/$$i.expect $(call shellquote,$(CHAINLINTTMP))/$$i.actual || err=1; \\\n \tdone && exit $$err\n \n test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \\\n@@ -92,7 +88,7 @@ test-lint-executable:\n \t\techo >&2 \"non-executable tests:\" $$bad; exit 1; }\n \n test-lint-shell-syntax:\n-\t@'$(PERL_PATH_SQ)' check-non-portable-shell.pl $(T) $(THELPERS) $(TPERF)\n+\t@$(call shellquote,$(PERL_PATH)) check-non-portable-shell.pl $(T) $(THELPERS) $(TPERF)\n \n test-lint-filenames:\n \t@# We do *not* pass a glob to ls-files but use grep instead, to catch\n@@ -107,9 +103,9 @@ aggregate-results-and-cleanup: $(T)\n \t$(MAKE) clean\n \n aggregate-results:\n-\tfor f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \\\n+\tfor f in $(call shellquote,$(TEST_RESULTS_DIRECTORY))/t*-*.counts; do \\\n \t\techo \"$$f\"; \\\n-\tdone | '$(SHELL_PATH_SQ)' ./aggregate-results.sh\n+\tdone | $(call shellquote,$(SHELL_PATH)) ./aggregate-results.sh\n \n gitweb-test:\n \t$(MAKE) $(TGITWEB)\ndiff --git a/templates/Makefile b/templates/Makefile\nindex d22a71a3999..c9251a96622 100644\n--- a/templates/Makefile\n+++ b/templates/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # make and install sample templates\n \n ifndef V\n@@ -18,13 +21,6 @@ ifndef PERL_PATH\n \tPERL_PATH = perl\n endif\n \n-SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n-PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n-\n-# Shell quote (do not use $(call) to accommodate ancient setups);\n-DESTDIR_SQ = $(subst ','\\'',$(DESTDIR))\n-template_instdir_SQ = $(subst ','\\'',$(template_instdir))\n-\n all: boilerplates.made custom\n \n # Put templates that can be copied straight from the source\n@@ -61,6 +57,6 @@ clean:\n \t$(RM) -r blt boilerplates.made\n \n install: all\n-\t$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(template_instdir_SQ)'\n+\t$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(template_instdir))\n \t(cd blt && $(TAR) cf - .) | \\\n-\t(cd '$(DESTDIR_SQ)$(template_instdir_SQ)' && umask 022 && $(TAR) xof -)\n+\t(cd $(call shellquote,$(DESTDIR)$(template_instdir)) && umask 022 && $(TAR) xof -)\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441018","messageId":"patch-v2-11.18-bfa15059d60-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 11/18] Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:55Z","receivedAt":"2021-11-12T21:49:36Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the hardcoding of @@GIT_VERSION@@ in generated *.perl scripts\nto instead shell out to \"git version\". This means that we can stop\nre-building during development every time the HEAD changes.\n\nThese codepaths are not \"hot\", so shelling out to get the version\nshouldn't matter to users, in the one case where it potentially would\nin send-email (the loop for each E-Mail we send) we now cache the\nvalue, so we'll only retrieve it once.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile            | 2 +-\n git-cvsserver.perl  | 6 +++---\n git-send-email.perl | 7 ++-----\n git-svn.perl        | 2 +-\n 4 files changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex c698c5b058a..8205614c6ec 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2333,7 +2333,7 @@ PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n perl_localedir_SQ =\n endif\n \n-$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n+$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER\n \t$(QUIET_GEN) \\\n \tsed -e '1{' \\\n \t    -e '\ts|#!.*perl|#!$(PERL_PATH_SQ)|' \\\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 64319bed43f..76f0e8bbbef 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -26,8 +26,6 @@\n use File::Basename;\n use Getopt::Long qw(:config require_order no_ignore_case);\n \n-my $VERSION = '@@GIT_VERSION@@';\n-\n my $log = GITCVS::log->new();\n my $cfg;\n \n@@ -126,7 +124,9 @@\n     or die $usage;\n \n if ($state->{version}) {\n-    print \"git-cvsserver version $VERSION\\n\";\n+    my $version = qx[git version];\n+    $version =~ s/^(git)\\b/$1-cvsserver/;\n+    print $version;\n     exit;\n }\n if ($state->{help}) {\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 5262d88ee32..041cd2fb96d 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -1468,6 +1468,7 @@ sub file_name_is_absolute {\n #\n # If an error occurs sending the email, this just dies.\n \n+my $gitversion;\n sub send_message {\n \tmy @recipients = unique_email_list(@to);\n \t@cc = (grep { my $cc = extract_valid_address_or_die($_);\n@@ -1478,11 +1479,6 @@ sub send_message {\n \t@recipients = unique_email_list(@recipients,@cc,@initial_bcc);\n \t@recipients = (map { extract_valid_address_or_die($_) } @recipients);\n \tmy $date = format_2822_time($time++);\n-\tmy $gitversion = '@@GIT_VERSION@@';\n-\tif ($gitversion =~ m/..GIT_VERSION../) {\n-\t    $gitversion = Git::version();\n-\t}\n-\n \tmy $cc = join(\",\\n\\t\", unique_email_list(@cc));\n \tmy $ccline = \"\";\n \tif ($cc ne '') {\n@@ -1497,6 +1493,7 @@ sub send_message {\n Message-Id: $message_id\n \";\n \tif ($use_xmailer) {\n+\t\t$gitversion ||= Git::version();\n \t\t$header .= \"X-Mailer: git-send-email $gitversion\\n\";\n \t}\n \tif ($in_reply_to) {\ndiff --git a/git-svn.perl b/git-svn.perl\nindex be987e316f9..727431412be 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -9,7 +9,6 @@\n \t\t$_revision $_repository\n \t\t$_q $_authors $_authors_prog %users/;\n $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';\n-$VERSION = '@@GIT_VERSION@@';\n \n use Carp qw/croak/;\n use File::Basename qw/dirname basename/;\n@@ -47,6 +46,7 @@\n \tcommand_close_bidi_pipe\n \tget_record\n );\n+$VERSION = Git::version();\n \n BEGIN {\n \tMemoize::memoize 'Git::config';\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441016","messageId":"patch-v2-16.18-0a348b54491-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 16/18] Makefile: add \"$(QUIET)\" boilerplate to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:49:00Z","receivedAt":"2021-11-12T21:49:37Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"The $(QUIET) variables we define are largely duplicated between our\nvarious Makefiles, let's define them in the new \"shared.mak\" instead.\n\nSince we're not using the environment to pass these around we don't\nneed to export the \"QUIET_GEN\" and \"QUIET_BUILT_IN\" variables\nanymore. The \"QUIET_GEN\" variable is used in \"git-gui/Makefile\" and\n\"gitweb/Makefile\", but they've got their own definition for those. The\n\"QUIET_BUILT_IN\" variable is only used in the top-level \"Makefile\". We\nstill need to export the \"V\" variable.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile | 32 -------------------------\n Makefile               | 33 --------------------------\n config.mak.uname       |  1 -\n shared.mak             | 53 ++++++++++++++++++++++++++++++++++++++++++\n templates/Makefile     |  5 ----\n 5 files changed, 53 insertions(+), 71 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex 4a939cc2c25..69a9af35397 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -218,38 +218,6 @@ DEFAULT_EDITOR_SQ = $(subst ','\\'',$(DEFAULT_EDITOR))\n ASCIIDOC_EXTRA += -a 'git-default-editor=$(DEFAULT_EDITOR_SQ)'\n endif\n \n-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n-QUIET_SUBDIR1  =\n-\n-ifneq ($(findstring $(MAKEFLAGS),w),w)\n-PRINT_DIR = --no-print-directory\n-else # \"make -w\"\n-NO_SUBDIR = :\n-endif\n-\n-ifneq ($(findstring $(MAKEFLAGS),s),s)\n-ifndef V\n-\tQUIET\t\t= @\n-\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n-\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n-\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n-\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n-\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n-\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n-\tQUIET_GEN\t= @echo '   ' GEN $@;\n-\tQUIET_STDERR\t= 2> /dev/null\n-\tQUIET_SUBDIR0\t= +@subdir=\n-\tQUIET_SUBDIR1\t= ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n-\t\t\t  $(MAKE) $(PRINT_DIR) -C $$subdir\n-\n-\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n-\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n-\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n-\n-\texport V\n-endif\n-endif\n-\n all: html man\n \n html: $(DOC_HTML)\ndiff --git a/Makefile b/Makefile\nindex c8a0a1586ca..c437aea9e4a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1939,39 +1939,6 @@ ifndef PAGER_ENV\n PAGER_ENV = LESS=FRX LV=-c\n endif\n \n-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n-QUIET_SUBDIR1  =\n-\n-ifneq ($(findstring w,$(MAKEFLAGS)),w)\n-PRINT_DIR = --no-print-directory\n-else # \"make -w\"\n-NO_SUBDIR = :\n-endif\n-\n-ifneq ($(findstring s,$(MAKEFLAGS)),s)\n-ifndef V\n-\tQUIET_CC       = @echo '   ' CC $@;\n-\tQUIET_AR       = @echo '   ' AR $@;\n-\tQUIET_LINK     = @echo '   ' LINK $@;\n-\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n-\tQUIET_GEN      = @echo '   ' GEN $@;\n-\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n-\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n-\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n-\tQUIET_GCOV     = @echo '   ' GCOV $@;\n-\tQUIET_SP       = @echo '   ' SP $<;\n-\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n-\tQUIET_RC       = @echo '   ' RC $@;\n-\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n-\tQUIET_SUBDIR0  = +@subdir=\n-\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n-\t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n-\texport V\n-\texport QUIET_GEN\n-\texport QUIET_BUILT_IN\n-endif\n-endif\n-\n ifdef NO_INSTALL_HARDLINKS\n \texport NO_INSTALL_HARDLINKS\n endif\ndiff --git a/config.mak.uname b/config.mak.uname\nindex d0701f9beb0..1a12d8c635f 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -715,7 +715,6 @@ vcxproj:\n \tgit diff-index --cached --quiet HEAD --\n \n \t# Make .vcxproj files and add them\n-\tunset QUIET_GEN QUIET_BUILT_IN; \\\n \tperl contrib/buildsystems/generate -g Vcxproj\n \tgit add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj\n \ndiff --git a/shared.mak b/shared.mak\nindex 3b4163e652a..80176f705fc 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -35,6 +35,59 @@ space = $(empty) $(empty)\n wspfx = $(space)$(space)$(space)\n wspfx_sq = $(call shellquote,$(wspfx))\n \n+### Quieting\n+## common\n+QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n+QUIET_SUBDIR1  =\n+\n+ifneq ($(findstring w,$(MAKEFLAGS)),w)\n+PRINT_DIR = --no-print-directory\n+else # \"make -w\"\n+NO_SUBDIR = :\n+endif\n+\n+ifneq ($(findstring s,$(MAKEFLAGS)),s)\n+ifndef V\n+## common\n+\tQUIET_SUBDIR0  = +@subdir=\n+\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n+\t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n+\n+\tQUIET          = @\n+\tQUIET_GEN      = @echo '   ' GEN $@;\n+\n+## Used in \"Makefile\"\n+\tQUIET_CC       = @echo '   ' CC $@;\n+\tQUIET_AR       = @echo '   ' AR $@;\n+\tQUIET_LINK     = @echo '   ' LINK $@;\n+\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n+\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n+\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n+\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n+\tQUIET_GCOV     = @echo '   ' GCOV $@;\n+\tQUIET_SP       = @echo '   ' SP $<;\n+\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n+\tQUIET_RC       = @echo '   ' RC $@;\n+\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n+\n+## Used in \"Documentation/Makefile\"\n+\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n+\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n+\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n+\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n+\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n+\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n+\tQUIET_GEN\t= @echo '   ' GEN $@;\n+\tQUIET_STDERR\t= 2> /dev/null\n+\n+\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n+\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n+\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n+\n+\texport V\n+endif\n+endif\n+\n ### Templates\n \n ## Template for making a GIT-SOMETHING, which changes if a\ndiff --git a/templates/Makefile b/templates/Makefile\nindex c9251a96622..b056e710b7e 100644\n--- a/templates/Makefile\n+++ b/templates/Makefile\n@@ -2,11 +2,6 @@\n include ../shared.mak\n \n # make and install sample templates\n-\n-ifndef V\n-\tQUIET = @\n-endif\n-\n INSTALL ?= install\n TAR ?= tar\n RM ?= rm -f\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441017","messageId":"patch-v2-15.18-5654d7f7f29-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 15/18] Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:48:59Z","receivedAt":"2021-11-12T21:49:37Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move the mostly copy/pasted code in the \"Makefile\" and\n\"Documentation/Makefile\" which FORCE-generates a file based on a\nvariable in play in the Makefile to use a template.\n\nThis will make it easier later on to move these to rules that aren't\nFORCE-run using optional gmake 4.2+ features, but for now just getting\nrid of the repetition is worth it.\n\nThe message for the new generated rule will say whether or not we're\ngenerating the file for the first time, as opposed to the old messages\nsaying \"new\" whether we had flag modifications, or were building for\nthe first time.\n\nExample output before:\n\n    $ make clean\n    [...]\n    $ make\n    GIT_VERSION = 2.34.0-rc1-dev\n        * new build flags\n        CC grep.o\n    $ make CFLAGS=-I$RANDOM grep.o\n        * new build flags\n        CC grep.o\n\nAfter:\n\n    $ make clean\n    [...]\n    $ make grep.o\n    GIT_VERSION = 2.34.0-rc1-dev\n        GIT-CFLAGS PARAMETERS (new)\n        CC grep.o\n    $ make CFLAGS=-I$RANDOM grep.o\n        GIT-CFLAGS PARAMETERS (changed)\n        CC grep.o\n\nNote: It's important that \"@FLAGS\" here be defined as '$$($(2))', and\nnot the eagerly expanded '$($(2))'. The latter will break if\ne.g. curl-config isn't installed, since we'll end up recursively\nexpanding that part of the variable even if NO_CURL isn't defined,\nwhich happens e.g. for the \"check-docs\" target in CI.\n\nWe're also introducing a $(wspfx) variable here to control the\nwhitespace prefixing. It matches the $(QUIET...) variables, who'll be\nusing these variables in a subsequent commit. Note that it's important\nthat we call the shell quote escaping macros inline (or equivalent),\nbecause if we'd like variables to be overridable we need to support e.g.:\n\n    $ make CFLAGS=-I$RANDOM grep.o wspfx='$(space)->'\n     -> GIT-CFLAGS PARAMETERS (changed)\n        CC grep.o\n\nIf we simply quoted and used $(wspfx) then the user would need to\nprovide us with a quoted version, so there's still some use-cases for\nthese $(*_sq) variables. It could also be done inline, but that's a\nlot more verbose.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile |  8 +------\n Makefile               | 51 ++++++------------------------------------\n shared.mak             | 22 ++++++++++++++++++\n 3 files changed, 30 insertions(+), 51 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ba27456c86a..4a939cc2c25 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -343,13 +343,7 @@ mergetools-list.made: ../git-mergetool--lib.sh $(wildcard ../mergetools/*)\n \tdate >$@\n \n TRACK_ASCIIDOCFLAGS = $(subst ','\\'',$(ASCIIDOC_COMMON):$(ASCIIDOC_HTML):$(ASCIIDOC_DOCBOOK))\n-\n-GIT-ASCIIDOCFLAGS: FORCE\n-\t@FLAGS='$(TRACK_ASCIIDOCFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-ASCIIDOCFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new asciidoc flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-ASCIIDOCFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-ASCIIDOCFLAGS,TRACK_ASCIIDOCFLAGS))\n \n clean:\n \t$(RM) -rf .build/\ndiff --git a/Makefile b/Makefile\nindex b458c24d95e..c8a0a1586ca 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2087,10 +2087,7 @@ endif\n GIT_USER_AGENT_SQ = $(subst ','\\'',$(GIT_USER_AGENT))\n GIT_USER_AGENT_CQ = \"$(subst \",\\\",$(subst \\,\\\\,$(GIT_USER_AGENT)))\"\n GIT_USER_AGENT_CQ_SQ = $(subst ','\\'',$(GIT_USER_AGENT_CQ))\n-GIT-USER-AGENT: FORCE\n-\t@if test x'$(GIT_USER_AGENT_SQ)' != x\"`cat GIT-USER-AGENT 2>/dev/null`\"; then \\\n-\t\techo '$(GIT_USER_AGENT_SQ)' >GIT-USER-AGENT; \\\n-\tfi\n+$(eval $(call TRACK_template,GIT-USER-AGENT,GIT_USER_AGENT_SQ))\n \n ifdef DEFAULT_HELP_FORMAT\n BASIC_CFLAGS += -DDEFAULT_HELP_FORMAT='\"$(DEFAULT_HELP_FORMAT)\"'\n@@ -2238,12 +2235,7 @@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\\\n \t$(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n \t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(PAGER_ENV):\\\n \t$(perllibdir_SQ)\n-GIT-SCRIPT-DEFINES: FORCE\n-\t@FLAGS='$(SCRIPT_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new script parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-SCRIPT-DEFINES,SCRIPT_DEFINES))\n \n define cmd_munge_script\n sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2355,13 +2347,7 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n endif # NO_PERL\n-\n-GIT-PERL-DEFINES: FORCE\n-\t@FLAGS='$(PERL_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new perl-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n+$(eval $(call TRACK_template,GIT-PERL-DEFINES,PERL_DEFINES))\n \n # As with NO_PERL=Y we'll still make GIT-PYTHON-DEFINES if \"NO_PYTHON\"\n # is defined, for creating the \"unimplemented.sh\" scripts.\n@@ -2390,12 +2376,7 @@ $(SCRIPT_PYTHON_GEN): % : %.py GIT-PYTHON-DEFINES\n \tmv $@+ $@\n endif # NO_PYTHON\n \n-GIT-PYTHON-DEFINES: FORCE\n-\t@FLAGS='$(PYTHON_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new python-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n+$(eval $(call TRACK_template,GIT-PYTHON-DEFINES,PYTHON_DEFINES))\n \n CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t\t\tconfigure.ac >configure.ac+ && \\\n@@ -2751,31 +2732,13 @@ cscope: cscope.out\n ### Detect prefix changes\n TRACK_PREFIX = $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\\\n \t\t$(localedir_SQ)\n-\n-GIT-PREFIX: FORCE\n-\t@FLAGS='$(TRACK_PREFIX)'; \\\n-\tif test x\"$$FLAGS\" != x\"`cat GIT-PREFIX 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new prefix flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-PREFIX; \\\n-\tfi\n+$(eval $(call TRACK_template,GIT-PREFIX,TRACK_PREFIX))\n \n TRACK_CFLAGS = $(CC):$(subst ','\\'',$(ALL_CFLAGS)):$(USE_GETTEXT_SCHEME)\n-\n-GIT-CFLAGS: FORCE\n-\t@FLAGS='$(TRACK_CFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-CFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new build flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-CFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-CFLAGS,TRACK_CFLAGS))\n \n TRACK_LDFLAGS = $(subst ','\\'',$(ALL_LDFLAGS))\n-\n-GIT-LDFLAGS: FORCE\n-\t@FLAGS='$(TRACK_LDFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-LDFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new link flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-LDFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-LDFLAGS,TRACK_LDFLAGS))\n \n # We need to apply sq twice, once to protect from the shell\n # that runs GIT-BUILD-OPTIONS, and then again to protect it\ndiff --git a/shared.mak b/shared.mak\nindex ef03c2bc094..3b4163e652a 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -29,3 +29,25 @@ shelldquote = '\"$(call shdq,$(call shq,$(1)))\"'\n comma = ,\n empty =\n space = $(empty) $(empty)\n+\n+## wspfx: the whitespace prefix padding for $(QUIET...) and similarly\n+## aligned output.\n+wspfx = $(space)$(space)$(space)\n+wspfx_sq = $(call shellquote,$(wspfx))\n+\n+### Templates\n+\n+## Template for making a GIT-SOMETHING, which changes if a\n+## TRACK_SOMETHING variable changes.\n+define TRACK_template\n+.PHONY: FORCE\n+$(1): FORCE\n+\t@FLAGS='$$($(2))'; \\\n+\tif ! test -f $(1) ; then \\\n+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (new)\" $@; \\\n+\t\techo \"$$$$FLAGS\" >$(1); \\\n+\telif test x\"$$$$FLAGS\" != x\"`cat $(1) 2>/dev/null`\" ; then \\\n+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (changed)\" $@; \\\n+\t\techo \"$$$$FLAGS\" >$(1); \\\n+\tfi\n+endef\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441020","messageId":"patch-v2-17.18-34f692144d1-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 17/18] Makefile: use $(wspfx) for $(QUIET...) in shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:49:01Z","receivedAt":"2021-11-12T21:49:38Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the mostly move-only change in the preceding commit to use the\n$(wspfx) variable for defining the QUIET padding, to guarantee that\nit's consistent with the \"TRACK_template\" template.\n\n    $ make CFLAGS=-I$RANDOM grep.o wspfx='$(space)->'\n     -> GIT-CFLAGS PARAMETERS (changed)\n     -> CC grep.o\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n shared.mak | 48 ++++++++++++++++++++++++------------------------\n 1 file changed, 24 insertions(+), 24 deletions(-)\n\ndiff --git a/shared.mak b/shared.mak\nindex 80176f705fc..a1b62b272f8 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -50,39 +50,39 @@ ifneq ($(findstring s,$(MAKEFLAGS)),s)\n ifndef V\n ## common\n \tQUIET_SUBDIR0  = +@subdir=\n-\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n+\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo $(wspfx_sq) SUBDIR $$subdir; \\\n \t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n \n \tQUIET          = @\n-\tQUIET_GEN      = @echo '   ' GEN $@;\n+\tQUIET_GEN      = @echo $(wspfx_sq) GEN $@;\n \n ## Used in \"Makefile\"\n-\tQUIET_CC       = @echo '   ' CC $@;\n-\tQUIET_AR       = @echo '   ' AR $@;\n-\tQUIET_LINK     = @echo '   ' LINK $@;\n-\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n-\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n-\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n-\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n-\tQUIET_GCOV     = @echo '   ' GCOV $@;\n-\tQUIET_SP       = @echo '   ' SP $<;\n-\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n-\tQUIET_RC       = @echo '   ' RC $@;\n-\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n+\tQUIET_CC       = @echo $(wspfx_sq) CC $@;\n+\tQUIET_AR       = @echo $(wspfx_sq) AR $@;\n+\tQUIET_LINK     = @echo $(wspfx_sq) LINK $@;\n+\tQUIET_BUILT_IN = @echo $(wspfx_sq) BUILTIN $@;\n+\tQUIET_LNCP     = @echo $(wspfx_sq) LN/CP $@;\n+\tQUIET_XGETTEXT = @echo $(wspfx_sq) XGETTEXT $@;\n+\tQUIET_MSGFMT   = @echo $(wspfx_sq) MSGFMT $@;\n+\tQUIET_GCOV     = @echo $(wspfx_sq) GCOV $@;\n+\tQUIET_SP       = @echo $(wspfx_sq) SP $<;\n+\tQUIET_HDR      = @echo $(wspfx_sq) HDR $(<:hcc=h);\n+\tQUIET_RC       = @echo $(wspfx_sq) RC $@;\n+\tQUIET_SPATCH   = @echo $(wspfx_sq) SPATCH $<;\n \n ## Used in \"Documentation/Makefile\"\n-\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n-\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n-\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n-\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n-\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n-\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n-\tQUIET_GEN\t= @echo '   ' GEN $@;\n+\tQUIET_ASCIIDOC\t= @echo $(wspfx_sq) ASCIIDOC $@;\n+\tQUIET_XMLTO\t= @echo $(wspfx_sq) XMLTO $@;\n+\tQUIET_DB2TEXI\t= @echo $(wspfx_sq) DB2TEXI $@;\n+\tQUIET_MAKEINFO\t= @echo $(wspfx_sq) MAKEINFO $@;\n+\tQUIET_DBLATEX\t= @echo $(wspfx_sq) DBLATEX $@;\n+\tQUIET_XSLTPROC\t= @echo $(wspfx_sq) XSLTPROC $@;\n+\tQUIET_GEN\t= @echo $(wspfx_sq) GEN $@;\n \tQUIET_STDERR\t= 2> /dev/null\n \n-\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n-\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n-\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n+\tQUIET_LINT_GITLINK\t= @echo $(wspfx_sq) LINT GITLINK $<;\n+\tQUIET_LINT_MANSEC\t= @echo $(wspfx_sq) LINT MAN SEC $<;\n+\tQUIET_LINT_MANEND\t= @echo $(wspfx_sq) LINT MAN END $<;\n \n \texport V\n endif\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441021","messageId":"patch-v2-18.18-5b3986bc4a8-20211112T214150Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v2 18/18] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-12T21:49:02Z","receivedAt":"2021-11-12T21:49:40Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\nfor us, and use it for the \"make lint-docs\" targets I added in\n8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n\nAs seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\ndependency, 2021-10-26) maintaining these manual lists of parent\ndirectory dependencies is fragile, in addition to being obviously\nverbose.\n\nI used this pattern at the time because I couldn't find another method\nthan \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\nevery file being created, which as noted in [1] would be significantly\nslower.\n\nBut as it turns out we can use this neat trick of only doing a \"mkdir\n-p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\nof a performance test similar to thatnoted downthread of [1] in [2]\nshows that this is faster, in addition to being less verbose and more\nreliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n\n    $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n    Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n      Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n      Range (min … max):    2.121 s …  2.158 s    10 runs\n\n    Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n      Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n      Range (min … max):    2.657 s …  2.662 s    10 runs\n\n    Summary\n      'make -C Documentation lint-docs' in 'HEAD~0' ran\n        1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n\nSo let's use that pattern both for the \"lint-docs\" target, and a few\nmiscellaneous other targets.\n\nThis method of creating parent directories is explicitly racy in that\nwe don't know if we're going to say always create a \"foo\" followed by\na \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n\"foo/bar\" first. In this case it doesn't matter for anything except\nthat we aren't guaranteed to get the same number of rules firing when\nrunning make in parallel.\n\n1. https://lore.kernel.org/git/211028.861r45y3pt.gmgdl@evledraar.gmail.com/\n2. https://lore.kernel.org/git/211028.86o879vvtp.gmgdl@evledraar.gmail.com/\n3. https://gitlab.com/avar/git-hyperfine/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile | 25 +++----------------------\n Makefile               | 12 +++++++-----\n shared.mak             |  7 +++++++\n 3 files changed, 17 insertions(+), 27 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex 69a9af35397..d16b653394c 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -428,25 +428,11 @@ quick-install-html: require-htmlrepo\n print-man1:\n \t@for i in $(MAN1_TXT); do echo $$i; done\n \n-## Lint: Common\n-.build:\n-\t$(QUIET)mkdir $@\n-.build/lint-docs: | .build\n-\t$(QUIET)mkdir $@\n-\n ## Lint: gitlink\n-.build/lint-docs/gitlink: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n-.build/lint-docs/gitlink/howto: | .build/lint-docs/gitlink\n-\t$(QUIET)mkdir $@\n-.build/lint-docs/gitlink/config: | .build/lint-docs/gitlink\n-\t$(QUIET)mkdir $@\n LINT_DOCS_GITLINK = $(patsubst %.txt,.build/lint-docs/gitlink/%.ok,$(HOWTO_TXT) $(DOC_DEP_TXT))\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/howto\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/config\n $(LINT_DOCS_GITLINK): lint-gitlink.perl\n $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_GITLINK)$(PERL_PATH) lint-gitlink.perl \\\n \t\t$< \\\n \t\t$(HOWTO_TXT) $(DOC_DEP_TXT) \\\n@@ -457,23 +443,18 @@ $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt\n lint-docs-gitlink: $(LINT_DOCS_GITLINK)\n \n ## Lint: man-end-blurb\n-.build/lint-docs/man-end-blurb: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n LINT_DOCS_MAN_END_BLURB = $(patsubst %.txt,.build/lint-docs/man-end-blurb/%.ok,$(MAN_TXT))\n-$(LINT_DOCS_MAN_END_BLURB): | .build/lint-docs/man-end-blurb\n $(LINT_DOCS_MAN_END_BLURB): lint-man-end-blurb.perl\n $(LINT_DOCS_MAN_END_BLURB): .build/lint-docs/man-end-blurb/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_MANEND)$(PERL_PATH) lint-man-end-blurb.perl $< >$@\n .PHONY: lint-docs-man-end-blurb\n-lint-docs-man-end-blurb: $(LINT_DOCS_MAN_END_BLURB)\n \n ## Lint: man-section-order\n-.build/lint-docs/man-section-order: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n LINT_DOCS_MAN_SECTION_ORDER = $(patsubst %.txt,.build/lint-docs/man-section-order/%.ok,$(MAN_TXT))\n-$(LINT_DOCS_MAN_SECTION_ORDER): | .build/lint-docs/man-section-order\n $(LINT_DOCS_MAN_SECTION_ORDER): lint-man-section-order.perl\n $(LINT_DOCS_MAN_SECTION_ORDER): .build/lint-docs/man-section-order/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_MANSEC)$(PERL_PATH) lint-man-section-order.perl $< >$@\n .PHONY: lint-docs-man-section-order\n lint-docs-man-section-order: $(LINT_DOCS_MAN_SECTION_ORDER)\ndiff --git a/Makefile b/Makefile\nindex c437aea9e4a..0a3f292bf82 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2632,7 +2632,8 @@ all:: $(MOFILES)\n endif\n \n po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n-\t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_MSGFMT)$(MSGFMT) -o $@ $<\n \n ifndef NO_PERL\n LIB_PERL = $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n@@ -2641,7 +2642,8 @@ LIB_CPAN = $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n LIB_CPAN_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n-\t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_GEN) \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n \t    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \\\n \t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(call shq,$(NO_PERL_CPAN_FALLBACKS))|g' \\\n@@ -2655,8 +2657,8 @@ endif\n \n # install-man depends on Git.3pm even with NO_PERL=Y\n perl/build/man/man3/Git.3pm: perl/Git.pm\n-\t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n-\tpod2man $< $@\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_GEN)pod2man $< $@\n \n FIND_SOURCE_FILES = ( \\\n \tgit ls-files \\\n@@ -2780,7 +2782,7 @@ test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(\n all:: $(TEST_PROGRAMS) $(test_bindir_programs)\n \n bin-wrappers/%: wrap-for-bin.sh\n-\t@mkdir -p bin-wrappers\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n \t     -e 's|@@BUILD_DIR@@|$(shell pwd)|' \\\n \t     -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \\\ndiff --git a/shared.mak b/shared.mak\nindex a1b62b272f8..363138a5577 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -56,6 +56,8 @@ ifndef V\n \tQUIET          = @\n \tQUIET_GEN      = @echo $(wspfx_sq) GEN $@;\n \n+\tQUIET_MKDIR_P_PARENT  = @echo $(wspfx_sq) MKDIR -p $(@D);\n+\n ## Used in \"Makefile\"\n \tQUIET_CC       = @echo $(wspfx_sq) CC $@;\n \tQUIET_AR       = @echo $(wspfx_sq) AR $@;\n@@ -88,6 +90,11 @@ ifndef V\n endif\n endif\n \n+## Helpers\n+define mkdir_p_parent_template\n+$(if $(wildcard $(@D)),,$(QUIET_MKDIR_P_PARENT)$(shell mkdir -p $(@D)))\n+endef\n+\n ### Templates\n \n ## Template for making a GIT-SOMETHING, which changes if a\n-- \n2.34.0.rc2.795.g926201d1cc8\n\n"},{"id":"441295","messageId":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com","subject":"[PATCH v3 00/23] Makefile: dependency fixes, make noop runtime ~1.4x faster","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:00Z","receivedAt":"2021-11-16T12:02:37Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"As noted in v2[1] this series fixes various dependency issues in the\nMakfile.\n\nNew in v3 is a fix for the dependency issue Mike Hommey reported[2]\nwith hook-list.h, and 3x new and big optimizations that I'd planned to\nsubmit later on-top, but I figured would be better to consider as part\nof these general dependency improvements.\n\nWith those new changes on top we run ~1.4x faster on no-op runs (under\nNO_TCLTK=Y, since that would otherwise eat most of our runtime either\nway):\n    \n    $ git hyperfine -L rev origin/next,HEAD~0 -s 'make -j8 all NO_TCLTK=Y' 'make NO_TCLTK=Y' --warmup 10 -r 10\n    Benchmark 1: make NO_TCLTK=Y' in 'origin/next\n      Time (mean ± σ):     187.4 ms ±   2.4 ms    [User: 146.5 ms, System: 57.1 ms]\n      Range (min … max):   184.7 ms … 192.8 ms    10 runs\n     \n    Benchmark 2: make NO_TCLTK=Y' in 'HEAD~0\n      Time (mean ± σ):     136.1 ms ±   0.9 ms    [User: 103.0 ms, System: 47.6 ms]\n      Range (min … max):   135.4 ms … 138.2 ms    10 runs\n     \n    Summary\n      'make NO_TCLTK=Y' in 'HEAD~0' ran\n        1.38 ± 0.02 times faster than 'make NO_TCLTK=Y' in 'origin/next'\n\nWhich, as noted before is working nicely towards making executing\n\"make\" in a loop faster, such as under \"git rebase --exec\".\n\nThose optimizations are a mixture of clever and \"dumb but\nworks\". E.g. around 10% of the runtime was spent by the Makefile\nlooking for git's sources in the RCS and SCCS source control\nmanagement systems, before giving up and considering the relevant file\non disk.\n\n1. https://lore.kernel.org/git/cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com\n2. https://lore.kernel.org/git/20211115230032.3or3qqlsdnxjtrol@glandium.org/\n\nÆvar Arnfjörð Bjarmason (23):\n  Makefile: don't invoke msgfmt with --statistics\n  Makefile: don't set up \"perl/build\" rules under NO_PERL=Y\n  Makefile: use \"=\" not \":=\" for po/* and perl/*\n  Makefile: clean perl/build/ even with NO_PERL=Y\n  Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR\n  Makefile: guard Perl-only variable assignments\n  Makefile: change \"ifndef NO_PERL\" to \"ifdef NO_PERL\"\n  Makefile: adjust Perl-related comments & whitespace\n  Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph\n  Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"\n  Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts\n  Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it\n  Makefile: move $(comma), $(empty) and $(space) to shared.mak\n  Makefile: re-add and use the \"shellquote\" macros\n  Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}\n  Makefile: add \"$(QUIET)\" boilerplate to shared.mak\n  Makefile: use $(wspfx) for $(QUIET...) in shared.mak\n  Makefiles: add and use wildcard \"mkdir -p\" template\n  Makefile: correct the dependency graph of hook-list.h\n  Makefile: use $(file) I/O instead of \"FORCE\" when possible\n  Makefile: disable GNU make built-in wildcard rules\n  Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES)\n  Makefile: move \".SUFFIXES\" rule to shared.mak\n\n .gitignore             |   2 +-\n Documentation/Makefile |  71 +---------\n Makefile               | 313 +++++++++++++++--------------------------\n config.mak.uname       |   1 -\n git-cvsserver.perl     |   6 +-\n git-send-email.perl    |   7 +-\n git-svn.perl           |   2 +-\n shared.mak             | 187 ++++++++++++++++++++++++\n t/Makefile             |  34 ++---\n templates/Makefile     |  19 +--\n 10 files changed, 337 insertions(+), 305 deletions(-)\n create mode 100644 shared.mak\n\nRange-diff against v2:\n 1:  75ebf7b04e5 =  1:  1621ca72c1d Makefile: don't invoke msgfmt with --statistics\n 2:  138f60ba37b =  2:  b7c36c9fea0 Makefile: don't set up \"perl/build\" rules under NO_PERL=Y\n 3:  472e1eb74bd =  3:  510499d18ba Makefile: use \"=\" not \":=\" for po/* and perl/*\n 4:  a5ce2dce164 =  4:  37f3591bcca Makefile: clean perl/build/ even with NO_PERL=Y\n 5:  04dbc1d2809 =  5:  e38c90ad0b6 Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR\n 6:  eea89794493 =  6:  98e14c7eba9 Makefile: guard Perl-only variable assignments\n 7:  e06732d4639 =  7:  047a42b01cf Makefile: change \"ifndef NO_PERL\" to \"ifdef NO_PERL\"\n 8:  a9502a23989 =  8:  0c0a3de390e Makefile: adjust Perl-related comments & whitespace\n 9:  c1336fc0a56 =  9:  1ece3160915 Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph\n10:  41f65a12205 = 10:  e9b61cd0ba5 Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"\n11:  bfa15059d60 = 11:  b020f8e3257 Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts\n12:  656d02ab641 = 12:  19539ce7d2d Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it\n13:  6e25ac71cbc = 13:  6c9291c2c9f Makefile: move $(comma), $(empty) and $(space) to shared.mak\n14:  64296e6e8e5 = 14:  e811a907b08 Makefile: re-add and use the \"shellquote\" macros\n15:  5654d7f7f29 = 15:  fac30fe8b56 Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}\n16:  0a348b54491 = 16:  a3e3acea82d Makefile: add \"$(QUIET)\" boilerplate to shared.mak\n17:  34f692144d1 = 17:  22264f431c8 Makefile: use $(wspfx) for $(QUIET...) in shared.mak\n18:  5b3986bc4a8 = 18:  d61e2b44f68 Makefiles: add and use wildcard \"mkdir -p\" template\n -:  ----------- > 19:  234b4eb613c Makefile: correct the dependency graph of hook-list.h\n -:  ----------- > 20:  567ad5c3ebc Makefile: use $(file) I/O instead of \"FORCE\" when possible\n -:  ----------- > 21:  cb3ae5ce00b Makefile: disable GNU make built-in wildcard rules\n -:  ----------- > 22:  88cfc946b37 Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES)\n -:  ----------- > 23:  276e226f0a8 Makefile: move \".SUFFIXES\" rule to shared.mak\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441296","messageId":"patch-v3-02.23-b7c36c9fea0-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 02/23] Makefile: don't set up \"perl/build\" rules under NO_PERL=Y","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:02Z","receivedAt":"2021-11-16T12:02:43Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Do not define LIB_{PERL,CPAN}{,_GEN} if NO_PERL is defined. This\nchanges no functionality, but makes it clear which of these rules are\nneeded under NO_PERL=Y. See 20d2a30f8ff (Makefile: replace\nperl/Makefile.PL with simple make rules, 2017-12-10) for the initial\nimplementation.\n\nWe do for better or worse rely on \"install-doc\" calling\n\"install-man-perl\" regardless of whether NO_PERL=Y is defined or not,\ni.e. we'll always end up with that manual page, even if we don't have\nany of the Perl code installed. Let's add a comment about that\nadjacent to the rules that build perl/build.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 17 +++++++++--------\n 1 file changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 11da97de233..06405825a24 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2684,19 +2684,12 @@ endif\n po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n \t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n \n+ifndef NO_PERL\n LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n-ifndef NO_PERL\n-all:: $(LIB_PERL_GEN)\n-ifndef NO_PERL_CPAN_FALLBACKS\n-all:: $(LIB_CPAN_GEN)\n-endif\n-NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n-endif\n-\n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n@@ -2704,6 +2697,14 @@ perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \\\n \t< $< > $@\n \n+all:: $(LIB_PERL_GEN)\n+ifndef NO_PERL_CPAN_FALLBACKS\n+all:: $(LIB_CPAN_GEN)\n+endif\n+NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n+endif\n+\n+# install-man depends on Git.3pm even with NO_PERL=Y\n perl/build/man/man3/Git.3pm: perl/Git.pm\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tpod2man $< $@\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441297","messageId":"patch-v3-01.23-1621ca72c1d-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 01/23] Makefile: don't invoke msgfmt with --statistics","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:01Z","receivedAt":"2021-11-16T12:02:44Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the --statistics flag that I added in 5e9637c6297 (i18n: add\ninfrastructure for translating Git with gettext, 2011-11-18). Our\nMakefile output is good about reducing verbosity by default, except in\nthis case:\n\n    $ rm -rf po/build/locale/e*; time make -j $(nproc) all\n        SUBDIR templates\n        MKDIR -p po/build/locale/el/LC_MESSAGES\n        MSGFMT po/build/locale/el/LC_MESSAGES/git.mo\n        MKDIR -p po/build/locale/es/LC_MESSAGES\n        MSGFMT po/build/locale/es/LC_MESSAGES/git.mo\n    1038 translated messages, 3325 untranslated messages.\n    5230 translated messages.\n\nI didn't have any good reason for using --statistics at the time other\nthan ad-hoc eyeballing of the output. We don't need to spew out\nexactly how many messages we've got translated every time. Now we'll\ninstead emit:\n\n    $ rm -rf po/build/locale/e*; time make -j $(nproc) all\n        SUBDIR templates\n        MKDIR -p po/build/locale/el/LC_MESSAGES\n        MSGFMT po/build/locale/el/LC_MESSAGES/git.mo\n        MKDIR -p po/build/locale/es/LC_MESSAGES\n        MSGFMT po/build/locale/es/LC_MESSAGES/git.mo\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex d56c0e4aadc..11da97de233 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1870,7 +1870,7 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT\n endif\n \n ifndef NO_MSGFMT_EXTENDED_OPTIONS\n-\tMSGFMT += --check --statistics\n+\tMSGFMT += --check\n endif\n \n ifdef HAVE_CLOCK_GETTIME\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441298","messageId":"patch-v3-03.23-510499d18ba-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 03/23] Makefile: use \"=\" not \":=\" for po/* and perl/*","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:03Z","receivedAt":"2021-11-16T12:02:45Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change these variable definitions from being simply-expanded to be\nrecursively expanded instead. I.e. they'll be lazily expanded when\nused.\n\nI added these in 5e9637c6297 (i18n: add infrastructure for translating\nGit with gettext, 2011-11-18) and 20d2a30f8ff (Makefile: replace\nperl/Makefile.PL with simple make rules, 2017-12-10), the reason for\nusing \":=\" over \"=\" was that I didn't know the difference in 2011 (I\nthink I copied some POC code), and in 2017 I used the 2011 commit for\nreference.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 16 ++++++++--------\n 1 file changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 06405825a24..6b77702e102 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2672,11 +2672,11 @@ po/git.pot: $(GENERATED_H) FORCE\n pot: po/git.pot\n \n ifdef NO_GETTEXT\n-POFILES :=\n-MOFILES :=\n+POFILES =\n+MOFILES =\n else\n-POFILES := $(wildcard po/*.po)\n-MOFILES := $(patsubst po/%.po,po/build/locale/%/LC_MESSAGES/git.mo,$(POFILES))\n+POFILES = $(wildcard po/*.po)\n+MOFILES = $(patsubst po/%.po,po/build/locale/%/LC_MESSAGES/git.mo,$(POFILES))\n \n all:: $(MOFILES)\n endif\n@@ -2685,10 +2685,10 @@ po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n \t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n \n ifndef NO_PERL\n-LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n-LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n-LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n-LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n+LIB_PERL = $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n+LIB_PERL_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n+LIB_CPAN = $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n+LIB_CPAN_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441299","messageId":"patch-v3-04.23-37f3591bcca-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 04/23] Makefile: clean perl/build/ even with NO_PERL=Y","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:04Z","receivedAt":"2021-11-16T12:02:46Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a regression in 499c29394ce (Makefile: allow building without\nperl, 2009-04-03) where we'd stop cleaning the perl/* directory\nbecause NO_PERL was defined, thus leaving behind litter if the flag at\n\"clean\" time didn't match that of build time.\n\nIn 499c29394ce this was done to avoid relying on the perl/Makefile.PL,\nbut since my 20d2a30f8ff (Makefile: replace perl/Makefile.PL with\nsimple make rules, 2017-12-10) we can clean things in that directory\nunconditionally.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex 6b77702e102..a71fba15e30 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -3234,6 +3234,7 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) $(HCC)\n \t$(RM) -r bin-wrappers $(dep_dirs) $(compdb_dir) compile_commands.json\n \t$(RM) -r po/build/\n+\t$(RM) -r perl/build/\n \t$(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope*\n \t$(RM) -r .dist-tmp-dir .doc-tmp-dir\n \t$(RM) $(GIT_TARNAME).tar.gz\n@@ -3242,7 +3243,6 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) Documentation/GIT-EXCLUDED-PROGRAMS\n ifndef NO_PERL\n \t$(MAKE) -C gitweb clean\n-\t$(RM) -r perl/build/\n endif\n \t$(MAKE) -C templates/ clean\n \t$(MAKE) -C t/ clean\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441300","messageId":"patch-v3-06.23-98e14c7eba9-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 06/23] Makefile: guard Perl-only variable assignments","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:06Z","receivedAt":"2021-11-16T12:02:50Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move the \"ifndef NO_PERL\" a few lines earlier to encompass the\n\"perl_localedir_SQ\" variable. We'll only use it under !NO_PERL.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex 284725099c9..0cb10f00ebb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2291,11 +2291,11 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n # This makes sure we depend on the NO_PERL setting itself.\n $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n+ifndef NO_PERL\n # Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n # since the locale directory is injected.\n perl_localedir_SQ = $(localedir_SQ)\n \n-ifndef NO_PERL\n PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n PERL_DEFINES =\n PERL_DEFINES += $(PERL_PATH_SQ)\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441301","messageId":"patch-v3-05.23-e38c90ad0b6-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 05/23] Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:05Z","receivedAt":"2021-11-16T12:02:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Since 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\" flag,\n2021-06-29) we don't need to guard the clobbering of $@ with this sort\nof \"mv $@+ $@\" pattern in these cases where we're merely generating a\nfile that'll be used as a dependency for other files, as in this case\nfor GIT-PERL-HEADER.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex a71fba15e30..284725099c9 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2349,8 +2349,7 @@ GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n \t    -e 's=@@PERLLIBDIR_REL@@=$(perllibdir_relative_SQ)=g' \\\n \t    -e 's=@@GITEXECDIR_REL@@=$(gitexecdir_relative_SQ)=g' \\\n \t    -e 's=@@LOCALEDIR_REL@@=$(localedir_relative_SQ)=g' \\\n-\t    $< >$@+ && \\\n-\tmv $@+ $@\n+\t    $< >$@\n \n .PHONY: perllibdir\n perllibdir:\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441302","messageId":"patch-v3-10.23-e9b61cd0ba5-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 10/23] Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:10Z","receivedAt":"2021-11-16T12:02:58Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Create a new \"GIT-PYTHON-DEFINES\" file, and untangle the dependency\nissues of the Python by copying over the patterns established for\nbuilding the adjacent Perl code in preceding commits.\n\nAs with Perl, there's no real reason to depend on GIT-BUILD-OPTIONS or\nGIT-CFLAGS when building the Python code, nor did we need\nGIT-PREFIX. Let's instead add those variables we care about to a\n\"GIT-PYTHON-DEFINES\" and depend on that.\n\nThis changes code originally added in ca3bcabf118 (auto-detect changed\nprefix and/or changed build flags, 2006-06-15), and adjusted in\n96a4647fca5 (Makefile: detect when PYTHON_PATH changes, 2012-12-18).\n\nThe relevant code for the \"Perl\" targets was then added in\n07981dce81e (Makefile: rebuild perl scripts when perl paths change,\n2013-11-18), and has been adjusted in preceding commits.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n .gitignore |  2 +-\n Makefile   | 49 +++++++++++++++++++++++++------------------------\n 2 files changed, 26 insertions(+), 25 deletions(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 054249b20a8..845e5d0c355 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -8,7 +8,7 @@\n /GIT-PREFIX\n /GIT-PERL-DEFINES\n /GIT-PERL-HEADER\n-/GIT-PYTHON-VARS\n+/GIT-PYTHON-DEFINES\n /GIT-SCRIPT-DEFINES\n /GIT-USER-AGENT\n /GIT-VERSION-FILE\ndiff --git a/Makefile b/Makefile\nindex 361abff2402..c698c5b058a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2378,18 +2378,15 @@ GIT-PERL-DEFINES: FORCE\n \t\techo \"$$FLAGS\" >$@; \\\n \t    fi\n \n-# This makes sure we depend on the NO_PYTHON setting itself.\n-$(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS\n+# As with NO_PERL=Y we'll still make GIT-PYTHON-DEFINES if \"NO_PYTHON\"\n+# is defined, for creating the \"unimplemented.sh\" scripts.\n+PYTHON_DEFINES =\n+$(SCRIPT_PYTHON_GEN): GIT-PYTHON-DEFINES\n+\n+ifdef NO_PYTHON\n+PYTHON_DEFINES += $(SHELL_PATH_SQ)\n+PYTHON_DEFINES += $(NO_PYTHON)\n \n-ifndef NO_PYTHON\n-$(SCRIPT_PYTHON_GEN): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS\n-$(SCRIPT_PYTHON_GEN): % : %.py\n-\t$(QUIET_GEN) \\\n-\tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n-\t    $< >$@+ && \\\n-\tchmod +x $@+ && \\\n-\tmv $@+ $@\n-else # NO_PYTHON\n $(SCRIPT_PYTHON_GEN): % : unimplemented.sh\n \t$(QUIET_GEN) \\\n \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2397,8 +2394,24 @@ $(SCRIPT_PYTHON_GEN): % : unimplemented.sh\n \t    unimplemented.sh >$@+ && \\\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n+else # NO_PYTHON\n+PYTHON_DEFINES += $(PYTHON_PATH_SQ)\n+\n+$(SCRIPT_PYTHON_GEN): % : %.py GIT-PYTHON-DEFINES\n+\t$(QUIET_GEN) \\\n+\tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n+\t    $< >$@+ && \\\n+\tchmod +x $@+ && \\\n+\tmv $@+ $@\n endif # NO_PYTHON\n \n+GIT-PYTHON-DEFINES: FORCE\n+\t@FLAGS='$(PYTHON_DEFINES)'; \\\n+\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n+\t\techo >&2 \"    * new python-specific parameters\"; \\\n+\t\techo \"$$FLAGS\" >$@; \\\n+\t    fi\n+\n CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t\t\tconfigure.ac >configure.ac+ && \\\n \t\t   autoconf -o configure configure.ac+ && \\\n@@ -2848,18 +2861,6 @@ else\n endif\n \t@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi\n \n-### Detect Python interpreter path changes\n-ifndef NO_PYTHON\n-TRACK_PYTHON = $(subst ','\\'',-DPYTHON_PATH='$(PYTHON_PATH_SQ)')\n-\n-GIT-PYTHON-VARS: FORCE\n-\t@VARS='$(TRACK_PYTHON)'; \\\n-\t    if test x\"$$VARS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new Python interpreter location\"; \\\n-\t\techo \"$$VARS\" >$@; \\\n-            fi\n-endif\n-\n test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))\n \n all:: $(TEST_PROGRAMS) $(test_bindir_programs)\n@@ -3256,7 +3257,7 @@ ifndef NO_TCLTK\n endif\n \t$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS\n \t$(RM) GIT-USER-AGENT GIT-PREFIX\n-\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS\n+\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-DEFINES\n ifdef MSVC\n \t$(RM) $(patsubst %.o,%.o.pdb,$(OBJECTS))\n \t$(RM) $(patsubst %.exe,%.pdb,$(OTHER_PROGRAMS))\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441303","messageId":"patch-v3-12.23-19539ce7d2d-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 12/23] Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:12Z","receivedAt":"2021-11-16T12:03:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We have various behavior that's shared across our Makefiles, or that\nreally should be (e.g. via defined templates). Let's create a\ntop-level \"shared.mak\" to house those sorts of things, and start by\nadding the \".DELETE_ON_ERROR\" flag to it.\n\nSee my own 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\"\nflag, 2021-06-29) and db10fc6c09f (doc: simplify Makefile using\n.DELETE_ON_ERROR, 2021-05-21) for the addition and use of the\n\".DELETE_ON_ERROR\" flag.\n\nThis does have the potential downside that if e.g. templates/Makefile\nwould like to include this \"shared.mak\" in the future the semantics of\nsuch a Makefile will change, but as noted in the above commits (and\nGNU make's own documentation) any such change would be for the better,\nso it's safe to do this.\n\nThis also doesn't introduce a bug by e.g. having this\n\".DELETE_ON_ERROR\" flag only apply to this new shared.mak, Makefiles\nhave no such scoping semantics.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile |  6 +++---\n Makefile               | 13 +++----------\n shared.mak             |  9 +++++++++\n 3 files changed, 15 insertions(+), 13 deletions(-)\n create mode 100644 shared.mak\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ed656db2ae9..ba27456c86a 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # Guard against environment variables\n MAN1_TXT =\n MAN5_TXT =\n@@ -524,7 +527,4 @@ doc-l10n install-l10n::\n \t$(MAKE) -C po $@\n endif\n \n-# Delete the target file on error\n-.DELETE_ON_ERROR:\n-\n .PHONY: FORCE\ndiff --git a/Makefile b/Makefile\nindex 8205614c6ec..5ae7d012cfb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include shared.mak\n+\n # The default target of this Makefile is...\n all::\n \n@@ -2158,16 +2161,6 @@ shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell\n strip: $(PROGRAMS) git$X\n \t$(STRIP) $(STRIP_OPTS) $^\n \n-### Flags affecting all rules\n-\n-# A GNU make extension since gmake 3.72 (released in late 1994) to\n-# remove the target of rules if commands in those rules fail. The\n-# default is to only do that if make itself receives a signal. Affects\n-# all targets, see:\n-#\n-#    info make --index-search=.DELETE_ON_ERROR\n-.DELETE_ON_ERROR:\n-\n ### Target-specific flags and dependencies\n \n # The generic compilation pattern rule and automatically\ndiff --git a/shared.mak b/shared.mak\nnew file mode 100644\nindex 00000000000..0170bb397ae\n--- /dev/null\n+++ b/shared.mak\n@@ -0,0 +1,9 @@\n+### Flags affecting all rules\n+\n+# A GNU make extension since gmake 3.72 (released in late 1994) to\n+# remove the target of rules if commands in those rules fail. The\n+# default is to only do that if make itself receives a signal. Affects\n+# all targets, see:\n+#\n+#    info make --index-search=.DELETE_ON_ERROR\n+.DELETE_ON_ERROR:\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441304","messageId":"patch-v3-11.23-b020f8e3257-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 11/23] Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:11Z","receivedAt":"2021-11-16T12:03:29Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the hardcoding of @@GIT_VERSION@@ in generated *.perl scripts\nto instead shell out to \"git version\". This means that we can stop\nre-building during development every time the HEAD changes.\n\nThese codepaths are not \"hot\", so shelling out to get the version\nshouldn't matter to users, in the one case where it potentially would\nin send-email (the loop for each E-Mail we send) we now cache the\nvalue, so we'll only retrieve it once.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile            | 2 +-\n git-cvsserver.perl  | 6 +++---\n git-send-email.perl | 7 ++-----\n git-svn.perl        | 2 +-\n 4 files changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex c698c5b058a..8205614c6ec 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2333,7 +2333,7 @@ PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n perl_localedir_SQ =\n endif\n \n-$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n+$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER\n \t$(QUIET_GEN) \\\n \tsed -e '1{' \\\n \t    -e '\ts|#!.*perl|#!$(PERL_PATH_SQ)|' \\\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 64319bed43f..76f0e8bbbef 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -26,8 +26,6 @@\n use File::Basename;\n use Getopt::Long qw(:config require_order no_ignore_case);\n \n-my $VERSION = '@@GIT_VERSION@@';\n-\n my $log = GITCVS::log->new();\n my $cfg;\n \n@@ -126,7 +124,9 @@\n     or die $usage;\n \n if ($state->{version}) {\n-    print \"git-cvsserver version $VERSION\\n\";\n+    my $version = qx[git version];\n+    $version =~ s/^(git)\\b/$1-cvsserver/;\n+    print $version;\n     exit;\n }\n if ($state->{help}) {\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 5262d88ee32..041cd2fb96d 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -1468,6 +1468,7 @@ sub file_name_is_absolute {\n #\n # If an error occurs sending the email, this just dies.\n \n+my $gitversion;\n sub send_message {\n \tmy @recipients = unique_email_list(@to);\n \t@cc = (grep { my $cc = extract_valid_address_or_die($_);\n@@ -1478,11 +1479,6 @@ sub send_message {\n \t@recipients = unique_email_list(@recipients,@cc,@initial_bcc);\n \t@recipients = (map { extract_valid_address_or_die($_) } @recipients);\n \tmy $date = format_2822_time($time++);\n-\tmy $gitversion = '@@GIT_VERSION@@';\n-\tif ($gitversion =~ m/..GIT_VERSION../) {\n-\t    $gitversion = Git::version();\n-\t}\n-\n \tmy $cc = join(\",\\n\\t\", unique_email_list(@cc));\n \tmy $ccline = \"\";\n \tif ($cc ne '') {\n@@ -1497,6 +1493,7 @@ sub send_message {\n Message-Id: $message_id\n \";\n \tif ($use_xmailer) {\n+\t\t$gitversion ||= Git::version();\n \t\t$header .= \"X-Mailer: git-send-email $gitversion\\n\";\n \t}\n \tif ($in_reply_to) {\ndiff --git a/git-svn.perl b/git-svn.perl\nindex be987e316f9..727431412be 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -9,7 +9,6 @@\n \t\t$_revision $_repository\n \t\t$_q $_authors $_authors_prog %users/;\n $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';\n-$VERSION = '@@GIT_VERSION@@';\n \n use Carp qw/croak/;\n use File::Basename qw/dirname basename/;\n@@ -47,6 +46,7 @@\n \tcommand_close_bidi_pipe\n \tget_record\n );\n+$VERSION = Git::version();\n \n BEGIN {\n \tMemoize::memoize 'Git::config';\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441305","messageId":"patch-v3-09.23-1ece3160915-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 09/23] Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:09Z","receivedAt":"2021-11-16T12:03:42Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix several small issues with the dependency graph of the generated\n\"GIT-PERL-DEFINES\" and \"GIT-PERL-HEADER\" files:\n\n1. Don't have \"GIT-PERL-HEADER\" depend on the \"Makefile\". That was a\n   lazy way to over-declare the dependencies added in\n   f6a0ad4be71 (Makefile: generate Perl header from template file,\n   2018-04-10). Let's correct our dependency graph instead.\n\n2. Don't have $(SCRIPT_PERL_GEN) (such as \"git-send-email\") depend on\n   GIT-BUILD-OPTIONS. Let's instead use GIT-PERL-DEFINES.\n\n   The reason for depending on \"GIT-BUILD-OPTIONS\" was to trigger a\n   re-build if NO_PERL=Y was defined. We can instead add that variable\n   to \"PERL_DEFINES\", and have \"GIT-PERL-DEFINES\" created and updated\n   if \"NO_PERL=Y\" is defined.\n\n3. Due to #2 we'll need to have GIT-PERL-DEFINES be generated even\n   under NO_PERL, since that variable will be used by the\n   \"unimplemented.sh\" script.\n\n4. Don't depend on $(gitexecdir), $(perllibdir) and $(localedir),\n   instead depend on the $(*_relative_SQ) versions of those.\n\n   The latter is what we'll actually use, while it's unlikely to\n   matter in practice (we'd just skip re-building these under\n   RUNTIME_PREFIX if the relative path was the same) it makes the code\n   easier to read.\n\n   That's because this brings us to a 1=1 mapping of these variables\n   and what's subsequently used in the \"GIT-PERL-DEFINES\",\n   \"GIT-PERL-HEADER\" and \"perl/build/lib/%.pm\" rules below.\n\n5. We don't need the substitution of \" \" for \":\" added in\n   07d90eadb50 (Makefile: add Perl runtime prefix support,\n   2018-04-10), let's drop it. This doesn't matter for the correctness\n   of these files, because unlike GIT-BUILD-OPTIONS nothing is\n   consuming them except the Makefile itself.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 42 +++++++++++++++++++++++++-----------------\n 1 file changed, 25 insertions(+), 17 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex ab78f8dd42e..361abff2402 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2288,10 +2288,14 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n \t    $(shell echo $(GIT_VERSION) 0 0 0 0 | tr '.a-zA-Z-' ' '))) \\\n \t  -DGIT_VERSION=\"\\\\\\\"$(GIT_VERSION)\\\\\\\"\" -i $< -o $@\n \n-# This makes sure we depend on the NO_PERL setting itself.\n-$(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n+# Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n+# on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n+PERL_DEFINES =\n+$(SCRIPT_PERL_GEN): GIT-PERL-DEFINES\n \n ifdef NO_PERL\n+PERL_DEFINES += $(NO_PERL)\n+\n $(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n \t$(QUIET_GEN) \\\n \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2300,22 +2304,26 @@ $(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n else # NO_PERL\n-# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n-# since the locale directory is injected.\n+# The localedir is only used in Perl modules if !NO_GETTEXT\n+ifndef NO_GETTEXT\n perl_localedir_SQ = $(localedir_SQ)\n+endif\n \n PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n-PERL_DEFINES =\n+\n PERL_DEFINES += $(PERL_PATH_SQ)\n PERL_DEFINES += $(PERLLIB_EXTRA_SQ)\n PERL_DEFINES += $(perllibdir_SQ)\n PERL_DEFINES += $(RUNTIME_PREFIX)\n PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n PERL_DEFINES += $(NO_GETTEXT)\n-PERL_DEFINES += $(gitexecdir)\n-PERL_DEFINES += $(perllibdir)\n-PERL_DEFINES += $(localedir)\n-PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n+ifdef RUNTIME_PREFIX\n+PERL_DEFINES += $(gitexecdir_relative_SQ)\n+PERL_DEFINES += $(perllibdir_relative_SQ)\n+PERL_DEFINES += $(localedir_relative_SQ)\n+else\n+PERL_DEFINES += $(perllocaledir_SQ)\n+endif\n \n ifdef RUNTIME_PREFIX\n PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n@@ -2337,14 +2345,7 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n-GIT-PERL-DEFINES: FORCE\n-\t@FLAGS='$(PERL_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new perl-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n-\n-GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n+GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES\n \t$(QUIET_GEN) \\\n \tINSTLIBDIR='$(perllibdir_SQ)' && \\\n \tINSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \\\n@@ -2370,6 +2371,13 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \tmv $@+ $@\n endif # NO_PERL\n \n+GIT-PERL-DEFINES: FORCE\n+\t@FLAGS='$(PERL_DEFINES)'; \\\n+\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n+\t\techo >&2 \"    * new perl-specific parameters\"; \\\n+\t\techo \"$$FLAGS\" >$@; \\\n+\t    fi\n+\n # This makes sure we depend on the NO_PYTHON setting itself.\n $(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS\n \n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441306","messageId":"patch-v3-08.23-0c0a3de390e-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 08/23] Makefile: adjust Perl-related comments & whitespace","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:08Z","receivedAt":"2021-11-16T12:03:47Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Folllow-up my 4070c9e09fc (Makefile: don't re-define PERL_DEFINES,\n2021-05-05) and move the rest of the assignments to PERL_DEFINES to\none place.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 15 ++++++---------\n 1 file changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 288f4834db8..ab78f8dd42e 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2312,21 +2312,19 @@ PERL_DEFINES += $(perllibdir_SQ)\n PERL_DEFINES += $(RUNTIME_PREFIX)\n PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n PERL_DEFINES += $(NO_GETTEXT)\n+PERL_DEFINES += $(gitexecdir)\n+PERL_DEFINES += $(perllibdir)\n+PERL_DEFINES += $(localedir)\n+PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n \n-# Support Perl runtime prefix. In this mode, a different header is installed\n-# into Perl scripts.\n ifdef RUNTIME_PREFIX\n-\n PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n \n-# Don't export a fixed $(localedir) path; it will be resolved by the Perl header\n-# at runtime.\n+# The RUNTIME_PREFIX header defines $Git::I18N::TEXTDOMAINDIR, so\n+# $(perl_localedir_SQ) won't be needed\n perl_localedir_SQ =\n-\n endif\n \n-PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n-\n $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \t$(QUIET_GEN) \\\n \tsed -e '1{' \\\n@@ -2339,7 +2337,6 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n-PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n GIT-PERL-DEFINES: FORCE\n \t@FLAGS='$(PERL_DEFINES)'; \\\n \t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441307","messageId":"patch-v3-07.23-047a42b01cf-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 07/23] Makefile: change \"ifndef NO_PERL\" to \"ifdef NO_PERL\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:07Z","receivedAt":"2021-11-16T12:03:57Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the NO_PERL variable assignments so that they declare the much\nsmaller fallback condition first.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 18 +++++++++---------\n 1 file changed, 9 insertions(+), 9 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 0cb10f00ebb..288f4834db8 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2291,7 +2291,15 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n # This makes sure we depend on the NO_PERL setting itself.\n $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n-ifndef NO_PERL\n+ifdef NO_PERL\n+$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n+\t$(QUIET_GEN) \\\n+\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n+\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n+\t    unimplemented.sh >$@+ && \\\n+\tchmod +x $@+ && \\\n+\tmv $@+ $@\n+else # NO_PERL\n # Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n # since the locale directory is injected.\n perl_localedir_SQ = $(localedir_SQ)\n@@ -2363,14 +2371,6 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \t$(QUIET_GEN)$(cmd_munge_script) && \\\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n-else # NO_PERL\n-$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n-\t$(QUIET_GEN) \\\n-\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n-\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n-\t    unimplemented.sh >$@+ && \\\n-\tchmod +x $@+ && \\\n-\tmv $@+ $@\n endif # NO_PERL\n \n # This makes sure we depend on the NO_PYTHON setting itself.\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441308","messageId":"patch-v3-13.23-6c9291c2c9f-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 13/23] Makefile: move $(comma), $(empty) and $(space) to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:13Z","receivedAt":"2021-11-16T12:04:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move these variables over to the shared.max, we'll make use of them in\na subsequent commit. There was no reason for these to be \"simply\nexpanded variables\", so let's use the normal lazy \"=\" assignment here.\n\nSee 425ca6710b2 (Makefile: allow combining UBSan with other\nsanitizers, 2017-07-15) for the commit that introduced these.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile   | 4 ----\n shared.mak | 8 ++++++++\n 2 files changed, 8 insertions(+), 4 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 5ae7d012cfb..7130e32a251 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1252,10 +1252,6 @@ endif\n ALL_CFLAGS = $(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS)\n ALL_LDFLAGS = $(LDFLAGS)\n \n-comma := ,\n-empty :=\n-space := $(empty) $(empty)\n-\n ifdef SANITIZE\n SANITIZERS := $(foreach flag,$(subst $(comma),$(space),$(SANITIZE)),$(flag))\n BASIC_CFLAGS += -fsanitize=$(SANITIZE) -fno-sanitize-recover=$(SANITIZE)\ndiff --git a/shared.mak b/shared.mak\nindex 0170bb397ae..2d597ef7603 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -7,3 +7,11 @@\n #\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n+\n+### Global variables\n+\n+## comma, empty, space: handy variables as these tokens are either\n+## special or can be hard to spot among other Makefile syntax.\n+comma = ,\n+empty =\n+space = $(empty) $(empty)\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441309","messageId":"patch-v3-14.23-e811a907b08-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 14/23] Makefile: re-add and use the \"shellquote\" macros","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:14Z","receivedAt":"2021-11-16T12:04:13Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Re-add and use, and expand on \"shellquote\" macros added in\n4769948afe7 (Deal with $(bindir) and friends with whitespaces.,\n2005-10-10).\n\nWe avoided using them due to the \"$(call)\" feature of GNU make being\nrelatively new at the time, but it isn't anymore. We hard depend on\nGNU make versions that have it.\n\nThe use of \"$(call)\" was removed in 39c015c556f (Fixes for ancient\nversions of GNU make, 2006-02-18) and 7ffe7098dca (Fix installation of\ntemplates on ancient systems., 2006-07-29) due to those\nincompatibilities with older GNU make versions, and we've used the\nmore verbose *_SQ pattern ever since.\n\nThe \"$(call)\" feature was introduced in GNU make version 3.78,\nreleased on the 22nd of September, 1999. That release also introduced\n\"$(error)\" and \"$(warning)\", which we've been making use of since\nf2fabbf76e4 (Teach Makefile to check header dependencies, 2010-01-26).\n\nThis extends upon the macros added in 4769948afe7: We now have macros\nfor quoting a ' inside '', and a ' with no surrounding '' as before.\n\nAdditionally provide and use a \"shelldquote\" macro along with\n\"shellquote\" for the common case of wanting to quote a C string we\npass to the compiler with a -D flag.\n\nThis doesn't get rid of all of our shell quoting. We've still got some\nin the main Makefile, let's leave most of it to avoid in-flight\nconflicts. I've fully converted \"templates/Makefile\" and \"t/Makefile\"\nthough.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile           | 15 +++++----------\n shared.mak         | 14 ++++++++++++++\n t/Makefile         | 34 +++++++++++++++-------------------\n templates/Makefile | 14 +++++---------\n 4 files changed, 39 insertions(+), 38 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 7130e32a251..b458c24d95e 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1996,11 +1996,7 @@ ifneq (\"$(PROFILE)\",\"\")\n endif\n endif\n \n-# Shell quote (do not use $(call) to accommodate ancient setups);\n-\n-ETC_GITCONFIG_SQ = $(subst ','\\'',$(ETC_GITCONFIG))\n-ETC_GITATTRIBUTES_SQ = $(subst ','\\'',$(ETC_GITATTRIBUTES))\n-\n+# Shell quote, should be changed to use $(call shellquote,...)\n DESTDIR_SQ = $(subst ','\\'',$(DESTDIR))\n NO_GETTEXT_SQ = $(subst ','\\'',$(NO_GETTEXT))\n bindir_SQ = $(subst ','\\'',$(bindir))\n@@ -2535,11 +2531,11 @@ builtin/init-db.sp builtin/init-db.s builtin/init-db.o: EXTRA_CPPFLAGS = \\\n \n config.sp config.s config.o: GIT-PREFIX\n config.sp config.s config.o: EXTRA_CPPFLAGS = \\\n-\t-DETC_GITCONFIG='\"$(ETC_GITCONFIG_SQ)\"'\n+\t-DETC_GITCONFIG=$(call shelldquote,$(ETC_GITCONFIG))\n \n attr.sp attr.s attr.o: GIT-PREFIX\n attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \\\n-\t-DETC_GITATTRIBUTES='\"$(ETC_GITATTRIBUTES_SQ)\"'\n+\t-DETC_GITATTRIBUTES=$(call shelldquote,$(ETC_GITATTRIBUTES))\n \n gettext.sp gettext.s gettext.o: GIT-PREFIX\n gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \\\n@@ -2700,14 +2696,13 @@ perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n \t    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \\\n-\t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \\\n+\t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(call shq,$(NO_PERL_CPAN_FALLBACKS))|g' \\\n \t< $< > $@\n \n all:: $(LIB_PERL_GEN)\n ifndef NO_PERL_CPAN_FALLBACKS\n all:: $(LIB_CPAN_GEN)\n endif\n-NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n endif\n \n # install-man depends on Git.3pm even with NO_PERL=Y\n@@ -3021,7 +3016,7 @@ else\n \t$(INSTALL) $(vcpkg_dbg_bin)/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'\n endif\n endif\n-\t$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install\n+\t$(MAKE) -C templates DESTDIR=$(call shellquote,$(DESTDIR)) install\n \t$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'\n \t$(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'\n ifndef NO_GETTEXT\ndiff --git a/shared.mak b/shared.mak\nindex 2d597ef7603..ef03c2bc094 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -8,6 +8,20 @@\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n \n+### Quoting helpers\n+\n+## Quote a ' inside a '': FOO='$(call shq,$(BAR))'\n+shq = $(subst ','\\'',$(1))\n+\n+## Quote a ' and provide a '': FOO=$(call shq,$(BAR))\n+shellquote = '$(call shq,$(1))'\n+\n+## Quote a \" inside a \"\"\n+shdq = $(subst \",\\\",$(1))\n+\n+## Quote ' for the shell, and embedded \" for C: -DFOO=$(call shelldquote,$(BAR))\n+shelldquote = '\"$(call shdq,$(call shq,$(1)))\"'\n+\n ### Global variables\n \n ## comma, empty, space: handy variables as these tokens are either\ndiff --git a/t/Makefile b/t/Makefile\nindex 882d26eee30..4168b5c6ce6 100644\n--- a/t/Makefile\n+++ b/t/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # Run tests\n #\n # Copyright (c) 2005 Junio C Hamano\n@@ -24,13 +27,6 @@ TEST_RESULTS_DIRECTORY = test-results\n CHAINLINTTMP = chainlinttmp\n endif\n \n-# Shell quote;\n-SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n-TEST_SHELL_PATH_SQ = $(subst ','\\'',$(TEST_SHELL_PATH))\n-PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n-TEST_RESULTS_DIRECTORY_SQ = $(subst ','\\'',$(TEST_RESULTS_DIRECTORY))\n-CHAINLINTTMP_SQ = $(subst ','\\'',$(CHAINLINTTMP))\n-\n T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))\n TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh))\n THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh)))\n@@ -44,38 +40,38 @@ test: pre-clean check-chainlint $(TEST_LINT)\n \t$(MAKE) aggregate-results-and-cleanup\n \n failed:\n-\t@failed=$$(cd '$(TEST_RESULTS_DIRECTORY_SQ)' && \\\n+\t@failed=$$(cd $(call shellquote,$(TEST_RESULTS_DIRECTORY)) && \\\n \t\tgrep -l '^failed [1-9]' *.counts | \\\n \t\tsed -n 's/\\.counts$$/.sh/p') && \\\n \ttest -z \"$$failed\" || $(MAKE) $$failed\n \n prove: pre-clean check-chainlint $(TEST_LINT)\n-\t@echo \"*** prove ***\"; $(PROVE) --exec '$(TEST_SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n+\t@echo \"*** prove ***\"; $(PROVE) --exec $(call shellquote,$(SHELL_PATH)) $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n \t$(MAKE) clean-except-prove-cache\n \n $(T):\n-\t@echo \"*** $@ ***\"; '$(TEST_SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)\n+\t@echo \"*** $@ ***\"; $(call shellquote,$(SHELL_PATH)) $@ $(GIT_TEST_OPTS)\n \n pre-clean:\n-\t$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'\n+\t$(RM) -r $(call shellquote,$(TEST_RESULTS_DIRECTORY))\n \n clean-except-prove-cache: clean-chainlint\n-\t$(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)'\n+\t$(RM) -r 'trash directory'.* $(call shellquote,$(TEST_RESULTS_DIRECTORY))\n \t$(RM) -r valgrind/bin\n \n clean: clean-except-prove-cache\n \t$(RM) .prove\n \n clean-chainlint:\n-\t$(RM) -r '$(CHAINLINTTMP_SQ)'\n+\t$(RM) -r $(call shellquote,$(CHAINLINTTMP))\n \n check-chainlint:\n-\t@mkdir -p '$(CHAINLINTTMP_SQ)' && \\\n+\t@mkdir -p $(call shellquote,$(CHAINLINTTMP)) && \\\n \terr=0 && \\\n \tfor i in $(CHAINLINTTESTS); do \\\n \t\t$(CHAINLINT) <chainlint/$$i.test | \\\n-\t\tsed -e '/^# LINT: /d' >'$(CHAINLINTTMP_SQ)'/$$i.actual && \\\n-\t\tdiff -u chainlint/$$i.expect '$(CHAINLINTTMP_SQ)'/$$i.actual || err=1; \\\n+\t\tsed -e '/^# LINT: /d' >$(call shellquote,$(CHAINLINTTMP))/$$i.actual && \\\n+\t\tdiff -u chainlint/$$i.expect $(call shellquote,$(CHAINLINTTMP))/$$i.actual || err=1; \\\n \tdone && exit $$err\n \n test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \\\n@@ -92,7 +88,7 @@ test-lint-executable:\n \t\techo >&2 \"non-executable tests:\" $$bad; exit 1; }\n \n test-lint-shell-syntax:\n-\t@'$(PERL_PATH_SQ)' check-non-portable-shell.pl $(T) $(THELPERS) $(TPERF)\n+\t@$(call shellquote,$(PERL_PATH)) check-non-portable-shell.pl $(T) $(THELPERS) $(TPERF)\n \n test-lint-filenames:\n \t@# We do *not* pass a glob to ls-files but use grep instead, to catch\n@@ -107,9 +103,9 @@ aggregate-results-and-cleanup: $(T)\n \t$(MAKE) clean\n \n aggregate-results:\n-\tfor f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \\\n+\tfor f in $(call shellquote,$(TEST_RESULTS_DIRECTORY))/t*-*.counts; do \\\n \t\techo \"$$f\"; \\\n-\tdone | '$(SHELL_PATH_SQ)' ./aggregate-results.sh\n+\tdone | $(call shellquote,$(SHELL_PATH)) ./aggregate-results.sh\n \n gitweb-test:\n \t$(MAKE) $(TGITWEB)\ndiff --git a/templates/Makefile b/templates/Makefile\nindex d22a71a3999..c9251a96622 100644\n--- a/templates/Makefile\n+++ b/templates/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # make and install sample templates\n \n ifndef V\n@@ -18,13 +21,6 @@ ifndef PERL_PATH\n \tPERL_PATH = perl\n endif\n \n-SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n-PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n-\n-# Shell quote (do not use $(call) to accommodate ancient setups);\n-DESTDIR_SQ = $(subst ','\\'',$(DESTDIR))\n-template_instdir_SQ = $(subst ','\\'',$(template_instdir))\n-\n all: boilerplates.made custom\n \n # Put templates that can be copied straight from the source\n@@ -61,6 +57,6 @@ clean:\n \t$(RM) -r blt boilerplates.made\n \n install: all\n-\t$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(template_instdir_SQ)'\n+\t$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(template_instdir))\n \t(cd blt && $(TAR) cf - .) | \\\n-\t(cd '$(DESTDIR_SQ)$(template_instdir_SQ)' && umask 022 && $(TAR) xof -)\n+\t(cd $(call shellquote,$(DESTDIR)$(template_instdir)) && umask 022 && $(TAR) xof -)\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441310","messageId":"patch-v3-16.23-a3e3acea82d-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 16/23] Makefile: add \"$(QUIET)\" boilerplate to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:16Z","receivedAt":"2021-11-16T12:04:29Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"The $(QUIET) variables we define are largely duplicated between our\nvarious Makefiles, let's define them in the new \"shared.mak\" instead.\n\nSince we're not using the environment to pass these around we don't\nneed to export the \"QUIET_GEN\" and \"QUIET_BUILT_IN\" variables\nanymore. The \"QUIET_GEN\" variable is used in \"git-gui/Makefile\" and\n\"gitweb/Makefile\", but they've got their own definition for those. The\n\"QUIET_BUILT_IN\" variable is only used in the top-level \"Makefile\". We\nstill need to export the \"V\" variable.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile | 32 -------------------------\n Makefile               | 33 --------------------------\n config.mak.uname       |  1 -\n shared.mak             | 53 ++++++++++++++++++++++++++++++++++++++++++\n templates/Makefile     |  5 ----\n 5 files changed, 53 insertions(+), 71 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex 4a939cc2c25..69a9af35397 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -218,38 +218,6 @@ DEFAULT_EDITOR_SQ = $(subst ','\\'',$(DEFAULT_EDITOR))\n ASCIIDOC_EXTRA += -a 'git-default-editor=$(DEFAULT_EDITOR_SQ)'\n endif\n \n-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n-QUIET_SUBDIR1  =\n-\n-ifneq ($(findstring $(MAKEFLAGS),w),w)\n-PRINT_DIR = --no-print-directory\n-else # \"make -w\"\n-NO_SUBDIR = :\n-endif\n-\n-ifneq ($(findstring $(MAKEFLAGS),s),s)\n-ifndef V\n-\tQUIET\t\t= @\n-\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n-\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n-\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n-\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n-\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n-\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n-\tQUIET_GEN\t= @echo '   ' GEN $@;\n-\tQUIET_STDERR\t= 2> /dev/null\n-\tQUIET_SUBDIR0\t= +@subdir=\n-\tQUIET_SUBDIR1\t= ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n-\t\t\t  $(MAKE) $(PRINT_DIR) -C $$subdir\n-\n-\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n-\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n-\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n-\n-\texport V\n-endif\n-endif\n-\n all: html man\n \n html: $(DOC_HTML)\ndiff --git a/Makefile b/Makefile\nindex c8a0a1586ca..c437aea9e4a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1939,39 +1939,6 @@ ifndef PAGER_ENV\n PAGER_ENV = LESS=FRX LV=-c\n endif\n \n-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n-QUIET_SUBDIR1  =\n-\n-ifneq ($(findstring w,$(MAKEFLAGS)),w)\n-PRINT_DIR = --no-print-directory\n-else # \"make -w\"\n-NO_SUBDIR = :\n-endif\n-\n-ifneq ($(findstring s,$(MAKEFLAGS)),s)\n-ifndef V\n-\tQUIET_CC       = @echo '   ' CC $@;\n-\tQUIET_AR       = @echo '   ' AR $@;\n-\tQUIET_LINK     = @echo '   ' LINK $@;\n-\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n-\tQUIET_GEN      = @echo '   ' GEN $@;\n-\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n-\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n-\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n-\tQUIET_GCOV     = @echo '   ' GCOV $@;\n-\tQUIET_SP       = @echo '   ' SP $<;\n-\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n-\tQUIET_RC       = @echo '   ' RC $@;\n-\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n-\tQUIET_SUBDIR0  = +@subdir=\n-\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n-\t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n-\texport V\n-\texport QUIET_GEN\n-\texport QUIET_BUILT_IN\n-endif\n-endif\n-\n ifdef NO_INSTALL_HARDLINKS\n \texport NO_INSTALL_HARDLINKS\n endif\ndiff --git a/config.mak.uname b/config.mak.uname\nindex d0701f9beb0..1a12d8c635f 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -715,7 +715,6 @@ vcxproj:\n \tgit diff-index --cached --quiet HEAD --\n \n \t# Make .vcxproj files and add them\n-\tunset QUIET_GEN QUIET_BUILT_IN; \\\n \tperl contrib/buildsystems/generate -g Vcxproj\n \tgit add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj\n \ndiff --git a/shared.mak b/shared.mak\nindex 3b4163e652a..80176f705fc 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -35,6 +35,59 @@ space = $(empty) $(empty)\n wspfx = $(space)$(space)$(space)\n wspfx_sq = $(call shellquote,$(wspfx))\n \n+### Quieting\n+## common\n+QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n+QUIET_SUBDIR1  =\n+\n+ifneq ($(findstring w,$(MAKEFLAGS)),w)\n+PRINT_DIR = --no-print-directory\n+else # \"make -w\"\n+NO_SUBDIR = :\n+endif\n+\n+ifneq ($(findstring s,$(MAKEFLAGS)),s)\n+ifndef V\n+## common\n+\tQUIET_SUBDIR0  = +@subdir=\n+\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n+\t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n+\n+\tQUIET          = @\n+\tQUIET_GEN      = @echo '   ' GEN $@;\n+\n+## Used in \"Makefile\"\n+\tQUIET_CC       = @echo '   ' CC $@;\n+\tQUIET_AR       = @echo '   ' AR $@;\n+\tQUIET_LINK     = @echo '   ' LINK $@;\n+\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n+\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n+\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n+\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n+\tQUIET_GCOV     = @echo '   ' GCOV $@;\n+\tQUIET_SP       = @echo '   ' SP $<;\n+\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n+\tQUIET_RC       = @echo '   ' RC $@;\n+\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n+\n+## Used in \"Documentation/Makefile\"\n+\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n+\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n+\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n+\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n+\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n+\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n+\tQUIET_GEN\t= @echo '   ' GEN $@;\n+\tQUIET_STDERR\t= 2> /dev/null\n+\n+\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n+\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n+\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n+\n+\texport V\n+endif\n+endif\n+\n ### Templates\n \n ## Template for making a GIT-SOMETHING, which changes if a\ndiff --git a/templates/Makefile b/templates/Makefile\nindex c9251a96622..b056e710b7e 100644\n--- a/templates/Makefile\n+++ b/templates/Makefile\n@@ -2,11 +2,6 @@\n include ../shared.mak\n \n # make and install sample templates\n-\n-ifndef V\n-\tQUIET = @\n-endif\n-\n INSTALL ?= install\n TAR ?= tar\n RM ?= rm -f\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441311","messageId":"patch-v3-15.23-fac30fe8b56-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 15/23] Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:15Z","receivedAt":"2021-11-16T12:04:29Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move the mostly copy/pasted code in the \"Makefile\" and\n\"Documentation/Makefile\" which FORCE-generates a file based on a\nvariable in play in the Makefile to use a template.\n\nThis will make it easier later on to move these to rules that aren't\nFORCE-run using optional gmake 4.2+ features, but for now just getting\nrid of the repetition is worth it.\n\nThe message for the new generated rule will say whether or not we're\ngenerating the file for the first time, as opposed to the old messages\nsaying \"new\" whether we had flag modifications, or were building for\nthe first time.\n\nExample output before:\n\n    $ make clean\n    [...]\n    $ make\n    GIT_VERSION = 2.34.0-rc1-dev\n        * new build flags\n        CC grep.o\n    $ make CFLAGS=-I$RANDOM grep.o\n        * new build flags\n        CC grep.o\n\nAfter:\n\n    $ make clean\n    [...]\n    $ make grep.o\n    GIT_VERSION = 2.34.0-rc1-dev\n        GIT-CFLAGS PARAMETERS (new)\n        CC grep.o\n    $ make CFLAGS=-I$RANDOM grep.o\n        GIT-CFLAGS PARAMETERS (changed)\n        CC grep.o\n\nNote: It's important that \"@FLAGS\" here be defined as '$$($(2))', and\nnot the eagerly expanded '$($(2))'. The latter will break if\ne.g. curl-config isn't installed, since we'll end up recursively\nexpanding that part of the variable even if NO_CURL isn't defined,\nwhich happens e.g. for the \"check-docs\" target in CI.\n\nWe're also introducing a $(wspfx) variable here to control the\nwhitespace prefixing. It matches the $(QUIET...) variables, who'll be\nusing these variables in a subsequent commit. Note that it's important\nthat we call the shell quote escaping macros inline (or equivalent),\nbecause if we'd like variables to be overridable we need to support e.g.:\n\n    $ make CFLAGS=-I$RANDOM grep.o wspfx='$(space)->'\n     -> GIT-CFLAGS PARAMETERS (changed)\n        CC grep.o\n\nIf we simply quoted and used $(wspfx) then the user would need to\nprovide us with a quoted version, so there's still some use-cases for\nthese $(*_sq) variables. It could also be done inline, but that's a\nlot more verbose.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile |  8 +------\n Makefile               | 51 ++++++------------------------------------\n shared.mak             | 22 ++++++++++++++++++\n 3 files changed, 30 insertions(+), 51 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ba27456c86a..4a939cc2c25 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -343,13 +343,7 @@ mergetools-list.made: ../git-mergetool--lib.sh $(wildcard ../mergetools/*)\n \tdate >$@\n \n TRACK_ASCIIDOCFLAGS = $(subst ','\\'',$(ASCIIDOC_COMMON):$(ASCIIDOC_HTML):$(ASCIIDOC_DOCBOOK))\n-\n-GIT-ASCIIDOCFLAGS: FORCE\n-\t@FLAGS='$(TRACK_ASCIIDOCFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-ASCIIDOCFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new asciidoc flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-ASCIIDOCFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-ASCIIDOCFLAGS,TRACK_ASCIIDOCFLAGS))\n \n clean:\n \t$(RM) -rf .build/\ndiff --git a/Makefile b/Makefile\nindex b458c24d95e..c8a0a1586ca 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2087,10 +2087,7 @@ endif\n GIT_USER_AGENT_SQ = $(subst ','\\'',$(GIT_USER_AGENT))\n GIT_USER_AGENT_CQ = \"$(subst \",\\\",$(subst \\,\\\\,$(GIT_USER_AGENT)))\"\n GIT_USER_AGENT_CQ_SQ = $(subst ','\\'',$(GIT_USER_AGENT_CQ))\n-GIT-USER-AGENT: FORCE\n-\t@if test x'$(GIT_USER_AGENT_SQ)' != x\"`cat GIT-USER-AGENT 2>/dev/null`\"; then \\\n-\t\techo '$(GIT_USER_AGENT_SQ)' >GIT-USER-AGENT; \\\n-\tfi\n+$(eval $(call TRACK_template,GIT-USER-AGENT,GIT_USER_AGENT_SQ))\n \n ifdef DEFAULT_HELP_FORMAT\n BASIC_CFLAGS += -DDEFAULT_HELP_FORMAT='\"$(DEFAULT_HELP_FORMAT)\"'\n@@ -2238,12 +2235,7 @@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\\\n \t$(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n \t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(PAGER_ENV):\\\n \t$(perllibdir_SQ)\n-GIT-SCRIPT-DEFINES: FORCE\n-\t@FLAGS='$(SCRIPT_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new script parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-SCRIPT-DEFINES,SCRIPT_DEFINES))\n \n define cmd_munge_script\n sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2355,13 +2347,7 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n endif # NO_PERL\n-\n-GIT-PERL-DEFINES: FORCE\n-\t@FLAGS='$(PERL_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new perl-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n+$(eval $(call TRACK_template,GIT-PERL-DEFINES,PERL_DEFINES))\n \n # As with NO_PERL=Y we'll still make GIT-PYTHON-DEFINES if \"NO_PYTHON\"\n # is defined, for creating the \"unimplemented.sh\" scripts.\n@@ -2390,12 +2376,7 @@ $(SCRIPT_PYTHON_GEN): % : %.py GIT-PYTHON-DEFINES\n \tmv $@+ $@\n endif # NO_PYTHON\n \n-GIT-PYTHON-DEFINES: FORCE\n-\t@FLAGS='$(PYTHON_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new python-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n+$(eval $(call TRACK_template,GIT-PYTHON-DEFINES,PYTHON_DEFINES))\n \n CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t\t\tconfigure.ac >configure.ac+ && \\\n@@ -2751,31 +2732,13 @@ cscope: cscope.out\n ### Detect prefix changes\n TRACK_PREFIX = $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\\\n \t\t$(localedir_SQ)\n-\n-GIT-PREFIX: FORCE\n-\t@FLAGS='$(TRACK_PREFIX)'; \\\n-\tif test x\"$$FLAGS\" != x\"`cat GIT-PREFIX 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new prefix flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-PREFIX; \\\n-\tfi\n+$(eval $(call TRACK_template,GIT-PREFIX,TRACK_PREFIX))\n \n TRACK_CFLAGS = $(CC):$(subst ','\\'',$(ALL_CFLAGS)):$(USE_GETTEXT_SCHEME)\n-\n-GIT-CFLAGS: FORCE\n-\t@FLAGS='$(TRACK_CFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-CFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new build flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-CFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-CFLAGS,TRACK_CFLAGS))\n \n TRACK_LDFLAGS = $(subst ','\\'',$(ALL_LDFLAGS))\n-\n-GIT-LDFLAGS: FORCE\n-\t@FLAGS='$(TRACK_LDFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-LDFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new link flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-LDFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-LDFLAGS,TRACK_LDFLAGS))\n \n # We need to apply sq twice, once to protect from the shell\n # that runs GIT-BUILD-OPTIONS, and then again to protect it\ndiff --git a/shared.mak b/shared.mak\nindex ef03c2bc094..3b4163e652a 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -29,3 +29,25 @@ shelldquote = '\"$(call shdq,$(call shq,$(1)))\"'\n comma = ,\n empty =\n space = $(empty) $(empty)\n+\n+## wspfx: the whitespace prefix padding for $(QUIET...) and similarly\n+## aligned output.\n+wspfx = $(space)$(space)$(space)\n+wspfx_sq = $(call shellquote,$(wspfx))\n+\n+### Templates\n+\n+## Template for making a GIT-SOMETHING, which changes if a\n+## TRACK_SOMETHING variable changes.\n+define TRACK_template\n+.PHONY: FORCE\n+$(1): FORCE\n+\t@FLAGS='$$($(2))'; \\\n+\tif ! test -f $(1) ; then \\\n+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (new)\" $@; \\\n+\t\techo \"$$$$FLAGS\" >$(1); \\\n+\telif test x\"$$$$FLAGS\" != x\"`cat $(1) 2>/dev/null`\" ; then \\\n+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (changed)\" $@; \\\n+\t\techo \"$$$$FLAGS\" >$(1); \\\n+\tfi\n+endef\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441312","messageId":"patch-v3-17.23-22264f431c8-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 17/23] Makefile: use $(wspfx) for $(QUIET...) in shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:17Z","receivedAt":"2021-11-16T12:04:39Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the mostly move-only change in the preceding commit to use the\n$(wspfx) variable for defining the QUIET padding, to guarantee that\nit's consistent with the \"TRACK_template\" template.\n\n    $ make CFLAGS=-I$RANDOM grep.o wspfx='$(space)->'\n     -> GIT-CFLAGS PARAMETERS (changed)\n     -> CC grep.o\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n shared.mak | 48 ++++++++++++++++++++++++------------------------\n 1 file changed, 24 insertions(+), 24 deletions(-)\n\ndiff --git a/shared.mak b/shared.mak\nindex 80176f705fc..a1b62b272f8 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -50,39 +50,39 @@ ifneq ($(findstring s,$(MAKEFLAGS)),s)\n ifndef V\n ## common\n \tQUIET_SUBDIR0  = +@subdir=\n-\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n+\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo $(wspfx_sq) SUBDIR $$subdir; \\\n \t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n \n \tQUIET          = @\n-\tQUIET_GEN      = @echo '   ' GEN $@;\n+\tQUIET_GEN      = @echo $(wspfx_sq) GEN $@;\n \n ## Used in \"Makefile\"\n-\tQUIET_CC       = @echo '   ' CC $@;\n-\tQUIET_AR       = @echo '   ' AR $@;\n-\tQUIET_LINK     = @echo '   ' LINK $@;\n-\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n-\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n-\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n-\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n-\tQUIET_GCOV     = @echo '   ' GCOV $@;\n-\tQUIET_SP       = @echo '   ' SP $<;\n-\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n-\tQUIET_RC       = @echo '   ' RC $@;\n-\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n+\tQUIET_CC       = @echo $(wspfx_sq) CC $@;\n+\tQUIET_AR       = @echo $(wspfx_sq) AR $@;\n+\tQUIET_LINK     = @echo $(wspfx_sq) LINK $@;\n+\tQUIET_BUILT_IN = @echo $(wspfx_sq) BUILTIN $@;\n+\tQUIET_LNCP     = @echo $(wspfx_sq) LN/CP $@;\n+\tQUIET_XGETTEXT = @echo $(wspfx_sq) XGETTEXT $@;\n+\tQUIET_MSGFMT   = @echo $(wspfx_sq) MSGFMT $@;\n+\tQUIET_GCOV     = @echo $(wspfx_sq) GCOV $@;\n+\tQUIET_SP       = @echo $(wspfx_sq) SP $<;\n+\tQUIET_HDR      = @echo $(wspfx_sq) HDR $(<:hcc=h);\n+\tQUIET_RC       = @echo $(wspfx_sq) RC $@;\n+\tQUIET_SPATCH   = @echo $(wspfx_sq) SPATCH $<;\n \n ## Used in \"Documentation/Makefile\"\n-\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n-\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n-\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n-\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n-\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n-\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n-\tQUIET_GEN\t= @echo '   ' GEN $@;\n+\tQUIET_ASCIIDOC\t= @echo $(wspfx_sq) ASCIIDOC $@;\n+\tQUIET_XMLTO\t= @echo $(wspfx_sq) XMLTO $@;\n+\tQUIET_DB2TEXI\t= @echo $(wspfx_sq) DB2TEXI $@;\n+\tQUIET_MAKEINFO\t= @echo $(wspfx_sq) MAKEINFO $@;\n+\tQUIET_DBLATEX\t= @echo $(wspfx_sq) DBLATEX $@;\n+\tQUIET_XSLTPROC\t= @echo $(wspfx_sq) XSLTPROC $@;\n+\tQUIET_GEN\t= @echo $(wspfx_sq) GEN $@;\n \tQUIET_STDERR\t= 2> /dev/null\n \n-\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n-\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n-\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n+\tQUIET_LINT_GITLINK\t= @echo $(wspfx_sq) LINT GITLINK $<;\n+\tQUIET_LINT_MANSEC\t= @echo $(wspfx_sq) LINT MAN SEC $<;\n+\tQUIET_LINT_MANEND\t= @echo $(wspfx_sq) LINT MAN END $<;\n \n \texport V\n endif\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441313","messageId":"patch-v3-18.23-d61e2b44f68-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 18/23] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:18Z","receivedAt":"2021-11-16T12:04:43Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\nfor us, and use it for the \"make lint-docs\" targets I added in\n8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n\nAs seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\ndependency, 2021-10-26) maintaining these manual lists of parent\ndirectory dependencies is fragile, in addition to being obviously\nverbose.\n\nI used this pattern at the time because I couldn't find another method\nthan \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\nevery file being created, which as noted in [1] would be significantly\nslower.\n\nBut as it turns out we can use this neat trick of only doing a \"mkdir\n-p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\nof a performance test similar to thatnoted downthread of [1] in [2]\nshows that this is faster, in addition to being less verbose and more\nreliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n\n    $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n    Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n      Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n      Range (min … max):    2.121 s …  2.158 s    10 runs\n\n    Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n      Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n      Range (min … max):    2.657 s …  2.662 s    10 runs\n\n    Summary\n      'make -C Documentation lint-docs' in 'HEAD~0' ran\n        1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n\nSo let's use that pattern both for the \"lint-docs\" target, and a few\nmiscellaneous other targets.\n\nThis method of creating parent directories is explicitly racy in that\nwe don't know if we're going to say always create a \"foo\" followed by\na \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n\"foo/bar\" first. In this case it doesn't matter for anything except\nthat we aren't guaranteed to get the same number of rules firing when\nrunning make in parallel.\n\n1. https://lore.kernel.org/git/211028.861r45y3pt.gmgdl@evledraar.gmail.com/\n2. https://lore.kernel.org/git/211028.86o879vvtp.gmgdl@evledraar.gmail.com/\n3. https://gitlab.com/avar/git-hyperfine/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile | 25 +++----------------------\n Makefile               | 12 +++++++-----\n shared.mak             |  7 +++++++\n 3 files changed, 17 insertions(+), 27 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex 69a9af35397..d16b653394c 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -428,25 +428,11 @@ quick-install-html: require-htmlrepo\n print-man1:\n \t@for i in $(MAN1_TXT); do echo $$i; done\n \n-## Lint: Common\n-.build:\n-\t$(QUIET)mkdir $@\n-.build/lint-docs: | .build\n-\t$(QUIET)mkdir $@\n-\n ## Lint: gitlink\n-.build/lint-docs/gitlink: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n-.build/lint-docs/gitlink/howto: | .build/lint-docs/gitlink\n-\t$(QUIET)mkdir $@\n-.build/lint-docs/gitlink/config: | .build/lint-docs/gitlink\n-\t$(QUIET)mkdir $@\n LINT_DOCS_GITLINK = $(patsubst %.txt,.build/lint-docs/gitlink/%.ok,$(HOWTO_TXT) $(DOC_DEP_TXT))\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/howto\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/config\n $(LINT_DOCS_GITLINK): lint-gitlink.perl\n $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_GITLINK)$(PERL_PATH) lint-gitlink.perl \\\n \t\t$< \\\n \t\t$(HOWTO_TXT) $(DOC_DEP_TXT) \\\n@@ -457,23 +443,18 @@ $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt\n lint-docs-gitlink: $(LINT_DOCS_GITLINK)\n \n ## Lint: man-end-blurb\n-.build/lint-docs/man-end-blurb: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n LINT_DOCS_MAN_END_BLURB = $(patsubst %.txt,.build/lint-docs/man-end-blurb/%.ok,$(MAN_TXT))\n-$(LINT_DOCS_MAN_END_BLURB): | .build/lint-docs/man-end-blurb\n $(LINT_DOCS_MAN_END_BLURB): lint-man-end-blurb.perl\n $(LINT_DOCS_MAN_END_BLURB): .build/lint-docs/man-end-blurb/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_MANEND)$(PERL_PATH) lint-man-end-blurb.perl $< >$@\n .PHONY: lint-docs-man-end-blurb\n-lint-docs-man-end-blurb: $(LINT_DOCS_MAN_END_BLURB)\n \n ## Lint: man-section-order\n-.build/lint-docs/man-section-order: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n LINT_DOCS_MAN_SECTION_ORDER = $(patsubst %.txt,.build/lint-docs/man-section-order/%.ok,$(MAN_TXT))\n-$(LINT_DOCS_MAN_SECTION_ORDER): | .build/lint-docs/man-section-order\n $(LINT_DOCS_MAN_SECTION_ORDER): lint-man-section-order.perl\n $(LINT_DOCS_MAN_SECTION_ORDER): .build/lint-docs/man-section-order/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_MANSEC)$(PERL_PATH) lint-man-section-order.perl $< >$@\n .PHONY: lint-docs-man-section-order\n lint-docs-man-section-order: $(LINT_DOCS_MAN_SECTION_ORDER)\ndiff --git a/Makefile b/Makefile\nindex c437aea9e4a..0a3f292bf82 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2632,7 +2632,8 @@ all:: $(MOFILES)\n endif\n \n po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n-\t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_MSGFMT)$(MSGFMT) -o $@ $<\n \n ifndef NO_PERL\n LIB_PERL = $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n@@ -2641,7 +2642,8 @@ LIB_CPAN = $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n LIB_CPAN_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n-\t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_GEN) \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n \t    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \\\n \t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(call shq,$(NO_PERL_CPAN_FALLBACKS))|g' \\\n@@ -2655,8 +2657,8 @@ endif\n \n # install-man depends on Git.3pm even with NO_PERL=Y\n perl/build/man/man3/Git.3pm: perl/Git.pm\n-\t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n-\tpod2man $< $@\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_GEN)pod2man $< $@\n \n FIND_SOURCE_FILES = ( \\\n \tgit ls-files \\\n@@ -2780,7 +2782,7 @@ test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(\n all:: $(TEST_PROGRAMS) $(test_bindir_programs)\n \n bin-wrappers/%: wrap-for-bin.sh\n-\t@mkdir -p bin-wrappers\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n \t     -e 's|@@BUILD_DIR@@|$(shell pwd)|' \\\n \t     -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \\\ndiff --git a/shared.mak b/shared.mak\nindex a1b62b272f8..363138a5577 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -56,6 +56,8 @@ ifndef V\n \tQUIET          = @\n \tQUIET_GEN      = @echo $(wspfx_sq) GEN $@;\n \n+\tQUIET_MKDIR_P_PARENT  = @echo $(wspfx_sq) MKDIR -p $(@D);\n+\n ## Used in \"Makefile\"\n \tQUIET_CC       = @echo $(wspfx_sq) CC $@;\n \tQUIET_AR       = @echo $(wspfx_sq) AR $@;\n@@ -88,6 +90,11 @@ ifndef V\n endif\n endif\n \n+## Helpers\n+define mkdir_p_parent_template\n+$(if $(wildcard $(@D)),,$(QUIET_MKDIR_P_PARENT)$(shell mkdir -p $(@D)))\n+endef\n+\n ### Templates\n \n ## Template for making a GIT-SOMETHING, which changes if a\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441314","messageId":"patch-v3-21.23-cb3ae5ce00b-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 21/23] Makefile: disable GNU make built-in wildcard rules","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:21Z","receivedAt":"2021-11-16T12:05:54Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Override built-in rules of GNU make that use a wildcard target. This\nspeeds things up significantly as we don't need to stat() so many\nfiles just in case we'd be able to retrieve their contents from RCS or\nSCCS. See [1] for an old mailing list discussion about how to disable\nthese.\n\nThis gives us a noticeable speedup on a no-op run:\n\n    $ git hyperfine -L rev HEAD~1,HEAD~0 -s 'make -j8 all NO_TCLTK=Y' 'make NO_TCLTK=Y' --warmup 10 -M 10\n    Benchmark 1: make NO_TCLTK=Y' in 'HEAD~1\n      Time (mean ± σ):     182.2 ms ±   4.1 ms    [User: 146.8 ms, System: 49.5 ms]\n      Range (min … max):   179.6 ms … 193.4 ms    10 runs\n\n    Benchmark 2: make NO_TCLTK=Y' in 'HEAD~0\n      Time (mean ± σ):     167.9 ms ±   1.3 ms    [User: 127.8 ms, System: 55.6 ms]\n      Range (min … max):   166.1 ms … 170.4 ms    10 runs\n\n    Summary\n      'make NO_TCLTK=Y' in 'HEAD~0' ran\n        1.09 ± 0.03 times faster than 'make NO_TCLTK=Y' in 'HEAD~1'\n\nRunning the same except with 'strace -c -S calls make' as the\nbenchmark command shows (under --show-output) that we went from ~7716\nsyscalls to ~7519, mostly a reduction in [l]stat().\n\n1. https://lists.gnu.org/archive/html/help-make/2002-11/msg00063.html\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n shared.mak | 11 +++++++++++\n 1 file changed, 11 insertions(+)\n\ndiff --git a/shared.mak b/shared.mak\nindex 4ee0bb7a13d..4862df1607a 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -1,3 +1,14 @@\n+### Remove GNU make implicit rules\n+\n+## This speeds things up since we don't need to look for and stat() a\n+## \"foo.c,v\" every time a rule referring to \"foo.c\" is in play. See\n+## \"make -p -f/dev/null | grep ^%::'\".\n+%:: %,v\n+%:: RCS/%,v\n+%:: RCS/%\n+%:: s.%\n+%:: SCCS/s.%\n+\n ### Flags affecting all rules\n \n # A GNU make extension since gmake 3.72 (released in late 1994) to\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441315","messageId":"patch-v3-22.23-88cfc946b37-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 22/23] Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES)","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:22Z","receivedAt":"2021-11-16T12:06:05Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Combine the definitions of $(FIND_SOURCE_FILES) and $(LIB_H) to speed\nup the Makefile, as these are the two main expensive $(shell) commands\nthat we execute unconditionally.\n\nWhen see what was in $(FOUND_SOURCE_FILES) that wasn't in $(LIB_H) via\nthe ad-hoc test of:\n\n    $(error $(filter-out $(LIB_H),$(filter %.h,$(ALL_SOURCE_FILES))))\n    $(error $(filter-out $(ALL_SOURCE_FILES),$(filter %.h,$(LIB_H))))\n\nWe'll get, respectively:\n\n    Makefile:850: *** t/helper/test-tool.h.  Stop.\n    Makefile:850: *** .  Stop.\n\nI.e. we only had a discrepancy when it came to\nt/helper/test-tool.h. In terms of correctness this was broken before,\nbut now works:\n\n    $ make t/helper/test-tool.hco\n        HDR t/helper/test-tool.h\n\nThis speeds things up a lot:\n\n    $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make -j8 all NO_TCLTK=Y' 'make NO_TCLTK=Y' --war\n    mup 10 -M 10\n    Benchmark 1: make NO_TCLTK=Y' in 'HEAD~1\n      Time (mean ± σ):      99.5 ms ±   0.5 ms    [User: 83.4 ms, System: 20.7 ms]\n      Range (min … max):    98.8 ms … 100.2 ms    10 runs\n\n    Benchmark 2: make NO_TCLTK=Y' in 'HEAD~0\n      Time (mean ± σ):      69.4 ms ±   0.5 ms    [User: 58.8 ms, System: 14.2 ms]\n      Range (min … max):    68.9 ms …  70.3 ms    10 runs\n\n    Summary\n      'make NO_TCLTK=Y' in 'HEAD~0' ran\n        1.43 ± 0.01 times faster than 'make NO_TCLTK=Y' in 'HEAD~1'\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 54 ++++++++++++++++++++++++++----------------------------\n 1 file changed, 26 insertions(+), 28 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex bae20eb1b40..1041efb6e5e 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -821,12 +821,33 @@ GENERATED_H += hook-list.h\n .PHONY: generated-hdrs\n generated-hdrs: $(GENERATED_H)\n \n-LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \\\n+## Exhaustive lists of our source files, either dynamically generated,\n+## or hardcoded.\n+SOURCES_CMD = ( \\\n+\tgit ls-files \\\n+\t\t'*.[hcS]' \\\n+\t\t'*.sh' \\\n+\t\t':!*[tp][0-9][0-9][0-9][0-9]*' \\\n+\t\t':!contrib' \\\n+\t\t2>/dev/null || \\\n \t$(FIND) . \\\n-\t-name .git -prune -o \\\n-\t-name t -prune -o \\\n-\t-name Documentation -prune -o \\\n-\t-name '*.h' -print)))\n+\t\t\\( -name .git -type d -prune \\) \\\n+\t\t-o \\( -name '[tp][0-9][0-9][0-9][0-9]*' -prune \\) \\\n+\t\t-o \\( -name contrib -type d -prune \\) \\\n+\t\t-o \\( -name build -type d -prune \\) \\\n+\t\t-o \\( -name 'trash*' -type d -prune \\) \\\n+\t\t-o \\( -name '*.[hcS]' -type f -print \\) \\\n+\t\t-o \\( -name '*.sh' -type f -print \\) \\\n+\t\t| sed -e 's|^\\./||' \\\n+\t)\n+FOUND_SOURCE_FILES := $(shell $(SOURCES_CMD))\n+\n+FOUND_C_SOURCES = $(filter %.c,$(FOUND_SOURCE_FILES))\n+FOUND_H_SOURCES = $(filter %.h,$(FOUND_SOURCE_FILES))\n+\n+COCCI_SOURCES = $(filter-out $(THIRD_PARTY_SOURCES),$(FOUND_C_SOURCES))\n+\n+LIB_H = $(FOUND_H_SOURCES)\n \n LIB_OBJS += abspath.o\n LIB_OBJS += add-interactive.o\n@@ -2661,26 +2682,6 @@ perl/build/man/man3/Git.3pm: perl/Git.pm\n \t$(call mkdir_p_parent_template)\n \t$(QUIET_GEN)pod2man $< $@\n \n-FIND_SOURCE_FILES = ( \\\n-\tgit ls-files \\\n-\t\t'*.[hcS]' \\\n-\t\t'*.sh' \\\n-\t\t':!*[tp][0-9][0-9][0-9][0-9]*' \\\n-\t\t':!contrib' \\\n-\t\t2>/dev/null || \\\n-\t$(FIND) . \\\n-\t\t\\( -name .git -type d -prune \\) \\\n-\t\t-o \\( -name '[tp][0-9][0-9][0-9][0-9]*' -prune \\) \\\n-\t\t-o \\( -name contrib -type d -prune \\) \\\n-\t\t-o \\( -name build -type d -prune \\) \\\n-\t\t-o \\( -name 'trash*' -type d -prune \\) \\\n-\t\t-o \\( -name '*.[hcS]' -type f -print \\) \\\n-\t\t-o \\( -name '*.sh' -type f -print \\) \\\n-\t\t| sed -e 's|^\\./||' \\\n-\t)\n-\n-FOUND_SOURCE_FILES = $(shell $(FIND_SOURCE_FILES))\n-\n $(ETAGS_TARGET): $(FOUND_SOURCE_FILES)\n \t$(QUIET_GEN)$(RM) $@+ && \\\n \techo $(FOUND_SOURCE_FILES) | xargs etags -a -o $@+ && \\\n@@ -2860,9 +2861,6 @@ check: $(GENERATED_H)\n \t\texit 1; \\\n \tfi\n \n-FOUND_C_SOURCES = $(filter %.c,$(FOUND_SOURCE_FILES))\n-COCCI_SOURCES = $(filter-out $(THIRD_PARTY_SOURCES),$(FOUND_C_SOURCES))\n-\n %.cocci.patch: %.cocci $(COCCI_SOURCES)\n \t$(QUIET_SPATCH) \\\n \tif test $(SPATCH_BATCH_SIZE) = 0; then \\\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441316","messageId":"patch-v3-23.23-276e226f0a8-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 23/23] Makefile: move \".SUFFIXES\" rule to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:23Z","receivedAt":"2021-11-16T12:06:13Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This was added in 30248886ce8 (Makefile: disable default implicit\nrules, 2010-01-26), let's move it to the top of \"shared.mak\" so it'll\napply to all our Makefiles.\n\nThis doesn't benefit the main Makefile at all, since it already had\nthe rule, but since we're including shared.mak in other Makefiles\nstarts to benefit them. E.g. running the 'man\" target is now ~1.3x\nfaster:\n\n    $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make -j8 -C Documentation man' 'make -C Documentation man' --warmup 10 -M 10\n    Benchmark 1: make -C Documentation man' in 'HEAD~1\n      Time (mean ± σ):      87.2 ms ±   1.0 ms    [User: 79.3 ms, System: 10.8 ms]\n      Range (min … max):    86.3 ms …  89.7 ms    10 runs\n\n    Benchmark 2: make -C Documentation man' in 'HEAD~0\n      Time (mean ± σ):      64.5 ms ±   0.6 ms    [User: 54.5 ms, System: 13.0 ms]\n      Range (min … max):    63.8 ms …  65.7 ms    10 runs\n\n    Summary\n      'make -C Documentation man' in 'HEAD~0' ran\n        1.35 ± 0.02 times faster than 'make -C Documentation man' in 'HEAD~1'\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile   | 2 --\n shared.mak | 5 +++++\n 2 files changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 1041efb6e5e..d2cc6865a4e 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2460,8 +2460,6 @@ ASM_SRC := $(wildcard $(OBJECTS:o=S))\n ASM_OBJ := $(ASM_SRC:S=o)\n C_OBJ := $(filter-out $(ASM_OBJ),$(OBJECTS))\n \n-.SUFFIXES:\n-\n $(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)\n \t$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<\n $(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)\ndiff --git a/shared.mak b/shared.mak\nindex 4862df1607a..a20193b0c8f 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -9,6 +9,11 @@\n %:: s.%\n %:: SCCS/s.%\n \n+## Likewise delete default $(SUFFIXES). See:\n+##\n+##     info make --index-search=.DELETE_ON_ERROR\n+.SUFFIXES:\n+\n ### Flags affecting all rules\n \n # A GNU make extension since gmake 3.72 (released in late 1994) to\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441317","messageId":"patch-v3-20.23-567ad5c3ebc-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 20/23] Makefile: use $(file) I/O instead of \"FORCE\" when possible","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:20Z","receivedAt":"2021-11-16T12:06:24Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Provide an alternate implementation of the recently added\n\"TRACK_template\" which uses GNU make 4.2 features. If the 'file'\nfunction is available we don't need to shell out at all to check if\nour tracked files change.\n\nWe need to use the intermediate TRACK_template calling a\nTRACK_template_eval within the generated rule so that we don't eagerly\nfleshen these when \"make\" reads the file.\n\nThis doesn't make the runtime faster on my system, but helps to cut\ndown on the noise of things we shell out for\nunconditionally. I.e. running \"make\" with \"SHELL_PATH='sh -x'\" (twice,\nso we pick up the setting) shows than a no-op run went from emitting:\n\n    $ SHELL_PATH='sh -x' make -j8 >/dev/null 2>&1; SHELL_PATH='sh -x' make 2>&1 |wc -l\n    124\n\nTo:\n\n    $ SHELL_PATH='sh -x' make -j8 >/dev/null 2>&1; SHELL_PATH='sh -x' make 2>&1 |wc -l\n    95\n\nThat 124 to 95 number is a rough approximation of how many times we\nshell out. \"strace -f -c\" similarly shows that we went from 8798 to\n8466 syscalls. So this brings us further along in the goal of making\n\"make\" do as little as possible when it's got nothing to re-build (see\n[2]).\n\n1. https://lore.kernel.org/git/874kdn1j6i.fsf@evledraar.gmail.com/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n shared.mak | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 58 insertions(+)\n\ndiff --git a/shared.mak b/shared.mak\nindex 363138a5577..4ee0bb7a13d 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -8,6 +8,22 @@\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n \n+### GNU Make version detection\n+# We don't care about \"release\" versions like the \"90\" in \"3.99.90\"\n+MAKE_VERSION_MAJOR = $(word 1,$(subst ., ,$(MAKE_VERSION)))\n+MAKE_VERSION_MINOR = $(word 2,$(subst ., ,$(MAKE_VERSION)))\n+\n+# The oldest supported version of GNU make is 3-something. So \"not v3\"\n+# is a future-proof way to ask \"is it modern?\"\n+ifneq ($(MAKE_VERSION_MAJOR),3)\n+# $(file >[...]) and $(file >>[...]) is in 4.0...\n+MAKE_HAVE_FILE_WRITE = Need version 4.0 or later (released in late 2013)\n+# .. but we need 4.2 for $(file <[...])\n+ifneq ($(filter-out 0 1,$(MAKE_VERSION_MINOR)),)\n+MAKE_HAVE_FILE_READ = Need version 4.2 or later (released in mid-2016)\n+endif\n+endif\n+\n ### Quoting helpers\n \n ## Quote a ' inside a '': FOO='$(call shq,$(BAR))'\n@@ -99,6 +115,10 @@ endef\n \n ## Template for making a GIT-SOMETHING, which changes if a\n ## TRACK_SOMETHING variable changes.\n+##\n+## This is the slower version used on GNU make <4.2.\n+ifndef MAKE_HAVE_FILE_READ\n+\n define TRACK_template\n .PHONY: FORCE\n $(1): FORCE\n@@ -111,3 +131,41 @@ $(1): FORCE\n \t\techo \"$$$$FLAGS\" >$(1); \\\n \tfi\n endef\n+\n+endif # !MAKE_HAVE_FILE_READ\n+\n+## A TRACK_template template compatible with the one above. Uses\n+## features of GNU make >=4.2 to avoid shelling out for this \"hot\"\n+## \"FORCE\" logic.\n+##\n+## Since version >=4.2 can do both \"I\" and \"O\" in I/O with using\n+## $(file <)/$(file >) we read the GIT-SOMETHING file into a variable\n+## with the former, and if it's different from our expected value\n+## write it out with the latter.\n+ifdef MAKE_HAVE_FILE_READ\n+\n+define TRACK_template_eval\n+$(1)_WRITE =\n+$(1)_EXISTS = $(wildcard $(1))\n+ifeq ($$($(1)_EXISTS),)\n+$(1)_WRITE = new\n+else\n+$(1)_CONTENT = $(file <$(1))\n+ifeq ($$($(1)_CONTENT),$($(2)))\n+$(1)_WRITE = same\n+else\n+$(1)_WRITE = changed\n+endif\n+endif\n+ifneq ($$($(1)_WRITE),same)\n+$$(info $$(wspfx) $(1) parameters ($$($(1)_WRITE)))\n+$$(file >$(1),$($(2)))\n+endif\n+endef # TRACK_template_eval\n+\n+define TRACK_template\n+$(1):\n+\t$$(eval $$(call TRACK_template_eval,$(1),$(2)))\n+endef\n+\n+endif # MAKE_HAVE_FILE_READ\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441318","messageId":"patch-v3-19.23-234b4eb613c-20211116T114334Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v3 19/23] Makefile: correct the dependency graph of hook-list.h","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-16T12:00:19Z","receivedAt":"2021-11-16T12:06:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix an issue in my cfe853e66be (hook-list.h: add a generated list of\nhooks, like config-list.h, 2021-09-26), the builtin/help.c was\ninadvertently made to depend on hook-list.h, but it's used by\nbuiltin/bugreport.c.\n\nReported-by: Mike Hommey <mh@glandium.org>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex 0a3f292bf82..bae20eb1b40 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2162,8 +2162,9 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)\n \n help.sp help.s help.o: command-list.h\n hook.sp hook.s hook.o: hook-list.h\n+builtin/bugreport.sp builtin/bugreport.s builtin/bugreport.o: hook-list.h\n \n-builtin/help.sp builtin/help.s builtin/help.o: config-list.h hook-list.h GIT-PREFIX\n+builtin/help.sp builtin/help.s builtin/help.o: config-list.h GIT-PREFIX\n builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \\\n \t'-DGIT_HTML_PATH=\"$(htmldir_relative_SQ)\"' \\\n \t'-DGIT_MAN_PATH=\"$(mandir_relative_SQ)\"' \\\n-- \n2.34.0.795.g1e9501ab396\n\n"},{"id":"441388","messageId":"20211117015724.ts6ek3wap2ljyhy2@glandium.org","threadId":"56852","inReplyTo":"patch-v3-03.23-510499d18ba-20211116T114334Z-avarab@gmail.com","subject":"Re: [PATCH v3 03/23] Makefile: use \"=\" not \":=\" for po/* and perl/*","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2021-11-17T01:57:24Z","receivedAt":"2021-11-17T01:57:36Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Tue, Nov 16, 2021 at 01:00:03PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> Change these variable definitions from being simply-expanded to be\n> recursively expanded instead. I.e. they'll be lazily expanded when\n> used.\n> \n> I added these in 5e9637c6297 (i18n: add infrastructure for translating\n> Git with gettext, 2011-11-18) and 20d2a30f8ff (Makefile: replace\n> perl/Makefile.PL with simple make rules, 2017-12-10), the reason for\n> using \":=\" over \"=\" was that I didn't know the difference in 2011 (I\n> think I copied some POC code), and in 2017 I used the 2011 commit for\n> reference.\n\nFWIW, with those variables being used as dependencies, I don't think this\nmakes a difference in practice.\n\nMike\n"},{"id":"441389","messageId":"20211117020158.4p3iwlrdf2v4nc55@glandium.org","threadId":"56852","inReplyTo":"patch-v3-05.23-e38c90ad0b6-20211116T114334Z-avarab@gmail.com","subject":"Re: [PATCH v3 05/23] Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2021-11-17T02:01:58Z","receivedAt":"2021-11-17T02:02:08Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Tue, Nov 16, 2021 at 01:00:05PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> Since 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\" flag,\n> 2021-06-29) we don't need to guard the clobbering of $@ with this sort\n> of \"mv $@+ $@\" pattern in these cases where we're merely generating a\n> file that'll be used as a dependency for other files, as in this case\n> for GIT-PERL-HEADER.\n\n.DELETE_ON_ERROR is, as far as I know, a GNUism. Does building git require\nthe use of GNU make?\n\nMike\n"},{"id":"441390","messageId":"20211117021937.r63hm3irwqsw4p3y@glandium.org","threadId":"56852","inReplyTo":"patch-v3-15.23-fac30fe8b56-20211116T114334Z-avarab@gmail.com","subject":"Re: [PATCH v3 15/23] Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2021-11-17T02:19:37Z","receivedAt":"2021-11-17T02:19:45Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Tue, Nov 16, 2021 at 01:00:15PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> +\t\techo $(wspfx_sq) \"$(1) PARAMETERS (new)\" $@; \\\n> +\t\techo \"$$$$FLAGS\" >$(1); \\\n> +\telif test x\"$$$$FLAGS\" != x\"`cat $(1) 2>/dev/null`\" ; then \\\n> +\t\techo $(wspfx_sq) \"$(1) PARAMETERS (changed)\" $@; \\\n\nThese $@ will expand to nothing, I think.\n\nMike\n"},{"id":"441391","messageId":"20211117025148.awdha4udu5kmzwbe@glandium.org","threadId":"56852","inReplyTo":"patch-v3-18.23-d61e2b44f68-20211116T114334Z-avarab@gmail.com","subject":"Re: [PATCH v3 18/23] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2021-11-17T02:51:48Z","receivedAt":"2021-11-17T02:52:01Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Tue, Nov 16, 2021 at 01:00:18PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\n> for us, and use it for the \"make lint-docs\" targets I added in\n> 8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n> \n> As seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\n> dependency, 2021-10-26) maintaining these manual lists of parent\n> directory dependencies is fragile, in addition to being obviously\n> verbose.\n> \n> I used this pattern at the time because I couldn't find another method\n> than \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\n> every file being created, which as noted in [1] would be significantly\n> slower.\n> \n> But as it turns out we can use this neat trick of only doing a \"mkdir\n> -p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\n> of a performance test similar to thatnoted downthread of [1] in [2]\n> shows that this is faster, in addition to being less verbose and more\n> reliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n> \n>     $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n>     Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n>       Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n>       Range (min … max):    2.121 s …  2.158 s    10 runs\n> \n>     Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n>       Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n>       Range (min … max):    2.657 s …  2.662 s    10 runs\n> \n>     Summary\n>       'make -C Documentation lint-docs' in 'HEAD~0' ran\n>         1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n> \n> So let's use that pattern both for the \"lint-docs\" target, and a few\n> miscellaneous other targets.\n> \n> This method of creating parent directories is explicitly racy in that\n> we don't know if we're going to say always create a \"foo\" followed by\n> a \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n> \"foo/bar\" first. In this case it doesn't matter for anything except\n> that we aren't guaranteed to get the same number of rules firing when\n> running make in parallel.\n\nSomething else that is racy is that $(wildcard) might be saying the\ndirectory doesn't exist while there's another make subprocess that has\nalready started spawning `mkdir -p` for that directory.\nThat doesn't make a huge difference, but you can probably still end up\nwith multiple `mkdir -p` runs for the same directory.\n\nI think something like the following could work while avoiding those\nraces:\n\ndefine create_parent_dir_RULE\n$(1): | $(dir $(1)).\nALL_DIRS += $(dir $(1))\nendef\n\ndefine create_parent_dir_TARGET\n$(1)/.: $(dir $(1)).\n\techo mkdir $$(@D)\nendef\n\n$(eval $(call create_parent_dir_RULE, first/path/file))\n$(eval $(call create_parent_dir_RULE, second/path/file))\n# ...\n\n$(foreach dir,$(sort $(ALL_DIRS)),$(eval $(call create_parent_dir_TARGET,$(dir:%/=%))))\n\nMike\n"},{"id":"441392","messageId":"20211117025220.hpqn3vfhzvihoycd@glandium.org","threadId":"56852","inReplyTo":"patch-v3-19.23-234b4eb613c-20211116T114334Z-avarab@gmail.com","subject":"Re: [PATCH v3 19/23] Makefile: correct the dependency graph of hook-list.h","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2021-11-17T02:52:20Z","receivedAt":"2021-11-17T02:52:28Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Tue, Nov 16, 2021 at 01:00:19PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> Fix an issue in my cfe853e66be (hook-list.h: add a generated list of\n> hooks, like config-list.h, 2021-09-26), the builtin/help.c was\n> inadvertently made to depend on hook-list.h, but it's used by\n> builtin/bugreport.c.\n> \n> Reported-by: Mike Hommey <mh@glandium.org>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  Makefile | 3 ++-\n>  1 file changed, 2 insertions(+), 1 deletion(-)\n> \n> diff --git a/Makefile b/Makefile\n> index 0a3f292bf82..bae20eb1b40 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -2162,8 +2162,9 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)\n>  \n>  help.sp help.s help.o: command-list.h\n>  hook.sp hook.s hook.o: hook-list.h\n\nYou can remove this line too.\n\nMike\n"},{"id":"441395","messageId":"20211117030030.nru2ntuxk63lhwqx@glandium.org","threadId":"56852","inReplyTo":"patch-v3-21.23-cb3ae5ce00b-20211116T114334Z-avarab@gmail.com","subject":"Re: [PATCH v3 21/23] Makefile: disable GNU make built-in wildcard rules","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2021-11-17T03:00:30Z","receivedAt":"2021-11-17T03:00:38Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Tue, Nov 16, 2021 at 01:00:21PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> +### Remove GNU make implicit rules\n> +\n> +## This speeds things up since we don't need to look for and stat() a\n> +## \"foo.c,v\" every time a rule referring to \"foo.c\" is in play. See\n> +## \"make -p -f/dev/null | grep ^%::'\".\n> +%:: %,v\n> +%:: RCS/%,v\n> +%:: RCS/%\n> +%:: s.%\n> +%:: SCCS/s.%\n\n`MAKEFLAGS += -r` should have the same effect (and more)\n"},{"id":"441424","messageId":"211117.865ysr87cp.gmgdl@evledraar.gmail.com","threadId":"56852","inReplyTo":"20211117020158.4p3iwlrdf2v4nc55@glandium.org","subject":"Re: [PATCH v3 05/23] Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T09:20:10Z","receivedAt":"2021-11-17T09:22:21Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Nov 17 2021, Mike Hommey wrote:\n\n> On Tue, Nov 16, 2021 at 01:00:05PM +0100, Ævar Arnfjörð Bjarmason wrote:\n>> Since 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\" flag,\n>> 2021-06-29) we don't need to guard the clobbering of $@ with this sort\n>> of \"mv $@+ $@\" pattern in these cases where we're merely generating a\n>> file that'll be used as a dependency for other files, as in this case\n>> for GIT-PERL-HEADER.\n>\n> .DELETE_ON_ERROR is, as far as I know, a GNUism. Does building git require\n> the use of GNU make?\n\nYes, we've had a hard dependency on GNU make for forever, and already\nuse .DELETE_ON_ERROR, this is just moving it around.\n"},{"id":"441425","messageId":"211117.861r3f878n.gmgdl@evledraar.gmail.com","threadId":"56852","inReplyTo":"20211117021937.r63hm3irwqsw4p3y@glandium.org","subject":"Re: [PATCH v3 15/23] Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T09:24:24Z","receivedAt":"2021-11-17T09:24:45Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Nov 17 2021, Mike Hommey wrote:\n\n> On Tue, Nov 16, 2021 at 01:00:15PM +0100, Ævar Arnfjörð Bjarmason wrote:\n>> +\t\techo $(wspfx_sq) \"$(1) PARAMETERS (new)\" $@; \\\n>> +\t\techo \"$$$$FLAGS\" >$(1); \\\n>> +\telif test x\"$$$$FLAGS\" != x\"`cat $(1) 2>/dev/null`\" ; then \\\n>> +\t\techo $(wspfx_sq) \"$(1) PARAMETERS (changed)\" $@; \\\n>\n> These $@ will expand to nothing, I think.\n\nThat's correct, oops, I had that left over from some previous\nversion. Will fix.\n"},{"id":"441427","messageId":"211117.86wnl76sal.gmgdl@evledraar.gmail.com","threadId":"56852","inReplyTo":"20211117025148.awdha4udu5kmzwbe@glandium.org","subject":"Re: [PATCH v3 18/23] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T09:26:27Z","receivedAt":"2021-11-17T09:32:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Nov 17 2021, Mike Hommey wrote:\n\n> On Tue, Nov 16, 2021 at 01:00:18PM +0100, Ævar Arnfjörð Bjarmason wrote:\n>> Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\n>> for us, and use it for the \"make lint-docs\" targets I added in\n>> 8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n>> \n>> As seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\n>> dependency, 2021-10-26) maintaining these manual lists of parent\n>> directory dependencies is fragile, in addition to being obviously\n>> verbose.\n>> \n>> I used this pattern at the time because I couldn't find another method\n>> than \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\n>> every file being created, which as noted in [1] would be significantly\n>> slower.\n>> \n>> But as it turns out we can use this neat trick of only doing a \"mkdir\n>> -p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\n>> of a performance test similar to thatnoted downthread of [1] in [2]\n>> shows that this is faster, in addition to being less verbose and more\n>> reliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n>> \n>>     $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n>>     Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n>>       Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n>>       Range (min … max):    2.121 s …  2.158 s    10 runs\n>> \n>>     Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n>>       Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n>>       Range (min … max):    2.657 s …  2.662 s    10 runs\n>> \n>>     Summary\n>>       'make -C Documentation lint-docs' in 'HEAD~0' ran\n>>         1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n>> \n>> So let's use that pattern both for the \"lint-docs\" target, and a few\n>> miscellaneous other targets.\n>> \n>> This method of creating parent directories is explicitly racy in that\n>> we don't know if we're going to say always create a \"foo\" followed by\n>> a \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n>> \"foo/bar\" first. In this case it doesn't matter for anything except\n>> that we aren't guaranteed to get the same number of rules firing when\n>> running make in parallel.\n>\n> Something else that is racy is that $(wildcard) might be saying the\n> directory doesn't exist while there's another make subprocess that has\n> already started spawning `mkdir -p` for that directory.\n> That doesn't make a huge difference, but you can probably still end up\n> with multiple `mkdir -p` runs for the same directory.\n>\n> I think something like the following could work while avoiding those\n> races:\n>\n> define create_parent_dir_RULE\n> $(1): | $(dir $(1)).\n> ALL_DIRS += $(dir $(1))\n> endef\n>\n> define create_parent_dir_TARGET\n> $(1)/.: $(dir $(1)).\n> \techo mkdir $$(@D)\n> endef\n>\n> $(eval $(call create_parent_dir_RULE, first/path/file))\n> $(eval $(call create_parent_dir_RULE, second/path/file))\n> # ...\n>\n> $(foreach dir,$(sort $(ALL_DIRS)),$(eval $(call create_parent_dir_TARGET,$(dir:%/=%))))\n\nI think the \"race\" just isn't a problem, and makes managing this much\nsimpler.\n\nI.e. we already rely on \"mkdir -p\" not failing on an existing directory,\nso the case where we redundantly try to create a directory that just got\ncreated by a concurrent process is OK, and as the quoted benchmark shows\nis much faster than a similar (but not quite the same as) a\ndependency-based implementaiton.\n\nI haven't implemented your solution, but it seems to be inherently more\ncomplex.\n\nI.e. with the one I've got you just stick the \"mkdir if needed\"\none-liner in each rule, with yours you'll need to accumulate things in\nALL_DIRS, and have some foreach somewhere or dependency relationship to\ncreate those beforehand if they're nested, no?\n"},{"id":"441441","messageId":"20211117093947.ifkrvddmiiu3hg2v@glandium.org","threadId":"56852","inReplyTo":"211117.86wnl76sal.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v3 18/23] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2021-11-17T09:39:47Z","receivedAt":"2021-11-17T09:41:13Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Wed, Nov 17, 2021 at 10:26:27AM +0100, Ævar Arnfjörð Bjarmason wrote:\n> \n> On Wed, Nov 17 2021, Mike Hommey wrote:\n> \n> > On Tue, Nov 16, 2021 at 01:00:18PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> >> Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\n> >> for us, and use it for the \"make lint-docs\" targets I added in\n> >> 8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n> >> \n> >> As seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\n> >> dependency, 2021-10-26) maintaining these manual lists of parent\n> >> directory dependencies is fragile, in addition to being obviously\n> >> verbose.\n> >> \n> >> I used this pattern at the time because I couldn't find another method\n> >> than \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\n> >> every file being created, which as noted in [1] would be significantly\n> >> slower.\n> >> \n> >> But as it turns out we can use this neat trick of only doing a \"mkdir\n> >> -p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\n> >> of a performance test similar to thatnoted downthread of [1] in [2]\n> >> shows that this is faster, in addition to being less verbose and more\n> >> reliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n> >> \n> >>     $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n> >>     Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n> >>       Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n> >>       Range (min … max):    2.121 s …  2.158 s    10 runs\n> >> \n> >>     Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n> >>       Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n> >>       Range (min … max):    2.657 s …  2.662 s    10 runs\n> >> \n> >>     Summary\n> >>       'make -C Documentation lint-docs' in 'HEAD~0' ran\n> >>         1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n> >> \n> >> So let's use that pattern both for the \"lint-docs\" target, and a few\n> >> miscellaneous other targets.\n> >> \n> >> This method of creating parent directories is explicitly racy in that\n> >> we don't know if we're going to say always create a \"foo\" followed by\n> >> a \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n> >> \"foo/bar\" first. In this case it doesn't matter for anything except\n> >> that we aren't guaranteed to get the same number of rules firing when\n> >> running make in parallel.\n> >\n> > Something else that is racy is that $(wildcard) might be saying the\n> > directory doesn't exist while there's another make subprocess that has\n> > already started spawning `mkdir -p` for that directory.\n> > That doesn't make a huge difference, but you can probably still end up\n> > with multiple `mkdir -p` runs for the same directory.\n> >\n> > I think something like the following could work while avoiding those\n> > races:\n> >\n> > define create_parent_dir_RULE\n> > $(1): | $(dir $(1)).\n> > ALL_DIRS += $(dir $(1))\n> > endef\n> >\n> > define create_parent_dir_TARGET\n> > $(1)/.: $(dir $(1)).\n> > \techo mkdir $$(@D)\n\nerf, s/echo //\n\n> > endef\n> >\n> > $(eval $(call create_parent_dir_RULE, first/path/file))\n> > $(eval $(call create_parent_dir_RULE, second/path/file))\n> > # ...\n> >\n> > $(foreach dir,$(sort $(ALL_DIRS)),$(eval $(call create_parent_dir_TARGET,$(dir:%/=%))))\n> \n> I think the \"race\" just isn't a problem, and makes managing this much\n> simpler.\n> \n> I.e. we already rely on \"mkdir -p\" not failing on an existing directory,\n> so the case where we redundantly try to create a directory that just got\n> created by a concurrent process is OK, and as the quoted benchmark shows\n> is much faster than a similar (but not quite the same as) a\n> dependency-based implementaiton.\n> \n> I haven't implemented your solution, but it seems to be inherently more\n> complex.\n> \n> I.e. with the one I've got you just stick the \"mkdir if needed\"\n> one-liner in each rule, with yours you'll need to accumulate things in\n> ALL_DIRS, and have some foreach somewhere or dependency relationship to\n> create those beforehand if they're nested, no?\n\nFor each rule, it would also be a oneliner to add above the rule. The rest\nwould be a prelude and a an epilogue to stick somewhere in the Makefile.\n"},{"id":"441442","messageId":"211117.86sfvv6qyw.gmgdl@evledraar.gmail.com","threadId":"56852","inReplyTo":"20211117030030.nru2ntuxk63lhwqx@glandium.org","subject":"Re: [PATCH v3 21/23] Makefile: disable GNU make built-in wildcard rules","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T09:47:43Z","receivedAt":"2021-11-17T10:01:40Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Nov 17 2021, Mike Hommey wrote:\n\n> On Tue, Nov 16, 2021 at 01:00:21PM +0100, Ævar Arnfjörð Bjarmason wrote:\n>> +### Remove GNU make implicit rules\n>> +\n>> +## This speeds things up since we don't need to look for and stat() a\n>> +## \"foo.c,v\" every time a rule referring to \"foo.c\" is in play. See\n>> +## \"make -p -f/dev/null | grep ^%::'\".\n>> +%:: %,v\n>> +%:: RCS/%,v\n>> +%:: RCS/%\n>> +%:: s.%\n>> +%:: SCCS/s.%\n>\n> `MAKEFLAGS += -r` should have the same effect (and more)\n\nYeah, I did try that. It's a much bigger hammer though, and throws out\nall implicit rules, some of which we may use (I'm not sure). I've\nupdated the commit message to note this.\n\nIn terms of performance it doesn't seem to matter over the above more\nnarrow change.\n"},{"id":"441443","messageId":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com","subject":"[PATCH v4 00/23] Makefile: dependency fixes, make noop runtime ~1.4x faster","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:19:59Z","receivedAt":"2021-11-17T10:20:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"As noted in v2[1] this series fixes various dependency issues in the\nMakfile. See [2] for before/after benchmark numbers.\n\nThis v4 addresses small issues Mike Hommey noted, and clarifies\nvarious questions that came up with updated commit messages.\n\nThere's also a fix-for-the-fix here in removing the \"hook.c\"\ndependency on hook-list.h in 19/23.\n\n1. https://lore.kernel.org/git/cover-v2-00.18-00000000000-20211112T214150Z-avarab@gmail.com/\n2. https://lore.kernel.org/git/cover-v3-00.23-00000000000-20211116T114334Z-avarab@gmail.com/\n\nÆvar Arnfjörð Bjarmason (23):\n  Makefile: don't invoke msgfmt with --statistics\n  Makefile: don't set up \"perl/build\" rules under NO_PERL=Y\n  Makefile: use \"=\" not \":=\" for po/* and perl/*\n  Makefile: clean perl/build/ even with NO_PERL=Y\n  Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR\n  Makefile: guard Perl-only variable assignments\n  Makefile: change \"ifndef NO_PERL\" to \"ifdef NO_PERL\"\n  Makefile: adjust Perl-related comments & whitespace\n  Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph\n  Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"\n  Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts\n  Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it\n  Makefile: move $(comma), $(empty) and $(space) to shared.mak\n  Makefile: re-add and use the \"shellquote\" macros\n  Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}\n  Makefile: add \"$(QUIET)\" boilerplate to shared.mak\n  Makefile: use $(wspfx) for $(QUIET...) in shared.mak\n  Makefiles: add and use wildcard \"mkdir -p\" template\n  Makefile: correct the dependency graph of hook-list.h\n  Makefile: use $(file) I/O instead of \"FORCE\" when possible\n  Makefile: disable GNU make built-in wildcard rules\n  Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES)\n  Makefile: move \".SUFFIXES\" rule to shared.mak\n\n .gitignore             |   2 +-\n Documentation/Makefile |  71 +---------\n Makefile               | 314 +++++++++++++++--------------------------\n config.mak.uname       |   1 -\n git-cvsserver.perl     |   6 +-\n git-send-email.perl    |   7 +-\n git-svn.perl           |   2 +-\n shared.mak             | 187 ++++++++++++++++++++++++\n t/Makefile             |  34 ++---\n templates/Makefile     |  19 +--\n 10 files changed, 337 insertions(+), 306 deletions(-)\n create mode 100644 shared.mak\n\nRange-diff against v3:\n 1:  1621ca72c1d =  1:  1621ca72c1d Makefile: don't invoke msgfmt with --statistics\n 2:  b7c36c9fea0 =  2:  b7c36c9fea0 Makefile: don't set up \"perl/build\" rules under NO_PERL=Y\n 3:  510499d18ba !  3:  29b000eb0f1 Makefile: use \"=\" not \":=\" for po/* and perl/*\n    @@ Commit message\n         think I copied some POC code), and in 2017 I used the 2011 commit for\n         reference.\n     \n    +    This doesn't make much if any of a practical difference, doing this is\n    +    cheap either way, but as simply-expanded variables in our Makefile\n    +    generally indicate special behavior (e.g. making a copy now, and\n    +    modifying the RHS later) let's change these to show that nothing odd\n    +    is going on here).\n    +\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Makefile ##\n 4:  37f3591bcca =  4:  daead5ec293 Makefile: clean perl/build/ even with NO_PERL=Y\n 5:  e38c90ad0b6 !  5:  3c987590740 Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR\n    @@ Commit message\n         file that'll be used as a dependency for other files, as in this case\n         for GIT-PERL-HEADER.\n     \n    +    We have had a hard dependency on .DELETE_ON_ERROR since\n    +    7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\" flag,\n    +    2021-06-29), so this is a pure cleanup as a follow-up to that\n    +    commit. Support for the \".DELETE_ON_ERROR\" target itself is much older\n    +    than any GNU make version we support, it was added to GNU make in\n    +    1994.\n    +\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Makefile ##\n 6:  98e14c7eba9 =  6:  b57f582ccd3 Makefile: guard Perl-only variable assignments\n 7:  047a42b01cf =  7:  fcdee92f64c Makefile: change \"ifndef NO_PERL\" to \"ifdef NO_PERL\"\n 8:  0c0a3de390e =  8:  1e25b532ca2 Makefile: adjust Perl-related comments & whitespace\n 9:  1ece3160915 =  9:  77d9855bfcf Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph\n10:  e9b61cd0ba5 = 10:  6004cdcd8d9 Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"\n11:  b020f8e3257 = 11:  17b30e96057 Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts\n12:  19539ce7d2d = 12:  30ddf7da2c8 Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it\n13:  6c9291c2c9f = 13:  f378a7dc35e Makefile: move $(comma), $(empty) and $(space) to shared.mak\n14:  e811a907b08 = 14:  13cbb851d32 Makefile: re-add and use the \"shellquote\" macros\n15:  fac30fe8b56 ! 15:  337953e4994 Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}\n    @@ shared.mak: shelldquote = '\"$(call shdq,$(call shq,$(1)))\"'\n     +$(1): FORCE\n     +\t@FLAGS='$$($(2))'; \\\n     +\tif ! test -f $(1) ; then \\\n    -+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (new)\" $@; \\\n    ++\t\techo $(wspfx_sq) \"$(1) PARAMETERS (new)\"; \\\n     +\t\techo \"$$$$FLAGS\" >$(1); \\\n     +\telif test x\"$$$$FLAGS\" != x\"`cat $(1) 2>/dev/null`\" ; then \\\n    -+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (changed)\" $@; \\\n    ++\t\techo $(wspfx_sq) \"$(1) PARAMETERS (changed)\"; \\\n     +\t\techo \"$$$$FLAGS\" >$(1); \\\n     +\tfi\n     +endef\n16:  a3e3acea82d = 16:  5bb597c1993 Makefile: add \"$(QUIET)\" boilerplate to shared.mak\n17:  22264f431c8 = 17:  3c4d0589667 Makefile: use $(wspfx) for $(QUIET...) in shared.mak\n18:  d61e2b44f68 = 18:  be5882b2c99 Makefiles: add and use wildcard \"mkdir -p\" template\n19:  234b4eb613c ! 19:  2710f8af6cd Makefile: correct the dependency graph of hook-list.h\n    @@ Commit message\n         inadvertently made to depend on hook-list.h, but it's used by\n         builtin/bugreport.c.\n     \n    +    The hook.c also does not depend on hook-list.h. It did in an earlier\n    +    version of the greater series cfe853e66be was extracted from, but not\n    +    anymore. We might end up needing that line again, but let's remove it\n    +    for now.\n    +\n         Reported-by: Mike Hommey <mh@glandium.org>\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Makefile ##\n     @@ Makefile: git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)\n    + \t\t$(filter %.o,$^) $(LIBS)\n      \n      help.sp help.s help.o: command-list.h\n    - hook.sp hook.s hook.o: hook-list.h\n    +-hook.sp hook.s hook.o: hook-list.h\n     +builtin/bugreport.sp builtin/bugreport.s builtin/bugreport.o: hook-list.h\n      \n     -builtin/help.sp builtin/help.s builtin/help.o: config-list.h hook-list.h GIT-PREFIX\n20:  567ad5c3ebc = 20:  59f22a0269a Makefile: use $(file) I/O instead of \"FORCE\" when possible\n21:  cb3ae5ce00b ! 21:  dd569a59c74 Makefile: disable GNU make built-in wildcard rules\n    @@ Commit message\n         benchmark command shows (under --show-output) that we went from ~7716\n         syscalls to ~7519, mostly a reduction in [l]stat().\n     \n    +    We could also invoke make with \"-r\" by setting \"MAKEFLAGS = -r\" early,\n    +    adding a \"-r\" variant to the above benchmark shows that it may be 1.01\n    +    or so faster (but in my tests, always with a much bigger error\n    +    bar). But doing so is a much bigger hammer, since it will disable all\n    +    built-in rules, some (all?) of which can be seen with:\n    +\n    +        make -f/dev/null -p | grep -v -e ^# -e ^$\n    +\n    +    We may have something that relies on them, so let's go for the more\n    +    isolated optimization here that gives us most or all of the wins.\n    +\n         1. https://lists.gnu.org/archive/html/help-make/2002-11/msg00063.html\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n22:  88cfc946b37 = 22:  4168a7e3b30 Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES)\n23:  276e226f0a8 = 23:  48a3927d972 Makefile: move \".SUFFIXES\" rule to shared.mak\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441444","messageId":"patch-v4-01.23-1621ca72c1d-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 01/23] Makefile: don't invoke msgfmt with --statistics","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:00Z","receivedAt":"2021-11-17T10:20:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the --statistics flag that I added in 5e9637c6297 (i18n: add\ninfrastructure for translating Git with gettext, 2011-11-18). Our\nMakefile output is good about reducing verbosity by default, except in\nthis case:\n\n    $ rm -rf po/build/locale/e*; time make -j $(nproc) all\n        SUBDIR templates\n        MKDIR -p po/build/locale/el/LC_MESSAGES\n        MSGFMT po/build/locale/el/LC_MESSAGES/git.mo\n        MKDIR -p po/build/locale/es/LC_MESSAGES\n        MSGFMT po/build/locale/es/LC_MESSAGES/git.mo\n    1038 translated messages, 3325 untranslated messages.\n    5230 translated messages.\n\nI didn't have any good reason for using --statistics at the time other\nthan ad-hoc eyeballing of the output. We don't need to spew out\nexactly how many messages we've got translated every time. Now we'll\ninstead emit:\n\n    $ rm -rf po/build/locale/e*; time make -j $(nproc) all\n        SUBDIR templates\n        MKDIR -p po/build/locale/el/LC_MESSAGES\n        MSGFMT po/build/locale/el/LC_MESSAGES/git.mo\n        MKDIR -p po/build/locale/es/LC_MESSAGES\n        MSGFMT po/build/locale/es/LC_MESSAGES/git.mo\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex d56c0e4aadc..11da97de233 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1870,7 +1870,7 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT\n endif\n \n ifndef NO_MSGFMT_EXTENDED_OPTIONS\n-\tMSGFMT += --check --statistics\n+\tMSGFMT += --check\n endif\n \n ifdef HAVE_CLOCK_GETTIME\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441445","messageId":"patch-v4-02.23-b7c36c9fea0-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 02/23] Makefile: don't set up \"perl/build\" rules under NO_PERL=Y","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:01Z","receivedAt":"2021-11-17T10:20:32Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Do not define LIB_{PERL,CPAN}{,_GEN} if NO_PERL is defined. This\nchanges no functionality, but makes it clear which of these rules are\nneeded under NO_PERL=Y. See 20d2a30f8ff (Makefile: replace\nperl/Makefile.PL with simple make rules, 2017-12-10) for the initial\nimplementation.\n\nWe do for better or worse rely on \"install-doc\" calling\n\"install-man-perl\" regardless of whether NO_PERL=Y is defined or not,\ni.e. we'll always end up with that manual page, even if we don't have\nany of the Perl code installed. Let's add a comment about that\nadjacent to the rules that build perl/build.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 17 +++++++++--------\n 1 file changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 11da97de233..06405825a24 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2684,19 +2684,12 @@ endif\n po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n \t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n \n+ifndef NO_PERL\n LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n-ifndef NO_PERL\n-all:: $(LIB_PERL_GEN)\n-ifndef NO_PERL_CPAN_FALLBACKS\n-all:: $(LIB_CPAN_GEN)\n-endif\n-NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n-endif\n-\n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n@@ -2704,6 +2697,14 @@ perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \\\n \t< $< > $@\n \n+all:: $(LIB_PERL_GEN)\n+ifndef NO_PERL_CPAN_FALLBACKS\n+all:: $(LIB_CPAN_GEN)\n+endif\n+NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n+endif\n+\n+# install-man depends on Git.3pm even with NO_PERL=Y\n perl/build/man/man3/Git.3pm: perl/Git.pm\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tpod2man $< $@\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441446","messageId":"patch-v4-03.23-29b000eb0f1-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 03/23] Makefile: use \"=\" not \":=\" for po/* and perl/*","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:02Z","receivedAt":"2021-11-17T10:20:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change these variable definitions from being simply-expanded to be\nrecursively expanded instead. I.e. they'll be lazily expanded when\nused.\n\nI added these in 5e9637c6297 (i18n: add infrastructure for translating\nGit with gettext, 2011-11-18) and 20d2a30f8ff (Makefile: replace\nperl/Makefile.PL with simple make rules, 2017-12-10), the reason for\nusing \":=\" over \"=\" was that I didn't know the difference in 2011 (I\nthink I copied some POC code), and in 2017 I used the 2011 commit for\nreference.\n\nThis doesn't make much if any of a practical difference, doing this is\ncheap either way, but as simply-expanded variables in our Makefile\ngenerally indicate special behavior (e.g. making a copy now, and\nmodifying the RHS later) let's change these to show that nothing odd\nis going on here).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 16 ++++++++--------\n 1 file changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 06405825a24..6b77702e102 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2672,11 +2672,11 @@ po/git.pot: $(GENERATED_H) FORCE\n pot: po/git.pot\n \n ifdef NO_GETTEXT\n-POFILES :=\n-MOFILES :=\n+POFILES =\n+MOFILES =\n else\n-POFILES := $(wildcard po/*.po)\n-MOFILES := $(patsubst po/%.po,po/build/locale/%/LC_MESSAGES/git.mo,$(POFILES))\n+POFILES = $(wildcard po/*.po)\n+MOFILES = $(patsubst po/%.po,po/build/locale/%/LC_MESSAGES/git.mo,$(POFILES))\n \n all:: $(MOFILES)\n endif\n@@ -2685,10 +2685,10 @@ po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n \t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n \n ifndef NO_PERL\n-LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n-LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n-LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n-LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n+LIB_PERL = $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n+LIB_PERL_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))\n+LIB_CPAN = $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n+LIB_CPAN_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441447","messageId":"patch-v4-04.23-daead5ec293-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 04/23] Makefile: clean perl/build/ even with NO_PERL=Y","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:03Z","receivedAt":"2021-11-17T10:20:38Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a regression in 499c29394ce (Makefile: allow building without\nperl, 2009-04-03) where we'd stop cleaning the perl/* directory\nbecause NO_PERL was defined, thus leaving behind litter if the flag at\n\"clean\" time didn't match that of build time.\n\nIn 499c29394ce this was done to avoid relying on the perl/Makefile.PL,\nbut since my 20d2a30f8ff (Makefile: replace perl/Makefile.PL with\nsimple make rules, 2017-12-10) we can clean things in that directory\nunconditionally.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex 6b77702e102..a71fba15e30 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -3234,6 +3234,7 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) $(HCC)\n \t$(RM) -r bin-wrappers $(dep_dirs) $(compdb_dir) compile_commands.json\n \t$(RM) -r po/build/\n+\t$(RM) -r perl/build/\n \t$(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope*\n \t$(RM) -r .dist-tmp-dir .doc-tmp-dir\n \t$(RM) $(GIT_TARNAME).tar.gz\n@@ -3242,7 +3243,6 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) Documentation/GIT-EXCLUDED-PROGRAMS\n ifndef NO_PERL\n \t$(MAKE) -C gitweb clean\n-\t$(RM) -r perl/build/\n endif\n \t$(MAKE) -C templates/ clean\n \t$(MAKE) -C t/ clean\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441448","messageId":"patch-v4-05.23-3c987590740-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 05/23] Makefile: remove \"mv $@ $@+\" dance redundant to .DELETE_ON_ERROR","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:04Z","receivedAt":"2021-11-17T10:20:40Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Since 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\" flag,\n2021-06-29) we don't need to guard the clobbering of $@ with this sort\nof \"mv $@+ $@\" pattern in these cases where we're merely generating a\nfile that'll be used as a dependency for other files, as in this case\nfor GIT-PERL-HEADER.\n\nWe have had a hard dependency on .DELETE_ON_ERROR since\n7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\" flag,\n2021-06-29), so this is a pure cleanup as a follow-up to that\ncommit. Support for the \".DELETE_ON_ERROR\" target itself is much older\nthan any GNU make version we support, it was added to GNU make in\n1994.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex a71fba15e30..284725099c9 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2349,8 +2349,7 @@ GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n \t    -e 's=@@PERLLIBDIR_REL@@=$(perllibdir_relative_SQ)=g' \\\n \t    -e 's=@@GITEXECDIR_REL@@=$(gitexecdir_relative_SQ)=g' \\\n \t    -e 's=@@LOCALEDIR_REL@@=$(localedir_relative_SQ)=g' \\\n-\t    $< >$@+ && \\\n-\tmv $@+ $@\n+\t    $< >$@\n \n .PHONY: perllibdir\n perllibdir:\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441449","messageId":"patch-v4-07.23-fcdee92f64c-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 07/23] Makefile: change \"ifndef NO_PERL\" to \"ifdef NO_PERL\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:06Z","receivedAt":"2021-11-17T10:20:41Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the NO_PERL variable assignments so that they declare the much\nsmaller fallback condition first.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 18 +++++++++---------\n 1 file changed, 9 insertions(+), 9 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 0cb10f00ebb..288f4834db8 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2291,7 +2291,15 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n # This makes sure we depend on the NO_PERL setting itself.\n $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n-ifndef NO_PERL\n+ifdef NO_PERL\n+$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n+\t$(QUIET_GEN) \\\n+\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n+\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n+\t    unimplemented.sh >$@+ && \\\n+\tchmod +x $@+ && \\\n+\tmv $@+ $@\n+else # NO_PERL\n # Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n # since the locale directory is injected.\n perl_localedir_SQ = $(localedir_SQ)\n@@ -2363,14 +2371,6 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \t$(QUIET_GEN)$(cmd_munge_script) && \\\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n-else # NO_PERL\n-$(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n-\t$(QUIET_GEN) \\\n-\tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n-\t    -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \\\n-\t    unimplemented.sh >$@+ && \\\n-\tchmod +x $@+ && \\\n-\tmv $@+ $@\n endif # NO_PERL\n \n # This makes sure we depend on the NO_PYTHON setting itself.\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441450","messageId":"patch-v4-06.23-b57f582ccd3-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 06/23] Makefile: guard Perl-only variable assignments","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:05Z","receivedAt":"2021-11-17T10:20:43Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move the \"ifndef NO_PERL\" a few lines earlier to encompass the\n\"perl_localedir_SQ\" variable. We'll only use it under !NO_PERL.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Makefile b/Makefile\nindex 284725099c9..0cb10f00ebb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2291,11 +2291,11 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n # This makes sure we depend on the NO_PERL setting itself.\n $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n \n+ifndef NO_PERL\n # Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n # since the locale directory is injected.\n perl_localedir_SQ = $(localedir_SQ)\n \n-ifndef NO_PERL\n PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n PERL_DEFINES =\n PERL_DEFINES += $(PERL_PATH_SQ)\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441451","messageId":"patch-v4-08.23-1e25b532ca2-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 08/23] Makefile: adjust Perl-related comments & whitespace","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:07Z","receivedAt":"2021-11-17T10:20:54Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Folllow-up my 4070c9e09fc (Makefile: don't re-define PERL_DEFINES,\n2021-05-05) and move the rest of the assignments to PERL_DEFINES to\none place.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 15 ++++++---------\n 1 file changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 288f4834db8..ab78f8dd42e 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2312,21 +2312,19 @@ PERL_DEFINES += $(perllibdir_SQ)\n PERL_DEFINES += $(RUNTIME_PREFIX)\n PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n PERL_DEFINES += $(NO_GETTEXT)\n+PERL_DEFINES += $(gitexecdir)\n+PERL_DEFINES += $(perllibdir)\n+PERL_DEFINES += $(localedir)\n+PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n \n-# Support Perl runtime prefix. In this mode, a different header is installed\n-# into Perl scripts.\n ifdef RUNTIME_PREFIX\n-\n PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n \n-# Don't export a fixed $(localedir) path; it will be resolved by the Perl header\n-# at runtime.\n+# The RUNTIME_PREFIX header defines $Git::I18N::TEXTDOMAINDIR, so\n+# $(perl_localedir_SQ) won't be needed\n perl_localedir_SQ =\n-\n endif\n \n-PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)\n-\n $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \t$(QUIET_GEN) \\\n \tsed -e '1{' \\\n@@ -2339,7 +2337,6 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n-PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n GIT-PERL-DEFINES: FORCE\n \t@FLAGS='$(PERL_DEFINES)'; \\\n \t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441452","messageId":"patch-v4-09.23-77d9855bfcf-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 09/23] Makefile: correct \"GIT-PERL-{DEFINES,HEADER}\" dependency graph","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:08Z","receivedAt":"2021-11-17T10:21:00Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix several small issues with the dependency graph of the generated\n\"GIT-PERL-DEFINES\" and \"GIT-PERL-HEADER\" files:\n\n1. Don't have \"GIT-PERL-HEADER\" depend on the \"Makefile\". That was a\n   lazy way to over-declare the dependencies added in\n   f6a0ad4be71 (Makefile: generate Perl header from template file,\n   2018-04-10). Let's correct our dependency graph instead.\n\n2. Don't have $(SCRIPT_PERL_GEN) (such as \"git-send-email\") depend on\n   GIT-BUILD-OPTIONS. Let's instead use GIT-PERL-DEFINES.\n\n   The reason for depending on \"GIT-BUILD-OPTIONS\" was to trigger a\n   re-build if NO_PERL=Y was defined. We can instead add that variable\n   to \"PERL_DEFINES\", and have \"GIT-PERL-DEFINES\" created and updated\n   if \"NO_PERL=Y\" is defined.\n\n3. Due to #2 we'll need to have GIT-PERL-DEFINES be generated even\n   under NO_PERL, since that variable will be used by the\n   \"unimplemented.sh\" script.\n\n4. Don't depend on $(gitexecdir), $(perllibdir) and $(localedir),\n   instead depend on the $(*_relative_SQ) versions of those.\n\n   The latter is what we'll actually use, while it's unlikely to\n   matter in practice (we'd just skip re-building these under\n   RUNTIME_PREFIX if the relative path was the same) it makes the code\n   easier to read.\n\n   That's because this brings us to a 1=1 mapping of these variables\n   and what's subsequently used in the \"GIT-PERL-DEFINES\",\n   \"GIT-PERL-HEADER\" and \"perl/build/lib/%.pm\" rules below.\n\n5. We don't need the substitution of \" \" for \":\" added in\n   07d90eadb50 (Makefile: add Perl runtime prefix support,\n   2018-04-10), let's drop it. This doesn't matter for the correctness\n   of these files, because unlike GIT-BUILD-OPTIONS nothing is\n   consuming them except the Makefile itself.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 42 +++++++++++++++++++++++++-----------------\n 1 file changed, 25 insertions(+), 17 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex ab78f8dd42e..361abff2402 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2288,10 +2288,14 @@ git.res: git.rc GIT-VERSION-FILE GIT-PREFIX\n \t    $(shell echo $(GIT_VERSION) 0 0 0 0 | tr '.a-zA-Z-' ' '))) \\\n \t  -DGIT_VERSION=\"\\\\\\\"$(GIT_VERSION)\\\\\\\"\" -i $< -o $@\n \n-# This makes sure we depend on the NO_PERL setting itself.\n-$(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS\n+# Under NO_PERL=Y we'll still make GIT-PERL-DEFINES. We need to depend\n+# on NO_PERL=Y itself for creating \"unimplemented.sh\" scripts.\n+PERL_DEFINES =\n+$(SCRIPT_PERL_GEN): GIT-PERL-DEFINES\n \n ifdef NO_PERL\n+PERL_DEFINES += $(NO_PERL)\n+\n $(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n \t$(QUIET_GEN) \\\n \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2300,22 +2304,26 @@ $(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n else # NO_PERL\n-# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX\n-# since the locale directory is injected.\n+# The localedir is only used in Perl modules if !NO_GETTEXT\n+ifndef NO_GETTEXT\n perl_localedir_SQ = $(localedir_SQ)\n+endif\n \n PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl\n-PERL_DEFINES =\n+\n PERL_DEFINES += $(PERL_PATH_SQ)\n PERL_DEFINES += $(PERLLIB_EXTRA_SQ)\n PERL_DEFINES += $(perllibdir_SQ)\n PERL_DEFINES += $(RUNTIME_PREFIX)\n PERL_DEFINES += $(NO_PERL_CPAN_FALLBACKS)\n PERL_DEFINES += $(NO_GETTEXT)\n-PERL_DEFINES += $(gitexecdir)\n-PERL_DEFINES += $(perllibdir)\n-PERL_DEFINES += $(localedir)\n-PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))\n+ifdef RUNTIME_PREFIX\n+PERL_DEFINES += $(gitexecdir_relative_SQ)\n+PERL_DEFINES += $(perllibdir_relative_SQ)\n+PERL_DEFINES += $(localedir_relative_SQ)\n+else\n+PERL_DEFINES += $(perllocaledir_SQ)\n+endif\n \n ifdef RUNTIME_PREFIX\n PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n@@ -2337,14 +2345,7 @@ $(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n-GIT-PERL-DEFINES: FORCE\n-\t@FLAGS='$(PERL_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new perl-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n-\n-GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile\n+GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES\n \t$(QUIET_GEN) \\\n \tINSTLIBDIR='$(perllibdir_SQ)' && \\\n \tINSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \\\n@@ -2370,6 +2371,13 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \tmv $@+ $@\n endif # NO_PERL\n \n+GIT-PERL-DEFINES: FORCE\n+\t@FLAGS='$(PERL_DEFINES)'; \\\n+\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n+\t\techo >&2 \"    * new perl-specific parameters\"; \\\n+\t\techo \"$$FLAGS\" >$@; \\\n+\t    fi\n+\n # This makes sure we depend on the NO_PYTHON setting itself.\n $(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS\n \n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441453","messageId":"patch-v4-10.23-6004cdcd8d9-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 10/23] Makefile: create a GIT-PYTHON-DEFINES, like \"PERL\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:09Z","receivedAt":"2021-11-17T10:21:01Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Create a new \"GIT-PYTHON-DEFINES\" file, and untangle the dependency\nissues of the Python by copying over the patterns established for\nbuilding the adjacent Perl code in preceding commits.\n\nAs with Perl, there's no real reason to depend on GIT-BUILD-OPTIONS or\nGIT-CFLAGS when building the Python code, nor did we need\nGIT-PREFIX. Let's instead add those variables we care about to a\n\"GIT-PYTHON-DEFINES\" and depend on that.\n\nThis changes code originally added in ca3bcabf118 (auto-detect changed\nprefix and/or changed build flags, 2006-06-15), and adjusted in\n96a4647fca5 (Makefile: detect when PYTHON_PATH changes, 2012-12-18).\n\nThe relevant code for the \"Perl\" targets was then added in\n07981dce81e (Makefile: rebuild perl scripts when perl paths change,\n2013-11-18), and has been adjusted in preceding commits.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n .gitignore |  2 +-\n Makefile   | 49 +++++++++++++++++++++++++------------------------\n 2 files changed, 26 insertions(+), 25 deletions(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 054249b20a8..845e5d0c355 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -8,7 +8,7 @@\n /GIT-PREFIX\n /GIT-PERL-DEFINES\n /GIT-PERL-HEADER\n-/GIT-PYTHON-VARS\n+/GIT-PYTHON-DEFINES\n /GIT-SCRIPT-DEFINES\n /GIT-USER-AGENT\n /GIT-VERSION-FILE\ndiff --git a/Makefile b/Makefile\nindex 361abff2402..c698c5b058a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2378,18 +2378,15 @@ GIT-PERL-DEFINES: FORCE\n \t\techo \"$$FLAGS\" >$@; \\\n \t    fi\n \n-# This makes sure we depend on the NO_PYTHON setting itself.\n-$(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS\n+# As with NO_PERL=Y we'll still make GIT-PYTHON-DEFINES if \"NO_PYTHON\"\n+# is defined, for creating the \"unimplemented.sh\" scripts.\n+PYTHON_DEFINES =\n+$(SCRIPT_PYTHON_GEN): GIT-PYTHON-DEFINES\n+\n+ifdef NO_PYTHON\n+PYTHON_DEFINES += $(SHELL_PATH_SQ)\n+PYTHON_DEFINES += $(NO_PYTHON)\n \n-ifndef NO_PYTHON\n-$(SCRIPT_PYTHON_GEN): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS\n-$(SCRIPT_PYTHON_GEN): % : %.py\n-\t$(QUIET_GEN) \\\n-\tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n-\t    $< >$@+ && \\\n-\tchmod +x $@+ && \\\n-\tmv $@+ $@\n-else # NO_PYTHON\n $(SCRIPT_PYTHON_GEN): % : unimplemented.sh\n \t$(QUIET_GEN) \\\n \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2397,8 +2394,24 @@ $(SCRIPT_PYTHON_GEN): % : unimplemented.sh\n \t    unimplemented.sh >$@+ && \\\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n+else # NO_PYTHON\n+PYTHON_DEFINES += $(PYTHON_PATH_SQ)\n+\n+$(SCRIPT_PYTHON_GEN): % : %.py GIT-PYTHON-DEFINES\n+\t$(QUIET_GEN) \\\n+\tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n+\t    $< >$@+ && \\\n+\tchmod +x $@+ && \\\n+\tmv $@+ $@\n endif # NO_PYTHON\n \n+GIT-PYTHON-DEFINES: FORCE\n+\t@FLAGS='$(PYTHON_DEFINES)'; \\\n+\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n+\t\techo >&2 \"    * new python-specific parameters\"; \\\n+\t\techo \"$$FLAGS\" >$@; \\\n+\t    fi\n+\n CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t\t\tconfigure.ac >configure.ac+ && \\\n \t\t   autoconf -o configure configure.ac+ && \\\n@@ -2848,18 +2861,6 @@ else\n endif\n \t@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi\n \n-### Detect Python interpreter path changes\n-ifndef NO_PYTHON\n-TRACK_PYTHON = $(subst ','\\'',-DPYTHON_PATH='$(PYTHON_PATH_SQ)')\n-\n-GIT-PYTHON-VARS: FORCE\n-\t@VARS='$(TRACK_PYTHON)'; \\\n-\t    if test x\"$$VARS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new Python interpreter location\"; \\\n-\t\techo \"$$VARS\" >$@; \\\n-            fi\n-endif\n-\n test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))\n \n all:: $(TEST_PROGRAMS) $(test_bindir_programs)\n@@ -3256,7 +3257,7 @@ ifndef NO_TCLTK\n endif\n \t$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS\n \t$(RM) GIT-USER-AGENT GIT-PREFIX\n-\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS\n+\t$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-DEFINES\n ifdef MSVC\n \t$(RM) $(patsubst %.o,%.o.pdb,$(OBJECTS))\n \t$(RM) $(patsubst %.exe,%.pdb,$(OTHER_PROGRAMS))\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441460","messageId":"patch-v4-11.23-17b30e96057-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 11/23] Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:10Z","receivedAt":"2021-11-17T10:21:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the hardcoding of @@GIT_VERSION@@ in generated *.perl scripts\nto instead shell out to \"git version\". This means that we can stop\nre-building during development every time the HEAD changes.\n\nThese codepaths are not \"hot\", so shelling out to get the version\nshouldn't matter to users, in the one case where it potentially would\nin send-email (the loop for each E-Mail we send) we now cache the\nvalue, so we'll only retrieve it once.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile            | 2 +-\n git-cvsserver.perl  | 6 +++---\n git-send-email.perl | 7 ++-----\n git-svn.perl        | 2 +-\n 4 files changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex c698c5b058a..8205614c6ec 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2333,7 +2333,7 @@ PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl\n perl_localedir_SQ =\n endif\n \n-$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE\n+$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER\n \t$(QUIET_GEN) \\\n \tsed -e '1{' \\\n \t    -e '\ts|#!.*perl|#!$(PERL_PATH_SQ)|' \\\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 64319bed43f..76f0e8bbbef 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -26,8 +26,6 @@\n use File::Basename;\n use Getopt::Long qw(:config require_order no_ignore_case);\n \n-my $VERSION = '@@GIT_VERSION@@';\n-\n my $log = GITCVS::log->new();\n my $cfg;\n \n@@ -126,7 +124,9 @@\n     or die $usage;\n \n if ($state->{version}) {\n-    print \"git-cvsserver version $VERSION\\n\";\n+    my $version = qx[git version];\n+    $version =~ s/^(git)\\b/$1-cvsserver/;\n+    print $version;\n     exit;\n }\n if ($state->{help}) {\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 5262d88ee32..041cd2fb96d 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -1468,6 +1468,7 @@ sub file_name_is_absolute {\n #\n # If an error occurs sending the email, this just dies.\n \n+my $gitversion;\n sub send_message {\n \tmy @recipients = unique_email_list(@to);\n \t@cc = (grep { my $cc = extract_valid_address_or_die($_);\n@@ -1478,11 +1479,6 @@ sub send_message {\n \t@recipients = unique_email_list(@recipients,@cc,@initial_bcc);\n \t@recipients = (map { extract_valid_address_or_die($_) } @recipients);\n \tmy $date = format_2822_time($time++);\n-\tmy $gitversion = '@@GIT_VERSION@@';\n-\tif ($gitversion =~ m/..GIT_VERSION../) {\n-\t    $gitversion = Git::version();\n-\t}\n-\n \tmy $cc = join(\",\\n\\t\", unique_email_list(@cc));\n \tmy $ccline = \"\";\n \tif ($cc ne '') {\n@@ -1497,6 +1493,7 @@ sub send_message {\n Message-Id: $message_id\n \";\n \tif ($use_xmailer) {\n+\t\t$gitversion ||= Git::version();\n \t\t$header .= \"X-Mailer: git-send-email $gitversion\\n\";\n \t}\n \tif ($in_reply_to) {\ndiff --git a/git-svn.perl b/git-svn.perl\nindex be987e316f9..727431412be 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -9,7 +9,6 @@\n \t\t$_revision $_repository\n \t\t$_q $_authors $_authors_prog %users/;\n $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';\n-$VERSION = '@@GIT_VERSION@@';\n \n use Carp qw/croak/;\n use File::Basename qw/dirname basename/;\n@@ -47,6 +46,7 @@\n \tcommand_close_bidi_pipe\n \tget_record\n );\n+$VERSION = Git::version();\n \n BEGIN {\n \tMemoize::memoize 'Git::config';\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441454","messageId":"patch-v4-12.23-30ddf7da2c8-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 12/23] Makefiles: add \"shared.mak\", move \".DELETE_ON_ERROR\" to it","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:11Z","receivedAt":"2021-11-17T10:21:04Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We have various behavior that's shared across our Makefiles, or that\nreally should be (e.g. via defined templates). Let's create a\ntop-level \"shared.mak\" to house those sorts of things, and start by\nadding the \".DELETE_ON_ERROR\" flag to it.\n\nSee my own 7b76d6bf221 (Makefile: add and use the \".DELETE_ON_ERROR\"\nflag, 2021-06-29) and db10fc6c09f (doc: simplify Makefile using\n.DELETE_ON_ERROR, 2021-05-21) for the addition and use of the\n\".DELETE_ON_ERROR\" flag.\n\nThis does have the potential downside that if e.g. templates/Makefile\nwould like to include this \"shared.mak\" in the future the semantics of\nsuch a Makefile will change, but as noted in the above commits (and\nGNU make's own documentation) any such change would be for the better,\nso it's safe to do this.\n\nThis also doesn't introduce a bug by e.g. having this\n\".DELETE_ON_ERROR\" flag only apply to this new shared.mak, Makefiles\nhave no such scoping semantics.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile |  6 +++---\n Makefile               | 13 +++----------\n shared.mak             |  9 +++++++++\n 3 files changed, 15 insertions(+), 13 deletions(-)\n create mode 100644 shared.mak\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ed656db2ae9..ba27456c86a 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # Guard against environment variables\n MAN1_TXT =\n MAN5_TXT =\n@@ -524,7 +527,4 @@ doc-l10n install-l10n::\n \t$(MAKE) -C po $@\n endif\n \n-# Delete the target file on error\n-.DELETE_ON_ERROR:\n-\n .PHONY: FORCE\ndiff --git a/Makefile b/Makefile\nindex 8205614c6ec..5ae7d012cfb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include shared.mak\n+\n # The default target of this Makefile is...\n all::\n \n@@ -2158,16 +2161,6 @@ shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell\n strip: $(PROGRAMS) git$X\n \t$(STRIP) $(STRIP_OPTS) $^\n \n-### Flags affecting all rules\n-\n-# A GNU make extension since gmake 3.72 (released in late 1994) to\n-# remove the target of rules if commands in those rules fail. The\n-# default is to only do that if make itself receives a signal. Affects\n-# all targets, see:\n-#\n-#    info make --index-search=.DELETE_ON_ERROR\n-.DELETE_ON_ERROR:\n-\n ### Target-specific flags and dependencies\n \n # The generic compilation pattern rule and automatically\ndiff --git a/shared.mak b/shared.mak\nnew file mode 100644\nindex 00000000000..0170bb397ae\n--- /dev/null\n+++ b/shared.mak\n@@ -0,0 +1,9 @@\n+### Flags affecting all rules\n+\n+# A GNU make extension since gmake 3.72 (released in late 1994) to\n+# remove the target of rules if commands in those rules fail. The\n+# default is to only do that if make itself receives a signal. Affects\n+# all targets, see:\n+#\n+#    info make --index-search=.DELETE_ON_ERROR\n+.DELETE_ON_ERROR:\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441455","messageId":"patch-v4-13.23-f378a7dc35e-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 13/23] Makefile: move $(comma), $(empty) and $(space) to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:12Z","receivedAt":"2021-11-17T10:21:05Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move these variables over to the shared.max, we'll make use of them in\na subsequent commit. There was no reason for these to be \"simply\nexpanded variables\", so let's use the normal lazy \"=\" assignment here.\n\nSee 425ca6710b2 (Makefile: allow combining UBSan with other\nsanitizers, 2017-07-15) for the commit that introduced these.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile   | 4 ----\n shared.mak | 8 ++++++++\n 2 files changed, 8 insertions(+), 4 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 5ae7d012cfb..7130e32a251 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1252,10 +1252,6 @@ endif\n ALL_CFLAGS = $(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS)\n ALL_LDFLAGS = $(LDFLAGS)\n \n-comma := ,\n-empty :=\n-space := $(empty) $(empty)\n-\n ifdef SANITIZE\n SANITIZERS := $(foreach flag,$(subst $(comma),$(space),$(SANITIZE)),$(flag))\n BASIC_CFLAGS += -fsanitize=$(SANITIZE) -fno-sanitize-recover=$(SANITIZE)\ndiff --git a/shared.mak b/shared.mak\nindex 0170bb397ae..2d597ef7603 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -7,3 +7,11 @@\n #\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n+\n+### Global variables\n+\n+## comma, empty, space: handy variables as these tokens are either\n+## special or can be hard to spot among other Makefile syntax.\n+comma = ,\n+empty =\n+space = $(empty) $(empty)\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441456","messageId":"patch-v4-14.23-13cbb851d32-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 14/23] Makefile: re-add and use the \"shellquote\" macros","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:13Z","receivedAt":"2021-11-17T10:21:07Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Re-add and use, and expand on \"shellquote\" macros added in\n4769948afe7 (Deal with $(bindir) and friends with whitespaces.,\n2005-10-10).\n\nWe avoided using them due to the \"$(call)\" feature of GNU make being\nrelatively new at the time, but it isn't anymore. We hard depend on\nGNU make versions that have it.\n\nThe use of \"$(call)\" was removed in 39c015c556f (Fixes for ancient\nversions of GNU make, 2006-02-18) and 7ffe7098dca (Fix installation of\ntemplates on ancient systems., 2006-07-29) due to those\nincompatibilities with older GNU make versions, and we've used the\nmore verbose *_SQ pattern ever since.\n\nThe \"$(call)\" feature was introduced in GNU make version 3.78,\nreleased on the 22nd of September, 1999. That release also introduced\n\"$(error)\" and \"$(warning)\", which we've been making use of since\nf2fabbf76e4 (Teach Makefile to check header dependencies, 2010-01-26).\n\nThis extends upon the macros added in 4769948afe7: We now have macros\nfor quoting a ' inside '', and a ' with no surrounding '' as before.\n\nAdditionally provide and use a \"shelldquote\" macro along with\n\"shellquote\" for the common case of wanting to quote a C string we\npass to the compiler with a -D flag.\n\nThis doesn't get rid of all of our shell quoting. We've still got some\nin the main Makefile, let's leave most of it to avoid in-flight\nconflicts. I've fully converted \"templates/Makefile\" and \"t/Makefile\"\nthough.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile           | 15 +++++----------\n shared.mak         | 14 ++++++++++++++\n t/Makefile         | 34 +++++++++++++++-------------------\n templates/Makefile | 14 +++++---------\n 4 files changed, 39 insertions(+), 38 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 7130e32a251..b458c24d95e 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1996,11 +1996,7 @@ ifneq (\"$(PROFILE)\",\"\")\n endif\n endif\n \n-# Shell quote (do not use $(call) to accommodate ancient setups);\n-\n-ETC_GITCONFIG_SQ = $(subst ','\\'',$(ETC_GITCONFIG))\n-ETC_GITATTRIBUTES_SQ = $(subst ','\\'',$(ETC_GITATTRIBUTES))\n-\n+# Shell quote, should be changed to use $(call shellquote,...)\n DESTDIR_SQ = $(subst ','\\'',$(DESTDIR))\n NO_GETTEXT_SQ = $(subst ','\\'',$(NO_GETTEXT))\n bindir_SQ = $(subst ','\\'',$(bindir))\n@@ -2535,11 +2531,11 @@ builtin/init-db.sp builtin/init-db.s builtin/init-db.o: EXTRA_CPPFLAGS = \\\n \n config.sp config.s config.o: GIT-PREFIX\n config.sp config.s config.o: EXTRA_CPPFLAGS = \\\n-\t-DETC_GITCONFIG='\"$(ETC_GITCONFIG_SQ)\"'\n+\t-DETC_GITCONFIG=$(call shelldquote,$(ETC_GITCONFIG))\n \n attr.sp attr.s attr.o: GIT-PREFIX\n attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \\\n-\t-DETC_GITATTRIBUTES='\"$(ETC_GITATTRIBUTES_SQ)\"'\n+\t-DETC_GITATTRIBUTES=$(call shelldquote,$(ETC_GITATTRIBUTES))\n \n gettext.sp gettext.s gettext.o: GIT-PREFIX\n gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \\\n@@ -2700,14 +2696,13 @@ perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n \t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n \t    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \\\n-\t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \\\n+\t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(call shq,$(NO_PERL_CPAN_FALLBACKS))|g' \\\n \t< $< > $@\n \n all:: $(LIB_PERL_GEN)\n ifndef NO_PERL_CPAN_FALLBACKS\n all:: $(LIB_CPAN_GEN)\n endif\n-NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\\'',$(NO_PERL_CPAN_FALLBACKS))\n endif\n \n # install-man depends on Git.3pm even with NO_PERL=Y\n@@ -3021,7 +3016,7 @@ else\n \t$(INSTALL) $(vcpkg_dbg_bin)/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'\n endif\n endif\n-\t$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install\n+\t$(MAKE) -C templates DESTDIR=$(call shellquote,$(DESTDIR)) install\n \t$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'\n \t$(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'\n ifndef NO_GETTEXT\ndiff --git a/shared.mak b/shared.mak\nindex 2d597ef7603..ef03c2bc094 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -8,6 +8,20 @@\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n \n+### Quoting helpers\n+\n+## Quote a ' inside a '': FOO='$(call shq,$(BAR))'\n+shq = $(subst ','\\'',$(1))\n+\n+## Quote a ' and provide a '': FOO=$(call shq,$(BAR))\n+shellquote = '$(call shq,$(1))'\n+\n+## Quote a \" inside a \"\"\n+shdq = $(subst \",\\\",$(1))\n+\n+## Quote ' for the shell, and embedded \" for C: -DFOO=$(call shelldquote,$(BAR))\n+shelldquote = '\"$(call shdq,$(call shq,$(1)))\"'\n+\n ### Global variables\n \n ## comma, empty, space: handy variables as these tokens are either\ndiff --git a/t/Makefile b/t/Makefile\nindex 882d26eee30..4168b5c6ce6 100644\n--- a/t/Makefile\n+++ b/t/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # Run tests\n #\n # Copyright (c) 2005 Junio C Hamano\n@@ -24,13 +27,6 @@ TEST_RESULTS_DIRECTORY = test-results\n CHAINLINTTMP = chainlinttmp\n endif\n \n-# Shell quote;\n-SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n-TEST_SHELL_PATH_SQ = $(subst ','\\'',$(TEST_SHELL_PATH))\n-PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n-TEST_RESULTS_DIRECTORY_SQ = $(subst ','\\'',$(TEST_RESULTS_DIRECTORY))\n-CHAINLINTTMP_SQ = $(subst ','\\'',$(CHAINLINTTMP))\n-\n T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))\n TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh))\n THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh)))\n@@ -44,38 +40,38 @@ test: pre-clean check-chainlint $(TEST_LINT)\n \t$(MAKE) aggregate-results-and-cleanup\n \n failed:\n-\t@failed=$$(cd '$(TEST_RESULTS_DIRECTORY_SQ)' && \\\n+\t@failed=$$(cd $(call shellquote,$(TEST_RESULTS_DIRECTORY)) && \\\n \t\tgrep -l '^failed [1-9]' *.counts | \\\n \t\tsed -n 's/\\.counts$$/.sh/p') && \\\n \ttest -z \"$$failed\" || $(MAKE) $$failed\n \n prove: pre-clean check-chainlint $(TEST_LINT)\n-\t@echo \"*** prove ***\"; $(PROVE) --exec '$(TEST_SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n+\t@echo \"*** prove ***\"; $(PROVE) --exec $(call shellquote,$(SHELL_PATH)) $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)\n \t$(MAKE) clean-except-prove-cache\n \n $(T):\n-\t@echo \"*** $@ ***\"; '$(TEST_SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)\n+\t@echo \"*** $@ ***\"; $(call shellquote,$(SHELL_PATH)) $@ $(GIT_TEST_OPTS)\n \n pre-clean:\n-\t$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'\n+\t$(RM) -r $(call shellquote,$(TEST_RESULTS_DIRECTORY))\n \n clean-except-prove-cache: clean-chainlint\n-\t$(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)'\n+\t$(RM) -r 'trash directory'.* $(call shellquote,$(TEST_RESULTS_DIRECTORY))\n \t$(RM) -r valgrind/bin\n \n clean: clean-except-prove-cache\n \t$(RM) .prove\n \n clean-chainlint:\n-\t$(RM) -r '$(CHAINLINTTMP_SQ)'\n+\t$(RM) -r $(call shellquote,$(CHAINLINTTMP))\n \n check-chainlint:\n-\t@mkdir -p '$(CHAINLINTTMP_SQ)' && \\\n+\t@mkdir -p $(call shellquote,$(CHAINLINTTMP)) && \\\n \terr=0 && \\\n \tfor i in $(CHAINLINTTESTS); do \\\n \t\t$(CHAINLINT) <chainlint/$$i.test | \\\n-\t\tsed -e '/^# LINT: /d' >'$(CHAINLINTTMP_SQ)'/$$i.actual && \\\n-\t\tdiff -u chainlint/$$i.expect '$(CHAINLINTTMP_SQ)'/$$i.actual || err=1; \\\n+\t\tsed -e '/^# LINT: /d' >$(call shellquote,$(CHAINLINTTMP))/$$i.actual && \\\n+\t\tdiff -u chainlint/$$i.expect $(call shellquote,$(CHAINLINTTMP))/$$i.actual || err=1; \\\n \tdone && exit $$err\n \n test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \\\n@@ -92,7 +88,7 @@ test-lint-executable:\n \t\techo >&2 \"non-executable tests:\" $$bad; exit 1; }\n \n test-lint-shell-syntax:\n-\t@'$(PERL_PATH_SQ)' check-non-portable-shell.pl $(T) $(THELPERS) $(TPERF)\n+\t@$(call shellquote,$(PERL_PATH)) check-non-portable-shell.pl $(T) $(THELPERS) $(TPERF)\n \n test-lint-filenames:\n \t@# We do *not* pass a glob to ls-files but use grep instead, to catch\n@@ -107,9 +103,9 @@ aggregate-results-and-cleanup: $(T)\n \t$(MAKE) clean\n \n aggregate-results:\n-\tfor f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \\\n+\tfor f in $(call shellquote,$(TEST_RESULTS_DIRECTORY))/t*-*.counts; do \\\n \t\techo \"$$f\"; \\\n-\tdone | '$(SHELL_PATH_SQ)' ./aggregate-results.sh\n+\tdone | $(call shellquote,$(SHELL_PATH)) ./aggregate-results.sh\n \n gitweb-test:\n \t$(MAKE) $(TGITWEB)\ndiff --git a/templates/Makefile b/templates/Makefile\nindex d22a71a3999..c9251a96622 100644\n--- a/templates/Makefile\n+++ b/templates/Makefile\n@@ -1,3 +1,6 @@\n+# Import tree-wide shared Makefile behavior and libraries\n+include ../shared.mak\n+\n # make and install sample templates\n \n ifndef V\n@@ -18,13 +21,6 @@ ifndef PERL_PATH\n \tPERL_PATH = perl\n endif\n \n-SHELL_PATH_SQ = $(subst ','\\'',$(SHELL_PATH))\n-PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n-\n-# Shell quote (do not use $(call) to accommodate ancient setups);\n-DESTDIR_SQ = $(subst ','\\'',$(DESTDIR))\n-template_instdir_SQ = $(subst ','\\'',$(template_instdir))\n-\n all: boilerplates.made custom\n \n # Put templates that can be copied straight from the source\n@@ -61,6 +57,6 @@ clean:\n \t$(RM) -r blt boilerplates.made\n \n install: all\n-\t$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(template_instdir_SQ)'\n+\t$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(template_instdir))\n \t(cd blt && $(TAR) cf - .) | \\\n-\t(cd '$(DESTDIR_SQ)$(template_instdir_SQ)' && umask 022 && $(TAR) xof -)\n+\t(cd $(call shellquote,$(DESTDIR)$(template_instdir)) && umask 022 && $(TAR) xof -)\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441457","messageId":"patch-v4-15.23-337953e4994-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 15/23] Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:14Z","receivedAt":"2021-11-17T10:21:08Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Move the mostly copy/pasted code in the \"Makefile\" and\n\"Documentation/Makefile\" which FORCE-generates a file based on a\nvariable in play in the Makefile to use a template.\n\nThis will make it easier later on to move these to rules that aren't\nFORCE-run using optional gmake 4.2+ features, but for now just getting\nrid of the repetition is worth it.\n\nThe message for the new generated rule will say whether or not we're\ngenerating the file for the first time, as opposed to the old messages\nsaying \"new\" whether we had flag modifications, or were building for\nthe first time.\n\nExample output before:\n\n    $ make clean\n    [...]\n    $ make\n    GIT_VERSION = 2.34.0-rc1-dev\n        * new build flags\n        CC grep.o\n    $ make CFLAGS=-I$RANDOM grep.o\n        * new build flags\n        CC grep.o\n\nAfter:\n\n    $ make clean\n    [...]\n    $ make grep.o\n    GIT_VERSION = 2.34.0-rc1-dev\n        GIT-CFLAGS PARAMETERS (new)\n        CC grep.o\n    $ make CFLAGS=-I$RANDOM grep.o\n        GIT-CFLAGS PARAMETERS (changed)\n        CC grep.o\n\nNote: It's important that \"@FLAGS\" here be defined as '$$($(2))', and\nnot the eagerly expanded '$($(2))'. The latter will break if\ne.g. curl-config isn't installed, since we'll end up recursively\nexpanding that part of the variable even if NO_CURL isn't defined,\nwhich happens e.g. for the \"check-docs\" target in CI.\n\nWe're also introducing a $(wspfx) variable here to control the\nwhitespace prefixing. It matches the $(QUIET...) variables, who'll be\nusing these variables in a subsequent commit. Note that it's important\nthat we call the shell quote escaping macros inline (or equivalent),\nbecause if we'd like variables to be overridable we need to support e.g.:\n\n    $ make CFLAGS=-I$RANDOM grep.o wspfx='$(space)->'\n     -> GIT-CFLAGS PARAMETERS (changed)\n        CC grep.o\n\nIf we simply quoted and used $(wspfx) then the user would need to\nprovide us with a quoted version, so there's still some use-cases for\nthese $(*_sq) variables. It could also be done inline, but that's a\nlot more verbose.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile |  8 +------\n Makefile               | 51 ++++++------------------------------------\n shared.mak             | 22 ++++++++++++++++++\n 3 files changed, 30 insertions(+), 51 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex ba27456c86a..4a939cc2c25 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -343,13 +343,7 @@ mergetools-list.made: ../git-mergetool--lib.sh $(wildcard ../mergetools/*)\n \tdate >$@\n \n TRACK_ASCIIDOCFLAGS = $(subst ','\\'',$(ASCIIDOC_COMMON):$(ASCIIDOC_HTML):$(ASCIIDOC_DOCBOOK))\n-\n-GIT-ASCIIDOCFLAGS: FORCE\n-\t@FLAGS='$(TRACK_ASCIIDOCFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-ASCIIDOCFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new asciidoc flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-ASCIIDOCFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-ASCIIDOCFLAGS,TRACK_ASCIIDOCFLAGS))\n \n clean:\n \t$(RM) -rf .build/\ndiff --git a/Makefile b/Makefile\nindex b458c24d95e..c8a0a1586ca 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2087,10 +2087,7 @@ endif\n GIT_USER_AGENT_SQ = $(subst ','\\'',$(GIT_USER_AGENT))\n GIT_USER_AGENT_CQ = \"$(subst \",\\\",$(subst \\,\\\\,$(GIT_USER_AGENT)))\"\n GIT_USER_AGENT_CQ_SQ = $(subst ','\\'',$(GIT_USER_AGENT_CQ))\n-GIT-USER-AGENT: FORCE\n-\t@if test x'$(GIT_USER_AGENT_SQ)' != x\"`cat GIT-USER-AGENT 2>/dev/null`\"; then \\\n-\t\techo '$(GIT_USER_AGENT_SQ)' >GIT-USER-AGENT; \\\n-\tfi\n+$(eval $(call TRACK_template,GIT-USER-AGENT,GIT_USER_AGENT_SQ))\n \n ifdef DEFAULT_HELP_FORMAT\n BASIC_CFLAGS += -DDEFAULT_HELP_FORMAT='\"$(DEFAULT_HELP_FORMAT)\"'\n@@ -2238,12 +2235,7 @@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\\\n \t$(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n \t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(PAGER_ENV):\\\n \t$(perllibdir_SQ)\n-GIT-SCRIPT-DEFINES: FORCE\n-\t@FLAGS='$(SCRIPT_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new script parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-SCRIPT-DEFINES,SCRIPT_DEFINES))\n \n define cmd_munge_script\n sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n@@ -2355,13 +2347,7 @@ git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n endif # NO_PERL\n-\n-GIT-PERL-DEFINES: FORCE\n-\t@FLAGS='$(PERL_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new perl-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n+$(eval $(call TRACK_template,GIT-PERL-DEFINES,PERL_DEFINES))\n \n # As with NO_PERL=Y we'll still make GIT-PYTHON-DEFINES if \"NO_PYTHON\"\n # is defined, for creating the \"unimplemented.sh\" scripts.\n@@ -2390,12 +2376,7 @@ $(SCRIPT_PYTHON_GEN): % : %.py GIT-PYTHON-DEFINES\n \tmv $@+ $@\n endif # NO_PYTHON\n \n-GIT-PYTHON-DEFINES: FORCE\n-\t@FLAGS='$(PYTHON_DEFINES)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new python-specific parameters\"; \\\n-\t\techo \"$$FLAGS\" >$@; \\\n-\t    fi\n+$(eval $(call TRACK_template,GIT-PYTHON-DEFINES,PYTHON_DEFINES))\n \n CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t\t\tconfigure.ac >configure.ac+ && \\\n@@ -2751,31 +2732,13 @@ cscope: cscope.out\n ### Detect prefix changes\n TRACK_PREFIX = $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\\\n \t\t$(localedir_SQ)\n-\n-GIT-PREFIX: FORCE\n-\t@FLAGS='$(TRACK_PREFIX)'; \\\n-\tif test x\"$$FLAGS\" != x\"`cat GIT-PREFIX 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new prefix flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-PREFIX; \\\n-\tfi\n+$(eval $(call TRACK_template,GIT-PREFIX,TRACK_PREFIX))\n \n TRACK_CFLAGS = $(CC):$(subst ','\\'',$(ALL_CFLAGS)):$(USE_GETTEXT_SCHEME)\n-\n-GIT-CFLAGS: FORCE\n-\t@FLAGS='$(TRACK_CFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-CFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new build flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-CFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-CFLAGS,TRACK_CFLAGS))\n \n TRACK_LDFLAGS = $(subst ','\\'',$(ALL_LDFLAGS))\n-\n-GIT-LDFLAGS: FORCE\n-\t@FLAGS='$(TRACK_LDFLAGS)'; \\\n-\t    if test x\"$$FLAGS\" != x\"`cat GIT-LDFLAGS 2>/dev/null`\" ; then \\\n-\t\techo >&2 \"    * new link flags\"; \\\n-\t\techo \"$$FLAGS\" >GIT-LDFLAGS; \\\n-            fi\n+$(eval $(call TRACK_template,GIT-LDFLAGS,TRACK_LDFLAGS))\n \n # We need to apply sq twice, once to protect from the shell\n # that runs GIT-BUILD-OPTIONS, and then again to protect it\ndiff --git a/shared.mak b/shared.mak\nindex ef03c2bc094..97c8903f22c 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -29,3 +29,25 @@ shelldquote = '\"$(call shdq,$(call shq,$(1)))\"'\n comma = ,\n empty =\n space = $(empty) $(empty)\n+\n+## wspfx: the whitespace prefix padding for $(QUIET...) and similarly\n+## aligned output.\n+wspfx = $(space)$(space)$(space)\n+wspfx_sq = $(call shellquote,$(wspfx))\n+\n+### Templates\n+\n+## Template for making a GIT-SOMETHING, which changes if a\n+## TRACK_SOMETHING variable changes.\n+define TRACK_template\n+.PHONY: FORCE\n+$(1): FORCE\n+\t@FLAGS='$$($(2))'; \\\n+\tif ! test -f $(1) ; then \\\n+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (new)\"; \\\n+\t\techo \"$$$$FLAGS\" >$(1); \\\n+\telif test x\"$$$$FLAGS\" != x\"`cat $(1) 2>/dev/null`\" ; then \\\n+\t\techo $(wspfx_sq) \"$(1) PARAMETERS (changed)\"; \\\n+\t\techo \"$$$$FLAGS\" >$(1); \\\n+\tfi\n+endef\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441458","messageId":"patch-v4-16.23-5bb597c1993-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 16/23] Makefile: add \"$(QUIET)\" boilerplate to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:15Z","receivedAt":"2021-11-17T10:21:09Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"The $(QUIET) variables we define are largely duplicated between our\nvarious Makefiles, let's define them in the new \"shared.mak\" instead.\n\nSince we're not using the environment to pass these around we don't\nneed to export the \"QUIET_GEN\" and \"QUIET_BUILT_IN\" variables\nanymore. The \"QUIET_GEN\" variable is used in \"git-gui/Makefile\" and\n\"gitweb/Makefile\", but they've got their own definition for those. The\n\"QUIET_BUILT_IN\" variable is only used in the top-level \"Makefile\". We\nstill need to export the \"V\" variable.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile | 32 -------------------------\n Makefile               | 33 --------------------------\n config.mak.uname       |  1 -\n shared.mak             | 53 ++++++++++++++++++++++++++++++++++++++++++\n templates/Makefile     |  5 ----\n 5 files changed, 53 insertions(+), 71 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex 4a939cc2c25..69a9af35397 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -218,38 +218,6 @@ DEFAULT_EDITOR_SQ = $(subst ','\\'',$(DEFAULT_EDITOR))\n ASCIIDOC_EXTRA += -a 'git-default-editor=$(DEFAULT_EDITOR_SQ)'\n endif\n \n-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n-QUIET_SUBDIR1  =\n-\n-ifneq ($(findstring $(MAKEFLAGS),w),w)\n-PRINT_DIR = --no-print-directory\n-else # \"make -w\"\n-NO_SUBDIR = :\n-endif\n-\n-ifneq ($(findstring $(MAKEFLAGS),s),s)\n-ifndef V\n-\tQUIET\t\t= @\n-\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n-\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n-\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n-\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n-\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n-\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n-\tQUIET_GEN\t= @echo '   ' GEN $@;\n-\tQUIET_STDERR\t= 2> /dev/null\n-\tQUIET_SUBDIR0\t= +@subdir=\n-\tQUIET_SUBDIR1\t= ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n-\t\t\t  $(MAKE) $(PRINT_DIR) -C $$subdir\n-\n-\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n-\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n-\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n-\n-\texport V\n-endif\n-endif\n-\n all: html man\n \n html: $(DOC_HTML)\ndiff --git a/Makefile b/Makefile\nindex c8a0a1586ca..c437aea9e4a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1939,39 +1939,6 @@ ifndef PAGER_ENV\n PAGER_ENV = LESS=FRX LV=-c\n endif\n \n-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n-QUIET_SUBDIR1  =\n-\n-ifneq ($(findstring w,$(MAKEFLAGS)),w)\n-PRINT_DIR = --no-print-directory\n-else # \"make -w\"\n-NO_SUBDIR = :\n-endif\n-\n-ifneq ($(findstring s,$(MAKEFLAGS)),s)\n-ifndef V\n-\tQUIET_CC       = @echo '   ' CC $@;\n-\tQUIET_AR       = @echo '   ' AR $@;\n-\tQUIET_LINK     = @echo '   ' LINK $@;\n-\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n-\tQUIET_GEN      = @echo '   ' GEN $@;\n-\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n-\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n-\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n-\tQUIET_GCOV     = @echo '   ' GCOV $@;\n-\tQUIET_SP       = @echo '   ' SP $<;\n-\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n-\tQUIET_RC       = @echo '   ' RC $@;\n-\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n-\tQUIET_SUBDIR0  = +@subdir=\n-\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n-\t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n-\texport V\n-\texport QUIET_GEN\n-\texport QUIET_BUILT_IN\n-endif\n-endif\n-\n ifdef NO_INSTALL_HARDLINKS\n \texport NO_INSTALL_HARDLINKS\n endif\ndiff --git a/config.mak.uname b/config.mak.uname\nindex d0701f9beb0..1a12d8c635f 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -715,7 +715,6 @@ vcxproj:\n \tgit diff-index --cached --quiet HEAD --\n \n \t# Make .vcxproj files and add them\n-\tunset QUIET_GEN QUIET_BUILT_IN; \\\n \tperl contrib/buildsystems/generate -g Vcxproj\n \tgit add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj\n \ndiff --git a/shared.mak b/shared.mak\nindex 97c8903f22c..1b666a1bc69 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -35,6 +35,59 @@ space = $(empty) $(empty)\n wspfx = $(space)$(space)$(space)\n wspfx_sq = $(call shellquote,$(wspfx))\n \n+### Quieting\n+## common\n+QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir\n+QUIET_SUBDIR1  =\n+\n+ifneq ($(findstring w,$(MAKEFLAGS)),w)\n+PRINT_DIR = --no-print-directory\n+else # \"make -w\"\n+NO_SUBDIR = :\n+endif\n+\n+ifneq ($(findstring s,$(MAKEFLAGS)),s)\n+ifndef V\n+## common\n+\tQUIET_SUBDIR0  = +@subdir=\n+\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n+\t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n+\n+\tQUIET          = @\n+\tQUIET_GEN      = @echo '   ' GEN $@;\n+\n+## Used in \"Makefile\"\n+\tQUIET_CC       = @echo '   ' CC $@;\n+\tQUIET_AR       = @echo '   ' AR $@;\n+\tQUIET_LINK     = @echo '   ' LINK $@;\n+\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n+\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n+\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n+\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n+\tQUIET_GCOV     = @echo '   ' GCOV $@;\n+\tQUIET_SP       = @echo '   ' SP $<;\n+\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n+\tQUIET_RC       = @echo '   ' RC $@;\n+\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n+\n+## Used in \"Documentation/Makefile\"\n+\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n+\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n+\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n+\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n+\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n+\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n+\tQUIET_GEN\t= @echo '   ' GEN $@;\n+\tQUIET_STDERR\t= 2> /dev/null\n+\n+\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n+\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n+\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n+\n+\texport V\n+endif\n+endif\n+\n ### Templates\n \n ## Template for making a GIT-SOMETHING, which changes if a\ndiff --git a/templates/Makefile b/templates/Makefile\nindex c9251a96622..b056e710b7e 100644\n--- a/templates/Makefile\n+++ b/templates/Makefile\n@@ -2,11 +2,6 @@\n include ../shared.mak\n \n # make and install sample templates\n-\n-ifndef V\n-\tQUIET = @\n-endif\n-\n INSTALL ?= install\n TAR ?= tar\n RM ?= rm -f\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441459","messageId":"patch-v4-17.23-3c4d0589667-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 17/23] Makefile: use $(wspfx) for $(QUIET...) in shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:16Z","receivedAt":"2021-11-17T10:21:10Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the mostly move-only change in the preceding commit to use the\n$(wspfx) variable for defining the QUIET padding, to guarantee that\nit's consistent with the \"TRACK_template\" template.\n\n    $ make CFLAGS=-I$RANDOM grep.o wspfx='$(space)->'\n     -> GIT-CFLAGS PARAMETERS (changed)\n     -> CC grep.o\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n shared.mak | 48 ++++++++++++++++++++++++------------------------\n 1 file changed, 24 insertions(+), 24 deletions(-)\n\ndiff --git a/shared.mak b/shared.mak\nindex 1b666a1bc69..36f00e88bb8 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -50,39 +50,39 @@ ifneq ($(findstring s,$(MAKEFLAGS)),s)\n ifndef V\n ## common\n \tQUIET_SUBDIR0  = +@subdir=\n-\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \\\n+\tQUIET_SUBDIR1  = ;$(NO_SUBDIR) echo $(wspfx_sq) SUBDIR $$subdir; \\\n \t\t\t $(MAKE) $(PRINT_DIR) -C $$subdir\n \n \tQUIET          = @\n-\tQUIET_GEN      = @echo '   ' GEN $@;\n+\tQUIET_GEN      = @echo $(wspfx_sq) GEN $@;\n \n ## Used in \"Makefile\"\n-\tQUIET_CC       = @echo '   ' CC $@;\n-\tQUIET_AR       = @echo '   ' AR $@;\n-\tQUIET_LINK     = @echo '   ' LINK $@;\n-\tQUIET_BUILT_IN = @echo '   ' BUILTIN $@;\n-\tQUIET_LNCP     = @echo '   ' LN/CP $@;\n-\tQUIET_XGETTEXT = @echo '   ' XGETTEXT $@;\n-\tQUIET_MSGFMT   = @echo '   ' MSGFMT $@;\n-\tQUIET_GCOV     = @echo '   ' GCOV $@;\n-\tQUIET_SP       = @echo '   ' SP $<;\n-\tQUIET_HDR      = @echo '   ' HDR $(<:hcc=h);\n-\tQUIET_RC       = @echo '   ' RC $@;\n-\tQUIET_SPATCH   = @echo '   ' SPATCH $<;\n+\tQUIET_CC       = @echo $(wspfx_sq) CC $@;\n+\tQUIET_AR       = @echo $(wspfx_sq) AR $@;\n+\tQUIET_LINK     = @echo $(wspfx_sq) LINK $@;\n+\tQUIET_BUILT_IN = @echo $(wspfx_sq) BUILTIN $@;\n+\tQUIET_LNCP     = @echo $(wspfx_sq) LN/CP $@;\n+\tQUIET_XGETTEXT = @echo $(wspfx_sq) XGETTEXT $@;\n+\tQUIET_MSGFMT   = @echo $(wspfx_sq) MSGFMT $@;\n+\tQUIET_GCOV     = @echo $(wspfx_sq) GCOV $@;\n+\tQUIET_SP       = @echo $(wspfx_sq) SP $<;\n+\tQUIET_HDR      = @echo $(wspfx_sq) HDR $(<:hcc=h);\n+\tQUIET_RC       = @echo $(wspfx_sq) RC $@;\n+\tQUIET_SPATCH   = @echo $(wspfx_sq) SPATCH $<;\n \n ## Used in \"Documentation/Makefile\"\n-\tQUIET_ASCIIDOC\t= @echo '   ' ASCIIDOC $@;\n-\tQUIET_XMLTO\t= @echo '   ' XMLTO $@;\n-\tQUIET_DB2TEXI\t= @echo '   ' DB2TEXI $@;\n-\tQUIET_MAKEINFO\t= @echo '   ' MAKEINFO $@;\n-\tQUIET_DBLATEX\t= @echo '   ' DBLATEX $@;\n-\tQUIET_XSLTPROC\t= @echo '   ' XSLTPROC $@;\n-\tQUIET_GEN\t= @echo '   ' GEN $@;\n+\tQUIET_ASCIIDOC\t= @echo $(wspfx_sq) ASCIIDOC $@;\n+\tQUIET_XMLTO\t= @echo $(wspfx_sq) XMLTO $@;\n+\tQUIET_DB2TEXI\t= @echo $(wspfx_sq) DB2TEXI $@;\n+\tQUIET_MAKEINFO\t= @echo $(wspfx_sq) MAKEINFO $@;\n+\tQUIET_DBLATEX\t= @echo $(wspfx_sq) DBLATEX $@;\n+\tQUIET_XSLTPROC\t= @echo $(wspfx_sq) XSLTPROC $@;\n+\tQUIET_GEN\t= @echo $(wspfx_sq) GEN $@;\n \tQUIET_STDERR\t= 2> /dev/null\n \n-\tQUIET_LINT_GITLINK\t= @echo '   ' LINT GITLINK $<;\n-\tQUIET_LINT_MANSEC\t= @echo '   ' LINT MAN SEC $<;\n-\tQUIET_LINT_MANEND\t= @echo '   ' LINT MAN END $<;\n+\tQUIET_LINT_GITLINK\t= @echo $(wspfx_sq) LINT GITLINK $<;\n+\tQUIET_LINT_MANSEC\t= @echo $(wspfx_sq) LINT MAN SEC $<;\n+\tQUIET_LINT_MANEND\t= @echo $(wspfx_sq) LINT MAN END $<;\n \n \texport V\n endif\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441461","messageId":"patch-v4-18.23-be5882b2c99-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 18/23] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:17Z","receivedAt":"2021-11-17T10:21:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\nfor us, and use it for the \"make lint-docs\" targets I added in\n8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n\nAs seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\ndependency, 2021-10-26) maintaining these manual lists of parent\ndirectory dependencies is fragile, in addition to being obviously\nverbose.\n\nI used this pattern at the time because I couldn't find another method\nthan \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\nevery file being created, which as noted in [1] would be significantly\nslower.\n\nBut as it turns out we can use this neat trick of only doing a \"mkdir\n-p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\nof a performance test similar to thatnoted downthread of [1] in [2]\nshows that this is faster, in addition to being less verbose and more\nreliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n\n    $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n    Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n      Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n      Range (min … max):    2.121 s …  2.158 s    10 runs\n\n    Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n      Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n      Range (min … max):    2.657 s …  2.662 s    10 runs\n\n    Summary\n      'make -C Documentation lint-docs' in 'HEAD~0' ran\n        1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n\nSo let's use that pattern both for the \"lint-docs\" target, and a few\nmiscellaneous other targets.\n\nThis method of creating parent directories is explicitly racy in that\nwe don't know if we're going to say always create a \"foo\" followed by\na \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n\"foo/bar\" first. In this case it doesn't matter for anything except\nthat we aren't guaranteed to get the same number of rules firing when\nrunning make in parallel.\n\n1. https://lore.kernel.org/git/211028.861r45y3pt.gmgdl@evledraar.gmail.com/\n2. https://lore.kernel.org/git/211028.86o879vvtp.gmgdl@evledraar.gmail.com/\n3. https://gitlab.com/avar/git-hyperfine/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/Makefile | 25 +++----------------------\n Makefile               | 12 +++++++-----\n shared.mak             |  7 +++++++\n 3 files changed, 17 insertions(+), 27 deletions(-)\n\ndiff --git a/Documentation/Makefile b/Documentation/Makefile\nindex 69a9af35397..d16b653394c 100644\n--- a/Documentation/Makefile\n+++ b/Documentation/Makefile\n@@ -428,25 +428,11 @@ quick-install-html: require-htmlrepo\n print-man1:\n \t@for i in $(MAN1_TXT); do echo $$i; done\n \n-## Lint: Common\n-.build:\n-\t$(QUIET)mkdir $@\n-.build/lint-docs: | .build\n-\t$(QUIET)mkdir $@\n-\n ## Lint: gitlink\n-.build/lint-docs/gitlink: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n-.build/lint-docs/gitlink/howto: | .build/lint-docs/gitlink\n-\t$(QUIET)mkdir $@\n-.build/lint-docs/gitlink/config: | .build/lint-docs/gitlink\n-\t$(QUIET)mkdir $@\n LINT_DOCS_GITLINK = $(patsubst %.txt,.build/lint-docs/gitlink/%.ok,$(HOWTO_TXT) $(DOC_DEP_TXT))\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/howto\n-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/config\n $(LINT_DOCS_GITLINK): lint-gitlink.perl\n $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_GITLINK)$(PERL_PATH) lint-gitlink.perl \\\n \t\t$< \\\n \t\t$(HOWTO_TXT) $(DOC_DEP_TXT) \\\n@@ -457,23 +443,18 @@ $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt\n lint-docs-gitlink: $(LINT_DOCS_GITLINK)\n \n ## Lint: man-end-blurb\n-.build/lint-docs/man-end-blurb: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n LINT_DOCS_MAN_END_BLURB = $(patsubst %.txt,.build/lint-docs/man-end-blurb/%.ok,$(MAN_TXT))\n-$(LINT_DOCS_MAN_END_BLURB): | .build/lint-docs/man-end-blurb\n $(LINT_DOCS_MAN_END_BLURB): lint-man-end-blurb.perl\n $(LINT_DOCS_MAN_END_BLURB): .build/lint-docs/man-end-blurb/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_MANEND)$(PERL_PATH) lint-man-end-blurb.perl $< >$@\n .PHONY: lint-docs-man-end-blurb\n-lint-docs-man-end-blurb: $(LINT_DOCS_MAN_END_BLURB)\n \n ## Lint: man-section-order\n-.build/lint-docs/man-section-order: | .build/lint-docs\n-\t$(QUIET)mkdir $@\n LINT_DOCS_MAN_SECTION_ORDER = $(patsubst %.txt,.build/lint-docs/man-section-order/%.ok,$(MAN_TXT))\n-$(LINT_DOCS_MAN_SECTION_ORDER): | .build/lint-docs/man-section-order\n $(LINT_DOCS_MAN_SECTION_ORDER): lint-man-section-order.perl\n $(LINT_DOCS_MAN_SECTION_ORDER): .build/lint-docs/man-section-order/%.ok: %.txt\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_LINT_MANSEC)$(PERL_PATH) lint-man-section-order.perl $< >$@\n .PHONY: lint-docs-man-section-order\n lint-docs-man-section-order: $(LINT_DOCS_MAN_SECTION_ORDER)\ndiff --git a/Makefile b/Makefile\nindex c437aea9e4a..0a3f292bf82 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2632,7 +2632,8 @@ all:: $(MOFILES)\n endif\n \n po/build/locale/%/LC_MESSAGES/git.mo: po/%.po\n-\t$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_MSGFMT)$(MSGFMT) -o $@ $<\n \n ifndef NO_PERL\n LIB_PERL = $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)\n@@ -2641,7 +2642,8 @@ LIB_CPAN = $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)\n LIB_CPAN_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))\n \n perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES\n-\t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_GEN) \\\n \tsed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \\\n \t    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \\\n \t    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(call shq,$(NO_PERL_CPAN_FALLBACKS))|g' \\\n@@ -2655,8 +2657,8 @@ endif\n \n # install-man depends on Git.3pm even with NO_PERL=Y\n perl/build/man/man3/Git.3pm: perl/Git.pm\n-\t$(QUIET_GEN)mkdir -p $(dir $@) && \\\n-\tpod2man $< $@\n+\t$(call mkdir_p_parent_template)\n+\t$(QUIET_GEN)pod2man $< $@\n \n FIND_SOURCE_FILES = ( \\\n \tgit ls-files \\\n@@ -2780,7 +2782,7 @@ test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(\n all:: $(TEST_PROGRAMS) $(test_bindir_programs)\n \n bin-wrappers/%: wrap-for-bin.sh\n-\t@mkdir -p bin-wrappers\n+\t$(call mkdir_p_parent_template)\n \t$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n \t     -e 's|@@BUILD_DIR@@|$(shell pwd)|' \\\n \t     -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \\\ndiff --git a/shared.mak b/shared.mak\nindex 36f00e88bb8..8d3023c2782 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -56,6 +56,8 @@ ifndef V\n \tQUIET          = @\n \tQUIET_GEN      = @echo $(wspfx_sq) GEN $@;\n \n+\tQUIET_MKDIR_P_PARENT  = @echo $(wspfx_sq) MKDIR -p $(@D);\n+\n ## Used in \"Makefile\"\n \tQUIET_CC       = @echo $(wspfx_sq) CC $@;\n \tQUIET_AR       = @echo $(wspfx_sq) AR $@;\n@@ -88,6 +90,11 @@ ifndef V\n endif\n endif\n \n+## Helpers\n+define mkdir_p_parent_template\n+$(if $(wildcard $(@D)),,$(QUIET_MKDIR_P_PARENT)$(shell mkdir -p $(@D)))\n+endef\n+\n ### Templates\n \n ## Template for making a GIT-SOMETHING, which changes if a\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441462","messageId":"patch-v4-19.23-2710f8af6cd-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 19/23] Makefile: correct the dependency graph of hook-list.h","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:18Z","receivedAt":"2021-11-17T10:21:14Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix an issue in my cfe853e66be (hook-list.h: add a generated list of\nhooks, like config-list.h, 2021-09-26), the builtin/help.c was\ninadvertently made to depend on hook-list.h, but it's used by\nbuiltin/bugreport.c.\n\nThe hook.c also does not depend on hook-list.h. It did in an earlier\nversion of the greater series cfe853e66be was extracted from, but not\nanymore. We might end up needing that line again, but let's remove it\nfor now.\n\nReported-by: Mike Hommey <mh@glandium.org>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 0a3f292bf82..a9fa9461613 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2161,9 +2161,9 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)\n \t\t$(filter %.o,$^) $(LIBS)\n \n help.sp help.s help.o: command-list.h\n-hook.sp hook.s hook.o: hook-list.h\n+builtin/bugreport.sp builtin/bugreport.s builtin/bugreport.o: hook-list.h\n \n-builtin/help.sp builtin/help.s builtin/help.o: config-list.h hook-list.h GIT-PREFIX\n+builtin/help.sp builtin/help.s builtin/help.o: config-list.h GIT-PREFIX\n builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \\\n \t'-DGIT_HTML_PATH=\"$(htmldir_relative_SQ)\"' \\\n \t'-DGIT_MAN_PATH=\"$(mandir_relative_SQ)\"' \\\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441463","messageId":"patch-v4-20.23-59f22a0269a-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 20/23] Makefile: use $(file) I/O instead of \"FORCE\" when possible","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:19Z","receivedAt":"2021-11-17T10:21:17Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Provide an alternate implementation of the recently added\n\"TRACK_template\" which uses GNU make 4.2 features. If the 'file'\nfunction is available we don't need to shell out at all to check if\nour tracked files change.\n\nWe need to use the intermediate TRACK_template calling a\nTRACK_template_eval within the generated rule so that we don't eagerly\nfleshen these when \"make\" reads the file.\n\nThis doesn't make the runtime faster on my system, but helps to cut\ndown on the noise of things we shell out for\nunconditionally. I.e. running \"make\" with \"SHELL_PATH='sh -x'\" (twice,\nso we pick up the setting) shows than a no-op run went from emitting:\n\n    $ SHELL_PATH='sh -x' make -j8 >/dev/null 2>&1; SHELL_PATH='sh -x' make 2>&1 |wc -l\n    124\n\nTo:\n\n    $ SHELL_PATH='sh -x' make -j8 >/dev/null 2>&1; SHELL_PATH='sh -x' make 2>&1 |wc -l\n    95\n\nThat 124 to 95 number is a rough approximation of how many times we\nshell out. \"strace -f -c\" similarly shows that we went from 8798 to\n8466 syscalls. So this brings us further along in the goal of making\n\"make\" do as little as possible when it's got nothing to re-build (see\n[2]).\n\n1. https://lore.kernel.org/git/874kdn1j6i.fsf@evledraar.gmail.com/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n shared.mak | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 58 insertions(+)\n\ndiff --git a/shared.mak b/shared.mak\nindex 8d3023c2782..2d5d5b2fb9b 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -8,6 +8,22 @@\n #    info make --index-search=.DELETE_ON_ERROR\n .DELETE_ON_ERROR:\n \n+### GNU Make version detection\n+# We don't care about \"release\" versions like the \"90\" in \"3.99.90\"\n+MAKE_VERSION_MAJOR = $(word 1,$(subst ., ,$(MAKE_VERSION)))\n+MAKE_VERSION_MINOR = $(word 2,$(subst ., ,$(MAKE_VERSION)))\n+\n+# The oldest supported version of GNU make is 3-something. So \"not v3\"\n+# is a future-proof way to ask \"is it modern?\"\n+ifneq ($(MAKE_VERSION_MAJOR),3)\n+# $(file >[...]) and $(file >>[...]) is in 4.0...\n+MAKE_HAVE_FILE_WRITE = Need version 4.0 or later (released in late 2013)\n+# .. but we need 4.2 for $(file <[...])\n+ifneq ($(filter-out 0 1,$(MAKE_VERSION_MINOR)),)\n+MAKE_HAVE_FILE_READ = Need version 4.2 or later (released in mid-2016)\n+endif\n+endif\n+\n ### Quoting helpers\n \n ## Quote a ' inside a '': FOO='$(call shq,$(BAR))'\n@@ -99,6 +115,10 @@ endef\n \n ## Template for making a GIT-SOMETHING, which changes if a\n ## TRACK_SOMETHING variable changes.\n+##\n+## This is the slower version used on GNU make <4.2.\n+ifndef MAKE_HAVE_FILE_READ\n+\n define TRACK_template\n .PHONY: FORCE\n $(1): FORCE\n@@ -111,3 +131,41 @@ $(1): FORCE\n \t\techo \"$$$$FLAGS\" >$(1); \\\n \tfi\n endef\n+\n+endif # !MAKE_HAVE_FILE_READ\n+\n+## A TRACK_template template compatible with the one above. Uses\n+## features of GNU make >=4.2 to avoid shelling out for this \"hot\"\n+## \"FORCE\" logic.\n+##\n+## Since version >=4.2 can do both \"I\" and \"O\" in I/O with using\n+## $(file <)/$(file >) we read the GIT-SOMETHING file into a variable\n+## with the former, and if it's different from our expected value\n+## write it out with the latter.\n+ifdef MAKE_HAVE_FILE_READ\n+\n+define TRACK_template_eval\n+$(1)_WRITE =\n+$(1)_EXISTS = $(wildcard $(1))\n+ifeq ($$($(1)_EXISTS),)\n+$(1)_WRITE = new\n+else\n+$(1)_CONTENT = $(file <$(1))\n+ifeq ($$($(1)_CONTENT),$($(2)))\n+$(1)_WRITE = same\n+else\n+$(1)_WRITE = changed\n+endif\n+endif\n+ifneq ($$($(1)_WRITE),same)\n+$$(info $$(wspfx) $(1) parameters ($$($(1)_WRITE)))\n+$$(file >$(1),$($(2)))\n+endif\n+endef # TRACK_template_eval\n+\n+define TRACK_template\n+$(1):\n+\t$$(eval $$(call TRACK_template_eval,$(1),$(2)))\n+endef\n+\n+endif # MAKE_HAVE_FILE_READ\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441464","messageId":"patch-v4-21.23-dd569a59c74-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 21/23] Makefile: disable GNU make built-in wildcard rules","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:20Z","receivedAt":"2021-11-17T10:21:19Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Override built-in rules of GNU make that use a wildcard target. This\nspeeds things up significantly as we don't need to stat() so many\nfiles just in case we'd be able to retrieve their contents from RCS or\nSCCS. See [1] for an old mailing list discussion about how to disable\nthese.\n\nThis gives us a noticeable speedup on a no-op run:\n\n    $ git hyperfine -L rev HEAD~1,HEAD~0 -s 'make -j8 all NO_TCLTK=Y' 'make NO_TCLTK=Y' --warmup 10 -M 10\n    Benchmark 1: make NO_TCLTK=Y' in 'HEAD~1\n      Time (mean ± σ):     182.2 ms ±   4.1 ms    [User: 146.8 ms, System: 49.5 ms]\n      Range (min … max):   179.6 ms … 193.4 ms    10 runs\n\n    Benchmark 2: make NO_TCLTK=Y' in 'HEAD~0\n      Time (mean ± σ):     167.9 ms ±   1.3 ms    [User: 127.8 ms, System: 55.6 ms]\n      Range (min … max):   166.1 ms … 170.4 ms    10 runs\n\n    Summary\n      'make NO_TCLTK=Y' in 'HEAD~0' ran\n        1.09 ± 0.03 times faster than 'make NO_TCLTK=Y' in 'HEAD~1'\n\nRunning the same except with 'strace -c -S calls make' as the\nbenchmark command shows (under --show-output) that we went from ~7716\nsyscalls to ~7519, mostly a reduction in [l]stat().\n\nWe could also invoke make with \"-r\" by setting \"MAKEFLAGS = -r\" early,\nadding a \"-r\" variant to the above benchmark shows that it may be 1.01\nor so faster (but in my tests, always with a much bigger error\nbar). But doing so is a much bigger hammer, since it will disable all\nbuilt-in rules, some (all?) of which can be seen with:\n\n    make -f/dev/null -p | grep -v -e ^# -e ^$\n\nWe may have something that relies on them, so let's go for the more\nisolated optimization here that gives us most or all of the wins.\n\n1. https://lists.gnu.org/archive/html/help-make/2002-11/msg00063.html\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n shared.mak | 11 +++++++++++\n 1 file changed, 11 insertions(+)\n\ndiff --git a/shared.mak b/shared.mak\nindex 2d5d5b2fb9b..20109e6a90e 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -1,3 +1,14 @@\n+### Remove GNU make implicit rules\n+\n+## This speeds things up since we don't need to look for and stat() a\n+## \"foo.c,v\" every time a rule referring to \"foo.c\" is in play. See\n+## \"make -p -f/dev/null | grep ^%::'\".\n+%:: %,v\n+%:: RCS/%,v\n+%:: RCS/%\n+%:: s.%\n+%:: SCCS/s.%\n+\n ### Flags affecting all rules\n \n # A GNU make extension since gmake 3.72 (released in late 1994) to\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441465","messageId":"patch-v4-22.23-4168a7e3b30-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 22/23] Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES)","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:21Z","receivedAt":"2021-11-17T10:21:23Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Combine the definitions of $(FIND_SOURCE_FILES) and $(LIB_H) to speed\nup the Makefile, as these are the two main expensive $(shell) commands\nthat we execute unconditionally.\n\nWhen see what was in $(FOUND_SOURCE_FILES) that wasn't in $(LIB_H) via\nthe ad-hoc test of:\n\n    $(error $(filter-out $(LIB_H),$(filter %.h,$(ALL_SOURCE_FILES))))\n    $(error $(filter-out $(ALL_SOURCE_FILES),$(filter %.h,$(LIB_H))))\n\nWe'll get, respectively:\n\n    Makefile:850: *** t/helper/test-tool.h.  Stop.\n    Makefile:850: *** .  Stop.\n\nI.e. we only had a discrepancy when it came to\nt/helper/test-tool.h. In terms of correctness this was broken before,\nbut now works:\n\n    $ make t/helper/test-tool.hco\n        HDR t/helper/test-tool.h\n\nThis speeds things up a lot:\n\n    $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make -j8 all NO_TCLTK=Y' 'make NO_TCLTK=Y' --war\n    mup 10 -M 10\n    Benchmark 1: make NO_TCLTK=Y' in 'HEAD~1\n      Time (mean ± σ):      99.5 ms ±   0.5 ms    [User: 83.4 ms, System: 20.7 ms]\n      Range (min … max):    98.8 ms … 100.2 ms    10 runs\n\n    Benchmark 2: make NO_TCLTK=Y' in 'HEAD~0\n      Time (mean ± σ):      69.4 ms ±   0.5 ms    [User: 58.8 ms, System: 14.2 ms]\n      Range (min … max):    68.9 ms …  70.3 ms    10 runs\n\n    Summary\n      'make NO_TCLTK=Y' in 'HEAD~0' ran\n        1.43 ± 0.01 times faster than 'make NO_TCLTK=Y' in 'HEAD~1'\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile | 54 ++++++++++++++++++++++++++----------------------------\n 1 file changed, 26 insertions(+), 28 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex a9fa9461613..eb1c944787b 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -821,12 +821,33 @@ GENERATED_H += hook-list.h\n .PHONY: generated-hdrs\n generated-hdrs: $(GENERATED_H)\n \n-LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \\\n+## Exhaustive lists of our source files, either dynamically generated,\n+## or hardcoded.\n+SOURCES_CMD = ( \\\n+\tgit ls-files \\\n+\t\t'*.[hcS]' \\\n+\t\t'*.sh' \\\n+\t\t':!*[tp][0-9][0-9][0-9][0-9]*' \\\n+\t\t':!contrib' \\\n+\t\t2>/dev/null || \\\n \t$(FIND) . \\\n-\t-name .git -prune -o \\\n-\t-name t -prune -o \\\n-\t-name Documentation -prune -o \\\n-\t-name '*.h' -print)))\n+\t\t\\( -name .git -type d -prune \\) \\\n+\t\t-o \\( -name '[tp][0-9][0-9][0-9][0-9]*' -prune \\) \\\n+\t\t-o \\( -name contrib -type d -prune \\) \\\n+\t\t-o \\( -name build -type d -prune \\) \\\n+\t\t-o \\( -name 'trash*' -type d -prune \\) \\\n+\t\t-o \\( -name '*.[hcS]' -type f -print \\) \\\n+\t\t-o \\( -name '*.sh' -type f -print \\) \\\n+\t\t| sed -e 's|^\\./||' \\\n+\t)\n+FOUND_SOURCE_FILES := $(shell $(SOURCES_CMD))\n+\n+FOUND_C_SOURCES = $(filter %.c,$(FOUND_SOURCE_FILES))\n+FOUND_H_SOURCES = $(filter %.h,$(FOUND_SOURCE_FILES))\n+\n+COCCI_SOURCES = $(filter-out $(THIRD_PARTY_SOURCES),$(FOUND_C_SOURCES))\n+\n+LIB_H = $(FOUND_H_SOURCES)\n \n LIB_OBJS += abspath.o\n LIB_OBJS += add-interactive.o\n@@ -2660,26 +2681,6 @@ perl/build/man/man3/Git.3pm: perl/Git.pm\n \t$(call mkdir_p_parent_template)\n \t$(QUIET_GEN)pod2man $< $@\n \n-FIND_SOURCE_FILES = ( \\\n-\tgit ls-files \\\n-\t\t'*.[hcS]' \\\n-\t\t'*.sh' \\\n-\t\t':!*[tp][0-9][0-9][0-9][0-9]*' \\\n-\t\t':!contrib' \\\n-\t\t2>/dev/null || \\\n-\t$(FIND) . \\\n-\t\t\\( -name .git -type d -prune \\) \\\n-\t\t-o \\( -name '[tp][0-9][0-9][0-9][0-9]*' -prune \\) \\\n-\t\t-o \\( -name contrib -type d -prune \\) \\\n-\t\t-o \\( -name build -type d -prune \\) \\\n-\t\t-o \\( -name 'trash*' -type d -prune \\) \\\n-\t\t-o \\( -name '*.[hcS]' -type f -print \\) \\\n-\t\t-o \\( -name '*.sh' -type f -print \\) \\\n-\t\t| sed -e 's|^\\./||' \\\n-\t)\n-\n-FOUND_SOURCE_FILES = $(shell $(FIND_SOURCE_FILES))\n-\n $(ETAGS_TARGET): $(FOUND_SOURCE_FILES)\n \t$(QUIET_GEN)$(RM) $@+ && \\\n \techo $(FOUND_SOURCE_FILES) | xargs etags -a -o $@+ && \\\n@@ -2859,9 +2860,6 @@ check: $(GENERATED_H)\n \t\texit 1; \\\n \tfi\n \n-FOUND_C_SOURCES = $(filter %.c,$(FOUND_SOURCE_FILES))\n-COCCI_SOURCES = $(filter-out $(THIRD_PARTY_SOURCES),$(FOUND_C_SOURCES))\n-\n %.cocci.patch: %.cocci $(COCCI_SOURCES)\n \t$(QUIET_SPATCH) \\\n \tif test $(SPATCH_BATCH_SIZE) = 0; then \\\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441466","messageId":"patch-v4-23.23-48a3927d972-20211117T101807Z-avarab@gmail.com","threadId":"56852","inReplyTo":"cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com","subject":"[PATCH v4 23/23] Makefile: move \".SUFFIXES\" rule to shared.mak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T10:20:22Z","receivedAt":"2021-11-17T10:21:24Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This was added in 30248886ce8 (Makefile: disable default implicit\nrules, 2010-01-26), let's move it to the top of \"shared.mak\" so it'll\napply to all our Makefiles.\n\nThis doesn't benefit the main Makefile at all, since it already had\nthe rule, but since we're including shared.mak in other Makefiles\nstarts to benefit them. E.g. running the 'man\" target is now ~1.3x\nfaster:\n\n    $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make -j8 -C Documentation man' 'make -C Documentation man' --warmup 10 -M 10\n    Benchmark 1: make -C Documentation man' in 'HEAD~1\n      Time (mean ± σ):      87.2 ms ±   1.0 ms    [User: 79.3 ms, System: 10.8 ms]\n      Range (min … max):    86.3 ms …  89.7 ms    10 runs\n\n    Benchmark 2: make -C Documentation man' in 'HEAD~0\n      Time (mean ± σ):      64.5 ms ±   0.6 ms    [User: 54.5 ms, System: 13.0 ms]\n      Range (min … max):    63.8 ms …  65.7 ms    10 runs\n\n    Summary\n      'make -C Documentation man' in 'HEAD~0' ran\n        1.35 ± 0.02 times faster than 'make -C Documentation man' in 'HEAD~1'\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Makefile   | 2 --\n shared.mak | 5 +++++\n 2 files changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex eb1c944787b..035573c8997 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2459,8 +2459,6 @@ ASM_SRC := $(wildcard $(OBJECTS:o=S))\n ASM_OBJ := $(ASM_SRC:S=o)\n C_OBJ := $(filter-out $(ASM_OBJ),$(OBJECTS))\n \n-.SUFFIXES:\n-\n $(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)\n \t$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<\n $(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)\ndiff --git a/shared.mak b/shared.mak\nindex 20109e6a90e..d8453bb471f 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -9,6 +9,11 @@\n %:: s.%\n %:: SCCS/s.%\n \n+## Likewise delete default $(SUFFIXES). See:\n+##\n+##     info make --index-search=.DELETE_ON_ERROR\n+.SUFFIXES:\n+\n ### Flags affecting all rules\n \n # A GNU make extension since gmake 3.72 (released in late 1994) to\n-- \n2.34.0.796.g2c87ed6146a\n\n"},{"id":"441477","messageId":"211117.86k0h76lcy.gmgdl@evledraar.gmail.com","threadId":"56852","inReplyTo":"20211117093947.ifkrvddmiiu3hg2v@glandium.org","subject":"Re: [PATCH v3 18/23] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-17T11:52:11Z","receivedAt":"2021-11-17T12:02:41Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Nov 17 2021, Mike Hommey wrote:\n\n> On Wed, Nov 17, 2021 at 10:26:27AM +0100, Ævar Arnfjörð Bjarmason wrote:\n>> \n>> On Wed, Nov 17 2021, Mike Hommey wrote:\n>> \n>> > On Tue, Nov 16, 2021 at 01:00:18PM +0100, Ævar Arnfjörð Bjarmason wrote:\n>> >> Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\n>> >> for us, and use it for the \"make lint-docs\" targets I added in\n>> >> 8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n>> >> \n>> >> As seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\n>> >> dependency, 2021-10-26) maintaining these manual lists of parent\n>> >> directory dependencies is fragile, in addition to being obviously\n>> >> verbose.\n>> >> \n>> >> I used this pattern at the time because I couldn't find another method\n>> >> than \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\n>> >> every file being created, which as noted in [1] would be significantly\n>> >> slower.\n>> >> \n>> >> But as it turns out we can use this neat trick of only doing a \"mkdir\n>> >> -p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\n>> >> of a performance test similar to thatnoted downthread of [1] in [2]\n>> >> shows that this is faster, in addition to being less verbose and more\n>> >> reliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n>> >> \n>> >>     $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n>> >>     Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n>> >>       Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n>> >>       Range (min … max):    2.121 s …  2.158 s    10 runs\n>> >> \n>> >>     Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n>> >>       Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n>> >>       Range (min … max):    2.657 s …  2.662 s    10 runs\n>> >> \n>> >>     Summary\n>> >>       'make -C Documentation lint-docs' in 'HEAD~0' ran\n>> >>         1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n>> >> \n>> >> So let's use that pattern both for the \"lint-docs\" target, and a few\n>> >> miscellaneous other targets.\n>> >> \n>> >> This method of creating parent directories is explicitly racy in that\n>> >> we don't know if we're going to say always create a \"foo\" followed by\n>> >> a \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n>> >> \"foo/bar\" first. In this case it doesn't matter for anything except\n>> >> that we aren't guaranteed to get the same number of rules firing when\n>> >> running make in parallel.\n>> >\n>> > Something else that is racy is that $(wildcard) might be saying the\n>> > directory doesn't exist while there's another make subprocess that has\n>> > already started spawning `mkdir -p` for that directory.\n>> > That doesn't make a huge difference, but you can probably still end up\n>> > with multiple `mkdir -p` runs for the same directory.\n>> >\n>> > I think something like the following could work while avoiding those\n>> > races:\n>> >\n>> > define create_parent_dir_RULE\n>> > $(1): | $(dir $(1)).\n>> > ALL_DIRS += $(dir $(1))\n>> > endef\n>> >\n>> > define create_parent_dir_TARGET\n>> > $(1)/.: $(dir $(1)).\n>> > \techo mkdir $$(@D)\n>\n> erf, s/echo //\n>\n>> > endef\n>> >\n>> > $(eval $(call create_parent_dir_RULE, first/path/file))\n>> > $(eval $(call create_parent_dir_RULE, second/path/file))\n>> > # ...\n>> >\n>> > $(foreach dir,$(sort $(ALL_DIRS)),$(eval $(call create_parent_dir_TARGET,$(dir:%/=%))))\n>> \n>> I think the \"race\" just isn't a problem, and makes managing this much\n>> simpler.\n>> \n>> I.e. we already rely on \"mkdir -p\" not failing on an existing directory,\n>> so the case where we redundantly try to create a directory that just got\n>> created by a concurrent process is OK, and as the quoted benchmark shows\n>> is much faster than a similar (but not quite the same as) a\n>> dependency-based implementaiton.\n>> \n>> I haven't implemented your solution, but it seems to be inherently more\n>> complex.\n>> \n>> I.e. with the one I've got you just stick the \"mkdir if needed\"\n>> one-liner in each rule, with yours you'll need to accumulate things in\n>> ALL_DIRS, and have some foreach somewhere or dependency relationship to\n>> create those beforehand if they're nested, no?\n>\n> For each rule, it would also be a oneliner to add above the rule. The rest\n> would be a prelude and a an epilogue to stick somewhere in the Makefile.\n\nHow would that epilogue know to handle cases where we're running \"clean\"\nor whatever thing doesn't want to create the full set of directories\nwe've accumulated in ALL_DIRS while parsing the Makefile?\n\nWon't that require extensive use of the same sort of MAKECMDGOALS\ntrickery I added for one target in 8cc804d0abf (doc build: speed up\n\"make lint-docs\", 2021-10-15)?\n\nI can imagine how we /could/ get that to work, but so far I just dont's\nsee the point. The wildcard trick I'm proposing here seems to be the\nbest of both worlds, it's both faster than anything else I've come up\nwith or seen, and requires zero management outside the rule itself.\n\nAlso, only the lint-docs rule I'm modifying here went to any trouble to\navoid redundant \"mkdir\" calls at all, the rest are all doing a \"mkdir\nparent-dir\" every single time. So as far as any edge cases with these\nrules tripping over one another are concerned I think we're already\nhandling that.\n\nWell, I suppose *theoretically* not, because I'm assuming that we only\never run the equivalent of \"make all\" or \"make clean && make all\" and\nnot \"make -jN clean all\".\n\nBut while it's possible to get a Makefile working that can clean and\nbuild things in parallel in practice nobody does that, and ours\ndoesn't. If you try that it'll fail right away on some bad dependency\n(which we both just generated and rm -rf'd).\n"},{"id":"441540","messageId":"20211118000002.wykfbk3qtlt46ab7@glandium.org","threadId":"56852","inReplyTo":"211117.86k0h76lcy.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v3 18/23] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2021-11-18T00:00:02Z","receivedAt":"2021-11-18T00:00:30Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Wed, Nov 17, 2021 at 12:52:11PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> \n> On Wed, Nov 17 2021, Mike Hommey wrote:\n> \n> > On Wed, Nov 17, 2021 at 10:26:27AM +0100, Ævar Arnfjörð Bjarmason wrote:\n> >> \n> >> On Wed, Nov 17 2021, Mike Hommey wrote:\n> >> \n> >> > On Tue, Nov 16, 2021 at 01:00:18PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> >> >> Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\n> >> >> for us, and use it for the \"make lint-docs\" targets I added in\n> >> >> 8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n> >> >> \n> >> >> As seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\n> >> >> dependency, 2021-10-26) maintaining these manual lists of parent\n> >> >> directory dependencies is fragile, in addition to being obviously\n> >> >> verbose.\n> >> >> \n> >> >> I used this pattern at the time because I couldn't find another method\n> >> >> than \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\n> >> >> every file being created, which as noted in [1] would be significantly\n> >> >> slower.\n> >> >> \n> >> >> But as it turns out we can use this neat trick of only doing a \"mkdir\n> >> >> -p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\n> >> >> of a performance test similar to thatnoted downthread of [1] in [2]\n> >> >> shows that this is faster, in addition to being less verbose and more\n> >> >> reliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n> >> >> \n> >> >>     $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n> >> >>     Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n> >> >>       Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n> >> >>       Range (min … max):    2.121 s …  2.158 s    10 runs\n> >> >> \n> >> >>     Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n> >> >>       Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n> >> >>       Range (min … max):    2.657 s …  2.662 s    10 runs\n> >> >> \n> >> >>     Summary\n> >> >>       'make -C Documentation lint-docs' in 'HEAD~0' ran\n> >> >>         1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n> >> >> \n> >> >> So let's use that pattern both for the \"lint-docs\" target, and a few\n> >> >> miscellaneous other targets.\n> >> >> \n> >> >> This method of creating parent directories is explicitly racy in that\n> >> >> we don't know if we're going to say always create a \"foo\" followed by\n> >> >> a \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n> >> >> \"foo/bar\" first. In this case it doesn't matter for anything except\n> >> >> that we aren't guaranteed to get the same number of rules firing when\n> >> >> running make in parallel.\n> >> >\n> >> > Something else that is racy is that $(wildcard) might be saying the\n> >> > directory doesn't exist while there's another make subprocess that has\n> >> > already started spawning `mkdir -p` for that directory.\n> >> > That doesn't make a huge difference, but you can probably still end up\n> >> > with multiple `mkdir -p` runs for the same directory.\n> >> >\n> >> > I think something like the following could work while avoiding those\n> >> > races:\n> >> >\n> >> > define create_parent_dir_RULE\n> >> > $(1): | $(dir $(1)).\n> >> > ALL_DIRS += $(dir $(1))\n> >> > endef\n> >> >\n> >> > define create_parent_dir_TARGET\n> >> > $(1)/.: $(dir $(1)).\n> >> > \techo mkdir $$(@D)\n> >\n> > erf, s/echo //\n> >\n> >> > endef\n> >> >\n> >> > $(eval $(call create_parent_dir_RULE, first/path/file))\n> >> > $(eval $(call create_parent_dir_RULE, second/path/file))\n> >> > # ...\n> >> >\n> >> > $(foreach dir,$(sort $(ALL_DIRS)),$(eval $(call create_parent_dir_TARGET,$(dir:%/=%))))\n> >> \n> >> I think the \"race\" just isn't a problem, and makes managing this much\n> >> simpler.\n> >> \n> >> I.e. we already rely on \"mkdir -p\" not failing on an existing directory,\n> >> so the case where we redundantly try to create a directory that just got\n> >> created by a concurrent process is OK, and as the quoted benchmark shows\n> >> is much faster than a similar (but not quite the same as) a\n> >> dependency-based implementaiton.\n> >> \n> >> I haven't implemented your solution, but it seems to be inherently more\n> >> complex.\n> >> \n> >> I.e. with the one I've got you just stick the \"mkdir if needed\"\n> >> one-liner in each rule, with yours you'll need to accumulate things in\n> >> ALL_DIRS, and have some foreach somewhere or dependency relationship to\n> >> create those beforehand if they're nested, no?\n> >\n> > For each rule, it would also be a oneliner to add above the rule. The rest\n> > would be a prelude and a an epilogue to stick somewhere in the Makefile.\n> \n> How would that epilogue know to handle cases where we're running \"clean\"\n> or whatever thing doesn't want to create the full set of directories\n> we've accumulated in ALL_DIRS while parsing the Makefile?\n\nThe epilogue only adds rules like:\n\ndir/subdir/.: dir/.\n\tmkdir $(@D)\n\nAs long as those \"clean\" or whatever rules don't depend on those,\nnothing will happen.\n"},{"id":"441603","messageId":"211118.868rxl61rt.gmgdl@evledraar.gmail.com","threadId":"56852","inReplyTo":"20211118000002.wykfbk3qtlt46ab7@glandium.org","subject":"Re: [PATCH v3 18/23] Makefiles: add and use wildcard \"mkdir -p\" template","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-18T13:05:48Z","receivedAt":"2021-11-18T13:18:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Nov 18 2021, Mike Hommey wrote:\n\n> On Wed, Nov 17, 2021 at 12:52:11PM +0100, Ævar Arnfjörð Bjarmason wrote:\n>> \n>> On Wed, Nov 17 2021, Mike Hommey wrote:\n>> \n>> > On Wed, Nov 17, 2021 at 10:26:27AM +0100, Ævar Arnfjörð Bjarmason wrote:\n>> >> \n>> >> On Wed, Nov 17 2021, Mike Hommey wrote:\n>> >> \n>> >> > On Tue, Nov 16, 2021 at 01:00:18PM +0100, Ævar Arnfjörð Bjarmason wrote:\n>> >> >> Add a template to do the \"mkdir -p\" of $(@D) (the parent dir of $@)\n>> >> >> for us, and use it for the \"make lint-docs\" targets I added in\n>> >> >> 8650c6298c1 (doc lint: make \"lint-docs\" non-.PHONY, 2021-10-15).\n>> >> >> \n>> >> >> As seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir\n>> >> >> dependency, 2021-10-26) maintaining these manual lists of parent\n>> >> >> directory dependencies is fragile, in addition to being obviously\n>> >> >> verbose.\n>> >> >> \n>> >> >> I used this pattern at the time because I couldn't find another method\n>> >> >> than \"order-only\" prerequisites to avoid doing a \"mkdir -p $(@D)\" for\n>> >> >> every file being created, which as noted in [1] would be significantly\n>> >> >> slower.\n>> >> >> \n>> >> >> But as it turns out we can use this neat trick of only doing a \"mkdir\n>> >> >> -p\" if the $(wildcard) macro tells us the path doesn't exist. A re-run\n>> >> >> of a performance test similar to thatnoted downthread of [1] in [2]\n>> >> >> shows that this is faster, in addition to being less verbose and more\n>> >> >> reliable (this uses my \"git-hyperfine\" thin wrapper for \"hyperfine\"[3]):\n>> >> >> \n>> >> >>     $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'\n>> >> >>     Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0\n>> >> >>       Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]\n>> >> >>       Range (min … max):    2.121 s …  2.158 s    10 runs\n>> >> >> \n>> >> >>     Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1\n>> >> >>       Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]\n>> >> >>       Range (min … max):    2.657 s …  2.662 s    10 runs\n>> >> >> \n>> >> >>     Summary\n>> >> >>       'make -C Documentation lint-docs' in 'HEAD~0' ran\n>> >> >>         1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'\n>> >> >> \n>> >> >> So let's use that pattern both for the \"lint-docs\" target, and a few\n>> >> >> miscellaneous other targets.\n>> >> >> \n>> >> >> This method of creating parent directories is explicitly racy in that\n>> >> >> we don't know if we're going to say always create a \"foo\" followed by\n>> >> >> a \"foo/bar\" under parallelism, or skip the \"foo\" because we created\n>> >> >> \"foo/bar\" first. In this case it doesn't matter for anything except\n>> >> >> that we aren't guaranteed to get the same number of rules firing when\n>> >> >> running make in parallel.\n>> >> >\n>> >> > Something else that is racy is that $(wildcard) might be saying the\n>> >> > directory doesn't exist while there's another make subprocess that has\n>> >> > already started spawning `mkdir -p` for that directory.\n>> >> > That doesn't make a huge difference, but you can probably still end up\n>> >> > with multiple `mkdir -p` runs for the same directory.\n>> >> >\n>> >> > I think something like the following could work while avoiding those\n>> >> > races:\n>> >> >\n>> >> > define create_parent_dir_RULE\n>> >> > $(1): | $(dir $(1)).\n>> >> > ALL_DIRS += $(dir $(1))\n>> >> > endef\n>> >> >\n>> >> > define create_parent_dir_TARGET\n>> >> > $(1)/.: $(dir $(1)).\n>> >> > \techo mkdir $$(@D)\n>> >\n>> > erf, s/echo //\n>> >\n>> >> > endef\n>> >> >\n>> >> > $(eval $(call create_parent_dir_RULE, first/path/file))\n>> >> > $(eval $(call create_parent_dir_RULE, second/path/file))\n>> >> > # ...\n>> >> >\n>> >> > $(foreach dir,$(sort $(ALL_DIRS)),$(eval $(call create_parent_dir_TARGET,$(dir:%/=%))))\n>> >> \n>> >> I think the \"race\" just isn't a problem, and makes managing this much\n>> >> simpler.\n>> >> \n>> >> I.e. we already rely on \"mkdir -p\" not failing on an existing directory,\n>> >> so the case where we redundantly try to create a directory that just got\n>> >> created by a concurrent process is OK, and as the quoted benchmark shows\n>> >> is much faster than a similar (but not quite the same as) a\n>> >> dependency-based implementaiton.\n>> >> \n>> >> I haven't implemented your solution, but it seems to be inherently more\n>> >> complex.\n>> >> \n>> >> I.e. with the one I've got you just stick the \"mkdir if needed\"\n>> >> one-liner in each rule, with yours you'll need to accumulate things in\n>> >> ALL_DIRS, and have some foreach somewhere or dependency relationship to\n>> >> create those beforehand if they're nested, no?\n>> >\n>> > For each rule, it would also be a oneliner to add above the rule. The rest\n>> > would be a prelude and a an epilogue to stick somewhere in the Makefile.\n>> \n>> How would that epilogue know to handle cases where we're running \"clean\"\n>> or whatever thing doesn't want to create the full set of directories\n>> we've accumulated in ALL_DIRS while parsing the Makefile?\n>\n> The epilogue only adds rules like:\n>\n> dir/subdir/.: dir/.\n> \tmkdir $(@D)\n>\n> As long as those \"clean\" or whatever rules don't depend on those,\n> nothing will happen.\n\nAh, I see.\n\nI don't see why why this pattern would be preferrable to the $(wildcard)\nidiom I'm introducing, which doesn't require any boilerplate at all.\n\nWe've got that in snippet form on the one hand, and then my working\npatch. I haven't tried to implement what you suggested, but don't see\nhow it wouldn't be the same thing speed-wise as the explicitly\nenumerated dependiencies I replaced for the lint-docs target.\n\nSo unless there's something broken etc. about that approach I think we\nshould go forward with it.\n\n"},{"id":"441695","messageId":"xmqqbl2gskxm.fsf@gitster.g","threadId":"56852","inReplyTo":"patch-v4-15.23-337953e4994-20211117T101807Z-avarab@gmail.com","subject":"Re: [PATCH v4 15/23] Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-11-19T06:45:25Z","receivedAt":"2021-11-19T06:45:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> @@ -2238,12 +2235,7 @@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\\\n>  \t$(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n>  \t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(PAGER_ENV):\\\n>  \t$(perllibdir_SQ)\n> -GIT-SCRIPT-DEFINES: FORCE\n> -\t@FLAGS='$(SCRIPT_DEFINES)'; \\\n> -\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n> -\t\techo >&2 \"    * new script parameters\"; \\\n> -\t\techo \"$$FLAGS\" >$@; \\\n> -            fi\n> +$(eval $(call TRACK_template,GIT-SCRIPT-DEFINES,SCRIPT_DEFINES))\n>  \n>  define cmd_munge_script\n>  sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n\nAttempting to apply 1-14 on top of 'master' gets stuck here, as\n\"GIT-SCRIPT-DEFINES: FORCE\" appears after \"define cmd_munge_script\".\n\nAre you basing these patches on some unrelated work?\n\n\n"},{"id":"441696","messageId":"xmqq7dd4sket.fsf@gitster.g","threadId":"56852","inReplyTo":"xmqqbl2gskxm.fsf@gitster.g","subject":"Re: [PATCH v4 15/23] Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-11-19T06:56:42Z","receivedAt":"2021-11-19T06:56:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> @@ -2238,12 +2235,7 @@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\\\n>>  \t$(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n>>  \t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(PAGER_ENV):\\\n>>  \t$(perllibdir_SQ)\n>> -GIT-SCRIPT-DEFINES: FORCE\n>> -\t@FLAGS='$(SCRIPT_DEFINES)'; \\\n>> -\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n>> -\t\techo >&2 \"    * new script parameters\"; \\\n>> -\t\techo \"$$FLAGS\" >$@; \\\n>> -            fi\n>> +$(eval $(call TRACK_template,GIT-SCRIPT-DEFINES,SCRIPT_DEFINES))\n>>  \n>>  define cmd_munge_script\n>>  sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n>\n> Attempting to apply 1-14 on top of 'master' gets stuck here, as\n> \"GIT-SCRIPT-DEFINES: FORCE\" appears after \"define cmd_munge_script\".\n>\n> Are you basing these patches on some unrelated work?\n\nAh, I figured it out.  This wants to be applied after the\nab/sh-retire-helper-functions topic graduates to 'master'.\n\n"},{"id":"441704","messageId":"211119.86a6i04n36.gmgdl@evledraar.gmail.com","threadId":"56852","inReplyTo":"xmqq7dd4sket.fsf@gitster.g","subject":"Re: [PATCH v4 15/23] Makefile: add a \"TRACK_template\" for GIT-*{FLAGS,DEFINES,...}","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-11-19T07:30:55Z","receivedAt":"2021-11-19T07:32:50Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Nov 18 2021, Junio C Hamano wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>>\n>>> @@ -2238,12 +2235,7 @@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\\\n>>>  \t$(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n>>>  \t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(PAGER_ENV):\\\n>>>  \t$(perllibdir_SQ)\n>>> -GIT-SCRIPT-DEFINES: FORCE\n>>> -\t@FLAGS='$(SCRIPT_DEFINES)'; \\\n>>> -\t    if test x\"$$FLAGS\" != x\"`cat $@ 2>/dev/null`\" ; then \\\n>>> -\t\techo >&2 \"    * new script parameters\"; \\\n>>> -\t\techo \"$$FLAGS\" >$@; \\\n>>> -            fi\n>>> +$(eval $(call TRACK_template,GIT-SCRIPT-DEFINES,SCRIPT_DEFINES))\n>>>  \n>>>  define cmd_munge_script\n>>>  sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n>>\n>> Attempting to apply 1-14 on top of 'master' gets stuck here, as\n>> \"GIT-SCRIPT-DEFINES: FORCE\" appears after \"define cmd_munge_script\".\n>>\n>> Are you basing these patches on some unrelated work?\n>\n> Ah, I figured it out.  This wants to be applied after the\n> ab/sh-retire-helper-functions topic graduates to 'master'.\n\nIt is noted in the v1..v3 cover letter of this series that it needs to\nbe on top of ab/sh-retire-helper-functions.\n\nBut I omitted it from the v4 by mistake. Sorry about wasting your time\non finding that out as a result, it really should have been noted there.\n"},{"id":"444050","messageId":"xmqq4k7c9k68.fsf@gitster.g","threadId":"56852","inReplyTo":"patch-v4-14.23-13cbb851d32-20211117T101807Z-avarab@gmail.com","subject":"Re: [PATCH v4 14/23] Makefile: re-add and use the \"shellquote\" macros","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-12-13T23:09:19Z","receivedAt":"2021-12-13T23:09:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Re-add and use, and expand on \"shellquote\" macros added in\n> 4769948afe7 (Deal with $(bindir) and friends with whitespaces.,\n> 2005-10-10).\n>\n> We avoided using them due to the \"$(call)\" feature of GNU make being\n> relatively new at the time, but it isn't anymore. We hard depend on\n> GNU make versions that have it.\n>\n> The use of \"$(call)\" was removed in 39c015c556f (Fixes for ancient\n> versions of GNU make, 2006-02-18) and 7ffe7098dca (Fix installation of\n> templates on ancient systems., 2006-07-29) due to those\n> incompatibilities with older GNU make versions, and we've used the\n> more verbose *_SQ pattern ever since.\n>\n> The \"$(call)\" feature was introduced in GNU make version 3.78,\n> released on the 22nd of September, 1999. That release also introduced\n> \"$(error)\" and \"$(warning)\", which we've been making use of since\n> f2fabbf76e4 (Teach Makefile to check header dependencies, 2010-01-26).\n>\n> This extends upon the macros added in 4769948afe7: We now have macros\n> for quoting a ' inside '', and a ' with no surrounding '' as before.\n>\n> Additionally provide and use a \"shelldquote\" macro along with\n> \"shellquote\" for the common case of wanting to quote a C string we\n> pass to the compiler with a -D flag.\n>\n> This doesn't get rid of all of our shell quoting. We've still got some\n> in the main Makefile, let's leave most of it to avoid in-flight\n> conflicts. I've fully converted \"templates/Makefile\" and \"t/Makefile\"\n> though.\n\nAll of the above may very well explain why we decided not to use\n$(call shellquote) in the past, and it may also explain why it is\nsafe to start using it again today, but it does not explain why we\nwant to do so in the first place.\n\nHaving to write\n\n\t$(call shellquote,$(VAR))\n\nin longhand is much more cumbersome to read, write and merge than\ndefining a prepackaged VAR_SQ just once and refer it as\n\n\t'$(VAR_SQ)'\n\neverywhere.\n\nIn fact, having to resolve merge conflicts in t/Makefile today,\nwhich wouldn't have been necessary if we didn't have this change,\nfelt like a makework to me, and my time would have been better spent\nelsewhere [*].\n\nIs there a justification other than \"this uses a feature supported\nby newer GNUMake\" we can give to future readers of the log message?\nWhy do we want to make this change?\n\nIt may be that this patch was particularly unlucky to collide with\nsomething else to irritate me, and the above comment may apply to\nother patches we saw recently on the list (and they are lucky that\nthey did not collide with anything not yet in 'master').  \n\nIn any case, I am wondering if we see too much churn without much\nreal benefit X-<.\n\nHere is a sample of the damage.  Look how long the lines that use\n_SQ twice have become.\n\n clean-chainlint:\n-\t$(RM) -r '$(CHAINLINTTMP_SQ)'\n+\t$(RM) -r $(call shellquote,$(CHAINLINTTMP))\n \n check-chainlint:\n-\t@mkdir -p '$(CHAINLINTTMP_SQ)' && \\\n-\tsed -e '/^# LINT: /d' $(patsubst %,chainlint/%.test,$(CHAINLINTTESTS)) >'$(CHAINLINTTMP_SQ)'/tests && \\\n-\tsed -e '/^[ \t]*$$/d' $(patsubst %,chainlint/%.expect,$(CHAINLINTTESTS)) >'$(CHAINLINTTMP_SQ)'/expect && \\\n-\t$(CHAINLINT) '$(CHAINLINTTMP_SQ)'/tests | grep -v '^[\t]*$$' >'$(CHAINLINTTMP_SQ)'/actual && \\\n-\tdiff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual\n+\t@mkdir -p $(call shellquote,$(CHAINLINTTMP)) && \\\n+\tsed -e '/^# LINT: /d' $(patsubst %,chainlint/%.test,$(CHAINLINTTESTS)) >$(call shellquote,$(CHAINLINTTMP))/tests && \\\n+\tsed -e '/^[ \t]*$$/d' $(patsubst %,chainlint/%.expect,$(CHAINLINTTESTS)) >$(call shellquote,$(CHAINLINTTMP))/expect && \\\n+\t$(CHAINLINT) $(call shellquote,$(CHAINLINTTMP))/tests | grep -v '^[\t]*$$' >$(call shellquote,$(CHAINLINTTMP))/actual && \\\n+\tdiff -u $(call shellquote,$(CHAINLINTTMP))/expect $(call shellquote,$(CHAINLINTTMP))/actual\n"},{"id":"444055","messageId":"xmqqr1ag81tm.fsf@gitster.g","threadId":"56852","inReplyTo":"xmqq4k7c9k68.fsf@gitster.g","subject":"Re: [PATCH v4 14/23] Makefile: re-add and use the \"shellquote\" macros","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-12-14T00:31:01Z","receivedAt":"2021-12-14T00:31:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> All of the above may very well explain why we decided not to use\n> $(call shellquote) in the past, and it may also explain why it is\n> safe to start using it again today, but it does not explain why we\n> want to do so in the first place.\n>\n> Having to write\n>\n> \t$(call shellquote,$(VAR))\n>\n> in longhand is much more cumbersome to read, write and merge than\n> defining a prepackaged VAR_SQ just once and refer it as\n>\n> \t'$(VAR_SQ)'\n>\n> everywhere.\n\nHaving said all that, I would not have minded if this change were\nmore isolated and turned things like\n\nCHAINLINTTMP_SQ = $(subst ','\\'',$(CHAINLINTTMP))\n\nto use the $(call shellquote) mechanism, if all of us found it\neasier to read than repeating the same line-noise substitutions for\nmany variables.\n\nWhat was irritating was primarily that the patch went one step\nfurther to eliminate the _SQ variant variables, making the resulting\nsites that use them harder to read and understand.\n\n"}]}