[CMake] copy_if_different on build

Skippy VonDrake skippyvondrake at gmail.com
Wed Apr 17 12:41:53 EDT 2013


> believe what you want is:
>
>  add_custom_command(
>     OUTPUT "${output}"
>     DEPENDS "${input}"
>     COMMAND ${CMAKE_COMMAND} -E copy
>             "${input}" "${output}"
>
> ...which is roughly equivalent to a Makefile rule like:
>
> output: input
>   cp input output
>
> IOW, the file "${output}" depends on the file "${input}" (so the target will
> only run when "${input}" is newer than "${output}"), and will be created by
> copying "${input}" to "${output}" (using 'cmake -E' for portability).
>
> Don't forget to have an actual target depend on "${output}" :-). (Probably
> you are using it as a source file for a library or executable, so there is
> no problem.)
>
> You may also want to use 'copy_if_different' instead of just 'copy', which
> won't change the time stamp of "${output}" if the contents are the same as
> "${input}". On the plus side, this means that large targets depending on
> "${output}" won't be needlessly rebuilt/relinked. On the down side, the
> copy_if_different will remain out of date, and as a result still think it
> needs to run after a successful build.

Thought I understood this - but alas my implementation is wrong.

Here's my test case with a top-level cmake file and 3 subdirectories:
'src', 'bin' and 'outdir'.

Top level CMakeLists.txt
   cmake_minimum_required (VERSION 2.8)
   project (copyFile)
   set (TARGETNAME fooCopy)
   set (TARGETDEST ${PROJECT_SOURCE_DIR}/bin)
   add_subdirectory (src)

src/CMakeLists.txt
   add_executable (${TARGETNAME} 	main.cpp)
   set (input  ${CMAKE_CURRENT_SOURCE_DIR}/bin/config.cfg)
   set (output ${CMAKE_CURRENT_SOURCE_DIR}/outdir/config.cfg)

   add_dependencies(${TARGETNAME}  ${output})

   add_custom_command(
       OUTPUT "${output}"
       DEPENDS "${input}"
       COMMAND ${CMAKE_COMMAND} -E copy_if_different
		"${input}" "${output}"
   )

   install (TARGETS ${TARGETNAME} DESTINATION ${TARGETDEST})

The config file (config.cfg) is just some text and cpp file is just a
"hello world"
example.

Since the config file is not source included as a dependency in the
add_executable command, I assume my problem is making the target
properly depend on it? Specifically ${TARGETNAME} should depend
on "${output}"?

-Skippy


More information about the CMake mailing list