做開發快3年了,在linux下編譯安裝軟件算是家常便飯了。就拿gcc來說,都有不下10次了,可基本每次都會碰到些奇奇怪怪的問題。看來還是像vs、codeblocks這樣的ide把人弄蠢了。便下定決心一定要好好學習下如何在linux下純手工gcc編譯c項目。今天學了2點,一個是庫文件處理,另一個是makefile編寫。
學習的系統是centos6.6,編譯升級的gcc4.8.2,明天寫個博客總結下這回gcc安裝的過程,每次都能學到些東西。
gcc的編譯過程
首先需要清楚gcc編譯做了些什么
源文件----預處理---->預處理文件(*.i)----編譯---->匯編文件(*.s)----匯編編譯---->目標文件(*.o)----鏈接---->可執行文件
基本與windows下的類似。通過給gcc加一些選項,可以控制編譯工作進行到指定的階段,下面試常用的一些gcc編譯選項
- -c 編譯,匯編源文件,不鏈接,得到*.o文件
- -S 只編譯,不匯編,得到*.s文件
- -E 預處理文件,得到*.E文件
- -o [dis] [src] 將src文件編譯成可執行文件dis
- -Idir 指定include包含文件搜索路徑
- -g 生成具有調試信息,如果不加這個選項,*.o文件中不會生成.debug段,在調試時將不能查看打印變量值
學習過c和c++的都知道,c或c++程序存在各種各樣的庫文件,就是已經編譯好的包含數據和執行代碼的二進制文件。windows就是dll文件,linux下有.a和.so文件。如果需要使用這些庫文件,在ide環境下勾個選項就把事給辦了,在手工編譯的情況下就麻煩了點。
gcc創建和使用靜態庫
編寫static_lib.c文件
創建靜態庫
1 gcc -c static_lib.c 2 ar rcs static_lib.a static_lib.o
上面的命令會在當前目錄下生產 static_lib.a 靜態庫文件
使用鏈接靜態庫
編寫 static_lib.h文件
編寫main3.c文件,使用靜態庫中的方法
編譯main3.c並鏈接靜態庫文件
執行
1 gcc main3.c -lstatic_lib.a -o app3
但卻出現鏈接器ld找不到庫的問題,把-l參數去掉就正常了
1 gcc main3.c static_lib.a -o app3
最后會生成可執行文件app3。靜態庫的特點是將庫里的代碼放到了執行文件里,如果修改了靜態庫的代碼,要重新編譯依賴它執行文件才能升級
gcc創建和使用動態庫
動態庫就是在有執行文件需要使用這個庫時,動態加載到執行的庫文件。
編寫share_lib.c文件
創建動態庫
因為需要與位置無關,所以需要使用-fPIC選項,gcc的選項有上千個,需要查詢某個選項可以man gcc然后查找查看
1 gcc -shared -fPIC -o share_lib.so share_lib.c
生成的share_lib.so文件就是動態庫文件,在使用這個庫的程序使用時被動態加載,並沒有被寫入到別的執行文件中,所以當庫文件修改,不需要去重新編譯其他使用這個庫的程序
使用動態庫
share_lib.h文件聲明函數
編寫main4.c文件,include "share_lib.h" 文件
編譯main4.c並鏈接動態庫
1 gcc main4.c ./share_lib.so -o app4
生成的app4就是可執行文件.
編寫makefile編譯
將前面靜態庫的3個源文件main3.c,static_lib.c,static_lib.h放到一個目錄下。
編寫Makefile文件。
其中冒號左邊表示目標文件或者命令,命令也叫偽目標。
執行make
執行make clean可以清除編譯產生的文件
當然,這恐怕是最簡單的makefile了,Makefile還有很多學的,我也在學習中,以后有收獲會繼續寫博客記錄,爭取以后看大神寫的makefile不要在略懂略懂了