2012-08-24 110 views
36

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

+1

看起来像'frecord-gcc-switches'是海湾合作委员会的招数,但英特尔(icc)有没有类似的标志? – Mosby

+0

有没有办法做到这一点没有frecord-gcc-switches?例如查看循环展开级别等 – OneSolitaryNoob

回答

48

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 

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


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

+0

用于readelf。 – Johan

+0

'-frecord-gcc-switches'几乎是我所需要的。然而,结果部分具有'-fpreprocessed',并且所有'-D'宏定义不再存在。我怎样才能得到它们? (我正在构建一个内核模块。) –

3

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

如果您想检查二进制文件,strings命令将向您显示文件中所有似乎都是可读字符串的内容。

1

我很怀疑这是可能的:

int main() 
{ 
} 

当编译:

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

参数都不能在生成的对象中找到:

strings main | grep -O3 
(no output) 
+0

尽管...我正在做一个类似的“无所事事”程序生成的可执行文件与有无优化之间的比较,他们确实显示出一些差异... –

+0

好吧,用'readelf'检查表明它只是一些不同的安排函数,没有任何明确的尖叫“这是用'-O3'编译的”。 –

11

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

+0

检查二进制文件的最佳方法是什么? 16进制软件? binutils的? – Johan

+2

@Johan:'readelf'。 –

+0

字符串没有为我工作,readelf确实工作。 – Johan

1

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

5

另一种选择是-grecord-gcc-swtiches(注意,不是-f,而是-g)。根据海湾合作委员会的文件,它会把标志放入矮人调试信息。从gcc 4.8开始,它看起来是默认启用的。

我发现dwarfdump程序可以用来提取这些cflags。请注意,字符串程序不会看到它们。看起来侏儒信息是压缩的。