首頁 > 軟體

Linux編譯相關命令

2020-06-16 16:43:24

一、編譯可執行檔案

g++ –c Hello.cpp  編譯檔案,生成目標檔案Hello.o

g++ Hello.o –o a.out  連結並重新命名為可執行檔案a.out

g++ Hello.cc    編譯連結一起,生成a.out

g++ Hello.cc –o hello 生成a.out並命名為hello

二、編譯相關選項

(1)-c

生成.o檔案,對程式碼檔案進行預處理、編譯和組合,相當於windows下生成目標檔案obj

g++ -c hello.cpp

(2)-I DirPath

指定檔案查詢目錄

-include file

-i file

指定包含的檔案

g++ hello.cpp -include ../include/a.h

-I- DirPath

就是取消前一個引數的功能,所以一般在-I DirPath之後使用

(3)-L LibPath

指定連結庫的路徑

-l library

-llibrary

指定連結庫

(4)  -g   
在編譯的時候,產生偵錯資訊,程式執行時可以dbg偵錯

(4)-static

此選項將禁止使用動態庫。

優點:程式執行不依賴於其他庫

缺點:檔案比較大

gcc test_main.c -static -o test_main -lpthread

會發現test_main很大,它已經把各種依賴的東西都包含進來

(5) -shared (-G)

此選項將儘量使用動態庫,為預設選項

優點:生成檔案比較小

缺點:執行時需要系統提供動態庫

(6)-Wall

一般使用該選項,允許發出GCC能夠提供的所有有用的警告。也可以用-W{warning}來標記指定的警告。

三、靜態庫和動態庫的編譯命令

1、生成動態庫和靜態庫

(1)得到hello.o

g++ -c hello.cpp

(2)得到靜態庫myhello.a

ar -cr libmyhello.a hello.o

(3)使用靜態庫

g++ -o hello main.c -L. -lmyhello

-L.表示靜態庫位於當前目錄下,myhello自動加上lib組成靜態庫名稱libmyhello.a

(4)得到動態庫myhello.so

 g++ -fPIC -shared hello.cpp -o libmyhello.so

(5)使用動態庫

動態庫的時候和靜態庫使用一樣,唯一值得注意的是當目錄中同時存在相同名稱的動態庫和靜態庫時,編譯的時候優先使用動態庫

2、fPIC選項

加上fPIC選項生成的動態庫時位置無關的,可以實現多個進程共用動態庫,多個進程參照同一個PIC動態庫時,可以共用記憶體。這一個庫在不同進程中的虛擬地址不同,但作業系統顯然會把它們對映到同一塊實體記憶體上。

不加fPIC,則載入so檔案時,需要對程式碼段參照的資料物件需要重定位,重定位會修改程式碼段的內容,這就造成每個使用這個.so檔案程式碼段的進程在核心裡都會生成這個.so檔案程式碼段的copy.每個copy都不一樣,取決於這個.so檔案程式碼段和資料段記憶體對映的位置。可見,這種方式更消耗記憶體。

3、如何解決執行時找不到動態庫的問題

(1)將動態庫新增到系統預設的搜尋路徑下,如/lib、/usr/lib

(2)設定臨時動態庫路徑的環境變數,這種方法設定的是臨時的,系統重新啟動之後就沒了

export LD_LIBRARY_PATH=./

取消設定

export LD_LIBRARY_PATH=

(3)/etc/ld.so.cache中快取了動態庫路徑,可以通過修改組態檔/etc/ld.so.conf中指定的動態庫搜尋路徑,然後執行ldconfig命令來改變

(4)編譯連結新增-WL,-rpath命令選項,將執行時動態庫的搜尋路徑記錄在可執行程式中

例如,有原始檔test.cpp和func.cpp

g++ -shared -fPIC func.cpp -o libfunc.so

編譯得到libfunc.so動態庫

g++ main.cpp -o a.out -L ./ -lfunc

編譯得到a.out,執行a.out,提示出錯

ldd檢視a.out依賴的動態庫,發現libfunc.so找不到

g++ main.cpp -o a.out -L ./ -lfunc -WL,-rpath ./

編譯得到a.out,執行a.out,執行成功,ldd檢視a.out依賴的動態庫,發現libfunc.so路徑正確

把a.out和libfunc.so拷貝到任何目錄下,都能執行成功


IT145.com E-mail:sddin#qq.com