Search code examples
cmakeubuntu-16.04static-linkingpaho

How to get static libraries for Eclipse Paho MQTT C client?


I'm trying to compile the code from the Paho repository on Ubuntu 16.04, such that the static libraries are produced:

cd ~/Downloads
git clone https://github.com/eclipse/paho.mqtt.c.git
mkdir /tmp/build.paho
cd /tmp/build.paho
cmake -GNinja -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_STATIC=TRUE ~/Downloads/paho.mqtt.c

The procedure always fails with the following errors:

-- The C compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- CMake version: 3.5.1
-- CMake system name: Linux
-- Timestamp is 2019-10-22T09:16:51Z
CMake Error at src/CMakeLists.txt:95 (ADD_LIBRARY):
  add_library cannot create target "paho-mqtt3c" because another target with the same name already exists.  The existing target is a shared library created in source directory "/home/<username>/Downloads/paho.mqtt.c/src".  See documentation for policy CMP0002 for more details.

CMake Error at src/CMakeLists.txt:96 (ADD_LIBRARY):
  add_library cannot create target "paho-mqtt3a" because another target with the same name already exists.  The existing target is a shared library created in source directory "/home/<username>/Downloads/paho.mqtt.c/src".  See documentation for policy CMP0002 for more details.

CMake Error at src/CMakeLists.txt:101 (INSTALL):
  install TARGETS given no LIBRARY DESTINATION for shared library target "paho-mqtt3c".

-- OpenSSL hints: 
-- OpenSSL headers found at /usr/include
-- OpenSSL library found at /usr/lib/aarch64-linux-gnu/libssl.so
-- OpenSSL Crypto library found at /usr/lib/aarch64-linux-gnu/libcrypto.so
CMake Error at src/CMakeLists.txt:165 (ADD_LIBRARY):
  add_library cannot create target "paho-mqtt3cs" because another target with the same name already exists.  The existing target is a shared library created in source directory "/home/<username>/Downloads/paho.mqtt.c/src".  See documentation for policy CMP0002 for more details.

CMake Error at src/CMakeLists.txt:166 (ADD_LIBRARY):
  add_library cannot create target "paho-mqtt3as" because another target with the same name already exists.  The existing target is a shared library created in source directory "/home/<username>/Downloads/paho.mqtt.c/src".  See documentation for policy CMP0002 for more details.

CMake Error at src/CMakeLists.txt:176 (INSTALL):
  install TARGETS given no LIBRARY DESTINATION for shared library target "paho-mqtt3cs".

-- OpenSSL hints: 
-- OpenSSL headers found at /usr/include
-- Configuring incomplete, errors occurred!
See also "/home/<username>/Downloads/paho.mqtt.c/build/CMakeFiles/CMakeOutput.log".

I don't understand what is going wrong. To my understanding I'm exactly following the steps of the repository documentation.

What else do I have to do, or what do I need to do differently?


Solution

  • In this repository, the static library target names conflict with the shared library target names. CMake does not allow this, as the target names must be unique. It looks like these ill-advised changes were pushed to the repository, which broke the PAHO CMake build (see here). Since the issue has been raised, one would assume a fix will be pushed soon.

    If you need a quick fix however, it is fairly painless to get this working. You can add the -static postfix onto the static library names in the paho.mqtt.c/src/CMakeLists.txt file. There are two notable sections in which this change need to happen, just search that file for PAHO_BUILD_STATIC:

    Near line 94 (add -static to the library names referenced within the if-statement, in bold below):

    IF (PAHO_BUILD_STATIC)
        ADD_LIBRARY(paho-mqtt3c-static STATIC $ MQTTClient.c)
        ADD_LIBRARY(paho-mqtt3a-static STATIC $ MQTTAsync.c)
    
        TARGET_LINK_LIBRARIES(paho-mqtt3c-static ${LIBS_SYSTEM})
        TARGET_LINK_LIBRARIES(paho-mqtt3a-static ${LIBS_SYSTEM})
    
        INSTALL(TARGETS paho-mqtt3c-static paho-mqtt3a-static
            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
    ENDIF() 
    

    Near line 164 (add -static to the library names referenced within the if-statement, in bold below):

        IF (PAHO_BUILD_STATIC)
            ADD_LIBRARY(paho-mqtt3cs-static STATIC $ MQTTClient.c SSLSocket.c)
            ADD_LIBRARY(paho-mqtt3as-static STATIC $ MQTTAsync.c SSLSocket.c)
    
            TARGET_LINK_LIBRARIES(paho-mqtt3cs-static ${OPENSSL_LIBRARIES} ${LIBS_SYSTEM})
            TARGET_LINK_LIBRARIES(paho-mqtt3as-static ${OPENSSL_LIBRARIES} ${LIBS_SYSTEM})
            SET_TARGET_PROPERTIES(
            paho-mqtt3cs-static paho-mqtt3as-static PROPERTIES
            VERSION ${CLIENT_VERSION}
            SOVERSION ${PAHO_VERSION_MAJOR}
            COMPILE_DEFINITIONS "OPENSSL=1")
    
            INSTALL(TARGETS paho-mqtt3cs-static paho-mqtt3as-static
                ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
        ENDIF()
    

    After making the changes, clear your CMake cache (or delete the CMakeCache.txt file in your build folder) and re-run CMake. This should resolve the issue.