編譯:
第一步、是進行預編譯,使用-E參數可讓GCC在預處理結束後中止編譯過程:
gcc -E hello.c -o hello.i
預處理的宏定義插入到hello.i中
第二步、是將hello.i編譯爲目標代碼,這能夠經過使用-c參數來完成:
gcc -c hello.i -o hello.o
也能夠經過源文件直接生成
gcc -c hello.c
第三步、是將生成的目標文件連接成可執行文件:
gcc hello.o -o hello
也能夠經過源文件直接生成
gcc -o hello hello.c
警告:
一、-pedantic 選項,那麼使用了擴展語法的地方將產生相應的警告信息
二、-Wall 使用它可以使GCC產生儘量多的警告信息
三、-Werror,它要求GCC將全部的警告當成錯誤進行處理
庫依賴:
一、Linux下的大多數函數都默認:
頭文件放到/usr/include/目錄下
而庫文件則放到/usr/lib/目錄下
二、GCC在編譯時必須有本身的辦法來查找所須要的頭文件和庫文件。
-I選項能夠向GCC的頭文件搜索路徑中添加新的目錄。
例如,若是在/home/yy/include/目錄下有編譯時所須要的頭文件,爲了讓GCC可以順利地找到它們,就可使用-I選項:
gcc -o test test.c -I /home/yy/include
-L選項向GCC的庫文件搜索路徑中添加新的目錄
例如,若是在/home/yy/lib/目錄下有連接時所須要的庫文件libfoo.so,爲了讓GCC可以順利地找到它,可使用下面的命令
gcc -o test test.c -L /home/yy/lib -lfoo
值得好好解釋一下的是-l選項,它指示GCC去鏈接庫文件libfoo.so。
Linux下的庫文件在命名時有一個約定,那就是應該以lib三個字母開頭,因爲全部的庫文件都遵循了一樣的規範,所以在用-l選項指定連接的庫文件名時能夠省去lib三個字母,也就是說GCC在對-lfoo進行處理時,會自動去連接名爲libfoo.so的文件。
-static選項,強制使用靜態連接庫
若是在/home/yy/lib/目錄下有連接時所須要的庫文件libfoo.so和libfoo.a
爲了讓GCC在連接時只用到靜態連接庫,可使用下面的命令:
gcc -o test test.c -L /home/yy/lib -static -lfoo程序員
編譯成動態庫:編程
g++ -fPIC -shared -o libfunc.so func.cpp函數
-fPIC參數
表示編譯爲位置獨立的代碼,用於編譯共享庫。目標文件須要建立成位置無關碼,概念上就是在可執行程序裝載它們的時候,它們能夠放在可執行程序的內存裏的任何地方。性能
選項-O能夠告訴GCC同時減少代碼的長度和執行時間,其效果等價於-O1。
在這一級別上可以進行的優化類型雖然取決於目標處理器,但通常都會包括線程跳轉(Thread Jump)和延遲退棧(Deferred Stack Pops)兩種優化。
選項-O2告訴GCC除了完成全部-O1級別的優化以外,同時還要進行一些額外的調整工做,如處理器指令調度等。
選項-O3則除了完成全部-O2級別的優化以外,還包括循環展開和其它一些與處理器特性相關的優化工做。
一般來講,數字越大優化的等級越高,同時也就意味着程序的運行速度越快。
許多Linux程序員都喜歡使用-O2選項,由於它在優化長度、編譯時間和代碼大小之間,取得了一個比較理想的平衡點。
time ./test 查看程序執行時間
優化雖然可以給程序帶來更好的執行性能,但在以下一些場合中應該避免優化代碼:
程序開發的時候優化等級越高,消耗在編譯上的時間就越長,所以在開發的時候最好不要使用優化選項,只有到軟件發行或開發結束的時候,才考慮對最終生成的代碼進行優化。
資源受限的時候一些優化選項會增長可執行代碼的體積,若是程序在運行時可以申請到的內存資源很是緊張(如一些實時嵌入式設備),那就不要對代碼進行優化,由於由這帶來的負面影響可能會產生很是嚴重的後果。
跟蹤調試的時候在對代碼進行優化的時候,某些代碼可能會被刪除或改寫,或者爲了取得更佳的性能而進行重組,從而使跟蹤和調試變得異常困難。
加速:
使用管道代替編譯中臨時文件,
-pipe 加速編譯
gcc -pipe foo.c -o foo
GCC經常使用選項
-c 通知GCC取消連接步驟,即編譯源碼並在最後生成目標文件;
-Dmacro 定義指定的宏,使它可以經過源碼中的#ifdef進行檢驗;
-E 不通過編譯預處理程序的輸出而輸送至標準輸出;
-g3 得到有關調試程序的詳細信息,它不能與-o選項聯合使用;
-Idirectory 在包含文件搜索路徑的起點處添加指定目錄;
-llibrary 提示連接程序在建立最終可執行文件時包含指定的庫;
-O、-O二、-O3 將優化狀態打開,該選項不能與-g選項聯合使用;
-S 要求編譯程序生成來自源代碼的彙編程序輸出;
-v 啓動全部警報;
-Wall 在發生警報時取消編譯操做,即將警報看做是錯誤;
-Werror 在發生警報時取消編譯操做,即把報警看成是錯誤;
-w 禁止全部的報警。 優化
靜態連接spa
在這種鏈接方式下,函數的代碼將直接拷貝到最終的可執行文件中。該程序被執行時候,會被裝入該進程的虛擬地址空間中。靜態連接庫其實是一個或若干目標文件。線程
動態連接調試
這種方式下,函數的代碼被放到稱做動態鏈接庫或共享對象的某個目標文件中。連接程序此時的工做只是在生成的可執行文件中,記錄下共享對象的名字以及少許關鍵信息。動態鏈接庫能夠被多個進程共享,在運行時候內存中只有一個實例。對象
兩者比較進程
使用動態連接可以使可執行文件較小,而且當共享對象被多個進程使用時節省內存。但有時候系統運行改變或升級,不能保證動態鏈接庫必定可用、有效。