5

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

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

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

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

这种方法不再有效。在前两种情况下,导出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

4

2 回答 2

1

最终的解决方案是不重视受影响的变量:

顶级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永远不会被视为珍贵,因此永远不会缓存或传递给子包configures-他们将其视为专有的环境变量,然后将其自己缓存在公共顶级中config.cache

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

于 2015-12-17T12:52:07.050 回答
1

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

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

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

  • hack分别ac_cv_env_CFLAGS_{set,value}包含set和修改CFLAGS

这导致两个问题:

  1. 使用缓存,./config.status --recheck将再次执行对 CFLAGS 的修改,即使此修改已被缓存,导致重复标志。仅在未完成修改时才进行修改可以解决此问题。
  2. 当使用现有的配置调用顶级配置时config.cache,损坏是不可避免的,因为config.cache一致性检查执行得太早,不会受到影响。只有当我们在命令行(或环境)上通过包括CFLAGS -modificationconfigure时,这个检查才会通过,没有办法绕过它。唯一的解决方法是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

Makefiles 只打印目标$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
于 2015-12-16T14:26:39.403 回答