Si está usando cmake y pkg-config de una manera bastante normal, esta solución funciona.
Sin embargo, si tiene una biblioteca que existe en algún directorio de desarrollo (como / home / me / hack / lib), el uso de otros métodos que se muestran aquí no configura las rutas del enlazador. Las bibliotecas que no se encuentran en las ubicaciones de instalación típicas darían lugar a errores del vinculador, como /usr/bin/ld: cannot find -lmy-hacking-library-1.0. Esta solución corrige el error del vinculador para ese caso.
Otro problema podría ser que los archivos pkg-config no están instalados en el lugar normal y las rutas pkg-config para el proyecto deben agregarse utilizando la variable de entorno PKG_CONFIG_PATH mientras cmake se está ejecutando (consulte otras preguntas de Stack Overflow al respecto). Suponiendo que tenga configurada la ruta correcta de pkg-config, esta solución también soluciona ese problema.
La solución se reduce a esta versión final de un CMakeLists.txt funcional:
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)
Tenga en cuenta que target_link_librarieshace más que cambiar los comandos del vinculador. También propaga otras propiedades PÚBLICAS de objetivos especificados como: indicadores del compilador, definiciones del compilador, rutas de inclusión, etc.
IMPORTED_TARGETrequiere CMake 3.6 o más reciente.Primero de, la llamada:
debe ser reemplazado por:
La
find_package()llamada es más flexible y permite opciones comoREQUIRED, que hacen cosas automáticamente con las que uno tendría que hacer manualmenteinclude().En segundo lugar, las llamadas manuales
pkg-configdeben evitarse cuando sea posible. CMake viene con un amplio conjunto de definiciones de paquetes, que se encuentran en Linux en/usr/share/cmake-3.0/Modules/Find*cmake. Estos brindan más opciones y opciones para el usuario que una llamada sin procesarpkg_search_module().En cuanto al
target_use()comando hipotético mencionado , CMake ya lo tiene incorporado de alguna manera con PUBLIC | PRIVATE | INTERFACE. Una llamada comotarget_include_directories(mytarget PUBLIC ...)hará que los directorios de inclusión se utilicen automáticamente en cada destino que utilicemytarget, por ejemplotarget_link_libraries(myapp mytarget). Sin embargo, este mecanismo parece ser solo para bibliotecas creadas dentro delCMakeLists.txtarchivo y no funciona para bibliotecas adquiridas conpkg_search_module(). La llamadaadd_library(bar SHARED IMPORTED)podría usarse para eso, pero aún no lo he investigado.En cuanto a la pregunta principal, esto aquí funciona en la mayoría de los casos:
El
SDL2_CFLAGS_OTHERcontiene define y otras banderas necesarios para una compilación exitosa. Las banderasSDL2_LIBRARY_DIRSSDL2_LDFLAGS_OTHERSin embargo, las y aún se ignoran, no tengo idea de la frecuencia con la que eso se convertiría en un problema.Más documentación aquí http://www.cmake.org/cmake/help/v3.0/module/FindPkgConfig.html
fuente
Es raro que solo sea necesario vincular con SDL2. La respuesta actualmente popular usa
pkg_search_module()which verifica los módulos dados y usa el primero que funciona.Es más probable que desee vincular con SDL2 y SDL2_Mixer y SDL2_TTF, etc ...
pkg_check_modules()comprueba todos los módulos dados.Descargo de responsabilidad: simplemente habría comentado sobre la respuesta propia de Grumbel si tuviera suficientes créditos callejeros con stackoverflow.
fuente
target_link_libraries(my_app ${SDL2_LINK_LIBRARIES})funcionó mejor.La mayoría de las respuestas disponibles no configuran los encabezados de la
pkg-configbiblioteca. Después de meditar en la documentación de FindPkgConfig, se me ocurrió una solución que también proporciona:( Sustituya su objetivo en lugar de
<my-target>y cualquier biblioteca en lugar de<some-lib>, según corresponda. )La
IMPORTED_TARGETopción parece ser clave y hace que todo esté disponible en elPkgConfig::espacio de nombres. Esto era todo lo que se requería y también todo lo que debía requerirse.fuente
pkg_check_modulespara ver las vars disponibles stackoverflow.com/a/9328525/1211174No existe un comando como
target_use. Pero conozco varios proyectos que han escrito tal comando para su uso interno. Pero cada proyecto quiere pasar banderas o definiciones adicionales, por lo que no tiene sentido tenerlo en CMake general. Otra razón para no tenerlo son las bibliotecas con plantillas de C ++ como Eigen, no hay biblioteca, pero solo tiene un montón de archivos de inclusión.La forma descrita a menudo es correcta. Puede que sea diferente para algunas bibliotecas, luego tendrá que agregar
_LDFLAGSo_CFLAGS. Una razón más para no tenertarget_use. Si no le funciona, haga una nueva pregunta específica sobre SDL2 o cualquier biblioteca que desee usar.fuente
Si también está buscando agregar definiciones de la biblioteca, las
add_definitionsinstrucciones están ahí para eso. La documentación se puede encontrar aquí , junto con más formas de agregar indicadores del compilador.El siguiente fragmento de código usa esta instrucción para agregar GTKGL al proyecto:
fuente
include_directoriesetc. ¡infectará el alcance global! Usetarget_include_directoriesetc