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.

Author: Jim B., 2018-01-02

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.
 3
Author: natersoz, 2018-01-02 05:34:30

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

 1
Author: usr1234567, 2018-01-02 18:14:53

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(...).

Por isso não precisas de copiar os teus cabeçalhos! CMake > = 2.8.12 é lindo, não é?

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
 1
Author: ataraxis, 2019-01-19 02:37:22

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}>

 0
Author: Mizux, 2019-05-16 11:57:23