Undefined references in autotools project - linux

Here's the project I'm developing: https://github.com/bigdatadev/riemannpp
I'm a relative beginner to autotools, and I'm having difficulty getting my shared object riemannpp to link against another library called riemann-client (link in the README.md).
I find the compile / link flags for riemann-client using PKG_CHECK_MODULES in configure.ac (ln. 38). I then use the flags in Makefile.am when I build the .so using LIBADD (ln. 29).
If you try to compile the sources (make), libriemannpp.so will build, but seems that I am doing something very wrong when I try to link the client and unit tests. I add the reference to libriemannpp.so by referencing libriemannpp.la (Makefile.am ln. 41).
The error I'm getting is undefined references to functions from the riemann-client library which riemannpp.so depends. nm shows that riemannpp.so has undefined references, but ldd shows no dependency on riemann-client, which nm shows does exports the missing symbols. I have tried fiddling with the Makefile.am to get the riemannpp library to link properly, but I'm giving in and am hoping an expert will be able to help me out.
If anyone can help me understand what I'm doing wrong and how to fix it I would be very grateful.
I'm using Ubuntu 14.04 with default system packages for gcc, autoconf, automake and libtool.
EDIT: Some more information
ldd output on libriemannpp.so:
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)
nm output on libriemannpp.so:
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
... etc ...
nm output on libriemann-client.so:
0000000000002c70 T riemann_event_attribute_add
0000000000002cd0 T riemann_event_create
0000000000002610 T riemann_event_free
00000000000025f0 T riemann_event_new
... etc ...
So it seems that the symbols are correctly defined in libriemann-client.so. At least I'm not going completely insane...
The offending build output:
/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*)'
Steps to try it out:
$ 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
Note that you will have unresolved symbol references in libriemannpp.so when compiling the client program, despite libriemannpp having references to the riemann-c-client (obtained via pkg-config riemann-client --cflags --libs).
EDIT: I get the same problem even if I run ./configure --disable-shared, which seems to rule out any possibility of a bug in the shared object I'm building. I'm clearly missing how to add the dependency information to the library, but Google isn't giving any answers away.
It seems very unlikely that this is a bug in the riemann-client library, as that builds and passes its unit tests flawlessly.

riemann-client fails to use
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
in its header files, therefore your riemanpp code parts think it is calling C++ code when in fact it is C.
And you cannot just use
#ifdef __cplusplus
extern "C" {
#endif
#include <riemann/event.h>
...
as that could possibly subject C++ headers to be wrongly wrapped into C calling conventions. (Meaning the fix must occur in riemann-client)

Related

Errors while statically compiling poco with ssl in gcc

I have all the .a files in usr/local/lib. Moreover I've deleted all the .so libraries from the folder to ensure that it compiles statically. I'm using this command to compile it-
g++ HttpAPICall.cpp ... main.cpp -Bstatic -L/usr/local/lib/ -lPocoUtil -lPocoXML -lcrypto -lssl \
-lPocoCrypto -lgumbo -lPocoNet -lPocoJSON -lPocoNetSSL -lPocoFoundation -luuid -std=gnu++11 -o analyzer
I'm getting the following error-
/usr/local/lib//libPocoNetSSL.a(SSLManager.o): In function `Poco::Net::SSLManager::appConfig()':
SSLManager.cpp:(.text+0x383): undefined reference to `Poco::Util::Application::_pInstance'
SSLManager.cpp:(.text+0x3b5): undefined reference to `Poco::Util::Application::_pInstance'
/usr/local/lib//libPocoNetSSL.a(SSLManager.o): In function `Poco::Net::SSLManager::initPassphraseHandler(bool)':
SSLManager.cpp:(.text+0xd58): undefined reference to `Poco::Util::AbstractConfiguration::getString(std::string const&, std::string const&) const'
SSLManager.cpp:(.text+0xdd6): undefined reference to `Poco::Util::UnknownOptionException::UnknownOptionException(std::string const&, int)'
SSLManager.cpp:(.text+0xe01): undefined reference to `Poco::Util::UnknownOptionException::~UnknownOptionException()'
SSLManager.cpp:(.text+0xe06): undefined reference to `typeinfo for Poco::Util::UnknownOptionException'
/usr/local/lib//libPocoNetSSL.a(SSLManager.o): In function `Poco::Net::SSLManager::initCertificateHandler(bool)':
SSLManager.cpp:(.text+0x15a8): undefined reference to `Poco::Util::AbstractConfiguration::getString(std::string const&, std::string const&) const'
I've read that the order or compilation matters in such case. I've tried -WL,--start-group --end-group as well. No luck with that. The same code using mac static libraries is getting compiled easily on xcode. Also, by using the dynamic libraries, the code compiles fine on linux as well. Kindly help me with static compiling on linux.

Linking with libbluetooth.so

On Ubuntu 14.04, I'm trying to do a small example of bluetooth device listing but I'm facing a simple issue about linking with the bluetooth shared library when compiling this minimalistic demo http://people.csail.mit.edu/albert/bluez-intro/c404.html:
$ sudo apt-get install libbluetooth-dev
$ gcc -lbluetooth simplescan.c -o simplescan
/tmp/ccuwRsB5.o: In function `main':
simplescan.c:(.text+0x79): undefined reference to `hci_get_route'
simplescan.c:(.text+0x8c): undefined reference to `hci_open_dev'
simplescan.c:(.text+0x132): undefined reference to `hci_inquiry'
simplescan.c:(.text+0x18f): undefined reference to `ba2str'
simplescan.c:(.text+0x1f0): undefined reference to `hci_read_remote_name'
collect2: error: ld returned 1 exit status
$ nm -D /usr/lib/x86_64-linux-gnu/libbluetooth.so.3.13.0 | grep hci_get_route
0000000000008f00 T hci_get_route
The bluetooth shared library seems to be found and containing the required functions, but the linking phase doesn't achieve.
The solution is astonished (to me): the order of the arguments given to gcc is important. "-lbluetooth" should be put after "simplescan.c":
$ gcc simplescan.c -lbluetooth -o simplescan # Success
$ gcc -lbluetooth simplescan.c -o simplescan # Failure
/tmp/ccWhZFXs.o: In function `main':
simplescan.c:(.text+0x79): undefined reference to `hci_get_route'
simplescan.c:(.text+0x8c): undefined reference to `hci_open_dev'
simplescan.c:(.text+0x132): undefined reference to `hci_inquiry'
simplescan.c:(.text+0x18f): undefined reference to `ba2str'
simplescan.c:(.text+0x1f0): undefined reference to `hci_read_remote_name'
collect2: error: ld returned 1 exit status

Undefine reference for libraries, so How could I find the right path?

I am trying to compile a v4l2 example in Ubuntu but I am getting the following error:
guilherme#notedev01:~/Downloads/V4l2_samples-0.4.1$ make
gcc -O2 -L/usr/include -lX11 -lXext -o viewer viewer.c
/tmp/ccUjnjWQ.o: In function `image_destroy':
viewer.c:(.text+0x234): undefined reference to `XDestroyImage'
viewer.c:(.text+0x256): undefined reference to `XFreeGC'
viewer.c:(.text+0x277): undefined reference to `XShmDetach'
viewer.c:(.text+0x2ac): undefined reference to `XFreePixmap'
/tmp/ccUjnjWQ.o: In function `image_create':
viewer.c:(.text+0x305): undefined reference to `XCreateGC'
viewer.c:(.text+0x31d): undefined reference to `XGetWindowAttributes'
viewer.c:(.text+0x39e): undefined reference to `XShmCreateImage'
viewer.c:(.text+0x3f5): undefined reference to `XShmAttach'
viewer.c:(.text+0x44e): undefined reference to `XCreateImage'
viewer.c:(.text+0x494): undefined reference to `XShmQueryExtension'
viewer.c:(.text+0x4b4): undefined reference to `XShmPixmapFormat'
viewer.c:(.text+0x4dc): undefined reference to `XShmCreatePixmap'
/tmp/ccUjnjWQ.o: In function `image_put':
viewer.c:(.text+0x54c): undefined reference to `XPutImage'
viewer.c:(.text+0x586): undefined reference to `XShmPutImage'
/tmp/ccUjnjWQ.o: In function `main':
viewer.c:(.text.startup+0x18b): undefined reference to `XOpenDisplay'
viewer.c:(.text.startup+0x1b1): undefined reference to `XScreenOfDisplay'
viewer.c:(.text.startup+0x1ee): undefined reference to `XCreateSimpleWindow'
viewer.c:(.text.startup+0x249): undefined reference to `XMapRaised'
viewer.c:(.text.startup+0x263): undefined reference to `XStoreName'
viewer.c:(.text.startup+0x280): undefined reference to `XGetWindowAttributes'
viewer.c:(.text.startup+0x92f): undefined reference to `XPending'
viewer.c:(.text.startup+0x94c): undefined reference to `XNextEvent'
viewer.c:(.text.startup+0xaee): undefined reference to `XPending'
viewer.c:(.text.startup+0xb0b): undefined reference to `XNextEvent'
viewer.c:(.text.startup+0xf39): undefined reference to `XPending'
viewer.c:(.text.startup+0xf56): undefined reference to `XNextEvent'
collect2: error: ld returned 1 exit status
make: *** [viewer] Error 1
What I can see is that the path for -lx11 and -lXext isn't -L/usr/include.
How can I find the right path for those libraries?
Thanks.
as Chris has pointed out, the order is wrong, you need to put the -lX11 -lXext after the source-code/object-files.
this is because modern compilers try to optimize the final result and not link against unused libraries.
they do so by maintaining a list of unresolved symbols within an object and use any binary files that come aferwards in the linker arguments to resolve those symbols.
example
your program test uses the function do_foo() from libfoo and the function do_bar_do() from libbar.
you link it using:
$ gcc -o test test.o -lfoo -lbar
the linker first searches test.o and notices that some symbols (do_foo and do_bar_do) are not defined anywhere. it then proceeds to libfoo (specified right after test.o) and finds that it provides do_foo, so it creates code to use it from your program. do_bar_do is still unresolved, until the linker checks upon libbar.
consider doing it the wrong way:
$ gcc -o test -lfoo test.o -lbar
the linker will first check libfoo and see that it doesn't contain any unresolved symbols. cool. it will then proceed to test.o and notice do_bar_do and do_foo. do_bar_do is resolved by the right-hand libbar but do_foo is not resolved at all, and you get an error:
undefined reference to `do_foo'
"but the code is meant to be a tutorial..."
so why is it not working?
older compilers where a bit lax about the order of dependencies (they would check all binaries/libraries/objects whether a given symbol could be resolved); that's why you can still find code out there that puts the libraries to link against before the object files.
The -lX11 -lXext must come after the viewer.c in the command line (and should probably be in the order -lXext -lX11). Also, ensure that the libx11-6-dev and libxext6-dev packages are installed.
System libraries are usually in /lib and /usr/lib, and you do not need to use -L to specify those directories.

pwntcha build error in Cygwin: undefined reference to imlib_load_image

I'm trying to build pwntcha on windows using Cygwin with imlib2. At the "make" step I get the error message:
/home/username/pwntcha/src/image.c:37: undefined reference to imlib_load_image.
Can anyone help me to solve it?
For more detailed:
gcc `imlib2-config --cflags` -DX_DISPLAY_MISSING=1 -Wall -O6 -g -O2 `imlib2-config --libs` -o pwntcha.exe pwntcha-main.o pwntcha-filter.o pwntcha-font.o pwntcha-image.o pwntcha-easter-eggs.o pwntcha-test.o authimage/libdecoder.a clubic/libdecoder.a java/libdecoder.a linuxfr/libdecoder.a livejournal/libdecoder.a lmt/libdecoder.a paypal/libdecoder.a phpbb/libdecoder.a scode/libdecoder.a slashdot/libdecoder.a ticketmaster/libdecoder.a tickets/libdecoder.a vbulletin/libdecoder.a xanga/libdecoder.a
pwntcha-image.o: In function `image_load':
/home/username/pwntcha/src/image.c:37: undefined reference to "imlib_load_image"
/home/username/pwntcha/src/image.c:63: undefined reference to "imlib_context_set_image"
/home/username/pwntcha/src/image.c:64: undefined reference to "imlib_image_get_width"
/home/username/pwntcha/src/image.c:65: undefined reference to "imlib_image_get_height"
/home/username/pwntcha/src/image.c:66: undefined reference to "imlib_image_get_width"
/home/username/pwntcha/src/image.c:68: undefined reference to "imlib_image_get_data"
Thank in advance.
gcc resolves symbols in the order listed. You need to patch the build system to move `imlib2-config --libs` to the very end of the link command.

undefined reference to `jack_client_close`, et al

I'm trying to follow this introductory tutorial on jack (audio server for linux). In the tutorial, the author explains that you should use pkg-config to find the cflags and libs for jack, making the gcc command like this:
gcc -o simple_client `pkg-config --cflags --libs jack` simple_client.c
which gives the output:
/tmp/ccyuOC0u.o: In function `signal_handler':
simple_client.c:(.text+0x16): undefined reference to `jack_client_close'
/tmp/ccyuOC0u.o: In function `process':
simple_client.c:(.text+0x6f): undefined reference to `jack_port_get_buffer'
simple_client.c:(.text+0x87): undefined reference to `jack_port_get_buffer'
/tmp/ccyuOC0u.o: In function `main':
simple_client.c:(.text+0x25b): undefined reference to `sin'
simple_client.c:(.text+0x2c1): undefined reference to `jack_client_open'
simple_client.c:(.text+0x372): undefined reference to `jack_get_client_name'
simple_client.c:(.text+0x3b1): undefined reference to `jack_set_process_callback'
simple_client.c:(.text+0x3ca): undefined reference to `jack_on_shutdown'
simple_client.c:(.text+0x3ee): undefined reference to `jack_port_register'
simple_client.c:(.text+0x419): undefined reference to `jack_port_register'
simple_client.c:(.text+0x475): undefined reference to `jack_activate'
simple_client.c:(.text+0x4c5): undefined reference to `jack_get_ports'
simple_client.c:(.text+0x514): undefined reference to `jack_port_name'
simple_client.c:(.text+0x52c): undefined reference to `jack_connect'
simple_client.c:(.text+0x56e): undefined reference to `jack_port_name'
simple_client.c:(.text+0x586): undefined reference to `jack_connect'
simple_client.c:(.text+0x5ba): undefined reference to `jack_free'
collect2: ld returned 1 exit status
I'm not very experienced using gcc or writing c programs generally (most of my experience has been with javascript, clojure, java, python, and php). What I gather from this and my research into it is that some libraries are missing or linked incorrectly (not sure which).
So just running pkg-config --cflags --libs jack on my machine, I get:
-ljack
In the tutorial referenced above, the author demonstrates the same method for gleaning the libs to be linked for jack, but his output looks like this:
-ljack -lpthread -ldl -lrt
Not sure what pthread is, but I think dl is dsp-loader, and rt has something to do with realtime. I've searched in several directories called /lib and haven't come across anything for these other libs, so I don't think they exist on my machine. However, it seems strange to me that calling pkg-config doesn't make any mention of them. How should I go about finding these libs? Or am I on the wrong track?
Your link command line is wrong, try this one instead:
gcc -o simple_client simple_client.c `pkg-config --cflags --libs jack`
The order of archive libraries on command line matters.

Resources