summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/file.rst17
-rw-r--r--Help/manual/cmake-developer.7.rst2
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst2
-rw-r--r--Help/release/dev/file_cmd_touch.rst6
-rw-r--r--Help/release/dev/genex-IN_LIST-logical-operator.rst5
-rw-r--r--Help/variable/CMAKE_NETRC.rst2
-rw-r--r--Help/variable/CMAKE_NETRC_FILE.rst2
-rw-r--r--Modules/CMakeTestCSharpCompiler.cmake2
-rw-r--r--Modules/CMakeTestCUDACompiler.cmake2
-rw-r--r--Modules/CMakeTestCXXCompiler.cmake2
-rw-r--r--Modules/CMakeTestFortranCompiler.cmake2
-rw-r--r--Modules/CMakeTestJavaCompiler.cmake2
-rw-r--r--Modules/CMakeTestRCCompiler.cmake2
-rw-r--r--Modules/CMakeTestSwiftCompiler.cmake2
-rw-r--r--Modules/CPackRPM.cmake2
-rw-r--r--Modules/ExternalData.cmake2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmFileCommand.cxx38
-rw-r--r--Source/cmFileCommand.h1
-rw-r--r--Source/cmGeneratorExpressionNode.cxx26
-rw-r--r--Source/cmcmd.cxx2
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt5
-rw-r--r--Tests/GeneratorExpression/check-part1.cmake5
-rw-r--r--Tests/QtAutogen/RerunRccDepends/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake3
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/file/TOUCH-error-in-source-directory-result.txt1
-rw-r--r--Tests/RunCMake/file/TOUCH-error-in-source-directory-stderr.txt1
-rw-r--r--Tests/RunCMake/file/TOUCH-error-in-source-directory.cmake2
-rw-r--r--Tests/RunCMake/file/TOUCH-error-missing-directory-result.txt1
-rw-r--r--Tests/RunCMake/file/TOUCH-error-missing-directory-stderr.txt1
-rw-r--r--Tests/RunCMake/file/TOUCH-error-missing-directory.cmake1
-rw-r--r--Tests/RunCMake/file/TOUCH-result.txt1
-rw-r--r--Tests/RunCMake/file/TOUCH-stderr.txt9
-rw-r--r--Tests/RunCMake/file/TOUCH.cmake16
35 files changed, 157 insertions, 21 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 5ce86e5..5e18077 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -285,6 +285,23 @@ If neither ``TLS`` option is given CMake will check variables
::
+ file(TOUCH [<files>...])
+ file(TOUCH_NOCREATE [<files>...])
+
+Create a file with no content if it does not yet exist. If the file already
+exists, its access and/or modification will be updated to the time when the
+function call is executed.
+
+Use TOUCH_NOCREATE to touch a file if it exists but not create it. If a file
+does not exist it will be silently ignored.
+
+With TOUCH and TOUCH_NOCREATE the contents of an existing file will not be
+modified.
+
+------------------------------------------------------------------------------
+
+::
+
file(TIMESTAMP <filename> <variable> [<format>] [UTC])
Compute a string representation of the modification time of ``<filename>``
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index cd509ac..41fe90c 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -943,7 +943,7 @@ populated:
endif()
The ``RELEASE`` variant should be listed first in the property
-so that that variant is chosen if the user uses a configuration which is
+so that the variant is chosen if the user uses a configuration which is
not an exact match for any listed ``IMPORTED_CONFIGURATIONS``.
Most of the cache variables should be hidden in the ``ccmake`` interface unless
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 13948d3..04cb1dc 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -57,6 +57,8 @@ Available logical expressions are:
``1`` if ``a`` is STREQUAL ``b``, else ``0``
``$<EQUAL:a,b>``
``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0``
+``$<IN_LIST:a,b>``
+ ``1`` if ``a`` is IN_LIST ``b``, else ``0``
``$<CONFIG:cfg>``
``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison.
The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by
diff --git a/Help/release/dev/file_cmd_touch.rst b/Help/release/dev/file_cmd_touch.rst
new file mode 100644
index 0000000..b1b1e3c
--- /dev/null
+++ b/Help/release/dev/file_cmd_touch.rst
@@ -0,0 +1,6 @@
+file_cmd_touch
+------------------
+
+* The :command:`file(TOUCH)` and :command:`file(TOUCH_NOCREATE)` commands
+ were added to expose TOUCH functionality without having to use CMake's
+ command-line tool mode with :command:`execute_process`.
diff --git a/Help/release/dev/genex-IN_LIST-logical-operator.rst b/Help/release/dev/genex-IN_LIST-logical-operator.rst
new file mode 100644
index 0000000..28fa7ce
--- /dev/null
+++ b/Help/release/dev/genex-IN_LIST-logical-operator.rst
@@ -0,0 +1,5 @@
+genex-IN_LIST-logical-operator
+------------------------------
+
+* A new ``$<IN_LIST:...>`` :manual:`generator expression <cmake-generator-expressions(7)>`
+ has been added.
diff --git a/Help/variable/CMAKE_NETRC.rst b/Help/variable/CMAKE_NETRC.rst
index 52f857e..903ec31 100644
--- a/Help/variable/CMAKE_NETRC.rst
+++ b/Help/variable/CMAKE_NETRC.rst
@@ -2,7 +2,7 @@ CMAKE_NETRC
-----------
This variable is used to initialize the ``NETRC`` option for
-:command:`file(DOWNLOAD)` and :command:`file(DOWNLOAD)` commands and the
+:command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands and the
module :module:`ExternalProject`. See those commands for additional
information.
diff --git a/Help/variable/CMAKE_NETRC_FILE.rst b/Help/variable/CMAKE_NETRC_FILE.rst
index 1508f1e..0f09afe 100644
--- a/Help/variable/CMAKE_NETRC_FILE.rst
+++ b/Help/variable/CMAKE_NETRC_FILE.rst
@@ -2,7 +2,7 @@ CMAKE_NETRC_FILE
----------------
This variable is used to initialize the ``NETRC_FILE`` option for
-:command:`file(DOWNLOAD)` and :command:`file(DOWNLOAD)` commands and the
+:command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands and the
module :module:`ExternalProject`. See those commands for additional
information.
diff --git a/Modules/CMakeTestCSharpCompiler.cmake b/Modules/CMakeTestCSharpCompiler.cmake
index f3b95fd..6715c30 100644
--- a/Modules/CMakeTestCSharpCompiler.cmake
+++ b/Modules/CMakeTestCSharpCompiler.cmake
@@ -15,7 +15,7 @@ unset(CMAKE_CSharp_COMPILER_WORKS CACHE)
set(test_compile_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCSharpCompiler.cs")
# This file is used by EnableLanguage in cmGlobalGenerator to
-# determine that that selected C# compiler can actually compile
+# determine that the selected C# compiler can actually compile
# and link the most basic of programs. If not, a fatal error
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake
index df5ec72..f0454da 100644
--- a/Modules/CMakeTestCUDACompiler.cmake
+++ b/Modules/CMakeTestCUDACompiler.cmake
@@ -15,7 +15,7 @@ include(CMakeTestCompilerCommon)
unset(CMAKE_CUDA_COMPILER_WORKS CACHE)
# This file is used by EnableLanguage in cmGlobalGenerator to
-# determine that that selected cuda compiler can actually compile
+# determine that the selected cuda compiler can actually compile
# and link the most basic of programs. If not, a fatal error
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
index 7b80dc0..e4d49ae 100644
--- a/Modules/CMakeTestCXXCompiler.cmake
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -16,7 +16,7 @@ include(CMakeTestCompilerCommon)
unset(CMAKE_CXX_COMPILER_WORKS CACHE)
# This file is used by EnableLanguage in cmGlobalGenerator to
-# determine that that selected C++ compiler can actually compile
+# determine that the selected C++ compiler can actually compile
# and link the most basic of programs. If not, a fatal error
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake
index 3c150a8..e9860e9 100644
--- a/Modules/CMakeTestFortranCompiler.cmake
+++ b/Modules/CMakeTestFortranCompiler.cmake
@@ -16,7 +16,7 @@ include(CMakeTestCompilerCommon)
unset(CMAKE_Fortran_COMPILER_WORKS CACHE)
# This file is used by EnableLanguage in cmGlobalGenerator to
-# determine that that selected Fortran compiler can actually compile
+# determine that the selected Fortran compiler can actually compile
# and link the most basic of programs. If not, a fatal error
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
diff --git a/Modules/CMakeTestJavaCompiler.cmake b/Modules/CMakeTestJavaCompiler.cmake
index 23fdbdc..3c33573 100644
--- a/Modules/CMakeTestJavaCompiler.cmake
+++ b/Modules/CMakeTestJavaCompiler.cmake
@@ -3,7 +3,7 @@
# This file is used by EnableLanguage in cmGlobalGenerator to
-# determine that that selected Fortran compiler can actually compile
+# determine that the selected Fortran compiler can actually compile
# and link the most basic of programs. If not, a fatal error
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
diff --git a/Modules/CMakeTestRCCompiler.cmake b/Modules/CMakeTestRCCompiler.cmake
index c510d3a..3123a6c 100644
--- a/Modules/CMakeTestRCCompiler.cmake
+++ b/Modules/CMakeTestRCCompiler.cmake
@@ -3,7 +3,7 @@
# This file is used by EnableLanguage in cmGlobalGenerator to
-# determine that that selected RC compiler can actually compile
+# determine that the selected RC compiler can actually compile
# and link the most basic of programs. If not, a fatal error
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake
index bcd5c33..858c1be 100644
--- a/Modules/CMakeTestSwiftCompiler.cmake
+++ b/Modules/CMakeTestSwiftCompiler.cmake
@@ -16,7 +16,7 @@ include(CMakeTestCompilerCommon)
unset(CMAKE_Swift_COMPILER_WORKS CACHE)
# This file is used by EnableLanguage in cmGlobalGenerator to
-# determine that that selected C++ compiler can actually compile
+# determine that the selected C++ compiler can actually compile
# and link the most basic of programs. If not, a fatal error
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index bb5181f..258922c 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -1984,7 +1984,7 @@ function(cpack_rpm_generate_package)
endif()
if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER})
- # Prefix can be replaced by Prefixes but the old version stil works so we'll ignore it for now
+ # Prefix can be replaced by Prefixes but the old version still works so we'll ignore it for now
# Requires* is a special case because it gets transformed to Requires(pre/post/preun/postun)
# Auto* is a special case because the tags can not be queried by querytags rpmbuild flag
set(special_case_tags_ PREFIX REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN AUTOPROV AUTOREQ AUTOREQPROV)
diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake
index 7331fb2..e5dbcd9 100644
--- a/Modules/ExternalData.cmake
+++ b/Modules/ExternalData.cmake
@@ -1133,7 +1133,7 @@ if("${ExternalData_ACTION}" STREQUAL "fetch")
if(file_up_to_date)
# Touch the file to convince the build system it is up to date.
- execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${file}")
+ file(TOUCH "${file}")
else()
_ExternalData_link_or_copy("${obj}" "${file}")
endif()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 27281fe..1477f0d 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 11)
-set(CMake_VERSION_PATCH 20180216)
+set(CMake_VERSION_PATCH 20180220)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index d3dcc01..8492c17 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -160,6 +160,12 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "TO_NATIVE_PATH") {
return this->HandleCMakePathCommand(args, true);
}
+ if (subCommand == "TOUCH") {
+ return this->HandleTouchCommand(args, true);
+ }
+ if (subCommand == "TOUCH_NOCREATE") {
+ return this->HandleTouchCommand(args, false);
+ }
if (subCommand == "TIMESTAMP") {
return this->HandleTimestampCommand(args);
}
@@ -905,6 +911,38 @@ bool cmFileCommand::HandleMakeDirectoryCommand(
return true;
}
+bool cmFileCommand::HandleTouchCommand(std::vector<std::string> const& args,
+ bool create)
+{
+ // File command has at least one argument
+ assert(args.size() > 1);
+
+ std::vector<std::string>::const_iterator i = args.begin();
+
+ i++; // Get rid of subcommand
+
+ for (; i != args.end(); ++i) {
+ std::string tfile = *i;
+ if (!cmsys::SystemTools::FileIsFullPath(tfile)) {
+ tfile = this->Makefile->GetCurrentSourceDirectory();
+ tfile += "/" + *i;
+ }
+ if (!this->Makefile->CanIWriteThisFile(tfile)) {
+ std::string e =
+ "attempted to touch a file: " + tfile + " in a source directory.";
+ this->SetError(e);
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ if (!cmSystemTools::Touch(tfile, create)) {
+ std::string error = "problem touching file: " + tfile;
+ this->SetError(error);
+ return false;
+ }
+ }
+ return true;
+}
+
bool cmFileCommand::HandleDifferentCommand(
std::vector<std::string> const& args)
{
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 17269f3..719dca2 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -39,6 +39,7 @@ protected:
bool HandleHashCommand(std::vector<std::string> const& args);
bool HandleStringsCommand(std::vector<std::string> const& args);
bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse);
+ bool HandleTouchCommand(std::vector<std::string> const& args, bool create);
bool HandleMakeDirectoryCommand(std::vector<std::string> const& args);
bool HandleRelativePathCommand(std::vector<std::string> const& args);
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index c1f1ee4..0d22028 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -275,6 +275,31 @@ static const struct EqualNode : public cmGeneratorExpressionNode
}
} equalNode;
+static const struct InListNode : public cmGeneratorExpressionNode
+{
+ InListNode() {}
+
+ int NumExpectedParameters() const override { return 2; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* /*context*/,
+ const GeneratorExpressionContent* /*content*/,
+ cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+ {
+ std::vector<std::string> values;
+ cmSystemTools::ExpandListArgument(parameters[1], values);
+ if (values.empty()) {
+ return "0";
+ }
+
+ return std::find(values.cbegin(), values.cend(), parameters.front()) ==
+ values.cend()
+ ? "0"
+ : "1";
+ }
+} inListNode;
+
static const struct LowerCaseNode : public cmGeneratorExpressionNode
{
LowerCaseNode() {}
@@ -1827,6 +1852,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
nodeMap["TARGET_BUNDLE_CONTENT_DIR"] = &targetBundleContentDirNode;
nodeMap["STREQUAL"] = &strEqualNode;
nodeMap["EQUAL"] = &equalNode;
+ nodeMap["IN_LIST"] = &inListNode;
nodeMap["LOWER_CASE"] = &lowerCaseNode;
nodeMap["UPPER_CASE"] = &upperCaseNode;
nodeMap["MAKE_C_IDENTIFIER"] = &makeCIdentifierNode;
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 0988c3c..e7d92d4 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -689,8 +689,6 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
// Touch file
if (args[1] == "touch_nocreate" && args.size() > 2) {
for (std::string::size_type cc = 2; cc < args.size(); cc++) {
- // Complain if the file could not be removed, still exists,
- // and the -f option was not given.
if (!cmSystemTools::Touch(args[cc], false)) {
return 1;
}
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 19d12e5..3d08704 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -57,6 +57,11 @@ add_custom_target(check-part1 ALL
-Dtest_strequal_angle_r_comma=$<STREQUAL:$<ANGLE-R>,$<COMMA>>
-Dtest_strequal_both_empty=$<STREQUAL:,>
-Dtest_strequal_one_empty=$<STREQUAL:something,>
+ -Dtest_inlist_true=$<IN_LIST:a,a$<SEMICOLON>b>
+ -Dtest_inlist_false=$<IN_LIST:c,a$<SEMICOLON>b>
+ -Dtest_inlist_empty_1=$<IN_LIST:a,>
+ -Dtest_inlist_empty_2=$<IN_LIST:,a>
+ -Dtest_inlist_empty_3=$<IN_LIST:,>
-Dtest_angle_r=$<ANGLE-R>
-Dtest_comma=$<COMMA>
-Dtest_semicolon=$<SEMICOLON>
diff --git a/Tests/GeneratorExpression/check-part1.cmake b/Tests/GeneratorExpression/check-part1.cmake
index 60b193f..41bcd6d 100644
--- a/Tests/GeneratorExpression/check-part1.cmake
+++ b/Tests/GeneratorExpression/check-part1.cmake
@@ -49,6 +49,11 @@ check(test_strequal_semicolon "1")
check(test_strequal_angle_r_comma "0")
check(test_strequal_both_empty "1")
check(test_strequal_one_empty "0")
+check(test_inlist_true "1")
+check(test_inlist_false "0")
+check(test_inlist_empty_1 "0")
+check(test_inlist_empty_2 "0")
+check(test_inlist_empty_3 "0")
check(test_angle_r ">")
check(test_comma ",")
check(test_semicolon ";")
diff --git a/Tests/QtAutogen/RerunRccDepends/CMakeLists.txt b/Tests/QtAutogen/RerunRccDepends/CMakeLists.txt
index 2e6a5bd..f9c52b7 100644
--- a/Tests/QtAutogen/RerunRccDepends/CMakeLists.txt
+++ b/Tests/QtAutogen/RerunRccDepends/CMakeLists.txt
@@ -45,8 +45,7 @@ file(TIMESTAMP "${rccDepBinGen}" rdGenBefore "${timeformat}")
# - Change a resource files listed in the .qrc file
# - Rebuild
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resPlain/input.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resGen/input.txt")
+file(TOUCH "${rccDepBD}/resPlain/input.txt" "${rccDepBD}/resGen/input.txt")
execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
if (result)
message(SEND_ERROR "Second build of rccDepends failed.")
@@ -97,8 +96,7 @@ file(TIMESTAMP "${rccDepBinGen}" rdGenBefore "${timeformat}")
# - Change a newly added resource files listed in the .qrc file
# - Rebuild
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resPlain/inputAdded.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resGen/inputAdded.txt")
+file(TOUCH "${rccDepBD}/resPlain/inputAdded.txt" "${rccDepBD}/resGen/inputAdded.txt")
execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
if (result)
message(SEND_ERROR "Fourth build of rccDepends failed.")
diff --git a/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake b/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake
index 45766a0..96be54b 100644
--- a/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake
+++ b/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake
@@ -16,8 +16,7 @@ set(fileNames)
foreach(e ${fileExtensions})
set(currentFile "${CMAKE_CURRENT_BINARY_DIR}/foo.${e}")
list(APPEND fileNames ${currentFile})
- execute_process(COMMAND ${CMAKE_COMMAND} -E touch
- "${currentFile}")
+ file(TOUCH "${currentFile}")
string(TOUPPER ${e} eUC)
set_source_files_properties("${currentFile}"
PROPERTIES
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index 3be4fb7..9a72333 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -5,6 +5,9 @@ run_cmake(DOWNLOAD-unused-argument)
run_cmake(DOWNLOAD-httpheader-not-set)
run_cmake(DOWNLOAD-netrc-bad)
run_cmake(DOWNLOAD-pass-not-set)
+run_cmake(TOUCH)
+run_cmake(TOUCH-error-in-source-directory)
+run_cmake(TOUCH-error-missing-directory)
run_cmake(UPLOAD-unused-argument)
run_cmake(UPLOAD-httpheader-not-set)
run_cmake(UPLOAD-netrc-bad)
diff --git a/Tests/RunCMake/file/TOUCH-error-in-source-directory-result.txt b/Tests/RunCMake/file/TOUCH-error-in-source-directory-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/TOUCH-error-in-source-directory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/TOUCH-error-in-source-directory-stderr.txt b/Tests/RunCMake/file/TOUCH-error-in-source-directory-stderr.txt
new file mode 100644
index 0000000..f899c75
--- /dev/null
+++ b/Tests/RunCMake/file/TOUCH-error-in-source-directory-stderr.txt
@@ -0,0 +1 @@
+.*file attempted to touch a file:
diff --git a/Tests/RunCMake/file/TOUCH-error-in-source-directory.cmake b/Tests/RunCMake/file/TOUCH-error-in-source-directory.cmake
new file mode 100644
index 0000000..9aa7c56
--- /dev/null
+++ b/Tests/RunCMake/file/TOUCH-error-in-source-directory.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_DISABLE_SOURCE_CHANGES ON)
+file(TOUCH "${CMAKE_CURRENT_SOURCE_DIR}/touch_test")
diff --git a/Tests/RunCMake/file/TOUCH-error-missing-directory-result.txt b/Tests/RunCMake/file/TOUCH-error-missing-directory-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/TOUCH-error-missing-directory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/TOUCH-error-missing-directory-stderr.txt b/Tests/RunCMake/file/TOUCH-error-missing-directory-stderr.txt
new file mode 100644
index 0000000..f52e11a
--- /dev/null
+++ b/Tests/RunCMake/file/TOUCH-error-missing-directory-stderr.txt
@@ -0,0 +1 @@
+.*file problem touching file:
diff --git a/Tests/RunCMake/file/TOUCH-error-missing-directory.cmake b/Tests/RunCMake/file/TOUCH-error-missing-directory.cmake
new file mode 100644
index 0000000..0cfb8d9
--- /dev/null
+++ b/Tests/RunCMake/file/TOUCH-error-missing-directory.cmake
@@ -0,0 +1 @@
+file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/missing/directory/file.to-touch")
diff --git a/Tests/RunCMake/file/TOUCH-result.txt b/Tests/RunCMake/file/TOUCH-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/TOUCH-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/TOUCH-stderr.txt b/Tests/RunCMake/file/TOUCH-stderr.txt
new file mode 100644
index 0000000..9f31676
--- /dev/null
+++ b/Tests/RunCMake/file/TOUCH-stderr.txt
@@ -0,0 +1,9 @@
+^CMake Error at TOUCH\.cmake:[0-9]+ \(file\):
+ file must be called with at least two arguments\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at TOUCH\.cmake:[0-9]+ \(file\):
+ file must be called with at least two arguments\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/TOUCH.cmake b/Tests/RunCMake/file/TOUCH.cmake
new file mode 100644
index 0000000..8931eb5
--- /dev/null
+++ b/Tests/RunCMake/file/TOUCH.cmake
@@ -0,0 +1,16 @@
+set(file "${CMAKE_CURRENT_BINARY_DIR}/file-to-touch")
+
+file(REMOVE "${file}")
+file(TOUCH_NOCREATE "${file}")
+if(EXISTS "${file}")
+ message(FATAL_ERROR "error: TOUCH_NOCREATE created a file!")
+endif()
+
+file(TOUCH "${file}")
+if(NOT EXISTS "${file}")
+ message(FATAL_ERROR "error: TOUCH did not create a file!")
+endif()
+file(REMOVE "${file}")
+
+file(TOUCH)
+file(TOUCH_NOCREATE)