[Cmake-commits] CMake branch, next, updated. v3.6.1-1870-g11d249a
Brad King
brad.king at kitware.com
Wed Sep 7 15:18:20 EDT 2016
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".
The branch, next has been updated
via 11d249a583a14be654790ab6c8ecc5814018b2a4 (commit)
via f9973166e82c3f5d8e05e2ab57aceb15ff267295 (commit)
from 5a9e906925cf7a4512fa8765be35b0d15feccd7f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=11d249a583a14be654790ab6c8ecc5814018b2a4
commit 11d249a583a14be654790ab6c8ecc5814018b2a4
Merge: 5a9e906 f997316
Author: Brad King <brad.king at kitware.com>
AuthorDate: Wed Sep 7 15:18:18 2016 -0400
Commit: CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Wed Sep 7 15:18:18 2016 -0400
Merge topic 'ExternalData-repeat-file' into next
f9973166 ExternalData: Tolerate files duplicated across multiple targets
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f9973166e82c3f5d8e05e2ab57aceb15ff267295
commit f9973166e82c3f5d8e05e2ab57aceb15ff267295
Author: Brad King <brad.king at kitware.com>
AuthorDate: Wed Sep 7 15:09:19 2016 -0400
Commit: Brad King <brad.king at kitware.com>
CommitDate: Wed Sep 7 15:17:33 2016 -0400
ExternalData: Tolerate files duplicated across multiple targets
If multiple ExternalData_Target_Add calls generate the same output file
then we need to avoid calling add_custom_command multiple times with
that output. This was already done within a single target by setting a
variable in the local function scope. This will not be visible in other
calls though so we need to use a directory property instead to prevent
adding a custom command multiple times for one output in a directory.
Normally it is not safe to have multiple custom commands that produce
the same output file across multiple independent targets, but since we
use atomic replacement of outputs the resulting races should not be a
problem. For the convenience of projects, tolerate this instead of
diagnosing it. In particular, we previously allowed up to two copies
of the custom command in one directory because CMake has a fallback
from MAIN_DEPENDENCY to an `<output>.rule` file.
While at it, add a note to the documentation that typically only one
external data target should be needed for a project.
Reported-by: David Manthey <david.manthey at kitware.com>
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()
diff --git a/Tests/Module/ExternalData/CMakeLists.txt b/Tests/Module/ExternalData/CMakeLists.txt
index f07ab71..1018dd8 100644
--- a/Tests/Module/ExternalData/CMakeLists.txt
+++ b/Tests/Module/ExternalData/CMakeLists.txt
@@ -53,4 +53,5 @@ ExternalData_Add_Target(Data1)
add_subdirectory(Data2)
add_subdirectory(Data3)
add_subdirectory(Data4)
+add_subdirectory(Data5)
add_subdirectory(DataNoSymlinks)
diff --git a/Tests/Module/ExternalData/Data5/CMakeLists.txt b/Tests/Module/ExternalData/Data5/CMakeLists.txt
new file mode 100644
index 0000000..13c7fab
--- /dev/null
+++ b/Tests/Module/ExternalData/Data5/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Test adding the same data file in multiple tests
+ExternalData_Add_Test(Data5.A
+ NAME Data5Check.A
+ COMMAND ${CMAKE_COMMAND}
+ -D Data5=DATA{../Data.dat}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
+ )
+ExternalData_Add_Target(Data5.A)
+ExternalData_Add_Test(Data5.B
+ NAME Data5Check.B
+ COMMAND ${CMAKE_COMMAND}
+ -D Data5=DATA{../Data.dat}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
+ )
+ExternalData_Add_Target(Data5.B)
+ExternalData_Add_Test(Data5.C
+ NAME Data5Check.C
+ COMMAND ${CMAKE_COMMAND}
+ -D Data5=DATA{../Data.dat}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
+ )
+ExternalData_Add_Target(Data5.C)
diff --git a/Tests/Module/ExternalData/Data5/Data5Check.cmake b/Tests/Module/ExternalData/Data5/Data5Check.cmake
new file mode 100644
index 0000000..4dea9a4
--- /dev/null
+++ b/Tests/Module/ExternalData/Data5/Data5Check.cmake
@@ -0,0 +1,4 @@
+file(STRINGS "${Data5}" lines LIMIT_INPUT 1024)
+if(NOT "x${lines}" STREQUAL "xInput file already transformed.")
+ message(SEND_ERROR "Input file:\n ${Data5}\ndoes not have expected content, but [[${lines}]]")
+endif()
-----------------------------------------------------------------------
Summary of changes:
Modules/ExternalData.cmake | 76 +++++++++++++---------
Tests/Module/ExternalData/CMakeLists.txt | 1 +
Tests/Module/ExternalData/Data5/CMakeLists.txt | 22 +++++++
Tests/Module/ExternalData/Data5/Data5Check.cmake | 4 ++
4 files changed, 74 insertions(+), 29 deletions(-)
create mode 100644 Tests/Module/ExternalData/Data5/CMakeLists.txt
create mode 100644 Tests/Module/ExternalData/Data5/Data5Check.cmake
hooks/post-receive
--
CMake
More information about the Cmake-commits
mailing list