【问题标题】:gcc linking object files with warning/optimization flagsgcc 使用警告/优化标志链接目标文件
【发布时间】:2017-03-03 18:30:57
【问题描述】:

我们正在使用泛型编译一个软件,其中文件首先被制作成目标文件,它们的构建方式如下:

arm-unknown-linux-gnu-gcc -c -O2 -Wstrict-prototypes -Wdeclaration-after-statement -fsigned-char -I/opt/tm-sdk/include  -mlittle-endian -Wno-trigraphs -fno-strict-aliasing -fno-omit-frame-pointer -march=armv4 -mtune=arm9tdmi -Wall -Wextra -o src/flex.o src/flex.c
...
arm-unknown-linux-gnu-gcc -c -O2 -Wstrict-prototypes -Wdeclaration-after-statement -fsigned-char -I/opt/tm-sdk/include  -mlittle-endian -Wno-trigraphs -fno-strict-aliasing -fno-omit-frame-pointer -march=armv4 -mtune=arm9tdmi -Wall -Wextra -o src/flexdb.o src/flexdb.c

然后它们被链接到:

arm-unknown-linux-gnu-gcc -o flex src/flex.o src/flexdb.o src/flexio.o src/flexprotocol.o src/flexsettings.o src/flexstate.o -L/opt/tm-sdk/lib -ltag  -lrt -ltmreader -lsqlite3 -lsha1

我的问题是: 我们是否需要在链接期间包含优化和警告标志?如果在从目标文件创建 flex 二进制文件时包含 -Wall-Wextra-O2,它会做任何事情吗?

编辑:根据反馈阐明含义。

【问题讨论】:

  • C 中的泛型是编译时表达式。不知道为什么这会是相关的。以及哪个“编译的最后阶段”?编译器一次运行(从用户视图)
  • 我只是将其视为一个两步过程。构建目标文件,然后合并目标文件。
  • 构建!= 编译!
  • 你说得对,“编译的最后阶段”令人困惑。
  • @Kyles -c 开关的意思是“只编译和/或汇编,但不链接”。最后一个命令称为linking。 GCC 将成为 GNU 链接器ld 的前端

标签: c gcc compiler-optimization gcc-warning object-files


【解决方案1】:

我们是否需要在编译的最后阶段包含优化和警告标志?

当然,您需要在链接阶段包含它们。您已经知道这一点,因为您包含它们。但我认为你真正想知道的是......

如果在从目标文件构建 flex 二进制文件时包含 -Wall、-Wextra 和 -O2,它会做任何事情吗?

在编译阶段会生成所有或几乎所有警告。我不知道有任何例外,但可以想象有一些例外。因此,在链接期间传递与警告相关的标志可能会触发警告,否则您将不会收到。但这不应该以任何方式影响编译的二进制文件。

优化不同。可以在链接时执行一些优化,但可能不会在默认优化级别执行。从链接命令中省略优化标志不应破坏您的构建,但包含它们可能会导致二进制文件更快和/或更小。

总的来说,我认为没有充分的理由避免在链接步骤中传递与编译步骤相同的警告和优化标志。如果您愿意,传递特定于预处理器的标志(例如-D)也无害,因为它们只会在链接期间被忽略。我认为这一切都是由make 管理的,所以你实际上并不需要每次都输入选项。

【讨论】:

  • 正确,我们正在使用 make。谢谢。
【解决方案2】:

不,您只是在最后调用 gcc 时调用链接器,而 -W 和 -O 标志用于编译器。

【讨论】:

    【解决方案3】:

    -Wall 主要是一个预处理器选项,但也有库的参考。见here

    -Wextra 似乎是严格的 c++ 预处理器选项。见here

    -O2 是编译器优化级别设置。见here

    因此,要回答您的确切问题,只有 -Wall 可能会在您的链接步骤中有所帮助。另外两个不会。您可以通过使用和不使用这些选项进行构建来测试这一点,看看是否在出现警告的情况下创建了任何额外的输出,以及构建之间的代码大小或执行时间是否不同。

    【讨论】:

    • -Wall 和 -Wextra 都不是预处理器选项。
    • 我认为 -Wextra 只是有一些 C++ 独有的特性。我不相信它只是 C++。只能看到 C++ 选项here
    • 在帮助页面上,它说除了一个之外的所有内容都与 c++ 相关。使用 或 >= 将指针与整数零进行比较。 (仅限 C++)枚举数和非枚举数都出现在条件表达式中。 (仅限 C++)模棱两可的虚基。 (仅限 C++)下标已声明为寄存器的数组。 (仅限 C++)获取已声明为寄存器的变量的地址。 (仅限 C++)基类未在派生类的复制构造函数中初始化。
    • @netskink 在您提供的链接中,-Wextra 启用了 4 个警告,它们仅适用于 C,另外 10 个适用于 C 和 C++。我认为您可能误读了该列表(您引用的项目符号列表之前的代码块中的内容也由 -Wextra 启用)
    • @netskink:来自关于 `-Wextra" 的链接页面:...选项 -Wextra also 打印警告消息..."(强调我的),这意味着这里的“除了”。您完全忽略了上面列出的消息。您的其余答案也大多是错误的。它也没有真正回答这个问题。
    猜你喜欢
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多