【问题标题】:GNU autotools: Debug/Release targets?GNU 自动工具:调试/发布目标?
【发布时间】:2011-06-01 00:34:16
【问题描述】:

我一直在寻找这个:我目前正在将一个中型程序转换为自动工具,来自基于 Eclipse 的方法(使用 makefile)

我总是习惯于“调试”构建,包含所有调试符号且没有优化,以及“发布”构建,没有调试符号和最佳优化。

现在我正在尝试使用 autotools 以某种方式复制它,因此我可以(也许)执行以下操作:

./configure
make debug

其中包含所有调试符号且没有优化,以及在哪里:

./configure
make

将产生“发布”版本(默认)

PS:我已经阅读了有关 --enable-debug 标志/功能的信息,但在我当前(简单)的设置中,configure 无法识别使用它

【问题讨论】:

  • 请将接受的答案从 ismall's 更改为 William Pursell's。接受的答案不正确。

标签: c++ autotools autoconf automake


【解决方案1】:

ismail 的解决方案是一种常见的方法,但它存在一些严重的问题。如果用户尝试通过执行 './configure --enable-debug' 来获得调试版本,则配置脚本会将 CFLAGS 设置为 '-g -O2' 并且 Makefile 将使用 '-g3 -O0 ... -g -O2' 构建任何可执行文件时。在这种情况下,gcc 将使用 -O2,并且一些编译器会因为 -O 选项冲突而中止。这两种情况都不是预期的行为。

是否使用调试符号构建不是项目维护者应该担心的事情根本。这是用户的问题。如果您正在构建项目并且想要进行调试构建或发布构建,则应在配置时使用不同的选项。例如,

$ mkdir debug
$ mkdir release
$ cd debug && /path/to/configure --prefix=/dbg \
   CPPFLAGS=-DDEBUG CFLAGS="-g -O0" && make && make install
$ cd ../release && /path/to/configure CPPFLAGS=-DNDEBUG && make && make install

这将在 /dbg/bin 中安装带有 `-DDEBUG' 和 '-g -O0' 的构建(“调试构建”),并在 /usr/local/bin 中安装“发布”

您可以通过使用 CONFIG_SITE 文件来减少必要的打字工作。例如,您可以这样做:

echo 'CPPFLAGS=-DDEBUG CFLAGS="-g -O0"' >> /dbg/share/config.site

然后所有未来的 'configure --prefix=/dbg' 调用将自动继承 CPPFLAGS 和 CFLAGS 的设置,无需在命令行中指定。

如果作为包维护者,您想为用户提供一种构建“调试版本”的简单方法,那么在分发中包含一个脚本是完全可以接受的,该脚本使用适当的参数调用配置脚本并调用make && make install,但是绝对没有必要在你的自动工具元文件中乱扔垃圾。它根本不属于那里。请注意,许多软件包都尝试添加--enable-debug,这是完全错误的。如果用户调用configure CFLAGS="-g -O0",但得到的构建应用了意外的标志,那么你就有一个错误并且你的包损坏了。这是一种非常常见的体验,如果您维护一个包(目前正在考虑tmuxcurl),其中用户在调用configure CFLAGS="-g -O0" 后没有得到任何合理的人所说的“调试构建”,那么你的包裹损坏了

在使用 autotools 维护包时必须始终记住的重要一点是,用户可能使用与您完全不同的工具链。用户的工具链完全有可能需要-DMAKE_IT_A_DEBUG-DUSE_DEBUG-I/non/standard/path/to/headers。也许它需要-O145-Q 传递给编译器或-debug 传递给链接器,或者......任何东西。作为维护者,您根本没有必要的信息来使“调试构建”这个短语对所有用户都有意义。所以不要尝试,因为您可能会使特定用户无法构建该软件。

【讨论】:

  • @Honza 需要更多详细信息来调试您的问题。如果$prefix/share/config.site 存在且CONFIG_SITE 在运行configure 脚本的进程环境中没有设置(如果configure 脚本是由autoconf 生成的),则应该读取它。在configure 脚本中搜索config.site
  • 我试过CPPFLAGS=-DDEBUG CXXFLAGS="-g -O0" && make && make install,但它似乎忽略了这些标志。我不得不改用make CPPFLAGS=-DDEBUG CXXFLAGS="-g -O0"
  • @Craig 你没有运行配置。你需要:CPPFLAGS=-DDEBUG ./configure && make ...
  • 如果可能,使用-ggdb 进行最大程度的调试。
  • Ismail 的解决方案完全被打破了。在这种情况下,configure --enable-debug 使用-O0 ... -O2 调用编译器,即使在最常见的情况下也会被破坏。
【解决方案2】:

在您的configure.inconfigure.ac 文件中添加一个子句;

AC_ARG_ENABLE(debug,
AS_HELP_STRING([--enable-debug],
               [enable debugging, default: no]),
[case "${enableval}" in
             yes) debug=true ;;
             no)  debug=false ;;
             *)   AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
esac],
[debug=false])

AM_CONDITIONAL(DEBUG, test x"$debug" = x"true")

现在在你的Makefile.inMakefile.am;

if DEBUG
AM_CFLAGS = -g3 -O0
AM_CXXFLAGS = -g3 -O0
else
AM_CFLAGS = -O2
AM_CXXFLAGS = -O2
endif

所以当debug被启用时,你可以修改你的{C/CXX}FLAGS来启用调试信息。

【讨论】:

  • -1 这是一个可怕的解决方案,完全违背了自动工具的理念。下面给出的答案中有更多描述。
  • 让我进一步澄清为什么这是一个糟糕的解决方案。当用户运行'configure CFLAGS=-O1 && make'时会发生什么?编译器将使用“-O1 -O2”调用。将设置哪个优化级别?用户明确要求 -O1,但您必须查看文档以了解编译器实际做了什么。
  • @Ismail 我的意思是您的解决方案将导致两个标志都传递给编译器。如果用户使用不同的编译器,您声称如果 -O1 和 -O2 都通过,gcc 将使用 -O1 是完全不相关的。您的解决方案的问题在于您对用户的环境做出假设,而不是让用户驱动构建,这完全与自动工具的理念相冲突。
  • @Ismail 你怎么能声称所有编译器的行为?所有编译器都识别'-g3'吗?那里有很多编译器。然而,这不是重点。关键是包维护者不应该对用户的环境做出这样的假设。这些决定应该留给用户。
  • @ismail -- 我刚刚在我的机器上发现了一个编译器,如果在命令行上同时传递了 -O1 和 -O2 ,它就会中止。如果您可以修改您的解决方案,以便用户有一种方法来确保您在 AM_CFLAGS 中指定的任何标志都不会传递给编译器(无需修改 Makefile.am 或 Makefile),我将很乐意删除我的反对票。但这不是一个问题。这是困扰自动工具的核心问题。构建的包忽略了工具链的理念,结果是包没有按预期构建。
【解决方案3】:

使用 autotools 创建的默认 Makefile 生成带有调试符号的二进制文件。使用make install-strip 生成发布目标。

【讨论】:

  • 即使二进制文件包含调试符号,它通常也是使用 -O2 构建的。
【解决方案4】:

另一个配置CFLAGS/CXXFLAGS而不编辑Makefile.inMakefile.am的例子。将此代码添加到您的 configure.inconfigure.ac 文件中:

test -z "$SED" && SED=sed

AC_ARG_ENABLE([debug],
  [AS_HELP_STRING([--enable-debug],
                  [whether to include debug symbols (default is no)])],
  [enable_debug=$enableval],
  [enable_debug=no]
)

if test "x$enable_debug" = xyes; then
  dnl Remove all optimization flags from CFLAGS
  changequote({,})
  CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9s]*//g'`
  CXXFLAGS=`echo "$CXXFLAGS" | $SED -e 's/-O[0-9s]*//g'`

  CFLAGS=`echo "$CFLAGS" | $SED -e 's/-g[0-9]*//g'`
  CXXFLAGS=`echo "$CXXFLAGS" | $SED -e 's/-g[0-9]*//g'`
  changequote([,])

  CFLAGS="$CFLAGS -g -O0"
  CXXFLAGS="$CXXFLAGS -g -O0"
fi

echo "CFLAGS=$CFLAGS"

测试一下:

$ ./configure --enable-debug | grep CFLAGS

【讨论】:

    猜你喜欢
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    相关资源
    最近更新 更多