autotools - 更改configure.ac中的*FLAGS与使用子项目进行缓存

标签 autotools autoconf automake cflags

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

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

这在简单调用 configure 时有效。一旦发生以下情况之一:

  1. CFLAGS 在调用 configure 时导出到环境中
  2. CFLAGSconfigure 命令行中设置
  3. 使用缓存(configure -C)

这种方法不再有效。在前两种情况下,导出的 CFLAGS 会被简单地忽略;在最后一个中,configure 失败并显示

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

<小时/>

我已经成功地通过以下方式使其可靠地工作:

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 来实现此目的?

最佳答案

除了跨多个顶级 configure 运行进行缓存之外,我终于让它正常工作了。这个想法是破解 autoconf 的内部变量以获得所需的功能,而且这并不太难:

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

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

  • 破解 ac_cv_env_CF​​LAGS_{set,value} 以分别包含 set 和修改后的 CFLAGS

这会导致两个问题:

  1. 使用缓存,./config.status --recheck 将再次执行对 CFLAGS 的修改,即使此修改已被缓存,从而导致重复标志。仅当尚未解决此问题时才进行修改。
  2. 当使用现有的config.cache调用顶级配置时,损坏是不可避免的,因为config.cache一致性检查执行得太早,它无法受到影响。只有当我们在命令行(或环境)上传递 CFLAGS 包括 configure 修改时,此检查才会通过,不可能周围。唯一的解决办法是在配置所有子包后删除 config.cache。由于子包配置期间的缓存仍然有效,我发现这是可以接受的。

顶级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 仅打印 all-local 目标中 $CFLAGS 的值。

输出如下:

$ 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

关于autotools - 更改configure.ac中的*FLAGS与使用子项目进行缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34124337/

相关文章:

使用 autoconf 检查 C#define 的值

c++ - 如何使用 autotools 构建 Python C 扩展模块

shell - autoconf:我应该始终使用 AS_IF 而不是 if 和 m4_if 吗?

c++ - 带 openc 的自动工具(未定义引用)

c++ - gcov:从共享库生成 .gcda 输出?

python - autotools:将常量从configure.ac传递到python脚本

c - 如何使用 DejaGnu 设置单元测试

linux - 查找要与 dlload 一起使用的共享库名称

Linux Pam 创建静态库而不是共享库

c++ - 如何修复 Makefile.am asterisk-Cpp : C++ Static Library 中的错误