Estoy tratando de hacer que un sistema de compilación multiplataforma funcione usando 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 archivo find_package()
que abre un Find*.cmake
archivo y busca la biblioteca en el sistema y define algunas variables comoSomeLib_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 busca CMake después de Find*.cmake
y agregué el directorio SomeLib
donde FindSomeLib.cmake
se puede encontrar, por lo quefind_package()
funciona como se esperaba.
Pero esto es un poco extraño porque una de las razones por las cuales find_package()
existe es para alejarse de los caminos codificados sin plataforma cruzada.
¿Cómo se hace esto generalmente? ¿Debo copiar el cmake/
directorio de SomeLib
en mi proyecto y configurar el CMAKE_MODULE_PATH
relativamente?
Respuestas:
El comando
find_package
tiene dos modos:Module
modo yConfig
modo. Estás intentando usar elModule
modo cuando realmente necesitas elConfig
modo.Modo de módulo
Find<package>.cmake
archivo ubicado dentro de su proyecto. Algo como esto:CMakeLists.txt
contenido:Tenga en cuenta que
CMAKE_MODULE_PATH
tiene alta prioridad y puede ser útil cuando necesita reescribir unFind<package>.cmake
archivo estándar .Modo de configuración (instalar)
<package>Config.cmake
archivo ubicado afuera y producido porinstall
comando de otro proyecto (Foo
por ejemplo).foo
biblioteca:Versión simplificada del archivo de configuración:
Por defecto proyecto instalado en el
CMAKE_INSTALL_PREFIX
directorio:Modo de configuración (uso)
Use
find_package(... CONFIG)
para incluirFooConfig.cmake
con destino importadofoo
:Tenga en cuenta que el objetivo importado es altamente configurable. Mira mi respuesta .
Actualizar
fuente
configure_package_config_file
. Por cierto, si tiene alguna otra sugerencia, puede enviarme una solicitud de extracción.bin/lib
(intente instalar el ejecutable y ejecutarlo en Windows). Y los espacios de nombres se ven muy bonitos, así que los mantendré también :) También agreguémonolithic
build.Si está ejecutando
cmake
para generarSomeLib
usted mismo (por ejemplo, como parte de una superconstrucción), considere usar el Registro de paquetes de usuario . Esto no requiere rutas codificadas y es multiplataforma. En Windows (incluido mingw64) funciona a través del registro. Si examina cómo se construye la lista de prefijos de instalación mediante elCONFIG
modo del comando find_packages () , verá que el Registro de paquetes de usuario es uno de los elementos.Breve instrucciones
Asocia los objetivos
SomeLib
que necesitas fuera de ese proyecto externo agregándolos a un conjunto de exportación en losCMakeLists.txt
archivos donde se crean:Cree un
XXXConfig.cmake
archivoSomeLib
en${CMAKE_CURRENT_BUILD_DIR}
y almacene esta ubicación en el Registro de paquetes de usuario agregando dos llamadas a export () a lasCMakeLists.txt
asociadas conSomeLib
:Emita su
find_package(SomeLib REQUIRED)
comando en elCMakeLists.txt
archivo del proyecto que dependeSomeLib
sin los "caminos codificados no multiplataforma" jugando con elCMAKE_MODULE_PATH
.Cuando podría ser el enfoque correcto
Este enfoque probablemente sea el más adecuado para situaciones en las que nunca usará su software aguas abajo del directorio de compilación (por ejemplo, está compilando de forma cruzada y nunca instala nada en su máquina, o está construyendo el software solo para ejecutar pruebas en el directorio de compilación), ya que crea un enlace a un archivo .cmake en su salida de "compilación", que puede ser temporal.
Pero si nunca está realmente instalando
SomeLib
en su flujo de trabajo, las llamadas leEXPORT(PACKAGE <name>)
permiten evitar la ruta codificada. Y, por supuesto, si está instalandoSomeLib
, probablemente conozca su plataformaCMAKE_MODULE_PATH
, etc., por lo que la excelente respuesta de @ user2288008 lo tendrá cubierto.fuente
No necesita especificar la ruta del módulo per se. CMake se entrega con su propio conjunto de scripts find_package integrados, y su ubicación está en el CMAKE_MODULE_PATH predeterminado.
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 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.
fuente
their location is in the default CMAKE_MODULE_PATH
por defectoCMAKE_MODULE_PATH
está vacíoCMAKE_MODULE_PATH
está vacío en Windows.Si no confía en que CMake tenga ese módulo, entonces, sí, haga eso: copie el
find_SomeLib.cmake
y sus dependencias en sucmake/
directorio. Eso es lo que hago como reserva. Sin embargo, es una solución fea.Tenga en cuenta que
FindFoo.cmake
cada uno de los módulos es una especie de puente entre la dependencia de la plataforma y la independencia de la plataforma: se ven en varios lugares específicos de la plataforma para obtener rutas en variables cuyos nombres son independientes de la plataforma.fuente