Subject: Re: bug#35526: misleading documentation about flag variable ordering

From: Nick Bowler <[email-masked]>
Date: Wed, 1 May 2019 14:28:01 -0400

On 5/1/19, Daniel Kahn Gillmor <[email-masked]> wrote:
> https://www.gnu.org/software/automake/manual/automake.html#Flag-Variables-Ordering
> says:
>
>     The reason ‘$(CPPFLAGS)’ appears after ‘$(AM_CPPFLAGS)’ or
>     ‘$(mumble_CPPFLAGS)’ in the compile command is that users should
>     always have the last say.
>
> The implication here is that for any of the *FLAGS variables, later
> options are inherently more effective than earlier options.
>
> This is not the case universally.  For example -Wl,--as-needed is more
> effective if it shows up earlier in the command line.  (see
> https://bugs.debian.org/347650 for a libtool-related problem for that
> kind of ordering/re-ordering)

It's still mostly true, and it really is more about turning off options
that may be turned on by the package but the user does not want.  Even
in the case of --as-needed, if the package had AM_LDFLAGS = -Wl,--as-needed
the user could (in principle) cancel it with LDFLAGS = -Wl,--no-as-needed,
since the user flags appear later.  If these were reversed then the
package option would override anything the user tried to do.

But it is true that this is not universal.  Not every compiler option
has a way to cancel its effect later on the command line.  In the case
of CPPFLAGS, -I options are an example where later options are in some
sense "less effective" than earlier options.

But on the other hand, -D options are commonly placed in CPPFLAGS and
in that case their effects can be canceled and/or changed by later
options.

Since all the user-provided flags are lumped together in a single
variable they have to go _somewhere_ as a unit, and convention puts them
after the corresponding package-set flags, so compilation commands look
something like:

  cc <package-cppflags> <user-cppflags> <package-cflags> <user-cflags> \
      <operational-switches> <files>

and linking (when the C compiler is used for linking) looks like:

  cc <package-cflags> <user-cflags> <package-ldflags> <user-ldflags> \
      <operational-switches> <objects-and-libraries>

(Note that the convention puts LDFLAGS before libraries so things
like LDFLAGS=-Wl,--as-needed _should_ work as expected, libtool
issues notwithstanding).

Obviously this scheme is not perfect in every possible scenario, but
the only way to handle every possible scenario is probably to have the
user to write all the compiler commands manually, in which case there
is no point in having a build system.

> It would be good if the documentation could avoid implying something
> that isn't the case, because that dubious suggestion casts doubt on the
> rest of the documentation (or on the user's understanding of the rest of
> the buildsystem)

The manual can always be improved.  Do you have a suggestion for how to
write this paragraph to make it better?

Cheers,
  Nick