CMake: copiar o ficheiro header para a pasta de saída
tenho uma pasta com ficheiros de código C++ e header. Quero criar um Cmakelista.txt para compilar isto como uma biblioteca para usar em outros projetos do CMake que o incluem como um sub diretório.
Estrutura:
example/
foo.h
foo.cpp
CMakeLists.txt
O problema com que me deparo é que o CMake não parece colocar o foo.h em qualquer lugar, por isso fazer com que o CMake pai saiba como encontrar o ficheiro header está a enganar-me.
Aqui estão os meus actuais Cmakelistas.txt:
cmake_minimum_required(VERSION 3.8.2)
project(example)
set (CMAKE_CXX_STANDARD 11)
# add library target foo
add_library(foo STATIC foo.cpp)
# tell cmake where to find headers for it
target_include_directories(foo PUBLIC .)
# sad attempt to get it to output the header
set_target_properties(foo PROPERTIES PUBLIC_HEADER foo.h)
Não quero ter de o fazer. instalar. A idéia aqui é que a biblioteca seria usada por outros projetos do CMake, não por todo o sistema.
Idealmente, o foo.o h apareceria ao lado da libfoo.a no directório de compilação.
Tentei chamá-lo de "FRAMEWORK", sem sorte; isso só faz é um framework macOs.
Acho que posso improvisar isto, mas acho que há uma boa prática por aí.
Aberto a uma resposta que diga "aqui está uma maneira melhor", também...
Actualizar
pode ajudar a esclareça como eu acho que eu quero puxar este projeto para outro. Já vi outros projectos usarem algo assim.
add_subdirectory(<path_to_foo>/foo foo_build)
O que faz com que a construção do foo aconteça numa subdiretoria. Isto permite-me referir à biblioteca usando 'foo_build', que é agradável e limpo. No entanto, ainda tenho que apontar para o diretório de inclusão original para obter o.h file, O que me faz sentir que me está a escapar alguma coisa.
Parece que o cmake teria uma solução limpa para isto.
4 answers
Sou bastante novo no CMake, mas o que acho que queres é um 'add_custom_command'.
add_custom_command(TARGET foo.a POST_BUILD COMMAND cp foo.h ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
Isso pode funcionar.
Como regra geral para o CMake, as fontes são mantidas no directório de origem e os binários e outros ficheiros gerados estão dentro do directório de compilação. Então, o teu desejo não é nada de especial.
O CMake colocaria cabeçalhos e bibliotecas de acordo com os seus desejos quando instalar o projecto. Então você pode especificar o que copiar onde.
Como não quer instalar este módulo, a melhor maneira é criar um pacote, fornecendo um ficheiro de configuração do CMake para o seu projecto. Isto significa que o seu projecto o Foo iria gerar um ficheiro {[[0]} que contém os caminhos para incluir e bibliotecas. O outro projecto do CMake usaria find_package(Foo)
para procurar o ficheiro. Ao adicionar uma dica a Foo_DIR
, poderá fazer com que o CMake encontre o seu projecto numa pasta não-padrão.
Leitura Adicional:
Note, que configure_file
não está relacionado com o que você deseja, o nome confuso tem histórico questao. Você pode usar este comando, mas por si só não está relacionado.
Actualização: depois da actualização, acho que queres usar um projecto externo. Comporta-se como uma biblioteca interna, mas muito separada. Ver https://cmake.org/cmake/help/latest/module/ExternalProject.html
O que procura é a seguinte estrutura:
example/
- CMakeLists.txt
- src/
- main.c
- sub/
- foo/
- CMakeLists.txt
- src/
- foo/
- foo.c
- foo.h
Os seus Cmakelistas parecerão os seguintes.
Exemplo / Lista De Cmakelistas.txt
# use modern target-based cmake features
cmake_minimum_required (VERSION 3.0)
# projectname
project (ff1_selfcheck)
add_subdirectory (sub/foo)
# executable to create
add_executable(${PROJECT_NAME}
src/main.c
)
# link libraries
target_link_libraries(${PROJECT_NAME}
PRIVATE
foo # imported target
)
Exemplo / sub / foo / CMakeLists.txt
# use modern target-based cmake features
cmake_minimum_required (VERSION 3.0)
# projectname
project (foo)
# executable to create
add_library(${PROJECT_NAME}
src/foo.c
)
# directories where to search for header files
target_include_directories(${PROJECT_NAME}
PUBLIC
source # the headerfiles in source are the includes
)
Ao usar o nome do projecto foo
em target_link_libraries(...)
, Você refere-se ao alvo da biblioteca foo
Além disso, ao usar a palavra-chave PUBLIC
na biblioteca XPTO, os seus cabeçalhos (o seu directório de inclusão) são automaticamente propagados para cada projecto CMake isso adiciona esta biblioteca via add_subdirectory(...)
.
Se realmente quiser copiar ficheiros via CMake, o seguinte funcionaria:
file(COPY srcDir
DESTINATION dstDir
FILES_MATCHING
PATTERN .h
)
Dá uma vista de olhos aqui. https://cmake.org/cmake/help/v3.2/command/file.html
Deve usar a expressão do gerador para a sua pasta de inclusão" foo":
target_include_directories(foo PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR})
E como você não quer regras de instalação não precisa também adicionar um $<INSTALL_INTERFACE:include>
...
BTW você não deve se importar de copiar o arquivo de inclusão no diretório de compilação (supondo que você está construindo a partir da fonte).
Ps: se também gerar ficheiros de cabeçalhos basta adicionar $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>