使用Autotools的默认编译器标志

时间:2010-06-25 08:40:46

标签: makefile autoconf automake

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

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

./configure 'CXXFLAGS=-O0 -g'

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

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

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

7 个答案:

答案 0 :(得分:19)

根据autoconf手册(约AC_PROG_CC):

  

如果使用GNU C编译器,请将shell变量GCC设置为“yes”。如果   输出变量CFLAGS尚未设置,将其设置为-g -O2   GNU C编译器(在GCC不接受-g的系统上为-O2)或-g   对于其他编译器。如果你的包不喜欢这个默认值,那么   插入行

是可以接受的      

: ${CFLAGS=""}

     

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

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

  

如果使用GNU C ++编译器,请将shell变量GXX设置为“yes”。如果   输出变量CXXFLAGS尚未设置,将其设置为-g -O2   GNU C ++编译器(在G ++不接受-g的系统上为-O2)或-g   对于其他编译器。如果你的包不喜欢这个默认值,那么   插入行

是可以接受的      

: ${CXXFLAGS=""}

     

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

答案 1 :(得分:8)

如果您只想在运行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设置)

答案 2 :(得分:7)

同时我想出了怎么做。我将对此作出解释。

基本的是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 :(得分:2)

您可以在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写得正确,那么在没有优化的情况下配置您的版本,同时保持(良好)默认值不变。
  3. 简短版本:你现在正在采取的方式是正确的方式。

    已编辑添加:

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

答案 4 :(得分: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中。

答案 5 :(得分:0)

在Makefile.am上,您可以使用

定义它们
programname_CXXFLAGS=-O0 -g

更新时间:20100628

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

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

如果我感到好奇,请告诉我这是否有效: - )

答案 6 :(得分: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配合使用将是微不足道的。

参考文献: