2009-07-21 41 views
2

在一個項目中,我定義了兩個noinst_PROGRAM。其中一人工作得很好,但對方是給我下面的消息:我應該在automake/autoconf項目中尋找解決符號查找/未定義符號的方法?

/home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar: symbol lookup error: /home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar: undefined symbol: _ZN5gdata7service7ServiceD1Ev

我一直在尋找通過我的Makefile.am文件的內容,我無法找到任何我已經錯過了。該應用程序編譯正確,所以我猜測這意味着頭文件找到正確,但由於某種原因,我的gdata::service::Service沒有被包含在src/libgdata.la庫中。

我的假設可能是正確的嗎?在src/libgdata.la庫中定義的其他類似乎是可用的。 「make」的輸出顯示Service.cc文件正在編譯正確......我應該查看哪些指針以確保它被包含在最終庫中?

編輯:

我已經能夠有點進一步調試此基礎上迄今提供的答案。

析構函數在Service.cc中定義。如果我在頭文件中給析構函數一個正文,一切正常。

// In Service.h 
~Service() {} 

// In Service.cc 
// Service::~Service() {} 

現在,析構函數「作品」,我已經運行到Service.cc規定的其他方法未找到。

使用@ ephemient的方法,它在我看來像這些符號實際上被包含在庫中。或者我讀錯了嗎?

000000e0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_ 
000000a0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b 
./src/.libs/libgdata.a 
000240d0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_ 
00024090 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b 
000240d0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_ 
00024090 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b 
./src/.libs/libgdata.so 
00000080 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_ 
00000070 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b 
./src//gdata/service/libgdata__gdata_service_la-Service.o 
000000e0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_ 
000000a0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b 
./src//gdata/service/.libs/libgdata__gdata_service.a 
000000e0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_ 
000000a0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b 
./src//gdata/service/.libs/libgdata__gdata_service_la-Service.o 

我的src/Makefile.am看起來是這樣的:

SUBDIRS = gdata 

lib_LTLIBRARIES = libgdata.la 

libgdata_la_SOURCES = 

libgdata_la_LIBADD = \ 
    gdata/client/libgdata_gdata_client.la \ 
    gdata/data/libgdata_gdata_data.la \ 
    gdata/data/youtube/libgdata_gdata_data_youtube.la \ 
    gdata/util/libgdata_gdata_util.la \ 
    gdata/service/libgdata_gdata_service.la \ 
    gdata/service/calendar/libgdata_gdata_service_calendar.la 

我的src/GDATA /服務/ Makefile.am看起來是這樣的:

SUBDIRS = calendar 

noinst_LTLIBRARIES = libgdata_gdata_service.la 

libgdata_gdata_service_ladir = \ 
    $(includedir)/gdata/service 

libgdata_gdata_service_la_SOURCES = \ 
    Service.cc 

libgdata_gdata_service_la_HEADERS = \ 
    Service.h 

我的測試/ Makefile文件。我看起來是這樣的:

INCLUDES = -I$(top_srcdir)/src/ -I$(top_srcdir)/test/ 

LDADD = ../src/libgdata.la 

TESTS = check_bare 

noinst_PROGRAMS = gdatacalendar gdatayoutube $(TESTS) 

check_bare_SOURCES = check_bare.cc 

gdatacalendar_SOURCES = gdatacalendar.cc 

gdatayoutube_SOURCES = gdatayoutube.cc 

gdatayoutub e工作得很好。它是使用客戶端目錄代碼而不是服務的代碼(gdata/client/libgdata_gdata_client.la)...我看不出客戶端是如何從服務設置的。 : -/

**編輯#2:##

好吧,我也不知道怎麼回事,但我想我找到了我的問題。我認爲測試應用程序與我正在使用的庫的已安裝版本鏈接,而不是在src /中內置的本地版本。

我會探索這個更多,也許再問一些其他問題。

+0

嘗試將`libgdata_gdata_service.la`移動到`libgdata_la_LIBADD`中的`libgdata_gdata_service_calendar.la`後面,以查看它是否歸因於圖書館排序,正如Jonathan所懷疑的。 – ephemient 2009-07-22 00:37:45

回答

2

(還有由名libgdata已經現有的項目,但是這可能不相關。)

 
$ find -name '*.o' -o -name '*.a' -o -name '*.so' | 
> while read i; do 
>  (nm --defined-only $i; nm -D --defined-only $i) 2>/dev/null | 
>  grep _ZN5gdata7service7ServiceD1Ev && echo "$i" 
> done 

這是一個相當暴力的方式來發現哪些對象(如果有的話)的符號_ZN5gdata7service7ServiceD1Ev被定義。(這可能是更容易只是爲了找到定義gdata::service::Service源文件,如果模板是不是在玩。)

 
$ rm libgdata.la gdatacalendar 
$ make 

這是一個強力的方式來發現是越來越列入libgdata.lagdatacalendar什麼。 (但是,從相應的Makefile.am中查看(libgdata_la|gdatacalendar)_(SOURCES|LIBADD)應該是非常明顯的。)

這裏有不匹配嗎?

+0

感謝您的指點!我更新了我的問題,並提供了更多細節。 :) – 2009-07-21 21:35:14

7

由於c++filt -n -s gnu-v3 _ZN5gdata7service7ServiceD1Ev得到名稱:

gdata::service::Service::~Service() 

你需要在該類的析構函數是否總是被定義爲看很難,還是有一些方法也可以不定義(或者,實際上,無論是它是永遠定義的)。或者是否編譯了包含析構函數的源文件(爲什麼不是Service.cc?)。某些使用代碼的文件希望找到它的析構函數,即使Service.cc認爲沒有必要。

另一種可能性是庫排序錯誤 - 也就是說,鏈接行按照A B C的順序列出庫,但它們需要按照B C A或某種其他排列的順序,並且您正在與靜態庫鏈接。通常情況下,如果您使用靜態庫進行鏈接(但使用共享庫會隱藏排序問題),則會導致大量未定義的符號。

@Ephemient給了你一些關於如何找到引用析構函數的對象文件的好指針。您還應該確定Service.oService.lo.lib/Service.o.lib/Service.o或其他類似名稱)是否包含析構函數 - 它極有可能不包含析構函數,因爲鏈接錯誤。

+1

+1真棒,我永遠不會記得如何解開那些不合格的C++符號...... @Beau:如果你有圖書館訂購問題,圖書館提供了在命令行中列出的對象和庫的符號(除非`-Wl , - startgroup -W1, - endgroup`在玩)。 – ephemient 2009-07-21 01:57:53

相關問題