我有一个包含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会为此提供一个干净的解决方案。
答案 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
)