Search code examples
c++linuxmakefile.so

Makefile cannot find .so files when running executable


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 {[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.


Solution

  • 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:

    LIBS += -L/usr/src/mosquitto/lib/cpp -l:libmosquittopp.so.1 -Wl,-rpath,/usr/src/mosquitto/lib/cpp
    LIBS += -L/usr/src/mosquitto/lib -l:libmosquitto.so.1 -Wl,-rpath,/usr/src/mosquitto/lib