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_libraries
hace 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_TARGET
requiere 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-config
deben 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.txt
archivo 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_OTHER
contiene define y otras banderas necesarios para una compilación exitosa. Las banderasSDL2_LIBRARY_DIRS
SDL2_LDFLAGS_OTHER
Sin 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-config
biblioteca. 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_TARGET
opció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_modules
para 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
_LDFLAGS
o_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_definitions
instrucciones 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_directories
etc. ¡infectará el alcance global! Usetarget_include_directories
etc