Eu escrevi uma biblioteca que costumava compilar usando um Makefile auto-escrito, mas agora quero mudar para cmake. A árvore fica assim (removi todos os arquivos irrelevantes):
Então, o que estou tentando fazer é apenas compilar a fonte em uma biblioteca compartilhada e instalá-la com os arquivos de cabeçalho.
Muitos exemplos que encontrei executáveis ​​de compilação com algumas bibliotecas compartilhadas, mas nunca apenas uma biblioteca compartilhada simples. Também seria útil se alguém pudesse me dizer uma biblioteca muito simples que usa cmake, para que eu possa usar isso como um exemplo.
— Florian M
relacionada stackoverflow.com/questions/2152077/...
A mesma pergunta, mas existe uma maneira de manter minhas fontes mistas (.h ans .cpp no ​​mesmo diretório de fontes), mas permitir que o Cmake produza um diretório de inclusão, produto de seu trabalho?
Sempre especifique a versão mínima exigida do cmake
Você deve declarar um projeto. cmakediz que é obrigatória e vai definir variáveis convenientes PROJECT_NAME, PROJECT_VERSIONe PROJECT_DESCRIPTION(esta última necessitate variável cmake 3.9):
Declare um novo destino de biblioteca. Por favor, evite o uso de file(GLOB ...). Esse recurso não fornece o domínio do processo de compilação. Se você é preguiçoso, copie e cole a saída de ls -1 sources/*.cpp:
Defina a VERSIONpropriedade (opcional, mas é uma boa prática):
Você também pode definir SOVERSIONum número principal de VERSION. Então libmylib.so.1será um link simbólico para libmylib.so.1.0.0.
Declare a API pública da sua biblioteca. Essa API será instalada para o aplicativo de terceiros. É uma boa prática isolá-lo na árvore de projetos (como colocá-lo no include/diretório). Observe que cabeçalhos privados não devem ser instalados e eu sugiro colocá-los com os arquivos de origem.
Se você trabalha com subdiretórios, não é muito conveniente incluir caminhos relativos como "../include/mylib.h". Portanto, passe um diretório superior nos diretórios incluídos:
Crie uma regra de instalação para sua biblioteca. Sugiro usar variáveis CMAKE_INSTALL_*DIRdefinidas em GNUInstallDirs:
E declare os arquivos para instalar:
Você também pode exportar um pkg-configarquivo. Este arquivo permite que um aplicativo de terceiros importe facilmente sua biblioteca:
com Makefile, consulte pkg-config
com Autotools, consulte PKG_CHECK_MODULES
com cmake, veja pkg_check_modules
Crie um arquivo de modelo chamado mylib.pc.in(consulte a página de manual do pc (5) para obter mais informações):
No seu CMakeLists.txt, adicione uma regra para expandir @macros ( @ONLYpeça ao cmake para não expandir variáveis ​​do formulário ${VAR}):
E, finalmente, instale o arquivo gerado:
Você também pode usar o recurso cmakeEXPORT . No entanto, esse recurso é compatível apenas cmakee acho difícil de usar.
Finalmente, o conjunto CMakeLists.txtdeve se parecer com:
Apenas complementando a incrível explicação do @ Jezz: após todas as etapas acima, o programador pode construir e instalar a biblioteca mkdir build && cd build/ && cmake .. && sudo make install(ou sudo make install/strippara instalar a versão distribuída da biblioteca).
Você tem uma técnica para transmitir dependências da biblioteca? Por exemplo, se mylib dependesse de liblog4cxx, qual seria uma boa maneira de passar todo esse caminho para mylib.pc?
— Mpr3
@mpr Se o liblog4cxx fornecer um .pcarquivo, adicione Requires: liblog4cxxao seu mylib.pc, caso contrário, você pode simplesmente adicionar -llog4cxxao Libs:.
Como eu usaria essa biblioteca em outro projeto? Você poderia estender seu exemplo?
— Damir Porobic
E você adiciona todos os cabeçalhos a PUBLIC_HEADER ou apenas o que outros usuários devem poder ver? Caso contrário, o que você faz com todos os outros cabeçalhos?
Esse CMakeLists.txtarquivo mínimo compila uma biblioteca compartilhada simples:
No entanto, não tenho experiência em copiar arquivos para um destino diferente com o CMake. O comando file com a assinatura COPY / INSTALL parece ser útil.
CMAKE_BUILD_TYPE deve ser omitido, portanto a decisão depende de quem compila.
Não especificando ${CMAKE_CURRENT_SOURCE_DIR}/em include_directoriesé útil?
@ Jezz Acho que não, o mesmo diretório é incluído sem o prefixo. No entanto, seria importante se você estivesse em um subdiretório.
— Arnav Borborah
E se eu quiser misturar minhas fontes e meus cabeçalhos em um diretório "fonte" genérico? Existe a possibilidade de "pós-geração" de criar o diretório "cabeçalho" a partir das minhas fontes? (comandos de instalação talvez)
Estou tentando aprender como fazer isso sozinho, e parece que você pode instalar a biblioteca assim:
Primeiro, este é o layout do diretório que estou usando:
Depois de alguns dias analisando isso, esta é a minha maneira favorita de fazer isso, graças ao CMake moderno:
Após executar o CMake e instalar a biblioteca, não há necessidade de usar os arquivos Find ***. Cmake, eles podem ser usados ​​assim:
É isso, se tiver sido instalado em um diretório padrão, ele será encontrado e não será necessário fazer mais nada. Se ele foi instalado em um caminho não padrão, também é fácil, basta dizer ao CMake onde encontrar o MyLibConfig.cmake usando:
Espero que isso ajude a todos, tanto quanto me ajudou. As velhas maneiras de fazer isso eram bastante complicadas.