CMake:将头文件复制到输出目录 我有一个带有C++源代码和头文件的目录。我想创建一个CMakeLists.txt,将其构建为一个库,用于其他将其作为子目录包含的CMake项目

CMake:将头文件复制到输出目录 我有一个带有C++源代码和头文件的目录。我想创建一个CMakeLists.txt,将其构建为一个库,用于其他将其作为子目录包含的CMake项目,c++,build,cmake,C++,Build,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_librar

结构:

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将显示在build目录中libfoo.a的旁边

我试着称之为“框架”,运气不好;这只是一个macOs框架

我相信我能操纵这个,但我认为有一个最佳实践

开放的回答说:“这里有一个更好的方式”,太

更新

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

add_subdirectory(<path_to_foo>/foo foo_build)
add_子目录(/foo-foo_-build)
这会导致foo构建发生在子目录中。这使我能够使用“foo_build”来引用库,它很好而且干净。但是,我仍然必须指向原始的include目录才能获得.h文件,这让我觉得我遗漏了一些东西


似乎cmake会有一个干净的解决方案。

我对cmake还很陌生,但我想你想要的是一个“”


这可能有用。

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

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

进一步阅读:

请注意,
configure_file
与您想要的内容无关,令人困惑的名称有其历史原因。您可以使用此命令,但本质上它是不相关的


更新:更新后,我认为您希望使用外部项目。其行为类似于内部库,但非常分离。请参见

您应该为“foo”include目录使用生成器表达式:

target_include_directories(foo PUBLIC 
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR})
target\u include\u目录(foo PUBLIC

$您要查找的是以下结构:

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
)
# 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
)
example/sub/foo/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
)
# 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
)
通过在
target\u link\u库(…)
中使用项目名称
foo
,可以引用foo库目标

此外,通过使用foo库中的
PUBLIC
关键字,您的头(include目录)将自动传播到每个通过
add_子目录(…)
添加此库的CMake项目

所以你不需要复制你的头!CMake>=2.8.12很漂亮,不是吗


如果您真的想通过CMake复制文件,以下操作将起作用:

file(COPY srcDir
    DESTINATION dstDir
    FILES_MATCHING
        PATTERN .h
)


查看此处:

注意:要强制C++11,您还需要更好地将其添加为目标属性,以便在需要时转发此要求……谢谢,这非常有用。我更新了原始帖子,以澄清我想寻找的内容,它肯定应该是cmake-y。我不只是试图快速修复;这是我所理解的更好。@JimBaldwin I.相应地更新了我的答案。