All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] Makefile: optimize noop runs, add shared.mak
@ 2021-12-17  1:39 Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 1/8] Makefiles: add "shared.mak", move ".DELETE_ON_ERROR" to it Ævar Arnfjörð Bjarmason
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-17  1:39 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques, Eric Wong,
	Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye,
	Ævar Arnfjörð Bjarmason

This topic is split-up from v4 of ab/make-dependency[1], and is the
last topic I've split up from that which I'll submit before the
outstanding ones land.

This speeds up noop runs of "make" by a lot. After a "make" running a
"make -j1" with this is ~1.5 faster than on "master"[2], and around 3x
as fast with "make -j1 NO_TCLTK=Y" (the TCL part takes a lot of time,
but that's another matter).

As shown in 8/8 the only meaningful change to existing Makefile rules
makes things simpler, while making them much faster. In 3/8 a rather
trivial change to use ":=" instead of "=" for a "$(shell)" assignment
likewise speeds things up.

The "shared.mak" introduced while getting to 8/8 will then be used by
follow-on topics to make introducing shared behavior (particularly via
$(call), which we can now rely on) easier.

The range-diff to [1] shows changes from that topic. Most of them are
from pulling this topic out of those larger changes. I also re-ran all
the benchmarks & updated those in the commit messages.

1. https://lore.kernel.org/git/cover-v4-00.23-00000000000-20211117T101807Z-avarab@gmail.com/
2. $ git -c hyperfine.hook.setup= hyperfine -L rev origin/master,HEAD~0 -s 'make' 'make -j1' --warmup 1
   Benchmark 1: make -j1' in 'origin/master
     Time (mean ± σ):     563.1 ms ±  14.5 ms    [User: 453.3 ms, System: 117.6 ms]
     Range (min … max):   542.7 ms … 595.0 ms    10 runs

   Benchmark 2: make -j1' in 'HEAD~0
     Time (mean ± σ):     362.5 ms ±   4.5 ms    [User: 299.7 ms, System: 73.9 ms]
     Range (min … max):   356.9 ms … 369.4 ms    10 runs

   Summary
     'make -j1' in 'HEAD~0' ran
       1.55 ± 0.04 times faster than 'make -j1' in 'origin/master'
3. git -c hyperfine.hook.setup= hyperfine -L rev origin/master,HEAD~0 -s 'make' 'make -j1 NO_TCLTK=Y' --warmup 1
   Benchmark 1: make -j1 NO_TCLTK=Y' in 'origin/master
     Time (mean ± σ):     291.1 ms ±  24.1 ms    [User: 225.6 ms, System: 68.9 ms]
     Range (min … max):   275.0 ms … 353.9 ms    10 runs

   Benchmark 2: make -j1 NO_TCLTK=Y' in 'HEAD~0
     Time (mean ± σ):      95.8 ms ±   0.7 ms    [User: 81.9 ms, System: 18.1 ms]
     Range (min … max):    94.8 ms …  98.4 ms    31 runs

   Summary
     'make -j1 NO_TCLTK=Y' in 'HEAD~0' ran
       3.04 ± 0.25 times faster than 'make -j1 NO_TCLTK=Y' in 'origin/master'

Ævar Arnfjörð Bjarmason (8):
  Makefiles: add "shared.mak", move ".DELETE_ON_ERROR" to it
  Makefile: disable GNU make built-in wildcard rules
  Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES)
  Makefile: move ".SUFFIXES" rule to shared.mak
  Makefile: move $(comma), $(empty) and $(space) to shared.mak
  Makefile: add "$(QUIET)" boilerplate to shared.mak
  Makefile: use $(wspfx) for $(QUIET...) in shared.mak
  Makefiles: add and use wildcard "mkdir -p" template

 Documentation/Makefile |  63 +++-------------------
 Makefile               | 118 +++++++++++++----------------------------
 config.mak.uname       |   1 -
 shared.mak             | 109 +++++++++++++++++++++++++++++++++++++
 t/Makefile             |   3 ++
 t/interop/Makefile     |   3 ++
 templates/Makefile     |   8 ++-
 7 files changed, 160 insertions(+), 145 deletions(-)
 create mode 100644 shared.mak

Range-diff:
 1:  1621ca72c1d <  -:  ----------- Makefile: don't invoke msgfmt with --statistics
 2:  b7c36c9fea0 <  -:  ----------- Makefile: don't set up "perl/build" rules under NO_PERL=Y
 3:  29b000eb0f1 <  -:  ----------- Makefile: use "=" not ":=" for po/* and perl/*
 4:  daead5ec293 <  -:  ----------- Makefile: clean perl/build/ even with NO_PERL=Y
 5:  3c987590740 <  -:  ----------- Makefile: remove "mv $@ $@+" dance redundant to .DELETE_ON_ERROR
 6:  b57f582ccd3 <  -:  ----------- Makefile: guard Perl-only variable assignments
 7:  fcdee92f64c <  -:  ----------- Makefile: change "ifndef NO_PERL" to "ifdef NO_PERL"
 8:  1e25b532ca2 <  -:  ----------- Makefile: adjust Perl-related comments & whitespace
 9:  77d9855bfcf <  -:  ----------- Makefile: correct "GIT-PERL-{DEFINES,HEADER}" dependency graph
10:  6004cdcd8d9 <  -:  ----------- Makefile: create a GIT-PYTHON-DEFINES, like "PERL"
11:  17b30e96057 <  -:  ----------- Makefile: stop needing @@GIT_VERSION@@ in *.perl scripts
12:  30ddf7da2c8 !  1:  f74b47662b7 Makefiles: add "shared.mak", move ".DELETE_ON_ERROR" to it
    @@ shared.mak (new)
     +#
     +#    info make --index-search=.DELETE_ON_ERROR
     +.DELETE_ON_ERROR:
    +
    + ## t/Makefile ##
    +@@
    ++# Import tree-wide shared Makefile behavior and libraries
    ++include ../shared.mak
    ++
    + # Run tests
    + #
    + # Copyright (c) 2005 Junio C Hamano
    +
    + ## t/interop/Makefile ##
    +@@
    ++# Import tree-wide shared Makefile behavior and libraries
    ++include ../../shared.mak
    ++
    + -include ../../config.mak
    + export GIT_TEST_OPTIONS
    + 
    +
    + ## templates/Makefile ##
    +@@
    ++# Import tree-wide shared Makefile behavior and libraries
    ++include ../shared.mak
    ++
    + # make and install sample templates
    + 
    + ifndef V
21:  dd569a59c74 !  2:  b0c63abe091 Makefile: disable GNU make built-in wildcard rules
    @@ Commit message
         Makefile: disable GNU make built-in wildcard rules
     
         Override built-in rules of GNU make that use a wildcard target. This
    -    speeds things up significantly as we don't need to stat() so many
    -    files just in case we'd be able to retrieve their contents from RCS or
    -    SCCS. See [1] for an old mailing list discussion about how to disable
    -    these.
    -
    -    This gives us a noticeable speedup on a no-op run:
    -
    -        $ git hyperfine -L rev HEAD~1,HEAD~0 -s 'make -j8 all NO_TCLTK=Y' 'make NO_TCLTK=Y' --warmup 10 -M 10
    -        Benchmark 1: make NO_TCLTK=Y' in 'HEAD~1
    -          Time (mean ± σ):     182.2 ms ±   4.1 ms    [User: 146.8 ms, System: 49.5 ms]
    -          Range (min … max):   179.6 ms … 193.4 ms    10 runs
    -
    -        Benchmark 2: make NO_TCLTK=Y' in 'HEAD~0
    -          Time (mean ± σ):     167.9 ms ±   1.3 ms    [User: 127.8 ms, System: 55.6 ms]
    -          Range (min … max):   166.1 ms … 170.4 ms    10 runs
    -
    -        Summary
    -          'make NO_TCLTK=Y' in 'HEAD~0' ran
    -            1.09 ± 0.03 times faster than 'make NO_TCLTK=Y' in 'HEAD~1'
    -
    -    Running the same except with 'strace -c -S calls make' as the
    -    benchmark command shows (under --show-output) that we went from ~7716
    -    syscalls to ~7519, mostly a reduction in [l]stat().
    -
    -    We could also invoke make with "-r" by setting "MAKEFLAGS = -r" early,
    -    adding a "-r" variant to the above benchmark shows that it may be 1.01
    -    or so faster (but in my tests, always with a much bigger error
    -    bar). But doing so is a much bigger hammer, since it will disable all
    -    built-in rules, some (all?) of which can be seen with:
    +    can speeds things up significantly as we don't need to stat() so many
    +    files. GNU make does that by default to see if it can retrieve their
    +    contents from RCS or SCCS. See [1] for an old mailing list discussion
    +    about how to disable these.
    +
    +    The speed-up may wary. I've seen 1-10% depending on the speed of the
    +    local disk, caches, -jN etc. Running:
    +
    +        strace -f -c -S calls make -j1 NO_TCLTK=Y
    +
    +    Shows that we reduce the number of syscalls we make, mostly in "stat"
    +    calls.
    +
    +    We could also invoke make with "-r" by setting "MAKEFLAGS = -r"
    +    early. Doing so might make us a bit faster still. But doing so is a
    +    much bigger hammer, since it will disable all built-in rules,
    +    some (all?) of which can be seen with:
     
             make -f/dev/null -p | grep -v -e ^# -e ^$
     
22:  4168a7e3b30 !  3:  c6c6f7cf8d8 Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES)
    @@ Commit message
     
         This speeds things up a lot:
     
    -        $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make -j8 all NO_TCLTK=Y' 'make NO_TCLTK=Y' --war
    -        mup 10 -M 10
    -        Benchmark 1: make NO_TCLTK=Y' in 'HEAD~1
    -          Time (mean ± σ):      99.5 ms ±   0.5 ms    [User: 83.4 ms, System: 20.7 ms]
    -          Range (min … max):    98.8 ms … 100.2 ms    10 runs
    +        $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make NO_TCLTK=Y' 'make -j1 NO_TCLTK=Y' --warmup 10 -M 10
    +        Benchmark 1: make -j1 NO_TCLTK=Y' in 'HEAD~1
    +          Time (mean ± σ):     159.9 ms ±   6.8 ms    [User: 137.2 ms, System: 28.0 ms]
    +          Range (min … max):   154.6 ms … 175.9 ms    10 runs
     
    -        Benchmark 2: make NO_TCLTK=Y' in 'HEAD~0
    -          Time (mean ± σ):      69.4 ms ±   0.5 ms    [User: 58.8 ms, System: 14.2 ms]
    -          Range (min … max):    68.9 ms …  70.3 ms    10 runs
    +        Benchmark 2: make -j1 NO_TCLTK=Y' in 'HEAD~0
    +          Time (mean ± σ):     100.0 ms ±   1.3 ms    [User: 84.2 ms, System: 20.2 ms]
    +          Range (min … max):    98.8 ms … 102.8 ms    10 runs
     
             Summary
    -          'make NO_TCLTK=Y' in 'HEAD~0' ran
    -            1.43 ± 0.01 times faster than 'make NO_TCLTK=Y' in 'HEAD~1'
    +          'make -j1 NO_TCLTK=Y' in 'HEAD~0' ran
    +            1.60 ± 0.07 times faster than 'make -j1 NO_TCLTK=Y' in 'HEAD~1'
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ Makefile: GENERATED_H += hook-list.h
      LIB_OBJS += abspath.o
      LIB_OBJS += add-interactive.o
     @@ Makefile: perl/build/man/man3/Git.3pm: perl/Git.pm
    - 	$(call mkdir_p_parent_template)
    - 	$(QUIET_GEN)pod2man $< $@
    + 	$(QUIET_GEN)mkdir -p $(dir $@) && \
    + 	pod2man $< $@
      
     -FIND_SOURCE_FILES = ( \
     -	git ls-files \
23:  48a3927d972 !  4:  ed64cd1bd4a Makefile: move ".SUFFIXES" rule to shared.mak
    @@ Commit message
     
         This doesn't benefit the main Makefile at all, since it already had
         the rule, but since we're including shared.mak in other Makefiles
    -    starts to benefit them. E.g. running the 'man" target is now ~1.3x
    -    faster:
    +    starts to benefit them. E.g. running the 'man" target is now faster:
     
    -        $ 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
    -        Benchmark 1: make -C Documentation man' in 'HEAD~1
    -          Time (mean ± σ):      87.2 ms ±   1.0 ms    [User: 79.3 ms, System: 10.8 ms]
    -          Range (min … max):    86.3 ms …  89.7 ms    10 runs
    +        $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make -C Documentation man' 'make -C Documentation -j1 man'
    +        Benchmark 1: make -C Documentation -j1 man' in 'HEAD~1
    +          Time (mean ± σ):     121.7 ms ±   8.8 ms    [User: 105.8 ms, System: 18.6 ms]
    +          Range (min … max):   112.8 ms … 148.4 ms    26 runs
     
    -        Benchmark 2: make -C Documentation man' in 'HEAD~0
    -          Time (mean ± σ):      64.5 ms ±   0.6 ms    [User: 54.5 ms, System: 13.0 ms]
    -          Range (min … max):    63.8 ms …  65.7 ms    10 runs
    +        Benchmark 2: make -C Documentation -j1 man' in 'HEAD~0
    +          Time (mean ± σ):      97.5 ms ±   8.0 ms    [User: 80.1 ms, System: 20.1 ms]
    +          Range (min … max):    89.8 ms … 111.8 ms    32 runs
     
             Summary
    -          'make -C Documentation man' in 'HEAD~0' ran
    -            1.35 ± 0.02 times faster than 'make -C Documentation man' in 'HEAD~1'
    +          'make -C Documentation -j1 man' in 'HEAD~0' ran
    +            1.25 ± 0.14 times faster than 'make -C Documentation -j1 man' in 'HEAD~1'
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
13:  f378a7dc35e =  5:  1749085b929 Makefile: move $(comma), $(empty) and $(space) to shared.mak
14:  13cbb851d32 <  -:  ----------- Makefile: re-add and use the "shellquote" macros
15:  337953e4994 <  -:  ----------- Makefile: add a "TRACK_template" for GIT-*{FLAGS,DEFINES,...}
16:  5bb597c1993 !  6:  c25284b24cf Makefile: add "$(QUIET)" boilerplate to shared.mak
    @@ config.mak.uname: vcxproj:
      
     
      ## shared.mak ##
    -@@ shared.mak: space = $(empty) $(empty)
    - wspfx = $(space)$(space)$(space)
    - wspfx_sq = $(call shellquote,$(wspfx))
    - 
    +@@
    + comma = ,
    + empty =
    + space = $(empty) $(empty)
    ++
     +### Quieting
     +## common
     +QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir
    @@ shared.mak: space = $(empty) $(empty)
     +	export V
     +endif
     +endif
    -+
    - ### Templates
    - 
    - ## Template for making a GIT-SOMETHING, which changes if a
     
      ## templates/Makefile ##
     @@
17:  3c4d0589667 <  -:  ----------- Makefile: use $(wspfx) for $(QUIET...) in shared.mak
 -:  ----------- >  7:  3daef7672be Makefile: use $(wspfx) for $(QUIET...) in shared.mak
18:  be5882b2c99 !  8:  aca560ca410 Makefiles: add and use wildcard "mkdir -p" template
    @@ Commit message
         shows that this is faster, in addition to being less verbose and more
         reliable (this uses my "git-hyperfine" thin wrapper for "hyperfine"[3]):
     
    -        $ git hyperfine -L rev HEAD~0,HEAD~1 -b 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation lint-docs'
    -        Benchmark 1: make -C Documentation lint-docs' in 'HEAD~0
    -          Time (mean ± σ):      2.129 s ±  0.011 s    [User: 1.840 s, System: 0.321 s]
    -          Range (min … max):    2.121 s …  2.158 s    10 runs
    +        $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation -j1 lint-docs'
    +        Benchmark 1: make -C Documentation -j1 lint-docs' in 'HEAD~1
    +          Time (mean ± σ):      2.914 s ±  0.062 s    [User: 2.449 s, System: 0.489 s]
    +          Range (min … max):    2.834 s …  3.020 s    10 runs
     
    -        Benchmark 2: make -C Documentation lint-docs' in 'HEAD~1
    -          Time (mean ± σ):      2.659 s ±  0.002 s    [User: 2.306 s, System: 0.397 s]
    -          Range (min … max):    2.657 s …  2.662 s    10 runs
    +        Benchmark 2: make -C Documentation -j1 lint-docs' in 'HEAD~0
    +          Time (mean ± σ):      2.315 s ±  0.062 s    [User: 1.950 s, System: 0.386 s]
    +          Range (min … max):    2.229 s …  2.397 s    10 runs
     
             Summary
    -          'make -C Documentation lint-docs' in 'HEAD~0' ran
    -            1.25 ± 0.01 times faster than 'make -C Documentation lint-docs' in 'HEAD~1'
    +          'make -C Documentation -j1 lint-docs' in 'HEAD~0' ran
    +            1.26 ± 0.04 times faster than 'make -C Documentation -j1 lint-docs' in 'HEAD~1'
     
         So let's use that pattern both for the "lint-docs" target, and a few
         miscellaneous other targets.
    @@ Makefile: all:: $(MOFILES)
     +	$(call mkdir_p_parent_template)
     +	$(QUIET_MSGFMT)$(MSGFMT) -o $@ $<
      
    - ifndef NO_PERL
    - LIB_PERL = $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)
    -@@ Makefile: LIB_CPAN = $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)
    - LIB_CPAN_GEN = $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN))
    + LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)
    + LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))
    +@@ Makefile: NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\'',$(NO_PERL_CPAN_FALLBACKS))
    + endif
      
      perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES
     -	$(QUIET_GEN)mkdir -p $(dir $@) && \
    @@ Makefile: LIB_CPAN = $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm)
     +	$(QUIET_GEN) \
      	sed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \
      	    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \
    - 	    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(call shq,$(NO_PERL_CPAN_FALLBACKS))|g' \
    -@@ Makefile: endif
    + 	    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \
    + 	< $< > $@
      
    - # install-man depends on Git.3pm even with NO_PERL=Y
      perl/build/man/man3/Git.3pm: perl/Git.pm
     -	$(QUIET_GEN)mkdir -p $(dir $@) && \
     -	pod2man $< $@
     +	$(call mkdir_p_parent_template)
     +	$(QUIET_GEN)pod2man $< $@
      
    - FIND_SOURCE_FILES = ( \
    - 	git ls-files \
    + $(ETAGS_TARGET): $(FOUND_SOURCE_FILES)
    + 	$(QUIET_GEN)$(RM) $@+ && \
     @@ Makefile: test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(
      all:: $(TEST_PROGRAMS) $(test_bindir_programs)
      
    @@ Makefile: test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_
      ## shared.mak ##
     @@ shared.mak: ifndef V
      	QUIET          = @
    - 	QUIET_GEN      = @echo $(wspfx_sq) GEN $@;
    + 	QUIET_GEN      = @echo $(wspfx_SQ) GEN $@;
      
    -+	QUIET_MKDIR_P_PARENT  = @echo $(wspfx_sq) MKDIR -p $(@D);
    ++	QUIET_MKDIR_P_PARENT  = @echo $(wspfx_SQ) MKDIR -p $(@D);
     +
      ## Used in "Makefile"
    - 	QUIET_CC       = @echo $(wspfx_sq) CC $@;
    - 	QUIET_AR       = @echo $(wspfx_sq) AR $@;
    + 	QUIET_CC       = @echo $(wspfx_SQ) CC $@;
    + 	QUIET_AR       = @echo $(wspfx_SQ) AR $@;
     @@ shared.mak: ifndef V
    + 	export V
      endif
      endif
    - 
    -+## Helpers
    ++
    ++### Templates
    ++
    ++## mkdir_p_parent: lazily "mkdir -p" the path needed for a $@
    ++## file. Uses $(wildcard) to avoid the "mkdir -p" if it's not
    ++## needed.
    ++##
    ++## Is racy, but in a good way; we might redundantly (and safely)
    ++## "mkdir -p" when running in parallel, but won't need to exhaustively
    ++## individual rules for "a" -> "prefix" -> "dir" -> "file" if given a
    ++## "a/prefix/dir/file". This can instead be inserted at the start of
    ++## the "a/prefix/dir/file" rule.
     +define mkdir_p_parent_template
     +$(if $(wildcard $(@D)),,$(QUIET_MKDIR_P_PARENT)$(shell mkdir -p $(@D)))
     +endef
    -+
    - ### Templates
    - 
    - ## Template for making a GIT-SOMETHING, which changes if a
19:  2710f8af6cd <  -:  ----------- Makefile: correct the dependency graph of hook-list.h
20:  59f22a0269a <  -:  ----------- Makefile: use $(file) I/O instead of "FORCE" when possible
-- 
2.34.1.1119.g7a3fc8778ee


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/8] Makefiles: add "shared.mak", move ".DELETE_ON_ERROR" to it
  2021-12-17  1:39 [PATCH 0/8] Makefile: optimize noop runs, add shared.mak Ævar Arnfjörð Bjarmason
@ 2021-12-17  1:39 ` Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 2/8] Makefile: disable GNU make built-in wildcard rules Ævar Arnfjörð Bjarmason
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-17  1:39 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques, Eric Wong,
	Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye,
	Ævar Arnfjörð Bjarmason

We have various behavior that's shared across our Makefiles, or that
really should be (e.g. via defined templates). Let's create a
top-level "shared.mak" to house those sorts of things, and start by
adding the ".DELETE_ON_ERROR" flag to it.

See my own 7b76d6bf221 (Makefile: add and use the ".DELETE_ON_ERROR"
flag, 2021-06-29) and db10fc6c09f (doc: simplify Makefile using
.DELETE_ON_ERROR, 2021-05-21) for the addition and use of the
".DELETE_ON_ERROR" flag.

This does have the potential downside that if e.g. templates/Makefile
would like to include this "shared.mak" in the future the semantics of
such a Makefile will change, but as noted in the above commits (and
GNU make's own documentation) any such change would be for the better,
so it's safe to do this.

This also doesn't introduce a bug by e.g. having this
".DELETE_ON_ERROR" flag only apply to this new shared.mak, Makefiles
have no such scoping semantics.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/Makefile |  6 +++---
 Makefile               | 13 +++----------
 shared.mak             |  9 +++++++++
 t/Makefile             |  3 +++
 t/interop/Makefile     |  3 +++
 templates/Makefile     |  3 +++
 6 files changed, 24 insertions(+), 13 deletions(-)
 create mode 100644 shared.mak

diff --git a/Documentation/Makefile b/Documentation/Makefile
index ed656db2ae9..ba27456c86a 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,3 +1,6 @@
+# Import tree-wide shared Makefile behavior and libraries
+include ../shared.mak
+
 # Guard against environment variables
 MAN1_TXT =
 MAN5_TXT =
@@ -524,7 +527,4 @@ doc-l10n install-l10n::
 	$(MAKE) -C po $@
 endif
 
-# Delete the target file on error
-.DELETE_ON_ERROR:
-
 .PHONY: FORCE
diff --git a/Makefile b/Makefile
index 9c00a793e47..9842a234790 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,6 @@
+# Import tree-wide shared Makefile behavior and libraries
+include shared.mak
+
 # The default target of this Makefile is...
 all::
 
@@ -2168,16 +2171,6 @@ shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
 strip: $(PROGRAMS) git$X
 	$(STRIP) $(STRIP_OPTS) $^
 
-### Flags affecting all rules
-
-# A GNU make extension since gmake 3.72 (released in late 1994) to
-# remove the target of rules if commands in those rules fail. The
-# default is to only do that if make itself receives a signal. Affects
-# all targets, see:
-#
-#    info make --index-search=.DELETE_ON_ERROR
-.DELETE_ON_ERROR:
-
 ### Target-specific flags and dependencies
 
 # The generic compilation pattern rule and automatically
diff --git a/shared.mak b/shared.mak
new file mode 100644
index 00000000000..0170bb397ae
--- /dev/null
+++ b/shared.mak
@@ -0,0 +1,9 @@
+### Flags affecting all rules
+
+# A GNU make extension since gmake 3.72 (released in late 1994) to
+# remove the target of rules if commands in those rules fail. The
+# default is to only do that if make itself receives a signal. Affects
+# all targets, see:
+#
+#    info make --index-search=.DELETE_ON_ERROR
+.DELETE_ON_ERROR:
diff --git a/t/Makefile b/t/Makefile
index 882d26eee30..795b94b50ce 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -1,3 +1,6 @@
+# Import tree-wide shared Makefile behavior and libraries
+include ../shared.mak
+
 # Run tests
 #
 # Copyright (c) 2005 Junio C Hamano
diff --git a/t/interop/Makefile b/t/interop/Makefile
index 31a4bbc716a..6911c2915a7 100644
--- a/t/interop/Makefile
+++ b/t/interop/Makefile
@@ -1,3 +1,6 @@
+# Import tree-wide shared Makefile behavior and libraries
+include ../../shared.mak
+
 -include ../../config.mak
 export GIT_TEST_OPTIONS
 
diff --git a/templates/Makefile b/templates/Makefile
index d22a71a3999..636cee52f51 100644
--- a/templates/Makefile
+++ b/templates/Makefile
@@ -1,3 +1,6 @@
+# Import tree-wide shared Makefile behavior and libraries
+include ../shared.mak
+
 # make and install sample templates
 
 ifndef V
-- 
2.34.1.1119.g7a3fc8778ee


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/8] Makefile: disable GNU make built-in wildcard rules
  2021-12-17  1:39 [PATCH 0/8] Makefile: optimize noop runs, add shared.mak Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 1/8] Makefiles: add "shared.mak", move ".DELETE_ON_ERROR" to it Ævar Arnfjörð Bjarmason
@ 2021-12-17  1:39 ` Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 3/8] Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES) Ævar Arnfjörð Bjarmason
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-17  1:39 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques, Eric Wong,
	Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye,
	Ævar Arnfjörð Bjarmason

Override built-in rules of GNU make that use a wildcard target. This
can speeds things up significantly as we don't need to stat() so many
files. GNU make does that by default to see if it can retrieve their
contents from RCS or SCCS. See [1] for an old mailing list discussion
about how to disable these.

The speed-up may wary. I've seen 1-10% depending on the speed of the
local disk, caches, -jN etc. Running:

    strace -f -c -S calls make -j1 NO_TCLTK=Y

Shows that we reduce the number of syscalls we make, mostly in "stat"
calls.

We could also invoke make with "-r" by setting "MAKEFLAGS = -r"
early. Doing so might make us a bit faster still. But doing so is a
much bigger hammer, since it will disable all built-in rules,
some (all?) of which can be seen with:

    make -f/dev/null -p | grep -v -e ^# -e ^$

We may have something that relies on them, so let's go for the more
isolated optimization here that gives us most or all of the wins.

1. https://lists.gnu.org/archive/html/help-make/2002-11/msg00063.html

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 shared.mak | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/shared.mak b/shared.mak
index 0170bb397ae..29f0e69ecb9 100644
--- a/shared.mak
+++ b/shared.mak
@@ -1,3 +1,14 @@
+### Remove GNU make implicit rules
+
+## This speeds things up since we don't need to look for and stat() a
+## "foo.c,v" every time a rule referring to "foo.c" is in play. See
+## "make -p -f/dev/null | grep ^%::'".
+%:: %,v
+%:: RCS/%,v
+%:: RCS/%
+%:: s.%
+%:: SCCS/s.%
+
 ### Flags affecting all rules
 
 # A GNU make extension since gmake 3.72 (released in late 1994) to
-- 
2.34.1.1119.g7a3fc8778ee


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/8] Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES)
  2021-12-17  1:39 [PATCH 0/8] Makefile: optimize noop runs, add shared.mak Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 1/8] Makefiles: add "shared.mak", move ".DELETE_ON_ERROR" to it Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 2/8] Makefile: disable GNU make built-in wildcard rules Ævar Arnfjörð Bjarmason
@ 2021-12-17  1:39 ` Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 4/8] Makefile: move ".SUFFIXES" rule to shared.mak Ævar Arnfjörð Bjarmason
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-17  1:39 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques, Eric Wong,
	Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye,
	Ævar Arnfjörð Bjarmason

Combine the definitions of $(FIND_SOURCE_FILES) and $(LIB_H) to speed
up the Makefile, as these are the two main expensive $(shell) commands
that we execute unconditionally.

When see what was in $(FOUND_SOURCE_FILES) that wasn't in $(LIB_H) via
the ad-hoc test of:

    $(error $(filter-out $(LIB_H),$(filter %.h,$(ALL_SOURCE_FILES))))
    $(error $(filter-out $(ALL_SOURCE_FILES),$(filter %.h,$(LIB_H))))

We'll get, respectively:

    Makefile:850: *** t/helper/test-tool.h.  Stop.
    Makefile:850: *** .  Stop.

I.e. we only had a discrepancy when it came to
t/helper/test-tool.h. In terms of correctness this was broken before,
but now works:

    $ make t/helper/test-tool.hco
        HDR t/helper/test-tool.h

This speeds things up a lot:

    $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make NO_TCLTK=Y' 'make -j1 NO_TCLTK=Y' --warmup 10 -M 10
    Benchmark 1: make -j1 NO_TCLTK=Y' in 'HEAD~1
      Time (mean ± σ):     159.9 ms ±   6.8 ms    [User: 137.2 ms, System: 28.0 ms]
      Range (min … max):   154.6 ms … 175.9 ms    10 runs

    Benchmark 2: make -j1 NO_TCLTK=Y' in 'HEAD~0
      Time (mean ± σ):     100.0 ms ±   1.3 ms    [User: 84.2 ms, System: 20.2 ms]
      Range (min … max):    98.8 ms … 102.8 ms    10 runs

    Summary
      'make -j1 NO_TCLTK=Y' in 'HEAD~0' ran
        1.60 ± 0.07 times faster than 'make -j1 NO_TCLTK=Y' in 'HEAD~1'

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Makefile | 54 ++++++++++++++++++++++++++----------------------------
 1 file changed, 26 insertions(+), 28 deletions(-)

diff --git a/Makefile b/Makefile
index 9842a234790..d290a28671a 100644
--- a/Makefile
+++ b/Makefile
@@ -826,12 +826,33 @@ GENERATED_H += hook-list.h
 .PHONY: generated-hdrs
 generated-hdrs: $(GENERATED_H)
 
-LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \
+## Exhaustive lists of our source files, either dynamically generated,
+## or hardcoded.
+SOURCES_CMD = ( \
+	git ls-files \
+		'*.[hcS]' \
+		'*.sh' \
+		':!*[tp][0-9][0-9][0-9][0-9]*' \
+		':!contrib' \
+		2>/dev/null || \
 	$(FIND) . \
-	-name .git -prune -o \
-	-name t -prune -o \
-	-name Documentation -prune -o \
-	-name '*.h' -print)))
+		\( -name .git -type d -prune \) \
+		-o \( -name '[tp][0-9][0-9][0-9][0-9]*' -prune \) \
+		-o \( -name contrib -type d -prune \) \
+		-o \( -name build -type d -prune \) \
+		-o \( -name 'trash*' -type d -prune \) \
+		-o \( -name '*.[hcS]' -type f -print \) \
+		-o \( -name '*.sh' -type f -print \) \
+		| sed -e 's|^\./||' \
+	)
+FOUND_SOURCE_FILES := $(shell $(SOURCES_CMD))
+
+FOUND_C_SOURCES = $(filter %.c,$(FOUND_SOURCE_FILES))
+FOUND_H_SOURCES = $(filter %.h,$(FOUND_SOURCE_FILES))
+
+COCCI_SOURCES = $(filter-out $(THIRD_PARTY_SOURCES),$(FOUND_C_SOURCES))
+
+LIB_H = $(FOUND_H_SOURCES)
 
 LIB_OBJS += abspath.o
 LIB_OBJS += add-interactive.o
@@ -2748,26 +2769,6 @@ perl/build/man/man3/Git.3pm: perl/Git.pm
 	$(QUIET_GEN)mkdir -p $(dir $@) && \
 	pod2man $< $@
 
-FIND_SOURCE_FILES = ( \
-	git ls-files \
-		'*.[hcS]' \
-		'*.sh' \
-		':!*[tp][0-9][0-9][0-9][0-9]*' \
-		':!contrib' \
-		2>/dev/null || \
-	$(FIND) . \
-		\( -name .git -type d -prune \) \
-		-o \( -name '[tp][0-9][0-9][0-9][0-9]*' -prune \) \
-		-o \( -name contrib -type d -prune \) \
-		-o \( -name build -type d -prune \) \
-		-o \( -name 'trash*' -type d -prune \) \
-		-o \( -name '*.[hcS]' -type f -print \) \
-		-o \( -name '*.sh' -type f -print \) \
-		| sed -e 's|^\./||' \
-	)
-
-FOUND_SOURCE_FILES = $(shell $(FIND_SOURCE_FILES))
-
 $(ETAGS_TARGET): $(FOUND_SOURCE_FILES)
 	$(QUIET_GEN)$(RM) $@+ && \
 	echo $(FOUND_SOURCE_FILES) | xargs etags -a -o $@+ && \
@@ -2977,9 +2978,6 @@ check: $(GENERATED_H)
 		exit 1; \
 	fi
 
-FOUND_C_SOURCES = $(filter %.c,$(FOUND_SOURCE_FILES))
-COCCI_SOURCES = $(filter-out $(THIRD_PARTY_SOURCES),$(FOUND_C_SOURCES))
-
 %.cocci.patch: %.cocci $(COCCI_SOURCES)
 	$(QUIET_SPATCH) \
 	if test $(SPATCH_BATCH_SIZE) = 0; then \
-- 
2.34.1.1119.g7a3fc8778ee


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/8] Makefile: move ".SUFFIXES" rule to shared.mak
  2021-12-17  1:39 [PATCH 0/8] Makefile: optimize noop runs, add shared.mak Ævar Arnfjörð Bjarmason
                   ` (2 preceding siblings ...)
  2021-12-17  1:39 ` [PATCH 3/8] Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES) Ævar Arnfjörð Bjarmason
@ 2021-12-17  1:39 ` Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 5/8] Makefile: move $(comma), $(empty) and $(space) " Ævar Arnfjörð Bjarmason
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-17  1:39 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques, Eric Wong,
	Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye,
	Ævar Arnfjörð Bjarmason

This was added in 30248886ce8 (Makefile: disable default implicit
rules, 2010-01-26), let's move it to the top of "shared.mak" so it'll
apply to all our Makefiles.

This doesn't benefit the main Makefile at all, since it already had
the rule, but since we're including shared.mak in other Makefiles
starts to benefit them. E.g. running the 'man" target is now faster:

    $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make -C Documentation man' 'make -C Documentation -j1 man'
    Benchmark 1: make -C Documentation -j1 man' in 'HEAD~1
      Time (mean ± σ):     121.7 ms ±   8.8 ms    [User: 105.8 ms, System: 18.6 ms]
      Range (min … max):   112.8 ms … 148.4 ms    26 runs

    Benchmark 2: make -C Documentation -j1 man' in 'HEAD~0
      Time (mean ± σ):      97.5 ms ±   8.0 ms    [User: 80.1 ms, System: 20.1 ms]
      Range (min … max):    89.8 ms … 111.8 ms    32 runs

    Summary
      'make -C Documentation -j1 man' in 'HEAD~0' ran
        1.25 ± 0.14 times faster than 'make -C Documentation -j1 man' in 'HEAD~1'

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Makefile   | 2 --
 shared.mak | 5 +++++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index d290a28671a..50359603dbc 100644
--- a/Makefile
+++ b/Makefile
@@ -2543,8 +2543,6 @@ ASM_SRC := $(wildcard $(OBJECTS:o=S))
 ASM_OBJ := $(ASM_SRC:S=o)
 C_OBJ := $(filter-out $(ASM_OBJ),$(OBJECTS))
 
-.SUFFIXES:
-
 $(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
 	$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
 $(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
diff --git a/shared.mak b/shared.mak
index 29f0e69ecb9..155ac84f867 100644
--- a/shared.mak
+++ b/shared.mak
@@ -9,6 +9,11 @@
 %:: s.%
 %:: SCCS/s.%
 
+## Likewise delete default $(SUFFIXES). See:
+##
+##     info make --index-search=.DELETE_ON_ERROR
+.SUFFIXES:
+
 ### Flags affecting all rules
 
 # A GNU make extension since gmake 3.72 (released in late 1994) to
-- 
2.34.1.1119.g7a3fc8778ee


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/8] Makefile: move $(comma), $(empty) and $(space) to shared.mak
  2021-12-17  1:39 [PATCH 0/8] Makefile: optimize noop runs, add shared.mak Ævar Arnfjörð Bjarmason
                   ` (3 preceding siblings ...)
  2021-12-17  1:39 ` [PATCH 4/8] Makefile: move ".SUFFIXES" rule to shared.mak Ævar Arnfjörð Bjarmason
@ 2021-12-17  1:39 ` Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 6/8] Makefile: add "$(QUIET)" boilerplate " Ævar Arnfjörð Bjarmason
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-17  1:39 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques, Eric Wong,
	Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye,
	Ævar Arnfjörð Bjarmason

Move these variables over to the shared.max, we'll make use of them in
a subsequent commit. There was no reason for these to be "simply
expanded variables", so let's use the normal lazy "=" assignment here.

See 425ca6710b2 (Makefile: allow combining UBSan with other
sanitizers, 2017-07-15) for the commit that introduced these.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Makefile   | 4 ----
 shared.mak | 8 ++++++++
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 50359603dbc..4dfb88ccb3f 100644
--- a/Makefile
+++ b/Makefile
@@ -1278,10 +1278,6 @@ endif
 ALL_CFLAGS = $(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS)
 ALL_LDFLAGS = $(LDFLAGS)
 
-comma := ,
-empty :=
-space := $(empty) $(empty)
-
 ifdef SANITIZE
 SANITIZERS := $(foreach flag,$(subst $(comma),$(space),$(SANITIZE)),$(flag))
 BASIC_CFLAGS += -fsanitize=$(SANITIZE) -fno-sanitize-recover=$(SANITIZE)
diff --git a/shared.mak b/shared.mak
index 155ac84f867..b34fb948c0f 100644
--- a/shared.mak
+++ b/shared.mak
@@ -23,3 +23,11 @@
 #
 #    info make --index-search=.DELETE_ON_ERROR
 .DELETE_ON_ERROR:
+
+### Global variables
+
+## comma, empty, space: handy variables as these tokens are either
+## special or can be hard to spot among other Makefile syntax.
+comma = ,
+empty =
+space = $(empty) $(empty)
-- 
2.34.1.1119.g7a3fc8778ee


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/8] Makefile: add "$(QUIET)" boilerplate to shared.mak
  2021-12-17  1:39 [PATCH 0/8] Makefile: optimize noop runs, add shared.mak Ævar Arnfjörð Bjarmason
                   ` (4 preceding siblings ...)
  2021-12-17  1:39 ` [PATCH 5/8] Makefile: move $(comma), $(empty) and $(space) " Ævar Arnfjörð Bjarmason
@ 2021-12-17  1:39 ` Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 7/8] Makefile: use $(wspfx) for $(QUIET...) in shared.mak Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 8/8] Makefiles: add and use wildcard "mkdir -p" template Ævar Arnfjörð Bjarmason
  7 siblings, 0 replies; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-17  1:39 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques, Eric Wong,
	Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye,
	Ævar Arnfjörð Bjarmason

The $(QUIET) variables we define are largely duplicated between our
various Makefiles, let's define them in the new "shared.mak" instead.

Since we're not using the environment to pass these around we don't
need to export the "QUIET_GEN" and "QUIET_BUILT_IN" variables
anymore. The "QUIET_GEN" variable is used in "git-gui/Makefile" and
"gitweb/Makefile", but they've got their own definition for those. The
"QUIET_BUILT_IN" variable is only used in the top-level "Makefile". We
still need to export the "V" variable.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/Makefile | 32 -------------------------
 Makefile               | 33 --------------------------
 config.mak.uname       |  1 -
 shared.mak             | 53 ++++++++++++++++++++++++++++++++++++++++++
 templates/Makefile     |  5 ----
 5 files changed, 53 insertions(+), 71 deletions(-)

diff --git a/Documentation/Makefile b/Documentation/Makefile
index ba27456c86a..0f4ebdeda8a 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -218,38 +218,6 @@ DEFAULT_EDITOR_SQ = $(subst ','\'',$(DEFAULT_EDITOR))
 ASCIIDOC_EXTRA += -a 'git-default-editor=$(DEFAULT_EDITOR_SQ)'
 endif
 
-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir
-QUIET_SUBDIR1  =
-
-ifneq ($(findstring $(MAKEFLAGS),w),w)
-PRINT_DIR = --no-print-directory
-else # "make -w"
-NO_SUBDIR = :
-endif
-
-ifneq ($(findstring $(MAKEFLAGS),s),s)
-ifndef V
-	QUIET		= @
-	QUIET_ASCIIDOC	= @echo '   ' ASCIIDOC $@;
-	QUIET_XMLTO	= @echo '   ' XMLTO $@;
-	QUIET_DB2TEXI	= @echo '   ' DB2TEXI $@;
-	QUIET_MAKEINFO	= @echo '   ' MAKEINFO $@;
-	QUIET_DBLATEX	= @echo '   ' DBLATEX $@;
-	QUIET_XSLTPROC	= @echo '   ' XSLTPROC $@;
-	QUIET_GEN	= @echo '   ' GEN $@;
-	QUIET_STDERR	= 2> /dev/null
-	QUIET_SUBDIR0	= +@subdir=
-	QUIET_SUBDIR1	= ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
-			  $(MAKE) $(PRINT_DIR) -C $$subdir
-
-	QUIET_LINT_GITLINK	= @echo '   ' LINT GITLINK $<;
-	QUIET_LINT_MANSEC	= @echo '   ' LINT MAN SEC $<;
-	QUIET_LINT_MANEND	= @echo '   ' LINT MAN END $<;
-
-	export V
-endif
-endif
-
 all: html man
 
 html: $(DOC_HTML)
diff --git a/Makefile b/Makefile
index 4dfb88ccb3f..9f27fc77e5a 100644
--- a/Makefile
+++ b/Makefile
@@ -1970,39 +1970,6 @@ ifndef PAGER_ENV
 PAGER_ENV = LESS=FRX LV=-c
 endif
 
-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir
-QUIET_SUBDIR1  =
-
-ifneq ($(findstring w,$(MAKEFLAGS)),w)
-PRINT_DIR = --no-print-directory
-else # "make -w"
-NO_SUBDIR = :
-endif
-
-ifneq ($(findstring s,$(MAKEFLAGS)),s)
-ifndef V
-	QUIET_CC       = @echo '   ' CC $@;
-	QUIET_AR       = @echo '   ' AR $@;
-	QUIET_LINK     = @echo '   ' LINK $@;
-	QUIET_BUILT_IN = @echo '   ' BUILTIN $@;
-	QUIET_GEN      = @echo '   ' GEN $@;
-	QUIET_LNCP     = @echo '   ' LN/CP $@;
-	QUIET_XGETTEXT = @echo '   ' XGETTEXT $@;
-	QUIET_MSGFMT   = @echo '   ' MSGFMT $@;
-	QUIET_GCOV     = @echo '   ' GCOV $@;
-	QUIET_SP       = @echo '   ' SP $<;
-	QUIET_HDR      = @echo '   ' HDR $(<:hcc=h);
-	QUIET_RC       = @echo '   ' RC $@;
-	QUIET_SPATCH   = @echo '   ' SPATCH $<;
-	QUIET_SUBDIR0  = +@subdir=
-	QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
-			 $(MAKE) $(PRINT_DIR) -C $$subdir
-	export V
-	export QUIET_GEN
-	export QUIET_BUILT_IN
-endif
-endif
-
 ifdef NO_INSTALL_HARDLINKS
 	export NO_INSTALL_HARDLINKS
 endif
diff --git a/config.mak.uname b/config.mak.uname
index a3a779327f8..cfc2416c935 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -720,7 +720,6 @@ vcxproj:
 	git diff-index --cached --quiet HEAD --
 
 	# Make .vcxproj files and add them
-	unset QUIET_GEN QUIET_BUILT_IN; \
 	perl contrib/buildsystems/generate -g Vcxproj
 	git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj
 
diff --git a/shared.mak b/shared.mak
index b34fb948c0f..d6f70f3d6c9 100644
--- a/shared.mak
+++ b/shared.mak
@@ -31,3 +31,56 @@
 comma = ,
 empty =
 space = $(empty) $(empty)
+
+### Quieting
+## common
+QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir
+QUIET_SUBDIR1  =
+
+ifneq ($(findstring w,$(MAKEFLAGS)),w)
+PRINT_DIR = --no-print-directory
+else # "make -w"
+NO_SUBDIR = :
+endif
+
+ifneq ($(findstring s,$(MAKEFLAGS)),s)
+ifndef V
+## common
+	QUIET_SUBDIR0  = +@subdir=
+	QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
+			 $(MAKE) $(PRINT_DIR) -C $$subdir
+
+	QUIET          = @
+	QUIET_GEN      = @echo '   ' GEN $@;
+
+## Used in "Makefile"
+	QUIET_CC       = @echo '   ' CC $@;
+	QUIET_AR       = @echo '   ' AR $@;
+	QUIET_LINK     = @echo '   ' LINK $@;
+	QUIET_BUILT_IN = @echo '   ' BUILTIN $@;
+	QUIET_LNCP     = @echo '   ' LN/CP $@;
+	QUIET_XGETTEXT = @echo '   ' XGETTEXT $@;
+	QUIET_MSGFMT   = @echo '   ' MSGFMT $@;
+	QUIET_GCOV     = @echo '   ' GCOV $@;
+	QUIET_SP       = @echo '   ' SP $<;
+	QUIET_HDR      = @echo '   ' HDR $(<:hcc=h);
+	QUIET_RC       = @echo '   ' RC $@;
+	QUIET_SPATCH   = @echo '   ' SPATCH $<;
+
+## Used in "Documentation/Makefile"
+	QUIET_ASCIIDOC	= @echo '   ' ASCIIDOC $@;
+	QUIET_XMLTO	= @echo '   ' XMLTO $@;
+	QUIET_DB2TEXI	= @echo '   ' DB2TEXI $@;
+	QUIET_MAKEINFO	= @echo '   ' MAKEINFO $@;
+	QUIET_DBLATEX	= @echo '   ' DBLATEX $@;
+	QUIET_XSLTPROC	= @echo '   ' XSLTPROC $@;
+	QUIET_GEN	= @echo '   ' GEN $@;
+	QUIET_STDERR	= 2> /dev/null
+
+	QUIET_LINT_GITLINK	= @echo '   ' LINT GITLINK $<;
+	QUIET_LINT_MANSEC	= @echo '   ' LINT MAN SEC $<;
+	QUIET_LINT_MANEND	= @echo '   ' LINT MAN END $<;
+
+	export V
+endif
+endif
diff --git a/templates/Makefile b/templates/Makefile
index 636cee52f51..367ad00c24c 100644
--- a/templates/Makefile
+++ b/templates/Makefile
@@ -2,11 +2,6 @@
 include ../shared.mak
 
 # make and install sample templates
-
-ifndef V
-	QUIET = @
-endif
-
 INSTALL ?= install
 TAR ?= tar
 RM ?= rm -f
-- 
2.34.1.1119.g7a3fc8778ee


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/8] Makefile: use $(wspfx) for $(QUIET...) in shared.mak
  2021-12-17  1:39 [PATCH 0/8] Makefile: optimize noop runs, add shared.mak Ævar Arnfjörð Bjarmason
                   ` (5 preceding siblings ...)
  2021-12-17  1:39 ` [PATCH 6/8] Makefile: add "$(QUIET)" boilerplate " Ævar Arnfjörð Bjarmason
@ 2021-12-17  1:39 ` Ævar Arnfjörð Bjarmason
  2021-12-17  1:39 ` [PATCH 8/8] Makefiles: add and use wildcard "mkdir -p" template Ævar Arnfjörð Bjarmason
  7 siblings, 0 replies; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-17  1:39 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques, Eric Wong,
	Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye,
	Ævar Arnfjörð Bjarmason

Change the mostly move-only change in the preceding commit to use the
$(wspfx) variable for defining the QUIET padding, to guarantee that
it's consistent with the "TRACK_template" template.

    $ make CFLAGS=-I$RANDOM grep.o wspfx='$(space)->'
     -> GIT-CFLAGS PARAMETERS (changed)
     -> CC grep.o

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 shared.mak | 54 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/shared.mak b/shared.mak
index d6f70f3d6c9..f8ebaf30569 100644
--- a/shared.mak
+++ b/shared.mak
@@ -32,6 +32,12 @@ comma = ,
 empty =
 space = $(empty) $(empty)
 
+## wspfx: the whitespace prefix padding for $(QUIET...) and similarly
+## aligned output.
+wspfx = $(space)$(space)$(space)
+wspfx_SQ = '$(subst ','\'',$(wspfx))'
+# ' closing quote to appease Emacs make-mode.elxo
+
 ### Quieting
 ## common
 QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir
@@ -47,39 +53,39 @@ ifneq ($(findstring s,$(MAKEFLAGS)),s)
 ifndef V
 ## common
 	QUIET_SUBDIR0  = +@subdir=
-	QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
+	QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo $(wspfx_SQ) SUBDIR $$subdir; \
 			 $(MAKE) $(PRINT_DIR) -C $$subdir
 
 	QUIET          = @
-	QUIET_GEN      = @echo '   ' GEN $@;
+	QUIET_GEN      = @echo $(wspfx_SQ) GEN $@;
 
 ## Used in "Makefile"
-	QUIET_CC       = @echo '   ' CC $@;
-	QUIET_AR       = @echo '   ' AR $@;
-	QUIET_LINK     = @echo '   ' LINK $@;
-	QUIET_BUILT_IN = @echo '   ' BUILTIN $@;
-	QUIET_LNCP     = @echo '   ' LN/CP $@;
-	QUIET_XGETTEXT = @echo '   ' XGETTEXT $@;
-	QUIET_MSGFMT   = @echo '   ' MSGFMT $@;
-	QUIET_GCOV     = @echo '   ' GCOV $@;
-	QUIET_SP       = @echo '   ' SP $<;
-	QUIET_HDR      = @echo '   ' HDR $(<:hcc=h);
-	QUIET_RC       = @echo '   ' RC $@;
-	QUIET_SPATCH   = @echo '   ' SPATCH $<;
+	QUIET_CC       = @echo $(wspfx_SQ) CC $@;
+	QUIET_AR       = @echo $(wspfx_SQ) AR $@;
+	QUIET_LINK     = @echo $(wspfx_SQ) LINK $@;
+	QUIET_BUILT_IN = @echo $(wspfx_SQ) BUILTIN $@;
+	QUIET_LNCP     = @echo $(wspfx_SQ) LN/CP $@;
+	QUIET_XGETTEXT = @echo $(wspfx_SQ) XGETTEXT $@;
+	QUIET_MSGFMT   = @echo $(wspfx_SQ) MSGFMT $@;
+	QUIET_GCOV     = @echo $(wspfx_SQ) GCOV $@;
+	QUIET_SP       = @echo $(wspfx_SQ) SP $<;
+	QUIET_HDR      = @echo $(wspfx_SQ) HDR $(<:hcc=h);
+	QUIET_RC       = @echo $(wspfx_SQ) RC $@;
+	QUIET_SPATCH   = @echo $(wspfx_SQ) SPATCH $<;
 
 ## Used in "Documentation/Makefile"
-	QUIET_ASCIIDOC	= @echo '   ' ASCIIDOC $@;
-	QUIET_XMLTO	= @echo '   ' XMLTO $@;
-	QUIET_DB2TEXI	= @echo '   ' DB2TEXI $@;
-	QUIET_MAKEINFO	= @echo '   ' MAKEINFO $@;
-	QUIET_DBLATEX	= @echo '   ' DBLATEX $@;
-	QUIET_XSLTPROC	= @echo '   ' XSLTPROC $@;
-	QUIET_GEN	= @echo '   ' GEN $@;
+	QUIET_ASCIIDOC	= @echo $(wspfx_SQ) ASCIIDOC $@;
+	QUIET_XMLTO	= @echo $(wspfx_SQ) XMLTO $@;
+	QUIET_DB2TEXI	= @echo $(wspfx_SQ) DB2TEXI $@;
+	QUIET_MAKEINFO	= @echo $(wspfx_SQ) MAKEINFO $@;
+	QUIET_DBLATEX	= @echo $(wspfx_SQ) DBLATEX $@;
+	QUIET_XSLTPROC	= @echo $(wspfx_SQ) XSLTPROC $@;
+	QUIET_GEN	= @echo $(wspfx_SQ) GEN $@;
 	QUIET_STDERR	= 2> /dev/null
 
-	QUIET_LINT_GITLINK	= @echo '   ' LINT GITLINK $<;
-	QUIET_LINT_MANSEC	= @echo '   ' LINT MAN SEC $<;
-	QUIET_LINT_MANEND	= @echo '   ' LINT MAN END $<;
+	QUIET_LINT_GITLINK	= @echo $(wspfx_SQ) LINT GITLINK $<;
+	QUIET_LINT_MANSEC	= @echo $(wspfx_SQ) LINT MAN SEC $<;
+	QUIET_LINT_MANEND	= @echo $(wspfx_SQ) LINT MAN END $<;
 
 	export V
 endif
-- 
2.34.1.1119.g7a3fc8778ee


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/8] Makefiles: add and use wildcard "mkdir -p" template
  2021-12-17  1:39 [PATCH 0/8] Makefile: optimize noop runs, add shared.mak Ævar Arnfjörð Bjarmason
                   ` (6 preceding siblings ...)
  2021-12-17  1:39 ` [PATCH 7/8] Makefile: use $(wspfx) for $(QUIET...) in shared.mak Ævar Arnfjörð Bjarmason
@ 2021-12-17  1:39 ` Ævar Arnfjörð Bjarmason
  2021-12-17  6:09   ` Eric Sunshine
  7 siblings, 1 reply; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-17  1:39 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques, Eric Wong,
	Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye,
	Ævar Arnfjörð Bjarmason

Add a template to do the "mkdir -p" of $(@D) (the parent dir of $@)
for us, and use it for the "make lint-docs" targets I added in
8650c6298c1 (doc lint: make "lint-docs" non-.PHONY, 2021-10-15).

As seen in 4c64fb5aad9 (Documentation/Makefile: fix lint-docs mkdir
dependency, 2021-10-26) maintaining these manual lists of parent
directory dependencies is fragile, in addition to being obviously
verbose.

I used this pattern at the time because I couldn't find another method
than "order-only" prerequisites to avoid doing a "mkdir -p $(@D)" for
every file being created, which as noted in [1] would be significantly
slower.

But as it turns out we can use this neat trick of only doing a "mkdir
-p" if the $(wildcard) macro tells us the path doesn't exist. A re-run
of a performance test similar to thatnoted downthread of [1] in [2]
shows that this is faster, in addition to being less verbose and more
reliable (this uses my "git-hyperfine" thin wrapper for "hyperfine"[3]):

    $ git -c hyperfine.hook.setup= hyperfine -L rev HEAD~1,HEAD~0 -s 'make -C Documentation lint-docs' -p 'rm -rf Documentation/.build' 'make -C Documentation -j1 lint-docs'
    Benchmark 1: make -C Documentation -j1 lint-docs' in 'HEAD~1
      Time (mean ± σ):      2.914 s ±  0.062 s    [User: 2.449 s, System: 0.489 s]
      Range (min … max):    2.834 s …  3.020 s    10 runs

    Benchmark 2: make -C Documentation -j1 lint-docs' in 'HEAD~0
      Time (mean ± σ):      2.315 s ±  0.062 s    [User: 1.950 s, System: 0.386 s]
      Range (min … max):    2.229 s …  2.397 s    10 runs

    Summary
      'make -C Documentation -j1 lint-docs' in 'HEAD~0' ran
        1.26 ± 0.04 times faster than 'make -C Documentation -j1 lint-docs' in 'HEAD~1'

So let's use that pattern both for the "lint-docs" target, and a few
miscellaneous other targets.

This method of creating parent directories is explicitly racy in that
we don't know if we're going to say always create a "foo" followed by
a "foo/bar" under parallelism, or skip the "foo" because we created
"foo/bar" first. In this case it doesn't matter for anything except
that we aren't guaranteed to get the same number of rules firing when
running make in parallel.

1. https://lore.kernel.org/git/211028.861r45y3pt.gmgdl@evledraar.gmail.com/
2. https://lore.kernel.org/git/211028.86o879vvtp.gmgdl@evledraar.gmail.com/
3. https://gitlab.com/avar/git-hyperfine/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/Makefile | 25 +++----------------------
 Makefile               | 12 +++++++-----
 shared.mak             | 17 +++++++++++++++++
 3 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/Documentation/Makefile b/Documentation/Makefile
index 0f4ebdeda8a..1eb9192dae8 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -434,25 +434,11 @@ quick-install-html: require-htmlrepo
 print-man1:
 	@for i in $(MAN1_TXT); do echo $$i; done
 
-## Lint: Common
-.build:
-	$(QUIET)mkdir $@
-.build/lint-docs: | .build
-	$(QUIET)mkdir $@
-
 ## Lint: gitlink
-.build/lint-docs/gitlink: | .build/lint-docs
-	$(QUIET)mkdir $@
-.build/lint-docs/gitlink/howto: | .build/lint-docs/gitlink
-	$(QUIET)mkdir $@
-.build/lint-docs/gitlink/config: | .build/lint-docs/gitlink
-	$(QUIET)mkdir $@
 LINT_DOCS_GITLINK = $(patsubst %.txt,.build/lint-docs/gitlink/%.ok,$(HOWTO_TXT) $(DOC_DEP_TXT))
-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink
-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/howto
-$(LINT_DOCS_GITLINK): | .build/lint-docs/gitlink/config
 $(LINT_DOCS_GITLINK): lint-gitlink.perl
 $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt
+	$(call mkdir_p_parent_template)
 	$(QUIET_LINT_GITLINK)$(PERL_PATH) lint-gitlink.perl \
 		$< \
 		$(HOWTO_TXT) $(DOC_DEP_TXT) \
@@ -463,23 +449,18 @@ $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt
 lint-docs-gitlink: $(LINT_DOCS_GITLINK)
 
 ## Lint: man-end-blurb
-.build/lint-docs/man-end-blurb: | .build/lint-docs
-	$(QUIET)mkdir $@
 LINT_DOCS_MAN_END_BLURB = $(patsubst %.txt,.build/lint-docs/man-end-blurb/%.ok,$(MAN_TXT))
-$(LINT_DOCS_MAN_END_BLURB): | .build/lint-docs/man-end-blurb
 $(LINT_DOCS_MAN_END_BLURB): lint-man-end-blurb.perl
 $(LINT_DOCS_MAN_END_BLURB): .build/lint-docs/man-end-blurb/%.ok: %.txt
+	$(call mkdir_p_parent_template)
 	$(QUIET_LINT_MANEND)$(PERL_PATH) lint-man-end-blurb.perl $< >$@
 .PHONY: lint-docs-man-end-blurb
-lint-docs-man-end-blurb: $(LINT_DOCS_MAN_END_BLURB)
 
 ## Lint: man-section-order
-.build/lint-docs/man-section-order: | .build/lint-docs
-	$(QUIET)mkdir $@
 LINT_DOCS_MAN_SECTION_ORDER = $(patsubst %.txt,.build/lint-docs/man-section-order/%.ok,$(MAN_TXT))
-$(LINT_DOCS_MAN_SECTION_ORDER): | .build/lint-docs/man-section-order
 $(LINT_DOCS_MAN_SECTION_ORDER): lint-man-section-order.perl
 $(LINT_DOCS_MAN_SECTION_ORDER): .build/lint-docs/man-section-order/%.ok: %.txt
+	$(call mkdir_p_parent_template)
 	$(QUIET_LINT_MANSEC)$(PERL_PATH) lint-man-section-order.perl $< >$@
 .PHONY: lint-docs-man-section-order
 lint-docs-man-section-order: $(LINT_DOCS_MAN_SECTION_ORDER)
diff --git a/Makefile b/Makefile
index 9f27fc77e5a..ed601534967 100644
--- a/Makefile
+++ b/Makefile
@@ -2704,7 +2704,8 @@ all:: $(MOFILES)
 endif
 
 po/build/locale/%/LC_MESSAGES/git.mo: po/%.po
-	$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<
+	$(call mkdir_p_parent_template)
+	$(QUIET_MSGFMT)$(MSGFMT) -o $@ $<
 
 LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm)
 LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL))
@@ -2720,15 +2721,16 @@ NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\'',$(NO_PERL_CPAN_FALLBACKS))
 endif
 
 perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES
-	$(QUIET_GEN)mkdir -p $(dir $@) && \
+	$(call mkdir_p_parent_template)
+	$(QUIET_GEN) \
 	sed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \
 	    -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \
 	    -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \
 	< $< > $@
 
 perl/build/man/man3/Git.3pm: perl/Git.pm
-	$(QUIET_GEN)mkdir -p $(dir $@) && \
-	pod2man $< $@
+	$(call mkdir_p_parent_template)
+	$(QUIET_GEN)pod2man $< $@
 
 $(ETAGS_TARGET): $(FOUND_SOURCE_FILES)
 	$(QUIET_GEN)$(RM) $@+ && \
@@ -2862,7 +2864,7 @@ test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(
 all:: $(TEST_PROGRAMS) $(test_bindir_programs)
 
 bin-wrappers/%: wrap-for-bin.sh
-	@mkdir -p bin-wrappers
+	$(call mkdir_p_parent_template)
 	$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
 	     -e 's|@@BUILD_DIR@@|$(shell pwd)|' \
 	     -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \
diff --git a/shared.mak b/shared.mak
index f8ebaf30569..13fb5eb93bb 100644
--- a/shared.mak
+++ b/shared.mak
@@ -59,6 +59,8 @@ ifndef V
 	QUIET          = @
 	QUIET_GEN      = @echo $(wspfx_SQ) GEN $@;
 
+	QUIET_MKDIR_P_PARENT  = @echo $(wspfx_SQ) MKDIR -p $(@D);
+
 ## Used in "Makefile"
 	QUIET_CC       = @echo $(wspfx_SQ) CC $@;
 	QUIET_AR       = @echo $(wspfx_SQ) AR $@;
@@ -90,3 +92,18 @@ ifndef V
 	export V
 endif
 endif
+
+### Templates
+
+## mkdir_p_parent: lazily "mkdir -p" the path needed for a $@
+## file. Uses $(wildcard) to avoid the "mkdir -p" if it's not
+## needed.
+##
+## Is racy, but in a good way; we might redundantly (and safely)
+## "mkdir -p" when running in parallel, but won't need to exhaustively
+## individual rules for "a" -> "prefix" -> "dir" -> "file" if given a
+## "a/prefix/dir/file". This can instead be inserted at the start of
+## the "a/prefix/dir/file" rule.
+define mkdir_p_parent_template
+$(if $(wildcard $(@D)),,$(QUIET_MKDIR_P_PARENT)$(shell mkdir -p $(@D)))
+endef
-- 
2.34.1.1119.g7a3fc8778ee


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 8/8] Makefiles: add and use wildcard "mkdir -p" template
  2021-12-17  1:39 ` [PATCH 8/8] Makefiles: add and use wildcard "mkdir -p" template Ævar Arnfjörð Bjarmason
@ 2021-12-17  6:09   ` Eric Sunshine
  2021-12-24 17:41     ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 11+ messages in thread
From: Eric Sunshine @ 2021-12-17  6:09 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Git List, Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques,
	Eric Wong, Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye

On Thu, Dec 16, 2021 at 11:40 PM Ævar Arnfjörð Bjarmason
<avarab@gmail.com> wrote:
> [...]
> But as it turns out we can use this neat trick of only doing a "mkdir
> -p" if the $(wildcard) macro tells us the path doesn't exist. A re-run
> of a performance test similar to thatnoted downthread of [1] in [2]
> shows that this is faster, in addition to being less verbose and more
> reliable (this uses my "git-hyperfine" thin wrapper for "hyperfine"[3]):

s/thatnoted/that noted/

> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> diff --git a/shared.mak b/shared.mak
> @@ -90,3 +92,18 @@ ifndef V
> +## Is racy, but in a good way; we might redundantly (and safely)
> +## "mkdir -p" when running in parallel, but won't need to exhaustively
> +## individual rules for "a" -> "prefix" -> "dir" -> "file" if given a
> +## "a/prefix/dir/file". This can instead be inserted at the start of
> +## the "a/prefix/dir/file" rule.

Is there a word missing between "exhaustively" and "individual"?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 8/8] Makefiles: add and use wildcard "mkdir -p" template
  2021-12-17  6:09   ` Eric Sunshine
@ 2021-12-24 17:41     ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 11+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-12-24 17:41 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Git List, Junio C Hamano, Phillip Wood, Jeff King, Dan Jacques,
	Eric Wong, Jonathan Nieder, Mike Hommey,
	Đoàn Trần Công Danh, Victoria Dye


On Fri, Dec 17 2021, Eric Sunshine wrote:

> On Thu, Dec 16, 2021 at 11:40 PM Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>> [...]
>> But as it turns out we can use this neat trick of only doing a "mkdir
>> -p" if the $(wildcard) macro tells us the path doesn't exist. A re-run
>> of a performance test similar to thatnoted downthread of [1] in [2]
>> shows that this is faster, in addition to being less verbose and more
>> reliable (this uses my "git-hyperfine" thin wrapper for "hyperfine"[3]):
>
> s/thatnoted/that noted/
>
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> ---
>> diff --git a/shared.mak b/shared.mak
>> @@ -90,3 +92,18 @@ ifndef V
>> +## Is racy, but in a good way; we might redundantly (and safely)
>> +## "mkdir -p" when running in parallel, but won't need to exhaustively
>> +## individual rules for "a" -> "prefix" -> "dir" -> "file" if given a
>> +## "a/prefix/dir/file". This can instead be inserted at the start of
>> +## the "a/prefix/dir/file" rule.
>
> Is there a word missing between "exhaustively" and "individual"?

Thanks. I addressed both of these in the v2, for which I accidentally
broke the threading by omitting In-Reply-To (sorry!):
https://lore.kernel.org/git/cover-v2-0.8-00000000000-20211224T173558Z-avarab@gmail.com/

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-12-24 17:42 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-17  1:39 [PATCH 0/8] Makefile: optimize noop runs, add shared.mak Ævar Arnfjörð Bjarmason
2021-12-17  1:39 ` [PATCH 1/8] Makefiles: add "shared.mak", move ".DELETE_ON_ERROR" to it Ævar Arnfjörð Bjarmason
2021-12-17  1:39 ` [PATCH 2/8] Makefile: disable GNU make built-in wildcard rules Ævar Arnfjörð Bjarmason
2021-12-17  1:39 ` [PATCH 3/8] Makefile: define $(LIB_H) in terms of $(FIND_SOURCE_FILES) Ævar Arnfjörð Bjarmason
2021-12-17  1:39 ` [PATCH 4/8] Makefile: move ".SUFFIXES" rule to shared.mak Ævar Arnfjörð Bjarmason
2021-12-17  1:39 ` [PATCH 5/8] Makefile: move $(comma), $(empty) and $(space) " Ævar Arnfjörð Bjarmason
2021-12-17  1:39 ` [PATCH 6/8] Makefile: add "$(QUIET)" boilerplate " Ævar Arnfjörð Bjarmason
2021-12-17  1:39 ` [PATCH 7/8] Makefile: use $(wspfx) for $(QUIET...) in shared.mak Ævar Arnfjörð Bjarmason
2021-12-17  1:39 ` [PATCH 8/8] Makefiles: add and use wildcard "mkdir -p" template Ævar Arnfjörð Bjarmason
2021-12-17  6:09   ` Eric Sunshine
2021-12-24 17:41     ` Ævar Arnfjörð Bjarmason

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.