更改configure.ac中的* FLAGS与子项目的缓存

时间:2015-12-06 23:52:18

标签: autotools autoconf automake cflags

假设我希望在CFLAGS脚本中向configure添加一个特定的标记,该标记应该传播到所有子项目' configure脚本:

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

当简单地调用configure时,这是有效的。一旦发生下列情况之一:

    调用CFLAGS时,
  1. configure将在环境中导出
  2. CFLAGS命令行上设置了
  3. configure
  4. 使用缓存(configure -C
  5. 此方法不再有效。在前两种情况下,导出的CFLAGS被忽略;在最后一个中,configure失败并带有

      

    配置:错误:`CFLAGS'没有在上一次运行中设置

    我已经设法通过以下方式可靠地运作:

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

    考虑到有多个子项目和多个*FLAGS变量可能需要像这样设置,这是中途可以,但仍然不是最理想的。有没有办法只通过攻击顶级configure.ac来完成这项工作?

2 个答案:

答案 0 :(得分:0)

除了在多个顶级configure次运行中进行缓存外,我终于得到了这个功能。我们的想法是破解autoconf的内部变量以获得所需的功能,这并不太难:

  • 修改CFLAGS
  • 黑客ac_configure_args包含修改后的CFLAGS,而不是任何外部检测到的CFLAGS

这立即解决了问题描述中的问题1.和2.(外部CFLAGS)。为了修复缓存,我不得不:

  • 黑客ac_cv_env_CFLAGS_{set,value}分别包含set和修改后的CFLAGS

这导致两个问题:

  1. 通过缓存,./config.status --recheck将再次执行对CFLAGS的修改,即使此修改已被缓存,也会导致重复的标记。仅在尚未完成修改时解决此问题。
  2. 在使用现有config.cache调用顶级配置时,损坏是不可避免的,因为config.cache一致性检查是如此早地执行,不会受到影响。只有当我们在命令行(或环境)上传递CFLAGS 包括 configure - 修改时,才能通过此检查,无法绕过它。唯一的解决方法是在配置完所有子包后删除config.cache。由于子包配置期间的缓存仍然有效,我发现这是可以接受的。
  3. 顶级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])
    
    # Replace/add CFLAGS in/to ac_configure_args
    AS_CASE([$ac_configure_args],
        [*CFLAGS=*], [ac_configure_args=`AS_ECHO "$ac_configure_args" | $SED ["s|CFLAGS=[^']*|CFLAGS=$CFLAGS|"]`],
        [AS_VAR_APPEND([ac_configure_args],[" 'CFLAGS=$CFLAGS'"])]
    )
    
    # Fix the cache vars
    ac_cv_env_CFLAGS_set=set
    ac_cv_env_CFLAGS_value=$CFLAGS
    
    # exporting CFLAGS is not needed for sub-packages: they get CFLAGS from ac_configure_args
    
    AC_CONFIG_SUBDIRS([sub])
    AC_CONFIG_FILES([Makefile])
    AC_OUTPUT
    
    AC_MSG_NOTICE([removing config.cache])
    rm -f config.cache
    

    子级configure.ac

    AC_INIT([test-sub], [0.1])
    AC_CONFIG_MACRO_DIR([../m4])
    AM_INIT_AUTOMAKE([-Wall -Werror foreign])
    AC_PROG_CC
    AX_APPEND_FLAG([-Dsub-configure], [CFLAGS])
    AC_CONFIG_FILES([Makefile])
    AC_OUTPUT
    

    Makefile仅在$CFLAGS目标中打印all-local的值。

    输出如下:

    $ autoconf && ./configure -C >/dev/null && make | grep CFLAGS # 1st run
    sub CFLAGS: -g -O2 -Dtop-configure -Dsub-configure
    top CFLAGS: -g -O2 -Dtop-configure
    $ ./configure -C >/dev/null && make | grep CFLAGS # 2nd run
    sub CFLAGS: -g -O2 -Dtop-configure -Dsub-configure
    top CFLAGS: -g -O2 -Dtop-configure
    $ touch configure.ac && make | grep CFLAGS # recheck run
    running CONFIG_SHELL=/bin/sh /bin/sh ./configure -C CFLAGS=-g -O2 -Dtop-configure --no-create --no-recursion
    sub CFLAGS: -g -O2 -Dtop-configure -Dsub-configure
    top CFLAGS: -g -O2 -Dtop-configure
    $ CFLAGS=-Dexternal ./configure -C >/dev/null && make | grep CFLAGS # 1st run
    sub CFLAGS: -Dexternal -Dtop-configure -Dsub-configure
    top CFLAGS: -Dexternal -Dtop-configure
    $ CFLAGS=-Dexternal ./configure -C >/dev/null && make | grep CFLAGS # 2nd run
    sub CFLAGS: -Dexternal -Dtop-configure -Dsub-configure
    top CFLAGS: -Dexternal -Dtop-configure
    $ touch configure.ac && make | grep CFLAGS # recheck run
    running CONFIG_SHELL=/bin/sh /bin/sh ./configure -C CFLAGS=-Dexternal -Dtop-configure --no-create --no-recursion
    sub CFLAGS: -Dexternal -Dtop-configure -Dsub-configure
    top CFLAGS: -Dexternal -Dtop-configure
    

答案 1 :(得分:0)

最终的解决方案是un-precious受影响的变量:

顶级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

在窗帘后面,CFLAGS从未被视为珍贵,因此从未被缓存或传递给子包configure - 他们将其视为环境变量完全,然后将它们自己缓存在公共顶级config.cache中。

这非常可靠,并且通过允许缓存值甚至跨顶级配置运行(以及通过更简单)来改进我之前的解决方案。