Search code examples
autotools

What is the precedence in autotools user variables?


If you have a project with a configure.ac and many Makefile.am files, it is possible to pass a user variable such as CFLAGS to configure as

CFLAGS=DEBUG_OPTIONS ./configure

But, if inside configure.ac, you have a statement like CFLAGS=NON_DEBUG_OPTIONS (you can assume this is coming after AC_PROG_CC) will the final objects be debuggable or not?


Solution

  • From Autoconf's perspective, CFLAGS is an output variable, just like those your configure.ac declares explicitly via the AC_SUBST macro. The details of output variables are spread about a bit in the Autoconf documentation, but basically,

    [they] are shell variables whose values are substituted into files that configure outputs.

    (Autoconf manual, section 7.2)

    The AC_PROG_CC macro provides a default value for CFLAGS if that variable is not already set (e.g. from the environment); otherwise, it leaves the value unchanged. This is why it is generally effective to specify CFLAGS and certain other output variables to Autoconf configure scripts on the command line in the way you show -- it is standard shell syntax that causes the variable binding to be placed in the environment of the command being run.

    The manual goes on to say,

    [Being an output variable] means that AC_OUTPUT replaces instances of ‘@variable@’ in input files with the value that the shell variable variable has when AC_OUTPUT is called.

    (Emphasis added.) Although that's in the docs of the AC_SUBST macro, it applies to preset output variables the same as it does to those set via AC_SUBST. Thus, if configure assigns a new value to CFLAGS before AC_OUTPUT, then the last such value assigned is the one that is substituted into your Makefiles. In direct answer to your question, then, the situation you describe will result in a build with non-debug options.

    Note also that this is not a precedence issue at all because there's only one variable involved. The CFLAGS set in the environment is effectively the same variable that the configure script accesses and uses internally, that you can modify within via assignment, and that ultimately is substituted into your Makefiles. Thus, it's a simple order of operations question.

    Finally, I observe that your question arises at all only if you violate an Autotools principle regarding "user variables" such as CFLAGS. The Autoconf docs for that variable put it this way:

    Sometimes package developers are tempted to set user variables such as CFLAGS because it appears to make their job easier. However, the package itself should never set a user variable, particularly not to include switches that are required for proper compilation of the package. Since these variables are documented as being for the package builder, that person rightfully expects to be able to override any of these variables at build time. If the package developer needs to add switches without interfering with the user, the proper way to do that is to introduce an additional variable. Automake makes this easy by introducing AM_CFLAGS (see Flag Variables Ordering), but the concept is the same even if Automake is not used.

    (Emphasis added.)

    Extra finally, note that a user can always override an output variable or other make variable by setting a value on the make command line, as an argument to make, either instead of or in addition to specifying it to configure.