使用 GCC 進行 C/C++ 代碼編譯時,如果代碼中使用到了庫函式,需要使用 -l 選項指定該庫函式所在的庫,如:-lm、-lrt、-lpthread等,這種方式使用的是庫的縮寫,一個庫的檔案名如果是:libxxx.so 或 libxxx.a,則可以使用 -lxxx 進行鏈接,這種規則很常見,但是缺點也很明顯,假設在一臺 Linux 機器上,同時具有 libxxx.so 和 libxxx.a,GCC 會優先鏈接 libxxx.so,雖然,GCC 也提供了 -static 選項可以強制鏈接靜態庫,但是,這時候新的問題出現了,假設有兩個庫 x 和 y,他們都具有靜態庫和動態庫兩個版本,假設我想要鏈接 libx.so 和 liby.a,使用 -static 選項無法滿足這個要求,我需要更加精細的控制,最好是直接根據檔案名直接指定鏈接哪個版本的庫檔案,就沒有任何歧義,
GCC 檔案的關于 -l 選項的描述沒有告訴我如何直接使用一個庫檔案名,于是翻看 ld 的檔案,在關于 -l 選項的描述中,有這樣一段話:
If namespec is of the form ‘:filename’, ld will search the library path for a file called filename, otherwise it will search the library path for a file called ‘libnamespec.a’.
也就是說可以使用 -l:filename 的形式直接指定庫檔案名,這個只是 ld 的選項,GCC 能不能直接使用還需要驗證,設計三個 .cpp 檔案,分為 x.cpp y.cpp 和 main.cpp,
// x.cpp
#include <iostream>
void print_x()
{
std::cout << "x" << std::endl;
}
// y.cpp
#include <iostream>
void print_y()
{
std::cout << "y" << std::endl;
}
// main.cpp
void print_x();
void print_y();
int main()
{
print_x();
print_y();
}
使用如下 Makefile 進行編譯,x.cpp 編譯成 libx.so 和 libx.a,y.cpp 編譯成 liby.so 和 liby.a,main.cpp 與 libx.so 和 liby.a 編譯連接成 main.out,
all : main
x :
gcc -o libx.so -shared -fPIC x.cpp
gcc -o x.o -c x.cpp
ar crs libx.a x.o
y :
gcc -o liby.so -shared -fPIC y.cpp
gcc -o y.o -c y.cpp
ar crs liby.a y.o
clean :
rm -f *.out *.o *.so *.a
main : x y
gcc -o main.out main.cpp -Wl,-rpath=./ -lstdc++ -L. -l:libx.so -l:liby.a
能直接通過編譯,使用 ldd main.out 查看一下動態庫依賴:
linux-vdso.so.1 (0x00007ffe71ace000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f1bdea54000)
libx.so => ./libx.so (0x00007f1bdea4f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f1bde845000)
libm.so.6 => /lib64/libm.so.6 (0x00007f1bde769000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1bdec7b000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f1bde74e000)
可以看到 libx.so 被動態鏈接,而 liby.a 被靜態鏈接,沒有顯示,執行 main.out,輸出結果也符合預期,
x
y
由此可見,-l:filename 能直接用于 GCC,這種方法除了控制鏈接的庫是靜態的還是動態的之外,還能用于控制庫的版本號,例如 libx.so 同時存在兩個版本 libx.so.1 和 libx.so.2 ,可以使用 -l:libx.so.1 指定版本號為 1 的庫,
本文來自博客園,作者:mkckr0,轉載請注明原文鏈接:https://www.cnblogs.com/mkckr0/p/15914118.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/428493.html
標籤:其他
上一篇:python函式
下一篇:IO流學習筆記
