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

发布于 2024-07-29 04:37:53 字数 3384 浏览 5 评论 0原文

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

/home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar: 符号查找错误: /home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar: 未定义的符号: _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

我的 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

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

**编辑 #2:##

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆梦 2024-08-05 04:37:53

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

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

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

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

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

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.

走走停停 2024-08-05 04:37:53

(已经有一个名为 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

这是一个相当粗暴的项目-force 方法来发现符号 _ZN5gdata7service7ServiceD1Ev 定义在哪些对象(如果有)中。(仅找到定义 gdata::service::Service 的源文件可能会更容易>,如果模板没有发挥作用。)

$ rm libgdata.la gdatacalendar
$ make

这是一种发现 libgdata.lagdatacalendar 中包含内容的强力方法。 (但是,通过查看相应 Makefile.am 中的 (libgdata_la|gdatacalendar)_(SOURCES|LIBADD) 应该会非常明显。)

这里是否存在不匹配?

(There's an existing project by the name libgdata already, but that's probably not relevant.)

$ 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

That's a rather brute-force way to discover which objects (if any) the symbol _ZN5gdata7service7ServiceD1Ev is defined in. (It may be easier just to find the source file defining gdata::service::Service, if templates aren't in play.)

$ rm libgdata.la gdatacalendar
$ make

This is a brute-force way to discover what is getting included in libgdata.la and gdatacalendar. (But it should be pretty obvious from looking at (libgdata_la|gdatacalendar)_(SOURCES|LIBADD) in the appropriate Makefile.am.)

Is there a mismatch here?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文