Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build against rabbitmq-c

Tags:

c

rabbitmq

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.

like image 453
Jermin Bazazian Avatar asked Aug 19 '12 16:08

Jermin Bazazian


People also ask

Does RabbitMQ use WebSockets?

RabbitMQ Web MQTT plugin is rather simple. It takes the MQTT protocol, as provided by RabbitMQ MQTT plugin and exposes it using WebSockets.

Is RabbitMQ written in Erlang?

Written in Erlang, the RabbitMQ server is built on the Open Telecom Platform framework for clustering and failover. Client libraries to interface with the broker are available for all major programming languages. The source code is released under the Mozilla Public License.

Does RabbitMQ use UDP?

RabbitMQ "UDP Exchange" Plugin. Extends RabbitMQ Server with support for a new experimental exchange type, x-udp . Each created x-udp exchange listens on a specified UDP port for incoming messages, and relays them on to the queues bound to the exchange.

Is RabbitMQ a library?

The . NET RabbitMQ client library is hosted and developed on GitHub. Please see the . NET client build guide for instructions on compiling from source.


1 Answers

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?.

like image 132
user272735 Avatar answered Nov 15 '22 17:11

user272735