c++ - 我应该在哪里使用 automake/autoconf 项目解决符号查找/ undefined symbol ?

标签 c++ linker symbols autoconf automake

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

/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/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

我的测试/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

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

**编辑 #2:##

嗯,我不知道这是怎么发生的,但我想我找到了我的问题。我认为测试应用程序链接的是我正在处理的库的安装版本,而不是 src/中内置的本地版本。

我会进一步探讨这个问题,也许下次再问一些其他问题。

最佳答案

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

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

您需要仔细查看该类的析构函数是否始终被定义,或者是否可以通过某种方式将其保留为未定义(或者,实际上,它是否曾经被定义)。或者包含析构函数的源文件(为什么不是Service.cc?)是否被编译。某些使用该代码的文件希望为其找到析构函数,即使 Service.cc 认为没有必要。

另一种可能性是库排序错误 - 也就是说,链接行以 A B C 的顺序列出了库,但它们需要按 B C A 的顺序或其他一些排列,并且您正在链接静态库。通常,如果您链​​接静态库(但使用共享库会隐藏排序问题),这会导致大量 undefined symbol 。

@Ephemient 为您提供了一些关于如何找到引用析构函数的对象文件的很好的指导。您还应该确定 Service.o(Service.lo.lib/Service.o 或其他类似名称)是否包含析构函数 - 鉴于链接错误,它很可能不包含析构函数。

关于c++ - 我应该在哪里使用 automake/autoconf 项目解决符号查找/ undefined symbol ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1156792/

相关文章:

c++ - elf 文件中的 ".debug_info"部分是什么?

c++ - 如何检查多个变量是否等于相同的值?

c++ - 如果在同一翻译单元中调用函数,为什么需要重定位

delphi - 为什么每次构建都会更改 exe 文件?

c++ - 在哪一行调用了复制构造函数?

c - C 中的包含和链接

mysql - At-在列名之前登录 SQL 语句

function - 如何从Clojure中的符号获取函数名称?

c++ - 程序将奇怪的符号打印到输出文件 C++

c++ - fatal error C1001 : internal error trying to use templates