C++ 我应该在哪里使用automake/autoconf项目解决符号查找/未定义符号?
在一个项目中,我定义了两个C++ 我应该在哪里使用automake/autoconf项目解决符号查找/未定义符号?,c++,linker,symbols,autoconf,automake,C++,Linker,Symbols,Autoconf,Automake,在一个项目中,我定义了两个noinst\u程序。其中一个很好,但另一个给了我以下信息: /home/altern8/workspace/4355/libgdata/test/.libs/lt-gdatacalendar: 符号查找错误: /home/altern8/workspace/4355/libgdata/test/.libs/lt-gdatacalendar: 未定义的符号: _ZN5gdata7service7ServiceD1Ev 我一直在查看Makefile.am文件,但没有找到任
noinst\u程序。其中一个很好,但另一个给了我以下信息:
/home/altern8/workspace/4355/libgdata/test/.libs/lt-gdatacalendar:
符号查找错误:
/home/altern8/workspace/4355/libgdata/test/.libs/lt-gdatacalendar:
未定义的符号:
_ZN5gdata7service7ServiceD1Ev
我一直在查看Makefile.am文件,但没有找到任何遗漏的内容。应用程序编译正确,因此我猜这意味着头文件找到正确,但由于某种原因,src/libgdata.la库中没有包含mygdata::service::service
我的假设可能是正确的吗?src/libgdata.la库中定义的其他类似乎是可用的。“make”的输出显示Service.cc文件正在正确编译。。。我应该在哪里寻找,以确保它被包括在最终的库中
编辑:
根据目前为止提供的答案,我已经能够进一步调试它
析构函数在Service.cc中定义。如果我在头文件中给析构函数一个body,那么一切都正常
// 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
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
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
我的src/gdata/service/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
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
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
我的test/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
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
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
YouTube运行得很好。旧代码使用客户端目录中的代码而不是服务(gdata/client/libgdata_gdata_client.la)。。。我看不出客户端与服务的设置方式有任何区别:-/
**编辑#2:##
我不知道这是怎么发生的,但我想我发现了我的问题。我认为测试应用程序链接的是我正在使用的库的安装版本,而不是本地版本内置的src/
我将进一步探讨这个问题,也许下次再问一些其他问题。(已经有一个名为的现有项目,但可能与此无关。)
这是一种蛮力方式,可以发现libgdata.la
和gdatacalendar
中包含的内容。(但从相应的Makefile.am
中的(libgdata|la | gdatacalendar)(SOURCES | LIBADD)
可以看出这一点)
这里是否存在不匹配?因为c++filt-n-s gnu-v3\u ZN5gdata7service7ServiceD1Ev
生成了以下名称:
gdata::service::Service::~Service()
您需要仔细查看该类的析构函数是否总是定义的,或者是否有某种方法可以不定义它(或者,实际上,是否曾经定义过它)。或者是否编译了包含析构函数的源文件(为什么不是Service.cc
?)。某些使用代码的文件希望为其找到析构函数,即使Service.cc
认为不需要析构函数
另一种可能是库排序错误-也就是说,链接行按ABC顺序列出库,但它们必须按BC顺序或其他排列,并且您正在链接静态库。通常,如果使用静态库链接,会导致大量未定义的符号(但使用共享库会隐藏排序问题)
@Ephemient为您提供了一些关于如何查找引用析构函数的对象文件的好指针。您还应该确定是否<代码>服务.O.<代码>(<代码>服务> Loo/Service .Ob/Service .O./Cu>或其他类似名称)包含析构函数-它很可能不包含析构函数,因为链接错误。 + 1非常棒,我永远记不记得如何去解那些该死的C++符号……Beau:如果您有库排序问题,库会为命令行中在它们前面列出的对象和库提供符号(除非-Wl,--startgroup-Wl,--endgroup
正在使用中)。析构函数是在Service.cc文件中定义的,但我尝试将其移动到标头以查看效果。通过将其移动到标头,我已经确认了至少标头正在工作,而且问题似乎确实是Service.o对象由于某种原因没有进入libgdata。谢谢你的想法,因为我认为它帮助我缩小了问题的范围。我用更多的细节更新了我的问题。谢谢你的指点!我已经更新了我的问题的更多细节。:)尝试将libgdata\u gdata\u service.la
移动到libgdata\u gdata\u service\u calendar.la
中的libgdata\u la\u LIBADD
之后,以查看是否如乔纳森所怀疑的那样是由于图书馆订购引起的。