CMake: Problem mit externer Lib bei Subprojekten



  • Hi,
    ich entwickle momentan an einer Anwendung, welche ich auf verschiedene statische Bibliotheken aufteilen möchte.
    Da ich dabei QT verwende hab ich bis jetzt QMake eingesetzt möchte nun allerdings zu CMake wechseln.

    Dabei hab ich das Problem, das ich in einer Bibliothek libCURL benötige.
    Nun lässt sich die Bibliothek auch kompilieren und linken, allerdings versucht CMake die libCURL nun auch mit der Anwendung zu linken, was fehlschlägt, da die Bibliothek beim kompilieren der Anwendung nicht gefunden wird.

    Um den Fehler zu reproduzieren hab ich ein Testprojekt mit dem folgenden Aufbau erstellt:

    Root of the project
    |---src
    |   |---test_app
    |   |   |---main.cpp
    |   |   +---CMakeLists.txt
    |   +---test_lib
    |       |---FtpTransfer.cpp
    |       |---FtpTransfer.h
    |       +---CMakeLists.txt
    +---CMakeLists.txt
    

    test_lib -> CMakeLists.txt

    cmake_minimum_required(VERSION 2.6)
    project(test_lib)
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    FIND_PACKAGE(Qt4 REQUIRED)
    
    FIND_PACKAGE(CURL REQUIRED)
    
    FILE(GLOB_RECURSE SRCS "*.cpp" )
    
    add_library (${PROJECT_NAME} STATIC ${SRCS})
    target_link_libraries(${PROJECT_NAME} CURL Qt4::QtCore)
    
    set(${PROJECT_NAME}_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}
        CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
    
    set_target_properties(${PROJECT_NAME}
        PROPERTIES
        ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
        LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
        RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
    )
    

    test_app -> CMakeLists.txt

    cmake_minimum_required(VERSION 2.6)
    project(test_app)
    
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    set(CMAKE_AUTORCC ON)
    
    FIND_PACKAGE(Qt4 REQUIRED)
    
    FILE(GLOB_RECURSE SRCS "*.cpp")
    
    include_directories(${test_lib_INCLUDES})
    
    add_executable(${PROJECT_NAME}  ${SRCS} ${MISC_SRCS} ${RES})
    target_link_libraries(${PROJECT_NAME} 
      Qt4::QtCore
    
      test_lib
    )
    
    set_target_properties(${PROJECT_NAME} 
        PROPERTIES
        ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
        LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
        RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
    )
    

    root -> CMakeLists.txt

    cmake_minimum_required(VERSION 2.6)
    project("CmakeTest")
    
    set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
    set(CMAKE_DISABLE_SOURCE_CHANGES  ON)
    
    if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
      message(SEND_ERROR "In-source builds are not allowed.")
    endif ()
    
    add_subdirectory(src/test_lib)
    
    add_subdirectory(src/test_app)
    

    Beim kompilieren (Linux) bekomme ich dann diese Fehlermeldung:

    Scanning dependencies of target test_lib
    [ 33%] Building CXX object src/test_lib/CMakeFiles/test_lib.dir/FtpTransfer.cpp.o
    Linking CXX static library ../../lib/libtest_lib.a
    [ 33%] Built target test_lib
    Scanning dependencies of target test_app_automoc
    [ 66%] Automatic rcc for target test_app
    [ 66%] Built target test_app_automoc
    Scanning dependencies of target test_app
    [100%] Building CXX object src/test_app/CMakeFiles/test_app.dir/main.cpp.o
    Linking CXX executable ../../bin/test_app
    /usr/bin/ld: cannot find -lCURL
    collect2: Fehler: ld gab 1 als Ende-Status zurück
    src/test_app/CMakeFiles/test_app.dir/build.make:88: recipe for target 'bin/test_app' failed
    make[2]: *** [bin/test_app] Error 1
    CMakeFiles/Makefile2:127: recipe for target 'src/test_app/CMakeFiles/test_app.dir/all' failed
    make[1]: *** [src/test_app/CMakeFiles/test_app.dir/all] Error 2
    Makefile:76: recipe for target 'all' failed
    make: *** [all] Error 2
    

    Ich würde mich über alle Tipps freuen, die mir bei diesem Problem weiter helfen könnten.

    Grüße
    Valdis



  • Du hast (mindestens) CURL falsch eingebunden.

    Korrekt ist noch der Aufruf von find_package(..) und er erzeugt verschiedene Variablen. Unter anderem CURL_FOUND und CURL_LIBRARIES.

    FIND_PACKAGE(CURL REQUIRED)
    

    Danach musst du die Libraries angeben, welche dazu gelinkt werden sollen (Qt habe ich auch gleich korrigiert).

    target_link_libraries(${PROJECT_NAME} ${CURL_LIBRARIES} ${QT_LIBRARIES})
    


  • Vielen Dank für die schnelle Antwort.

    Leider passt die Lösung nicht zu 100%, hat mich aber auf die richtige Idee gebracht.

    Die Zeile muss so aussehen:

    target_link_libraries(${PROJECT_NAME} ${CURL_LIBRARIES} Qt4::QtCore)
    

    Qt muss so angeben werden, da so auch die Module gewählt werden. (Doku)

    Wenn ich das so ändere verschwindet der Fehler beim Linken und die Anwendung wird korrekt erstellt.

    Grüße
    Valdis


Anmelden zum Antworten