这是我正在开发的项目: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输出:
nm输出:
nm输出:
所以似乎符号在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库中的错误,因为它可以完美地构建并通过其单元测试。
答案 0 :(得分:1)
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
在其头文件中,因此你的riemanpp代码部分认为它在调用C ++代码时实际上它是C. 你不能只使用
#ifdef __cplusplus
extern "C" {
#endif
#include <riemann/event.h>
...
因为这可能会使C ++标头被错误地包装到C调用约定中。 (意味着修复必须在riemann-client中发生)