使用Autotools的默认编译器标志

问题描述 投票:24回答:7

我想知道如何设置默认的编译器/链接器/等。标志,如果我使用Autoconf / Automake组合。

例如,如果我没有设置任何内容,则默认编译器标志为“-O2 -g”。我可以用其他东西覆盖它,例如,如果我想调试:

./configure 'CXXFLAGS=-O0 -g'

但我发现默认配置很愚蠢,因为如果我启用优化,调试将变得不可能。所以默认标志应该是“-O2”或“-O0 -g”,如果我运行没有参数的configure。我该怎么做?

编辑:我尝试了以下解决方案:

  • progname_CXXFLAGS=whatever放到Makefile.am。它不起作用,因为它将标志添加到默认标志而不是替换它们。
  • CXXFLAGS=whatever放入configure.ac。这有效,但后来我无法覆盖它。
makefile autoconf automake
7个回答
19
投票

根据autoconf手册(关于AC_PROG_CC):

如果使用GNU C编译器,请将shell变量GCC设置为“yes”。如果尚未设置输出变量CFLAGS,则将其设置为GNU C编译器的-g -O2(在GCC不接受-g的系统上为-O2),或者为其他编译器设置-g。如果您的包不喜欢此默认值,则可以插入该行

: ${CFLAGS=""}

在AC_INIT之后和AC_PROG_CC之前选择一个空的默认值。

同样,根据autoconf手册(关于AC_PROG_CXX):

如果使用GNU C ++编译器,请将shell变量GXX设置为“yes”。如果尚未设置输出变量CXXFLAGS,则将其设置为GNU C ++编译器的-g -O2(在G ++不接受-g的系统上为-O2),或者为其他编译器设置-g。如果您的包不喜欢此默认值,则可以插入该行

: ${CXXFLAGS=""}

在AC_INIT之后和AC_PROG_CXX之前选择一个空的默认值。


9
投票

如果您只想在运行configure时为自己设置默认标志,则有(至少)3种好方法可以执行此操作。在您的环境中设置CXXFLAGS(例如在.login或.bashrc中),使用CONFIG_SITE环境变量指定配置文件,或在$ prefix / share / config.site中设置CXXFLAGS所需的值。如果要为包的所有用户将默认标志设置为“-O2 -g”以外的其他标志,则需要更改所需内容,因为这样做会违反最少惊喜的主体。任何熟悉autoconf的人都希望默认标志为-O2 -g,你不应该改变它。

使用上面给出的第3个选项,然后就可以了

$ echo 'CXXFLAGS="-O0 -g"' > /usr/local/share/config.site

(或重定向到通常设置$前缀的位置,例如$ HOME / share / config.site)作为额外的奖励,这将为您配置的所有自动混合项目设置CXXFLAGS,而不仅仅是您自己的。 (假设您正确设置了前缀。如果您希望config.site对所有项目都有效,而不考虑前缀,那么使用CONFIG_SITE设置)


6
投票

与此同时,我想出了如何做到这一点。我会对此作出解释。

基本的是Autoconf替换Makefile.in中的shell变量。问题是如何获得这些变量的值?答案是初始化命令替换在命令行(如./configure 'CXXFLAGS=-O0 -g')告诉它们的变量,否则它们被任何定义默认值的命令(例如,CXXFLAGS由AC_PROG_CXX设置)替换,如果它们不为空。因此,解决方案是在AC_PROG_CXX之前设置我们的新默认值,但是在从命令行进行替换之后。例如:

if test -z $CXXFLAGS; then
    CXXFLAGS='-O2'
fi
AC_PROG_CXX

3
投票

您可以在Makefile.am中设置特定于目标的默认值,也可以在configure.ac中设置默认值,这将适用于您在项目中构建的所有内容。

请参阅autoconf manual中的4.8.1(和5.10.4)部分。

请注意4.8.1中关于不猜测最终包用户的注释:如果你想设置用户不应该关注的标志,那么使用AM_CXXFLAGS设置它们,这样的标志,用户应该能够覆盖应该在CXXFLAGS中设置。

但是......你真的想这样做吗?

  1. 你说'调试将变得不可能'。你试过这个并看到出了什么事吗?编译器/调试器可能比您认可的更聪明。
  2. 在开发时对您来说什么是一个很好的默认值,对于最终用户来说,在构建时不一定是一个很好的默认值。如果在开发过程中确实需要关闭优化,那么只需使用./configure CXXFLAGS='-O0 -g'配置开发系统,完全如您所述。如果您的configure.ac编写正确,那么将在不进行优化的情况下配置您的构建,同时保持(良好)默认值不变。

简短版本:你现在的做法是正确的方式。

编辑添加:

通常,如果shell变量作为AC_SUBST的参数出现(或者显式地或者像CXXFLAGS这样的情况,隐含在其他命令中),那么它将被替换为输出文件。也就是说,在AC_SUBST(foo)之后,$foo脚本中的./configure变量的值将被替换为@foo@实例。


1
投票

基于上面的答案,我将此添加到configure.ac:

AC_ARG_WITH(debug, [  --with-debug            add the debugging module], [AC_DEFINE(WITH_DEBUG,1,0)
AC_SUBST(WITH_DEBUG,1)
CXXFLAGS="-O0 -ggdb"])

它还在AC_CONFIG_HEADERS(config.h)中定义WITH_DEBUG,并使用AC_SUBST()将其添加到Makefile中。


0
投票

在Makefile.am上,您可以使用它来定义它们

programname_CXXFLAGS=-O0 -g

更新:20100628

在调用AC_PROG_CXX之前,您应该尝试在configure.in中添加CXXFLAGS。我没有测试它,但你的configure.in看起来应该是这样的

AC_INIT
...
CXXFLAGS=-MY -FLAGS
...
AC_PROG_CXX

请让我知道,如果这是有效的,因为我很好奇:-)


0
投票

关于用户并不奇怪的要点是有效的,但是默认情况下有些标志是合理的(例如-Wall -Wextra),而其他标志是特定于代码库的并且有时需要(例如-std=gnu99)。

那么问题就变成了如何便携地做到这一点。我亲自从libuv项目中窃取了标志检查宏。为此,我将libuv-check-flags.m4添加到项目的m4目录中。然后我可以在我的configure.ac中执行以下操作:

m4_include([m4/libuv-check-flags.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign 1.11.2])

# Checks for programs.
AC_PROG_CC
CC_CHECK_CFLAGS_APPEND([-std=gnu99])
CC_CHECK_CFLAGS_APPEND([-Wall])
CC_CHECK_CFLAGS_APPEND([-Wextra])
AC_PROG_LIBTOOL

我生成的配置文件然后生成一个编译器命令行:

gcc -g -O2 -std=gnu99 -Wall -Wextra

我仍然可以使用上面的解决方案覆盖-g -O2默认值,例如:

./configure CFLAGS='-O0 -g'

生成命令行:

gcc -O0 -g -std=gnu99 -Wall -Wextra

并且利用gcc语义,我仍然可以在必要时禁用基本标志。例如,如果我真的想要,我可以禁用警告:

./configure CFLAGS='-Wno-all -Wno-extra'

你可能会说,“那么如果编译器不支持这些标志呢?”这就是为什么这些宏如此有用和伟大,因为它们确保首先检查编译器功能,因此如果不支持-Wall-Wextra,则不会首先添加它们。

libuv是地球上最便携和最广泛使用的C库之一,所以我认为遵循它们是合理的。虽然这些宏是纯C特定的,但将它们与CXXFLAGS一起使用将是微不足道的。

参考文献:

© www.soinside.com 2019 - 2024. All rights reserved.