Jeśli używasz cmake i pkg-config w całkiem normalny sposób, to rozwiązanie działa.
Jeśli jednak masz bibliotekę, która istnieje w jakimś katalogu programistycznym (takim jak / home / me / hack / lib), to użycie innych metod opisanych tutaj nie spowoduje skonfigurowania ścieżek konsolidatora. Biblioteki, które nie zostały znalezione w typowych lokalizacjach instalacji, spowodowałyby błędy konsolidatora, takie jak /usr/bin/ld: cannot find -lmy-hacking-library-1.0
. To rozwiązanie naprawia błąd konsolidatora w tym przypadku.
Innym problemem może być to, że pliki pkg-config nie są instalowane w normalnym miejscu, a ścieżki pkg-config dla projektu muszą zostać dodane przy użyciu zmiennej środowiskowej PKG_CONFIG_PATH podczas działania cmake (zobacz inne pytania dotyczące przepełnienia stosu). Zakładając, że masz skonfigurowaną poprawną ścieżkę pkg-config, to rozwiązanie również rozwiązuje ten problem.
Rozwiązanie sprowadza się do tej ostatecznej wersji działającego CMakeLists.txt:
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)
Zauważ, że target_link_libraries
robi coś więcej niż tylko zmianę poleceń konsolidatora. Propaguje również inne właściwości PUBLIC określonych celów, takie jak: flagi kompilatora, definicje kompilatora, ścieżki dołączania itp.
IMPORTED_TARGET
wymaga CMake 3.6 lub nowszej.Po pierwsze, wezwanie:
należy zastąpić:
find_package()
Rozmowa jest bardziej elastyczny i pozwala na takie opcje, jakREQUIRED
, to robić rzeczy automatycznie, że trzeba by zrobić ręcznieinclude()
.Po drugie, w
pkg-config
miarę możliwości należy unikać ręcznego dzwonienia . CMake zawiera bogaty zestaw definicji pakietów, które można znaleźć w Linuksie pod/usr/share/cmake-3.0/Modules/Find*cmake
. Zapewniają one więcej opcji i możliwości wyboru dla użytkownika niż surowe wywołaniepkg_search_module()
.Jeśli chodzi o wspomniane hipotetyczne
target_use()
polecenie, CMake ma już to wbudowane w pewien sposób z PUBLIC | PRIVATE | INTERFACE. Takie wywołanietarget_include_directories(mytarget PUBLIC ...)
spowoduje, że katalogi dołączania będą automatycznie używane w każdym używanym celumytarget
, nptarget_link_libraries(myapp mytarget)
. Jednak ten mechanizm wydaje się być tylko dla bibliotek utworzonych wCMakeLists.txt
pliku i nie działa dla bibliotek nabytych za pomocąpkg_search_module()
. To wezwanieadd_library(bar SHARED IMPORTED)
może zostać użyte do tego, ale jeszcze się nad tym nie sprawdziłem.Jeśli chodzi o główne pytanie, to tutaj działa w większości przypadków:
Plik
SDL2_CFLAGS_OTHER
Zawiera definiuje i inne flagi niezbędne dla pomyślnej kompilacji. FlagiSDL2_LIBRARY_DIRS
iSDL2_LDFLAGS_OTHER
są jednak nadal ignorowane, nie mam pojęcia, jak często będzie to problemem.Więcej dokumentacji tutaj http://www.cmake.org/cmake/help/v3.0/module/FindPkgConfig.html
źródło
Rzadko się zdarza, że wystarczy połączyć się z SDL2. Obecnie popularna odpowiedź wykorzystuje
pkg_search_module()
który sprawdza dane moduły i używa pierwszego działającego.Bardziej prawdopodobne jest, że będziesz chciał połączyć się z SDL2 i SDL2_Mixer i SDL2_TTF, itd ...
pkg_check_modules()
sprawdza wszystkie podane moduły.Zastrzeżenie: po prostu skomentowałbym własną odpowiedź Grumbela, gdybym miał wystarczająco dużo ulicznych kredytów ze stackoverflow.
źródło
target_link_libraries(my_app ${SDL2_LINK_LIBRARIES})
działało lepiej.W przypadku większości dostępnych odpowiedzi nie można skonfigurować nagłówków
pkg-config
biblioteki. Po medytacji nad dokumentacją dla FindPkgConfig wymyśliłem rozwiązanie, które zapewnia je również:( Zastąp cel w miejscu
<my-target>
i dowolnej bibliotece zamiast<some-lib>
, odpowiednio. )IMPORTED_TARGET
Opcja wydaje się być kluczowym i sprawia, że wszystko, co potem dostępne podPkgConfig::
nazw. To było wszystko, co było wymagane, a także wszystko, co powinno być wymagane.źródło
pkg_check_modules
aby zobaczyć dostępne vars stackoverflow.com/a/9328525/1211174Nie ma takiego polecenia jak
target_use
. Ale znam kilka projektów, które napisały takie polecenie do użytku wewnętrznego. Ale każdy projekt chce przekazać dodatkowe flagi lub definicje, dlatego nie ma sensu mieć go w ogólnym CMake. Innym powodem, dla którego go nie ma, są biblioteki szablonów C ++, takie jak Eigen, nie ma biblioteki, ale masz tylko kilka plików dołączanych.Opisany sposób jest często poprawny. Może się różnić w przypadku niektórych bibliotek, wtedy będziesz musiał dodać
_LDFLAGS
lub_CFLAGS
. Jeszcze jeden powód, żeby tego nie miećtarget_use
. Jeśli to nie zadziała, zadaj nowe pytanie dotyczące SDL2 lub innej biblioteki, z której chcesz korzystać.źródło
Jeśli chcesz dodać definicje również z biblioteki,
add_definitions
instrukcja jest do tego. Dokumentację można znaleźć tutaj , wraz z innymi sposobami dodawania flag kompilatora.Poniższy fragment kodu używa tej instrukcji, aby dodać GTKGL do projektu:
źródło
include_directories
itp. Spowoduje to zainfekowanie zasięgu globalnego! Użyjtarget_include_directories
itp.