0

Let's say we have a project like this:

foo
+-bar
+ +-header.h    <-- copy if updated
+-baz
+ +-header.h    <-- copy if updated
+-wibble
+ +-ni
+   +-header.h  <-- copy if updated
target
+-header.h      <-- to here

We have three possible candidates for header.h, but one final location; we're not using symbolic links for reasons. Note that there are actually around 350 header files with just a few duplicates, so listing each individually is troublesome, especially if these subdirectories update their header files. Currently, we do this unconditional copy:

file(glob_recurse HEADERS foo/*.h)
file(COPY ${HEADERS} DESTINATION target)

However, this rule only runs when we do a CMake rebuild and not when only header files change, so I would like to get this working for header file changes alone.

Now, looking at this answer I try something like this:

file(glob_recurse HEADERS foo/*.h)
foreach(file_i ${HEADERS})
    get_filename_component(barename, ${file_i} NAME)
    add_custom_command(
        OUTPUT target/${barename}
        COMMAND ${CMAKE_COMMAND}
            ARGS -E copy ${file_i} target
    )
endforeach( file_i )

However, CMake complains with the error:

CMake Error: Attempt to add a custom rule to output "target/header.h" which already has a custom rule.

I understand why I get the error, but I cannot think of any way to do what I want to do.

Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
  • "However, this rule only runs when we do a CMake rebuild and not when only header files change" - You may add *configure-time dependency* on a file with `configure_file( COPYONLY)`. Such way, `cmake` will be rerun every time when `` has been changed. – Tsyvarev Jun 18 '18 at 07:57
  • If you want to update target header with `add_custom_command`, you need to use it only once, and *DEPENDS* on **all three headers**. Within the *COMMAND* you need to implement a logic of "selective update": what to do, if only one of three files has been changed; what to do, if 2 of 3 files has been changed; what to do if all 3 files has been changed. You may use *script mode* (`cmake -P script.cmake`) for make the algorithm to be cross-platform. E.g., in a CMake script you may use `file(TIMESTAMP)` for extract modification time of the file. – Tsyvarev Jun 18 '18 at 08:04

0 Answers0