summaryrefslogtreecommitdiffstats
path: root/Modules/ExternalData.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/ExternalData.cmake')
-rw-r--r--Modules/ExternalData.cmake76
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()