views:

344

answers:

2

In one project, I have two noinst_PROGRAM's defined. One of them works just fine, but the other is giving me the following message:

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

I have been looking through my Makefile.am files and I cannot find anything I've missed. The application compiles correctly so I am guessing that that means that the header file is found correctly but for some reason my gdata::service::Service is not being included in the src/libgdata.la library.

Is it likely that my assumption is correct? The other classes defined in the src/libgdata.la library seem to be usable. The output of "make" shows that the Service.cc file is being compiled correctly... any pointers for where I should look to make certain that it is being included in the final library?

EDIT:

I've been able to debug this a bit further based on the answers provided so far.

The destructor is defined in Service.cc. If I give the destructor a body in the header file, everything works just fine.

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

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

Now that the destructor "works", I've run into other methods defined in Service.cc that are not found.

Using @ephemient's method, it looks to me like these symbols are actually being included in the library. Or am I reading the output incorrectly?

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

My src/Makefile.am looks like this:

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

My src/gdata/service/Makefile.am looks like this:

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

My test/Makefile.am looks like this:

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

gdatayoutube works just fine. It is older code that uses code from the client directory instead of service ( gdata/client/libgdata_gdata_client.la ) ... I cannot see any difference between how client is setup from service. :-/

**EDIT #2:##

Well, I don't know how this happened, but I think I found my problem. I think that the test apps were linking against the installed version of the library I was working on instead of the local version built in src/.

I'll explore this more and maybe ask some other questions another time.

+2  A: 
ephemient
Thanks for the pointers! I've updated my question with more details. :)
Beau Simensen
+3  A: 

Since c++filt -n -s gnu-v3 _ZN5gdata7service7ServiceD1Ev yields the name:

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

you need to look hard at whether the destructor for that class is defined always, or whether there is some way it can be left undefined (or, indeed, whether it is ever defined). Or whether the source file containing the destructor (why isn't it Service.cc?) is compiled. Some file using the code expects to find a destructor for it, even if Service.cc does not think one is necessary.

Another possibility is a library sequencing error - that is, the link line lists the libraries in the order A B C but they need to be in the order B C A or some other permutation and you are linking with static libraries. Usually, that leads to large numbers of undefined symbols if you are linking with static libraries (but using shared libraries conceals ordering problems).

@Ephemient has given you some good pointers on how to find the object file that references the destructor. You should also determine whether or not Service.o (Service.lo, or .lib/Service.o or other similar names) contains the destructor - it most likely does not contain the destructor, given the link error.

Jonathan Leffler
+1 Awesome, I never remember how to unmangle those darn C++ symbols... @Beau: if you have library ordering problems, libraries provide symbols for objects and libraries listed ahead of them in the command line (unless `-Wl,--startgroup -Wl,--endgroup` are in play).
ephemient
The destructor **was** defined in the Service.cc file, but I tried moving it to the header to see what that would do. By moving it to the header, I've confirmed that at least the header is working and that the problem does indeed seem to be that the Service.o object is not making its way into libgdata for some reason. Thanks for the idea there, as I think it helped me narrow down the I've updated my question with more details.
Beau Simensen