I am currently trying to create a C++ program in Ubuntu that embeds a shared library. For this I have locally the .so file (in my case: libSimpleAmqpClient.so).
The library itself also calls preinstalled shared libraries (in my case: librabbitmq.so and librabbitmq.so.4).
I use the following CMAKE code:
cmake_minimum_required(VERSION 3.19)
project(AMQPListener)
## Add SimpleAMQP library headers ##
include_directories(/usr/local/SimpleAmqplient)
## Add RabbitMQ library headers ##
include_directories(/usr/local/rabbitmq-c)
# Create program executable
add_executable(AMQPListener main.cpp)
target_link_libraries(AMQPListener /usr/local/lib/librabbitmq.so.4)
target_link_libraries(AMQPListener /usr/local/lib/librabbitmq.so)
target_link_libraries(AMQPListener /usr/local/lib/libSimpleAmqpClient.so)
The main.cpp file looks like this:
#include "SimpleAmqpClient/SimpleAmqpClient.h"
int main() {
AmqpClient::Channel::OpenOpts opts;
opts.port = 5672;
opts.host = "192.0.2.255";
opts.auth = AmqpClient::Channel::OpenOpts::BasicAuth("guest", "guest");
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Open(opts);
return 0;
}
It compiles fine. But during the runtime, I get the following error message:
error while loading shared libraries: librabbitmq.so.4: cannot open shared object file: No such file or directory
But it works fine, if I directly call some functions from the shared library that is called by the actual library I would like to include:
#include "amqp.h"
#include "SimpleAmqpClient/SimpleAmqpClient.h"
int main() {
amqp_connection_state_t conn;
conn = amqp_new_connection();
AmqpClient::Channel::OpenOpts opts;
opts.port = 5672;
opts.host = "192.0.2.255";
opts.auth = AmqpClient::Channel::OpenOpts::BasicAuth("guest", "guest");
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Open(opts);
return 0;
But of course I do not want to do that. So, is there a way I can just use the one shared library and the other needed shared libraries are automatic included?
The shared library files can identify their dependencies on their own during execution, Given that you have linked them during the compilation process
Here's a Link to Read about that. Linking with dynamic library with dependencies
What cmake code below makes sure that compiler ( linker ) finds all the required function definition in the below .so files
target_link_libraries(AMQPListener /usr/local/lib/librabbitmq.so.4)
target_link_libraries(AMQPListener /usr/local/lib/librabbitmq.so)
target_link_libraries(AMQPListener /usr/local/lib/libSimpleAmqpClient.so)
Since, these are not static library files (***.a)
, the library function defintions will not be present inside the executable itself, rather the executable will have an instruction stating that these instructions could be found in .so files.
However during runtime, the OS will look for the required .so files only in the paths set by the LD_LIBRARY_PATH ( unless specified otherwise )
So the given error message error while loading shared libraries: librabbitmq.so.4: cannot open shared object file: No such file or directory
means that during runtime the executable could not find the librabbitmq.so.4
file in the paths which is mentioned by LD_LIBRARY_PATH
Given , your OS is debian based, You can try executing this in the terminal, before running your program
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/
Or follow the methods given here How to set the environmental variable LD_LIBRARY_PATH in linux