Вопрос:

CMake: copy header file to output directory

c++ build cmake

2471 просмотра

4 ответа

2817 Репутация автора

I have a directory with c++ source and header files. I want to create a CMakeLists.txt to build this as a library for use in other CMake projects that include it as a sub directory.

Structure:

example/
    foo.h
    foo.cpp
    CMakeLists.txt

The problem I run into is CMake doesn't seem to put foo.h anywhere, so getting the parent CMake to know how to find the header file is beguiling me.

Here's my current CMakeLists.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)

I DON'T want to have to do install. The idea here is that the library would be used by other CMake projects, not by the entire system.

Ideally, the foo.h would show up next to libfoo.a in the build directory.

I've tried calling it a "FRAMEWORK", no luck; that only makes is a macOs framework.

I believe I can jury rig this, but methinks there's a best practice out there.

Открой для ответа, который говорит, что "здесь лучший путь", также ...

ОБНОВИТЬ

Это может помочь уточнить, как я думаю, что я хочу перетащить этот проект в другой. Я видел, как другие проекты используют что-то вроде этого:

add_subdirectory(<path_to_foo>/foo foo_build)

что вызывает сборку foo в подкаталоге. Это позволяет мне ссылаться на библиотеку, используя 'foo_build', которая хороша и чиста. Тем не менее, я все еще должен указать на исходный каталог include, чтобы получить файл .h, что заставляет меня чувствовать, что я что-то упустил.

Кажется, что у cmake было бы чистое решение для этого.

Автор: Jim B. Источник Размещён: 02.01.2018 03:56

Ответы (4)


1 плюс

1008 Репутация автора

Я довольно новичок в CMake, но я думаю, что вы хотите добавить add_custom_command .

add_custom_command(TARGET foo.a POST_BUILD COMMAND cp foo.h ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})

Это может сработать.

Автор: natersoz Размещён: 02.01.2018 05:34

1 плюс

11357 Репутация автора

Как правило для CMake, исходники хранятся в каталоге исходных файлов, а двоичные файлы и другие сгенерированные файлы находятся в каталоге сборки. Таким образом, вы хотите не очень CMake-иш.
CMake установит заголовки и библиотеки в соответствии с вашими пожеланиями при установке проекта. Затем вы можете указать, что копировать куда.

Поскольку вы не хотите устанавливать этот модуль, лучший способ - создать пакет, предоставив конфигурационный файл CMake для вашего проекта. Это означает, что ваш проект Foo сгенерирует файл, FooConfig.cmakeсодержащий пути к файлам и библиотекам. Другой проект CMake будет использовать find_package(Foo)для поиска файла. Добавив подсказку, Foo_DIRвы можете заставить CMake найти ваш проект в нестандартной директории.

Дальнейшее чтение:

Обратите внимание, что configure_fileэто не имеет отношения к тому, что вы хотите, запутанное имя имеет исторические причины. Вы можете использовать эту команду, но по сути она не связана.

ОБНОВЛЕНИЕ: после обновления я думаю, что вы хотите использовать внешний проект. Ведёт себя как внутренняя библиотека, но довольно разобщённая. См. Https://cmake.org/cmake/help/latest/module/ExternalProject.html.

Автор: usr1234567 Размещён: 02.01.2018 09:19

0 плюса

1148 Репутация автора

Вы должны использовать выражение генератора для вашей директории "foo":

target_include_directories(foo PUBLIC 
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR})

А так как вы не хотите устанавливать правила, не нужно также добавлять $<INSTALL_INTERFACE:include>...

Кстати, вам не нужно копировать включаемый файл в директорию сборки (предположим, что вы строите из исходного кода).

PS: если вы также генерируете заголовочные файлы, просто добавьте $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>

Автор: Mizux Размещён: 02.01.2018 12:38

0 плюса

163 Репутация автора

То, что вы ищете, это следующая структура:

example/
- CMakeLists.txt
- src/
  - main.c
- sub/
  - foo/
    - CMakeLists.txt
    - src/
      - foo/
        - foo.c
        - foo.h

Ваши CMakeLists будут выглядеть следующим образом

Пример / CMakeLists.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
)

Пример / суб / 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
)

Используя имя проекта fooв target_link_libraries(...)ссылке на целевую библиотеке Foo

Кроме того, используя PUBLICключевое слово в библиотеке foo, ваши заголовки (ваш каталог include) автоматически распространяются на каждый проект CMake, через который эта библиотека добавляется add_subdirectory(...).

Поэтому вам не нужно копировать ваши заголовки! CMake> = 2.8.12 красиво, не правда ли?


Если вы действительно хотите копировать файлы через CMake, сработает следующее:

file(COPY srcDir
    DESTINATION dstDir
    FILES_MATCHING
        PATTERN .h
)

Посмотрите здесь: https://cmake.org/cmake/help/v3.2/command/file.html

Автор: ataraxis Размещён: 19.01.2019 02:31
Вопросы из категории :
32x32