GCC編譯工具
阿新 • • 發佈:2021-01-01
示例程式碼如下,檔名:main.c
#include <stdio.h>
int main()
{
printf("hello lee.\n");
return 0;
}
1. GCC引數講解
引數:-o
gcc main.c -o main -> -o引數表示輸出檔案
引數:-c
只編譯不連結
,做大專案的時候只針對一個檔案進行編譯,同時避免每次都連結
gcc -c main.c -o ->生成.o檔案
gcc main.o -o main ->連結,生成可執行檔案
注: 編譯的時候是不需要指定庫檔案的路徑(不考慮);在連結的時候處理,可以把不同的引數分開在不同的地方進行處理
引數:-E
預處理:只做預處理
,巨集定義與標頭檔案的替換
gcc -E main.c -o main.i -> 生成.i檔案
引數:-S
編譯:只編譯,不彙編
,區別-c只編譯不連結
gcc -S main.i -o main.s -> 生成.s檔案(彙編程式碼)
引數:-c
彙編:只編譯不連結
gcc -c main.s -o main.o -> 生成二進位制檔案,不進行連結
引數:-d
生成除錯資訊,對應Debug版本,不指定預設位Release版本
gcc -d main.c -o main -> 生成帶有除錯資訊的二進位制檔案
2. GCC多檔案編譯
https://blog.csdn.net/deeplan_1994/article/details/82892572
#include <iostream>
#include "Person.h"//大小寫敏感
using namespacing std;
int main(int argc,char *argv[])
{
Person person;
cout << "test g++ .\n" << endl;
return 0;
}
main.cpp同級目錄下新建檔案家Person,建立以下Person類檔案
Person類定義程式碼如下,檔名Person.cpp
#include "Person.h"
#include <stdio.h>
class Person::Person(){
printf("test Person"\n);
}
Person類申明程式碼如下,檔名Person.h
class Person
{
Person();
};
g++ Person.cpp -o Person//(gcc Person.cpp)如果是在單獨的檔案家裡面,沒有main是會報錯的,因為最後需要連結到唯一的main函式
g++ mian.c//也會報錯,因為找不到標頭檔案,需要指定標頭檔案的路徑
g++ mian.cpp -o main -I../Person.h//大寫的i指定標頭檔案的路徑,還是會報錯,找不到定義
g++ main.cpp ../Person/Person.cpp -o main -I../Person.h//指定定義檔案
3. GCC靜態編譯
linux上面的靜態庫比較簡單,區別windows,linux下的.o檔案就可以相當於一個靜態庫
如果把一個程式直接編譯成靜態庫,就會把所有引用到的系統檔案都編譯成靜態庫,全部編到可執行檔案中,
iostream stdio實際上會連結很多系統庫,c++有std stl庫,這些庫不會編譯進去,所以執行程式很小,當把這些庫都編進去就會變得很大,但是執行的時候是在特定環境下,這個環境下面是包含動態庫的,所以可以直接執行。
動態編譯(連結動態庫):
g++ mian.cpp -o main
ldd main //檢視可執行程式所引用的所有的庫
靜態編譯:
g++ mian.cpp -o main_static -static
ldd main_static //檢視是沒有動態庫的引用,檔案變得很大,編譯時間長,因為需要拷貝庫檔案,造成執行簡單,編譯複雜
4. GCC動態庫編譯和呼叫
g++ Person.cpp -fpic -shared -o libPerson.so//->生成libPerson.so
- -fpic表示Person裡面的函式與程式碼位置不相關,通過名字就能找到函式所在的位置
- -shared表示需要生成一個動態連結庫
- 名稱必須lib+“庫名”+.so,引用庫的時候只需要寫Person就行了
靜態庫生成後,開始編譯,g++ main.cpp -o main
//報錯,找不到標頭檔案
g++ main.cpp -o mian -I../Person
//報錯,找不到定義:
g++ mian.cpp -o mian -I../Person -L../Person -lPerson
大寫i指定標頭檔案路徑,大寫的L指定庫檔案路徑,小寫的l指定庫檔名
,生成可執行檔案,執行./main,報錯:因為沒有指定可執行程式庫檔案的路徑- 解決方法:
- 方法1. 把lib檔案拷貝到系統的path路徑下面;
- 方法2. 可執行指令碼的方式:
export LD_LIBRARY_PATH=../Person
,直接把path指定為動態庫的路徑,然後./mian就可以運行了,ldd mian
可以看到連結的動態庫有libPerson.so檔案,是在…/Person下面找到的