从编译的可执行文件中获取编译器选项?

时间:2012-08-24 15:27:05

标签: c++ c linux

有没有办法看到在* nix中使用什么编译器和标志来创建可执行文件?我有一个旧版本的代码编译,我想看看是否编译有或没有优化。谷歌没有太大帮助,但我不确定我使用的是正确的关键词。

7 个答案:

答案 0 :(得分:58)

gcc有一个-frecord-gcc-switches选项:

   -frecord-gcc-switches
       This switch causes the command line that was used to invoke the compiler to
       be recorded into the object file that is being created.  This switch is only
       implemented on some targets and the exact format of the recording is target
       and binary file format dependent, but it usually takes the form of a section
       containing ASCII text.

之后,ELF可执行文件将包含.GCC.command.line部分,其中包含该信息。

$ gcc -O2 -frecord-gcc-switches a.c
$ readelf -p .GCC.command.line a.out 

String dump of section '.GCC.command.line':
  [     0]  a.c
  [     4]  -mtune=generic
  [    13]  -march=x86-64
  [    21]  -O2
  [    25]  -frecord-gcc-switches

当然,它不适用于没有该选项编译的可执行文件。


对于简单的优化情况,如果文件是使用调试信息编译的,那么可以尝试使用调试器。如果您稍微介绍一下,您可能会注意到某些变量已“优化”。这表明优化已经发生。

答案 1 :(得分:12)

如果使用-frecord-gcc-switches标志进行编译,则命令行编译器选项将写入注释部分的二进制文件中。 See also the docs

答案 2 :(得分:8)

另一种选择是-grecord-gcc-swtiches(注意,不是-f但是-g)。根据gcc docs,它会将标志放入矮人调试信息中。看起来它默认启用,因为gcc 4.8。

我发现dwarfdump程序对于提取那些cflags非常有用。注意,字符串程序看不到它们。看起来矮人信息被压缩了。

答案 3 :(得分:3)

这需要编译器支持。你没有提到你正在使用什么编译器,但是因为你标记了你的问题linux我会假设你正在使用gcc - 它不会默认你要问的功能(但-frecord-gcc-switches是执行此操作的选项。)

如果要检查二进制文件,strings命令将显示文件中看似可读字符串的所有内容。

答案 4 :(得分:1)

我非常怀疑这是可能的:

int main()
{
}

编译时使用:

gcc -O3 -ffast-math -g main.c -o main

在生成的对象中找不到任何参数:

strings main | grep -O3
(no output)

答案 5 :(得分:1)

如果您仍然使用了您使用的编译器(相同版本),并且它只是您不确定的一个标志,您可以尝试再次编译代码,一次使用,一次没有标记。然后你可以比较可执行文件。你的旧的应该与其中一个相同或非常相似。

答案 6 :(得分:1)

只要可执行文件是由带有 -g 选项的 gcc 编译的,以下内容就可以解决问题:

readelf --debug-dump=info /path/to/executable | grep "DW_AT_producer"

例如:

% cat test.c
int main() {
    return 42;
}
% gcc -g test.c -o test
% readelf --debug-dump=info ./test | grep "DW_AT_producer"
    <c>   DW_AT_producer    : (indirect string, offset: 0x2a): GNU C17 10.2.0 -mtune=generic -march=x86-64 -g

遗憾的是,clang 似乎没有以类似的方式记录选项,至少在版本 10 中如此。

当然,strings 也会出现这种情况,但是人们必须至少知道要查找什么,因为用肉眼检查现实世界二进制文件中的所有字符串通常是不切实际的。例如。使用上面示例中的二进制文件:

% strings ./test | grep march
GNU C17 10.2.0 -mtune=generic -march=x86-64 -g -O3