Estou tentando obter um sistema de compilação multiplataforma trabalhando com o CMake. Agora o software tem algumas dependências. Eu os compilei e os instalei no meu sistema.
Alguns arquivos de exemplo que foram instalados:
-- 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
Agora o CMake possui um find_package()
que abre um Find*.cmake
arquivo e pesquisa a biblioteca no sistema e define algumas variáveis como SomeLib_FOUND
etc.
Meu CMakeLists.txt contém algo como isto:
set(CMAKE_MODULE_PATH "/usr/local/lib/SomeLib/cmake/;${CMAKE_MODULE_PATH}")
find_package(SomeLib REQUIRED)
O primeiro comando define onde o CMake pesquisa depois do Find*.cmake
e adicionei o diretório de SomeLib
onde ele FindSomeLib.cmake
pode ser encontrado, para que find_package()
funcione conforme o esperado.
Mas isso é meio estranho, porque uma das razões pelas quais find_package()
existe é fugir de caminhos codificados que não sejam de plataforma cruzada.
Como isso geralmente é feito? Devo copiar o cmake/
diretório de SomeLib
para o meu projeto e definir o CMAKE_MODULE_PATH
relativamente?
Respostas:
O comando
find_package
possui dois modos:Module
mode eConfig
mode. Você está tentando usar oModule
modo quando realmente precisa doConfig
modo.Modo de módulo
Find<package>.cmake
arquivo localizado dentro do seu projeto. Algo assim:CMakeLists.txt
conteúdo:Observe que
CMAKE_MODULE_PATH
tem alta prioridade e pode ser útil quando você precisar reescrever oFind<package>.cmake
arquivo padrão .Modo de configuração (instalação)
<package>Config.cmake
arquivo localizado fora e produzido porinstall
comando de outro projeto (Foo
por exemplo).foo
biblioteca:Versão simplificada do arquivo de configuração:
Por projeto padrão instalado no
CMAKE_INSTALL_PREFIX
diretório:Modo de configuração (uso)
Use
find_package(... CONFIG)
para incluirFooConfig.cmake
no destino importadofoo
:Observe que o destino importado é altamente configurável. Veja minha resposta .
Atualizar
fonte
configure_package_config_file
. A propósito, se você tiver outras sugestões, pode me enviar uma solicitação de recebimento.bin/lib
(tente instalar o executável e executá-lo no Windows). E os namespaces parecem muito bonitos, então eu os manterei também :) Também adicioneimonolithic
build.Se você estiver executando
cmake
para gerar aSomeLib
si mesmo (digamos, como parte de uma superbuild), considere usar o Registro de Pacotes do Usuário . Isso não requer caminhos codificados e é multiplataforma. No Windows (incluindo o mingw64), ele funciona através do registro. Se você examinar como a lista de prefixos de instalação é construída peloCONFIG
modo dos find_packages () comando , verá que o Registro de Pacotes do Usuário é um dos elementos.Breve tutorial
Associe os destinos
SomeLib
necessários fora desse projeto externo, adicionando-os a um conjunto de exportação nosCMakeLists.txt
arquivos em que são criados:Crie um
XXXConfig.cmake
arquivoSomeLib
nele${CMAKE_CURRENT_BUILD_DIR}
e armazene esse local no Registro de Pacotes do Usuário adicionando duas chamadas para exportar () aoCMakeLists.txt
associado aSomeLib
:Emita seu
find_package(SomeLib REQUIRED)
comando noCMakeLists.txt
arquivo do projeto que dependeSomeLib
sem que os "caminhos codificados por hardware que não sejam de plataforma cruzada" mexam com oCMAKE_MODULE_PATH
.Quando pode ser a abordagem correta
Essa abordagem provavelmente é mais adequada para situações em que você nunca usará o software a jusante do diretório de construção (por exemplo, você está compilando de forma cruzada e nunca instala nada em sua máquina, ou está construindo o software apenas para executar testes no o diretório build), pois ele cria um link para um arquivo .cmake na saída "build", que pode ser temporária.
Mas se você nunca estiver realmente instalando
SomeLib
no seu fluxo de trabalho, a chamadaEXPORT(PACKAGE <name>)
permitirá que você evite o caminho codificado. E, é claro, se você estiver instalandoSomeLib
, provavelmente conhece sua plataformaCMAKE_MODULE_PATH
etc., então a excelente resposta do @ user2288008 o ajudará a entender.fonte
Você não precisa especificar o caminho do módulo em si. O CMake é enviado com seu próprio conjunto de scripts find_package internos e sua localização é no CMAKE_MODULE_PATH padrão.
O caso de uso mais normal para projetos dependentes que foram CMakeified seria usar o comando external_project do CMake e incluir o arquivo Use [Project] .cmake do subprojeto. Se você só precisa do script Find [Project] .cmake, copie-o do subprojeto e para o código-fonte do seu próprio projeto e não precisará aumentar o CMAKE_MODULE_PATH para encontrar o subprojeto no nível do sistema.
fonte
their location is in the default CMAKE_MODULE_PATH
por padrão,CMAKE_MODULE_PATH
está vazioCMAKE_MODULE_PATH
está vazio no Windows.Se você não confia no CMake para ter esse módulo, então - sim, faça isso - mais ou menos: Copie
find_SomeLib.cmake
e suas dependências para o seucmake/
diretório. É o que faço como substituto. É uma solução feia embora.Observe que os
FindFoo.cmake
módulos são uma espécie de ponte entre dependência de plataforma e independência de plataforma - eles procuram em vários locais específicos da plataforma para obter caminhos em variáveis cujos nomes são independentes de plataforma.fonte