CMake学习笔记(二):CMake拷贝文件夹

文章目录

一、拷贝目的

  • 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
)

附录

相关推荐
choumin17 分钟前
创建型模式——工厂方法模式
c++·设计模式·工厂方法模式·创建型模式
云小逸44 分钟前
【SVN 详细使用指南:从入门到团队协作】
c++·svn
一只小菜鸡..1 小时前
南京大学 操作系统 (JYY) 学习笔记:进程、系统调用与状态机管理
笔记·学习
DeviceHub2 小时前
硬件工程师选型笔记:ALPS RK12L1230C0K 与 Tonevee RK12L1230C0K 电位器 PIN TO PIN 评估指南
笔记
whyTeaFo2 小时前
GAMES101: Lecture 13: Ray Tracing 1 (Whitted-Style Ray Tracing) ppt笔记
笔记
天国梦5 小时前
2026英语教学系统选型实战:AI如何让备课效率提升42%?天学网技术落地全解析
人工智能·学习
维克兜率天5 小时前
【维克】大数定律与中心极限定理:为什么长期均值终将回归?
经验分享·学习·金融·概率论
中微极客5 小时前
降维算法75倍加速:从PCA到稀疏字典学习的工程实践
人工智能·学习·算法
ziguo11226 小时前
深入浅出 C/C++ 数据类型:从入门到踩坑
linux·c语言·c++·windows·visual studio
白色冰激凌6 小时前
[SECS/GEM研究] (三)SECS-I 串口上消息怎么分块和重传
c++·secs/gem