update_directory command for CMake

CMake offers several platform independent commands for manipulating files that are used often in the custom build commands. (For more details see Command-Line Tool Mode.)

One of the more useful ones is the copy_directory that is commonly used in post-build step to copy configuration and support files (configs, DLLs, …) to the binary directory so program can be directly executed in a IDE or debugger.
Unfortunately this command always overwrites the contents of the destination directory so all changes in the target folder are lost, this is a problem when developer wants to keep local configuration changes during development.

Here is how you can implement a custom update_directory that works exactly like copy_directory but writes files to the destination folder only if they are missing or the file timestamp is older.

# cmake/update_directory.cmake
file(GLOB_RECURSE _file_list RELATIVE "${src_dir}" "${src_dir}/*")

foreach( each_file ${_file_list} )
  set(destinationfile "${dst_dir}/${each_file}")
  set(sourcefile "${src_dir}/${each_file}")
  if(NOT EXISTS ${destinationfile} OR ${sourcefile} IS_NEWER_THAN ${destinationfile})
    get_filename_component(destinationdir ${destinationfile} DIRECTORY)
    file(COPY ${sourcefile} DESTINATION ${destinationdir})
  endif()
endforeach(each_file)

This is how you might use it in CMakeLists.txt

# Example CMakeLists.txt
cmake_minimum_required(VERSION 3.7.0)
project(Dummy)

set(_target Dummy)
add_executable(${_target} src/dummy.c)

set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/configs")
set(dest_dir "$<TARGET_FILE_DIR:${_target}>")

# Copy changed files from config to the binary folder after
# a successful build
add_custom_command(TARGET ${_target}
  POST_BUILD
  COMMAND ${CMAKE_COMMAND}
    -Dsrc_dir="${source_dir}"
    -Ddst_dir="${dest_dir}"
    -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/update_directory.cmake"
)

Caveat! CMake post build steps are executed only if the build is really needed, if target is up to date no command is executed.

Get full example from https://github.com/tikonen/blog/tree/master/cmake/update_directory

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: