I am creating a C++ application with a Makefile in VScode and Ubuntu that uses the mosquitto MQTT protocol.
I cloned the official repo under the /usr/src/
directory and I am trying to link my makefile with the necessary shared object files using variables.
CXX := g++
CXXFLAGS := -Wall -Wextra -pedantic
INCLUDES += -I/usr/src/mosquitto/lib/cpp
INCLUDES += -I/usr/src/mosquitto/include
LIBS += -L/usr/src/mosquitto/lib/cpp -l:libmosquittopp.so.1
LIBS += -L/usr/src/mosquitto/lib -l:libmosquitto.so.1
BIN = bin
all: main.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -o $(BIN)/main $< $(LIBS)
run:
@./bin/*
clean:`
rm -rf ./bin/*
The project structure consists of a single directory with a makefile and a main.cpp
file, in addition to a bin
folder to store the executable.
├── bin
├── main.cpp
├── makefile
So far, main.cpp
‘s only external dependency is on the mosquittopp
header file.
#include <iostream>
#include <mosquittopp.h>
int main() {
int mid_val {235};
int* mid = &mid_val;
const char* device_name {"mqtt_c8y_1234abc"};
const char* username {};
const char* password {[password]};
const char* host {"[domain].cumulocity.com"};
const int port {1883};
mosqpp::lib_init();
mosqpp::mosquittopp mosq_client {device_name, true};
int auth_status { mosq_client.username_pw_set(username, password)};
if(auth_status == MOSQ_ERR_SUCCESS){
std::cout << "User authentication success!n";
}
return 0;
}
I am able to run the build
target without a problem, but when I try to execute the run
target I get the following error:
./bin/main: error while loading shared libraries: libmosquittopp.so.1: cannot open shared object file: No such file or directory
make: *** [makefile:15: run] Error 127
This occurs even though I can verify the correct location of the libraries and their names in my file system [emphasis added]:
/usr/src/mosquitto/lib$ tree
.
.
.
├── connect.c
├── connect.o
├── cpp
│ ├── CMakeLists.txt
│ ├── **libmosquittopp.so.1**
│ ├── Makefile
│ ├── mosquittopp.cpp
│ ├── mosquittopp.h
│ └── mosquittopp.o
├── dummypthread.h
├── handle_auth.c
.
.
.
├── helpers.c
├── helpers.o
├── **libmosquitto.so.1**
├── linker.version
Please note: I have already tried giving the shorthand name of the library files by listing them as -lmosquittopp
and -lmosquitto
, but then the makefile could not locate them when trying to run all
.
2
Answers
Update: I followed the advice posted on the reply to my question, but this time I set the names of the actual shared library files to their full name using the prefix colon
:
and the suffix.so.1
, and it worked!Here is the full code for the
LIBS
variable:For dynamic libraries linking is done in two steps:
First the static linking done at build-time. For libraries installed in non-standard location you use the
-L
option to tell the linker where the libraries are located, as in-L/path/to/library/directory
.Then there’s the runtime linking, done by the operating system when it loads and runs your program. It also needs to know the location for the libraries, and if they are not in a standard location they will not be found and you will get an error when attempting to run the application. When using the
g++
driver program you need to add the option-Wl,-rpath,/path/to/library/directory
.Please note that these options are passed the directory where the libraries are located, and not the libraries themselves.
The error you get is from the second OS-level linking.
On another note, when linking with libraries that are in a standard location, or whose directory is added with
-L
, you don’t need to supply the full filename, only the library name without thelib
prefix or the.so
suffix.So instead of linking with
libmosquitto.so.1
, link withmosquitto
.Putting it all together, change your
LIBS
variables as this: