在連接庫的時候,會出現undefined reference的現象,大致有以下幾種可能。 該錯誤的本質是編譯時聲明的實體(變量、函數等)在連接時找不到對應的定義。 經過前后摸索并查閱一些資料,把可能的原因總結如下,供各位參考: 1. 沒有指定對應的庫(.o/.a/.so) 使用了庫中定義的實體,但沒有指定庫(-lXXX)或者沒有指定庫路徑(-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)是兩個不同的函數。
Makefile 文件
TARGET1 = test_mainTARGET2 = libtxllmtrain.aTARGET3 = test_linkTARGET4 = test_main_lnOBJ1 = txl_lmtrain.o txl_lmtrain_api.o lex.o test_main.oOBJ2 = txl_lmtrain.o txl_lmtrain_api.o lex.oOBJ3 = test_link.o#OBJ4 = test_main_ln.o txl_lmtrain.o txl_lmtrain_api.o lex.oOBJ4 = test_main_ln.oall: $(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上面的情況中:
TARGET1 是可以make過的,沒有用到編譯連接的庫; TARGET2 這個就是 ar -r 的用法了,庫需要命名為libtxllmtrain.a,連接的時候 -L./ -ltxllmtrain 就可以了; TARGET3 這個用了編譯鏈接的庫,因為 libtxllmtrain.a 這個庫依賴于后面的庫,所以了這個是可以過的; TARGET4 這個會出現 undefined reference 的問題,也就是上面的第二點所說明的問題。編譯庫的順序的問題了。新聞熱點
疑難解答