descarga - cmake vs make
CMake: ¿De qué sirve find_package() si necesita especificar CMAKE_MODULE_PATH de todos modos? (3)
¿Cómo se hace esto usualmente? ¿Debo copiar el directorio
cmake/
de SomeLib en mi proyecto y configurar el CMAKE_MODULE_PATH de manera relativa?
Si no confías en CMake para tener ese módulo, entonces - sí, haz eso . Eso es lo que hago como alternativa.
Tenga en cuenta que los módulos FindFoo.cmake
son cada uno una especie de puente entre la dependencia de la plataforma y la independencia de la plataforma: buscan en varios lugares específicos de la plataforma obtener rutas en variables cuyos nombres son independientes de la plataforma.
Estoy tratando de obtener un sistema de compilación multiplataforma que funcione con CMake. Ahora el software tiene algunas dependencias. Los compilé yo mismo y los instalé en mi sistema.
Algunos archivos de ejemplo que se instalaron:
-- Installing: /usr/local/share/SomeLib/SomeDir/somefile
-- Installing: /usr/local/share/SomeLib/SomeDir/someotherfile
-- Installing: /usr/local/lib/SomeLib/somesharedlibrary
-- Installing: /usr/local/lib/SomeLib/cmake/FindSomeLib.cmake
-- Installing: /usr/local/lib/SomeLib/cmake/HelperFile.cmake
Ahora CMake tiene un find_package()
que abre un archivo Find*.cmake
y busca la biblioteca en el sistema y define algunas variables como SomeLib_FOUND
etc.
Mi CMakeLists.txt contiene algo como esto:
set(CMAKE_MODULE_PATH "/usr/local/lib/SomeLib/cmake/;${CMAKE_MODULE_PATH}")
find_package(SomeLib REQUIRED)
El primer comando define dónde CMake busca después de Find*.cmake
y agregué el directorio de SomeLib
donde FindSomeLib.cmake
se puede encontrar, por lo que find_package()
funciona como se esperaba.
Pero esto es un poco extraño porque una de las razones por las que find_package()
existe es alejarse de las rutas no codificadas de plataforma cruzada.
¿Cómo se hace esto usualmente? ¿Debo copiar el directorio cmake/
de SomeLib
en mi proyecto y configurar el CMAKE_MODULE_PATH
relativa?
Command find_package
tiene dos modos: modo Module
y modo Config
. Está intentando usar el modo Module
cuando realmente necesita el modo Config
.
Modo de módulo
Find<package>.cmake
archivo Find<package>.cmake
ubicado dentro de tu proyecto. Algo como esto:
CMakeLists.txt
cmake/FindFoo.cmake
cmake/FindBoo.cmake
Contenido de CMakeLists.txt
:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(Foo REQUIRED) # FOO_INCLUDE_DIR, FOO_LIBRARIES
find_package(Boo REQUIRED) # BOO_INCLUDE_DIR, BOO_LIBRARIES
include_directories("${FOO_INCLUDE_DIR}")
include_directories("${BOO_INCLUDE_DIR}")
add_executable(Bar Bar.hpp Bar.cpp)
target_link_libraries(Bar ${FOO_LIBRARIES} ${BOO_LIBRARIES})
Tenga en cuenta que CMAKE_MODULE_PATH
tiene una alta prioridad y puede ser útil cuando necesite reescribir el archivo estándar Find<package>.cmake
.
Modo de configuración (instalar)
<package>Config.cmake
archivo <package>Config.cmake
ubicado fuera y producido por el comando de install
de otro proyecto ( Foo
por ejemplo).
biblioteca de foo
:
> cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(Foo)
add_library(foo Foo.hpp Foo.cpp)
install(FILES Foo.hpp DESTINATION include)
install(TARGETS foo DESTINATION lib)
install(FILES FooConfig.cmake DESTINATION lib/cmake/Foo)
Versión simplificada del archivo de configuración:
> cat FooConfig.cmake
add_library(foo STATIC IMPORTED)
find_library(FOO_LIBRARY_PATH foo HINTS "${CMAKE_CURRENT_LIST_DIR}/../../")
set_target_properties(foo PROPERTIES IMPORTED_LOCATION "${FOO_LIBRARY_PATH}")
Por defecto, proyecto instalado en el directorio CMAKE_INSTALL_PREFIX
:
> cmake -H. -B_builds
> cmake --build _builds --target install
-- Install configuration: ""
-- Installing: /usr/local/include/Foo.hpp
-- Installing: /usr/local/lib/libfoo.a
-- Installing: /usr/local/lib/cmake/Foo/FooConfig.cmake
Modo de configuración (uso)
Utilice find_package(... CONFIG)
para incluir FooConfig.cmake
con foo
objetivo importado:
> cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(Boo)
# import library target `foo`
find_package(Foo CONFIG REQUIRED)
add_executable(boo Boo.cpp Boo.hpp)
target_link_libraries(boo foo)
> cmake -H. -B_builds -DCMAKE_VERBOSE_MAKEFILE=ON
> cmake --build _builds
Linking CXX executable Boo
/usr/bin/c++ ... -o Boo /usr/local/lib/libfoo.a
Tenga en cuenta que el objetivo importado es altamente configurable. Ver mi answer
Actualizar
No necesita especificar la ruta del módulo per se. CMake se envía con su propio conjunto de scripts find_package incorporados, y su ubicación está en el valor predeterminado CMAKE_MODULE_PATH.
El caso de uso más normal para proyectos dependientes que han sido CMakeified sería usar el comando external_project de CMake y luego incluir el archivo Use [Project] .cmake del subproyecto. Si solo necesita el script Find [Project] .cmake, cópielo fuera del subproyecto y en el código fuente de su propio proyecto, y luego no necesitará aumentar el CMAKE_MODULE_PATH para encontrar el subproyecto a nivel del sistema.