有没有办法看到在*nix中使用什么编译器和标志来创建可执行文件?我有一个旧版本的代码编译,我想看看是否编译有或没有优化.谷歌没有太大帮助,但我不确定我使用的是正确的关键词.
Mic*_*rny 60
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.
Run Code Online (Sandbox Code Playgroud)
之后,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
Run Code Online (Sandbox Code Playgroud)
当然,它不适用于没有该选项编译的可执行文件.
对于简单的优化情况,如果文件是使用调试信息编译的,则可以尝试使用调试器.如果您稍微介绍一下,您可能会注意到某些变量已"优化".这表明优化发生了.
另一种选择是-grecord-gcc-swtiches(注意,不是-f但是-g).根据gcc docs,它会将标志放入矮人调试信息中.看起来它默认启用,因为gcc 4.8.
我发现dwarfdump程序对于提取那些cflags非常有用.注意,字符串程序看不到它们.看起来矮人信息被压缩了.
只要可执行文件是由带有-g选项的 gcc 编译的,以下操作就可以解决问题:
readelf --debug-dump=info /path/to/executable | grep "DW_AT_producer"
Run Code Online (Sandbox Code Playgroud)
例如:
% 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
Run Code Online (Sandbox Code Playgroud)
遗憾的是,clang 似乎没有以类似的方式记录选项,至少在版本 10 中是这样。
当然,strings也会将其打开,但人们必须至少知道要寻找什么,因为用肉眼检查现实世界二进制中的所有字符串通常是不切实际的。例如,使用上面示例中的二进制文件:
% strings ./test | grep march
GNU C17 10.2.0 -mtune=generic -march=x86-64 -g -O3
Run Code Online (Sandbox Code Playgroud)