2012-08-24 76 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。請注意,字符串程序不會看到它們。看起來侏儒信息是壓縮的。