GNU autotools:调试/发布目标?

cpf*_*cpf 58 c++ automake autoconf autotools

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

我总是习惯于进行"调试"构建,包含所有调试符号和没有优化,以及"发布"构建,没有调试符号和最佳优化.

现在我试图用autotools以某种方式复制它,所以我可以(也许)做类似的事情:

./configure
make debug
Run Code Online (Sandbox Code Playgroud)

哪个会有所有调试符号而没有优化,以及哪里:

./configure
make
Run Code Online (Sandbox Code Playgroud)

会导致"发布"版本(默认)

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

Wil*_*ell 133

ismail的解决方案是一种常见的方法,但它遇到了一些严重的问题.如果用户通过执行'./configure --enable-debug'尝试获取调试版本,则configure脚本会将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
Run Code Online (Sandbox Code Playgroud)

这将在/ dbg/bin中安装调试版本,在/ usr/local/bin中安装"release"安装

此外,您可以使用CONFIG_SITE文件大大减少必要输入的繁琐.例如,你可以这样做:

echo 'CPPFLAGS=-DDEBUG CFLAGS="-g -O0"' >> /dbg/share/config.site
Run Code Online (Sandbox Code Playgroud)

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

如果作为软件包维护者,您希望为用户提供一种简单的方法来构建"调试版本",那么在分发中包含一个脚本是完全可以接受的,该脚本使用适当的参数调用configure脚本并调用make && make install,但是绝对没有必要乱丢你的autotool元文件.它根本不属于那里.并且要注意,许多软件包已经尝试添加--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传递给链接器,或者......任何东西.作为维护者,您根本没有必要的信息来使"调试构建"这一短语对所有用户都有意义.因此,请不要尝试,因为您可能会使某些用户无法构建该软件.

  • Ismail 的解决方案完全被破坏了。在这种情况下,`configure --enable-debug` 使用 `-O0 ... -O2` 调用编译器,即使在最常见的情况下也会被破坏。 (3认同)

ism*_*ail 18

在您的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")
Run Code Online (Sandbox Code Playgroud)

现在在你Makefile.inMakefile.am;

if DEBUG
AM_CFLAGS = -g3 -O0
AM_CXXFLAGS = -g3 -O0
else
AM_CFLAGS = -O2
AM_CXXFLAGS = -O2
endif
Run Code Online (Sandbox Code Playgroud)

因此,debug启用后,您可以修改您{C/CXX}FLAGS的启用调试信息.

  • -1这是一个可怕的解决方案,完全反对autotools的哲学.下面给出答案中的更多描述. (24认同)
  • @Ismail你怎么能对所有编译器的行为提出索赔?所有编译器都识别'-g3'吗?那里有很多*编译器.但是,这不是重点.关键是包维护者不应该对用户的环境做出这样的假设.这些决定应留给用户. (7认同)
  • 让我澄清一下为什么这是一个糟糕的解决方案.当用户运行'configure CFLAGS = -O1 && make'时会发生什么?将使用"-O1 -O2"调用编译器.将设置哪种级别的优化?用户明确要求-O1,但您必须检查文档以确定编译器实际执行的操作. (6认同)
  • @Ismail我的观点是你的解决方案会导致两个标志传递给编译器.如果用户使用不同的编译器,如果传递了-O1和-O2,则gcc将使用-O1的声明完全无关紧要.您的解决方案有什么问题,您正在假设用户的环境而不是让用户驱动构建,这完全违背了autotools的理念. (6认同)
  • @ismail - 我刚在我的机器上发现了一个编译器,如果在命令行上传递了-O1和-O2,它就会中止.如果你可以修改你的解决方案,以便用户有一个方法来确保你在AM_CFLAGS中指定的任何标志都没有传递给编译器(不修改Makefile.am或Makefile),我很乐意删除我的downvote.但这不是一个问题.这是困扰autotools的核心问题.构建的包忽略了工具链的原理,结果是不按预期构建的包. (6认同)
  • @ismail我不是试图加重,只是试图指出我认为是一个重大缺陷.实际上,您的解决方案存在更大的问题.即,将使用$(AM_CFLAGS)$(CFLAGS)调用编译器.如果用户未指定CFLAGS,则CFLAGS将默认为"-g -O2",并且"调试代码"将使用"-g3 -O0 ... -g -O2"进行编译,并且将应用-O2优化. (5认同)
  • @Ismail不,它不能.AM_CFLAGS和CFLAGS都将在编译时出现.如果将-O2添加到AM_CFLAGS并且用户将-O1添加到CFLAGS,则两者都将传递给编译器. (4认同)
  • `--enable-debug`应该只用*来启用条件调试代码,比如断言.常识是使用它的缺席来定义`NDEBUG`,仅此而已. (2认同)
  • @Arne,我只是重新阅读了您的上面的评论,并且必须声明“此解决方案使大多数用户易于启用调试”,这是例外。如果实施,此解决方案将在用户指定--enable-debug时将-g3 -O0 -g -O2传递给编译器。使用gcc时,会给出错误的行为。与其他编译器一起构建将会失败。这是该解决方案的一个重要失败。 (2认同)
  • @WilliamPursell:[您是对的](http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html)…为了使这项工作有效,实际上还需要添加AM_CFLAGS在Makefile中显式地指向目标CFLAGS:`prog2_CFLAGS = $(LIBFOOCFLAGS)$(AM_CFLAGS)` (2认同)

cre*_*ate 5

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