autotools项目中未定义的引用

时间:2014-08-14 20:38:03

标签: linux gcc makefile shared-libraries autotools

这是我正在开发的项目:https://github.com/bigdatadev/riemannpp

我是autotools的初学者,我很难让我的共享对象riemannpp链接到另一个名为riemann-client的库(README.md中的链接)。

我在configure.ac(ln.38)中使用PKG_CHECK_MODULES找到了riemann-client的编译/链接标志。然后,当我使用LIBADD(ln.29)构建.so时,我使用Makefile.am中的标志。

如果您尝试编译源代码(make),libriemannpp.so将构建,但是当我尝试链接客户端和单元测试时,我似乎做了一些非常错误的事情。我通过引用libriemannpp.la(Makefile.am ln.41)添加对libriemannpp.so的引用。

我得到的错误是对riemann-client依赖的riemann-client库函数的未定义引用。 nm显示riemannpp.so具有未定义的引用,但ldd显示不依赖于riemann-client,nm显示确实输出了缺失的符号。我试图摆弄Makefile.am以使riemannpp库正确链接,但我正在放弃并希望专家能够帮助我。

如果有人能帮助我理解我做错了什么以及如何解决它,我将非常感激。

我正在使用Ubuntu 14.04和gcc,autoconf,automake和libtool的默认系统包。


编辑:更多信息

libriemannpp.so上的ldd输出:

  • linux-vdso.so.1 => (0x00007fff36b29000)
  • libstdc ++。so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6(0x00007f9b13f54000)
  • libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6(0x00007f9b13b8e000)
  • libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1(0x00007f9b13977000)
  • libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6(0x00007f9b13671000)
  • /lib64/ld-linux-x86-64.so.2(0x00007f9b14488000)
libriemannpp.so上的

nm输出:

  • U _Z17riemann_event_newv
  • U _Z17riemann_event_setP6_Eventz
  • U _Z17riemann_query_newPKc
  • U _Z18riemann_client_newv
  • U _Z18riemann_event_freeP6_Event
  • U _Z18riemann_query_freeP6_Query
  • ......等......
libriemann-client.so上的

nm输出:

  • 0000000000002c70 T riemann_event_attribute_add
  • 0000000000002cd0 T riemann_event_create
  • 0000000000002610 T riemann_event_free
  • 00000000000025f0 T riemann_event_new
  • ......等......

所以似乎符号在libriemann-client.so中正确定义。至少我不会完全疯了......

违规构建输出:

/bin/bash ./libtool  --tag=CXX   --mode=link g++  -g -O2 -std=c++11   -o src/client/riemannpp src/client/riemannpp.o ./src/riemannpp/libriemannpp.la -L/usr/local/lib -lriemann-client    
libtool: link: g++ -g -O2 -std=c++11 -o src/client/.libs/riemannpp src/client/riemannpp.o  ./src/riemannpp/.libs/libriemannpp.so -L/usr/local/lib /usr/local/lib/libriemann-client.so
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_client_send_message(_riemann_client_t*, _Msg*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_query_set_string(_Query*, char const*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_client_send_message_oneshot(_riemann_client_t*, _Msg*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_client_disconnect(_riemann_client_t*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_attribute_set(_Attribute*, char const*, char const*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_client_new()'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_attribute_free(_Attribute*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_event_new()'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_client_free(_riemann_client_t*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_query_new(char const*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_attribute_create(char const*, char const*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_message_set_query(_Msg*, _Query*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_event_set(_Event*, ...)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_query_free(_Query*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_event_attribute_add(_Event*, _Attribute*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_attribute_set_value(_Attribute*, char const*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_attribute_new()'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_message_new()'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_client_connect(_riemann_client_t*, riemann_client_type_t, char const*, int)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_event_tag_add(_Event*, char const*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_message_free(_Msg*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_attribute_set_key(_Attribute*, char const*)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_message_set_events_n(_Msg*, unsigned long, _Event**)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_client_create(riemann_client_type_t, char const*, int)'
./src/riemannpp/.libs/libriemannpp.so: undefined reference to `riemann_event_free(_Event*)'

试用它的步骤:

$ git clone git@github.com:algernon/riemann-c-client.git
$ cd riemann-c-client
$ sudo apt-get install protobuf-c-compiler # ubuntu
$ ./configure && make && sudo make install
$ cd ..
$ git clone git@github.com:bigdatadev/riemannpp.git
$ cd riemannpp
$ ./autogen.sh
$ ./configure && make

请注意,在编译客户端程序时,libriemannpp.so中将包含未解析的符号引用,尽管libriemannpp引用了riemann-c-client(通过pkg-config riemann-client --cflags --libs获得)。


编辑:即使我运行./configure --disable-shared,我也会遇到同样的问题,这似乎排除了我正在构建的共享对象中任何错误的可能性。我显然不知道如何将依赖信息添加到库中,但谷歌没有给出任何答案。

这似乎不太可能是riemann-client库中的错误,因为它可以完美地构建并通过其单元测试。

1 个答案:

答案 0 :(得分:1)

riemann-client无法使用

#ifdef __cplusplus
extern "C" {
#endif
   ...
#ifdef __cplusplus
}
#endif

在其头文件中,因此你的riemanpp代码部分认为它在调用C ++代码时实际上它是C. 你不能只使用

#ifdef __cplusplus
extern "C" {
#endif
#include <riemann/event.h>
...

因为这可能会使C ++标头被错误地包装到C调用约定中。 (意味着修复必须在riemann-client中发生)