cmake - CMake:用于复制与模式匹配的文件并保留目录结构的自定义命令
问题描述
我有以下项目布局:
project/
├─ CMakeLists.txt
├─ main.cpp
╘═ my_lib/
├─ CMakeLists.txt
╞═ some_package1/
│ ├── header.hpp
│ └── impl.cpp
╘═ some_package2/
├── header.hpp
└── impl.cpp
my_lib
由CMakeLists.txt
from添加为子目录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 脚本”文件,该文件将包含您的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_DIR
和COPY_DEST_DIR
没有转义,这意味着cp.cmake
将包含它们的评估值。
注意 2:假设您的库创建了一个名为的目标my_lib
,并add_custom_command
作为POST_BUILD
该目标的事件添加。
推荐阅读
- angular - 如何实例化平台(@ionic/angular)对象
- git - 克隆私有存储库wsl
- javascript - 我将如何有效地过滤这个 JavaScript 对象?
- iis - 如何配置 IIS 以防止点击劫持并通过 DAST 扫描?
- pandas - 如何在 Pandas DataFrame 中确定给定 x 和 y 坐标列的象限
- ios - 快速设置和观察数据时出错
- tableau-desktop - 如何在 Tableau 中创建表示特定时间段内数据集平均值的列,同时排除周末?
- python - 在 Python 中操作数据框
- vue.js - Vue.js npm 链接问题
- java - Tic Tac Toe 运行和功能完全,但在连续获得 3 之后,必须再次移动它才能结束