How to copy directory from source tree to binary tree?

CCopyCmake

C Problem Overview


Copying directory from source tree to binary tree. For example: How to copy www to bin folder.

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

Thanks.

C Solutions


Solution 1 - C

Since version 2.8, the file command has a copy argument:

file(COPY yourDir DESTINATION yourDestination)

Note that:

> Relative input paths are evaluated with respect to the current source > directory, and a relative destination is evaluated with respect to the > current build directory

Solution 2 - C

With CMake 2.8, use the file(COPY ...) command.

With older CMake versions, this macro copies files from one directory to another. If you don't want to substitute variables in the copied files, then change the configure_file @ONLY argument (for example to 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)

Solution 3 - C

As nobody has mentioned cmake -E copy_directory as a custom target, here's what I've used:

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

Solution 4 - C

The configure command will only copy files when cmake is run. Another option is to create a new target, and use the custom_command option. Here's one that I use (if you run it more than once, you'll have to modify the add_custom_target line to make it unique for each call).

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)

Solution 5 - C

Use execute_process and call cmake -E. If you want a deep copy, you can use the copy_directory command. Even better, you could create a symlink (if your platform supports it) with the create_symlink command. The latter can be achieved like this:

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

From: http://www.cmake.org/pipermail/cmake/2009-March/028299.html

Solution 6 - C

Thank! That is really helpful advice to use bunch of add_custom_target and add_custom_command. I wrote the following function to use everywhere in my projects. Is also specifies the installation rule. I use it primarily to export interface header files.

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

Usage looks like this:

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

Solution 7 - C

Based on the answer from Seth Johnson; wrote for more convenience:

# 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()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJiang BianView Question on Stackoverflow
Solution 1 - CChtyView Answer on Stackoverflow
Solution 2 - CChin HuangView Answer on Stackoverflow
Solution 3 - CjuzzlinView Answer on Stackoverflow
Solution 4 - CSeth JohnsonView Answer on Stackoverflow
Solution 5 - CJiang BianView Answer on Stackoverflow
Solution 6 - CprokherView Answer on Stackoverflow
Solution 7 - CSalamandarView Answer on Stackoverflow