不常見但是很有用的 gcc 命令行選項(一)
舉一個例子:編譯器。一個優秀的編程語言編譯器總是會提供極多的選項,但是用戶一般只知道和使用其中很有限的一部分功能。更具體點來說,比如你是 C 語言開發人員,並將 Linux 作為你的開發平台,那麼你很有可能會用到 gcc 編譯器,這個編譯器提供了 (幾乎) 數不清的命令行選項列表。
你知道,你可以讓 gcc 保存每個編譯階段的輸出嗎?你知道用於生成警告的 -Wall
選項,它並不會包含一些特殊的警告嗎?gcc 的很多命令行選項都不會經常用到,但是它們在某些特定的情況下會變得非常有用,例如,當你在調試代碼的時候。
所以在本文中,我們會介紹這樣的幾個選項,提供所有必要的細節,並通過簡單易懂的例子來解釋它們。
但是在開始前,請注意本文中所有的例子所使用的環境:基於 Ubuntu 16.04 LTS 操作系統,gcc 版本為 5.4.0。
在每個編譯階段查看中間代碼的輸出
你知道在通過 gcc 編譯 c 語言代碼的時候大體上共分為四個階段嗎?分別為預處理 -> 編譯 -> 彙編 -> 鏈接。在每個階段之後,gcc 都會產生一個將移交給下一個階段的臨時輸出文件。但是生成的都是臨時文件,因此我們並不能看到它們——我們所看到的只是我們發起編譯命令,然後它生成的我們可以直接運行的二進位文件或可執行文件。
但是比如說在預處理階段,如果調試時需要查看代碼是如何進行處理的,你要怎麼做呢?好消息是 gcc 編譯器提供了相應的命令行選項,你可以在標準編譯命令中使用這些選項獲得原本被編譯器刪除的中間文件。我們所說的選項就是-save-temps
。
以下是 gcc 手冊中對該選項的介紹:
永久存儲臨時的中間文件,將它們放在當前的文件夾下並根據源文件名稱為其命名。因此,用
-c -save-temps
命令編譯 foo.c 文件時會生成 foo.i foo.s 和 foo.o 文件。即使現在編譯器大多使用的是集成的預處理器,這命令也會生成預處理輸出文件 foo.i。當與
-x
命令行選項結合使用時,-save-temps
命令會避免覆寫與中間文件有著相同擴展名的輸入源文件。相應的中間文件可以通過在使用-save-temps
命令之前重命名源文件獲得。
以下是怎樣使用這個選項的例子:
gcc -Wall -save-temps test.c -o test-exec
下圖為該命令的執行結果,驗證其確實產生了中間文件:
因此,在截圖中你所看到的 test.i、test.s、 test.o 文件都是由 -save-temps
選項產生的。這些文件分別對應於預處理、編譯和鏈接階段。
讓你的代碼可調試和可分析
你可以使用專有的工具調試和分析代碼。如 gdb 就是專用於調試的工具,而 gprof 則是熱門的分析工具。但你知道 gcc 特定的命令行選項也可以讓你的代碼可調試和可分析嗎?
讓我們開始調試之路吧!為了能在代碼調試中使用 gdb,你需要在編譯代碼的時候使用 gcc 編譯器提供的 -g
選項。這個選項讓 gcc 生成 gdb 需要的調試信息從而能成功地調試程序。
如果你想要使用此選項,建議您詳細閱讀 gcc 手冊提供的有關此選項的詳細信息——在某些情況下,其中的一些內容可能是至關重要的。 例如,以下是從手冊頁中摘錄的內容:
GCC 允許在使用
-g
選項的時候配合使用-O
選項。優化代碼採用的便捷方式有時可能會產生意想不到的結果:某些你聲明的變數可能不復存在;控制流可能會突然跳轉到你未曾預期的位置;一些語句也許不會執行,因為它們已經把常量結果計算了或值已經被保存;一些語句可能會在不同地方執行,因為它們已經被移出循環。然而優化的輸出也是可以調試的。這就使得讓優化器可以合理地優化或許有 bug 的代碼。
不只是 gdb,使用 -g
選項編譯代碼,還可以開啟使用 Valgrind 內存檢測工具,從而完全發揮出該選項的潛力。或許還有一些人不知道,mencheck 工具被程序員們用來檢測代碼中是否存在內存泄露。你可以在這裡參見這個工具的用法。
繼續往下,為了能夠在代碼分析中使用 gprof 工具,你需要使用 -pg
命令行選項來編譯代碼。這會讓 gcc 生成額外的代碼來寫入分析信息,gprof 工具需要這些信息來進行代碼分析。gcc 手冊 中提到:當編譯你需要數據的源文件時,你必須使用這個選項,當然鏈接時也需要使用它。為了能了解 gprof 分析代碼時具體是如何工作的,你可以轉到我們的網站專用教程進行了解。
注意:-g
和 -pg
選項的用法類似於上一節中使用 -save-temps
選項的方式。
結論
我相信除了 gcc 的專業人士,都可以在這篇文章中得到了一些啟發。嘗試一下這些選項,然後觀察它們是如何工作的。同時,請期待本教程系列的下一部分,我們將會討論更多有趣和有用的 gcc 命令行選項。
via: https://www.howtoforge.com/tutorial/uncommon-but-useful-gcc-command-line-options/
作者:Ansh 譯者:dongdongmian 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive