Subject: Re: Re-execute with the "correct" make implementation

From: Eric Blake <[email-masked]>
Date: Thu, 03 Jan 2013 15:40:49 -0700

[dropping autoconf]

On 01/03/2013 03:05 PM, Stefano Lattarini wrote:
> For usual targets, that is easy.  I don't even think that must be done
> at Automake-NG level; one can simply use 'GNUmakefile.am' as Automake-NG
> input file (instead of the usual 'Makefile.am'), add 'GNUmakefile' to
> an AC_CONFIG_FILES invocation, and then hand-write a simple Makefile
> acting as a thin wrapper:
> 
>   TARGETS = all check clean distclean dist distcheck install uninstall
>   .PHONY: $(TARGETS)
>   $(TARGETS): ; @gmake $(AM_MAKEFLAGS) $@

Is that sufficient, or will it bite users that get by with 'make check'
but then fails when they do 'make file', where 'file:' was a specific
rule in GNUMakefile?  It's too bad we can't rely on GNU make extensions
like $(MAKECMDGOALS) as a way to override every single target at once.
BSD make has $(.TARGETS) as something that looks like it would do the
same, and we might even get lucky to come up with constructs that work
nicely in some versions of make without choking any other versions of make.

> 
> The super-nice developer can even turn this Makefile into a Makefile.in,
> use '@GNU_MAKE@' rather than simply 'gmake', and (from configure) look
> for a GNU make implementation in the system and AC_SUBST '@GNU_MAKE@' to
> its absolute path.

How much of this niceness should be done by Automake-NG itself, rather
than making developers duplicate work?

> 
>> In fact, is it possible to write a
>> Makefile that compares the encoded settings of $(MAKE) set at configure
>> time, against the current value of $(MAKE) from the current make
>> implementation running the makefile, and which can re-execute and/or
>> loudly abort if there is a mismatch?
>>
> Loudly aborting on such a mismatch would likely be possible I think, by
> adding something like this to the footer.am:
> 
>     all check clean distclean dist distcheck install uninstall: am--no-make-mismatch
>     am--no-make-mismatch:
>         @test '$(MAKE)' = '@MAKE@' || fatal mismatch

But will that always work?  If there are any uses of GNU-make specific
syntax earlier in the file, will a less powerful make have already
choked on that earlier syntax before getting to this point, negating the
usefulness of the sanity check?

I speak from personal experience of using libvirt on a BSD machine;
libvirt has already chosen to require GNU make.  So I used ./configure
MAKE=gmake, then every so often I type 'make' instead of 'gmake' on that
package, and get:

$ make
Error expanding embedded variable.

as my reminder to use gmake.  But I haven't taken time to track whether
that error would happen from just automake code in a package that tried
to be portable to all make, or whether it specific to the fact that
libvirt's Makefile.am already used GNU-isms.

> 
> Well, almost: currently, if the make implementation in use (as specified
> by ${MAKE-make}) doesn't set $(MAKE) automatically, configure code generated
> by AM_INIT_AUTOMAKE causes $(MAKE) to be explicitly defined to '@MAKE@' in
> the generated Makefile.in (to be later subst'ed by 'config.status' in the
> resulting Makefile).  But this probably happens only with old broken make
> implementations (and maybe configure could start simply punting when such
> a borked make is detected?).

Is it worth a probe to see how many 'make's in the wild still fail to
set $(MAKE)?

> 
> In conclusion: if this approach can be made to work, a patch would be
> very welcome, and could go directly into 1.13.2 (as the change would not
> be invasive in the least, and would offer more reliable build systems).

Alas, I'm busy enough with other things (such as an overdue autoconf
release) that it probably won't be me writing such a patch.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org