【问题标题】:How to copy directory from source tree to binary tree?如何将目录从源树复制到二叉树?
【发布时间】:2010-10-16 09:39:24
【问题描述】:

将目录从源代码树复制到二叉树。例如:如何将 www 复制到 bin 文件夹。

work
├─bin
└─src
    ├─doing
    │  └─www
    ├─include
    └─lib

谢谢。

【问题讨论】:

    标签: c copy cmake


    【解决方案1】:

    从 2.8 版开始,file command 有一个复制参数:

    file(COPY yourDir DESTINATION yourDestination)
    

    注意:

    相对输入路径相对于当前源进行评估 目录,并相对于 当前构建目录

    【讨论】:

    • 这看起来很有希望。你能解释一下你是如何触发它的,还是每次都运行?
    • 它只在运行 cmake 命令时有效,在实际构建时无效
    • 如果我想检查目录是否已经存在于目的地怎么办?
    【解决方案2】:

    对于 CMake 2.8,使用 file(COPY ...) 命令。

    对于较旧的 CMake 版本,此宏将文件从一个目录复制到另一个目录。如果您不想替换复制文件中的变量,请更改 configure_file @ONLY 参数(例如更改为 COPYONLY)。

    # Copy files from source directory to destination directory, substituting any
    # variables.  Create destination directory if it does not exist.
    
    macro(configure_files srcDir destDir)
        message(STATUS "Configuring directory ${destDir}")
        make_directory(${destDir})
    
        file(GLOB templateFiles RELATIVE ${srcDir} ${srcDir}/*)
        foreach(templateFile ${templateFiles})
            set(srcTemplatePath ${srcDir}/${templateFile})
            if(NOT IS_DIRECTORY ${srcTemplatePath})
                message(STATUS "Configuring file ${templateFile}")
                configure_file(
                        ${srcTemplatePath}
                        ${destDir}/${templateFile}
                        @ONLY)
            endif(NOT IS_DIRECTORY ${srcTemplatePath})
        endforeach(templateFile)
    endmacro(configure_files)
    

    【讨论】:

    • 使用 cmake -E 模式可以轻松复制文件或目录。非常感谢
    • 已编辑,因为这是已接受的答案和文件的另一个答案(COPY 命令更清晰。
    • 是的,但是您可以将 file(COPY...) 作为依赖于目标的自定义命令运行吗?
    • 子目录的文件(GLOB_RECURSE ..)
    【解决方案3】:

    由于没有人提到 cmake -E copy_directory 作为自定义目标,我使用了以下内容:

    add_custom_target(copy-runtime-files ALL
        COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/runtime-files-dir ${CMAKE_BINARY_DIR}/runtime-files-dir
        DEPENDS ${MY_TARGET})
    

    【讨论】:

    • 简短易懂,很棒。如果你放弃DEPENDS ${MY_TARGET},它可以与编译过程并行运行。请记住,每次make 运行时都会复制文件,因此对于非常大的文件夹可能会有限制。
    • 我收到Expected a command name, got unquoted argument with text "/runtime-files-dir". :(
    • 这是我的首选解决方案,因为它适用于 $
    【解决方案4】:

    configure 命令只会在cmake 运行时复制文件。另一种选择是创建一个新目标,并使用 custom_command 选项。这是我使用的一个(如果您多次运行它,则必须修改 add_custom_target 行以使其对每个调用都是唯一的)。

    macro(copy_files GLOBPAT DESTINATION)
      file(GLOB COPY_FILES
        RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
        ${GLOBPAT})
      add_custom_target(copy ALL
        COMMENT "Copying files: ${GLOBPAT}")
    
      foreach(FILENAME ${COPY_FILES})
        set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
        set(DST "${DESTINATION}/${FILENAME}")
    
        add_custom_command(
          TARGET copy
          COMMAND ${CMAKE_COMMAND} -E copy ${SRC} ${DST}
          )
      endforeach(FILENAME)
    endmacro(copy_files)
    

    【讨论】:

    • 我调整了您的(惊人的)答案,使其具有更加模块化的脚本。看我的回答!
    • 请注意,这个(现在已经十岁了!!)答案早于 CMake 中的生成器表达式以及 copy_directory 命令。
    【解决方案5】:

    使用 execute_process 并调用 cmake -E。如果你想要一个深拷贝,你可以使用copy_directory 命令。更好的是,您可以使用 create_symlink 命令创建 symlink(如果您的平台支持)。后者可以这样实现:

    execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/path/to/www
                                                               ${CMAKE_BINARY_DIR}/path/to/www)
    

    发件人:http://www.cmake.org/pipermail/cmake/2009-March/028299.html

    【讨论】:

    • 唯一的问题是,如果在目录中生成临时文件,它会破坏源外构建的概念。
    【解决方案6】:

    谢谢!这是使用一堆 add_custom_target 和 add_custom_command 的真正有用的建议。我编写了以下函数以在我的项目中随处使用。也是指定安装规则。我主要用它来导出接口头文件。

    #
    # export file: copy it to the build tree on every build invocation and add rule for installation
    #
    function    (cm_export_file FILE DEST)
      if    (NOT TARGET export-files)
        add_custom_target(export-files ALL COMMENT "Exporting files into build tree")
      endif (NOT TARGET export-files)
      get_filename_component(FILENAME "${FILE}" NAME)
      add_custom_command(TARGET export-files COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${DEST}/${FILENAME}")
      install(FILES "${FILE}" DESTINATION "${DEST}")
    endfunction (cm_export_file)
    

    用法如下:

    cm_export_file("API/someHeader0.hpp" "include/API/")
    cm_export_file("API/someHeader1.hpp" "include/API/")
    

    【讨论】:

    • 这看起来很有趣。它可以复制整个目录吗?
    【解决方案7】:

    基于赛斯约翰逊的回答;为了更方便而写的:

    # Copy files
    macro(resource_files files)
        foreach(file ${files})
            message(STATUS "Copying resource ${file}")
            file(COPY ${file} DESTINATION ${Work_Directory})
        endforeach()
    endmacro()
    
    # Copy directories
    macro(resource_dirs dirs)
        foreach(dir ${dirs})
            # Replace / at the end of the path (copy dir content VS copy dir)
            string(REGEX REPLACE "/+$" "" dirclean "${dir}")
            message(STATUS "Copying resource ${dirclean}")
            file(COPY ${dirclean} DESTINATION ${Work_Directory})
        endforeach()
    endmacro()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      相关资源
      最近更新 更多