CMake v3.13.4中install()函数FILES_MATCHING参数使用问题咨询
解决CMake install()函数的两个问题:子目录复制与多后缀匹配
一、为什么子文件夹会被一并复制?
当你使用install(DIRECTORY)时,CMake的默认行为是保留源目录的目录结构——哪怕你加了FILES_MATCHING PATTERN,它也会复制那些包含匹配文件的子目录(空目录不会被复制,但有符合条件文件的子目录会被完整带过去)。
如果你想要的是仅复制当前目录下的匹配文件,完全不包含任何子文件夹,有两种解决方案:
方案1:用file(GLOB)收集文件 + install(FILES)
这种方式更直观,专门用于复制单个目录下的指定文件:
# 收集当前目录下所有.cfg文件 file(GLOB CFG_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cfg") # 安装到目标路径 install(FILES ${CFG_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX})
方案2:在install(DIRECTORY)中排除子目录
如果你坚持要用install(DIRECTORY),可以通过添加PATTERN "*/" EXCLUDE来排除所有子目录:
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.cfg" PATTERN "*/" EXCLUDE) # 匹配所有子目录并排除
二、如何实现多文件后缀的匹配?
CMake的PATTERN不支持*.cfg | *.xyz这种管道符写法,正确的做法是添加多个PATTERN指令,CMake会自动按逻辑或(OR)处理这些规则。
示例1:仅复制当前目录下的.cfg和.xyz文件
file(GLOB TARGET_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cfg" "${CMAKE_CURRENT_SOURCE_DIR}/*.xyz") install(FILES ${TARGET_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX})
示例2:保留目录结构,复制所有目录下的.cfg和.xyz文件
如果需要包含子目录里的目标文件,同时保留结构:
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.cfg" PATTERN "*.xyz")
三、关于你尝试的REGEX问题
你之前写的正则"[a-zA-Z0-9]*.ate|[a-zA-Z0-9]*.reserved"有两个问题:
- 正则语法错误:
.在正则中是匹配任意字符的通配符,要匹配实际的点号必须转义(写成\\.);另外没有用$锚定结尾,可能导致匹配到不符合预期的字符串。 - 未排除子目录:和之前的问题一样,没有排除子目录的话,包含匹配文件的子文件夹会被复制。
修正后的REGEX写法:
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING REGEX ".*\\.ate$|.*\\.reserved$" # 匹配以.ate或.reserved结尾的文件 PATTERN "*/" EXCLUDE) # 排除所有子目录
内容的提问来源于stack exchange,提问作者HFinch
相关产品推荐
相关产品推荐

