On 06/11/2020 18:18, Jeff King wrote: > On Thu, Nov 05, 2020 at 09:03:49PM +0000, Ramsay Jones wrote: > >> diff --git a/Documentation/Makefile b/Documentation/Makefile >> index 652d57a1b6..5c680024eb 100644 >> --- a/Documentation/Makefile >> +++ b/Documentation/Makefile >> @@ -272,7 +272,9 @@ install-html: html >> ../GIT-VERSION-FILE: FORCE >> $(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) GIT-VERSION-FILE >> >> +ifneq ($(MAKECMDGOALS),clean) >> -include ../GIT-VERSION-FILE >> +endif > > Calling out "clean" here specially feels somewhat backwards to me, in > terms of Makefile design. In an ideal world we provide all of the > dependencies to "make", and based on the targets we are building, it > decides what needs to be done. > > This works with normal targets, obviously, but also with variables. If > we do: > > FOO = $(shell do-the-thing) > > then we execute that command only when $(FOO) is needed[1]. > > But "include" here is tricky. It is loaded regardless of whether the > values it contains are needed or not. I wonder if we could do better by > giving make more information about what we're expecting to get from it. > I.e., if we wrote: > > GIT_VERSION = $(shell awk '{print $3}' GIT-VERSION-FILE) > > Then "make clean", not needing the value of $(GIT_VERSION), wouldn't run > that shell snippet at all. Of course there's a catch; we are also > relying on the include to trigger the dependency. So it is really more > like: > > GIT_VERSION = $(shell make GIT-VERSION-FILE && awk '{print $3}' GIT-VERSION-FILE) > > I'm not sure how bad that is. Re-invoking make seems like it could get > expensive, especially for the common case that we're building actual > binaries and we _do_ need the version. But we could probably cut "make" > out of the loop entirely. Generating GIT-VERSION-FILE is already a FORCE > target, so really: > > GIT_VERSION = $(shell ./GIT-VERSION-GEN) > > would be equivalent-ish (with some output changes, and possibly we'd > want to stash the value in a file for any other scripts to make use of). > > This is all just stuff I've written in my editor and not tried. I won't > be surprised if there are some gotchas. But it at least seems like a > conceptually cleaner path. > > -Peff > > [1] Variable assignment actually has a slight problem in the opposite > direction: it wants to run the shell snippet every time the variable > is referenced. There's a trick to get around that described in > 0573831950 (Makefile: avoid running curl-config unnecessarily, > 2020-04-04). > > It's built around evals. In fact, I suspect you could build a > function around eval that actually works similar to include, but > lazy-loads the file only when one of its stubs is referenced. I.e., > something like: > > GIT_VERSION = $(eval include GIT-VERSION-FILE) > > would probably work (and for other includes, multiple variables > could mention the same file; as soon as it gets included, it > overwrites the stubs). > Heh, in another reply in this thread, I mentioned that I had an alternate patch I was toying with. If I tell you it was inspired by your commit 0573831950 (Makefile: avoid running curl-config unnecessarily, 04-04-2020), you would probably not be surprised that it looks similar to what you outline here. I had only just started looking at this approach, but it has some wrinkles, so I thought I would look at it after submitting this series 'because this is an easy win'! ;-) I hadn't done so yet, but I had planned to modify the GIT-VERSION-GEN script (with -v parameter, say) to just output the version to stdout, because it would save a sed invocation. It currently looks something like this: diff --git a/Makefile b/Makefile index 372139f1f2..f166fbe067 100644 --- a/Makefile +++ b/Makefile @@ -493,7 +493,11 @@ all:: GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN --include GIT-VERSION-FILE + +ifeq ($(wildcard GIT-VERSION-FILE),) +$(shell ./GIT-VERSION-GEN) +endif +GIT_VERSION = $(eval GIT_VERSION := $$(shell cat GIT-VERSION-FILE | sed -e 's/^GIT_VERSION = //'))$(GIT_VERSION) # Set our default configuration. # Ignore the 'ifeq' for now (I had several versions, including getting rid of the GIT-VERSION-FILE rule, but that caused problems without changing the Documentation/Makefile, and several others ... (including in contrib)). So, I haven't worked everything out yet, but I had planned to look at this next. ATB, Ramsay Jones