Wenn Sie cmake und pkg-config auf ganz normale Weise verwenden, funktioniert diese Lösung.
Wenn Sie jedoch eine Bibliothek haben, die in einem Entwicklungsverzeichnis vorhanden ist (z. B. / home / me / hack / lib), können die Linkerpfade mit anderen hier gezeigten Methoden nicht konfiguriert werden. Bibliotheken, die sich nicht unter den typischen Installationsorten befinden, würden zu Linkerfehlern führen, wie z /usr/bin/ld: cannot find -lmy-hacking-library-1.0
. Diese Lösung behebt den Linkerfehler für diesen Fall.
Ein weiteres Problem könnte sein, dass die pkg-config-Dateien nicht an der normalen Stelle installiert sind und die pkg-config-Pfade für das Projekt mithilfe der Umgebungsvariablen PKG_CONFIG_PATH hinzugefügt werden müssen, während cmake ausgeführt wird (siehe andere diesbezügliche Fragen zum Stapelüberlauf). Angenommen, Sie haben den richtigen pkg-config-Pfad eingerichtet, behebt diese Lösung auch dieses Problem.
Die Lösung läuft auf diese endgültige Version einer funktionierenden CMakeLists.txt hinaus:
cmake_minimum_required(VERSION 3.14)
project(ya-project C)
# the `pkg_check_modules` function is created with this call
find_package(PkgConfig REQUIRED)
# these calls create special `PkgConfig::<MODULE>` variables
pkg_check_modules(MY_PKG REQUIRED IMPORTED_TARGET any-package)
pkg_check_modules(YOUR_PKG REQUIRED IMPORTED_TARGET ya-package)
add_executable(program-name file.c ya.c)
target_link_libraries(program-name PUBLIC
PkgConfig::MY_PKG
PkgConfig::YOUR_PKG)
Beachten Sie, dass target_link_libraries
dies mehr als nur die Linker-Befehle ändert. Es werden auch andere PUBLIC-Eigenschaften bestimmter Ziele weitergegeben, z. B.: Compiler-Flags, Compiler-Definitionen, Include-Pfade usw.
IMPORTED_TARGET
erfordert CMake 3.6 oder neuer.Zunächst der Anruf:
sollte ersetzt werden durch:
Der
find_package()
Anruf ist flexibler und ermöglicht Optionen wieREQUIRED
, die Dinge automatisch erledigen, mit denen man manuell arbeiten müssteinclude()
.Zweitens sollte ein manueller Anruf
pkg-config
nach Möglichkeit vermieden werden. CMake enthält eine Reihe von Paketdefinitionen, die unter Linux unter zu finden sind/usr/share/cmake-3.0/Modules/Find*cmake
. Diese bieten dem Benutzer mehr Optionen und Auswahlmöglichkeiten als ein roher Anruf anpkg_search_module()
.Was den erwähnten hypothetischen
target_use()
Befehl betrifft, hat CMake diesen bereits in gewisser Weise mit PUBLIC | PRIVATE | INTERFACE eingebaut. Ein Aufruf wietarget_include_directories(mytarget PUBLIC ...)
bewirkt, dass die Include-Verzeichnisse automatisch in jedem Ziel verwendet werdenmytarget
, das ztarget_link_libraries(myapp mytarget)
. Dieser Mechanismus scheint jedoch nur für Bibliotheken zu gelten, die in derCMakeLists.txt
Datei erstellt wurden, und funktioniert nicht für Bibliotheken, die mit erworben wurdenpkg_search_module()
. Der Anrufadd_library(bar SHARED IMPORTED)
könnte dafür verwendet werden, aber ich habe das noch nicht untersucht.Die Hauptfrage funktioniert hier in den meisten Fällen:
Das
SDL2_CFLAGS_OTHER
enthält Definitionen und andere Flags, die für eine erfolgreiche Kompilierung erforderlich sind. Die FlaggenSDL2_LIBRARY_DIRS
undSDL2_LDFLAGS_OTHER
sind aber immer noch ignoriert, keine Ahnung , wie oft , dass ein Problem werden würde.Weitere Dokumentation hier http://www.cmake.org/cmake/help/v3.0/module/FindPkgConfig.html
quelle
Es ist selten, dass man nur mit SDL2 verknüpfen muss. Die derzeit beliebte Antwort verwendet,
pkg_search_module()
welche nach bestimmten Modulen sucht und das erste funktionierende verwendet.Es ist wahrscheinlicher, dass Sie eine Verknüpfung mit SDL2 und SDL2_Mixer und SDL2_TTF usw. herstellen möchten,
pkg_check_modules()
um nach allen angegebenen Modulen zu suchen .Haftungsausschluss: Ich hätte Grumbels Selbstantwort einfach kommentiert, wenn ich genug Street Creds mit Stackoverflow gehabt hätte.
quelle
target_link_libraries(my_app ${SDL2_LINK_LIBRARIES})
besser funktioniert.Die meisten verfügbaren Antworten können die Header für die
pkg-config
Bibliothek nicht konfigurieren . Nachdem ich über die Dokumentation für FindPkgConfig meditiert hatte, kam ich auf eine Lösung, die auch Folgendes bietet:( Ersetzen Sie Ihr Ziel anstelle der
<my-target>
Bibliothek und entsprechend der Bibliothek<some-lib>
entsprechend. )Die
IMPORTED_TARGET
Option scheint der Schlüssel zu sein und macht alles dann unter demPkgConfig::
Namespace verfügbar . Das war alles , was erforderlich war , und auch , dass alle sollte erforderlich sein.quelle
pkg_check_modules
der verfügbaren sehen Vars stackoverflow.com/a/9328525/1211174Es gibt keinen Befehl wie
target_use
. Ich kenne jedoch mehrere Projekte, die einen solchen Befehl für den internen Gebrauch geschrieben haben. Jedes Projekt möchte jedoch zusätzliche Flags oder Definitionen übergeben, daher ist es nicht sinnvoll, es allgemein als CMake zu verwenden. Ein weiterer Grund, warum Sie es nicht haben sollten, sind Bibliotheken mit C ++ - Vorlagen wie Eigen. Es gibt keine Bibliothek, aber Sie haben nur eine Reihe von Include-Dateien.Der beschriebene Weg ist oft richtig. Es kann für einige Bibliotheken unterschiedlich sein, dann müssen Sie
_LDFLAGS
oder hinzufügen_CFLAGS
. Ein Grund mehr, nicht zu habentarget_use
. Wenn es bei Ihnen nicht funktioniert, stellen Sie eine neue Frage zu SDL2 oder einer anderen Bibliothek, die Sie verwenden möchten.quelle
Wenn Sie auch Definitionen aus der Bibliothek hinzufügen möchten, ist die
add_definitions
Anweisung dafür da. Dokumentation findet sich hier , zusammen mit mehr Möglichkeiten , Compiler - Flags hinzuzufügen.Das folgende Codefragment verwendet diese Anweisung, um GTKGL zum Projekt hinzuzufügen:
quelle
include_directories
etc, es wird den globalen Geltungsbereich infizieren! Verwenden Sietarget_include_directories
etc