Linux的動態庫和靜態庫的概念:
(1)靜態庫:Linux靜態庫就是一些 .a 文件。本質上就是一些二進制文件的打包,一個靜態庫可以是由 0 ~ 多個 .o 文件生成。靜態庫在鏈接到可執行文件時被拷貝到可執行文件中,因此可執行文件的大小會增加,並且在執行時不需要靜態庫。
(2)動態庫:Linux動態庫是一些 .so 文件。動態庫在鏈接時並不會被拷貝到可執行文件中,因此不會增加可執行文件的大小,但是在運行環境中需要動態庫,以便動態加載器加載。
Linux的動態庫和靜態庫的使用(注意,無論是動態庫還是靜態庫,在可執行文件的鏈接階段都需要指定鏈接):
場景如下:testb會被獨立編譯成一個庫,testa引用testb中的函數並生成另外一個庫。main會引用testa中的函數並鏈接這兩個庫,生成可執行文件。代碼如下:
testb.cc:
#include <iostream>
void dumpB() {
std::cout << "B" << std::endl;
}
testa.cc:
#include <iostream>
extern void dumpB();
void dumpA() {
std::cout << "A" << std::endl;
dumpB();
}
main.cc:
int main() {
dumpA();
return 0;
}
(1)二進制文件 .o 的生成:
g++ -fPIC -c testb.cc // 生成testb.o
g++ -fPIC -c testa.cc // 生成testa.o
(2)靜態庫的生成:
ar -rc libtestb.a testb.o //生成 libtestb.a靜態庫
ar -rc libtesta.a testa.o // 生成 libtesta.a靜態庫
(3)動態庫的生成:
g++ -fPIC --shared -o libtestb.so testb.o // --shared表示生成動態庫
g++ -fPIC --shared -o libtesta.so testa.o // --shared表示生成動態庫
(4)可執行文件的生成(庫的鏈接):
g++ -I. -L. -o main main.cc -ltesta -ltestb // 鏈接 testa, testb兩個庫,生成可執行文件main
注意:
(1)庫之間有依賴的情況下,在鏈接時按照依賴順序編寫,否則最終會有符號未定義的錯誤出現。如,上例中必須寫成 -ltesta -ltestb,而不能寫成 -ltestb -ltesta。
(2)靜態庫可以依賴動態庫,動態庫也可以依賴靜態庫。只要在鏈接到最終的可執行文件中,庫(無論是.a,.so)都存在,就ok。因此上例中,可以有如下組合:
1,libtesta.a 和 libtestb.a
2,libtesta.a 和 libtestb.so
3,libtesta.so 和 libtestb.a
4,libtesta.so 和 libtestb.so