Build against rabbitmq-c

2020-07-10 03:13发布

I am trying to connect to rabbitmq in c and it is failing every single time. Here is how I did it.

Downloaded rabbitmq-c
Installed it (make && make install) just to make sure dependencies are satisfied.
Modified connection variables in amqp_sendstring.c
Rebuilt using make, ran ./amqp_sendstring and it worked
Then I started creating my own files and compiling them through gcc using:

gcc -lrabbitmq -o j_test test.c

Ironically it fails to link against librabbitmq with the errors below:

/tmp/cc63IlXq.o: In function `main':
test.c:(.text+0xa): undefined reference to `amqp_new_connection'
test.c:(.text+0x1a): undefined reference to `amqp_destroy_connection'
collect2: ld returned 1 exit status

I removed everything starting with ampq_*. Voila! It was successfully built. That's to me an indicator that gcc is able to find the headers but not the lib.

Here is test.c source code:

#include <amqp.h>
#include <amqp_framing.h>
int main(int argc, char const * const *argv) {
   amqp_connection_state_t conn;
   conn = amqp_new_connection();
   amqp_destroy_connection(conn);
   return 0;
}

Would someone please point me to the right direction?

Edit: I forgot to mention that I am on an ubuntu box (12.04). Think it is implicitly implied in the statements above though.

标签: c rabbitmq
1条回答
【Aperson】
2楼-- · 2020-07-10 04:04

When you compile your program you have to tell to gcc not only the name of the library you are going to use (-lrabbimtq), but also the path (i.e. the directory) where the library should be searched from (-L/path/to/rabbitmq-c) during linking. gcc (or the linker) will always look for some default directories, but your rabbitmq-c library is not available in those directories.

So your gcc command-line should look like:

gcc -I/path/to/rabbitmq-c-header-dir -L/path/to/rabbitmq-c-lib-dir -o j_test test.c -lrabbitmq

Note that you have to tell the location of header files (-I) and that the position of -lrabbitmq is important.

In the example below directory ~/src/rabbitmq-c is the location of my clone of rabbitmq-c.

Locations of the headers and the shared library:

~/src/rabbitmq-c$ find . -name amqp.h
./librabbitmq/amqp.h
~/src/rabbitmq-c$ find . -name librabbitmq.so
./librabbitmq/.libs/librabbitmq.so
~/src/rabbitmq-c$

Compiling and linking your example program:

~/src/rabbitmq-c$ cat > stacko.c
#include <amqp.h>
#include <amqp_framing.h>
int main(int argc, char const * const *argv) {
   amqp_connection_state_t conn;
   conn = amqp_new_connection();
   amqp_destroy_connection(conn);
   return 0;
}
~/src/rabbitmq-c$ gcc -Ilibrabbitmq -g -Wall -c stacko.c
~/src/rabbitmq-c$ gcc -Llibrabbitmq/.libs -g -Wall -o stacko stacko.o -lrabbitmq
~/src/rabbitmq-c$

With shared libraries one have to tell also during runtime where the libraries will be found:

~/src/rabbitmq-c$ ./stacko 
./stacko: error while loading shared libraries: librabbitmq.so.0: cannot open shared object file: No such file or directory
~/src/rabbitmq-c$ LD_LIBRARY_PATH=librabbitmq/.libs ./stacko 
~/src/rabbitmq-c$

You can check what libraries an executable uses with ldd:

~/src/rabbitmq-c$ ldd ./stacko 
    linux-gate.so.1 =>  (0x00d7d000)
    librabbitmq.so.0 => not found
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00396000)
    /lib/ld-linux.so.2 (0x002d6000)
~/src/rabbitmq-c$ LD_LIBRARY_PATH=librabbitmq/.libs ldd ./stacko 
    linux-gate.so.1 =>  (0x001c8000)
    librabbitmq.so.0 => librabbitmq/.libs/librabbitmq.so.0 (0x00f77000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x001c9000)
    /lib/ld-linux.so.2 (0x00cc3000)
~/src/rabbitmq-c$

See also g++: how to specify preference of library path?.

查看更多
登录 后发表回答