做開發快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.c2 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不要在略懂略懂了


    推薦閱讀:
    查看原文 >>
    相關文章