1、編譯可執行文件windows
g++ –c Hello.cpp 編譯文件,生成目標文件Hello.o緩存
g++ Hello.o –o a.out 連接並重命名爲可執行文件a.outspa
g++ Hello.cc 編譯連接一塊兒,生成a.out操作系統
g++ Hello.cc –o hello 生成a.out並命名爲hello調試
2、編譯相關選項對象
(1)-cblog
生成.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}來標記指定的警告。
3、靜態庫和動態庫的編譯命令
一、生成動態庫和靜態庫
(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)使用動態庫
動態庫的時候和靜態庫使用同樣,惟一值得注意的是當目錄中同時存在相同名稱的動態庫和靜態庫時,編譯的時候優先使用動態庫
二、fPIC選項
加上fPIC選項生成的動態庫時位置無關的,能夠實現多個進程共享動態庫,多個進程引用同一個PIC動態庫時,能夠共享內存。這一個庫在不一樣進程中的虛擬地址不一樣,但操做系統顯然會把它們映射到同一塊物理內存上。
不加fPIC,則加載so文件時,須要對代碼段引用的數據對象須要重定位,重定位會修改代碼段的內容,這就形成每一個使用這個.so文件代碼段的進程在內核裏都會生成這個.so文件代碼段的copy.每一個copy都不同,取決於這個.so文件代碼段和數據段內存映射的位置。可見,這種方式更消耗內存。
三、如何解決運行時找不到動態庫的問題
(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拷貝到任何目錄下,都能運行成功