日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

[转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)

發布時間:2023/12/2 linux 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ?在windows環境下,我們通常在IDE如VS的工程中開發C++項目,對于生成和使用靜態庫(*.lib)與動態庫(*.dll)可能都已經比較熟悉,但是,在linux環境下,則是另一套模式,對應的靜態庫(*.a)與動態庫(*.so)的生成與使用方式是不同的。剛開始可能會不適應,但是用多了應該會習慣這種使用,因為步驟上并沒有VS下配置那么繁瑣。下面就分別總結下linux下生成并使用靜態庫與動態庫的方法:(由于是C++項目,所以編譯器用的g++,但是與gcc的使用是相通的)

? 首先是準備工作,把我們需要封裝成庫文件的函數的頭文件與源文件寫好,如下:

//myAPI.h int ADD(int a, int b); int MINUS(int a, int b); //myAPI.cpp #include "myAPI.h"int ADD(int a, int b){return a + b; }int MINUS(int a, int b){return a - b; }

? 接下來準備一個測試用的主函數源文件:

//main.cpp #include "myAPI.h" #include <iostream>int main(){std::cout << "1 + 1 = " << ADD(1, 1) << std::endl;std::cout << "1 - 1 = " << MINUS(1, 1) << std::endl;return 0; }

重要說明:

linux下用生成靜態庫的命令 ar 處理 myAPI.o 文件生成靜態庫文件,生成的庫文件應遵循規范,及linux下庫文件加“lib”前綴。

編譯/鏈接生成時,也要注意,目標文件/庫文件之間有依賴關系,則需要把被依賴文件放到后面(g++6.x),才能編譯,

不然可能報錯 找不到變量函數/ 未定義的引用?"undefined reference to".?

?

? 貼上Makefile,有注解:

all: main-1 main-2 main-a main-so main-so2main-1: myAPI.cpp main.cpp myAPI.hg++ -o main-1 myAPI.cpp main.cpp@echo "main-1 done. 直接編譯省略顯示編譯.o文件"@echomain-2: main.cpp myAPI.og++ -o main-2 myAPI.o main.cpp@echo "main-2 done. 顯示編譯.o文件"@echomain-a: libmyAPI.ag++ -o main-a main.cpp libmyAPI.a@echo "main-a done. 使用.a靜態庫文件 鏈接生成程序"@echomain-so: libmyAPI.sog++ -o main-so main.cpp ./libmyAPI.so@echo "main-so done. 直接使用.so動態庫文件(需要帶路徑,運行時直接使用此路徑) 鏈接生成程序"@echomain-so2: libmyAPI.sog++ -o main-so2 main.cpp -L. -lmyAPI@echo "main-so2 done. 讓g++自動在當前目錄("."表示當前目錄,或"./")查找.so動態庫文件 鏈接生成程序"@echo " 但運行時默認到/usr/lib目錄查找,,或運行前設置環境變量 LD_LIBRARY_PATH 為動態庫的路徑"@echomyAPI.o: myAPI.cpp myAPI.hg++ -c myAPI.cpp@echo "myAPI.o done. 編譯.o文件"@echolibmyAPI.a: myAPI.oar crv libmyAPI.a myAPI.o@echo "libmyAPI.a done. 編譯.a靜態庫文件"@echolibmyAPI.so:g++ -fPIC -c myAPI.cppg++ -shared -o libmyAPI.so myAPI.o@echo "libmyAPI.so done. 編譯.so動態庫文件,需要 .o文件編譯時加選項 -fPIC"@echo " 或者 直接編譯動態庫:"@echo " g++ -shared -fPIC -o libmyAPI.so myAPI.cpp"@echo#或者 直接編譯動態庫: #libmyAPI.so: # g++ -shared -fPIC -o libmyAPI.so myAPI.cpp #clean:rm -f *.o *.a *.so main-*

??

最后運行程序:

[root@lzp test2]# ./main-1 1 + 1 = 2 1 - 1 = 0 [root@lzp test2]# ./main-2 1 + 1 = 2 1 - 1 = 0 [root@lzp test2]# ./main-a 1 + 1 = 2 1 - 1 = 0 [root@lzp test2]# ./main-so 1 + 1 = 2 1 - 1 = 0 [root@lzp test2]# ./main-so2 ./main-so2: error while loading shared libraries: libmyAPI.so: cannot open shared object file: No such file or directory

可以看到 main-so直接運行了,但是 main-so2 運行出錯了,找不到動態庫,需要把動態庫放到/usr/lib目錄; ?或者使用"LD_LIBRARY_PATH"環境變量后可以直接運行

[root@lzp test2]# LD_LIBRARY_PATH=./ [root@lzp test2]# ./main-so2 ./main-so2: error while loading shared libraries: libmyAPI.so: cannot open shared object file: No such file or directory [root@lzp test2]# LD_LIBRARY_PATH=./ ./main-so2 1 + 1 = 2 1 - 1 = 0

PS:但是在 G++ 6.x版本下直接運行main-so2不出錯,,以上是G++4.X版本編譯的

?

?在項目開發過層中盡量讓lib是垂直關系,避免循環依賴;越是底層的庫,越是往后面寫!

例如:

g++ ... obj($?) -l(上層邏輯lib) -l(中間封裝lib) -l(基礎lib) -l(系統lib) -o $@

這樣寫可以避免很多問題,這個是在搭建項目的構建環境的過程中需要考慮 清楚地,在編譯和鏈接上浪費太多的生命不值得!

?

??推薦一本書,寫的很深刻:《程序員的自我修養——鏈接、裝載與庫》

[參考: http://www.tuicool.com/articles/m67z2u2; ?http://blog.chinaunix.net/uid-24352482-id-3199452.html]

[參考: http://www.cnblogs.com/little-ant/p/3398885.html]

轉載于:https://www.cnblogs.com/lzpong/p/5776728.html

總結

以上是生活随笔為你收集整理的[转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。