diff options
Diffstat (limited to 'Modules/ExternalData.cmake')
-rw-r--r-- | Modules/ExternalData.cmake | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake index a0bffe7..e7f8408 100644 --- a/Modules/ExternalData.cmake +++ b/Modules/ExternalData.cmake @@ -86,6 +86,10 @@ Module Functions in one of the paths specified in the ``ExternalData_OBJECT_STORES`` variable. + Typically only one target is needed to manage all external data within + a project. Call this function once at the end of configuration after + all data references have been processed. + Module Variables ^^^^^^^^^^^^^^^^ @@ -394,8 +398,14 @@ function(ExternalData_add_target target) set(files "") - # Set "_ExternalData_FILE_${file}" for each output file to avoid duplicate - # rules. Use local data first to prefer real files over content links. + # Set a "_ExternalData_FILE_${file}" variable for each output file to avoid + # duplicate entries within this target. Set a directory property of the same + # name to avoid repeating custom commands with the same output in this directory. + # Repeating custom commands with the same output across directories or across + # targets in the same directory may be a race, but this is likely okay because + # we use atomic replacement of output files. + # + # Use local data first to prefer real files over content links. # Custom commands to copy or link local data. get_property(data_local GLOBAL PROPERTY _ExternalData_${target}_LOCAL) @@ -405,16 +415,20 @@ function(ExternalData_add_target target) list(GET tuple 1 name) if(NOT DEFINED "_ExternalData_FILE_${file}") set("_ExternalData_FILE_${file}" 1) - add_custom_command( - COMMENT "Generating ${file}" - OUTPUT "${file}" - COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR} - -Dfile=${file} -Dname=${name} - -DExternalData_ACTION=local - -DExternalData_CONFIG=${config} - -P ${_ExternalData_SELF} - MAIN_DEPENDENCY "${name}" - ) + get_property(added DIRECTORY PROPERTY "_ExternalData_FILE_${file}") + if(NOT added) + set_property(DIRECTORY PROPERTY "_ExternalData_FILE_${file}" 1) + add_custom_command( + COMMENT "Generating ${file}" + OUTPUT "${file}" + COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR} + -Dfile=${file} -Dname=${name} + -DExternalData_ACTION=local + -DExternalData_CONFIG=${config} + -P ${_ExternalData_SELF} + MAIN_DEPENDENCY "${name}" + ) + endif() list(APPEND files "${file}") endif() endforeach() @@ -429,23 +443,27 @@ function(ExternalData_add_target target) set(stamp "${ext}-stamp") if(NOT DEFINED "_ExternalData_FILE_${file}") set("_ExternalData_FILE_${file}" 1) - add_custom_command( - # Users care about the data file, so hide the hash/timestamp file. - COMMENT "Generating ${file}" - # The hash/timestamp file is the output from the build perspective. - # List the real file as a second output in case it is a broken link. - # The files must be listed in this order so CMake can hide from the - # make tool that a symlink target may not be newer than the input. - OUTPUT "${file}${stamp}" "${file}" - # Run the data fetch/update script. - COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR} - -Dfile=${file} -Dname=${name} -Dext=${ext} - -DExternalData_ACTION=fetch - -DExternalData_CONFIG=${config} - -P ${_ExternalData_SELF} - # Update whenever the object hash changes. - MAIN_DEPENDENCY "${name}${ext}" - ) + get_property(added DIRECTORY PROPERTY "_ExternalData_FILE_${file}") + if(NOT added) + set_property(DIRECTORY PROPERTY "_ExternalData_FILE_${file}" 1) + add_custom_command( + # Users care about the data file, so hide the hash/timestamp file. + COMMENT "Generating ${file}" + # The hash/timestamp file is the output from the build perspective. + # List the real file as a second output in case it is a broken link. + # The files must be listed in this order so CMake can hide from the + # make tool that a symlink target may not be newer than the input. + OUTPUT "${file}${stamp}" "${file}" + # Run the data fetch/update script. + COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR} + -Dfile=${file} -Dname=${name} -Dext=${ext} + -DExternalData_ACTION=fetch + -DExternalData_CONFIG=${config} + -P ${_ExternalData_SELF} + # Update whenever the object hash changes. + MAIN_DEPENDENCY "${name}${ext}" + ) + endif() list(APPEND files "${file}${stamp}") endif() endforeach() |