在連線庫的時候,會出現undefined reference的現象,大致有以下幾種可能。
該錯誤的本質是編譯時宣告的實體(變數、函式等)在連線時找不到對應的定義。 經過前後摸索並查閱一些資料,把可能的原因總結如下,供各位參考:
1. 沒有指定對應的庫(.o/.a/.so) 使用了庫中定義的實體,但沒有指定庫(-l***)或者沒有指定庫路徑(-lyyy),會導致該錯誤
2. 連線庫引數的順序不對 (預設情況下)每個庫在連線時按照命令列引數的順序被搜尋並且只搜尋一次, 後面的庫如果用到了前面的庫中定義的實體,可能導致該錯誤 所以最好按照庫的依賴關係來按序寫引數,被依賴的庫放在後面
3. gcc/ld版本不匹配 gcc/ld的各版本間相容性並不是很好(最明顯表現於3.3和3.4之間), 比如低版本編譯的庫用高版本來進行連線,也可能會導致該錯誤
4. c/c++交叉編譯/連線 比如用c++連線c編譯的庫,但沒有在宣告實體時使用extern 「c」, 也會導致該錯誤。反之亦然。 tips:gcc會根據不同的副檔名使用不同語言編譯,比如對.c使用c,對.c/*.cpp使用c++
5. 函式定義與實現不一致 比如定義:int aaa(int b) 實現int aaa(u_int b)是兩個不同的函式。
我出現的問題在第二個,注意被依賴的庫需要放在後面。
ar打包出來的庫函式需要用連線 -l./ -l*** 標頭檔案,以及庫的名字。ar -r 就可以了
記錄一下我的第二個make相關的情況
makefile 檔案
target1 = test_main
target2 = libtxllmtrain.a
target3 = test_link
target4 = test_main_ln
obj1 = txl_lmtrain.o txl_lmtrain_api.o lex.o test_main.o
obj2 = txl_lmtrain.o txl_lmtrain_api.o lex.o
obj3 = test_link.o
#obj4 = test_main_ln.o txl_lmtrain.o txl_lmtrain_api.o lex.o
obj4 = test_main_ln.o
all:
$(target1) $(
target2)
rm -rf output
mkdir -p output/include
mkdir -p output/lib/
cp *.h output/include/
cp $(
target1) output
cp $(
target2) output/lib/
$(target1) :
$(obj1)
$(cxx) -g -o $@
$^$(
incdir) $(
libdir)
$(target2) :
$(obj2)
ar -r $(
target2) $(
obj2)
$(target3) :
$(obj3)
$(cxx) -g -o $@
$^ -l. -ltxllmtrain $(
incdir) $(
libdir)
$(target4) :
$(obj4)
$(cxx) -g -o $@
$^$(
incdir) $(
libdir) -l. -ltxllmtrain
上面的情況中: make太慢了,加快編譯速度的方法 make j
make j 既然io不是瓶頸,那cpu就應該是乙個影響編譯速度的重要因素了。用make j帶乙個引數,可以把專案在進行並行編譯,比如在一台雙核的機器上,完全可以用make j4,讓make最多允許4個編譯命令同時執行,這樣可以更有效的利用cpu資源。還是用kernel來測試 用make 40分16...
make太慢了,加快編譯速度的方法 make j
2018 01 18 09 04 05 gonghuihuihui 閱讀數 21957 收藏 更多 分類專欄 linux make j 既然io不是瓶頸,那cpu就應該是乙個影響編譯速度的重要因素了。用make j帶乙個引數,可以把專案在進行並行編譯,比如在一台雙核的機器上,完全可以用make j4...
make的條件語句
條件語句可以將乙個變數與其他變數進行比較,或將乙個變數與一字串變數相比較,這樣就可以根據變數的值執行或忽略makefile檔案中一部分指令碼。條件語句用於控制make實際看見的makefile檔案部分,不能在執行時控制shell命令,這個就和前面講過的偽指令不一樣了,偽指令可以控制一部分shell命...