2017-04-07 1 views
1

Ich arbeite an einer größeren C++ - Bibliothek, die CMake verwendet und hängt von Qt. Wir sind von Qt4 zu Qt5 gewechselt und jetzt stoße ich auf ein Problem, wenn wir unsere lib in einem Upstream-Projekt verwenden. Als minimales Beispiel arbeiten, das Problem demonstriert bitte einen Blick auf dieses Repo:CMake Paket Konfigurationsdateien für Upstream-Projekte mit Qt5 Probleme

https://github.com/philthiel/cmake_qt5_upstream

Es enthält zwei getrennte CMake Projekte:

  • MyLib: eine winzige Bibliothek, die QString von QT5 verwendet: :Ader.

    Es erzeugt und installiert Paket Konfigurationsdateien MyLIBConfig.cmake, MyLIBConfigVersion.cmake und MyLIBTargets.cmake um durch CMake find_package durchsuchbar zu sein()

  • myApp: ein winzige ausführbare abhängig von MyLib

    Das Projekt verwendet find_package (MyLib) und erstellt eine ausführbare Datei, die verwendet MyLib


Das Problem ist, dass CMake mir die folgende Fehlermeldung gibt, wenn das Projekt MeineAnw konfigurieren:

ist
CMake Error at CMakeLists.txt:11 (add_executable): 
    Target "MyAPP" links to target "Qt5::Core" but the target was not found. 
    Perhaps a find_package() call is missing for an IMPORTED target, or an 
    ALIAS target is missing? 

Der Grund für dieses Verhalten, das in der automatisch generierte MyLIBTargets.cmake den INTERFACE_LINK_LIBRARIES Eintrag Datei für QT5 Core ist die QT5 :: Kernsymbol Mit Qt4 wurde hier der absolute Pfad zur Qt-Core-Lib angegeben.


Jetzt kann ich einfach dieses Problem zu beheben, indem

find_package(Qt5Core 5.X REQUIRED) 

im myApp Projekt mit.

Allerdings würde ich gerne wissen, ob dies der beabsichtigte/generische Weg ist, dh Upstream-Projekte unserer lib anfragen, um die erforderlichen transitiven Qt5-Abhängigkeiten selbst zu suchen, oder wenn ich CMake hier wahrscheinlich missbrauche und ändern muss meine Konfigurationsprozedur?

Die CMake Doku auf Paketdatei Generation

https://cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html

erwähnt, dass Makros können durch die Paket-Konfigurationsdateien bereitgestellt werden, um den Strom. Vielleicht ist dies der richtige Ort, um nach importierten Zielen wie Qt5 zu suchen und Upstream-Konfigurationsläufe zu unterbrechen, wenn diese Abhängigkeiten nicht gefunden werden?

Best, Philipp

Antwort

1

[Bearbeiten des Bearbeitens] Vollständige Quelle Beispiel

Sie benötigen eine CMake Konfigurationsdatei für Ihr Projekt zu liefern, und wahrscheinlich die ConfigFile sollte über CMake selbst (weil Du generiert werden kann nicht wissen, wo der Benutzer Ihre Software installieren wird).

Tip, verwenden Sie die ECM Cmake Module die Erstellung, das zu erleichtern:

find_package(ECM REQUIRED NO_MODULE) 
include(CMakePackageConfigHelpers) 

ecm_setup_version(${PROJECT_VERSION} 
    VARIABLE_PREFIX ATCORE 
    VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/atcore_version.h" 
    PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5AtCoreConfigVersion.cmake" 
    SOVERSION 1 
) 

configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/KF5AtCoreConfig.cmake.in" 
           "${CMAKE_CURRENT_BINARY_DIR}/KF5AtCoreConfig.cmake" 
          INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} 
) 

und die KF5AtCoreConfig.cmake.in:

@[email protected] 

find_dependency(Qt5Widgets "@[email protected]") 
find_dependency(Qt5SerialPort "@[email protected]") 
find_dependency(KF5Solid "@[email protected]") 

include("${CMAKE_CURRENT_LIST_DIR}/KF5AtCoreTargets.cmake") 

Das mit all den richtigen FindYourSortware.cmake generieren Ihre Abhängigkeiten.

[Bearbeiten] Bessere Erklärung, was vor sich geht. Wenn Sie eine Bibliothek zur Verfügung stellen, die Qt verwenden, und das müsste auch die QT5 Bibliothek finden, bevor die Benutzer-Quelle compilling, müssen Sie sich einen FindYourLibrary.cmake Code zur Verfügung zu stellen, dass

find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Whatever) 

Jetzt nennen würde , wenn es Ihre ausführbare Datei ist, die verknüpft werden muss, verwenden Sie die Komponenten statt wie Sie es jetzt tun.

find_package(Qt5 REQUIRED COMPONENTS Core) 

dann verbinden Sie Ihre Bibliothek mit

target_link_libraries(YourTarget Qt5::Core) 
+0

Vielen Dank für die schnelle Antwort !! Die ausführbare Datei war nur ein Beispiel. Um Ihnen Recht zu geben, stelle ich tatsächlich ein benutzerdefiniertes Find-Modul oder entsprechende Makros mit meinen Bibliothekspaket-Konfigurationsdateien zur Verfügung, die nach transitiven Abhängigkeiten suchen und einen Fehler ausgeben, wenn der Upstream nach meiner Lib sucht und diese Abhängigkeiten nicht gefunden werden können? – philt

+0

ja, du musst. –

+0

Entschuldigung, ich drücke Enter, bevor ich fertig geschrieben habe. Ich aktualisiere die Antwort mit einem vollständigen Beispiel, wie ich damit umgehen soll. –