Merge topic 'cpack-different-checksum-file-per-generator'

b06870e5 CPack: use a distinct checksum file for each generator

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1291
diff --git a/.clang-tidy b/.clang-tidy
index 6093532..e8d39ce 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -8,7 +8,6 @@
 -misc-static-assert,\
 modernize-*,\
 -modernize-deprecated-headers,\
--modernize-loop-convert,\
 -modernize-pass-by-value,\
 -modernize-raw-string-literal,\
 -modernize-replace-auto-ptr,\
diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake
index 7f19969..e34ae75 100644
--- a/Modules/CMakeTestCCompiler.cmake
+++ b/Modules/CMakeTestCCompiler.cmake
@@ -48,9 +48,10 @@
   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
     "Determining if the C compiler works failed with "
     "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
-  message(FATAL_ERROR "The C compiler \"${CMAKE_C_COMPILER}\" "
+  string(REPLACE "\n" "\n  " _output "${__CMAKE_C_COMPILER_OUTPUT}")
+  message(FATAL_ERROR "The C compiler\n  \"${CMAKE_C_COMPILER}\"\n"
     "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n ${__CMAKE_C_COMPILER_OUTPUT}\n\n"
+    "with the following output:\n  ${_output}\n\n"
     "CMake will not be able to correctly generate this project.")
 else()
   if(C_TEST_WAS_RUN)
diff --git a/Modules/CMakeTestCSharpCompiler.cmake b/Modules/CMakeTestCSharpCompiler.cmake
index 1a8bf32..f3b95fd 100644
--- a/Modules/CMakeTestCSharpCompiler.cmake
+++ b/Modules/CMakeTestCSharpCompiler.cmake
@@ -42,9 +42,10 @@
   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
     "Determining if the C# compiler works failed with "
     "the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n")
-  message(FATAL_ERROR "The C# compiler \"${CMAKE_CSharp_COMPILER}\" "
+  string(REPLACE "\n" "\n  " _output "${__CMAKE_CSharp_COMPILER_OUTPUT}")
+  message(FATAL_ERROR "The C# compiler\n  \"${CMAKE_CSharp_COMPILER}\"\n"
     "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n ${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n"
+    "with the following output:\n  ${_output}\n\n"
     "CMake will not be able to correctly generate this project.")
 else()
   if(CSharp_TEST_WAS_RUN)
diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake
index 80113cb..df5ec72 100644
--- a/Modules/CMakeTestCUDACompiler.cmake
+++ b/Modules/CMakeTestCUDACompiler.cmake
@@ -42,9 +42,10 @@
   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
     "Determining if the CUDA compiler works failed with "
     "the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n")
-  message(FATAL_ERROR "The CUDA compiler \"${CMAKE_CUDA_COMPILER}\" "
+  string(REPLACE "\n" "\n  " _output "${__CMAKE_CUDA_COMPILER_OUTPUT}")
+  message(FATAL_ERROR "The CUDA compiler\n  \"${CMAKE_CUDA_COMPILER}\"\n"
     "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n ${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n"
+    "with the following output:\n  ${_output}\n\n"
     "CMake will not be able to correctly generate this project.")
 else()
   if(CUDA_TEST_WAS_RUN)
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
index a31067b..7b80dc0 100644
--- a/Modules/CMakeTestCXXCompiler.cmake
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -41,9 +41,10 @@
   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
     "Determining if the CXX compiler works failed with "
     "the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
-  message(FATAL_ERROR "The C++ compiler \"${CMAKE_CXX_COMPILER}\" "
+  string(REPLACE "\n" "\n  " _output "${__CMAKE_CXX_COMPILER_OUTPUT}")
+  message(FATAL_ERROR "The C++ compiler\n  \"${CMAKE_CXX_COMPILER}\"\n"
     "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n ${__CMAKE_CXX_COMPILER_OUTPUT}\n\n"
+    "with the following output:\n  ${_output}\n\n"
     "CMake will not be able to correctly generate this project.")
 else()
   if(CXX_TEST_WAS_RUN)
diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake
index c81694e..3c150a8 100644
--- a/Modules/CMakeTestFortranCompiler.cmake
+++ b/Modules/CMakeTestFortranCompiler.cmake
@@ -41,9 +41,10 @@
   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
     "Determining if the Fortran compiler works failed with "
     "the following output:\n${OUTPUT}\n\n")
-  message(FATAL_ERROR "The Fortran compiler \"${CMAKE_Fortran_COMPILER}\" "
+  string(REPLACE "\n" "\n  " _output "${OUTPUT}")
+  message(FATAL_ERROR "The Fortran compiler\n  \"${CMAKE_Fortran_COMPILER}\"\n"
     "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n ${OUTPUT}\n\n"
+    "with the following output:\n  ${_output}\n\n"
     "CMake will not be able to correctly generate this project.")
 else()
   if(FORTRAN_TEST_WAS_RUN)
diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake
index 6393f44..bcd5c33 100644
--- a/Modules/CMakeTestSwiftCompiler.cmake
+++ b/Modules/CMakeTestSwiftCompiler.cmake
@@ -39,9 +39,10 @@
   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
     "Determining if the Swift compiler works failed with "
     "the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
-  message(FATAL_ERROR "The Swift compiler \"${CMAKE_Swift_COMPILER}\" "
+  string(REPLACE "\n" "\n  " _output "${__CMAKE_Swift_COMPILER_OUTPUT}")
+  message(FATAL_ERROR "The Swift compiler\n  \"${CMAKE_Swift_COMPILER}\"\n"
     "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n ${__CMAKE_Swift_COMPILER_OUTPUT}\n\n"
+    "with the following output:\n  ${_output}\n\n"
     "CMake will not be able to correctly generate this project.")
 else()
   if(Swift_TEST_WAS_RUN)
diff --git a/Modules/Compiler/PGI-Fortran.cmake b/Modules/Compiler/PGI-Fortran.cmake
index 4783424..a183c33 100644
--- a/Modules/Compiler/PGI-Fortran.cmake
+++ b/Modules/Compiler/PGI-Fortran.cmake
@@ -7,7 +7,6 @@
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-Mnofreeform")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-Mfreeform")
 
-string(APPEND CMAKE_Fortran_FLAGS_INIT " -Mpreprocess -Kieee")
 string(APPEND CMAKE_Fortran_FLAGS_DEBUG_INIT " -Mbounds")
 
 set(CMAKE_Fortran_MODDIR_FLAG "-module ")
diff --git a/Modules/Compiler/PGI.cmake b/Modules/Compiler/PGI.cmake
index 0cbfd8a..d5a57ee 100644
--- a/Modules/Compiler/PGI.cmake
+++ b/Modules/Compiler/PGI.cmake
@@ -19,16 +19,20 @@
   string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g -O0")
   string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -O2 -s")
   string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -fast -O3")
-  # -Mipa was dropped with PGI 16.3 from Windows versions
-  if(NOT CMAKE_HOST_WIN32 OR CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 16.3)
-    string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -Mipa=fast")
-  endif()
   string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -gopt")
 
   if(CMAKE_HOST_WIN32)
     string(APPEND CMAKE_${lang}_FLAGS_INIT " -Bdynamic")
   endif()
 
+  set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
+  if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le AND (NOT CMAKE_HOST_WIN32 OR CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 16.3))
+    set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+    set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-Mipa=fast,inline")
+  else()
+    set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
+  endif()
+
   # Preprocessing and assembly rules.
   set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
   set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index b8f863f..b2916b4 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 9)
-set(CMake_VERSION_PATCH 20170919)
+set(CMake_VERSION_PATCH 20170921)
 #set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index b48bf12..d3de02b 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -34,7 +34,7 @@
   }
   fileName = CFSTR("RuntimeScript");
   if (!(scriptFileURL =
-          CFBundleCopyResourceURL(appBundle, fileName, NULL, NULL))) {
+          CFBundleCopyResourceURL(appBundle, fileName, nullptr, nullptr))) {
     DebugError("CFBundleCopyResourceURL failed");
     return 1;
   }
@@ -71,7 +71,7 @@
   for (cc = 1; cc < argc; ++cc) {
     args.push_back(argv[cc]);
   }
-  args.push_back(0);
+  args.push_back(nullptr);
 
   cmsysProcess* cp = cmsysProcess_New();
   cmsysProcess_SetCommand(cp, &*args.begin());
@@ -83,7 +83,7 @@
   std::vector<char> tempOutput;
   char* data;
   int length;
-  while (cmsysProcess_WaitForData(cp, &data, &length, 0)) {
+  while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
     // Translate NULL characters in the output into valid text.
     for (int i = 0; i < length; ++i) {
       if (data[i] == '\0') {
@@ -93,7 +93,7 @@
     std::cout.write(data, length);
   }
 
-  cmsysProcess_WaitForExit(cp, 0);
+  cmsysProcess_WaitForExit(cp, nullptr);
 
   bool result = true;
   if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) {
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
index d538901..bbf2a50 100644
--- a/Source/CPack/cmCPackBundleGenerator.cxx
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -19,7 +19,7 @@
 int cmCPackBundleGenerator::InitializeInternal()
 {
   const char* name = this->GetOption("CPACK_BUNDLE_NAME");
-  if (0 == name) {
+  if (nullptr == name) {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
                   "CPACK_BUNDLE_NAME must be set to use the Bundle generator."
                     << std::endl);
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 8758d32..88204c8 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -242,9 +242,9 @@
 {
   int exit_code = 1;
 
-  bool result =
-    cmSystemTools::RunSingleCommand(command.str().c_str(), output, output,
-                                    &exit_code, 0, this->GeneratorVerbose, 0);
+  bool result = cmSystemTools::RunSingleCommand(command.str().c_str(), output,
+                                                output, &exit_code, nullptr,
+                                                this->GeneratorVerbose, 0);
 
   if (!result || exit_code) {
     cmCPackLogger(cmCPackLog::LOG_ERROR, "Error executing: " << command.str()
@@ -553,10 +553,10 @@
       header_data.push_back(languages.size());
       for (size_t i = 0; i < languages.size(); ++i) {
         CFStringRef language_cfstring = CFStringCreateWithCString(
-          NULL, languages[i].c_str(), kCFStringEncodingUTF8);
+          nullptr, languages[i].c_str(), kCFStringEncodingUTF8);
         CFStringRef iso_language =
           CFLocaleCreateCanonicalLanguageIdentifierFromString(
-            NULL, language_cfstring);
+            nullptr, language_cfstring);
         if (!iso_language) {
           cmCPackLogger(cmCPackLog::LOG_ERROR, languages[i]
                           << " is not a recognized language" << std::endl);
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
index 8ea88a8..e75061e 100644
--- a/Source/CPack/cmCPackOSXX11Generator.cxx
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -154,9 +154,9 @@
   int numTries = 10;
   bool res = false;
   while (numTries > 0) {
-    res =
-      cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output, &output,
-                                      &retVal, 0, this->GeneratorVerbose, 0);
+    res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
+                                          &output, &retVal, nullptr,
+                                          this->GeneratorVerbose, 0);
     if (res && !retVal) {
       numTries = -1;
       break;
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index 70ae267..321b6a7 100644
--- a/Source/CPack/cmCPackPKGGenerator.cxx
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -70,7 +70,7 @@
   std::map<std::string, cmCPackComponentGroup>::iterator groupIt;
   for (groupIt = this->ComponentGroups.begin();
        groupIt != this->ComponentGroups.end(); ++groupIt) {
-    if (groupIt->second.ParentGroup == 0) {
+    if (groupIt->second.ParentGroup == nullptr) {
       CreateChoiceOutline(groupIt->second, xout);
     }
   }
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index 8db7cfb..6624b16 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -294,9 +294,9 @@
   int numTries = 10;
   bool res = false;
   while (numTries > 0) {
-    res =
-      cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output, &output,
-                                      &retVal, 0, this->GeneratorVerbose, 0);
+    res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
+                                          &output, &retVal, nullptr,
+                                          this->GeneratorVerbose, 0);
     if (res && !retVal) {
       numTries = -1;
       break;
@@ -466,7 +466,7 @@
   std::string output;
   int retVal = 1;
   bool res = cmSystemTools::RunSingleCommand(
-    command, &output, &output, &retVal, 0, this->GeneratorVerbose, 0);
+    command, &output, &output, &retVal, nullptr, this->GeneratorVerbose, 0);
   cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running package maker"
                   << std::endl);
   if (!res || retVal) {
diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx
index 1389eaa..ed4463c 100644
--- a/Source/CPack/cmCPackProductBuildGenerator.cxx
+++ b/Source/CPack/cmCPackProductBuildGenerator.cxx
@@ -54,7 +54,7 @@
   } else {
     if (!this->GenerateComponentPackage(basePackageDir,
                                         this->GetOption("CPACK_PACKAGE_NAME"),
-                                        toplevel, NULL)) {
+                                        toplevel, nullptr)) {
       return 0;
     }
   }
@@ -145,9 +145,9 @@
   cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl);
   std::string output, error_output;
   int retVal = 1;
-  bool res =
-    cmSystemTools::RunSingleCommand(command.c_str(), &output, &error_output,
-                                    &retVal, 0, this->GeneratorVerbose, 0);
+  bool res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
+                                             &error_output, &retVal, nullptr,
+                                             this->GeneratorVerbose, 0);
   cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running command" << std::endl);
   if (!res || retVal) {
     cmGeneratedFileStream ofs(tmpFile.c_str());
@@ -174,7 +174,7 @@
   cmCPackLogger(cmCPackLog::LOG_OUTPUT, "-   Building component package: "
                   << packageFile << std::endl);
 
-  const char* comp_name = component ? component->Name.c_str() : NULL;
+  const char* comp_name = component ? component->Name.c_str() : nullptr;
 
   const char* preflight = this->GetComponentScript("PREFLIGHT", comp_name);
   const char* postflight = this->GetComponentScript("POSTFLIGHT", comp_name);
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 33d03e5..cc51c60 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -350,13 +350,14 @@
           }
 
           if (!mf->GetDefinition("CPACK_INSTALL_COMMANDS") &&
+              !mf->GetDefinition("CPACK_INSTALL_SCRIPT") &&
               !mf->GetDefinition("CPACK_INSTALLED_DIRECTORIES") &&
               !mf->GetDefinition("CPACK_INSTALL_CMAKE_PROJECTS")) {
             cmCPack_Log(
               &log, cmCPackLog::LOG_ERROR,
               "Please specify build tree of the project that uses CMake "
               "using CPACK_INSTALL_CMAKE_PROJECTS, specify "
-              "CPACK_INSTALL_COMMANDS, or specify "
+              "CPACK_INSTALL_COMMANDS, CPACK_INSTALL_SCRIPT, or "
               "CPACK_INSTALLED_DIRECTORIES."
                 << std::endl);
             parsed = 0;
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 2d5350d..56eeceb 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -185,9 +185,9 @@
   this->CTest->EndXML(xml);
 }
 
-bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
-                                               const char* srcDir,
-                                               const char* binDir)
+bool cmCTestCoverageHandler::ShouldIDoCoverage(std::string const& file,
+                                               std::string const& srcDir,
+                                               std::string const& binDir)
 {
   if (this->IsFilteredOut(file)) {
     return false;
@@ -435,8 +435,8 @@
     }
 
     const std::string fullFileName = file.first;
-    bool shouldIDoCoverage = this->ShouldIDoCoverage(
-      fullFileName.c_str(), sourceDir.c_str(), binaryDir.c_str());
+    bool shouldIDoCoverage =
+      this->ShouldIDoCoverage(fullFileName, sourceDir, binaryDir);
     if (!shouldIDoCoverage) {
       cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                          ".NoDartCoverage found, so skip coverage check for: "
@@ -560,6 +560,8 @@
       ostr << "Cannot open source file: " << fullPath;
       errorsWhileAccumulating.push_back(ostr.str());
       error++;
+      covLogXML.EndElement(); // Report
+      covLogXML.EndElement(); // File
       continue;
     }
     int untested = 0;
@@ -2016,8 +2018,8 @@
         file += sourceFile;
       }
       file = cmSystemTools::CollapseFullPath(file);
-      bool shouldIDoCoverage = this->ShouldIDoCoverage(
-        file.c_str(), cont->SourceDir.c_str(), cont->BinaryDir.c_str());
+      bool shouldIDoCoverage =
+        this->ShouldIDoCoverage(file, cont->SourceDir, cont->BinaryDir);
       if (!shouldIDoCoverage) {
         cmCTestOptionalLog(
           this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -2318,8 +2320,7 @@
     gl.FindFiles(glob);
     std::vector<std::string> files = gl.GetFiles();
     for (std::string const& f : files) {
-      if (this->ShouldIDoCoverage(f.c_str(), cont->SourceDir.c_str(),
-                                  cont->BinaryDir.c_str())) {
+      if (this->ShouldIDoCoverage(f, cont->SourceDir, cont->BinaryDir)) {
         extraMatches.insert(this->CTest->GetShortPathToFile(f.c_str()));
       }
     }
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 99ac5df..6492fe9 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -57,8 +57,8 @@
   void SetLabelFilter(std::set<std::string> const& labels);
 
 private:
-  bool ShouldIDoCoverage(const char* file, const char* srcDir,
-                         const char* binDir);
+  bool ShouldIDoCoverage(std::string const& file, std::string const& srcDir,
+                         std::string const& binDir);
   void CleanCoverageLogFiles(std::ostream& log);
   bool StartCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
   void EndCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index ab80f5b..2c39cbe 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -14,8 +14,11 @@
       CMAKE_FLAGS ${maybe_cxx_standard}
       OUTPUT_VARIABLE OUTPUT
       )
+    set(check_output "${OUTPUT}")
     # Filter out MSBuild output that looks like a warning.
-    string(REGEX REPLACE " +0 Warning\\(s\\)" "" check_output "${OUTPUT}")
+    string(REGEX REPLACE " +0 Warning\\(s\\)" "" check_output "${check_output}")
+    # Filter out warnings caused by user flags.
+    string(REGEX REPLACE "[^\n]*warning:[^\n]*-Winvalid-command-line-argument[^\n]*" "" check_output "${check_output}")
     # If using the feature causes warnings, treat it as broken/unavailable.
     if(check_output MATCHES "[Ww]arning")
       set(CMake_HAVE_CXX_${FEATURE} OFF CACHE INTERNAL "TRY_COMPILE" FORCE)
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index 8596281..e7ed097 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -72,9 +72,8 @@
         this->Entry = ow;
         std::vector<std::string> options;
         cmSystemTools::ExpandListArgument(stringsProp, options);
-        for (std::vector<std::string>::iterator si = options.begin();
-             si != options.end(); ++si) {
-          ow->AddOption(*si);
+        for (auto const& opt : options) {
+          ow->AddOption(opt);
         }
         ow->SetOption(value);
       } else {
diff --git a/Source/CursesDialog/cmCursesOptionsWidget.cxx b/Source/CursesDialog/cmCursesOptionsWidget.cxx
index d26a98f..a8c4933 100644
--- a/Source/CursesDialog/cmCursesOptionsWidget.cxx
+++ b/Source/CursesDialog/cmCursesOptionsWidget.cxx
@@ -75,9 +75,8 @@
   this->CurrentOption = 0; // default to 0 index
   this->SetValue(value);
   int index = 0;
-  for (std::vector<std::string>::iterator i = this->Options.begin();
-       i != this->Options.end(); ++i) {
-    if (*i == value) {
+  for (auto const& opt : this->Options) {
+    if (opt == value) {
       this->CurrentOption = index;
     }
     index++;
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
index 8cb9c1f..5e2a329 100644
--- a/Source/CursesDialog/cmCursesStringWidget.cxx
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -188,9 +188,7 @@
     char fmt_s[] = "%s";
     char firstLine[512];
     // Clean the toolbar
-    for (int i = 0; i < 512; i++) {
-      firstLine[i] = ' ';
-    }
+    memset(firstLine, ' ', sizeof(firstLine));
     firstLine[511] = '\0';
     curses_move(y - 4, 0);
     printw(fmt_s, firstLine);
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index a290229..a5dc1c6 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -229,7 +229,7 @@
   // returned executableURL is relative to <appbundle>/Contents/MacOS/
   CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle);
 
-  if (executableURL != NULL) {
+  if (executableURL != nullptr) {
     const int MAX_OSX_PATH_SIZE = 1024;
     char buffer[MAX_OSX_PATH_SIZE];
 
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index eee63c9..3e9e995 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -861,18 +861,24 @@
 #endif
 }
 
-std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(
+std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
   const std::string& path) const
 {
+  auto const f = ConvertToNinjaPathCache.find(path);
+  if (f != ConvertToNinjaPathCache.end()) {
+    return f->second;
+  }
+
   cmLocalNinjaGenerator* ng =
     static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]);
-  std::string convPath = ng->ConvertToRelativePath(
-    this->LocalGenerators[0]->GetState()->GetBinaryDirectory(), path);
+  const char* bin_dir = ng->GetState()->GetBinaryDirectory();
+  std::string convPath = ng->ConvertToRelativePath(bin_dir, path);
   convPath = this->NinjaOutputPath(convPath);
 #ifdef _WIN32
   std::replace(convPath.begin(), convPath.end(), '/', '\\');
 #endif
-  return convPath;
+  return ConvertToNinjaPathCache.emplace(path, std::move(convPath))
+    .first->second;
 }
 
 void cmGlobalNinjaGenerator::AddCXXCompileCommand(
@@ -1037,35 +1043,51 @@
 void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
   cmGeneratorTarget const* target, cmNinjaDeps& outputs)
 {
-  TargetDependsClosureMap::iterator i =
-    this->TargetDependsClosures.find(target);
-  if (i == this->TargetDependsClosures.end()) {
-    TargetDependsClosureMap::value_type e(
-      target, std::set<cmGeneratorTarget const*>());
-    i = this->TargetDependsClosures.insert(e).first;
-    this->ComputeTargetDependsClosure(target, i->second);
-  }
-  std::set<cmGeneratorTarget const*> const& targets = i->second;
-  cmNinjaDeps outs;
-  for (auto tgt : targets) {
-    this->AppendTargetOutputs(tgt, outs);
-  }
-  std::sort(outs.begin(), outs.end());
+  cmNinjaOuts outs;
+  this->AppendTargetDependsClosure(target, outs, true);
+
   outputs.insert(outputs.end(), outs.begin(), outs.end());
 }
 
-void cmGlobalNinjaGenerator::ComputeTargetDependsClosure(
-  cmGeneratorTarget const* target, std::set<cmGeneratorTarget const*>& depends)
+void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
+  cmGeneratorTarget const* target, cmNinjaOuts& outputs, bool omit_self)
 {
-  cmTargetDependSet const& targetDeps = this->GetTargetDirectDepends(target);
-  for (auto targetDep : targetDeps) {
-    if (targetDep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-      continue;
+
+  // try to locate the target in the cache
+  auto find = this->TargetDependsClosures.lower_bound(target);
+
+  if (find == this->TargetDependsClosures.end() || find->first != target) {
+    // We now calculate the closure outputs by inspecting the dependent
+    // targets recursively.
+    // For that we have to distinguish between a local result set that is only
+    // relevant for filling the cache entries properly isolated and a global
+    // result set that is relevant for the result of the top level call to
+    // AppendTargetDependsClosure.
+    auto const& targetDeps = this->GetTargetDirectDepends(target);
+    cmNinjaOuts this_outs; // this will be the new cache entry
+
+    for (auto const& dep_target : targetDeps) {
+      if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+        continue;
+      }
+
+      // Collect the dependent targets for _this_ target
+      this->AppendTargetDependsClosure(dep_target, this_outs, false);
     }
-    if (depends.insert(targetDep).second) {
-      this->ComputeTargetDependsClosure(targetDep, depends);
-    }
+    find = this->TargetDependsClosures.emplace_hint(find, target,
+                                                    std::move(this_outs));
   }
+
+  // now fill the outputs of the final result from the newly generated cache
+  // entry
+  outputs.insert(find->second.begin(), find->second.end());
+
+  // finally generate the outputs of the target itself, if applicable
+  cmNinjaDeps outs;
+  if (!omit_self) {
+    this->AppendTargetOutputs(target, outs);
+  }
+  outputs.insert(outs.begin(), outs.end());
 }
 
 void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index f556ce1..7f80d08 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -9,6 +9,7 @@
 #include <map>
 #include <set>
 #include <string>
+#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -245,7 +246,7 @@
     return this->RulesFileStream;
   }
 
-  std::string ConvertToNinjaPath(const std::string& path) const;
+  std::string const& ConvertToNinjaPath(const std::string& path) const;
 
   struct MapToNinjaPathImpl
   {
@@ -320,6 +321,8 @@
     cmNinjaTargetDepends depends = DependOnTargetArtifact);
   void AppendTargetDependsClosure(cmGeneratorTarget const* target,
                                   cmNinjaDeps& outputs);
+  void AppendTargetDependsClosure(cmGeneratorTarget const* target,
+                                  cmNinjaOuts& outputs, bool omit_self);
   void AddDependencyToAll(cmGeneratorTarget* target);
   void AddDependencyToAll(const std::string& input);
 
@@ -448,10 +451,10 @@
   typedef std::map<std::string, cmGeneratorTarget*> TargetAliasMap;
   TargetAliasMap TargetAliases;
 
-  typedef std::map<cmGeneratorTarget const*,
-                   std::set<cmGeneratorTarget const*>>
-    TargetDependsClosureMap;
-  TargetDependsClosureMap TargetDependsClosures;
+  std::map<cmGeneratorTarget const*, cmNinjaOuts> TargetDependsClosures;
+
+  /// the local cache for calls to ConvertToNinjaPath
+  mutable std::unordered_map<std::string, std::string> ConvertToNinjaPathCache;
 
   std::string NinjaCommand;
   std::string NinjaVersion;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 7bc352b..2a05d4e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -79,7 +79,7 @@
 public:
   BuildObjectListOrString(cmGlobalXCodeGenerator* gen, bool buildObjectList)
     : Generator(gen)
-    , Group(0)
+    , Group(nullptr)
     , Empty(true)
   {
     if (buildObjectList) {
@@ -140,10 +140,10 @@
   this->VersionString = version_string;
   this->XcodeVersion = version_number;
 
-  this->RootObject = 0;
-  this->MainGroupChildren = 0;
-  this->CurrentMakefile = 0;
-  this->CurrentLocalGenerator = 0;
+  this->RootObject = nullptr;
+  this->MainGroupChildren = nullptr;
+  this->CurrentMakefile = nullptr;
+  this->CurrentLocalGenerator = nullptr;
   this->XcodeBuildCommandInitialized = false;
 
   this->ObjectDirArchDefault = "$(CURRENT_ARCH)";
@@ -161,15 +161,16 @@
   const std::string& name, cmake* cm) const
 {
   if (name != GetActualName())
-    return 0;
+    return nullptr;
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   cmXcodeVersionParser parser;
   std::string versionFile;
   {
     std::string out;
     std::string::size_type pos;
-    if (cmSystemTools::RunSingleCommand("xcode-select --print-path", &out, 0,
-                                        0, 0, cmSystemTools::OUTPUT_NONE) &&
+    if (cmSystemTools::RunSingleCommand("xcode-select --print-path", &out,
+                                        nullptr, nullptr, nullptr,
+                                        cmSystemTools::OUTPUT_NONE) &&
         (pos = out.find(".app/"), pos != std::string::npos)) {
       versionFile = out.substr(0, pos + 5) + "Contents/version.plist";
     }
@@ -391,7 +392,7 @@
   cmMakefile* mf = root->GetMakefile();
 
   // Add ALL_BUILD
-  const char* no_working_directory = 0;
+  const char* no_working_directory = nullptr;
   std::vector<std::string> no_depends;
   cmTarget* allbuild =
     mf->AddUtilityCommand("ALL_BUILD", true, no_depends, no_working_directory,
@@ -1018,7 +1019,7 @@
         }
         std::string const& obj = (*oi)->GetFullPath();
         cmXCodeObject* xsf =
-          this->CreateXCodeSourceFileFromPath(obj, gtgt, "", 0);
+          this->CreateXCodeSourceFileFromPath(obj, gtgt, "", nullptr);
         externalObjFiles.push_back(xsf);
       }
     }
@@ -1028,10 +1029,10 @@
     bool isBundleTarget = gtgt->GetPropertyAsBool("MACOSX_BUNDLE");
     bool isCFBundleTarget = gtgt->IsCFBundleOnApple();
 
-    cmXCodeObject* buildFiles = 0;
+    cmXCodeObject* buildFiles = nullptr;
 
     // create source build phase
-    cmXCodeObject* sourceBuildPhase = 0;
+    cmXCodeObject* sourceBuildPhase = nullptr;
     if (!sourceFiles.empty()) {
       sourceBuildPhase =
         this->CreateObject(cmXCodeObject::PBXSourcesBuildPhase);
@@ -1049,7 +1050,7 @@
     }
 
     // create header build phase - only for framework targets
-    cmXCodeObject* headerBuildPhase = 0;
+    cmXCodeObject* headerBuildPhase = nullptr;
     if (!headerFiles.empty() && isFrameworkTarget) {
       headerBuildPhase =
         this->CreateObject(cmXCodeObject::PBXHeadersBuildPhase);
@@ -1067,7 +1068,7 @@
     }
 
     // create resource build phase - only for framework or bundle targets
-    cmXCodeObject* resourceBuildPhase = 0;
+    cmXCodeObject* resourceBuildPhase = nullptr;
     if (!resourceFiles.empty() &&
         (isFrameworkTarget || isBundleTarget || isCFBundleTarget)) {
       resourceBuildPhase =
@@ -1177,7 +1178,7 @@
     }
 
     // create framework build phase
-    cmXCodeObject* frameworkBuildPhase = 0;
+    cmXCodeObject* frameworkBuildPhase = nullptr;
     if (!externalObjFiles.empty()) {
       frameworkBuildPhase =
         this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
@@ -1278,7 +1279,7 @@
   const std::vector<cmCustomCommand>& commands)
 {
   if (commands.size() == 0 && strcmp(name, "CMake ReRun") != 0) {
-    return 0;
+    return nullptr;
   }
   cmXCodeObject* buildPhase =
     this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
@@ -1754,8 +1755,8 @@
   const char* version = gtgt->GetProperty("VERSION");
   const char* soversion = gtgt->GetProperty("SOVERSION");
   if (!gtgt->HasSOName(configName) || gtgt->IsFrameworkOnApple()) {
-    version = 0;
-    soversion = 0;
+    version = nullptr;
+    soversion = nullptr;
   }
   if (version && !soversion) {
     soversion = version;
@@ -2038,7 +2039,7 @@
 
   bool same_gflags = true;
   std::map<std::string, std::string> gflags;
-  std::string const* last_gflag = 0;
+  std::string const* last_gflag = nullptr;
   std::string optLevel = "0";
 
   // Minimal map of flags to build settings.
@@ -2108,7 +2109,7 @@
   }
 
   // Add Fortran source format attribute if property is set.
-  const char* format = 0;
+  const char* format = nullptr;
   const char* tgtfmt = gtgt->GetProperty("Fortran_FORMAT");
   switch (cmOutputConverter::GetFortranFormat(tgtfmt)) {
     case cmOutputConverter::FortranFormatFixed:
@@ -2268,8 +2269,8 @@
   target->SetComment(gtgt->GetName());
   cmXCodeObject* buildPhases = this->CreateObject(cmXCodeObject::OBJECT_LIST);
   std::vector<cmXCodeObject*> emptyContentVector;
-  this->CreateCustomCommands(buildPhases, 0, 0, 0, emptyContentVector, 0,
-                             gtgt);
+  this->CreateCustomCommands(buildPhases, nullptr, nullptr, nullptr,
+                             emptyContentVector, nullptr, gtgt);
   target->AddAttribute("buildPhases", buildPhases);
   this->AddConfigurations(target, gtgt);
   cmXCodeObject* dependencies = this->CreateObject(cmXCodeObject::OBJECT_LIST);
@@ -2283,7 +2284,7 @@
   if (gtgt->GetType() == cmStateEnums::UTILITY) {
     std::vector<cmSourceFile*> sources;
     if (!gtgt->GetConfigCommonSourceFiles(sources)) {
-      return 0;
+      return nullptr;
     }
 
     for (std::vector<cmSourceFile*>::const_iterator i = sources.begin();
@@ -2383,7 +2384,7 @@
     default:
       break;
   }
-  return 0;
+  return nullptr;
 }
 
 const char* cmGlobalXCodeGenerator::GetTargetProductType(
@@ -2418,14 +2419,14 @@
     default:
       break;
   }
-  return 0;
+  return nullptr;
 }
 
 cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeTarget(
   cmGeneratorTarget* gtgt, cmXCodeObject* buildPhases)
 {
   if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-    return 0;
+    return nullptr;
   }
   cmXCodeObject* target = this->CreateObject(cmXCodeObject::PBXNativeTarget);
   target->AddAttribute("buildPhases", buildPhases);
@@ -2469,13 +2470,13 @@
   cmGeneratorTarget const* t)
 {
   if (!t) {
-    return 0;
+    return nullptr;
   }
 
   std::map<cmGeneratorTarget const*, cmXCodeObject*>::const_iterator const i =
     this->XCodeObjectMap.find(t);
   if (i == this->XCodeObjectMap.end()) {
-    return 0;
+    return nullptr;
   }
   return i->second;
 }
@@ -2747,7 +2748,7 @@
 cmXCodeObject* cmGlobalXCodeGenerator::CreatePBXGroup(cmXCodeObject* parent,
                                                       std::string name)
 {
-  cmXCodeObject* parentChildren = NULL;
+  cmXCodeObject* parentChildren = nullptr;
   if (parent)
     parentChildren = parent->GetObject("children");
   cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup);
@@ -2781,7 +2782,7 @@
   }
 
   it = this->TargetGroup.find(target);
-  cmXCodeObject* tgroup = 0;
+  cmXCodeObject* tgroup = nullptr;
   if (it != this->TargetGroup.end()) {
     tgroup = it->second;
   } else {
@@ -2847,8 +2848,8 @@
   cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
 {
   this->ClearXCodeObjects();
-  this->RootObject = 0;
-  this->MainGroupChildren = 0;
+  this->RootObject = nullptr;
+  this->MainGroupChildren = nullptr;
   cmXCodeObject* group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
   group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
   cmXCodeObject* listObjs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h
index 4ca02a9..b05eab7 100644
--- a/Source/cmLocalXCodeGenerator.h
+++ b/Source/cmLocalXCodeGenerator.h
@@ -36,7 +36,7 @@
   virtual void GenerateInstallRules();
   virtual void ComputeObjectFilenames(
     std::map<cmSourceFile const*, std::string>& mapping,
-    cmGeneratorTarget const* gt = 0);
+    cmGeneratorTarget const* gt = nullptr);
 
 private:
 };
diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx
index a4350f7..3706dd3 100644
--- a/Source/cmMachO.cxx
+++ b/Source/cmMachO.cxx
@@ -283,7 +283,7 @@
     return false;
   }
 
-  cmMachOHeaderAndLoadCommands* f = NULL;
+  cmMachOHeaderAndLoadCommands* f = nullptr;
   if (magic == MH_CIGAM || magic == MH_MAGIC) {
     bool swap = false;
     if (magic == MH_CIGAM) {
@@ -313,7 +313,7 @@
 // External class implementation.
 
 cmMachO::cmMachO(const char* fname)
-  : Internal(0)
+  : Internal(nullptr)
 {
   this->Internal = new cmMachOInternal(fname);
 }
diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h
index ec435d9..9e962f1 100644
--- a/Source/cmNinjaTypes.h
+++ b/Source/cmNinjaTypes.h
@@ -6,6 +6,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <map>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -16,6 +17,7 @@
 };
 
 typedef std::vector<std::string> cmNinjaDeps;
+typedef std::set<std::string> cmNinjaOuts;
 typedef std::map<std::string, std::string> cmNinjaVars;
 
 #endif // ! cmNinjaTypes_h
diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
index 0def8c3..957adb4 100644
--- a/Source/cmXCodeObject.cxx
+++ b/Source/cmXCodeObject.cxx
@@ -42,8 +42,8 @@
 cmXCodeObject::cmXCodeObject(PBXType ptype, Type type)
 {
   this->Version = 15;
-  this->Target = 0;
-  this->Object = 0;
+  this->Target = nullptr;
+  this->Object = nullptr;
 
   this->IsA = ptype;
 
@@ -71,7 +71,7 @@
 
   this->TypeValue = type;
   if (this->TypeValue == OBJECT) {
-    this->AddAttribute("isa", 0);
+    this->AddAttribute("isa", nullptr);
   }
 }
 
@@ -86,7 +86,7 @@
       return this->ObjectAttributes.empty();
     case OBJECT_REF:
     case OBJECT:
-      return this->Object == 0;
+      return this->Object == nullptr;
   }
   return true; // unreachable, but quiets warnings
 }
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index b92e6e3..b51aac7 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -114,7 +114,7 @@
     if (i != this->ObjectAttributes.end()) {
       return i->second;
     }
-    return 0;
+    return nullptr;
   }
   // search the attribute list for an object of the specified type
   cmXCodeObject* GetObject(cmXCodeObject::PBXType t) const
@@ -126,7 +126,7 @@
         return o;
       }
     }
-    return 0;
+    return nullptr;
   }
 
   void CopyAttributes(cmXCodeObject*);
diff --git a/Source/cmakexbuild.cxx b/Source/cmakexbuild.cxx
index 72da456..20ead47 100644
--- a/Source/cmakexbuild.cxx
+++ b/Source/cmakexbuild.cxx
@@ -47,7 +47,7 @@
     }
     pipe = cmSystemTools::WaitForLine(cp, line, 100, out, err);
   }
-  cmsysProcess_WaitForExit(cp, 0);
+  cmsysProcess_WaitForExit(cp, nullptr);
   if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) {
     return cmsysProcess_GetExitValue(cp);
   }
@@ -64,7 +64,7 @@
   for (int i = 1; i < ac; i++) {
     argv.push_back(av[i]);
   }
-  argv.push_back(0);
+  argv.push_back(nullptr);
   bool hitbug = true;
   int ret = 0;
   while (hitbug) {
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 26868bc..e152cdb 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -282,8 +282,7 @@
   std::vector<std::string> cppcheck_cmd;
   cmSystemTools::ExpandListArgument(runCmd, cppcheck_cmd, true);
   // extract all the -D, -U, and -I options from the compile line
-  for (size_t i = 0; i < orig_cmd.size(); i++) {
-    const std::string& opt = orig_cmd[i];
+  for (auto const& opt : orig_cmd) {
     if (opt.size() > 2) {
       if ((opt[0] == '-') &&
           ((opt[1] == 'D') || (opt[1] == 'I') || (opt[1] == 'U'))) {
@@ -367,9 +366,7 @@
     } else if (doing_options) {
       bool optionFound = false;
       // check arg against all the commandOptions
-      for (std::vector<std::string>::size_type i = 0;
-           i < commandOptions.size(); ++i) {
-        const std::string& command = commandOptions[i];
+      for (auto const& command : commandOptions) {
         if (arg.compare(0, command.size(), command) == 0) {
           optionFound = true;
           runCmd = arg.substr(command.size());
diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx
index 0d692ca..b49803b 100644
--- a/Tests/CMakeLib/run_compile_commands.cxx
+++ b/Tests/CMakeLib/run_compile_commands.cxx
@@ -144,14 +144,11 @@
   cmsys::ifstream file("compile_commands.json");
   CompileCommandParser parser(file);
   parser.Parse();
-  for (CompileCommandParser::TranslationUnitsType::const_iterator
-         it = parser.GetTranslationUnits().begin(),
-         end = parser.GetTranslationUnits().end();
-       it != end; ++it) {
+  for (auto const& tu : parser.GetTranslationUnits()) {
     std::vector<std::string> command;
-    cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command);
+    cmSystemTools::ParseUnixCommandLine(tu.at("command").c_str(), command);
     if (!cmSystemTools::RunSingleCommand(command, nullptr, nullptr, nullptr,
-                                         it->at("directory").c_str())) {
+                                         tu.at("directory").c_str())) {
       std::cout << "ERROR: Failed to run command \"" << command[0] << "\""
                 << std::endl;
       exit(1);
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 88952e1..73fa8fb 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -180,6 +180,8 @@
 add_RunCMake_test(add_custom_command)
 add_RunCMake_test(add_custom_target)
 add_RunCMake_test(add_dependencies)
+add_RunCMake_test(add_executable)
+add_RunCMake_test(add_library)
 add_RunCMake_test(add_subdirectory)
 add_RunCMake_test(build_command)
 add_executable(exit_code exit_code.c)
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index faf151a..fb1f476 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -27,3 +27,4 @@
 run_cpack_test(SYMLINKS "RPM;TGZ" false "MONOLITHIC;COMPONENT")
 run_cpack_test(USER_FILELIST "RPM" false "MONOLITHIC")
 run_cpack_test(MD5SUMS "DEB" false "MONOLITHIC;COMPONENT")
+run_cpack_test(CPACK_INSTALL_SCRIPT "ZIP" false "MONOLITHIC")
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/ExpectedFiles.cmake
new file mode 100644
index 0000000..5cb12c3
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/ExpectedFiles.cmake
@@ -0,0 +1,3 @@
+set(EXPECTED_FILES_COUNT "1")
+
+set(EXPECTED_FILE_CONTENT_1_LIST "/usr;/usr/foo;/usr/foo/abc.txt")
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake
new file mode 100644
index 0000000..e3fe0ca
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake
@@ -0,0 +1,11 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/abc.txt" "test content")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/user-script.cmake"
+  "file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/foo\"
+    TYPE FILE FILES \"${CMAKE_CURRENT_BINARY_DIR}/abc.txt\")")
+set(CPACK_INSTALL_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/user-script.cmake")
+
+function(run_after_include_cpack)
+  file(READ "${CPACK_OUTPUT_CONFIG_FILE}" conf_file_)
+  string(REGEX REPLACE "SET\\(CPACK_INSTALL_CMAKE_PROJECTS [^)]*\\)" "" conf_file_ "${conf_file_}")
+  file(WRITE "${CPACK_OUTPUT_CONFIG_FILE}" "${conf_file_}")
+endfunction()
diff --git a/Tests/RunCMake/add_executable/CMakeLists.txt b/Tests/RunCMake/add_executable/CMakeLists.txt
new file mode 100644
index 0000000..ef2163c
--- /dev/null
+++ b/Tests/RunCMake/add_executable/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/add_executable/NoSources-result.txt b/Tests/RunCMake/add_executable/NoSources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_executable/NoSources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_executable/NoSources-stderr.txt b/Tests/RunCMake/add_executable/NoSources-stderr.txt
new file mode 100644
index 0000000..5985905
--- /dev/null
+++ b/Tests/RunCMake/add_executable/NoSources-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoSources.cmake:[0-9]+ \(add_executable\):
+  add_executable called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/add_executable/NoSources.cmake b/Tests/RunCMake/add_executable/NoSources.cmake
new file mode 100644
index 0000000..563564a
--- /dev/null
+++ b/Tests/RunCMake/add_executable/NoSources.cmake
@@ -0,0 +1 @@
+add_executable(TestExeWithoutSources)
diff --git a/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-result.txt b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt
new file mode 100644
index 0000000..c8afadb
--- /dev/null
+++ b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error at NoSourcesButLinkObjects.cmake:[0-9]+ \(add_executable\):
+  add_executable called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at NoSourcesButLinkObjects.cmake:[0-9]+ \(target_link_libraries\):
+  Cannot specify link libraries for target \"TestExeWithoutSources\" which is
+  not built by this project.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/add_executable/NoSourcesButLinkObjects.cmake b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects.cmake
new file mode 100644
index 0000000..d0f2093
--- /dev/null
+++ b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_executable(TestExeWithoutSources)
+target_link_libraries(TestExeWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_executable/OnlyObjectSources-result.txt b/Tests/RunCMake/add_executable/OnlyObjectSources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_executable/OnlyObjectSources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_executable/OnlyObjectSources-stderr.txt b/Tests/RunCMake/add_executable/OnlyObjectSources-stderr.txt
new file mode 100644
index 0000000..ea72d5d
--- /dev/null
+++ b/Tests/RunCMake/add_executable/OnlyObjectSources-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error at OnlyObjectSources.cmake:[0-9]+ \(add_executable\):
+  add_executable called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at OnlyObjectSources.cmake:[0-9]+ \(target_sources\):
+  Cannot specify sources for target \"TestExeWithoutSources\" which is not
+  built by this project.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/add_executable/OnlyObjectSources.cmake b/Tests/RunCMake/add_executable/OnlyObjectSources.cmake
new file mode 100644
index 0000000..1c90e9a
--- /dev/null
+++ b/Tests/RunCMake/add_executable/OnlyObjectSources.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_executable(TestExeWithoutSources)
+target_sources(TestExeWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_executable/RunCMakeTest.cmake b/Tests/RunCMake/add_executable/RunCMakeTest.cmake
new file mode 100644
index 0000000..70a68f2
--- /dev/null
+++ b/Tests/RunCMake/add_executable/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(NoSources)
+run_cmake(OnlyObjectSources)
+run_cmake(NoSourcesButLinkObjects)
diff --git a/Tests/RunCMake/add_executable/test.cpp b/Tests/RunCMake/add_executable/test.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/add_executable/test.cpp
diff --git a/Tests/RunCMake/add_library/CMakeLists.txt b/Tests/RunCMake/add_library/CMakeLists.txt
new file mode 100644
index 0000000..ef2163c
--- /dev/null
+++ b/Tests/RunCMake/add_library/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/add_library/INTERFACEwithNoSources.cmake b/Tests/RunCMake/add_library/INTERFACEwithNoSources.cmake
new file mode 100644
index 0000000..79188f3
--- /dev/null
+++ b/Tests/RunCMake/add_library/INTERFACEwithNoSources.cmake
@@ -0,0 +1 @@
+add_library(TestInterfaceLibWithoutSources INTERFACE)
diff --git a/Tests/RunCMake/add_library/INTERFACEwithNoSourcesButLinkObjects.cmake b/Tests/RunCMake/add_library/INTERFACEwithNoSourcesButLinkObjects.cmake
new file mode 100644
index 0000000..53a48f0
--- /dev/null
+++ b/Tests/RunCMake/add_library/INTERFACEwithNoSourcesButLinkObjects.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestInterfaceLibWithoutSources INTERFACE)
+target_link_libraries(TestInterfaceLibWithoutSources INTERFACE $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/INTERFACEwithOnlyObjectSources.cmake b/Tests/RunCMake/add_library/INTERFACEwithOnlyObjectSources.cmake
new file mode 100644
index 0000000..86fab1d
--- /dev/null
+++ b/Tests/RunCMake/add_library/INTERFACEwithOnlyObjectSources.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestInterfaceLibWithoutSources INTERFACE)
+target_sources(TestInterfaceLibWithoutSources INTERFACE $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/MODULEwithNoSources-result.txt b/Tests/RunCMake/add_library/MODULEwithNoSources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/MODULEwithNoSources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt b/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt
new file mode 100644
index 0000000..5cf0b1e
--- /dev/null
+++ b/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt
@@ -0,0 +1,3 @@
+^You have called ADD_LIBRARY for library TestModuleLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file(
+CMake Error: CMake can not determine linker language for target: TestModuleLibWithoutSources)+(
+CMake Error: Cannot determine link language for target \"TestModuleLibWithoutSources\".)?$
diff --git a/Tests/RunCMake/add_library/MODULEwithNoSources.cmake b/Tests/RunCMake/add_library/MODULEwithNoSources.cmake
new file mode 100644
index 0000000..5df5033
--- /dev/null
+++ b/Tests/RunCMake/add_library/MODULEwithNoSources.cmake
@@ -0,0 +1 @@
+add_library(TestModuleLibWithoutSources MODULE)
diff --git a/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-result.txt b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt
new file mode 100644
index 0000000..951594a
--- /dev/null
+++ b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt
@@ -0,0 +1,3 @@
+^You have called ADD_LIBRARY for library TestModuleLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file(
+CMake Error: CMake can not determine linker language for target: TestModuleLibWithoutSources)+(
+CMake Error: Cannot determine link language for target \"TestModuleLibWithoutSources\".)*$
diff --git a/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects.cmake b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects.cmake
new file mode 100644
index 0000000..f9d00de
--- /dev/null
+++ b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestModuleLibWithoutSources MODULE)
+target_link_libraries(TestModuleLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/MODULEwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/MODULEwithOnlyObjectSources-stderr.txt
new file mode 100644
index 0000000..de83755
--- /dev/null
+++ b/Tests/RunCMake/add_library/MODULEwithOnlyObjectSources-stderr.txt
@@ -0,0 +1 @@
+^You have called ADD_LIBRARY for library TestModuleLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file$
diff --git a/Tests/RunCMake/add_library/MODULEwithOnlyObjectSources.cmake b/Tests/RunCMake/add_library/MODULEwithOnlyObjectSources.cmake
new file mode 100644
index 0000000..187481a
--- /dev/null
+++ b/Tests/RunCMake/add_library/MODULEwithOnlyObjectSources.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestModuleLibWithoutSources MODULE)
+target_sources(TestModuleLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSources-result.txt b/Tests/RunCMake/add_library/OBJECTwithNoSources-result.txt
new file mode 100644
index 0000000..9c558e3
--- /dev/null
+++ b/Tests/RunCMake/add_library/OBJECTwithNoSources-result.txt
@@ -0,0 +1 @@
+.
diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt b/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt
new file mode 100644
index 0000000..099ec4f
--- /dev/null
+++ b/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt
@@ -0,0 +1,2 @@
+^You have called ADD_LIBRARY for library TestObjectLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file(
+CMake Error: CMake can not determine linker language for target: TestObjectLibWithoutSources)*$
diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSources.cmake b/Tests/RunCMake/add_library/OBJECTwithNoSources.cmake
new file mode 100644
index 0000000..742e829
--- /dev/null
+++ b/Tests/RunCMake/add_library/OBJECTwithNoSources.cmake
@@ -0,0 +1 @@
+add_library(TestObjectLibWithoutSources OBJECT)
diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-result.txt b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt
new file mode 100644
index 0000000..8f20096
--- /dev/null
+++ b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt
@@ -0,0 +1,6 @@
+^You have called ADD_LIBRARY for library TestObjectLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file
+CMake Error at OBJECTwithNoSourcesButLinkObjects.cmake:[0-9]+ \(target_link_libraries\):
+  Object library target \"TestObjectLibWithoutSources\" may not link to
+  anything.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects.cmake b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects.cmake
new file mode 100644
index 0000000..6b4b55f
--- /dev/null
+++ b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestObjectLibWithoutSources OBJECT)
+target_link_libraries(TestObjectLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-result.txt b/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-stderr.txt
new file mode 100644
index 0000000..f9cbf6b
--- /dev/null
+++ b/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-stderr.txt
@@ -0,0 +1,17 @@
+^You have called ADD_LIBRARY for library TestObjectLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file
+CMake Error at OBJECTwithOnlyObjectSources.cmake:[0-9]+ \(add_library\):
+  OBJECT library \"TestObjectLibWithoutSources\" contains:
+
+    [^
+]*test(\.cpp)?\.o(bj)?
+
+  but may contain only sources that compile, header files, and other files
+  that would not affect linking of a normal library.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at OBJECTwithOnlyObjectSources.cmake:[0-9]+ \(add_library\):
+  Only executables and non-OBJECT libraries may reference target objects.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources.cmake b/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources.cmake
new file mode 100644
index 0000000..ff75a8c
--- /dev/null
+++ b/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestObjectLibWithoutSources OBJECT)
+target_sources(TestObjectLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/RunCMakeTest.cmake b/Tests/RunCMake/add_library/RunCMakeTest.cmake
new file mode 100644
index 0000000..0ba6216
--- /dev/null
+++ b/Tests/RunCMake/add_library/RunCMakeTest.cmake
@@ -0,0 +1,24 @@
+include(RunCMake)
+
+run_cmake(INTERFACEwithNoSources)
+run_cmake(OBJECTwithNoSources)
+run_cmake(STATICwithNoSources)
+run_cmake(SHAREDwithNoSources)
+run_cmake(MODULEwithNoSources)
+run_cmake(UNKNOWNwithNoSources)
+
+run_cmake(INTERFACEwithOnlyObjectSources)
+run_cmake(OBJECTwithOnlyObjectSources)
+run_cmake(STATICwithOnlyObjectSources)
+run_cmake(SHAREDwithOnlyObjectSources)
+run_cmake(MODULEwithOnlyObjectSources)
+run_cmake(UNKNOWNwithOnlyObjectSources)
+
+if(NOT RunCMake_GENERATOR STREQUAL "Xcode" OR NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
+  run_cmake(INTERFACEwithNoSourcesButLinkObjects)
+  run_cmake(OBJECTwithNoSourcesButLinkObjects)
+  run_cmake(STATICwithNoSourcesButLinkObjects)
+  run_cmake(SHAREDwithNoSourcesButLinkObjects)
+  run_cmake(MODULEwithNoSourcesButLinkObjects)
+  run_cmake(UNKNOWNwithNoSourcesButLinkObjects)
+endif()
diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSources-result.txt b/Tests/RunCMake/add_library/SHAREDwithNoSources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/SHAREDwithNoSources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt b/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt
new file mode 100644
index 0000000..228d1cc
--- /dev/null
+++ b/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt
@@ -0,0 +1,3 @@
+^You have called ADD_LIBRARY for library TestSharedLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file(
+CMake Error: CMake can not determine linker language for target: TestSharedLibWithoutSources)+(
+CMake Error: Cannot determine link language for target \"TestSharedLibWithoutSources\".)*$
diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSources.cmake b/Tests/RunCMake/add_library/SHAREDwithNoSources.cmake
new file mode 100644
index 0000000..e147b44
--- /dev/null
+++ b/Tests/RunCMake/add_library/SHAREDwithNoSources.cmake
@@ -0,0 +1 @@
+add_library(TestSharedLibWithoutSources SHARED)
diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-result.txt b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt
new file mode 100644
index 0000000..228d1cc
--- /dev/null
+++ b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt
@@ -0,0 +1,3 @@
+^You have called ADD_LIBRARY for library TestSharedLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file(
+CMake Error: CMake can not determine linker language for target: TestSharedLibWithoutSources)+(
+CMake Error: Cannot determine link language for target \"TestSharedLibWithoutSources\".)*$
diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects.cmake b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects.cmake
new file mode 100644
index 0000000..5e3c270
--- /dev/null
+++ b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestSharedLibWithoutSources SHARED)
+target_link_libraries(TestSharedLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources-stderr.txt
new file mode 100644
index 0000000..ec350cd
--- /dev/null
+++ b/Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources-stderr.txt
@@ -0,0 +1 @@
+^You have called ADD_LIBRARY for library TestSharedLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file$
diff --git a/Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources.cmake b/Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources.cmake
new file mode 100644
index 0000000..09281b0
--- /dev/null
+++ b/Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestSharedLibWithoutSources SHARED)
+target_sources(TestSharedLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/STATICwithNoSources-result.txt b/Tests/RunCMake/add_library/STATICwithNoSources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/STATICwithNoSources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt b/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt
new file mode 100644
index 0000000..830eb22
--- /dev/null
+++ b/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt
@@ -0,0 +1,3 @@
+^You have called ADD_LIBRARY for library TestStaticLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file(
+CMake Error: Cannot determine link language for target \"TestStaticLibWithoutSources\".)?(
+CMake Error: CMake can not determine linker language for target: TestStaticLibWithoutSources)+$
diff --git a/Tests/RunCMake/add_library/STATICwithNoSources.cmake b/Tests/RunCMake/add_library/STATICwithNoSources.cmake
new file mode 100644
index 0000000..94a2d9a
--- /dev/null
+++ b/Tests/RunCMake/add_library/STATICwithNoSources.cmake
@@ -0,0 +1 @@
+add_library(TestStaticLibWithoutSources STATIC)
diff --git a/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-result.txt b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt
new file mode 100644
index 0000000..830eb22
--- /dev/null
+++ b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt
@@ -0,0 +1,3 @@
+^You have called ADD_LIBRARY for library TestStaticLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file(
+CMake Error: Cannot determine link language for target \"TestStaticLibWithoutSources\".)?(
+CMake Error: CMake can not determine linker language for target: TestStaticLibWithoutSources)+$
diff --git a/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects.cmake b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects.cmake
new file mode 100644
index 0000000..b6e137f
--- /dev/null
+++ b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestStaticLibWithoutSources STATIC)
+target_link_libraries(TestStaticLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/STATICwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/STATICwithOnlyObjectSources-stderr.txt
new file mode 100644
index 0000000..5cd10d4
--- /dev/null
+++ b/Tests/RunCMake/add_library/STATICwithOnlyObjectSources-stderr.txt
@@ -0,0 +1 @@
+^You have called ADD_LIBRARY for library TestStaticLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file$
diff --git a/Tests/RunCMake/add_library/STATICwithOnlyObjectSources.cmake b/Tests/RunCMake/add_library/STATICwithOnlyObjectSources.cmake
new file mode 100644
index 0000000..74a8947
--- /dev/null
+++ b/Tests/RunCMake/add_library/STATICwithOnlyObjectSources.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestStaticLibWithoutSources STATIC)
+target_sources(TestStaticLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/UNKNOWNwithNoSources.cmake b/Tests/RunCMake/add_library/UNKNOWNwithNoSources.cmake
new file mode 100644
index 0000000..dc5d777
--- /dev/null
+++ b/Tests/RunCMake/add_library/UNKNOWNwithNoSources.cmake
@@ -0,0 +1 @@
+add_library(TestUnknownLibWithoutSources UNKNOWN IMPORTED)
diff --git a/Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects-result.txt b/Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects-stderr.txt
new file mode 100644
index 0000000..adcd3a2
--- /dev/null
+++ b/Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at UNKNOWNwithNoSourcesButLinkObjects.cmake:[0-9]+ \(target_link_libraries\):
+  Cannot specify link libraries for target \"TestUnknownLibWithoutSources\"
+  which is not built by this project.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects.cmake b/Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects.cmake
new file mode 100644
index 0000000..8e014c2
--- /dev/null
+++ b/Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestUnknownLibWithoutSources UNKNOWN IMPORTED)
+target_link_libraries(TestUnknownLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-result.txt b/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-stderr.txt
new file mode 100644
index 0000000..e332281
--- /dev/null
+++ b/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at UNKNOWNwithOnlyObjectSources.cmake:[0-9]+ \(target_sources\):
+  target_sources called with non-compilable target type
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources.cmake b/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources.cmake
new file mode 100644
index 0000000..604e339
--- /dev/null
+++ b/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(ObjectLibDependency OBJECT test.cpp)
+
+add_library(TestUnknownLibWithoutSources UNKNOWN IMPORTED)
+target_sources(TestUnknownLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
diff --git a/Tests/RunCMake/add_library/test.cpp b/Tests/RunCMake/add_library/test.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/add_library/test.cpp
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h
index 4cb8f81..f33208c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform.h
@@ -52,6 +52,17 @@
 #error Oops: No config.h and no pre-built configuration in archive_platform.h.
 #endif
 
+/* On macOS check for some symbols based on the deployment target version.  */
+#if defined(__APPLE__)
+# undef HAVE_FUTIMENS
+# undef HAVE_UTIMENSAT
+# include <AvailabilityMacros.h>
+# if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+#  define HAVE_FUTIMENS 1
+#  define HAVE_UTIMENSAT 1
+# endif
+#endif
+
 /* It should be possible to get rid of this by extending the feature-test
  * macros to cover Windows API functions, probably along with non-trivial
  * refactoring of code to find structures that sit more cleanly on top of