Subject: bug#13760: am__make_dryrun fails to handle GNU make -I option

From: Boris Kolpackov <[email-masked]>
Date: Tue, 19 Feb 2013 12:34:26 +0200

Hi,

After upgrading from 1.11.1 to 1.11.6 or 1.12.6, or 1.13.1 my
project's dist target stopped working. After some debugging,
the culprit turned out to be am__make_dryrun function that
mis-detects make dry-run mode (make -n) if make flags contain
a -I option with a path containing character 'n'. In my case,
flags come from the MAKEFLAGS environment variable which has
the following value:

-I ~/work/build -I/opt/qnx632/target/qnx6/usr/include

The MAKEFLAGS value as passed to the shell by make then becomes
(note the missing '-' in the first option -- that's documented
GNU make behavior):

"I /home/boris/work/build -I /opt/qnx632/target/qnx6/usr/include"

am__make_dryrun then goes ahead and check each word in this list
for the presence of 'n' and finds it in the path.

I've had some dealings with GNU make's MAKEFLAGS and the semantics
is quite convoluted. GNU make doesn't just store flags the way they
appeared on the command line. Instead, it translates, combines, and
rearranges them in a certain way. For example, GNU make will combine
certain one-letter options (including -n) and place them at the front
of MAKEFLAGS without the preceding '-'. For example:

make -n -k -j 2 foo=bar => "nk --jobserver-fds=3,4 -j -- foo=bar"

Generally, in GNU make, the -n option (or its aliases) will always
be translated and come in the first word of MAKEFLAGS. And the first
word in MAKEFLAGS is always one of the following:

1. Empty. If no "old" options (those that are combined in the
   first word) were specified but a new option was, then GNU make
   will add a leading space to the MAKEFLAGS, for example:

   make -j 2 => " --jobserver-fds=3,4 -j"

2. The "old" options combination (including -n), one letter per
   option, for example:

   make -n -k -j 2 => "nk --jobserver-fds=3,4 -j"

3. Command line variable assignment. If no options were specified
   ("old" or "new") but a variable assignment was specified, then
   the first word will be the variable assignment, for example
   (note that there is no leading space as in (2)):

   make foo=bar => "foo=bar"

So, based on this knowledge, for GNU make, all we need to do is
examine the first word in MAKEFLAGS. If it contains '=', then it
is a variable assignment, otherwise, we search for the 'n' character.

The complication is that we have to also support other makes (BSD,
Solaris). I have no idea about their MAKEFLAGS behavior.

Boris