Wie kann CMake dazu gebracht werden, eine ausführbare Datei mit einer externen gemeinsam genutzten Bibliothek zu verknüpfen, die nicht im selben CMake-Projekt erstellt wurde?
Nur zu tun target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so)
gibt den Fehler
make[2]: *** No rule to make target `res/mylib.so', needed by `GLBall'. Stop.
make[1]: *** [CMakeFiles/GLBall.dir/all] Error 2
make: *** [all] Error 2
(GLBall is the executable)
nachdem ich die Bibliothek in das Binärverzeichnis kopiert habe bin/res
.
Ich habe es versucht find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)
Was mit scheitert RESULT-NOTFOUND
.
link_directories
wird auch in der eigenen Dokumentation abgeraten. Ich denke, es wäre hier besser, den fehlgeschlagenenfind_library
Anruf in der ursprünglichen Frage zu beheben oder die Lösung von @ Andre zu verwenden.find_library
diesen Pfad immer verwenden und verwenden, anstatt ihn fest zu codieren, vgl. meine Antwort .Die Antwort von arrowdodger ist richtig und wird bei vielen Gelegenheiten bevorzugt. Ich möchte einfach eine Alternative zu seiner Antwort hinzufügen:
Sie können anstelle eines Linkverzeichnisses ein "importiertes" Bibliotheksziel hinzufügen. Etwas wie:
Und dann verlinken, als ob diese Bibliothek von Ihrem Projekt erstellt wurde:
Ein solcher Ansatz würde Ihnen etwas mehr Flexibilität geben: Sehen Sie sich den Befehl add_library () und die vielen Zieleigenschaften an, die sich auf importierte Bibliotheken beziehen .
Ich weiß nicht, ob dies Ihr Problem mit "aktualisierten Versionen von Bibliotheken" lösen wird.
quelle
add_library( mylib SHARED IMPORTED )
oder Sie bekommen einenadd_library called with IMPORTED argument but no library type
FehlerIMPORTED_LOCATION
die öffnende Klammer falsch istGLOBAL
nachdem ,IMPORTED
ob Sie die importierte Bibliothek in Verzeichnisse über dem aktuellen zugreifen möchten:add_library(breakpad STATIC IMPORTED GLOBAL)
Ich gehe davon aus, dass Sie eine Verknüpfung zu einer Bibliothek namens foo herstellen möchten. Der Dateiname ist normalerweise ein Link
foo.dll
oderlibfoo.so
.1. Bibliothek
suchen Sie müssen die Bibliothek finden. Dies ist eine gute Idee, auch wenn Sie den Pfad zu Ihrer Bibliothek kennen. CMake wird einen Fehler ausgeben, wenn die Bibliothek verschwunden ist oder einen neuen Namen erhalten hat. Dies hilft, Fehler frühzeitig zu erkennen und dem Benutzer (möglicherweise selbst) klar zu machen, was ein Problem verursacht.
Um eine Bibliothek zu finden foo und speichern Sie den Pfad in
FOO_LIB
GebrauchCMake wird selbst herausfinden, wie der tatsächliche Dateiname lautet. Es prüft die üblichen Orten wie
/usr/lib
,/usr/lib64
und die Wege inPATH
.Sie kennen bereits den Standort Ihrer Bibliothek. Fügen Sie es dem hinzu,
CMAKE_PREFIX_PATH
wenn Sie CMake aufrufen. CMake sucht dann auch in den übergebenen Pfaden nach Ihrer Bibliothek.Manchmal müssen Sie Hinweise oder Pfadsuffixe hinzufügen. Weitere Informationen finden Sie in der Dokumentation: https://cmake.org/cmake/help/latest/command/find_library.html
2. Verknüpfen Sie die Bibliothek Ab 1. Sie haben den vollständigen Bibliotheksnamen in
FOO_LIB
. Sie verwenden dies, um die BibliothekGLBall
wie in mit Ihrem Ziel zu verknüpfenSie sollten hinzufügen
PRIVATE
,PUBLIC
oderINTERFACE
nach dem Ziel, vgl die Dokumentation: https://cmake.org/cmake/help/latest/command/target_link_libraries.htmlWenn Sie keinen dieser Sichtbarkeitsspezifizierer hinzufügen, verhält sich dieser entweder wie
PRIVATE
oderPUBLIC
, abhängig von der CMake-Version und den festgelegten Richtlinien.3. Includes hinzufügen (Dieser Schritt ist möglicherweise nicht obligatorisch.)
Wenn Sie auch Header-Dateien einschließen möchten, verwenden Sie
find_path
ähnlich wiefind_library
und suchen Sie nach einer Header-Datei. Fügen Sie dann das Include-Verzeichnis mittarget_include_directories
ähnlichem hinzutarget_link_libraries
.Dokumentation: https://cmake.org/cmake/help/latest/command/find_path.html und https://cmake.org/cmake/help/latest/command/target_include_directories.html
Wenn für die externe Software verfügbar, können Sie diese ersetzen
find_library
undfind_path
durchfind_package
.quelle
find_package
ist so viel einfacher als diese Schritte zutarget_link_libraries(mylib "${FOO_LIB}")
? Das Ziel istmylib
anstelle seines eigentlichen ZielsGLBall
? macht für mich nicht viel SinnEine weitere Alternative, falls Sie mit dem Appstore arbeiten, benötigen "Berechtigungen" und müssen daher mit einem Apple-Framework verknüpft werden.
Damit Berechtigungen funktionieren (z. B. GameCenter), müssen Sie einen "Link Binary with Libraries" -Bildstep haben und dann mit "GameKit.framework" verknüpfen. CMake "injiziert" die Bibliotheken auf einer "niedrigen Ebene" in die Befehlszeile, daher weiß Xcode nicht wirklich davon, und als solches wird GameKit im Bildschirm "Funktionen" nicht aktiviert.
Eine Möglichkeit, CMake zu verwenden und einen "Link with Binaries" -Bildstep zu erstellen, besteht darin, das xcodeproj mit CMake zu generieren und dann mit 'sed' zu suchen und zu ersetzen und das GameKit so hinzuzufügen, wie es XCode gefällt ...
Das Skript sieht folgendermaßen aus (für Xcode 6.3.1).
speichere dies in "gamecenter.sed" und "wende" es dann so an (es ändert dein xcodeproj!)
Möglicherweise müssen Sie die Skriptbefehle ändern, um sie Ihren Anforderungen anzupassen.
Warnung: Es ist wahrscheinlich, dass es mit einer anderen Xcode-Version bricht, da sich das Projektformat ändern kann, die (fest codierte) eindeutige Nummer möglicherweise nicht wirklich eindeutig ist - und im Allgemeinen sind die Lösungen anderer Personen besser -, es sei denn, Sie müssen den Appstore + unterstützen Berechtigungen (und automatisierte Builds) tun dies nicht.
Dies ist ein CMake-Fehler, siehe http://cmake.org/Bug/view.php?id=14185 und http://gitlab.kitware.com/cmake/cmake/issues/14185
quelle