1. 程式人生 > 其它 >GCC編譯工具

GCC編譯工具

技術標籤:gccc++

示例程式碼如下,檔名: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

示例程式碼如下,檔名:main.cpp(c++)

#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下面找到的