c++cmakeqpid-proton

Linking to local qpid-proton-cpp installation


I would like to use a library to communicate using AMQP 1.0 in C++.

Qpid-proton (Github-mirror) seems like the way to go, and when following their regular installation, there are no issues linking it to my project.

I would however like to avoid the regular installation of the library, as it is installed globally on the machine. And instead opt for a local installation that my project may link to. This also seems easy enough to do, as one may set the CMAKE_INSTALL_PREFIX variable when generating cmake files, and setting the ProtonCpp_DIR variable in my projects own cmakelists file.

My project does not seem to link to the original Proton library, as it cannot find the core library file nor the proactor library file. Using ldd on the resulting executable reveals

libqpid-proton-proactor.so.1 => not found
libqpid-proton-core.so.10 => not found

Linking the proton project in my cmake does not seem to change anything either.

So I need to ask, what am I missing here? I feel that this should work?

Here I provide my projects current cmakeLists file

cmake_minimum_required(VERSION 3.16)

project(proton_test C CXX)
set(ProtonCpp_DIR "local_install/lib/cmake/ProtonCpp")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(ProtonCpp REQUIRED)

add_executable(main main.cpp)

# Link the Qpid Proton C++ library
target_link_libraries(main PRIVATE Proton::cpp)

For any further details on this setup, I have prepared a repo with instructions that results in the build with failed linking.


Solution

  • Your local install of libqpid-proton-cpp doesn't have an "rpath" set. If you run ldd on it you'll get:

    $ ldd local_install/lib/libqpid-proton-cpp.so
        linux-vdso.so.1 (0x00007fff402dd000)
        libqpid-proton-proactor.so.1 => not found
        libqpid-proton-core.so.10 => not found
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007113e0800000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007113e0b22000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007113e0400000)
        /lib64/ld-linux-x86-64.so.2 (0x00007113e0bcb000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007113e0717000)
    

    One way to address this (post-install) is to use patchelf to both confirm the lack of an rpath, and to set one.

    $ patchelf --print-rpath local_install/lib/libqpid-proton-cpp.so
    
    $ patchelf --set-rpath `pwd`/local_install/lib local_install/lib/libqpid-proton-cpp.so
    
    $ patchelf --print-rpath local_install/lib/libqpid-proton-cpp.so
    /tmp/qpid-test/local_install/lib
    
    $ ldd build/main
        linux-vdso.so.1 (0x00007fffdd519000)
        libqpid-proton-cpp.so.12 => /tmp/qpid-test/local_install/lib/libqpid-proton-cpp.so.12 (0x00007171e15cf000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007171e1200000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007171e1594000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007171e0e00000)
        libqpid-proton-proactor.so.1 => /tmp/local_install/lib/libqpid-proton-proactor.so.1 (0x00007171e157e000)
        libqpid-proton-core.so.10 => /tmp/local_install/lib/libqpid-proton-core.so.10 (0x00007171e1528000)
        /lib64/ld-linux-x86-64.so.2 (0x00007171e1654000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007171e1117000)
        libssl.so.3 => /lib/x86_64-linux-gnu/libssl.so.3 (0x00007171e147e000)
        libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x00007171e0800000)
    
    $ build/main
    Container start
    Container stopped...
    proton:io: Connection refused - disconnected 127.0.0.1:5672
    

    Obviously, "patching" libqpid-proton-cpp post-install isn't ideal. This smells like a bug or just an oversight in their link process, and they're not taking into account CMAKE_INSTALL_PREFIX. I haven't looked into what exactly they're doing, but I'd file an issue there.

    By-the-way, things work ask expected on macOS.

    $ otool -L main
    main:
        @rpath/libqpid-proton-cpp.12.dylib (compatibility version 12.0.0, current version 12.13.0)
        /opt/homebrew/opt/llvm/lib/c++/libc++.1.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)
    
    $ ./main
    Container start
    Container stopped...
    proton:io: connection refused - connecting to 127.0.0.1:5672