文章目录
一、拷贝目的
- cmake项目,需要将源路径下的某个文件夹拷贝至编译路径,在本文中该文件夹为Image
- 推荐方法5,函数封装,增量拷贝。
- 列出的方法均已测试,若有疏漏或不合理之处,还请见谅。
二、拷贝方法
方法1:使用file()拷贝
-
该拷贝在CMake配置阶段立即执行,不会在每次构建时候重写拷贝
file(COPY {CMAKE_SOURCE_DIR}/Image DESTINATION {CMAKE_BINARY_DIR}
)
方法2:使用add_custom_target()拷贝(全量拷贝文件夹)
-
拷贝整个文件夹,构建时执行(每次构建全量复制)
ALL表示此目标包含在默认构建目录,每次构建都会自动执行
add_custom_target(Image_Copy ALL
COMMAND {CMAKE_COMMAND} -E make_directory COMMAND {CMAKE_COMMAND} -E copy_directory
{CMAKE_SOURCE_DIR}/Image {CMAKE_BINARY_DIR}/Image
COMMENT "Copying configuration files..."
)确保主项目依赖此拷贝目标
add_dependencies(${PROJECT_NAME} Image_Copy)
方法3:使用add_custom_target()拷贝(增量拷贝文件夹所有文件)
-
拷贝Image文件夹下所有文件(构建时为若文件有变化再拷贝,会破坏子目录结构)
file(GLOB_RECURSE IMAGE_FILES {CMAKE_SOURCE_DIR}/Image/*) message(STATUS {IMAGE_FILES})
ALL表示此目标包含在默认构建目录,每次构建都会自动执行
add_custom_target(Image_Copy ALL
COMMAND {CMAKE_COMMAND} -E make_directory {CMAKE_BINARY_DIR}/Image
COMMAND {CMAKE_COMMAND} -E copy_if_different {IMAGE_FILES}
${CMAKE_BINARY_DIR}/Image
COMMENT "Copying jpg image files..."
)确保主项目依赖此拷贝目标
add_dependencies(${PROJECT_NAME} Image_Copy)
方法4:使用add_custom_command()拷贝
-
动态拷贝多级目录,增量构建时仅拷贝修改过的文件
获取所有文件(相对路径)
file(GLOB_RECURSE IMAGE_FILES RELATIVE ${CMAKE_SOURCE_DIR} "Image/*")
创建目标目录
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Image)
收集所有目标文件的路径
set(TARGET_FILES "")
add_custom_command生成的命令默认仅在显式请求时执行(如通过add_custom_target或作为其他目标的依赖)。若未建立依赖关系,命令不会自动运行。
foreach(FILE ${IMAGE_FILES})
# 源文件和目标文件的完整路径 set(SRC_FILE ${CMAKE_SOURCE_DIR}/${FILE}) set(DST_FILE ${CMAKE_BINARY_DIR}/${FILE}) # 添加到目标文件列表 list(APPEND TARGET_FILES ${DST_FILE}) # 获取目标文件所在目录 get_filename_component(DST_DIR ${DST_FILE} DIRECTORY) # 为每个文件创建复制命令 add_custom_command( OUTPUT ${DST_FILE} COMMAND ${CMAKE_COMMAND} -E make_directory ${DST_DIR} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SRC_FILE} ${DST_FILE} DEPENDS ${SRC_FILE} COMMENT "Copying ${FILE}" )endforeach()
创建依赖所有目标文件的自定义目标
add_custom_target(Image_Copy ALL DEPENDS ${TARGET_FILES})
方法5:使用add_custom_command()拷贝(封装为函数)
# 定义复制目录的函数
function(copy_directory_incremental COPY_NAME SRC_DIR DST_DIR)
file(GLOB_RECURSE FILES RELATIVE ${SRC_DIR} "${SRC_DIR}/*")
set(TARGET_FILES "")
foreach(FILE ${FILES})
set(SRC_FILE ${SRC_DIR}/${FILE})
set(DST_FILE ${DST_DIR}/${FILE})
list(APPEND TARGET_FILES ${DST_FILE})
get_filename_component(FILE_DIR ${DST_FILE} DIRECTORY)
add_custom_command(
OUTPUT ${DST_FILE}
COMMAND ${CMAKE_COMMAND} -E make_directory ${FILE_DIR}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SRC_FILE} ${DST_FILE}
DEPENDS ${SRC_FILE}
COMMENT "Copying ${FILE}"
)
endforeach()
add_custom_target(${COPY_NAME} ALL DEPENDS ${TARGET_FILES})
endfunction()
# 使用函数
copy_directory_incremental(
"Copy_Image"
${CMAKE_SOURCE_DIR}/Image
${CMAKE_BINARY_DIR}/Image
)