Merge topic 'cmcomputecomponentgraph-compute-method'

bd0d03386b cmComputeComponentGraph: Move work out of constructor into Compute() method

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5079
diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst
index c0677d2..a77ba37 100644
--- a/Help/command/add_test.rst
+++ b/Help/command/add_test.rst
@@ -10,9 +10,8 @@
            [WORKING_DIRECTORY <dir>]
            [COMMAND_EXPAND_LISTS])
 
-Adds a test called ``<name>``.  The test name may contain arbitrary
-characters except for double-quotes.  However, if it contains spaces
-or semicolons it must be enclosed in double-quotes.  The options are:
+Adds a test called ``<name>``.  The test name may not contain spaces,
+quotes, or other characters special in CMake syntax.  The options are:
 
 ``COMMAND``
   Specify the test command-line.  If ``<command>`` specifies an
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 693c059..2cf938b 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -776,11 +776,14 @@
 
 .. code-block:: cmake
 
-  file(DOWNLOAD <url> <file> [<options>...])
+  file(DOWNLOAD <url> [<file>] [<options>...])
   file(UPLOAD   <file> <url> [<options>...])
 
-The ``DOWNLOAD`` mode downloads the given ``<url>`` to a local ``<file>``.
-The ``UPLOAD`` mode uploads a local ``<file>`` to a given ``<url>``.
+The ``DOWNLOAD`` mode downloads the given ``<url>`` to a local ``<file>``. If
+``<file>`` is not specified for ``file(DOWNLOAD)``, the file is not saved. This
+can be useful if you want to know if a file can be downloaded (for example, to
+check that it exists) without actually saving it anywhere. The ``UPLOAD`` mode
+uploads a local ``<file>`` to a given ``<url>``.
 
 Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
 
@@ -853,10 +856,12 @@
 
   Verify that the downloaded content hash matches the expected value, where
   ``ALGO`` is one of the algorithms supported by ``file(<HASH>)``.
-  If it does not match, the operation fails with an error.
+  If it does not match, the operation fails with an error. It is an error to
+  specify this if ``DOWNLOAD`` is not given a ``<file>``.
 
 ``EXPECTED_MD5 <value>``
-  Historical short-hand for ``EXPECTED_HASH MD5=<value>``.
+  Historical short-hand for ``EXPECTED_HASH MD5=<value>``. It is an error to
+  specify this if ``DOWNLOAD`` is not given a ``<file>``.
 
 Locking
 ^^^^^^^
diff --git a/Help/release/3.18.rst b/Help/release/3.18.rst
index 427840e..ba80d2b 100644
--- a/Help/release/3.18.rst
+++ b/Help/release/3.18.rst
@@ -332,3 +332,10 @@
   architecture (the Xcode ``ARCHS`` setting).  This is needed for Xcode 12
   to select the host's architecture, which older versions of Xcode did
   by default.
+
+* In CMake 3.18.0 the :command:`add_test` command learned to support
+  special characters in test names.  This was accidentally left out of
+  its release notes.  Unfortunately the fix breaks existing projects
+  that were using manual quoting or escaping to work around the prior
+  limitation.  This fix has been reverted in 3.18.1, but may be
+  re-introduced in future versions of CMake with a policy for compatibility.
diff --git a/Help/release/dev/file-download-optional-file.rst b/Help/release/dev/file-download-optional-file.rst
new file mode 100644
index 0000000..f3dc24c
--- /dev/null
+++ b/Help/release/dev/file-download-optional-file.rst
@@ -0,0 +1,5 @@
+file-download-optional-file
+---------------------------
+
+* The ``<file>`` argument is now optional for :command:`file(DOWNLOAD)`. If it
+  is not specified, the file is not saved.
diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake
index 7cd7c47..cb1ab1d 100644
--- a/Modules/CMakeDetermineCompiler.cmake
+++ b/Modules/CMakeDetermineCompiler.cmake
@@ -140,7 +140,9 @@
       OUTPUT_VARIABLE _cmake_sysroot_run_out
       ERROR_VARIABLE _cmake_sysroot_run_err)
 
-    if(_cmake_sysroot_run_out AND NOT _cmake_sysroot_run_err AND IS_DIRECTORY "${_cmake_sysroot_run_out}/usr")
+    if(_cmake_sysroot_run_out AND NOT _cmake_sysroot_run_err
+        AND NOT _cmake_sysroot_run_out STREQUAL "/"
+        AND IS_DIRECTORY "${_cmake_sysroot_run_out}/usr")
       file(TO_CMAKE_PATH "${_cmake_sysroot_run_out}/usr" _cmake_sysroot_run_out_usr)
       set(CMAKE_${lang}_COMPILER_SYSROOT "${_cmake_sysroot_run_out_usr}" PARENT_SCOPE)
     else()
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index 3acadc2..74b36c6 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -150,16 +150,16 @@
   endif()
   foreach(component IN LISTS CURL_FIND_COMPONENTS)
     list(FIND CURL_KNOWN_PROTOCOLS ${component} _found)
-    if(_found)
+    if(NOT _found EQUAL -1)
       list(FIND CURL_SUPPORTED_PROTOCOLS ${component} _found)
-      if(_found)
+      if(NOT _found EQUAL -1)
         set(CURL_${component}_FOUND TRUE)
       elseif(CURL_FIND_REQUIRED)
         message(FATAL_ERROR "CURL: Required protocol ${component} is not found")
       endif()
     else()
       list(FIND CURL_SUPPORTED_FEATURES ${component} _found)
-      if(_found)
+      if(NOT _found EQUAL -1)
         set(CURL_${component}_FOUND TRUE)
       elseif(CURL_FIND_REQUIRED)
         message(FATAL_ERROR "CURL: Required feature ${component} is not found")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 0465c93..10f6e15 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 18)
-set(CMake_VERSION_PATCH 20200727)
+set(CMake_VERSION_PATCH 20200729)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 3d5fe6b..560e5c1 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -696,57 +696,57 @@
 
   const char* debian_pkg_source =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
-  if (debian_pkg_source && *debian_pkg_source) {
+  if (cmNonempty(debian_pkg_source)) {
     controlValues["Source"] = debian_pkg_source;
   }
   const char* debian_pkg_dep =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DEPENDS");
-  if (debian_pkg_dep && *debian_pkg_dep) {
+  if (cmNonempty(debian_pkg_dep)) {
     controlValues["Depends"] = debian_pkg_dep;
   }
   const char* debian_pkg_rec =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS");
-  if (debian_pkg_rec && *debian_pkg_rec) {
+  if (cmNonempty(debian_pkg_rec)) {
     controlValues["Recommends"] = debian_pkg_rec;
   }
   const char* debian_pkg_sug =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS");
-  if (debian_pkg_sug && *debian_pkg_sug) {
+  if (cmNonempty(debian_pkg_sug)) {
     controlValues["Suggests"] = debian_pkg_sug;
   }
   const char* debian_pkg_url =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE");
-  if (debian_pkg_url && *debian_pkg_url) {
+  if (cmNonempty(debian_pkg_url)) {
     controlValues["Homepage"] = debian_pkg_url;
   }
   const char* debian_pkg_predep =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS");
-  if (debian_pkg_predep && *debian_pkg_predep) {
+  if (cmNonempty(debian_pkg_predep)) {
     controlValues["Pre-Depends"] = debian_pkg_predep;
   }
   const char* debian_pkg_enhances =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ENHANCES");
-  if (debian_pkg_enhances && *debian_pkg_enhances) {
+  if (cmNonempty(debian_pkg_enhances)) {
     controlValues["Enhances"] = debian_pkg_enhances;
   }
   const char* debian_pkg_breaks =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_BREAKS");
-  if (debian_pkg_breaks && *debian_pkg_breaks) {
+  if (cmNonempty(debian_pkg_breaks)) {
     controlValues["Breaks"] = debian_pkg_breaks;
   }
   const char* debian_pkg_conflicts =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS");
-  if (debian_pkg_conflicts && *debian_pkg_conflicts) {
+  if (cmNonempty(debian_pkg_conflicts)) {
     controlValues["Conflicts"] = debian_pkg_conflicts;
   }
   const char* debian_pkg_provides =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES");
-  if (debian_pkg_provides && *debian_pkg_provides) {
+  if (cmNonempty(debian_pkg_provides)) {
     controlValues["Provides"] = debian_pkg_provides;
   }
   const char* debian_pkg_replaces =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_REPLACES");
-  if (debian_pkg_replaces && *debian_pkg_replaces) {
+  if (cmNonempty(debian_pkg_replaces)) {
     controlValues["Replaces"] = debian_pkg_replaces;
   }
 
@@ -756,7 +756,7 @@
   const char* debian_pkg_shlibs =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SHLIBS");
   const bool gen_shibs = this->IsOn("CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS") &&
-    debian_pkg_shlibs && *debian_pkg_shlibs;
+    cmNonempty(debian_pkg_shlibs);
   if (gen_shibs) {
     cmGeneratedFileStream out;
     out.Open(shlibsfilename, false, true);
@@ -832,11 +832,11 @@
 
   const char* debian_pkg_source =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
-  if (debian_pkg_source && *debian_pkg_source) {
+  if (cmNonempty(debian_pkg_source)) {
     controlValues["Source"] = debian_pkg_source;
   }
   const char* debian_build_ids = this->GetOption("GEN_BUILD_IDS");
-  if (debian_build_ids && *debian_build_ids) {
+  if (cmNonempty(debian_build_ids)) {
     controlValues["Build-Ids"] = debian_build_ids;
   }
 
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 53be4fe..0bc8456 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -61,7 +61,7 @@
   }
 
   const char* packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT");
-  if (packageScript && *packageScript) {
+  if (cmNonempty(packageScript)) {
     if (!cmSystemTools::FileIsFullPath(packageScript)) {
       cmCPackLogger(
         cmCPackLog::LOG_ERROR,
@@ -211,7 +211,7 @@
 
   const char* defaultDirectoryPermissions =
     this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (defaultDirectoryPermissions && *defaultDirectoryPermissions) {
+  if (cmNonempty(defaultDirectoryPermissions)) {
     root["defaultDirectoryPermissions"] = defaultDirectoryPermissions;
   }
   if (cmIsInternallyOn(this->Parent->GetOption("CPACK_SET_DESTDIR"))) {
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index c641175..3880f65 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -216,7 +216,7 @@
   mode_t* default_dir_mode = nullptr;
   const char* default_dir_install_permissions =
     this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (default_dir_install_permissions && *default_dir_install_permissions) {
+  if (cmNonempty(default_dir_install_permissions)) {
     std::vector<std::string> items =
       cmExpandedList(default_dir_install_permissions);
     for (const auto& arg : items) {
@@ -293,7 +293,7 @@
 {
   (void)setDestDir;
   const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS");
-  if (installCommands && *installCommands) {
+  if (cmNonempty(installCommands)) {
     std::string tempInstallDirectoryEnv =
       cmStrCat("CMAKE_INSTALL_PREFIX=", tempInstallDirectory);
     cmSystemTools::PutEnv(tempInstallDirectoryEnv);
@@ -344,7 +344,7 @@
   }
   const char* installDirectories =
     this->GetOption("CPACK_INSTALLED_DIRECTORIES");
-  if (installDirectories && *installDirectories) {
+  if (cmNonempty(installDirectories)) {
     std::vector<std::string> installDirectoriesVector =
       cmExpandedList(installDirectories);
     if (installDirectoriesVector.size() % 2 != 0) {
@@ -541,7 +541,7 @@
   const char* cmakeProjects = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
   const char* cmakeGenerator = this->GetOption("CPACK_CMAKE_GENERATOR");
   std::string absoluteDestFiles;
-  if (cmakeProjects && *cmakeProjects) {
+  if (cmNonempty(cmakeProjects)) {
     if (!cmakeGenerator) {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
                     "CPACK_INSTALL_CMAKE_PROJECTS is specified, but "
@@ -594,7 +594,7 @@
         std::string installTypesVar = "CPACK_" +
           cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES";
         const char* installTypes = this->GetOption(installTypesVar);
-        if (installTypes && *installTypes) {
+        if (cmNonempty(installTypes)) {
           std::vector<std::string> installTypesVector =
             cmExpandedList(installTypes);
           for (std::string const& installType : installTypesVector) {
@@ -607,7 +607,7 @@
         std::string componentsVar =
           "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component);
         const char* components = this->GetOption(componentsVar);
-        if (components && *components) {
+        if (cmNonempty(components)) {
           cmExpandList(components, componentsVector);
           for (std::string const& comp : componentsVector) {
             project.Components.push_back(
@@ -771,7 +771,7 @@
 
   const char* default_dir_inst_permissions =
     this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (default_dir_inst_permissions && *default_dir_inst_permissions) {
+  if (cmNonempty(default_dir_inst_permissions)) {
     mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS",
                      default_dir_inst_permissions);
   }
@@ -983,7 +983,7 @@
                                          const char* value)
 {
   const char* def = this->MakefileMap->GetDefinition(op);
-  if (def && *def) {
+  if (cmNonempty(def)) {
     return;
   }
   this->SetOption(op, value);
@@ -1215,7 +1215,7 @@
 bool cmCPackGenerator::IsSetToOff(const std::string& op) const
 {
   const char* ret = this->MakefileMap->GetDefinition(op);
-  if (ret && *ret) {
+  if (cmNonempty(ret)) {
     return cmIsOff(ret);
   }
   return false;
@@ -1509,7 +1509,7 @@
     installType->Name = name;
 
     const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME");
-    if (displayName && *displayName) {
+    if (cmNonempty(displayName)) {
       installType->DisplayName = displayName;
     } else {
       installType->DisplayName = installType->Name;
@@ -1531,7 +1531,7 @@
       "CPACK_COMPONENT_" + cmsys::SystemTools::UpperCase(name);
     component->Name = name;
     const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME");
-    if (displayName && *displayName) {
+    if (cmNonempty(displayName)) {
       component->DisplayName = displayName;
     } else {
       component->DisplayName = component->Name;
@@ -1543,17 +1543,17 @@
       cmIsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
 
     const char* archiveFile = this->GetOption(macroPrefix + "_ARCHIVE_FILE");
-    if (archiveFile && *archiveFile) {
+    if (cmNonempty(archiveFile)) {
       component->ArchiveFile = archiveFile;
     }
 
     const char* plist = this->GetOption(macroPrefix + "_PLIST");
-    if (plist && *plist) {
+    if (cmNonempty(plist)) {
       component->Plist = plist;
     }
 
     const char* groupName = this->GetOption(macroPrefix + "_GROUP");
-    if (groupName && *groupName) {
+    if (cmNonempty(groupName)) {
       component->Group = GetComponentGroup(projectName, groupName);
       component->Group->Components.push_back(component);
     } else {
@@ -1561,13 +1561,13 @@
     }
 
     const char* description = this->GetOption(macroPrefix + "_DESCRIPTION");
-    if (description && *description) {
+    if (cmNonempty(description)) {
       component->Description = description;
     }
 
     // Determine the installation types.
     const char* installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES");
-    if (installTypes && *installTypes) {
+    if (cmNonempty(installTypes)) {
       std::vector<std::string> installTypesVector =
         cmExpandedList(installTypes);
       for (std::string const& installType : installTypesVector) {
@@ -1578,7 +1578,7 @@
 
     // Determine the component dependencies.
     const char* depends = this->GetOption(macroPrefix + "_DEPENDS");
-    if (depends && *depends) {
+    if (cmNonempty(depends)) {
       std::vector<std::string> dependsVector = cmExpandedList(depends);
       for (std::string const& depend : dependsVector) {
         cmCPackComponent* child = GetComponent(projectName, depend);
@@ -1602,21 +1602,21 @@
     // Define the group
     group->Name = name;
     const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME");
-    if (displayName && *displayName) {
+    if (cmNonempty(displayName)) {
       group->DisplayName = displayName;
     } else {
       group->DisplayName = group->Name;
     }
 
     const char* description = this->GetOption(macroPrefix + "_DESCRIPTION");
-    if (description && *description) {
+    if (cmNonempty(description)) {
       group->Description = description;
     }
     group->IsBold = this->IsOn(macroPrefix + "_BOLD_TITLE");
     group->IsExpandedByDefault = this->IsOn(macroPrefix + "_EXPANDED");
     const char* parentGroupName =
       this->GetOption(macroPrefix + "_PARENT_GROUP");
-    if (parentGroupName && *parentGroupName) {
+    if (cmNonempty(parentGroupName)) {
       group->ParentGroup = GetComponentGroup(projectName, parentGroupName);
       group->ParentGroup->Subgroups.push_back(group);
     } else {
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 058b090..2109b4e 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -696,7 +696,7 @@
     const char* userUploadDirectory =
       this->GetOption("CPACK_UPLOAD_DIRECTORY");
     std::string uploadDirectory;
-    if (userUploadDirectory && *userUploadDirectory) {
+    if (cmNonempty(userUploadDirectory)) {
       uploadDirectory = userUploadDirectory;
     } else {
       uploadDirectory =
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index db426b2..a18cbb4 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -182,10 +182,9 @@
     std::vector<std::string> extraPaths;
     std::vector<std::string> failed;
     fullPath = cmCTestTestHandler::FindExecutable(
-      this->CTest, this->ConfigSample.c_str(), resultingConfig, extraPaths,
-      failed);
+      this->CTest, this->ConfigSample, resultingConfig, extraPaths, failed);
     if (!fullPath.empty() && !resultingConfig.empty()) {
-      this->CTest->SetConfigType(resultingConfig.c_str());
+      this->CTest->SetConfigType(resultingConfig);
     }
     out << "Using config sample with results: " << fullPath << " and "
         << resultingConfig << std::endl;
@@ -296,9 +295,8 @@
     extraPaths.push_back(tempPath);
   }
   std::vector<std::string> failed;
-  fullPath =
-    cmCTestTestHandler::FindExecutable(this->CTest, this->TestCommand.c_str(),
-                                       resultingConfig, extraPaths, failed);
+  fullPath = cmCTestTestHandler::FindExecutable(
+    this->CTest, this->TestCommand, resultingConfig, extraPaths, failed);
 
   if (!cmSystemTools::FileExists(fullPath)) {
     out << "Could not find path to executable, perhaps it was not built: "
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 44fdc29..8aab167 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -12,6 +12,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
@@ -38,10 +39,9 @@
 
   this->Handler = handler;
 
-  const char* ctestBuildCommand =
-    this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
-  if (ctestBuildCommand && *ctestBuildCommand) {
-    this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand,
+  cmProp ctestBuildCommand = this->Makefile->GetDef("CTEST_BUILD_COMMAND");
+  if (cmNonempty(ctestBuildCommand)) {
+    this->CTest->SetCTestConfiguration("MakeCommand", *ctestBuildCommand,
                                        this->Quiet);
   } else {
     const char* cmakeGeneratorName =
@@ -56,7 +56,7 @@
       this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
     const char* cmakeBuildConfiguration = !this->Configuration.empty()
       ? this->Configuration.c_str()
-      : ((ctestBuildConfiguration && *ctestBuildConfiguration)
+      : (cmNonempty(ctestBuildConfiguration)
            ? ctestBuildConfiguration
            : this->CTest->GetConfigType().c_str());
 
@@ -67,7 +67,7 @@
       ? this->Target.c_str()
       : this->Makefile->GetDefinition("CTEST_BUILD_TARGET");
 
-    if (cmakeGeneratorName && *cmakeGeneratorName) {
+    if (cmNonempty(cmakeGeneratorName)) {
       if (!cmakeBuildConfiguration) {
         cmakeBuildConfiguration = "Release";
       }
@@ -108,7 +108,7 @@
       cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                          "SetMakeCommand:" << buildCommand << "\n",
                          this->Quiet);
-      this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str(),
+      this->CTest->SetCTestConfiguration("MakeCommand", buildCommand,
                                          this->Quiet);
     } else {
       std::ostringstream ostr;
@@ -123,16 +123,15 @@
     }
   }
 
-  if (const char* useLaunchers =
-        this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS")) {
-    this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers,
+  if (cmProp useLaunchers = this->Makefile->GetDef("CTEST_USE_LAUNCHERS")) {
+    this->CTest->SetCTestConfiguration("UseLaunchers", *useLaunchers,
                                        this->Quiet);
   }
 
-  if (const char* labelsForSubprojects =
-        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+  if (cmProp labelsForSubprojects =
+        this->Makefile->GetDef("CTEST_LABELS_FOR_SUBPROJECTS")) {
     this->CTest->SetCTestConfiguration("LabelsForSubprojects",
-                                       labelsForSubprojects, this->Quiet);
+                                       *labelsForSubprojects, this->Quiet);
   }
 
   handler->SetQuiet(this->Quiet);
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index f42c3f1..ac57130 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -12,6 +12,7 @@
 #include "cmCTestConfigureHandler.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
@@ -38,16 +39,16 @@
     return nullptr;
   }
 
-  const char* ctestConfigureCommand =
-    this->Makefile->GetDefinition("CTEST_CONFIGURE_COMMAND");
+  cmProp ctestConfigureCommand =
+    this->Makefile->GetDef("CTEST_CONFIGURE_COMMAND");
 
-  if (ctestConfigureCommand && *ctestConfigureCommand) {
+  if (cmNonempty(ctestConfigureCommand)) {
     this->CTest->SetCTestConfiguration("ConfigureCommand",
-                                       ctestConfigureCommand, this->Quiet);
+                                       *ctestConfigureCommand, this->Quiet);
   } else {
     const char* cmakeGeneratorName =
       this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
-    if (cmakeGeneratorName && *cmakeGeneratorName) {
+    if (cmNonempty(cmakeGeneratorName)) {
       const std::string& source_dir =
         this->CTest->GetCTestConfiguration("SourceDirectory");
       if (source_dir.empty()) {
@@ -107,7 +108,7 @@
 
       const char* cmakeGeneratorPlatform =
         this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM");
-      if (cmakeGeneratorPlatform && *cmakeGeneratorPlatform) {
+      if (cmNonempty(cmakeGeneratorPlatform)) {
         cmakeConfigureCommand += " \"-A";
         cmakeConfigureCommand += cmakeGeneratorPlatform;
         cmakeConfigureCommand += "\"";
@@ -115,7 +116,7 @@
 
       const char* cmakeGeneratorToolset =
         this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET");
-      if (cmakeGeneratorToolset && *cmakeGeneratorToolset) {
+      if (cmNonempty(cmakeGeneratorToolset)) {
         cmakeConfigureCommand += " \"-T";
         cmakeConfigureCommand += cmakeGeneratorToolset;
         cmakeConfigureCommand += "\"";
@@ -125,8 +126,8 @@
       cmakeConfigureCommand += source_dir;
       cmakeConfigureCommand += "\"";
 
-      this->CTest->SetCTestConfiguration(
-        "ConfigureCommand", cmakeConfigureCommand.c_str(), this->Quiet);
+      this->CTest->SetCTestConfiguration("ConfigureCommand",
+                                         cmakeConfigureCommand, this->Quiet);
     } else {
       this->SetError(
         "Configure command is not specified. If this is a "
@@ -136,10 +137,10 @@
     }
   }
 
-  if (const char* labelsForSubprojects =
-        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+  if (cmProp labelsForSubprojects =
+        this->Makefile->GetDef("CTEST_LABELS_FOR_SUBPROJECTS")) {
     this->CTest->SetCTestConfiguration("LabelsForSubprojects",
-                                       labelsForSubprojects, this->Quiet);
+                                       *labelsForSubprojects, this->Quiet);
   }
 
   cmCTestConfigureHandler* handler = this->CTest->GetConfigureHandler();
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index b839c10..093b2d1 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -469,8 +469,8 @@
     }
 
     const std::string fileName = cmSystemTools::GetFilenameName(fullFileName);
-    std::string shortFileName =
-      this->CTest->GetShortPathToFile(fullFileName.c_str());
+    const std::string shortFileName =
+      this->CTest->GetShortPathToFile(fullFileName);
     const cmCTestCoverageHandlerContainer::SingleFileCoverageVector& fcov =
       file.second;
     covLogXML.StartElement("File");
@@ -538,7 +538,7 @@
     covSumXML.StartElement("File");
     covSumXML.Attribute("Name", fileName);
     covSumXML.Attribute("FullPath",
-                        this->CTest->GetShortPathToFile(fullFileName.c_str()));
+                        this->CTest->GetShortPathToFile(fullFileName));
     covSumXML.Attribute("Covered", tested + untested > 0 ? "true" : "false");
     covSumXML.Element("LOCTested", tested);
     covSumXML.Element("LOCUnTested", untested);
@@ -1887,8 +1887,8 @@
         // start the file output
         covLogXML.StartElement("File");
         covLogXML.Attribute("Name", i->first);
-        covLogXML.Attribute(
-          "FullPath", this->CTest->GetShortPathToFile(i->second.c_str()));
+        covLogXML.Attribute("FullPath",
+                            this->CTest->GetShortPathToFile(i->second));
         covLogXML.StartElement("Report");
         // write the bullseye header
         line = 0;
@@ -2064,8 +2064,7 @@
       total_untested += (totalFunctions - functionsCalled);
 
       std::string fileName = cmSystemTools::GetFilenameName(file);
-      std::string shortFileName =
-        this->CTest->GetShortPathToFile(file.c_str());
+      std::string shortFileName = this->CTest->GetShortPathToFile(file);
 
       float cper = static_cast<float>(percentBranch + percentFunction);
       if (totalBranches > 0) {
@@ -2266,7 +2265,7 @@
       // is the end of the target-wide labels.
       inTarget = false;
 
-      source = this->CTest->GetShortPathToFile(line.c_str());
+      source = this->CTest->GetShortPathToFile(line);
 
       // Label the source with the target labels.
       LabelSet& labelSet = this->SourceLabels[source];
@@ -2320,7 +2319,7 @@
 
   // The source is filtered out if it does not have any labels in
   // common with the filter set.
-  std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str());
+  std::string shortSrc = this->CTest->GetShortPathToFile(source);
   auto li = this->SourceLabels.find(shortSrc);
   if (li != this->SourceLabels.end()) {
     return !this->IntersectsFilter(li->second);
@@ -2342,14 +2341,14 @@
     std::vector<std::string> files = gl.GetFiles();
     for (std::string const& f : files) {
       if (this->ShouldIDoCoverage(f, cont->SourceDir, cont->BinaryDir)) {
-        extraMatches.insert(this->CTest->GetShortPathToFile(f.c_str()));
+        extraMatches.insert(this->CTest->GetShortPathToFile(f));
       }
     }
   }
 
   if (!extraMatches.empty()) {
     for (auto const& i : cont->TotalCoverage) {
-      std::string shortPath = this->CTest->GetShortPathToFile(i.first.c_str());
+      std::string shortPath = this->CTest->GetShortPathToFile(i.first);
       extraMatches.erase(shortPath);
     }
   }
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
index cc0b4ed..a71f550 100644
--- a/Source/CTest/cmCTestGenericHandler.cxx
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -100,7 +100,7 @@
                                                     << std::endl);
     return false;
   }
-  this->CTest->AddSubmitFile(part, ostr.str().c_str());
+  this->CTest->AddSubmitFile(part, ostr.str());
   return true;
 }
 
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index a755632..03b7173 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -14,6 +14,7 @@
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmWorkingDirectory.h"
@@ -125,23 +126,21 @@
   // CTEST_CONFIGURATION_TYPE script variable if it is defined.
   // The current script value trumps the -C argument on the command
   // line.
-  const char* ctestConfigType =
-    this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE");
+  cmProp ctestConfigType = this->Makefile->GetDef("CTEST_CONFIGURATION_TYPE");
   if (ctestConfigType) {
-    this->CTest->SetConfigType(ctestConfigType);
+    this->CTest->SetConfigType(*ctestConfigType);
   }
 
   if (!this->Build.empty()) {
     this->CTest->SetCTestConfiguration(
-      "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build).c_str(),
+      "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build),
       this->Quiet);
   } else {
     std::string const& bdir =
       this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY");
     if (!bdir.empty()) {
       this->CTest->SetCTestConfiguration(
-        "BuildDirectory", cmSystemTools::CollapseFullPath(bdir).c_str(),
-        this->Quiet);
+        "BuildDirectory", cmSystemTools::CollapseFullPath(bdir), this->Quiet);
     } else {
       cmCTestLog(this->CTest, ERROR_MESSAGE,
                  "CTEST_BINARY_DIRECTORY not set" << std::endl;);
@@ -151,20 +150,18 @@
     cmCTestLog(this->CTest, DEBUG,
                "Set source directory to: " << this->Source << std::endl);
     this->CTest->SetCTestConfiguration(
-      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
+      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source),
       this->Quiet);
   } else {
     this->CTest->SetCTestConfiguration(
       "SourceDirectory",
       cmSystemTools::CollapseFullPath(
-        this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY"))
-        .c_str(),
+        this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")),
       this->Quiet);
   }
 
-  if (const char* changeId =
-        this->Makefile->GetDefinition("CTEST_CHANGE_ID")) {
-    this->CTest->SetCTestConfiguration("ChangeId", changeId, this->Quiet);
+  if (cmProp changeId = this->Makefile->GetDef("CTEST_CHANGE_ID")) {
+    this->CTest->SetCTestConfiguration("ChangeId", *changeId, this->Quiet);
   }
 
   cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index d2772a7..822049e 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -354,7 +354,7 @@
   cmCTestMemCheckHandler::TestResultsVector::size_type cc;
   for (cmCTestTestResult const& result : this->TestResults) {
     std::string testPath = result.Path + "/" + result.Name;
-    xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
+    xml.Element("Test", this->CTest->GetShortPathToFile(testPath));
   }
   xml.EndElement(); // TestList
   cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.cxx b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
index ed14d06..a25cca4 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.cxx
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
@@ -15,7 +15,7 @@
   }
 
   for (std::string const& arg : args) {
-    this->CTest->ReadCustomConfigurationFileTree(arg.c_str(), this->Makefile);
+    this->CTest->ReadCustomConfigurationFileTree(arg, this->Makefile);
   }
 
   return true;
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 2c8e385..4d65c9b 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -619,11 +619,11 @@
     cmCTestMemCheckHandler* handler =
       static_cast<cmCTestMemCheckHandler*>(this->TestHandler);
     this->ActualCommand = handler->MemoryTester;
-    this->TestProperties->Args[1] = this->TestHandler->FindTheExecutable(
-      this->TestProperties->Args[1].c_str());
+    this->TestProperties->Args[1] =
+      this->TestHandler->FindTheExecutable(this->TestProperties->Args[1]);
   } else {
-    this->ActualCommand = this->TestHandler->FindTheExecutable(
-      this->TestProperties->Args[1].c_str());
+    this->ActualCommand =
+      this->TestHandler->FindTheExecutable(this->TestProperties->Args[1]);
     ++j; // skip the executable (it will be actualCommand)
   }
   std::string testCommand =
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
index fe68406..6398d66 100644
--- a/Source/CTest/cmCTestStartCommand.cxx
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -94,10 +94,9 @@
 
   std::string sourceDir = cmSystemTools::CollapseFullPath(src_dir);
   std::string binaryDir = cmSystemTools::CollapseFullPath(bld_dir);
-  this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir.c_str(),
+  this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir,
                                      this->Quiet);
-  this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir.c_str(),
-                                     this->Quiet);
+  this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir, this->Quiet);
 
   if (smodel) {
     cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 279216e..026e98f 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -35,12 +35,12 @@
 
 cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
 {
-  const char* submitURL = !this->SubmitURL.empty()
-    ? this->SubmitURL.c_str()
-    : this->Makefile->GetDefinition("CTEST_SUBMIT_URL");
+  const std::string* submitURL = !this->SubmitURL.empty()
+    ? &this->SubmitURL
+    : this->Makefile->GetDef("CTEST_SUBMIT_URL");
 
   if (submitURL) {
-    this->CTest->SetCTestConfiguration("SubmitURL", submitURL, this->Quiet);
+    this->CTest->SetCTestConfiguration("SubmitURL", *submitURL, this->Quiet);
   } else {
     this->CTest->SetCTestConfigurationFromCMakeVariable(
       this->Makefile, "DropMethod", "CTEST_DROP_METHOD", this->Quiet);
@@ -108,7 +108,7 @@
   if (this->PartsMentioned) {
     auto parts =
       cmMakeRange(this->Parts).transform([this](std::string const& arg) {
-        return this->CTest->GetPartFromName(arg.c_str());
+        return this->CTest->GetPartFromName(arg);
       });
     handler->SelectParts(std::set<cmCTest::Part>(parts.begin(), parts.end()));
   }
@@ -177,7 +177,7 @@
     !this->Files.empty() || cm::contains(keywords, "FILES");
 
   cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
-    cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
+    cmCTest::Part p = this->CTest->GetPartFromName(arg);
     if (p == cmCTest::PartCount) {
       std::ostringstream e;
       e << "Part name \"" << arg << "\" is invalid.";
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index ea36df5..5b54573 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -797,7 +797,7 @@
         gfile = gfile.substr(glen);
         cmCTestOptionalLog(this->CTest, DEBUG,
                            "Glob file: " << gfile << std::endl, this->Quiet);
-        this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfile.c_str());
+        this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfile);
       }
     } else {
       cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem globbing" << std::endl);
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index c71b409..cbc3c0c 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -13,6 +13,7 @@
 #include "cmCTestTestHandler.h"
 #include "cmDuration.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 
 void cmCTestTestCommand::BindArguments()
@@ -116,13 +117,13 @@
   unsigned long testLoad;
   const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
   if (!this->TestLoad.empty()) {
-    if (!cmStrToULong(this->TestLoad.c_str(), &testLoad)) {
+    if (!cmStrToULong(this->TestLoad, &testLoad)) {
       testLoad = 0;
       cmCTestLog(this->CTest, WARNING,
                  "Invalid value for 'TEST_LOAD' : " << this->TestLoad
                                                     << std::endl);
     }
-  } else if (ctestTestLoad && *ctestTestLoad) {
+  } else if (cmNonempty(ctestTestLoad)) {
     if (!cmStrToULong(ctestTestLoad, &testLoad)) {
       testLoad = 0;
       cmCTestLog(this->CTest, WARNING,
@@ -134,10 +135,10 @@
   }
   handler->SetTestLoad(testLoad);
 
-  if (const char* labelsForSubprojects =
-        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+  if (cmProp labelsForSubprojects =
+        this->Makefile->GetDef("CTEST_LABELS_FOR_SUBPROJECTS")) {
     this->CTest->SetCTestConfiguration("LabelsForSubprojects",
-                                       labelsForSubprojects, this->Quiet);
+                                       *labelsForSubprojects, this->Quiet);
   }
 
   handler->SetQuiet(this->Quiet);
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index d0dbaae..70e84ee 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1374,7 +1374,7 @@
   xml.StartElement("TestList");
   for (cmCTestTestResult const& result : this->TestResults) {
     std::string testPath = result.Path + "/" + result.Name;
-    xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
+    xml.Element("Test", this->CTest->GetShortPathToFile(testPath));
   }
   xml.EndElement(); // TestList
   for (cmCTestTestResult& result : this->TestResults) {
@@ -1483,8 +1483,8 @@
   }
   std::string testPath = result.Path + "/" + result.Name;
   xml.Element("Name", result.Name);
-  xml.Element("Path", this->CTest->GetShortPathToFile(result.Path.c_str()));
-  xml.Element("FullName", this->CTest->GetShortPathToFile(testPath.c_str()));
+  xml.Element("Path", this->CTest->GetShortPathToFile(result.Path));
+  xml.Element("FullName", this->CTest->GetShortPathToFile(testPath));
   xml.Element("FullCommandLine", result.FullCommandLine);
 }
 
@@ -1546,12 +1546,12 @@
 }
 
 // Find the appropriate executable to run for a test
-std::string cmCTestTestHandler::FindTheExecutable(const char* exe)
+std::string cmCTestTestHandler::FindTheExecutable(const std::string& exe)
 {
   std::string resConfig;
   std::vector<std::string> extraPaths;
   std::vector<std::string> failedPaths;
-  if (strcmp(exe, "NOT_AVAILABLE") == 0) {
+  if (exe == "NOT_AVAILABLE") {
     return exe;
   }
   return cmCTestTestHandler::FindExecutable(this->CTest, exe, resConfig,
@@ -1607,7 +1607,7 @@
 
 // Find the appropriate executable to run for a test
 std::string cmCTestTestHandler::FindExecutable(
-  cmCTest* ctest, const char* testCommand, std::string& resultingConfig,
+  cmCTest* ctest, const std::string& testCommand, std::string& resultingConfig,
   std::vector<std::string>& extraPaths, std::vector<std::string>& failed)
 {
   // now run the compiled test if we can find it
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 0d88c30..b26f8a6 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -198,7 +198,8 @@
                                 std::string filepath, std::string& filename);
 
   // full signature static method to find an executable
-  static std::string FindExecutable(cmCTest* ctest, const char* testCommand,
+  static std::string FindExecutable(cmCTest* ctest,
+                                    const std::string& testCommand,
                                     std::string& resultingConfig,
                                     std::vector<std::string>& extraPaths,
                                     std::vector<std::string>& failed);
@@ -309,7 +310,7 @@
   /**
    * Find the executable for a test
    */
-  std::string FindTheExecutable(const char* exe);
+  std::string FindTheExecutable(const std::string& exe);
 
   std::string GetTestStatus(cmCTestTestResult const&);
   void ExpandTestsToRunInformation(size_t numPossibleTests);
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 673eb9a..95cae13 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -11,14 +11,13 @@
 {
   if (!this->Source.empty()) {
     this->CTest->SetCTestConfiguration(
-      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
+      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source),
       this->Quiet);
   } else {
     this->CTest->SetCTestConfiguration(
       "SourceDirectory",
       cmSystemTools::CollapseFullPath(
-        this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY"))
-        .c_str(),
+        this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")),
       this->Quiet);
   }
   std::string source_dir =
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index a549117..9ee1c17 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -545,17 +545,17 @@
 #  endif
 #  ifdef SIGABRT
     case SIGABRT:
-      exception_str = "Child aborted";
+      exception_str = "Subprocess aborted";
       break;
 #  endif
 #  ifdef SIGKILL
     case SIGKILL:
-      exception_str = "Child killed";
+      exception_str = "Subprocess killed";
       break;
 #  endif
 #  ifdef SIGTERM
     case SIGTERM:
-      exception_str = "Child terminated";
+      exception_str = "Subprocess terminated";
       break;
 #  endif
 #  ifdef SIGHUP
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 4254e2e..a5fde89 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -394,7 +394,7 @@
   return this->Impl->CompressTestOutput;
 }
 
-cmCTest::Part cmCTest::GetPartFromName(const char* name)
+cmCTest::Part cmCTest::GetPartFromName(const std::string& name)
 {
   // Look up by lower-case to make names case-insensitive.
   std::string lower_name = cmSystemTools::LowerCase(name);
@@ -458,8 +458,7 @@
   cm.GetCurrentSnapshot().SetDefaultDefinitions();
   cmGlobalGenerator gg(&cm);
   cmMakefile mf(&gg, cm.GetCurrentSnapshot());
-  if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir.c_str(),
-                                             &mf)) {
+  if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir, &mf)) {
     cmCTestOptionalLog(
       this, DEBUG, "Cannot find custom configuration file tree" << std::endl,
       quiet);
@@ -523,7 +522,7 @@
         std::string model;
         if (cmSystemTools::GetLineFromStream(tfin, model) &&
             !this->Impl->Parts[PartStart] && !command) {
-          this->Impl->TestModel = GetTestModelFromString(model.c_str());
+          this->Impl->TestModel = GetTestModelFromString(model);
         }
         tfin.close();
       }
@@ -579,7 +578,7 @@
         cmSystemTools::GetLineFromStream(tfin, tag);
         cmSystemTools::GetLineFromStream(tfin, group);
         if (cmSystemTools::GetLineFromStream(tfin, modelStr)) {
-          model = GetTestModelFromString(modelStr.c_str());
+          model = GetTestModelFromString(modelStr);
         }
         tfin.close();
       }
@@ -793,7 +792,7 @@
   return this->Impl->TestModel;
 }
 
-bool cmCTest::SetTest(const char* ttype, bool report)
+bool cmCTest::SetTest(const std::string& ttype, bool report)
 {
   if (cmSystemTools::LowerCase(ttype) == "all") {
     for (Part p = PartStart; p != PartCount; p = Part(p + 1)) {
@@ -856,7 +855,7 @@
   return true;
 }
 
-bool cmCTest::AddIfExists(Part part, const char* file)
+bool cmCTest::AddIfExists(Part part, const std::string& file)
 {
   if (this->CTestFileExists(file)) {
     this->AddSubmitFile(part, file);
@@ -1008,7 +1007,7 @@
   if (this->Impl->Parts[PartNotes]) {
     this->UpdateCTestConfiguration();
     if (!this->Impl->NotesFiles.empty()) {
-      this->GenerateNotesFile(this->Impl->NotesFiles.c_str());
+      this->GenerateNotesFile(this->Impl->NotesFiles);
     }
   }
   if (this->Impl->Parts[PartSubmit]) {
@@ -1037,9 +1036,9 @@
   return "Experimental";
 }
 
-int cmCTest::GetTestModelFromString(const char* str)
+int cmCTest::GetTestModelFromString(const std::string& str)
 {
-  if (!str) {
+  if (str.empty()) {
     return cmCTest::EXPERIMENTAL;
   }
   std::string rstr = cmSystemTools::LowerCase(str);
@@ -1565,9 +1564,9 @@
   return 0;
 }
 
-int cmCTest::GenerateNotesFile(const char* cfiles)
+int cmCTest::GenerateNotesFile(const std::string& cfiles)
 {
-  if (!cfiles) {
+  if (cfiles.empty()) {
     return 1;
   }
 
@@ -1650,14 +1649,14 @@
                                             << std::endl;);
       return false;
     }
-    this->AddSubmitFile(PartExtraFiles, file.c_str());
+    this->AddSubmitFile(PartExtraFiles, file);
   }
   return true;
 }
 
-bool cmCTest::SubmitExtraFiles(const char* cfiles)
+bool cmCTest::SubmitExtraFiles(const std::string& cfiles)
 {
-  if (!cfiles) {
+  if (cfiles.empty()) {
     return true;
   }
 
@@ -1941,7 +1940,7 @@
   else if (this->CheckArgument(arg, "-C"_s, "--build-config") &&
            i < args.size() - 1) {
     i++;
-    this->SetConfigType(args[i].c_str());
+    this->SetConfigType(args[i]);
   }
 
   else if (this->CheckArgument(arg, "--debug"_s)) {
@@ -2016,7 +2015,7 @@
   else if (this->CheckArgument(arg, "-O"_s, "--output-log") &&
            i < args.size() - 1) {
     i++;
-    this->SetOutputLogFileName(args[i].c_str());
+    this->SetOutputLogFileName(args[i]);
   }
 
   else if (this->CheckArgument(arg, "--tomorrow-tag"_s)) {
@@ -2048,7 +2047,7 @@
     this->Impl->ProduceXML = true;
     this->SetTest("Notes");
     i++;
-    this->SetNotesFiles(args[i].c_str());
+    this->SetNotesFiles(args[i]);
     return true;
   }
 
@@ -2305,7 +2304,7 @@
       this->Impl->ProduceXML = true;
       this->SetTest("Submit");
       i++;
-      if (!this->SubmitExtraFiles(args[i].c_str())) {
+      if (!this->SubmitExtraFiles(args[i])) {
         return 0;
       }
     }
@@ -2376,7 +2375,7 @@
       (i < args.size() - 1)) {
     this->Impl->ProduceXML = true;
     i++;
-    if (!this->SetTest(args[i].c_str(), false)) {
+    if (!this->SetTest(args[i], false)) {
       success = false;
       cmCTestLog(this, ERROR_MESSAGE,
                  "CTest -T called with incorrect option: " << args[i]
@@ -2491,11 +2490,8 @@
   return retv;
 }
 
-void cmCTest::SetNotesFiles(const char* notes)
+void cmCTest::SetNotesFiles(const std::string& notes)
 {
-  if (!notes) {
-    return;
-  }
   this->Impl->NotesFiles = notes;
 }
 
@@ -2561,7 +2557,8 @@
   this->Impl->ScheduleType = type;
 }
 
-int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
+int cmCTest::ReadCustomConfigurationFileTree(const std::string& dir,
+                                             cmMakefile* mf)
 {
   bool found = false;
   cmCTestLog(this, DEBUG,
@@ -2648,7 +2645,7 @@
   val = atoi(dval);
 }
 
-std::string cmCTest::GetShortPathToFile(const char* cfname)
+std::string cmCTest::GetShortPathToFile(const std::string& cfname)
 {
   const std::string& sourceDir = cmSystemTools::CollapseFullPath(
     this->GetCTestConfiguration("SourceDirectory"));
@@ -2712,18 +2709,17 @@
   this->Impl->CTestConfiguration.clear();
 }
 
-void cmCTest::SetCTestConfiguration(const char* name, const char* value,
+void cmCTest::SetCTestConfiguration(const char* name, const std::string& value,
                                     bool suppress)
 {
   cmCTestOptionalLog(this, HANDLER_VERBOSE_OUTPUT,
-                     "SetCTestConfiguration:"
-                       << name << ":" << (value ? value : "(null)") << "\n",
+                     "SetCTestConfiguration:" << name << ":" << value << "\n",
                      suppress);
 
   if (!name) {
     return;
   }
-  if (!value) {
+  if (value.empty()) {
     this->Impl->CTestConfiguration.erase(name);
     return;
   }
@@ -2928,7 +2924,7 @@
   return this->Impl->BuildID;
 }
 
-void cmCTest::AddSubmitFile(Part part, const char* name)
+void cmCTest::AddSubmitFile(Part part, const std::string& name)
 {
   this->Impl->Parts[part].SubmitFiles.emplace_back(name);
 }
@@ -2964,9 +2960,9 @@
   this->Impl->CTestConfigurationOverwrites[key] = value;
 }
 
-void cmCTest::SetConfigType(const char* ct)
+void cmCTest::SetConfigType(const std::string& ct)
 {
-  this->Impl->ConfigType = ct ? ct : "";
+  this->Impl->ConfigType = ct;
   cmSystemTools::ReplaceString(this->Impl->ConfigType, ".\\", "");
   std::string confTypeEnv = "CMAKE_CONFIG_TYPE=" + this->Impl->ConfigType;
   cmSystemTools::PutEnv(confTypeEnv);
@@ -2976,8 +2972,7 @@
   cmMakefile* mf, const char* dconfig, const std::string& cmake_var,
   bool suppress)
 {
-  const char* ctvar;
-  ctvar = mf->GetDefinition(cmake_var);
+  cmProp ctvar = mf->GetDef(cmake_var);
   if (!ctvar) {
     return false;
   }
@@ -2985,7 +2980,7 @@
                      "SetCTestConfigurationFromCMakeVariable:"
                        << dconfig << ":" << cmake_var << std::endl,
                      suppress);
-  this->SetCTestConfiguration(dconfig, ctvar, suppress);
+  this->SetCTestConfiguration(dconfig, *ctvar, suppress);
   return true;
 }
 
@@ -3086,9 +3081,9 @@
   return result;
 }
 
-void cmCTest::SetOutputLogFileName(const char* name)
+void cmCTest::SetOutputLogFileName(const std::string& name)
 {
-  if (name) {
+  if (!name.empty()) {
     this->Impl->OutputLogFile = cm::make_unique<cmGeneratedFileStream>(name);
   } else {
     this->Impl->OutputLogFile.reset();
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index a39b8fe..1e0fb8c 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -64,7 +64,7 @@
 
   /** Get a testing part id from its string name.  Returns PartCount
       if the string does not name a valid part.  */
-  Part GetPartFromName(const char* name);
+  Part GetPartFromName(const std::string& name);
 
   /** Process Command line arguments */
   int Run(std::vector<std::string>&, std::string* output = nullptr);
@@ -127,12 +127,12 @@
    * Check if CTest file exists
    */
   bool CTestFileExists(const std::string& filename);
-  bool AddIfExists(Part part, const char* file);
+  bool AddIfExists(Part part, const std::string& file);
 
   /**
    * Set the cmake test
    */
-  bool SetTest(const char*, bool report = true);
+  bool SetTest(const std::string&, bool report = true);
 
   /**
    * Set the cmake test mode (experimental, nightly, continuous).
@@ -141,11 +141,11 @@
   int GetTestModel() const;
 
   std::string GetTestModelString();
-  static int GetTestModelFromString(const char* str);
+  static int GetTestModelFromString(const std::string& str);
   static std::string CleanString(const std::string& str,
                                  std::string::size_type spos = 0);
   std::string GetCTestConfiguration(const std::string& name);
-  void SetCTestConfiguration(const char* name, const char* value,
+  void SetCTestConfiguration(const char* name, const std::string& value,
                              bool suppress = false);
   void EmptyCTestConfiguration();
 
@@ -161,7 +161,7 @@
   cmCTest& operator=(const cmCTest&) = delete;
 
   /** Set the notes files to be created. */
-  void SetNotesFiles(const char* notes);
+  void SetNotesFiles(const std::string& notes);
 
   void PopulateCustomVector(cmMakefile* mf, const std::string& definition,
                             std::vector<std::string>& vec);
@@ -272,7 +272,7 @@
    * This means if the file is in binary or
    * source directory, it will become /.../relative/path/to/file
    */
-  std::string GetShortPathToFile(const char* fname);
+  std::string GetShortPathToFile(const std::string& fname);
 
   enum
   {
@@ -354,14 +354,14 @@
   int GenerateDoneFile();
 
   /** Submit extra files to the server */
-  bool SubmitExtraFiles(const char* files);
+  bool SubmitExtraFiles(const std::string& files);
   bool SubmitExtraFiles(std::vector<std::string> const& files);
 
   /** Set the output log file name */
-  void SetOutputLogFileName(const char* name);
+  void SetOutputLogFileName(const std::string& name);
 
   /** Set the visual studio or Xcode config type */
-  void SetConfigType(const char* ct);
+  void SetConfigType(const std::string& ct);
 
   /** Various log types */
   enum
@@ -399,14 +399,14 @@
   std::string GetBuildID() const;
 
   /** Add file to be submitted */
-  void AddSubmitFile(Part part, const char* name);
+  void AddSubmitFile(Part part, const std::string& name);
   std::vector<std::string> const& GetSubmitFiles(Part part) const;
   void ClearSubmitFiles(Part part);
 
   /**
    * Read the custom configuration files and apply them to the current ctest
    */
-  int ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf);
+  int ReadCustomConfigurationFileTree(const std::string& dir, cmMakefile* mf);
 
   std::vector<std::string>& GetInitialCommandLineArguments();
 
@@ -462,7 +462,7 @@
   void SetRunCurrentScript(bool value);
 
 private:
-  int GenerateNotesFile(const char* files);
+  int GenerateNotesFile(const std::string& files);
 
   void BlockTestErrorDiagnostics();
 
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index fbb95e1..43cceae 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -832,8 +832,7 @@
 
   // We can support link type switching only if all needed flags are
   // known.
-  if (static_link_type_flag && *static_link_type_flag &&
-      shared_link_type_flag && *shared_link_type_flag) {
+  if (cmNonempty(static_link_type_flag) && cmNonempty(shared_link_type_flag)) {
     this->LinkTypeEnabled = true;
     this->StaticLinkTypeFlag = static_link_type_flag;
     this->SharedLinkTypeFlag = shared_link_type_flag;
@@ -1768,7 +1767,7 @@
         std::string d = ri;
         if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
           d.erase(0, rootPath.size());
-        } else if (stagePath && *stagePath && cmHasPrefix(d, stagePath)) {
+        } else if (cmNonempty(stagePath) && cmHasPrefix(d, stagePath)) {
           d.erase(0, strlen(stagePath));
           d = cmStrCat(installPrefix, '/', d);
           cmSystemTools::ConvertToUnixSlashes(d);
@@ -1799,7 +1798,7 @@
           std::string d = ri;
           if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
             d.erase(0, rootPath.size());
-          } else if (stagePath && *stagePath && cmHasPrefix(d, stagePath)) {
+          } else if (cmNonempty(stagePath) && cmHasPrefix(d, stagePath)) {
             d.erase(0, strlen(stagePath));
             d = cmStrCat(installPrefix, '/', d);
             cmSystemTools::ConvertToUnixSlashes(d);
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 42c8a04..e717f71 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -185,7 +185,7 @@
 {
   // Get the depender.
   cmGeneratorTarget const* depender = this->Targets[depender_index];
-  if (depender->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!depender->IsInBuildSystem()) {
     return;
   }
 
@@ -199,16 +199,18 @@
     std::vector<std::string> const& configs =
       depender->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
     for (std::string const& it : configs) {
-      cmLinkImplementation const* impl = depender->GetLinkImplementation(it);
-
       // A target should not depend on itself.
       emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
       emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
-      for (cmLinkImplItem const& lib : impl->Libraries) {
-        // Don't emit the same library twice for this target.
-        if (emitted.insert(lib).second) {
-          this->AddTargetDepend(depender_index, lib, true, false);
-          this->AddInterfaceDepends(depender_index, lib, it, emitted);
+
+      if (cmLinkImplementation const* impl =
+            depender->GetLinkImplementation(it)) {
+        for (cmLinkImplItem const& lib : impl->Libraries) {
+          // Don't emit the same library twice for this target.
+          if (emitted.insert(lib).second) {
+            this->AddTargetDepend(depender_index, lib, true, false);
+            this->AddInterfaceDepends(depender_index, lib, it, emitted);
+          }
         }
       }
 
@@ -357,10 +359,9 @@
   int depender_index, cmGeneratorTarget const* dependee,
   cmListFileBacktrace const& dependee_backtrace, bool linking, bool cross)
 {
-  if (dependee->IsImported() ||
-      dependee->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-    // Skip IMPORTED and INTERFACE targets but follow their utility
-    // dependencies.
+  if (!dependee->IsInBuildSystem()) {
+    // Skip targets that are not in the buildsystem but follow their
+    // utility dependencies.
     std::set<cmLinkItem> const& utils = dependee->GetUtilityItems();
     for (cmLinkItem const& i : utils) {
       if (cmGeneratorTarget const* transitive_dependee = i.Target) {
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 8465c58..63c1484 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -1045,14 +1045,14 @@
   const char* config =
     this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
   // if a config was specified try that first
-  if (config && config[0]) {
+  if (cmNonempty(config)) {
     std::string tmp = cmStrCat('/', config);
     searchDirs.push_back(std::move(tmp));
   }
   searchDirs.emplace_back("/Debug");
 #if defined(__APPLE__)
   std::string app = "/" + targetName + ".app";
-  if (config && config[0]) {
+  if (cmNonempty(config)) {
     std::string tmp = cmStrCat('/', config, app);
     searchDirs.push_back(std::move(tmp));
   }
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 8f02d95..54418df 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -395,7 +395,7 @@
                   << ' ' << stampFileForShell;
       cmMakefile* mf = this->LocalGenerator->GetMakefile();
       const char* cid = mf->GetDefinition("CMAKE_Fortran_COMPILER_ID");
-      if (cid && *cid) {
+      if (cmNonempty(cid)) {
         makeDepends << ' ' << cid;
       }
       makeDepends << '\n';
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 7101e22..9db8b85 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -1394,8 +1394,10 @@
 {
   int realsize = static_cast<int>(size * nmemb);
   cmsys::ofstream* fout = static_cast<cmsys::ofstream*>(data);
-  const char* chPtr = static_cast<char*>(ptr);
-  fout->write(chPtr, realsize);
+  if (fout) {
+    const char* chPtr = static_cast<char*>(ptr);
+    fout->write(chPtr, realsize);
+  }
   return realsize;
 }
 
@@ -1551,15 +1553,14 @@
 {
 #if !defined(CMAKE_BOOTSTRAP)
   auto i = args.begin();
-  if (args.size() < 3) {
-    status.SetError("DOWNLOAD must be called with at least three arguments.");
+  if (args.size() < 2) {
+    status.SetError("DOWNLOAD must be called with at least two arguments.");
     return false;
   }
   ++i; // Get rid of subcommand
   std::string url = *i;
   ++i;
-  std::string file = *i;
-  ++i;
+  std::string file;
 
   long timeout = 0;
   long inactivity_timeout = 0;
@@ -1690,6 +1691,8 @@
         return false;
       }
       curl_headers.push_back(*i);
+    } else if (file.empty()) {
+      file = *i;
     } else {
       // Do not return error for compatibility reason.
       std::string err = cmStrCat("Unexpected argument: ", *i);
@@ -1697,11 +1700,18 @@
     }
     ++i;
   }
+  // Can't calculate hash if we don't save the file.
+  // TODO Incrementally calculate hash in the write callback as the file is
+  // being downloaded so this check can be relaxed.
+  if (file.empty() && hash) {
+    status.SetError("DOWNLOAD cannot calculate hash if file is not saved.");
+    return false;
+  }
   // If file exists already, and caller specified an expected md5 or sha,
   // and the existing file already has the expected hash, then simply
   // return.
   //
-  if (cmSystemTools::FileExists(file) && hash.get()) {
+  if (!file.empty() && cmSystemTools::FileExists(file) && hash.get()) {
     std::string msg;
     std::string actualHash = hash->HashFile(file);
     if (actualHash == expectedHash) {
@@ -1716,20 +1726,26 @@
   // Make sure parent directory exists so we can write to the file
   // as we receive downloaded bits from curl...
   //
-  std::string dir = cmSystemTools::GetFilenamePath(file);
-  if (!dir.empty() && !cmSystemTools::FileExists(dir) &&
-      !cmSystemTools::MakeDirectory(dir)) {
-    std::string errstring = "DOWNLOAD error: cannot create directory '" + dir +
-      "' - Specify file by full path name and verify that you "
-      "have directory creation and file write privileges.";
-    status.SetError(errstring);
-    return false;
+  if (!file.empty()) {
+    std::string dir = cmSystemTools::GetFilenamePath(file);
+    if (!dir.empty() && !cmSystemTools::FileExists(dir) &&
+        !cmSystemTools::MakeDirectory(dir)) {
+      std::string errstring = "DOWNLOAD error: cannot create directory '" +
+        dir +
+        "' - Specify file by full path name and verify that you "
+        "have directory creation and file write privileges.";
+      status.SetError(errstring);
+      return false;
+    }
   }
 
-  cmsys::ofstream fout(file.c_str(), std::ios::binary);
-  if (!fout) {
-    status.SetError("DOWNLOAD cannot open file for write.");
-    return false;
+  cmsys::ofstream fout;
+  if (!file.empty()) {
+    fout.open(file.c_str(), std::ios::binary);
+    if (!fout) {
+      status.SetError("DOWNLOAD cannot open file for write.");
+      return false;
+    }
   }
 
 #  if defined(_WIN32)
@@ -1791,7 +1807,8 @@
 
   cmFileCommandVectorOfChar chunkDebug;
 
-  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fout);
+  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA,
+                           file.empty() ? nullptr : &fout);
   check_curl_result(res, "DOWNLOAD cannot set write data: ");
 
   res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &chunkDebug);
@@ -1865,8 +1882,10 @@
 
   // Explicitly flush/close so we can measure the md5 accurately.
   //
-  fout.flush();
-  fout.close();
+  if (!file.empty()) {
+    fout.flush();
+    fout.close();
+  }
 
   // Verify MD5 sum if requested:
   //
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 627e05b..5d44a06 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -173,7 +173,7 @@
   // check if default dir creation permissions were set
   const char* default_dir_install_permissions = this->Makefile->GetDefinition(
     "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (default_dir_install_permissions && *default_dir_install_permissions) {
+  if (cmNonempty(default_dir_install_permissions)) {
     std::vector<std::string> items =
       cmExpandedList(default_dir_install_permissions);
     for (const auto& arg : items) {
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 3e97150..3401eff 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -208,10 +208,10 @@
   const char* sysrootLink =
     this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK");
   const char* rootPath = this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH");
-  const bool noSysroot = !sysroot || !*sysroot;
-  const bool noCompileSysroot = !sysrootCompile || !*sysrootCompile;
-  const bool noLinkSysroot = !sysrootLink || !*sysrootLink;
-  const bool noRootPath = !rootPath || !*rootPath;
+  const bool noSysroot = !cmNonempty(sysroot);
+  const bool noCompileSysroot = !cmNonempty(sysrootCompile);
+  const bool noLinkSysroot = !cmNonempty(sysrootLink);
+  const bool noRootPath = !cmNonempty(rootPath);
   if (noSysroot && noCompileSysroot && noLinkSysroot && noRootPath) {
     return;
   }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index b10ce89..41cff01 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1089,6 +1089,27 @@
   return this->Target->GetPostBuildCommands();
 }
 
+bool cmGeneratorTarget::IsInBuildSystem() const
+{
+  if (this->IsImported()) {
+    return false;
+  }
+  switch (this->Target->GetType()) {
+    case cmStateEnums::EXECUTABLE:
+    case cmStateEnums::STATIC_LIBRARY:
+    case cmStateEnums::SHARED_LIBRARY:
+    case cmStateEnums::MODULE_LIBRARY:
+    case cmStateEnums::OBJECT_LIBRARY:
+    case cmStateEnums::UTILITY:
+    case cmStateEnums::GLOBAL_TARGET:
+      return true;
+    case cmStateEnums::INTERFACE_LIBRARY:
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
+  }
+  return false;
+}
+
 bool cmGeneratorTarget::IsImported() const
 {
   return this->Target->IsImported();
@@ -1099,6 +1120,11 @@
   return this->Target->IsImportedGloballyVisible();
 }
 
+bool cmGeneratorTarget::CanCompileSources() const
+{
+  return this->Target->CanCompileSources();
+}
+
 const std::string& cmGeneratorTarget::GetLocationForBuild() const
 {
   static std::string location;
@@ -1365,7 +1391,7 @@
 
     for (const cmLinkImplItem& library : libraries->Libraries) {
       if (const cmGeneratorTarget* dependency = library.Target) {
-        if (dependency->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+        if (!dependency->IsInBuildSystem()) {
           continue;
         }
         if (cm::contains(dependency->GetAllConfigCompileLanguages(),
@@ -1995,7 +2021,7 @@
     std::string sepVar =
       cmStrCat("CMAKE_SHARED_LIBRARY_RUNTIME_", ll, "_FLAG_SEP");
     const char* sep = this->Makefile->GetDefinition(sepVar);
-    if (sep && *sep) {
+    if (cmNonempty(sep)) {
       // TODO: Add ELF check to ABI detection and get rid of
       // CMAKE_EXECUTABLE_FORMAT.
       if (const char* fmt =
@@ -2441,6 +2467,12 @@
 cmGeneratorTarget::LinkClosure const* cmGeneratorTarget::GetLinkClosure(
   const std::string& config) const
 {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
+    static LinkClosure const empty = { {}, {} };
+    return &empty;
+  }
+
   std::string key(cmSystemTools::UpperCase(config));
   auto i = this->LinkClosureMap.find(key);
   if (i == this->LinkClosureMap.end()) {
@@ -2757,6 +2789,12 @@
 cmGeneratorTarget::GetLinkImplementationClosure(
   const std::string& config) const
 {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
+    static std::vector<const cmGeneratorTarget*> const empty;
+    return empty;
+  }
+
   LinkImplClosure& tgts = this->LinkImplClosureMap[config];
   if (!tgts.Done) {
     tgts.Done = true;
@@ -2764,6 +2802,7 @@
 
     cmLinkImplementationLibraries const* impl =
       this->GetLinkImplementationLibraries(config);
+    assert(impl);
 
     for (cmLinkImplItem const& lib : impl->Libraries) {
       processILibs(config, this, lib,
@@ -2813,29 +2852,26 @@
   this->CurrentEntry = nullptr;
 
   // Queue all the source files already specified for the target.
-  if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-    std::set<cmSourceFile*> emitted;
-    std::vector<std::string> const& configs =
-      this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
-    for (std::string const& c : configs) {
-      std::vector<cmSourceFile*> sources;
-      this->GeneratorTarget->GetSourceFiles(sources, c);
-      for (cmSourceFile* sf : sources) {
-        const std::set<cmGeneratorTarget const*> tgts =
-          this->GlobalGenerator->GetFilenameTargetDepends(sf);
-        if (cm::contains(tgts, this->GeneratorTarget)) {
-          std::ostringstream e;
-          e << "Evaluation output file\n  \"" << sf->ResolveFullPath()
-            << "\"\ndepends on the sources of a target it is used in.  This "
-               "is a dependency loop and is not allowed.";
-          this->GeneratorTarget->LocalGenerator->IssueMessage(
-            MessageType::FATAL_ERROR, e.str());
-          return;
-        }
-        if (emitted.insert(sf).second &&
-            this->SourcesQueued.insert(sf).second) {
-          this->SourceQueue.push(sf);
-        }
+  std::set<cmSourceFile*> emitted;
+  std::vector<std::string> const& configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  for (std::string const& c : configs) {
+    std::vector<cmSourceFile*> sources;
+    this->GeneratorTarget->GetSourceFiles(sources, c);
+    for (cmSourceFile* sf : sources) {
+      const std::set<cmGeneratorTarget const*> tgts =
+        this->GlobalGenerator->GetFilenameTargetDepends(sf);
+      if (cm::contains(tgts, this->GeneratorTarget)) {
+        std::ostringstream e;
+        e << "Evaluation output file\n  \"" << sf->ResolveFullPath()
+          << "\"\ndepends on the sources of a target it is used in.  This "
+             "is a dependency loop and is not allowed.";
+        this->GeneratorTarget->LocalGenerator->IssueMessage(
+          MessageType::FATAL_ERROR, e.str());
+        return;
+      }
+      if (emitted.insert(sf).second && this->SourcesQueued.insert(sf).second) {
+        this->SourceQueue.push(sf);
       }
     }
   }
@@ -3413,23 +3449,24 @@
                       &dagChecker, entries);
 
   if (this->Makefile->IsOn("APPLE")) {
-    cmLinkImplementationLibraries const* impl =
-      this->GetLinkImplementationLibraries(config);
-    for (cmLinkImplItem const& lib : impl->Libraries) {
-      std::string libDir = cmSystemTools::CollapseFullPath(
-        lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
+    if (cmLinkImplementationLibraries const* impl =
+          this->GetLinkImplementationLibraries(config)) {
+      for (cmLinkImplItem const& lib : impl->Libraries) {
+        std::string libDir = cmSystemTools::CollapseFullPath(
+          lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
 
-      static cmsys::RegularExpression frameworkCheck(
-        "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
-      if (!frameworkCheck.find(libDir)) {
-        continue;
+        static cmsys::RegularExpression frameworkCheck(
+          "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
+        if (!frameworkCheck.find(libDir)) {
+          continue;
+        }
+
+        libDir = frameworkCheck.match(1);
+
+        EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
+        ee.Values.emplace_back(std::move(libDir));
+        entries.Entries.emplace_back(std::move(ee));
       }
-
-      libDir = frameworkCheck.match(1);
-
-      EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
-      ee.Values.emplace_back(std::move(libDir));
-      entries.Entries.emplace_back(std::move(ee));
     }
   }
 
@@ -6524,15 +6561,20 @@
                           iface.HadHeadSensitiveCondition,
                           iface.HadContextSensitiveCondition,
                           iface.HadLinkLanguageSensitiveCondition);
-  } else if (!cmp0022NEW)
+    return;
+  }
+
   // If CMP0022 is NEW then the plain tll signature sets the
   // INTERFACE_LINK_LIBRARIES, so if we get here then the project
   // cleared the property explicitly and we should not fall back
   // to the link implementation.
-  {
-    // The link implementation is the default link interface.
-    cmLinkImplementationLibraries const* impl =
-      this->GetLinkImplementationLibrariesInternal(config, headTarget);
+  if (cmp0022NEW) {
+    return;
+  }
+
+  // The link implementation is the default link interface.
+  if (cmLinkImplementationLibraries const* impl =
+        this->GetLinkImplementationLibrariesInternal(config, headTarget)) {
     iface.Libraries.insert(iface.Libraries.end(), impl->Libraries.begin(),
                            impl->Libraries.end());
     if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
@@ -6826,8 +6868,8 @@
 const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
   const std::string& config, bool secondPass) const
 {
-  // There is no link implementation for imported targets.
-  if (this->IsImported()) {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
     return nullptr;
   }
 
@@ -6990,6 +7032,11 @@
 void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
                                      const std::string& config) const
 {
+  // Targets that do not compile anything have no languages.
+  if (!this->CanCompileSources()) {
+    return;
+  }
+
   std::vector<cmSourceFile*> sourceFiles;
   this->GetSourceFiles(sourceFiles, config);
   for (cmSourceFile* src : sourceFiles) {
@@ -7085,8 +7132,8 @@
 cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
   const std::string& config, cmGeneratorTarget const* head) const
 {
-  // There is no link implementation for imported targets.
-  if (this->IsImported()) {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
     return nullptr;
   }
 
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 08aa015..4a03f65 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -45,8 +45,10 @@
 
   cmGlobalGenerator* GetGlobalGenerator() const;
 
+  bool IsInBuildSystem() const;
   bool IsImported() const;
   bool IsImportedGloballyVisible() const;
+  bool CanCompileSources() const;
   const std::string& GetLocation(const std::string& config) const;
 
   std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index 5eff3b8..9e5bbca 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -42,12 +42,7 @@
     // for all targets in the directory.
     for (const auto& gt : lg->GetGeneratorTargets()) {
       cmStateEnums::TargetType const type = gt->GetType();
-      if (type != cmStateEnums::EXECUTABLE &&
-          type != cmStateEnums::STATIC_LIBRARY &&
-          type != cmStateEnums::SHARED_LIBRARY &&
-          type != cmStateEnums::MODULE_LIBRARY &&
-          type != cmStateEnums::OBJECT_LIBRARY &&
-          type != cmStateEnums::UTILITY) {
+      if (type == cmStateEnums::GLOBAL_TARGET || !gt->IsInBuildSystem()) {
         continue;
       }
       DirectoryTarget::Target t;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 17c7e99..530bb59 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -302,9 +302,7 @@
   bool failed = false;
   for (const auto& localGen : this->LocalGenerators) {
     for (const auto& target : localGen->GetGeneratorTargets()) {
-      if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
-          target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
-          target->GetType() == cmStateEnums::TargetType::UTILITY ||
+      if (!target->CanCompileSources() ||
           cmIsOn(target->GetProperty("ghs_integrity_app"))) {
         continue;
       }
@@ -358,9 +356,7 @@
   bool failed = false;
   for (const auto& generator : this->LocalGenerators) {
     for (const auto& target : generator->GetGeneratorTargets()) {
-      if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
-          target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
-          target->GetType() == cmStateEnums::TargetType::UTILITY ||
+      if (!target->CanCompileSources() ||
           cmIsOn(target->GetProperty("ghs_integrity_app"))) {
         continue;
       }
@@ -405,15 +401,13 @@
       "all generators must specify this->FindMakeProgramFile");
     return false;
   }
-  if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") ||
-      cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+  if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
     std::string setMakeProgram = mf->GetModulesFile(this->FindMakeProgramFile);
     if (!setMakeProgram.empty()) {
       mf->ReadListFile(setMakeProgram);
     }
   }
-  if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") ||
-      cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+  if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
     std::ostringstream err;
     err << "CMake was unable to find a build program corresponding to \""
         << this->GetName() << "\".  CMAKE_MAKE_PROGRAM is not set.  You "
@@ -779,7 +773,7 @@
     std::string compilerEnv = cmStrCat("CMAKE_", lang, "_COMPILER_ENV_VAR");
     std::ostringstream noCompiler;
     const char* compilerFile = mf->GetDefinition(compilerName);
-    if (!compilerFile || !*compilerFile || cmIsNOTFOUND(compilerFile)) {
+    if (!cmNonempty(compilerFile) || cmIsNOTFOUND(compilerFile)) {
       /* clang-format off */
       noCompiler <<
         "No " << compilerName << " could be found.\n"
@@ -1595,9 +1589,7 @@
   for (const auto& lg : this->LocalGenerators) {
     lg->CreateEvaluationFileOutputs();
     for (const auto& gt : lg->GetGeneratorTargets()) {
-      if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          gt->GetType() == cmStateEnums::UTILITY ||
-          gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
+      if (!gt->CanCompileSources()) {
         continue;
       }
       lg->AddUnityBuild(gt.get());
@@ -1609,9 +1601,7 @@
   }
   for (const auto& lg : this->LocalGenerators) {
     for (const auto& gt : lg->GetGeneratorTargets()) {
-      if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          gt->GetType() == cmStateEnums::UTILITY ||
-          gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
+      if (!gt->CanCompileSources()) {
         continue;
       }
       // Handle targets that re-use a PCH from an above-handled target.
@@ -2165,7 +2155,7 @@
 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
                                    const cmGeneratorTarget* target) const
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return true;
   }
   cmMakefile* mf = root->GetMakefile();
@@ -2454,7 +2444,7 @@
   gti.WorkingDir = mf->GetCurrentBinaryDirectory();
   cmCustomCommandLine singleLine;
   singleLine.push_back(cmSystemTools::GetCPackCommand());
-  if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+  if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
     singleLine.push_back("-C");
     singleLine.push_back(cmakeCfgIntDir);
   }
@@ -2539,7 +2529,7 @@
       singleLine.push_back(arg);
     }
   }
-  if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+  if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
     singleLine.push_back("-C");
     singleLine.push_back(cmakeCfgIntDir);
   } else // TODO: This is a hack. Should be something to do with the
@@ -2620,7 +2610,7 @@
       "installation rules have been specified",
       mf->GetBacktrace());
   } else if (this->InstallTargetEnabled && !skipInstallRules) {
-    if (!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.') {
+    if (!(cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.')) {
       std::set<std::string>* componentsSet = &this->InstallComponents;
       std::ostringstream ostr;
       if (!componentsSet->empty()) {
@@ -2659,7 +2649,7 @@
       cmd = "cmake";
     }
     singleLine.push_back(cmd);
-    if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+    if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
       std::string cfgArg = "-DBUILD_TYPE=";
       bool useEPN = this->UseEffectivePlatformName(mf.get());
       if (useEPN) {
@@ -3054,7 +3044,7 @@
 
   for (const auto& lg : this->LocalGenerators) {
     for (const auto& tgt : lg->GetGeneratorTargets()) {
-      if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      if (!tgt->IsInBuildSystem()) {
         continue;
       }
       this->WriteSummary(tgt.get());
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 1664dd0..7c87131 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -218,10 +218,11 @@
 {
   const char* ghsRoot = mf->GetDefinition("GHS_TOOLSET_ROOT");
 
-  if (!ghsRoot || ghsRoot[0] == '\0') {
-    ghsRoot = DEFAULT_TOOLSET_ROOT;
+  if (cmNonempty(ghsRoot)) {
+    tsd = ghsRoot;
+  } else {
+    tsd = DEFAULT_TOOLSET_ROOT;
   }
-  tsd = ghsRoot;
 
   if (ts.empty()) {
     std::vector<std::string> output;
@@ -467,7 +468,7 @@
     this->ProjectTargets.push_back(t);
   }
   for (cmGeneratorTarget const* t : sortedProjectTargets) {
-    if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!t->IsInBuildSystem()) {
       continue;
     }
     if (!IsExcluded(t->GetLocalGenerator(), t)) {
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index b52dd28..2ef202d 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1105,8 +1105,9 @@
       break;
     }
 
-    default:
-      return;
+    case cmStateEnums::INTERFACE_LIBRARY:
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
   }
 }
 
@@ -1128,7 +1129,7 @@
     cmNinjaDeps outs;
     for (cmTargetDepend const& targetDep :
          this->GetTargetDirectDepends(target)) {
-      if (targetDep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      if (!targetDep->IsInBuildSystem()) {
         continue;
       }
       if (targetDep.IsCross()) {
@@ -1170,7 +1171,7 @@
     cmNinjaOuts this_outs; // this will be the new cache entry
 
     for (auto const& dep_target : this->GetTargetDirectDepends(target)) {
-      if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
+      if (!dep_target->IsInBuildSystem() ||
           (this->EnableCrossConfigBuild() && !dep_target.IsCross())) {
         continue;
       }
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 1764429..ebc90b6 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -845,8 +845,7 @@
     for (const auto& gt : lg->GetGeneratorTargets()) {
       cmLocalGenerator* tlg = gt->GetLocalGenerator();
 
-      if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          IsExcluded(lg.get(), gt.get())) {
+      if (!gt->IsInBuildSystem() || IsExcluded(lg.get(), gt.get())) {
         continue;
       }
 
@@ -881,7 +880,7 @@
   if (emitted.insert(target).second) {
     count = this->ProgressMap[target].Marks.size();
     for (cmTargetDepend const& depend : this->GetTargetDirectDepends(target)) {
-      if (depend->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      if (!depend->IsInBuildSystem()) {
         continue;
       }
       count += this->CountProgressMarksInTarget(depend, emitted);
@@ -938,7 +937,7 @@
   for (cmTargetDepend const& i : this->GetTargetDirectDepends(target)) {
     // Create the target-level dependency.
     cmGeneratorTarget const* dep = i;
-    if (dep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!dep->IsInBuildSystem()) {
       continue;
     }
     cmLocalUnixMakefileGenerator3* lg3 =
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index c851eea..f8b438a 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -339,7 +339,7 @@
   // loop over again and write out configurations for each target
   // in the solution
   for (cmGeneratorTarget const* target : projectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
@@ -369,7 +369,7 @@
 
   std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
   for (cmGeneratorTarget const* target : projectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     bool written = false;
@@ -436,7 +436,7 @@
   std::ostream& fout, OrderedTargetDependSet const& projectTargets)
 {
   for (cmGeneratorTarget const* target : projectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 29ca154..fcdfc50 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -325,7 +325,7 @@
   TargetDependSet const& unordered = this->GetTargetDirectDepends(gt);
   OrderedTargetDependSet depends(unordered, std::string());
   for (cmTargetDepend const& i : depends) {
-    if (i->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!i->IsInBuildSystem()) {
       continue;
     }
     std::string guid = this->GetGUID(i->GetName());
@@ -341,7 +341,7 @@
     if (cmGeneratorTarget* depTarget =
           target->GetLocalGenerator()->FindGeneratorTargetToUse(
             ui.Value.first)) {
-      if (depTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+      if (depTarget->IsInBuildSystem() &&
           depTarget->GetProperty("EXTERNAL_MSPROJECT")) {
         // This utility dependency names an external .vcproj target.
         // We use LinkLibraryDependencies="true" to link to it without
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index b31d069..001d876 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -368,7 +368,7 @@
 void cmGlobalVisualStudioGenerator::FollowLinkDepends(
   const cmGeneratorTarget* target, std::set<const cmGeneratorTarget*>& linked)
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return;
   }
   if (linked.insert(target).second &&
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index f632257..574e0f5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1199,7 +1199,7 @@
     return true;
   }
 
-  if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gtgt->IsInBuildSystem()) {
     return true;
   }
 
@@ -1845,7 +1845,7 @@
                                                  cmXCodeObject* buildSettings,
                                                  const std::string& configName)
 {
-  if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gtgt->IsInBuildSystem()) {
     return;
   }
 
@@ -2678,7 +2678,7 @@
 cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeTarget(
   cmGeneratorTarget* gtgt, cmXCodeObject* buildPhases)
 {
-  if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gtgt->IsInBuildSystem()) {
     return nullptr;
   }
   cmXCodeObject* target = this->CreateObject(cmXCodeObject::PBXNativeTarget);
@@ -2821,7 +2821,7 @@
     cmSystemTools::Error("Error no target on xobject\n");
     return;
   }
-  if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gt->IsInBuildSystem()) {
     return;
   }
 
@@ -3113,13 +3113,9 @@
       // end up with (empty anyhow) ZERO_CHECK, install, or test source
       // groups:
       //
-      if (gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) {
-        continue;
-      }
-      if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-        continue;
-      }
-      if (gtgt->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+      if (!gtgt->IsInBuildSystem() ||
+          gtgt->GetType() == cmStateEnums::GLOBAL_TARGET ||
+          gtgt->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
         continue;
       }
 
@@ -3385,7 +3381,7 @@
     buildSettings->AddAttribute("ONLY_ACTIVE_ARCH", this->CreateString("YES"));
     // When targeting macOS, use only the host architecture.
     if (this->SystemName == "Darwin"_s &&
-        (!sysroot || !*sysroot ||
+        (!cmNonempty(sysroot) ||
          cmSystemTools::LowerCase(sysroot).find("macos") !=
            std::string::npos)) {
       buildSettings->AddAttribute("ARCHS",
@@ -3395,7 +3391,7 @@
     // Tell Xcode to use ARCHS (ONLY_ACTIVE_ARCH defaults to NO).
     buildSettings->AddAttribute("ARCHS", this->CreateString(archs));
   }
-  if (deploymentTarget && *deploymentTarget) {
+  if (cmNonempty(deploymentTarget)) {
     buildSettings->AddAttribute(GetDeploymentPlatform(root->GetMakefile()),
                                 this->CreateString(deploymentTarget));
   }
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index c23156d..8e9abf8 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -260,7 +260,7 @@
   do {                                                                        \
     const char* value = mf.GetDefinition(cmakeDefinition);                    \
     if (value) {                                                              \
-      (var) = mf.IsOn(cmakeDefinition);                                       \
+      (var) = cmIsOn(value);                                                  \
     }                                                                         \
   } while (false)
 
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 028053d..4c9744f 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -221,7 +221,7 @@
   this->ObjectPathMax = 1000;
 #endif
   const char* plen = this->Makefile->GetDefinition("CMAKE_OBJECT_PATH_MAX");
-  if (plen && *plen) {
+  if (cmNonempty(plen)) {
     unsigned int pmax;
     if (sscanf(plen, "%u", &pmax) == 1) {
       if (pmax >= 128) {
@@ -284,7 +284,7 @@
   // Generate the rule files for each target.
   const auto& targets = this->GetGeneratorTargets();
   for (const auto& target : targets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     target->TraceDependencies();
@@ -434,7 +434,7 @@
       prefix_win32 = "C:";
     }
     const char* project_name = this->Makefile->GetDefinition("PROJECT_NAME");
-    if (project_name && project_name[0]) {
+    if (cmNonempty(project_name)) {
       prefix_win32 += "/Program Files/";
       prefix_win32 += project_name;
     } else {
@@ -760,7 +760,7 @@
   // Add our targets to the manifest for each configuration.
   const auto& targets = this->GetGeneratorTargets();
   for (const auto& target : targets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     for (std::string const& c : configNames) {
@@ -797,7 +797,7 @@
 
     // Now that C/C++ _STANDARD values have been computed
     // set the values to ObjC/ObjCXX _STANDARD variables
-    if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
+    if (target->CanCompileSources()) {
       for (std::string const& c : configNames) {
         target->ComputeCompileFeatures(c, inferredEnabledLanguages);
       }
@@ -893,7 +893,7 @@
   emitted.insert("/System/Library/Frameworks");
 #endif
   for (std::string const& i : includes) {
-    if (fwSearchFlag && *fwSearchFlag && this->Makefile->IsOn("APPLE") &&
+    if (cmNonempty(fwSearchFlag) && this->Makefile->IsOn("APPLE") &&
         cmSystemTools::IsPathToFramework(i)) {
       std::string const frameworkDir =
         cmSystemTools::CollapseFullPath(cmStrCat(i, "/../"));
@@ -1653,7 +1653,7 @@
 
   std::string fwSearchFlagVar = "CMAKE_" + lang + "_FRAMEWORK_SEARCH_FLAG";
   const char* fwSearchFlag = mf->GetDefinition(fwSearchFlagVar);
-  if (!(fwSearchFlag && *fwSearchFlag)) {
+  if (!cmNonempty(fwSearchFlag)) {
     return std::string();
   }
 
@@ -1892,7 +1892,7 @@
     std::string sysrootFlagVar =
       std::string("CMAKE_") + lang + "_SYSROOT_FLAG";
     const char* sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar);
-    if (sysrootFlag && *sysrootFlag) {
+    if (cmNonempty(sysrootFlag)) {
       if (!this->AppleArchSysroots.empty() &&
           !this->AllAppleArchSysrootsAreTheSame(archs, sysroot)) {
         for (std::string const& arch : archs) {
@@ -1921,8 +1921,7 @@
       std::string("CMAKE_") + lang + "_OSX_DEPLOYMENT_TARGET_FLAG";
     const char* deploymentTargetFlag =
       this->Makefile->GetDefinition(deploymentTargetFlagVar);
-    if (deploymentTargetFlag && *deploymentTargetFlag && deploymentTarget &&
-        *deploymentTarget) {
+    if (cmNonempty(deploymentTargetFlag) && cmNonempty(deploymentTarget)) {
       flags += " ";
       flags += deploymentTargetFlag;
       flags += deploymentTarget;
@@ -3062,7 +3061,7 @@
   if (!lang.empty()) {
     const char* df =
       this->Makefile->GetDefinition(cmStrCat("CMAKE_", lang, "_DEFINE_FLAG"));
-    if (df && *df) {
+    if (cmNonempty(df)) {
       dflag = df;
     }
   }
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index 098fa5a..a23ad57 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -11,7 +11,6 @@
 #include "cmGhsMultiTargetGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmSourceFile.h"
-#include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -33,7 +32,7 @@
 void cmLocalGhsMultiGenerator::GenerateTargetsDepthFirst(
   cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return;
   }
   // Find this target in the list of remaining targets.
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index c47a9b2..ef34953 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -90,7 +90,7 @@
   }
 
   for (const auto& target : this->GetGeneratorTargets()) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     auto tg = cmNinjaTargetGenerator::New(target.get());
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index df4bf6a..8acd1e3 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -101,7 +101,7 @@
   cmGlobalUnixMakefileGenerator3* gg =
     static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
   for (const auto& target : this->GetGeneratorTargets()) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     std::unique_ptr<cmMakefileTargetGenerator> tg(
@@ -137,7 +137,7 @@
   std::map<std::string, LocalObjectInfo>& localObjectFiles)
 {
   for (const auto& gt : this->GetGeneratorTargets()) {
-    if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!gt->CanCompileSources()) {
       continue;
     }
     std::vector<cmSourceFile const*> objectSources;
@@ -1807,7 +1807,7 @@
     std::string cidVar =
       cmStrCat("CMAKE_", implicitLang.first, "_COMPILER_ID");
     const char* cid = this->Makefile->GetDefinition(cidVar);
-    if (cid && *cid) {
+    if (cmNonempty(cid)) {
       cmakefileStream << "set(CMAKE_" << implicitLang.first
                       << "_COMPILER_ID \"" << cid << "\")\n";
     }
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index 9076e26..6c7d6c6 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -69,7 +69,7 @@
 void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
   cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return;
   }
   // Find this target in the list of remaining targets.
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index ad61ad3..fec6a9d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -66,7 +66,7 @@
   // Now create GUIDs for targets
   const auto& tgts = this->GetGeneratorTargets();
   for (const auto& l : tgts) {
-    if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!l->IsInBuildSystem()) {
       continue;
     }
     cmProp path = l->GetProperty("EXTERNAL_MSPROJECT");
@@ -129,7 +129,7 @@
 
   // Create the project file for each target.
   for (const auto& l : tgts) {
-    if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!l->IsInBuildSystem()) {
       continue;
     }
     // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index aca40fa..5e1f070 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -196,7 +196,7 @@
   std::string env;
   cmSystemTools::GetEnv(varName, env);
 
-  bool const haveVar = var && *var;
+  bool const haveVar = cmNonempty(var);
   bool const haveEnv = !env.empty();
   if ((haveVar || haveEnv) && this->WarnedCMP0074.insert(varName).second) {
     std::ostringstream w;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 286a3dc..13c2fe9 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -839,7 +839,7 @@
           run_iwyu += " --tidy=";
           const char* driverMode = this->Makefile->GetDefinition(
             "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
-          if (!(driverMode && *driverMode)) {
+          if (!cmNonempty(driverMode)) {
             driverMode = lang == "C" ? "gcc" : "g++";
           }
           run_iwyu += this->LocalGenerator->EscapeForShell(
@@ -1857,7 +1857,7 @@
       this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
     cmOutputConverter::SHELL);
   const char* nm_executable = this->Makefile->GetDefinition("CMAKE_NM");
-  if (nm_executable && *nm_executable) {
+  if (cmNonempty(nm_executable)) {
     cmd += " --nm=";
     cmd += this->LocalCommonGenerator->ConvertToOutputFormat(
       nm_executable, cmOutputConverter::SHELL);
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 924a44e..1775085 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -1096,7 +1096,7 @@
       obj_list_file, cmOutputConverter::SHELL);
 
     const char* nm_executable = GetMakefile()->GetDefinition("CMAKE_NM");
-    if (nm_executable && *nm_executable) {
+    if (cmNonempty(nm_executable)) {
       cmd += " --nm=";
       cmd += this->LocalCommonGenerator->ConvertToOutputFormat(
         nm_executable, cmOutputConverter::SHELL);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index de18536..048dbb6 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -847,7 +847,7 @@
         run_iwyu += " --tidy=";
         const char* driverMode = this->Makefile->GetDefinition(
           cmStrCat("CMAKE_", lang, "_CLANG_TIDY_DRIVER_MODE"));
-        if (!(driverMode && *driverMode)) {
+        if (!cmNonempty(driverMode)) {
           driverMode = lang == "C" ? "gcc" : "g++";
         }
         run_iwyu += this->GetLocalGenerator()->EscapeForShell(
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 2ec66d9..bb6db92 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -303,7 +303,7 @@
     std::string vw;
     for (std::string const& i : vv) {
       const char* const v = mf.GetDefinition(i);
-      if (v && *v) {
+      if (cmNonempty(v)) {
         if (cmp0048 == cmPolicies::WARN) {
           if (!injectedProjectCommand) {
             vw += "\n  ";
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index 766d347..eb8fcaf 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -180,7 +180,7 @@
     if (subdir == "include" || subdir == "lib") {
       const char* arch =
         this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
-      if (arch && *arch) {
+      if (cmNonempty(arch)) {
         if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") &&
             this->FC->Makefile->IsDefinitionSet(
               "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) {
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index 0eb869c..6dbab98 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -65,7 +65,7 @@
 
     const char* defaultStd = makefile->GetDefinition(
       cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT"));
-    if (!defaultStd || !*defaultStd) {
+    if (!cmNonempty(defaultStd)) {
       // this compiler has no notion of language standard levels
       return std::string{};
     }
@@ -472,7 +472,7 @@
   const char* featuresKnown =
     this->Makefile->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
 
-  if (!featuresKnown || !*featuresKnown) {
+  if (!cmNonempty(featuresKnown)) {
     std::ostringstream e;
     if (error) {
       e << "no";
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index aec9afa..0e5dfef 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -216,6 +216,15 @@
   std::string ProcessSourceItemCMP0049(const std::string& s);
 };
 
+namespace {
+#define SETUP_COMMON_LANGUAGE_PROPERTIES(lang)                                \
+  initProp(#lang "_COMPILER_LAUNCHER");                                       \
+  initProp(#lang "_STANDARD");                                                \
+  initProp(#lang "_STANDARD_REQUIRED");                                       \
+  initProp(#lang "_EXTENSIONS");                                              \
+  initProp(#lang "_VISIBILITY_PRESET")
+}
+
 cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
                    Visibility vis, cmMakefile* mf, PerConfig perConfig)
   : impl(cm::make_unique<cmTargetInternals>())
@@ -272,8 +281,14 @@
   };
 
   // Setup default property values.
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
+  if (this->CanCompileSources()) {
+
+    SETUP_COMMON_LANGUAGE_PROPERTIES(C);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJC);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(CXX);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJCXX);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(CUDA);
+
     initProp("ANDROID_API");
     initProp("ANDROID_API_MIN");
     initProp("ANDROID_ARCH");
@@ -335,38 +350,22 @@
     initProp("NO_SYSTEM_FROM_IMPORTED");
     initProp("BUILD_WITH_INSTALL_NAME_DIR");
     initProp("C_CLANG_TIDY");
-    initProp("C_COMPILER_LAUNCHER");
     initProp("C_CPPLINT");
     initProp("C_CPPCHECK");
     initProp("C_INCLUDE_WHAT_YOU_USE");
     initProp("LINK_WHAT_YOU_USE");
-    initProp("C_STANDARD");
-    initProp("C_STANDARD_REQUIRED");
-    initProp("C_EXTENSIONS");
-    initProp("OBJC_COMPILER_LAUNCHER");
-    initProp("OBJC_STANDARD");
-    initProp("OBJC_STANDARD_REQUIRED");
-    initProp("OBJC_EXTENSIONS");
     initProp("CXX_CLANG_TIDY");
-    initProp("CXX_COMPILER_LAUNCHER");
     initProp("CXX_CPPLINT");
     initProp("CXX_CPPCHECK");
     initProp("CXX_INCLUDE_WHAT_YOU_USE");
-    initProp("CXX_STANDARD");
-    initProp("CXX_STANDARD_REQUIRED");
-    initProp("CXX_EXTENSIONS");
-    initProp("OBJCXX_COMPILER_LAUNCHER");
-    initProp("OBJCXX_STANDARD");
-    initProp("OBJCXX_STANDARD_REQUIRED");
-    initProp("OBJCXX_EXTENSIONS");
-    initProp("CUDA_STANDARD");
-    initProp("CUDA_STANDARD_REQUIRED");
-    initProp("CUDA_EXTENSIONS");
-    initProp("CUDA_COMPILER_LAUNCHER");
     initProp("CUDA_SEPARABLE_COMPILATION");
     initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
     initProp("CUDA_RUNTIME_LIBRARY");
     initProp("CUDA_ARCHITECTURES");
+    initProp("VISIBILITY_INLINES_HIDDEN");
+    initProp("JOB_POOL_COMPILE");
+    initProp("JOB_POOL_LINK");
+    initProp("JOB_POOL_PRECOMPILE_HEADER");
     initProp("LINK_SEARCH_START_STATIC");
     initProp("LINK_SEARCH_END_STATIC");
     initProp("Swift_LANGUAGE_VERSION");
@@ -377,6 +376,7 @@
     initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
     initPropValue("UNITY_BUILD_MODE", "BATCH");
     initPropValue("PCH_WARN_INVALID", "ON");
+
 #ifdef __APPLE__
     if (this->GetGlobalGenerator()->IsXcode()) {
       initProp("XCODE_SCHEME_ADDRESS_SANITIZER");
@@ -410,7 +410,8 @@
   }
 
   // Setup per-configuration property default values.
-  if (this->GetType() != cmStateEnums::UTILITY) {
+  if (this->GetType() != cmStateEnums::UTILITY &&
+      this->GetType() != cmStateEnums::GLOBAL_TARGET) {
     static const auto configProps = {
       /* clang-format needs this comment to break after the opening brace */
       "ARCHIVE_OUTPUT_DIRECTORY_",     "LIBRARY_OUTPUT_DIRECTORY_",
@@ -487,16 +488,6 @@
                impl->Makefile->GetLinkDirectoriesBacktraces());
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
-    initProp("C_VISIBILITY_PRESET");
-    initProp("CXX_VISIBILITY_PRESET");
-    initProp("OBJC_VISIBILITY_PRESET");
-    initProp("OBJCXX_VISIBILITY_PRESET");
-    initProp("CUDA_VISIBILITY_PRESET");
-    initProp("VISIBILITY_INLINES_HIDDEN");
-  }
-
   if (impl->TargetType == cmStateEnums::EXECUTABLE) {
     initProp("ANDROID_GUI");
     initProp("CROSSCOMPILING_EMULATOR");
@@ -505,6 +496,8 @@
   if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
       impl->TargetType == cmStateEnums::MODULE_LIBRARY) {
     this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
+  } else if (this->CanCompileSources()) {
+    initProp("POSITION_INDEPENDENT_CODE");
   }
   if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
       impl->TargetType == cmStateEnums::EXECUTABLE) {
@@ -512,11 +505,6 @@
     initProp("WINDOWS_EXPORT_ALL_SYMBOLS");
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
-    initProp("POSITION_INDEPENDENT_CODE");
-  }
-
   // Record current policies for later use.
   impl->Makefile->RecordPolicies(impl->PolicyMap);
 
@@ -528,13 +516,6 @@
     impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
-    initProp("JOB_POOL_COMPILE");
-    initProp("JOB_POOL_LINK");
-    initProp("JOB_POOL_PRECOMPILE_HEADER");
-  }
-
   if (impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
     initProp("DOTNET_TARGET_FRAMEWORK");
     initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
@@ -1917,6 +1898,27 @@
   return impl->PerConfig;
 }
 
+bool cmTarget::CanCompileSources() const
+{
+  if (this->IsImported()) {
+    return false;
+  }
+  switch (this->GetType()) {
+    case cmStateEnums::EXECUTABLE:
+    case cmStateEnums::STATIC_LIBRARY:
+    case cmStateEnums::SHARED_LIBRARY:
+    case cmStateEnums::MODULE_LIBRARY:
+    case cmStateEnums::OBJECT_LIBRARY:
+      return true;
+    case cmStateEnums::UTILITY:
+    case cmStateEnums::INTERFACE_LIBRARY:
+    case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
+  }
+  return false;
+}
+
 const char* cmTarget::GetSuffixVariableInternal(
   cmStateEnums::ArtifactType artifact) const
 {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 7a16de8..43f1887 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -196,6 +196,7 @@
   bool IsImported() const;
   bool IsImportedGloballyVisible() const;
   bool IsPerConfig() const;
+  bool CanCompileSources() const;
 
   bool GetMappedConfig(std::string const& desired_config, cmProp& loc,
                        cmProp& imp, std::string& suffix) const;
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 7c0ce71..78b230c 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -77,7 +77,7 @@
   cmGeneratorExpression ge(this->Test->GetBacktrace());
 
   // Start the test command.
-  os << indent << "add_test(\"" << this->Test->GetName() << "\" ";
+  os << indent << "add_test(" << this->Test->GetName() << " ";
 
   // Evaluate command line arguments
   std::vector<std::string> argv =
@@ -127,8 +127,8 @@
   os << ")\n";
 
   // Output properties for the test.
-  os << indent << "set_tests_properties(\"" << this->Test->GetName()
-     << "\" PROPERTIES ";
+  os << indent << "set_tests_properties(" << this->Test->GetName()
+     << " PROPERTIES ";
   for (auto const& i : this->Test->GetProperties().GetList()) {
     os << " " << i.first << " "
        << cmOutputConverter::EscapeForCMake(
@@ -140,8 +140,7 @@
 
 void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, Indent indent)
 {
-  os << indent << "add_test(\"" << this->Test->GetName()
-     << "\" NOT_AVAILABLE)\n";
+  os << indent << "add_test(" << this->Test->GetName() << " NOT_AVAILABLE)\n";
 }
 
 bool cmTestGenerator::NeedsScriptNoConfig() const
@@ -161,8 +160,9 @@
 
   std::string exe = command[0];
   cmSystemTools::ConvertToUnixSlashes(exe);
-  fout << indent << "add_test(\"" << this->Test->GetName() << "\" \"" << exe
-       << "\"";
+  fout << indent;
+  fout << "add_test(";
+  fout << this->Test->GetName() << " \"" << exe << "\"";
 
   for (std::string const& arg : cmMakeRange(command).advance(1)) {
     // Just double-quote all arguments so they are re-parsed
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index a06dab3..6369c1f 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -4144,7 +4144,7 @@
   Elem e1(e0, "ItemGroup");
   e1.SetHasElements();
   for (cmGeneratorTarget const* dt : depends) {
-    if (dt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!dt->IsInBuildSystem()) {
       continue;
     }
     // skip fortran targets as they can not be processed by MSBuild
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 45fa44b..1e688ed 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2268,7 +2268,7 @@
   if (this->ClearBuildSystem) {
     // Get the generator used for this build system.
     const char* genName = mf.GetDefinition("CMAKE_DEPENDS_GENERATOR");
-    if (!genName || genName[0] == '\0') {
+    if (!cmNonempty(genName)) {
       genName = "Unix Makefiles";
     }
 
diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
index b5a34d5..e8474e2 100644
--- a/Source/kwsys/Glob.hxx.in
+++ b/Source/kwsys/Glob.hxx.in
@@ -126,8 +126,8 @@
   bool RecurseListDirs;
 
 private:
-  Glob(const Glob&);           // Not implemented.
-  void operator=(const Glob&); // Not implemented.
+  Glob(const Glob&) = delete;
+  void operator=(const Glob&) = delete;
 };
 
 } // namespace @KWSYS_NAMESPACE@
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index cc45529..e1e7721 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -2128,17 +2128,17 @@
 #endif
 #ifdef SIGABRT
     case SIGABRT:
-      KWSYSPE_CASE(Other, "Child aborted");
+      KWSYSPE_CASE(Other, "Subprocess aborted");
       break;
 #endif
 #ifdef SIGKILL
     case SIGKILL:
-      KWSYSPE_CASE(Other, "Child killed");
+      KWSYSPE_CASE(Other, "Subprocess killed");
       break;
 #endif
 #ifdef SIGTERM
     case SIGTERM:
-      KWSYSPE_CASE(Other, "Child terminated");
+      KWSYSPE_CASE(Other, "Subprocess terminated");
       break;
 #endif
 #ifdef SIGHUP
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 25705ea..2c39b91 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -1453,7 +1453,7 @@
 
 bool SystemTools::Touch(const std::string& filename, bool create)
 {
-  if (!SystemTools::PathExists(filename)) {
+  if (!SystemTools::FileExists(filename)) {
     if (create) {
       FILE* file = Fopen(filename, "a+b");
       if (file) {
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 0c658f5..eed770c 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -450,24 +450,25 @@
       printf("The process is still executing.\n");
       break;
     case kwsysProcess_State_Expired:
-      printf("Child was killed when timeout expired.\n");
+      printf("Subprocess was killed when timeout expired.\n");
       break;
     case kwsysProcess_State_Exited:
-      printf("Child exited with value = %d\n", kwsysProcess_GetExitValue(kp));
+      printf("Subprocess exited with value = %d\n",
+             kwsysProcess_GetExitValue(kp));
       result = ((exception != kwsysProcess_GetExitException(kp)) ||
                 (value != kwsysProcess_GetExitValue(kp)));
       break;
     case kwsysProcess_State_Killed:
-      printf("Child was killed by parent.\n");
+      printf("Subprocess was killed by parent.\n");
       break;
     case kwsysProcess_State_Exception:
-      printf("Child terminated abnormally: %s\n",
+      printf("Subprocess terminated abnormally: %s\n",
              kwsysProcess_GetExceptionString(kp));
       result = ((exception != kwsysProcess_GetExitException(kp)) ||
                 (value != kwsysProcess_GetExitValue(kp)));
       break;
     case kwsysProcess_State_Disowned:
-      printf("Child was disowned.\n");
+      printf("Subprocess was disowned.\n");
       break;
     case kwsysProcess_State_Error:
       printf("Error in administrating child process: [%s]\n",
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 1d34614..cfa420d 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -422,6 +422,28 @@
     res = false;
   }
 
+#if !defined(_WIN32)
+  std::string const testBadSymlink(testNewDir + "/badSymlink.txt");
+  std::string const testBadSymlinkTgt(testNewDir + "/missing/symlinkTgt.txt");
+  if (!kwsys::SystemTools::CreateSymlink(testBadSymlinkTgt, testBadSymlink)) {
+    std::cerr << "Problem with CreateSymlink for: " << testBadSymlink << " -> "
+              << testBadSymlinkTgt << std::endl;
+    res = false;
+  }
+
+  if (!kwsys::SystemTools::Touch(testBadSymlink, false)) {
+    std::cerr << "Problem with Touch (no create) for: " << testBadSymlink
+              << std::endl;
+    res = false;
+  }
+#endif
+
+  if (!kwsys::SystemTools::Touch(testNewDir, false)) {
+    std::cerr << "Problem with Touch (no create) for: " << testNewDir
+              << std::endl;
+    res = false;
+  }
+
   kwsys::SystemTools::Touch(testNewFile, true);
   if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) {
     std::cerr << "Problem with RemoveADirectory for: " << testNewDir
diff --git a/Tests/CMakeLib/testCMExtMemory.cxx b/Tests/CMakeLib/testCMExtMemory.cxx
index 6663c17..2aeaf7f 100644
--- a/Tests/CMakeLib/testCMExtMemory.cxx
+++ b/Tests/CMakeLib/testCMExtMemory.cxx
@@ -13,7 +13,7 @@
 class Derived : public Base
 {
 public:
-  ~Derived() = default;
+  ~Derived() override = default;
 
   void method() {}
 };
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 19aa4c4..4a774dd 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -2906,7 +2906,7 @@
       PASS_REGULAR_EXPRESSION "Failed")
   else()
     set_tests_properties(CTestTestCrash PROPERTIES
-      PASS_REGULAR_EXPRESSION "(Illegal|SegFault|Child aborted)")
+      PASS_REGULAR_EXPRESSION "(Illegal|SegFault|Subprocess aborted)")
   endif()
 
   configure_file(
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
index e32d693..348e6d0 100644
--- a/Tests/CMakeTests/CMakeLists.txt
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -35,7 +35,7 @@
 AddCMakeTest(FileDownload "")
 set_tests_properties(CMake.FileDownload PROPERTIES
   PASS_REGULAR_EXPRESSION "file already exists with expected MD5 sum"
-  FAIL_REGULAR_EXPRESSION "Unexpected status"
+  FAIL_REGULAR_EXPRESSION "Unexpected status|incorrectly interpreted"
   )
 AddCMakeTest(FileDownloadBadHash "")
 set_property(TEST CMake.FileDownloadBadHash PROPERTY
diff --git a/Tests/CMakeTests/FileDownloadTest.cmake.in b/Tests/CMakeTests/FileDownloadTest.cmake.in
index 76c0000..69d9a14 100644
--- a/Tests/CMakeTests/FileDownloadTest.cmake.in
+++ b/Tests/CMakeTests/FileDownloadTest.cmake.in
@@ -163,3 +163,16 @@
 if(NOT EXISTS file12.png)
   message(SEND_ERROR "file12.png not downloaded: ${status}")
 endif()
+
+message(STATUS "FileDownload:13")
+file(DOWNLOAD
+  ${url}
+  TIMEOUT ${timeout}
+  STATUS status
+  )
+__reportIfWrongStatus("${status}" 0)
+if(EXISTS TIMEOUT)
+  file(REMOVE TIMEOUT)
+  message(SEND_ERROR "TIMEOUT argument was incorrectly interpreted as a filename")
+endif()
+message(STATUS "${status}")
diff --git a/Tests/CMakeTests/FileTestScript.cmake b/Tests/CMakeTests/FileTestScript.cmake
index 145f28a..fc3c28a 100644
--- a/Tests/CMakeTests/FileTestScript.cmake
+++ b/Tests/CMakeTests/FileTestScript.cmake
@@ -10,7 +10,7 @@
   file(DIFFERENT ffff)
 
 elseif(testname STREQUAL download_not_enough_args) # fail
-  file(DOWNLOAD ffff)
+  file(DOWNLOAD)
 
 elseif(testname STREQUAL read_not_enough_args) # fail
   file(READ ffff)
@@ -181,7 +181,7 @@
   message("v='${v}'")
 
 elseif(testname STREQUAL download_wrong_number_of_args) # fail
-  file(DOWNLOAD zzzz://bogus/ffff)
+  file(DOWNLOAD)
 
 elseif(testname STREQUAL download_file_with_no_path) # pass
   file(DOWNLOAD zzzz://bogus/ffff ffff)
diff --git a/Tests/RunCMake/AndroidTestUtilities/check.cmake b/Tests/RunCMake/AndroidTestUtilities/check.cmake
index c24a3cd..ccd4d74 100644
--- a/Tests/RunCMake/AndroidTestUtilities/check.cmake
+++ b/Tests/RunCMake/AndroidTestUtilities/check.cmake
@@ -13,7 +13,7 @@
 endfunction()
 
 function(check_for_setup_test)
-  file(STRINGS "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" output_var REGEX "add_test\\(\"setup_test\".*")
+  file(STRINGS "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" output_var REGEX "add_test\\(setup_test.*")
   if(NOT output_var)
     set(RunCMake_TEST_FAILED "Could not find the test: setup_test" PARENT_SCOPE)
   endif()
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 36b016f..4d2a53c 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -289,7 +289,6 @@
 add_RunCMake_test(add_executable)
 add_RunCMake_test(add_library)
 add_RunCMake_test(add_subdirectory)
-add_RunCMake_test(add_test)
 add_RunCMake_test(build_command)
 add_executable(exit_code exit_code.c)
 set(execute_process_ARGS -DEXIT_CODE_EXE=$<TARGET_FILE:exit_code>)
diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake
index 3cbbc07..588b77b 100644
--- a/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake
+++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake
@@ -7,22 +7,22 @@
 
 set(error_details "There is a problem with generated test file: ${testfile}")
 
-if(testfile_contents MATCHES "add_test[(][\"]DoesNotUseEmulator[\"] [^\n]+pseudo_emulator[^\n]+\n")
+if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulator [^\n]+pseudo_emulator[^\n]+\n")
   message(SEND_ERROR "Used emulator when it should not be used. ${error_details}")
 endif()
 
-if(NOT testfile_contents MATCHES "add_test[(][\"]UsesEmulator[\"] [^\n]+pseudo_emulator[^\n]+\n")
+if(NOT testfile_contents MATCHES "add_test[(]UsesEmulator [^\n]+pseudo_emulator[^\n]+\n")
   message(SEND_ERROR "Did not use emulator when it should be used. ${error_details}")
 endif()
 
-if(testfile_contents MATCHES "add_test[(][\"]DoesNotUseEmulatorWithGenex[\"] [^\n]+pseudo_emulator[^\n]+\n")
+if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulatorWithGenex [^\n]+pseudo_emulator[^\n]+\n")
   message(SEND_ERROR "Used emulator when it should not be used. ${error_details}")
 endif()
 
-if(NOT testfile_contents MATCHES "add_test[(][\"]UsesEmulatorWithExecTargetFromSubdirAddedWithoutGenex[\"] [^\n]+pseudo_emulator[^\n]+\n")
+if(NOT testfile_contents MATCHES "add_test[(]UsesEmulatorWithExecTargetFromSubdirAddedWithoutGenex [^\n]+pseudo_emulator[^\n]+\n")
   message(SEND_ERROR "Did not use emulator when it should be used. ${error_details}")
 endif()
 
-if(testfile_contents MATCHES "add_test[(][\"]DoesNotUseEmulatorWithExecTargetFromSubdirAddedWithGenex[\"] [^\n]+pseudo_emulator[^\n]+\n")
+if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulatorWithExecTargetFromSubdirAddedWithGenex [^\n]+pseudo_emulator[^\n]+\n")
   message(SEND_ERROR "Used emulator when it should not be used. ${error_details}")
 endif()
diff --git a/Tests/RunCMake/add_test/CMakeLists.txt.in b/Tests/RunCMake/add_test/CMakeLists.txt.in
deleted file mode 100644
index 495240d..0000000
--- a/Tests/RunCMake/add_test/CMakeLists.txt.in
+++ /dev/null
@@ -1,27 +0,0 @@
-if (NOT DEFINED RUN_AS_SCRIPT)
-
-  cmake_minimum_required(VERSION 3.7)
-  project(@CASE_NAME@ NONE)
-  include(CTest)
-
-  # Two fallback tests for set_tests_properties.
-  add_test(NAME PrefixTest COMMAND "${CMAKE_COMMAND}" --version)
-  add_test(NAME SuffixTest COMMAND "${CMAKE_COMMAND}" --version)
-
-  add_test(
-    NAME @CASE_CMAKELISTS_NAME_1@
-    COMMAND "${CMAKE_COMMAND}" -D RUN_AS_SCRIPT=1 -P "${CMAKE_CURRENT_LIST_FILE}"
-  )
-  set_tests_properties(
-    @CASE_CMAKELISTS_NAME_2@
-    PROPERTIES
-      ENVIRONMENT CMAKE_add_test_ENVVAR=1
-  )
-
-else()
-
-  if(NOT DEFINED ENV{CMAKE_add_test_ENVVAR})
-    message(FATAL_ERROR "Setting property on test did not succeed!")
-  endif()
-
-endif()
diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument1-stdout.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument1-stdout.txt
deleted file mode 100644
index 00865d0..0000000
--- a/Tests/RunCMake/add_test/NameContainsBracketArgument1-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: \[=\[BracketArgument;SuffixTest\]=\] \.+[ ]+Passed
diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument2-stdout.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument2-stdout.txt
deleted file mode 100644
index a744beb..0000000
--- a/Tests/RunCMake/add_test/NameContainsBracketArgument2-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: BracketArgument;SuffixTest \.+[ ]+Passed
diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument3-result.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument3-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsBracketArgument3-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument3-stderr.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument3-stderr.txt
deleted file mode 100644
index 32c2112..0000000
--- a/Tests/RunCMake/add_test/NameContainsBracketArgument3-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Error\(s\) when configuring the project
-No tests were found!!!
diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument4-result.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument4-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsBracketArgument4-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument4-stderr.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument4-stderr.txt
deleted file mode 100644
index 32c2112..0000000
--- a/Tests/RunCMake/add_test/NameContainsBracketArgument4-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Error\(s\) when configuring the project
-No tests were found!!!
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote1-result.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote1-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote1-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stderr.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stderr.txt
deleted file mode 100644
index 0661945..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-Unable to find executable: SuffixTest
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stdout.txt
deleted file mode 100644
index 4875409..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: EscapedQuote \.+\*\*\*Not Run
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote2-result.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote2-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote2-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stderr.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stderr.txt
deleted file mode 100644
index 0661945..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-Unable to find executable: SuffixTest
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stdout.txt
deleted file mode 100644
index 4875409..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: EscapedQuote \.+\*\*\*Not Run
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote3-result.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote3-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote3-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stderr.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stderr.txt
deleted file mode 100644
index 0661945..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-Unable to find executable: SuffixTest
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stdout.txt
deleted file mode 100644
index 4875409..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: EscapedQuote \.+\*\*\*Not Run
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote4-result.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote4-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote4-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stderr.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stderr.txt
deleted file mode 100644
index 0661945..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-Unable to find executable: SuffixTest
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stdout.txt
deleted file mode 100644
index 4875409..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: EscapedQuote \.+\*\*\*Not Run
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars1-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars1-stdout.txt
deleted file mode 100644
index 80435b6..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars1-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: \(\) # \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars2-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars2-stdout.txt
deleted file mode 100644
index 80435b6..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars2-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: \(\) # \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars3-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars3-stdout.txt
deleted file mode 100644
index 80435b6..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars3-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: \(\) # \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars4-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars4-stdout.txt
deleted file mode 100644
index 80435b6..0000000
--- a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars4-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: \(\) # \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax1-stdout.txt b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax1-stdout.txt
deleted file mode 100644
index 172ff99..0000000
--- a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax1-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: \$<BOOL:0> \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax2-stdout.txt b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax2-stdout.txt
deleted file mode 100644
index 172ff99..0000000
--- a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax2-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: \$<BOOL:0> \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax3-stdout.txt b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax3-stdout.txt
deleted file mode 100644
index 172ff99..0000000
--- a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax3-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: \$<BOOL:0> \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax4-stdout.txt b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax4-stdout.txt
deleted file mode 100644
index 172ff99..0000000
--- a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax4-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: \$<BOOL:0> \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars1-stdout.txt b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars1-stdout.txt
deleted file mode 100644
index 83e3f86..0000000
--- a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars1-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: !§\$%&/ü:\*😤~ \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars2-stdout.txt b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars2-stdout.txt
deleted file mode 100644
index 83e3f86..0000000
--- a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars2-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: !§\$%&/ü:\*😤~ \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars3-stdout.txt b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars3-stdout.txt
deleted file mode 100644
index 83e3f86..0000000
--- a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars3-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: !§\$%&/ü:\*😤~ \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars4-stdout.txt b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars4-stdout.txt
deleted file mode 100644
index 83e3f86..0000000
--- a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars4-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: !§\$%&/ü:\*😤~ \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon1-stdout.txt b/Tests/RunCMake/add_test/NameContainsSemicolon1-stdout.txt
deleted file mode 100644
index 0fbf486..0000000
--- a/Tests/RunCMake/add_test/NameContainsSemicolon1-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: PrefixTest;SuffixTest \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon2-result.txt b/Tests/RunCMake/add_test/NameContainsSemicolon2-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsSemicolon2-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon2-stderr.txt b/Tests/RunCMake/add_test/NameContainsSemicolon2-stderr.txt
deleted file mode 100644
index 32c2112..0000000
--- a/Tests/RunCMake/add_test/NameContainsSemicolon2-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Error\(s\) when configuring the project
-No tests were found!!!
diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon3-stdout.txt b/Tests/RunCMake/add_test/NameContainsSemicolon3-stdout.txt
deleted file mode 100644
index c5ab1d8..0000000
--- a/Tests/RunCMake/add_test/NameContainsSemicolon3-stdout.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-3/3 Test #3: PrefixTest;SuffixTest \.+\*\*\*Failed.*
-CMake Error at .+/CMakeLists.txt:[0-9]+ \(message\):
-[ ]*Setting property on test did not succeed!
diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon4-result.txt b/Tests/RunCMake/add_test/NameContainsSemicolon4-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsSemicolon4-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon4-stderr.txt b/Tests/RunCMake/add_test/NameContainsSemicolon4-stderr.txt
deleted file mode 100644
index 32c2112..0000000
--- a/Tests/RunCMake/add_test/NameContainsSemicolon4-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Error\(s\) when configuring the project
-No tests were found!!!
diff --git a/Tests/RunCMake/add_test/NameContainsSpaces1-stdout.txt b/Tests/RunCMake/add_test/NameContainsSpaces1-stdout.txt
deleted file mode 100644
index a255fb1..0000000
--- a/Tests/RunCMake/add_test/NameContainsSpaces1-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: PrefixTest SuffixTest \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsSpaces2-result.txt b/Tests/RunCMake/add_test/NameContainsSpaces2-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsSpaces2-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsSpaces2-stderr.txt b/Tests/RunCMake/add_test/NameContainsSpaces2-stderr.txt
deleted file mode 100644
index 32c2112..0000000
--- a/Tests/RunCMake/add_test/NameContainsSpaces2-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Error\(s\) when configuring the project
-No tests were found!!!
diff --git a/Tests/RunCMake/add_test/NameContainsSpaces3-stdout.txt b/Tests/RunCMake/add_test/NameContainsSpaces3-stdout.txt
deleted file mode 100644
index 3d42b0b..0000000
--- a/Tests/RunCMake/add_test/NameContainsSpaces3-stdout.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-3/3 Test #3: PrefixTest SuffixTest \.+\*\*\*Failed.*
-CMake Error at .+/CMakeLists.txt:[0-9]+ \(message\):
-[ ]*Setting property on test did not succeed!
diff --git a/Tests/RunCMake/add_test/NameContainsSpaces4-result.txt b/Tests/RunCMake/add_test/NameContainsSpaces4-result.txt
deleted file mode 100644
index b57e2de..0000000
--- a/Tests/RunCMake/add_test/NameContainsSpaces4-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-(-1|255)
diff --git a/Tests/RunCMake/add_test/NameContainsSpaces4-stderr.txt b/Tests/RunCMake/add_test/NameContainsSpaces4-stderr.txt
deleted file mode 100644
index 32c2112..0000000
--- a/Tests/RunCMake/add_test/NameContainsSpaces4-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Error\(s\) when configuring the project
-No tests were found!!!
diff --git a/Tests/RunCMake/add_test/NameContainsValidSpecialChars1-stdout.txt b/Tests/RunCMake/add_test/NameContainsValidSpecialChars1-stdout.txt
deleted file mode 100644
index ae1a0b1..0000000
--- a/Tests/RunCMake/add_test/NameContainsValidSpecialChars1-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: abc_\.\+-012 \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsValidSpecialChars2-stdout.txt b/Tests/RunCMake/add_test/NameContainsValidSpecialChars2-stdout.txt
deleted file mode 100644
index ae1a0b1..0000000
--- a/Tests/RunCMake/add_test/NameContainsValidSpecialChars2-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: abc_\.\+-012 \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsValidSpecialChars3-stdout.txt b/Tests/RunCMake/add_test/NameContainsValidSpecialChars3-stdout.txt
deleted file mode 100644
index ae1a0b1..0000000
--- a/Tests/RunCMake/add_test/NameContainsValidSpecialChars3-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: abc_\.\+-012 \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameContainsValidSpecialChars4-stdout.txt b/Tests/RunCMake/add_test/NameContainsValidSpecialChars4-stdout.txt
deleted file mode 100644
index ae1a0b1..0000000
--- a/Tests/RunCMake/add_test/NameContainsValidSpecialChars4-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: abc_\.\+-012 \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameIsAlphaNumeric1-stdout.txt b/Tests/RunCMake/add_test/NameIsAlphaNumeric1-stdout.txt
deleted file mode 100644
index ed939bf..0000000
--- a/Tests/RunCMake/add_test/NameIsAlphaNumeric1-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: abcdefghijklmnopqrstuvwxyz0123456789 \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameIsAlphaNumeric2-stdout.txt b/Tests/RunCMake/add_test/NameIsAlphaNumeric2-stdout.txt
deleted file mode 100644
index ed939bf..0000000
--- a/Tests/RunCMake/add_test/NameIsAlphaNumeric2-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: abcdefghijklmnopqrstuvwxyz0123456789 \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameIsAlphaNumeric3-stdout.txt b/Tests/RunCMake/add_test/NameIsAlphaNumeric3-stdout.txt
deleted file mode 100644
index ed939bf..0000000
--- a/Tests/RunCMake/add_test/NameIsAlphaNumeric3-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: abcdefghijklmnopqrstuvwxyz0123456789 \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/NameIsAlphaNumeric4-stdout.txt b/Tests/RunCMake/add_test/NameIsAlphaNumeric4-stdout.txt
deleted file mode 100644
index ed939bf..0000000
--- a/Tests/RunCMake/add_test/NameIsAlphaNumeric4-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test #[0-9]+: abcdefghijklmnopqrstuvwxyz0123456789 \.+[ ]*Passed
diff --git a/Tests/RunCMake/add_test/RunCMakeTest.cmake b/Tests/RunCMake/add_test/RunCMakeTest.cmake
deleted file mode 100644
index 6e9edda..0000000
--- a/Tests/RunCMake/add_test/RunCMakeTest.cmake
+++ /dev/null
@@ -1,263 +0,0 @@
-include(RunCTest)
-
-set(ENV{CTEST_OUTPUT_ON_FAILURE} 1)
-
-function(run_NameIsAlphaNumeric1_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ abcdefghijklmnopqrstuvwxyz0123456789 ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ abcdefghijklmnopqrstuvwxyz0123456789 ]==])
-  run_ctest(NameIsAlphaNumeric1)
-endfunction()
-run_NameIsAlphaNumeric1_test()
-
-function(run_NameIsAlphaNumeric2_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["abcdefghijklmnopqrstuvwxyz0123456789"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["abcdefghijklmnopqrstuvwxyz0123456789"]==])
-  run_ctest(NameIsAlphaNumeric2)
-endfunction()
-run_NameIsAlphaNumeric2_test()
-
-function(run_NameIsAlphaNumeric3_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["abcdefghijklmnopqrstuvwxyz0123456789"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ abcdefghijklmnopqrstuvwxyz0123456789 ]==])
-  run_ctest(NameIsAlphaNumeric3)
-endfunction()
-run_NameIsAlphaNumeric3_test()
-
-function(run_NameIsAlphaNumeric4_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ abcdefghijklmnopqrstuvwxyz0123456789 ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["abcdefghijklmnopqrstuvwxyz0123456789"]==])
-  run_ctest(NameIsAlphaNumeric4)
-endfunction()
-run_NameIsAlphaNumeric4_test()
-
-
-function(run_NameContainsValidSpecialChars1_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ abc_.+-012 ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ abc_.+-012 ]==])
-  run_ctest(NameContainsValidSpecialChars1)
-endfunction()
-run_NameContainsValidSpecialChars1_test()
-
-function(run_NameContainsValidSpecialChars2_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["abc_.+-012"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["abc_.+-012"]==])
-  run_ctest(NameContainsValidSpecialChars2)
-endfunction()
-run_NameContainsValidSpecialChars2_test()
-
-function(run_NameContainsValidSpecialChars3_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["abc_.+-012"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ abc_.+-012 ]==])
-  run_ctest(NameContainsValidSpecialChars3)
-endfunction()
-run_NameContainsValidSpecialChars3_test()
-
-function(run_NameContainsValidSpecialChars4_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ abc_.+-012 ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["abc_.+-012"]==])
-  run_ctest(NameContainsValidSpecialChars4)
-endfunction()
-run_NameContainsValidSpecialChars4_test()
-
-
-function(run_NameContainsOtherSpecialChars1_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ !§$%&/ü:*😤~ ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ !§$%&/ü:*😤~ ]==])
-  run_ctest(NameContainsOtherSpecialChars1)
-endfunction()
-run_NameContainsOtherSpecialChars1_test()
-
-function(run_NameContainsOtherSpecialChars2_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["!§$%&/ü:*😤~"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["!§$%&/ü:*😤~"]==])
-  run_ctest(NameContainsOtherSpecialChars2)
-endfunction()
-run_NameContainsOtherSpecialChars2_test()
-
-function(run_NameContainsOtherSpecialChars3_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["!§$%&/ü:*😤~"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ !§$%&/ü:*😤~ ]==])
-  run_ctest(NameContainsOtherSpecialChars3)
-endfunction()
-run_NameContainsOtherSpecialChars3_test()
-
-function(run_NameContainsOtherSpecialChars4_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ !§$%&/ü:*😤~ ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["!§$%&/ü:*😤~"]==])
-  run_ctest(NameContainsOtherSpecialChars4)
-endfunction()
-run_NameContainsOtherSpecialChars4_test()
-
-
-function(run_NameContainsEscapedSpecialChars1_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ \(\)\ \# ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ \(\)\ \# ]==])
-  run_ctest(NameContainsEscapedSpecialChars1)
-endfunction()
-run_NameContainsEscapedSpecialChars1_test()
-
-function(run_NameContainsEscapedSpecialChars2_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["\(\)\ \#"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["\(\)\ \#"]==])
-  run_ctest(NameContainsEscapedSpecialChars2)
-endfunction()
-run_NameContainsEscapedSpecialChars2_test()
-
-function(run_NameContainsEscapedSpecialChars3_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["\(\)\ \#"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ \(\)\ \# ]==])
-  run_ctest(NameContainsEscapedSpecialChars3)
-endfunction()
-run_NameContainsEscapedSpecialChars3_test()
-
-function(run_NameContainsEscapedSpecialChars4_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ \(\)\ \# ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["\(\)\ \#"]==])
-  run_ctest(NameContainsEscapedSpecialChars4)
-endfunction()
-run_NameContainsEscapedSpecialChars4_test()
-
-
-function(run_NameContainsGeneratorExpressionSyntax1_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ $<BOOL:0> ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ $<BOOL:0> ]==])
-  run_ctest(NameContainsGeneratorExpressionSyntax1)
-endfunction()
-run_NameContainsGeneratorExpressionSyntax1_test()
-
-function(run_NameContainsGeneratorExpressionSyntax2_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["$<BOOL:0>"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["$<BOOL:0>"]==])
-  run_ctest(NameContainsGeneratorExpressionSyntax2)
-endfunction()
-run_NameContainsGeneratorExpressionSyntax2_test()
-
-function(run_NameContainsGeneratorExpressionSyntax3_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["$<BOOL:0>"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ $<BOOL:0> ]==])
-  run_ctest(NameContainsGeneratorExpressionSyntax3)
-endfunction()
-run_NameContainsGeneratorExpressionSyntax3_test()
-
-function(run_NameContainsGeneratorExpressionSyntax4_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ $<BOOL:0> ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["$<BOOL:0>"]==])
-  run_ctest(NameContainsGeneratorExpressionSyntax4)
-endfunction()
-run_NameContainsGeneratorExpressionSyntax4_test()
-
-
-function(run_NameContainsSpaces1_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["PrefixTest SuffixTest"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["PrefixTest SuffixTest"]==])
-  run_ctest(NameContainsSpaces1)
-endfunction()
-run_NameContainsSpaces1_test()
-
-function(run_NameContainsSpaces2_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ PrefixTest SuffixTest ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ PrefixTest SuffixTest ]==])
-  run_ctest(NameContainsSpaces2)
-endfunction()
-run_NameContainsSpaces2_test()
-
-function(run_NameContainsSpaces3_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["PrefixTest SuffixTest"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ PrefixTest SuffixTest ]==])
-  run_ctest(NameContainsSpaces3)
-endfunction()
-run_NameContainsSpaces3_test()
-
-function(run_NameContainsSpaces4_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ PrefixTest SuffixTest ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["PrefixTest SuffixTest"]==])
-  run_ctest(NameContainsSpaces4)
-endfunction()
-run_NameContainsSpaces4_test()
-
-
-function(run_NameContainsSemicolon1_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["PrefixTest;SuffixTest"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["PrefixTest;SuffixTest"]==])
-  run_ctest(NameContainsSemicolon1)
-endfunction()
-run_NameContainsSemicolon1_test()
-
-function(run_NameContainsSemicolon2_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ PrefixTest;SuffixTest ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ PrefixTest;SuffixTest ]==])
-  run_ctest(NameContainsSemicolon2)
-endfunction()
-run_NameContainsSemicolon2_test()
-
-function(run_NameContainsSemicolon3_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["PrefixTest;SuffixTest"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ PrefixTest;SuffixTest ]==])
-  run_ctest(NameContainsSemicolon3)
-endfunction()
-run_NameContainsSemicolon3_test()
-
-function(run_NameContainsSemicolon4_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ PrefixTest;SuffixTest ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["PrefixTest;SuffixTest"]==])
-  run_ctest(NameContainsSemicolon4)
-endfunction()
-run_NameContainsSemicolon4_test()
-
-
-function(run_NameContainsEscapedQuote1_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["EscapedQuote\"\"SuffixTest"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["EscapedQuote\"\"SuffixTest"]==])
-  run_ctest(NameContainsEscapedQuote1)
-endfunction()
-run_NameContainsEscapedQuote1_test()
-
-function(run_NameContainsEscapedQuote2_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ EscapedQuote\"\"SuffixTest ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ EscapedQuote\"\"SuffixTest ]==])
-  run_ctest(NameContainsEscapedQuote2)
-endfunction()
-run_NameContainsEscapedQuote2_test()
-
-function(run_NameContainsEscapedQuote3_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["EscapedQuote\"\"SuffixTest"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ EscapedQuote\"\"SuffixTest ]==])
-  run_ctest(NameContainsEscapedQuote3)
-endfunction()
-run_NameContainsEscapedQuote3_test()
-
-function(run_NameContainsEscapedQuote4_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ EscapedQuote\"\"SuffixTest ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["EscapedQuote\"\"SuffixTest"]==])
-  run_ctest(NameContainsEscapedQuote4)
-endfunction()
-run_NameContainsEscapedQuote4_test()
-
-
-function(run_NameContainsBracketArgument1_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["[=[BracketArgument;SuffixTest]=]"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["[=[BracketArgument;SuffixTest]=]"]==])
-  run_ctest(NameContainsBracketArgument1)
-endfunction()
-run_NameContainsBracketArgument1_test()
-
-function(run_NameContainsBracketArgument2_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ [=[BracketArgument;SuffixTest]=] ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ [=[BracketArgument;SuffixTest]=] ]==])
-  run_ctest(NameContainsBracketArgument2)
-endfunction()
-run_NameContainsBracketArgument2_test()
-
-function(run_NameContainsBracketArgument3_test)
-  set(CASE_CMAKELISTS_NAME_1 [==["[=[BracketArgument;SuffixTest]=]"]==])
-  set(CASE_CMAKELISTS_NAME_2 [==[ [=[BracketArgument;SuffixTest]=] ]==])
-  run_ctest(NameContainsBracketArgument3)
-endfunction()
-run_NameContainsBracketArgument3_test()
-
-function(run_NameContainsBracketArgument4_test)
-  set(CASE_CMAKELISTS_NAME_1 [==[ [=[BracketArgument;SuffixTest]=] ]==])
-  set(CASE_CMAKELISTS_NAME_2 [==["[=[BracketArgument;SuffixTest]=]"]==])
-  run_ctest(NameContainsBracketArgument4)
-endfunction()
-run_NameContainsBracketArgument4_test()
diff --git a/Tests/RunCMake/add_test/test.cmake.in b/Tests/RunCMake/add_test/test.cmake.in
deleted file mode 100644
index 9821c1c..0000000
--- a/Tests/RunCMake/add_test/test.cmake.in
+++ /dev/null
@@ -1,16 +0,0 @@
-cmake_minimum_required(VERSION 3.17)
-
-set(CTEST_SITE                          "test-site")
-set(CTEST_BUILD_NAME                    "test-build-name")
-set(CTEST_SOURCE_DIRECTORY              "@RunCMake_BINARY_DIR@/@CASE_NAME@")
-set(CTEST_BINARY_DIRECTORY              "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
-set(CTEST_CMAKE_GENERATOR               "@RunCMake_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_PLATFORM      "@RunCMake_GENERATOR_PLATFORM@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET       "@RunCMake_GENERATOR_TOOLSET@")
-set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
-
-set(ctest_test_args "@CASE_CTEST_TEST_ARGS@")
-ctest_start(Experimental)
-ctest_configure()
-#ctest_build()
-ctest_test(${ctest_test_args})
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt
new file mode 100644
index 0000000..b0f0d19
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at DOWNLOAD-no-save-hash\.cmake:[0-9]+ \(file\):
+  file DOWNLOAD cannot calculate hash if file is not saved\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake
new file mode 100644
index 0000000..ce959a7
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake
@@ -0,0 +1,8 @@
+if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
+  set(slash /)
+endif()
+file(DOWNLOAD
+  "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/DOWNLOAD-no-save-md5.txt"
+  EXPECTED_HASH MD5=55555555555555555555555555555555
+  STATUS status
+  )
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index a4de1d3..8d84943 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -11,6 +11,7 @@
 run_cmake(DOWNLOAD-tls-cainfo-not-set)
 run_cmake(DOWNLOAD-tls-verify-not-set)
 run_cmake(DOWNLOAD-pass-not-set)
+run_cmake(DOWNLOAD-no-save-hash)
 run_cmake(TOUCH)
 run_cmake(TOUCH-error-in-source-directory)
 run_cmake(TOUCH-error-missing-directory)