首页 > 解决方案 > CMake:用于复制与模式匹配的文件并保留目录结构的自定义命令

问题描述

我有以下项目布局:

project/
├─ CMakeLists.txt
├─ main.cpp
╘═ my_lib/
   ├─ CMakeLists.txt
   ╞═ some_package1/
   │  ├── header.hpp
   │  └── impl.cpp
   ╘═ some_package2/
      ├── header.hpp
      └── impl.cpp

my_libCMakeLists.txtfrom添加为子目录project
我想要的是一个目标,在my_lib CMakeLists.txt其中构建时,执行一个命令,将所有标题复制my_lib到目标目录,同时保留目录结构。目标目录将由project CMakeLists.txt.

基本上,如果我能以某种方式add_custom_command做到这一点:

file(COPY ${CMAKE_SOURCE_DIR}/my_lib DESTINATION ${COPY_DEST_DIR} FILES_MATCHING PATTERN "*.hpp")

我会非常高兴。但我还没有找到一种方法来做到这一点。这与安装目标非常相似,除了我需要在编译之前完成它。

我尝试执行以下操作:

set(MY_LIB_HEADER_FILES
    some_package1/header.hpp
    some_package2/header.hpp
)

add_custom_target(copy_headers)
add_custom_command(
    TARGET copy_headers
    COMMAND ${CMAKE_COMMAND} -E copy "${MY_LIB_HEADER_FILES}" ${COPY_DEST_DIR}
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/my_lib
)

但这不会保留目录结构,仅在本例中,这将导致一个标头被另一个标头覆盖。我一直无法找到解决方法。

我能想象的唯一解决方案是一个 hack,在其中我循环遍历 中的每个文件${MY_LIB_HEADER_FILES},删除最后一个正斜杠后面的任何内容,创建该目录,然后将文件复制到它。但这真的不是我想诉诸并想到的事情,考虑到必须在add_custom_command电话中完成,我什至不确定我将如何去做。

肯定有解决办法吧?

标签: cmake

解决方案


实现此目的的方法之一是编写一个“CMake 脚本”文件,该文件将包含您的file(COPY ....)命令并在add_custom_command. 简而言之,您的代码片段如下所示:

#create script file during configure phase...
file(WRITE ${CMAKE_BINARY_DIR}/cp.cmake
  "file(COPY ${CMAKE_SOURCE_DIR}/my_lib DESTINATION ${COPY_DEST_DIR} FILES_MATCHING PATTERN *.hpp)\n"
)

#execute the script during the build phase...
add_custom_command(
  TARGET my_lib
  POST_BUILD
  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cp.cmake
)

file(WRITE ....语句将在名为的根构建文件夹中创建一个新的 cmake 脚本文件cp.cmake

注 1:$前面的变量CMAKE_SOURCE_DIRCOPY_DEST_DIR没有转义,意味着cp.cmake将包含它们的评估值。

注意 2:假设您的库创建了一个名为的目标my_lib,并add_custom_command作为POST_BUILD该目标的事件添加。

最后,这里是关于add_custom_command文件命令在脚本模式下运行 CMake的 cmake 文档


推荐阅读