假设我希望在我的 configure
脚本中向 CFLAGS
添加一个特定标志,该标志应该传播到所有子项目的 configure
脚本:
CFLAGS+=" -Dfoobar"
export CFLAGS
AC_CONFIG_SUBDIRS([sub])
这在简单调用 configure
时有效。一旦发生以下情况之一:
CFLAGS
在调用configure
时导出到环境中CFLAGS
在configure
命令行中设置- 使用缓存(
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_CFLAGS_{set,value}
以分别包含set
和修改后的CFLAGS
这会导致两个问题:
- 使用缓存,
./config.status --recheck
将再次执行对 CFLAGS 的修改,即使此修改已被缓存,从而导致重复标志。仅当尚未解决此问题时才进行修改。 - 当使用现有的
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/