文章目錄
-
- 問題
- 環境
- 檔案邏輯
- 動态編譯
-
- 編譯成動态庫
- 使用g++連結
- 使用clang++連結
- 靜态連結
-
- 編譯成靜态庫
- 使用g++連結
- 使用clang++連結同g++。
- 結論
問題
讨論了一下動态連結和靜态連結的問題,即在連結過程中到底是以什麼順序進行連結的,中間會不會儲存一部分資訊到符号表中。
環境
Ubuntu 14.04.6 LTS
g++ (Ubuntu 5.5.0-12ubuntu1~14.04) 5.5.0 20171010
Ubuntu clang version 3.4-1ubuntu3
檔案邏輯
main.cc調用test.cc,test.cc調用test2.cc
// main.cc
#include "test.h"
int main()
{
test();
return 0;
}
// test.cc
#include "test2.h"
void test()
{
test2();
}
// test2.cc
#include <iostream>
using namespace std;
void test2()
{
cout << "test2" << endl;
}
動态編譯
編譯成動态庫
g++ test.cc -shared -fPIC -o libtest.so
g++ test2.cc -shared -fPIC -o libtest2.so
使用g++連結
g++ main.cc -o main -L./ -ltest -ltest2 -I./
g++ main.cc -o main -L./ -ltest2 -ltest -I./
第一條語句報錯
.//libtest.so: undefined reference to `test2()’
collect2: error: ld returned 1 exit status
第二條語句連結成功
使用clang++連結
clang++ main.cc -o main -L./ -ltest -ltest2 -I./
clang++ main.cc -o main -L./ -ltest2 -ltest -I./
兩條語句均可正常連結
靜态連結
編譯成靜态庫
g++ -c test.cc
g++ -c test2.cc
ar -rc test.a test.o
ar -rc test2.a test2.o
使用g++連結
g++ main.cc test.a test2.a -o main
g++ main.cc test2.a test.a -o main
第一條語句正常執行
第二條語句報錯
test.a(test.o): In function
test()': test.cc:(.text+0x5): undefined reference to
test2()’
collect2: error: ld returned 1 exit status
使用clang++連結同g++。
結論
網上那些文章不靠譜哇。
g++不論是靜态連結還是動态連結,都需要以正确的順序進行連結,即基礎類放在最右面。原理應該是g++從左向右掃描所有連結庫,遇到連結庫中不認識的符号就放在一個undefined表中,如果在後面的庫中發現這個符号就填上正确的位置,沒發現則最後連結報錯。
clang++動态連結過程中會自動識别連結的順序,靜态連結需要手動調整順序。