CMake:将头文件复制到输出目录

时间:2018-01-02 03:56:30

标签: c++ build cmake

我有一个包含c ++源文件和头文件的目录。我想创建一个CMakeLists.txt来构建它作为一个库,用于其他包含它作为子目录的CMake项目。

结构:

example/
    foo.h
    foo.cpp
    CMakeLists.txt

我遇到的问题是CMake似乎没有把foo.h放在任何地方,所以让父CMake知道如何找到头文件是骗我的。

这是我目前的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)

我不想安装。这里的想法是该库将被其他CMake项目使用,而不是整个系统。

理想情况下,foo.h将显示在构建目录中的libfoo.a旁边。

我试过把它称为“框架”,没有运气;这只是一个macOs框架。

我相信我可以陪审这个,但是那里有一个最好的做法。

打开一个答案,说“这是一个更好的方式”,也是......

更新

这可能有助于澄清我想如何将这个项目拉到另一个项目中。我见过其他项目使用过这样的东西:

add_subdirectory(<path_to_foo>/foo foo_build)

导致foo构建发生在子目录中。这允许我使用'foo_build'来引用库,它非常干净。但是,我仍然必须指向原始的include目录来获取.h文件,这让我觉得我错过了什么。

似乎cmake会为此提供一个干净的解决方案。

4 个答案:

答案 0 :(得分:1)

我对CMake相当新,但我认为你想要的是&#39; add_custom_command&#39;。

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

这可能有效。

答案 1 :(得分:1)

作为CMake的一般规则,源保存在源目录中,二进制文件和其他生成的文件位于构建目录中。所以你希望不是很好 安装项目时,CMake会根据您的意愿放置标题和库。然后,您可以指定要复制的位置。

由于您不想安装此模块,最好的方法是通过为项目提供CMake配置文件来创建包。这意味着您的项目 Foo 将生成一个文件FooConfig.cmake,其中包含包含和库的路径。另一个CMake项目将使用find_package(Foo)来查找文件。通过向Foo_DIR添加提示,您可以让CMake在非标准目录中找到您的项目。

进一步阅读:

请注意,configure_file与您的意愿无关,令人困惑的名称具有历史原因。您可以使用此命令,但本身不相关。

更新:更新后,我认为您要使用外部项目。表现得像一个内部库,但相当分离。见https://cmake.org/cmake/help/latest/module/ExternalProject.html

答案 2 :(得分:0)

你应该为你的&#34; foo&#34;使用生成器表达式。包含目录:

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

由于您不想要安装规则,因此无需添加$<INSTALL_INTERFACE:include> ...

顺便说一句,你不应该在构建目录中复制包含文件(假设你是在构建源代码之外)。

ps:如果您还生成头文件只需添加 $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>

答案 3 :(得分:0)

您要寻找的是以下结构:

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

您的CMakeList如下所示

示例/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
)

example / 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
)

通过使用foo中的项目名称target_link_libraries(...),您可以引用foo库目标

此外,通过在foo库中使用PUBLIC关键字,您的标头(您的包含目录)将自动传播到每个通过add_subdirectory(...)添加此库的CMake项目中。

因此,您无需复制标题! CMake> = 2.8.12很漂亮,不是吗?


如果您真的要通过CMake复制文件,则可以进行以下操作:

file(COPY srcDir
    DESTINATION dstDir
    FILES_MATCHING
        PATTERN .h
)

在这里看看:https://cmake.org/cmake/help/v3.2/command/file.html