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*.cmakearchivo 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*.cmakey agregué el directorio SomeLibdonde FindSomeLib.cmakese 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 SomeLiben mi proyecto y configurar el CMAKE_MODULE_PATHrelativamente?

Respuestas:
El comando
find_packagetiene dos modos:Modulemodo yConfigmodo. Estás intentando usar elModulemodo cuando realmente necesitas elConfigmodo.Modo de módulo
Find<package>.cmakearchivo ubicado dentro de su proyecto. Algo como esto:CMakeLists.txtcontenido:Tenga en cuenta que
CMAKE_MODULE_PATHtiene alta prioridad y puede ser útil cuando necesita reescribir unFind<package>.cmakearchivo estándar .Modo de configuración (instalar)
<package>Config.cmakearchivo ubicado afuera y producido porinstallcomando de otro proyecto (Foopor ejemplo).foobiblioteca:Versión simplificada del archivo de configuración:
Por defecto proyecto instalado en el
CMAKE_INSTALL_PREFIXdirectorio:Modo de configuración (uso)
Use
find_package(... CONFIG)para incluirFooConfig.cmakecon 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émonolithicbuild.Si está ejecutando
cmakepara generarSomeLibusted 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 elCONFIGmodo del comando find_packages () , verá que el Registro de paquetes de usuario es uno de los elementos.Breve instrucciones
Asocia los objetivos
SomeLibque necesitas fuera de ese proyecto externo agregándolos a un conjunto de exportación en losCMakeLists.txtarchivos donde se crean:Cree un
XXXConfig.cmakearchivoSomeLiben${CMAKE_CURRENT_BUILD_DIR}y almacene esta ubicación en el Registro de paquetes de usuario agregando dos llamadas a export () a lasCMakeLists.txtasociadas conSomeLib:Emita su
find_package(SomeLib REQUIRED)comando en elCMakeLists.txtarchivo del proyecto que dependeSomeLibsin 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
SomeLiben 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_PATHpor defectoCMAKE_MODULE_PATHestá vacíoCMAKE_MODULE_PATHestá vacío en Windows.Si no confía en que CMake tenga ese módulo, entonces, sí, haga eso: copie el
find_SomeLib.cmakey sus dependencias en sucmake/directorio. Eso es lo que hago como reserva. Sin embargo, es una solución fea.Tenga en cuenta que
FindFoo.cmakecada 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