我应该在哪里寻找使用automake/autoconf项目解决符号查找/未定义的符号?

Bea*_*sen 2 c++ linker automake autoconf symbols

在一个项目中,我有两个noinst_PROGRAM定义.其中一个工作正常,但另一个给我以下消息:

/home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar:符号查找错误:/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() {}
Run Code Online (Sandbox Code Playgroud)

既然析构函数"有效",我会遇到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
Run Code Online (Sandbox Code Playgroud)

我的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
Run Code Online (Sandbox Code Playgroud)

我的src/gdata/service/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
Run Code Online (Sandbox Code Playgroud)

我的test/Makefile.am看起来像这样:

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
Run Code Online (Sandbox Code Playgroud)

gdatayoutube工作正常.它是使用客户端目录中的代码而不是服务的旧代码(gdata/client/libgdata_gdata_client.la)...我看不出客户端如何从服务设置有任何区别.: - /

**编辑#2:##

好吧,我不知道这是怎么发生的,但我想我发现了我的问题.我认为测试应用程序链接到我正在处理的库的已安装版本,而不是src /中构建的本地版本.

我会更多地探索这个问题,也许还会再问一些其他问题.

Jon*_*ler 7

由于c++filt -n -s gnu-v3 _ZN5gdata7service7ServiceD1Ev产生名称:

gdata::service::Service::~Service()
Run Code Online (Sandbox Code Playgroud)

你需要仔细研究是否总是定义该类的析构函数,或者是否有某种方式可以保持未定义(或者,确实是否定义).或者是否编译了包含析构函数的源文件(为什么不是Service.cc?).使用代码的某些文件期望为它找到析构函数,即使Service.cc不认为有必要.

另一种可能性是库排序错误 - 也就是说,链接行按ABC的顺序列出库,但它们需要按照BCA或其他排列的顺序排列,并且您要与静态库链接.通常,如果要与静态库链接,则会导致大量未定义的符号(但使用共享库会隐藏排序问题).

@Ephemient给了你一些关于如何找到引用析构函数的目标文件的好指针.您还应确定Service.o(Service.lo.lib/Service.o或其他类似名称)是否包含析构函数 - 在链接错误的情况下,它很可能不包含析构函数.