autotoolsautoconfautomakecflags

Changing *FLAGS in configure.ac vs. caching with subprojects


Say I wish to add a specific flag to CFLAGS within my configure script, that should propagate to all subprojects' configure scripts:

CFLAGS+=" -Dfoobar"
export CFLAGS
AC_CONFIG_SUBDIRS([sub])

This works when configure is invoked trivially. As soon as one of the following happens:

  1. CFLAGS is exported in the environment when configure is invoked
  2. CFLAGS is set on configure command-line
  3. caching is used (configure -C)

This approach no longer works. In the first two cases, the exported CFLAGS is simply ignored; and in the last one, configure fails with

configure: error: `CFLAGS' was not set in the previous run


I have managed to get this working reliably by:

AM_CFLAGS+=" -Dfoobar"
export AM_CFLAGS
AC_SUBST([AM_CFLAGS]) # repeat this line in every configure.ac for each *FLAGS
AC_CONFIG_SUBDIRS([sub])

Considering there are multiple subprojects, and multiple *FLAGS variables that may need to be set like this, this is half-way okay but still suboptimal. Is there a way to make this work by only hacking the top-level configure.ac?


Solution

  • The ultimate solution was to un-precious the affected variables:

    Top-level configure.ac:

    AC_INIT([test], [0.1])
    AC_CONFIG_MACRO_DIR([m4]) # for ax_append_flag.m4
    AM_INIT_AUTOMAKE([-Wall -Werror foreign])
    
    AC_PROG_CC
    AC_PROG_SED
    
    # Modify the CFLAGS. AX_APPEND_FLAG makes sure not to add the flag if it's already there
    AX_APPEND_FLAG([-Dtop-configure], [CFLAGS])
    
    AC_DEFUN([AX_UNPRECIOUS], [
        m4_define([_AC_PRECIOUS_VARS], m4_bpatsubst(_AC_PRECIOUS_VARS, [$1
    ], []))
    ])
    AX_UNPRECIOUS([CFLAGS])
    export CFLAGS
    
    AC_CONFIG_SUBDIRS([sub])
    AC_CONFIG_FILES([Makefile])
    AC_OUTPUT
    

    Behind the curtains, CFLAGS is never seen as precious and thus never cached or passed to sub-package configures—they see it as an environment variable exclusively, and then cache it themselves in the common top-level config.cache.

    This works very reliably, and improves upon my previous solution by allowing cached values even across top-level configure runs (and by being simpler).