【问题标题】:Default compiler flags with AutotoolsAutotools 的默认编译器标志
【发布时间】:2011-03-08 04:41:37
【问题描述】:

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

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

./configure 'CXXFLAGS=-O0 -g'

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

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

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

【问题讨论】:

  • @users-not-understanding-why-this-doesn't-work-in-a-C-project: CXXFLAGS 在作为 arg 传递时应该是 CFLAGS。到 ./configure

标签: makefile autoconf automake


【解决方案1】:

在您的 Makefile.am 上,您可以使用

programname_CXXFLAGS=-O0 -g

更新:20100628

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

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

请告诉我这是否可行,因为我很好奇 :-)

【讨论】:

  • 我先试了那个。它不起作用。它将标志添加到默认标志,因此它产生“-O2 -g -O0 -g”或类似的东西。
  • 所有 configure.in 文件都应该为空白或不存在。 “configure.in”这个名字已经过时了好几年了。 'configure.ac' 是正确的名称。
【解决方案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 编写正确,那将配置 您的 构建而不进行优化,同时保持(良好)默认值不变。

短版:你现在的做法是正确的。

编辑添加:

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

【讨论】:

  • 首先,你没有回答我的问题。你评论了我为什么要这样做,这是我不想争论的事情,因为这不是重点。关键是我想更改默认编译器标志。
  • 很公平。我还没有真正意识到你的问题是关于设置变量的 sh 机制,我已经编辑了一个可能有用的额外评论。
  • @NormanGray -O2 优化了很多变量,所以是的,调试器并不比 petersohn 所认为的聪明。
  • 你当然可以超越规则,但最好不要这样做。
【解决方案3】:

与此同时,我想出了如何去做。我将对此进行解释。

基本的事情是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

【讨论】:

  • 这个解决方案完全违反了最小意外原则。在没有明确设置 CXXFLAGS 的情况下运行 configure 时,人们希望 CXXFLAGS 设置为“-g -O2”。如果您想自己更改它,请使用 config.site 进行更改。不要在 configure.ac 中进行更改。这是错误的地方。
  • 另外(尽管这似乎是一个不寻常的用例),如果用户明确将 CXXFLAGS 设置为空(配置 CXXFLAGS= --prefix ...),此代码将覆盖用户。与其测试 CXXFLAGS 是否为空,不如使用 ": ${CXXFLAGS=-O2}' 检查它是否未定义
  • 谢谢。这也是我想要的解决方案。我想将默认优化从 -O2 更改为 -O3,但允许人们进行自己的更改。
  • AM_CXXFLAGS 呢?
【解决方案4】:

如果您只想在运行 configure 时为自己设置默认标志,那么(至少)有 3 种好方法可以做到这一点。在您的环境中设置 CXXFLAGS(例如在 .login 或 .bashrc 中),使用 CONFIG_SITE 环境变量来指定配置文件,或者在 $prefix/share/config.site 中为 CXXFLAGS 设置所需的值。如果你想为你的包的所有用户设置默认标志,而不是'-O2 -g',那么你需要改变你想要的,因为这样做违反了最小意外原则。任何熟悉 autoconf 的人都希望默认标志是 -O2 -g 并且您不应该更改它。

选择上面给出的第三个选项,然后就可以了

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

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

【讨论】:

    【解决方案5】:

    根据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 之前选择一个空的默认值 而是。

    【讨论】:

      【解决方案6】:

      基于上述答案,我将其添加到 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。

      【讨论】:

        【解决方案7】:

        关于用户不足为奇的观点是有效的,但默认情况下某些标志是合理的(例如-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 一起使用将是微不足道的。

        参考资料:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-12
          • 2010-12-13
          • 2010-09-24
          • 1970-01-01
          • 2011-10-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多