gcc的簡單使用

gcc是一系列的軟件的組合
首先,gcc通過cpp預處理器將源程序進行擴展,包括頭文件的展開和宏的展開,形成.i文件,然後,gcc通過cc1編譯器進行編譯,生成彙編程序,通過彙編器as產生可重定位的目標程序,可重定位表示代碼段、數據段的開始地址爲0,沒有根據機器生成實際的地址。最後,通過鏈接器ld生成可執行目標程序,鏈接器不僅要完成物理地址的翻譯,還要和其他調用的庫鏈接,最終生成可執行文件。

gcc常用選項
-o    生成的文件名稱(.s,.i,.o等)
-E    只運行c預處理器
-S    生成彙編代碼後停止編譯
-c    取消鏈接的步驟,生成可重定位的目標代碼
-Wall  顯示所有的警告(建議全部加上)
例如:
gcc -E hello.c -o hello.i(預處理後的文件)
gcc -S hello.i -o hello.s(生成彙編代碼)
gcc -c hello.s -o hello.o(可重定位的目標程序)
gcc hello.c -o hello(直接生成可執行程序)

gcc編譯多個文件:
一次性編譯: gcc hello.c main.c -o main
分開各個編譯: gcc -c hello.c -o hello.o
                          gcc -c main.c -o main.o
                          gcc hello.o main.o -o main
爲什麼分開編譯需要加-c選項?因爲還無法知道其他庫的信息,無法進行鏈接

頭文件:一般包含外部函數的聲明
庫文件:預先編譯好的函數

外部庫的使用:gcc -Wall calc.c -o calc -lm         -l表示鏈接外部庫,m表示鏈接的庫是libm.a或者libm.so
雖然鏈接了外部的庫函數,但是函數聲明的頭文件必須要包含,否則可能產生隱式的轉換

靜態庫與共享庫:
靜態庫:.a文件,一般在程序的鏈接過程中就被包含進去,運行時不需要包含
動態庫:.so文件,只有在程序運行時才被包含,多個程序可以共享,所以,程序使用共享庫的時候,僅僅包含了函數入口地址的一個表,而不是整段代碼
在程序運行之前,由操作系統將共享庫代碼由磁盤的共享庫中拷貝到內存,稱爲動態鏈接

生成靜態庫:
ar rcs libhello.a hello.o      ar是gnu歸檔工具,r表示replace(如果存在則替換),c表示create(如果不存在則創建),s表示save(將.o文件中一些索引信息到.a文件中)

使用靜態庫
gcc -Wall main.c libhello.a -o main
gcc -Wall -L. main.c -o main -lhello     使用-L選項表示搜索的庫文件的路徑,表示將當前路徑加入

庫的搜索路徑:
C_INCLUDE_PATH,LIBRARY_PATH
從左至右搜索-I -L指定的路徑
環境變量指定的目錄    ~/.bashprofile
系統指定的目錄

生成共享庫:
gcc -shared -fPIC hello.o -o libhello.so   shared表示生成共享庫格式,PIC表示位置無關碼,可以在內存的任何位置啓動執行

使用共享庫:
gcc -Wall main.o -o main -L. -lhello
一般可以將庫文件拷貝至/usr/lib中使用

命令ldd 查看一個目標文件的鏈接情況

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章