[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: makefile rules

From: Bruno Haible
Subject: Re: makefile rules
Date: Tue, 21 Dec 2021 10:41:47 +0100

Paul Eggert wrote:
> One related topic. Many Gnulib modules list makefile rules containing 
> many instances of '&& \' at line ends. How about if we omit the '&& \' 
> when that's easy? Something like the attached

There are three problems with this patch:

1) A maintainability problem.

-       { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-         sed -e 's|@''HAVE_ALLOCA_H''@|$(HAVE_ALLOCA_H)|g' < 
$(srcdir)/alloca.in.h; \
-       } > $@-t && \

+       $(AM_V_at)sed -n \
+           -e h \
+           -e '1s,.*,/* DO NOT EDIT! GENERATED AUTOMATICALLY! *,w $@-t' \
+           -e g \
+           -e 's|@''HAVE_ALLOCA_H''@|$(HAVE_ALLOCA_H)|g' \
+           -e 'w $@-t' \
+           $(srcdir)/alloca.in.h

The number of developers who know about 'echo', 'cat', and *simple* 'sed'
commands is far larger than the number of developers who know about
advanced 'sed' commands (with hold space etc.). This kind of transformation
decreases maintainability significantly.

2) A transparency / serviceability problem.

 alloca.h: alloca.in.h $(top_builddir)/config.status
-       $(AM_V_GEN)rm -f $@-t $@ && \

 alloca.h: alloca.in.h $(top_builddir)/config.status
+       $(AM_V_at)rm -f $@-t $@
+       $(AM_V_at)$(MKDIR_P) '%reldir%'
+       $(AM_V_at)...
+       $(AM_V_GEN)mv -f $@-t $@

The old code prints "GEN alloca.h" before executing the commands;
the new code prints "GEN alloca.h" after most commands are done.
That means, when the commands don't behave right (loop endlessly
or whatever) and the user interrupts them with Ctrl-C, he will have
no clue which rule was misbehaving.

3) It suggests a coding style that only works when there are no shell
variable assignments in the command. In other words, when writing new
Makefile rules, a developer would have to consider whether the rules
need to assign a shell variable, and use one or the other coding style
depending on this.

This is added complexity. It is better if the developer has 1 coding
style that works in either case.

> This would break apart 'make' recipes into smaller commands, which is a 
> good thing.

I don't see it as a good thing. Better keep things in natural units. Here,
the natural unit is to create 1 file — whether it's done in 1 or 10 lines
of code, does not matter.

Also, with general 'make', every command triggers a subshell, therefore
smaller commands mean more /bin/sh invocations and longer execution times.

> And it would let GNU make invoke rm, mkdir, sed, and mv 
> directly instead of via a subshell, which would be a minor efficiency plus.

Now, that's a micro-optimization in the bad sense of the word. It's like
rewriting C code such as
  x += 1;
because you know that you current compiler will generate faster code for the

The real fix should be to improve GNU make in such a way that it does not
make a difference whether one writes



        command1 && command2


        { command1 && command2; }

> (I suppose we should also omit that 'rm -f $@-t $@'; it shouldn't be 
> needed

It can needed when people have done something like
  $ make
  $ sudo make check

> and it just slows things down on slow build hosts like some of 
> those that I use.)

On the slow build hosts that I use, the entire set of commands for
creating .h files is faster than compiling a single .c file, and
the time to execute 'configure' exceeds that by 2 or 3 orders of

In other words, the potential to gain build speed is much higher
when concentrating on the parts of the builds that take more
time. There's nearly nothing to be gained by attempting to optimize
build rules.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]