diff mbox series

[v2,1/1] Makefile: use `git ls-files` to list header files, if possible

Message ID cb253bd0cf2896cf31516079a89ec2dab21032cf.1551707225.git.gitgitgadget@gmail.com (mailing list archive)
State New, archived
Headers show
Series Avoid calling find in the Makefile, if possible | expand

Commit Message

Derrick Stolee via GitGitGadget March 4, 2019, 1:47 p.m. UTC
From: Johannes Schindelin <johannes.schindelin@gmx.de>

In d85b0dff72 (Makefile: use `find` to determine static header
dependencies, 2014-08-25), we switched from a static list of header
files to a dynamically-generated one, asking `find` to enumerate them.

Back in those days, we did not use `$(LIB_H)` by default, and many a
`make` implementation seems smart enough not to run that `find` command
in that case, so it was deemed okay to run `find` for special targets
requiring this macro.

However, as of ebb7baf02f (Makefile: add a hdr-check target,
2018-09-19), $(LIB_H) is part of a global rule and therefore must be
expanded. Meaning: this `find` command has to be run upon every
`make` invocation. In the presence of many a worktree, this can tax the
developers' patience quite a bit.

Even in the absence of worktrees or other untracked files and
directories, the cost of I/O to generate that list of header files is
simply a lot larger than a simple `git ls-files` call.

Therefore, just like in 335339758c (Makefile: ask "ls-files" to list
source files if available, 2011-10-18), we now prefer to use `git
ls-files` to enumerate the header files to enumerating them via `find`,
falling back to the latter if the former failed (which would be the case
e.g. in a worktree that was extracted from a source .tar file rather
than from a clone of Git's sources).

This has one notable consequence: we no longer include `command-list.h`
in `LIB_H`, as it is a generated file, not a tracked one, but that is
easily worked around. Of the three sites that use `LIB_H`, two
(`LOCALIZED_C` and `CHK_HDRS`) already handle generated headers
separately. In the third, the computed-dependency fallback, we can just
add in a reference to $(GENERATED_H).

Likewise, we no longer include not-yet-tracked header files in `LIB_H`.

Given the speed improvements, these consequences seem a comparably small
price to pay.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Makefile | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Comments

Ramsay Jones March 4, 2019, 8:38 p.m. UTC | #1
On 04/03/2019 13:47, Johannes Schindelin via GitGitGadget wrote:
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> In d85b0dff72 (Makefile: use `find` to determine static header
> dependencies, 2014-08-25), we switched from a static list of header
> files to a dynamically-generated one, asking `find` to enumerate them.
> 
> Back in those days, we did not use `$(LIB_H)` by default, and many a
> `make` implementation seems smart enough not to run that `find` command
> in that case, so it was deemed okay to run `find` for special targets
> requiring this macro.
> 
> However, as of ebb7baf02f (Makefile: add a hdr-check target,
> 2018-09-19), $(LIB_H) is part of a global rule and therefore must be
> expanded. Meaning: this `find` command has to be run upon every
> `make` invocation. In the presence of many a worktree, this can tax the
> developers' patience quite a bit.
> 
> Even in the absence of worktrees or other untracked files and
> directories, the cost of I/O to generate that list of header files is
> simply a lot larger than a simple `git ls-files` call.
> 
> Therefore, just like in 335339758c (Makefile: ask "ls-files" to list
> source files if available, 2011-10-18), we now prefer to use `git
> ls-files` to enumerate the header files to enumerating them via `find`,
> falling back to the latter if the former failed (which would be the case
> e.g. in a worktree that was extracted from a source .tar file rather
> than from a clone of Git's sources).
> 
> This has one notable consequence: we no longer include `command-list.h`
> in `LIB_H`, as it is a generated file, not a tracked one, but that is

Heh, just to be _unnecessarily_ picky, but this is not always true.
The 'command-list.h' header is _sometimes_ not included in the LIB_H
variable - it simply depends on whether it has been generated by the
time the $(FIND) is called.

Obviously, not worth a re-roll. Otherwise, this LGTM.

Thanks!

ATB,
Ramsay Jones

> easily worked around. Of the three sites that use `LIB_H`, two
> (`LOCALIZED_C` and `CHK_HDRS`) already handle generated headers
> separately. In the third, the computed-dependency fallback, we can just
> add in a reference to $(GENERATED_H).
> 
> Likewise, we no longer include not-yet-tracked header files in `LIB_H`.
> 
> Given the speed improvements, these consequences seem a comparably small
> price to pay.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>  Makefile | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/Makefile b/Makefile
> index c5240942f2..0c4712cb48 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -841,7 +841,8 @@ VCSSVN_LIB = vcs-svn/lib.a
>  
>  GENERATED_H += command-list.h
>  
> -LIB_H = $(shell $(FIND) . \
> +LIB_H := $(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \
> +	$(FIND) . \
>  	-name .git -prune -o \
>  	-name t -prune -o \
>  	-name Documentation -prune -o \
> @@ -2363,7 +2364,7 @@ else
>  # should _not_ be included here, since they are necessary even when
>  # building an object for the first time.
>  
> -$(OBJECTS): $(LIB_H)
> +$(OBJECTS): $(LIB_H) $(GENERATED_H)
>  endif
>  
>  exec-cmd.sp exec-cmd.s exec-cmd.o: GIT-PREFIX
>
Ramsay Jones March 4, 2019, 9:01 p.m. UTC | #2
On 04/03/2019 20:38, Ramsay Jones wrote:
> 
> 
> On 04/03/2019 13:47, Johannes Schindelin via GitGitGadget wrote:
>> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>>
>> In d85b0dff72 (Makefile: use `find` to determine static header
>> dependencies, 2014-08-25), we switched from a static list of header
>> files to a dynamically-generated one, asking `find` to enumerate them.
>>
>> Back in those days, we did not use `$(LIB_H)` by default, and many a
>> `make` implementation seems smart enough not to run that `find` command
>> in that case, so it was deemed okay to run `find` for special targets
>> requiring this macro.
>>
>> However, as of ebb7baf02f (Makefile: add a hdr-check target,
>> 2018-09-19), $(LIB_H) is part of a global rule and therefore must be
>> expanded. Meaning: this `find` command has to be run upon every
>> `make` invocation. In the presence of many a worktree, this can tax the
>> developers' patience quite a bit.
>>
>> Even in the absence of worktrees or other untracked files and
>> directories, the cost of I/O to generate that list of header files is
>> simply a lot larger than a simple `git ls-files` call.
>>
>> Therefore, just like in 335339758c (Makefile: ask "ls-files" to list
>> source files if available, 2011-10-18), we now prefer to use `git
>> ls-files` to enumerate the header files to enumerating them via `find`,
>> falling back to the latter if the former failed (which would be the case
>> e.g. in a worktree that was extracted from a source .tar file rather
>> than from a clone of Git's sources).
>>
>> This has one notable consequence: we no longer include `command-list.h`
>> in `LIB_H`, as it is a generated file, not a tracked one, but that is
> 
> Heh, just to be _unnecessarily_ picky, but this is not always true.
> The 'command-list.h' header is _sometimes_ not included in the LIB_H
> variable - it simply depends on whether it has been generated by the
> time the $(FIND) is called.
> 
> Obviously, not worth a re-roll. Otherwise, this LGTM.

Ahem! Obviously, I didn't read the commit message closely enough!

However, _before_ this change, then 'command-list.h' was sometimes
not included in $(LIB_H) ...

Sorry for the noise!

ATB,
Ramsay Jones
Jeff King March 4, 2019, 9:43 p.m. UTC | #3
On Mon, Mar 04, 2019 at 05:47:06AM -0800, Johannes Schindelin via GitGitGadget wrote:

> Therefore, just like in 335339758c (Makefile: ask "ls-files" to list
> source files if available, 2011-10-18), we now prefer to use `git
> ls-files` to enumerate the header files to enumerating them via `find`,
> falling back to the latter if the former failed (which would be the case
> e.g. in a worktree that was extracted from a source .tar file rather
> than from a clone of Git's sources).

Thanks, this version looks good to me, and seems like an obvious first
step regardless of whether we want to later push it into a sub-make.

-Peff
diff mbox series

Patch

diff --git a/Makefile b/Makefile
index c5240942f2..0c4712cb48 100644
--- a/Makefile
+++ b/Makefile
@@ -841,7 +841,8 @@  VCSSVN_LIB = vcs-svn/lib.a
 
 GENERATED_H += command-list.h
 
-LIB_H = $(shell $(FIND) . \
+LIB_H := $(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \
+	$(FIND) . \
 	-name .git -prune -o \
 	-name t -prune -o \
 	-name Documentation -prune -o \
@@ -2363,7 +2364,7 @@  else
 # should _not_ be included here, since they are necessary even when
 # building an object for the first time.
 
-$(OBJECTS): $(LIB_H)
+$(OBJECTS): $(LIB_H) $(GENERATED_H)
 endif
 
 exec-cmd.sp exec-cmd.s exec-cmd.o: GIT-PREFIX