如何在 GCC 中通过优化构建发布模式?

Posted

技术标签:

【中文标题】如何在 GCC 中通过优化构建发布模式?【英文标题】:How to build in release mode with optimizations in GCC? 【发布时间】:2009-10-08 00:08:51 【问题描述】:

我需要在“发布模式”中构建并在 GCC 中进行全面优化的具体选项是什么?如果有多个选项,请列出所有选项。谢谢。

【问题讨论】:

【参考方案1】:

http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

没有“一刀切”——您需要了解您的应用程序、您的要求和优化标志,以确定您的二进制文件的正确子集。

或者你想要的答案: -O3

【讨论】:

我找到了但找不到一个直截了当的解释。不过,我可能只是在搜索方面很烂。 此外,SO 的意义在于出现在像 Google 这样的搜索引擎中,所以无论如何最好在这里拥有它。 公平通话。这就是你所追求的吗?还是您需要更多上下文/信息? 通常,您也希望-DNDEBUG 去除断言。 你可能也想要-march=native -mtune=native,只要你不打算将二进制文件分发到其他机器。【参考方案2】:

这是我经常使用的 Makefile 的一部分(在这个例子中,它试图构建一个名为 foo 的程序)。

如果您像 $ make BUILD=debug$ make debug 一样运行它 然后将使用 Debug CFLAGS。这些关闭优化 (-O0) 并包括调试符号 (-g)。

如果您省略这些标志(通过运行 $ make 而不使用任何其他参数),您将构建启用优化 (-O2) 的 Release CFLAGS 版本,去除调试符号 ( -s) 并禁用断言 (-DNDEBUG)。

正如其他人所建议的,您可以根据自己的具体需求尝试不同的 -O* 设置。

ifeq ($(BUILD),debug)   
# "Debug" build - no optimization, and debugging symbols
CFLAGS += -O0 -g
else
# "Release" build - optimization, and no debug symbols
CFLAGS += -O2 -s -DNDEBUG
endif

all: foo

debug:
    make "BUILD=debug"

foo: foo.o
    # The rest of the makefile comes here...

【讨论】:

【参考方案3】:

请注意,gcc 没有 MSVC 那样的“发布模式”和“调试模式”。所有代码都只是代码。各种优化选项的存在(-O2 和 -Os 是您通常需要关心的唯一选项,除非您正在进行非常精细的调整)会修改生成的代码,但不会阻止与其他 ABI 兼容的互操作性代码。通常,您希望对要发布的内容进行优化。

“-g”选项的存在将导致扩展符号和源代码信息放置在生成的文件中,这对调试很有用,但会增加文件的大小(并显示您的源代码),即在“已发布”的二进制文件中通常不需要的东西。

但它们并不是唯一的。您可以使用优化和调试信息编译二进制文件,也可以两者都不编译。

【讨论】:

如果你打算调试生成的代码,通常应该禁用优化,否则你会发现调试是一种类似于大卫林奇电影的体验。 这还不错,我一直在查看“发布”二进制文件的堆栈转储和 valgrind 输出。只要您不使用 -fomit-stack-pointer 并了解静态可能是内联且不可见的,即使是经过高度优化的二进制文件,您也可以读取大量上下文。如果你的函数很短,你通常可以通过一两次猜测找出崩溃的表达式。 不过,与大卫林奇的电影不同,调试器让观众可以在不同的现实层次之间随意切换。如果您了解反汇编,那么即使进行优化,单步执行(穿插源代码行)通常也会有一定的意义。拆解不懂就学吧。 在相关说明中,有一些方法可以在“发布”版本中保留调试符号以进行维护。一种方法:gcc -g source.cc -o a.out; strip a.out -o a.out.syms; strip a.out。使用objdump -t a.out 来验证这些符号实际上已经被剥离了。 MSVC 也没有这些模式。这只是一些构建系统提出的一种约定,包括目前 Visual Studio IDE 使用的任何一种。【参考方案4】:

-O2 将打开所有不需要空间\速度折衷的优化,并且往往是我看到最常用的优化。 -O3 为速度权衡做了一些空间(如函数内联。) -Os 做了 O2 加上做其他事情以减少代码大小。通过提高缓存使用率,这可以使事情比 O3 更快。 (测试以了解它是否适​​合您。)请注意,有很多选项都没有 O 开关接触。它们被排除在外的原因是因为它通常取决于您正在编写的代码类型或非常依赖于架构。

【讨论】:

以上是关于如何在 GCC 中通过优化构建发布模式?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MockRestServiceServer 中通过字符串模式期待 requestTo?

如何在 MSYS2 中通过 CMake 构建 c++ Qt5 应用程序

如何在 Lua 中通过 ESP32 和 NodeMCU 使用蓝牙

如何在 Flutter 中通过更改主题来更改文本颜色

为啥这个结构文字在 VS2013 中通过地址而不是 gcc/clang 时会损坏?

如何在 Rails 中通过 jQuery 调用 JSON 文件?