Merge topic 'graphviz-link-type'

5b46cc91 graphviz: distinguish target dependency types

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1229
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/Auxiliary/vim/indent/cmake.vim b/Auxiliary/vim/indent/cmake.vim
index 6063e43..76aff64 100644
--- a/Auxiliary/vim/indent/cmake.vim
+++ b/Auxiliary/vim/indent/cmake.vim
@@ -14,7 +14,6 @@
 endif
 let b:did_indent = 1
 
-setlocal et
 setlocal indentexpr=CMakeGetIndent(v:lnum)
 setlocal indentkeys+==ENDIF(,ENDFOREACH(,ENDMACRO(,ELSE(,ELSEIF(,ENDWHILE(
 
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 03466ce..423f1ca 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -886,6 +886,8 @@
   * `CTest Script`_ variable: :variable:`CTEST_COVERAGE_EXTRA_FLAGS`
   * :module:`CTest` module variable: ``COVERAGE_EXTRA_FLAGS``
 
+  These options are the first arguments passed to ``CoverageCommand``.
+
 .. _`CTest MemCheck Step`:
 
 CTest MemCheck Step
diff --git a/Help/release/dev/FindMPI-overhaul.rst b/Help/release/dev/FindMPI-overhaul.rst
new file mode 100644
index 0000000..3bff602
--- /dev/null
+++ b/Help/release/dev/FindMPI-overhaul.rst
@@ -0,0 +1,16 @@
+findmpi-overhaul
+----------------
+
+* :module:`FindMPI` gained a number of new features, including:
+
+  * Language-specific components have been added to the module.
+  * Many more MPI environments are now supported.
+  * The environmental support for Fortran has been improved.
+  * A user now has fine-grained control over the MPI selection process,
+    including passing custom parameters to the MPI compiler.
+  * The version of the implemented MPI standard is now being exposed.
+  * MPI-2 C++ bindings can now be detected and also suppressed if so desired.
+  * The available Fortran bindings are now being detected and verified.
+  * Various MPI-3 information can be requested, including the library version
+    and Fortran capabilities of the individual bindings.
+  * Statically linked MPI implementations are supported.
diff --git a/Help/release/dev/cpack-rpm-deb-version.rst b/Help/release/dev/cpack-rpm-deb-version.rst
new file mode 100644
index 0000000..a64e8bd
--- /dev/null
+++ b/Help/release/dev/cpack-rpm-deb-version.rst
@@ -0,0 +1,14 @@
+cpack-rpm-deb-version
+---------------------
+
+* Modules :module:`CPackRPM` and :module:`CPackDeb` learned to set package epoch
+  version.
+  See :variable:`CPACK_RPM_PACKAGE_EPOCH` and
+  :variable:`CPACK_DEBIAN_PACKAGE_EPOCH` variables.
+
+* The :module:`CPackDeb` module learned to set package release version in
+  `Version` info property.
+  See :variable:`CPACK_DEBIAN_PACKAGE_RELEASE` variable.
+
+* The :module:`CPackDeb` module learned more strict package version checking
+  that complies with Debian rules.
diff --git a/Help/release/dev/freebsd-compiler-name.rst b/Help/release/dev/freebsd-compiler-name.rst
new file mode 100644
index 0000000..ece7596
--- /dev/null
+++ b/Help/release/dev/freebsd-compiler-name.rst
@@ -0,0 +1,4 @@
+freebsd-compiler-name
+---------------------
+
+* On FreeBSD the C++ compiler named ``c++`` is now the preferred default.
diff --git a/Help/release/dev/midipix-support.rst b/Help/release/dev/midipix-support.rst
new file mode 100644
index 0000000..adc971e
--- /dev/null
+++ b/Help/release/dev/midipix-support.rst
@@ -0,0 +1,4 @@
+midipix-support
+---------------
+
+* A new minimal platform file for ``Midipix`` was added.
diff --git a/Help/variable/APPLE.rst b/Help/variable/APPLE.rst
index 75eecf1..810d5fc 100644
--- a/Help/variable/APPLE.rst
+++ b/Help/variable/APPLE.rst
@@ -1,6 +1,5 @@
 APPLE
 -----
 
-``True`` if running on OS X.
-
-Set to ``true`` on OS X.
+Set to ``True`` when the target system is an Apple platform
+(macOS, iOS, tvOS or watchOS).
diff --git a/Help/variable/UNIX.rst b/Help/variable/UNIX.rst
index 0877b7c..49d8668 100644
--- a/Help/variable/UNIX.rst
+++ b/Help/variable/UNIX.rst
@@ -1,7 +1,7 @@
 UNIX
 ----
 
-``True`` for UNIX and UNIX like operating systems.
-
-Set to ``true`` when the target system is UNIX or UNIX like (i.e.
-:variable:`APPLE` and :variable:`CYGWIN`).
+Set to ``True`` when the target system is UNIX or UNIX-like
+(e.g. :variable:`APPLE` and :variable:`CYGWIN`).  The
+:variable:`CMAKE_SYSTEM_NAME` variable should be queried if
+a more specific understanding of the target system is required.
diff --git a/Help/variable/WIN32.rst b/Help/variable/WIN32.rst
index 2189069..78ab772 100644
--- a/Help/variable/WIN32.rst
+++ b/Help/variable/WIN32.rst
@@ -1,6 +1,4 @@
 WIN32
 -----
 
-``True`` on Windows systems, including Win64.
-
-Set to ``true`` when the target system is Windows.
+Set to ``True`` when the target system is Windows, including Win64.
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/CPackDeb.cmake b/Modules/CPackDeb.cmake
index 85d564e..337bec8 100644
--- a/Modules/CPackDeb.cmake
+++ b/Modules/CPackDeb.cmake
@@ -88,6 +88,16 @@
 #    get overwritten and it is up to the packager to set the variables in a
 #    manner that will prevent such errors.
 #
+# .. variable:: CPACK_DEBIAN_PACKAGE_EPOCH
+#
+#  The Debian package epoch
+#
+#  * Mandatory : No
+#  * Default   : -
+#
+#  Optional number that should be incremented when changing versioning schemas
+#  or fixing mistakes in the version numbers of older packages.
+#
 # .. variable:: CPACK_DEBIAN_PACKAGE_VERSION
 #
 #  The Debian package version
@@ -95,12 +105,17 @@
 #  * Mandatory : YES
 #  * Default   : :variable:`CPACK_PACKAGE_VERSION`
 #
+#  This variable may contain only alphanumerics (A-Za-z0-9) and the characters
+#  . + - ~ (full stop, plus, hyphen, tilde) and should start with a digit. If
+#  :variable:`CPACK_DEBIAN_PACKAGE_RELEASE` is not set then hyphens are not
+#  allowed.
+#
 # .. variable:: CPACK_DEBIAN_PACKAGE_RELEASE
 #
 #  The Debian package release - Debian revision number.
 #
-#  * Mandatory : YES
-#  * Default   : 1
+#  * Mandatory : No
+#  * Default   : -
 #
 #  This is the numbering of the DEB package itself, i.e. the version of the
 #  packaging and not the version of the content (see
@@ -738,6 +753,32 @@
     set(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
   endif()
 
+  if(NOT CPACK_DEBIAN_PACKAGE_VERSION MATCHES "^[0-9][A-Za-z0-9.+-~]*$")
+    message(FATAL_ERROR
+      "CPackDeb: Debian package version must confirm to \"^[0-9][A-Za-z0-9.+-~]*$\" regex!")
+  endif()
+
+  if(CPACK_DEBIAN_PACKAGE_RELEASE)
+    if(NOT CPACK_DEBIAN_PACKAGE_RELEASE MATCHES "^[A-Za-z0-9.+~]+$")
+      message(FATAL_ERROR
+        "CPackDeb: Debian package release must confirm to \"^[A-Za-z0-9.+~]+$\" regex!")
+    endif()
+    string(APPEND CPACK_DEBIAN_PACKAGE_VERSION
+      "-${CPACK_DEBIAN_PACKAGE_RELEASE}")
+  elseif(CPACK_DEBIAN_PACKAGE_VERSION MATCHES ".*-.*")
+    message(FATAL_ERROR
+      "CPackDeb: Debian package version must not contain hyphens when CPACK_DEBIAN_PACKAGE_RELEASE is not provided!")
+  endif()
+
+  if(CPACK_DEBIAN_PACKAGE_EPOCH)
+    if(NOT CPACK_DEBIAN_PACKAGE_EPOCH MATCHES "^[0-9]+$")
+      message(FATAL_ERROR
+        "CPackDeb: Debian package epoch must confirm to \"^[0-9]+$\" regex!")
+    endif()
+    set(CPACK_DEBIAN_PACKAGE_VERSION
+      "${CPACK_DEBIAN_PACKAGE_EPOCH}:${CPACK_DEBIAN_PACKAGE_VERSION}")
+  endif()
+
   # Architecture: (mandatory)
   if(CPACK_DEB_PACKAGE_COMPONENT AND CPACK_DEBIAN_${_local_component_name}_PACKAGE_ARCHITECTURE)
     set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_DEBIAN_${_local_component_name}_PACKAGE_ARCHITECTURE}")
@@ -961,11 +1002,6 @@
     set(CPACK_DEBIAN_GENERATE_POSTRM 0)
   endif()
 
-  if(NOT CPACK_DEBIAN_PACKAGE_RELEASE)
-    set(CPACK_DEBIAN_PACKAGE_RELEASE 1)
-  endif()
-
-
   cpack_deb_variable_fallback("CPACK_DEBIAN_FILE_NAME"
     "CPACK_DEBIAN_${_local_component_name}_FILE_NAME"
     "CPACK_DEBIAN_FILE_NAME")
@@ -974,7 +1010,7 @@
       # Patch package file name to be in corrent debian format:
       # <foo>_<VersionNumber>-<DebianRevisionNumber>_<DebianArchitecture>.deb
       set(CPACK_OUTPUT_FILE_NAME
-        "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}-${CPACK_DEBIAN_PACKAGE_RELEASE}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
+        "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
     else()
       cmake_policy(PUSH)
         cmake_policy(SET CMP0010 NEW)
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index 3913494..9f77ec3 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -106,6 +106,16 @@
 #  group rpm package is generated without component suffix in filename and
 #  package name.
 #
+# .. variable:: CPACK_RPM_PACKAGE_EPOCH
+#
+#  The RPM package epoch
+#
+#  * Mandatory : No
+#  * Default   : -
+#
+#  Optional number that should be incremented when changing versioning schemas
+#  or fixing mistakes in the version numbers of older packages.
+#
 # .. variable:: CPACK_RPM_PACKAGE_VERSION
 #
 #  The RPM package version.
@@ -530,7 +540,9 @@
 #  list of path to be excluded.
 #
 #  * Mandatory : NO
-#  * Default   : /etc /etc/init.d /usr /usr/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/include
+#  * Default   : /etc /etc/init.d /usr /usr/bin /usr/include /usr/lib
+#                /usr/libx32 /usr/lib64 /usr/share /usr/share/aclocal
+#                /usr/share/doc
 #
 #  May be used to exclude path (directories or files) from the auto-generated
 #  list of paths discovered by CPack RPM. The defaut value contains a
@@ -1083,7 +1095,9 @@
   endif()
 
   if(NOT DEFINED CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST)
-    set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST /etc /etc/init.d /usr /usr/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/libx32 /usr/include)
+    set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST /etc /etc/init.d /usr /usr/bin
+        /usr/include /usr/lib /usr/libx32 /usr/lib64
+        /usr/share /usr/share/aclocal /usr/share/doc )
     if(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION)
       if(CPACK_RPM_PACKAGE_DEBUG)
         message("CPackRPM:Debug: Adding ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION} to builtin omit list.")
@@ -1891,11 +1905,16 @@
     OUTPUT_STRIP_TRAILING_WHITESPACE)
   string(REPLACE "\n" ";" RPMBUILD_TAG_LIST "${RPMBUILD_TAG_LIST}")
 
+  if(CPACK_RPM_PACKAGE_EPOCH)
+    set(TMP_RPM_EPOCH "Epoch: ${CPACK_RPM_PACKAGE_EPOCH}")
+  endif()
+
   # Check if additional fields for RPM spec header are given
   # There may be some COMPONENT specific variables as well
   # If component specific var is not provided we use the global one
   # for each component
   foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN)
+
     if(CPACK_RPM_PACKAGE_DEBUG)
       message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}")
     endif()
@@ -2501,6 +2520,7 @@
 \@TMP_RPM_AUTOREQPROV\@
 \@TMP_RPM_BUILDARCH\@
 \@TMP_RPM_PREFIXES\@
+\@TMP_RPM_EPOCH\@
 
 %description -n \@CPACK_RPM_PACKAGE_NAME\@
 \@CPACK_RPM_PACKAGE_DESCRIPTION\@
@@ -2560,6 +2580,7 @@
 \@TMP_RPM_AUTOREQPROV\@
 \@TMP_RPM_BUILDARCH\@
 \@TMP_RPM_PREFIXES\@
+\@TMP_RPM_EPOCH\@
 
 \@TMP_RPM_DEBUGINFO\@
 
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/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 614a7ca..6d1514d 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -76,7 +76,7 @@
 # Boost::system will be automatically detected and satisfied, even
 # if system is not specified when using find_package and if
 # Boost::system is not added to target_link_libraries.  If using
-# Boost::thread, then Thread::Thread will also be added automatically.
+# Boost::thread, then Threads::Threads will also be added automatically.
 #
 # It is important to note that the imported targets behave differently
 # than variables created by this module: multiple calls to
@@ -214,6 +214,10 @@
 #
 # Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake.
 
+# Save project's policies
+cmake_policy(PUSH)
+cmake_policy(SET CMP0057 NEW) # if IN_LIST
+
 #-------------------------------------------------------------------------------
 # Before we go searching, check whether boost-cmake is available, unless the
 # user specifically asked NOT to search for boost-cmake.
@@ -307,6 +311,10 @@
 
     if(Boost_${basename}_LIBRARY AND Boost_${basename}_HEADER)
       set(Boost_${basename}_FOUND ON)
+      if("x${basename}" STREQUAL "xTHREAD" AND NOT TARGET Threads::Threads)
+        string(APPEND Boost_ERROR_REASON_THREAD " (missing dependency: Threads)")
+        set(Boost_THREAD_FOUND OFF)
+      endif()
     endif()
 
   endif()
@@ -901,9 +909,7 @@
       set(_Boost_${uppercomponent}_DEPENDENCIES ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE)
       set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE)
       foreach(componentdep ${_Boost_${uppercomponent}_DEPENDENCIES})
-        list(FIND _boost_processed_components "${componentdep}" _boost_component_found)
-        list(FIND _boost_new_components "${componentdep}" _boost_component_new)
-        if (_boost_component_found EQUAL -1 AND _boost_component_new EQUAL -1)
+        if (NOT ("${componentdep}" IN_LIST _boost_processed_components OR "${componentdep}" IN_LIST _boost_new_components))
           list(APPEND _boost_new_components ${componentdep})
         endif()
       endforeach()
@@ -1537,10 +1543,14 @@
 _Boost_MISSING_DEPENDENCIES(Boost_FIND_COMPONENTS _Boost_EXTRA_FIND_COMPONENTS)
 
 # If thread is required, get the thread libs as a dependency
-list(FIND Boost_FIND_COMPONENTS thread _Boost_THREAD_DEPENDENCY_LIBS)
-if(NOT _Boost_THREAD_DEPENDENCY_LIBS EQUAL -1)
-  include(CMakeFindDependencyMacro)
-  find_dependency(Threads)
+if("thread" IN_LIST Boost_FIND_COMPONENTS)
+  if(Boost_FIND_QUIETLY)
+    set(_Boost_find_quiet QUIET)
+  else()
+    set(_Boost_find_quiet "")
+  endif()
+  find_package(Threads ${_Boost_find_quiet})
+  unset(_Boost_find_quiet)
 endif()
 
 # If the user changed any of our control inputs flush previous results.
@@ -1770,8 +1780,9 @@
     string(APPEND Boost_ERROR_REASON
       " Boost libraries:\n")
     foreach(COMPONENT ${_Boost_MISSING_COMPONENTS})
+      string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
       string(APPEND Boost_ERROR_REASON
-        "        ${Boost_NAMESPACE}_${COMPONENT}\n")
+        "        ${Boost_NAMESPACE}_${COMPONENT}${Boost_ERROR_REASON_${UPPERCOMPONENT}}\n")
     endforeach()
 
     list(LENGTH Boost_FIND_COMPONENTS Boost_NUM_COMPONENTS_WANTED)
@@ -1967,3 +1978,6 @@
 list(SORT _Boost_COMPONENTS_SEARCHED)
 set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}"
   CACHE INTERNAL "Components requested for this build tree.")
+
+# Restore project's policies
+cmake_policy(POP)
diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake
index cb71ef1..b0579d9 100644
--- a/Modules/FindGTest.cmake
+++ b/Modules/FindGTest.cmake
@@ -75,7 +75,7 @@
 
 include(${CMAKE_CURRENT_LIST_DIR}/GoogleTest.cmake)
 
-function(_gtest_append_debugs _endvar _library)
+function(__gtest_append_debugs _endvar _library)
     if(${_library} AND ${_library}_DEBUG)
         set(_output optimized ${${_library}} debug ${${_library}_DEBUG})
     else()
@@ -84,7 +84,7 @@
     set(${_endvar} ${_output} PARENT_SCOPE)
 endfunction()
 
-function(_gtest_find_library _name)
+function(__gtest_find_library _name)
     find_library(${_name}
         NAMES ${ARGN}
         HINTS
@@ -95,6 +95,56 @@
     mark_as_advanced(${_name})
 endfunction()
 
+macro(__gtest_determine_windows_library_type _var)
+    if(EXISTS "${${_var}}")
+        file(TO_NATIVE_PATH "${${_var}}" _lib_path)
+        get_filename_component(_name "${${_var}}" NAME_WE)
+        file(STRINGS "${${_var}}" _match REGEX "${_name}\\.dll" LIMIT_COUNT 1)
+        if(NOT _match STREQUAL "")
+            set(${_var}_TYPE SHARED PARENT_SCOPE)
+        else()
+            set(${_var}_TYPE UNKNOWN PARENT_SCOPE)
+        endif()
+        return()
+    endif()
+endmacro()
+
+function(__gtest_determine_library_type _var)
+    if(WIN32)
+        # For now, at least, only Windows really needs to know the library type
+        __gtest_determine_windows_library_type(${_var})
+        __gtest_determine_windows_library_type(${_var}_RELEASE)
+        __gtest_determine_windows_library_type(${_var}_DEBUG)
+    endif()
+    # If we get here, no determination was made from the above checks
+    set(${_var}_TYPE UNKNOWN PARENT_SCOPE)
+endfunction()
+
+function(__gtest_import_library _target _var _config)
+    if(_config)
+        set(_config_suffix "_${_config}")
+    else()
+        set(_config_suffix "")
+    endif()
+
+    set(_lib "${${_var}${_config_suffix}}")
+    if(EXISTS "${_lib}")
+        if(_config)
+            set_property(TARGET ${_target} APPEND PROPERTY
+                IMPORTED_CONFIGURATIONS ${_config})
+        endif()
+        set_target_properties(${_target} PROPERTIES
+            IMPORTED_LINK_INTERFACE_LANGUAGES${_config_suffix} "CXX")
+        if(WIN32 AND ${_var}_TYPE STREQUAL SHARED)
+            set_target_properties(${_target} PROPERTIES
+                IMPORTED_IMPLIB${_config_suffix} "${_lib}")
+        else()
+            set_target_properties(${_target} PROPERTIES
+                IMPORTED_LOCATION${_config_suffix} "${_lib}")
+        endif()
+    endif()
+endfunction()
+
 #
 
 if(NOT DEFINED GTEST_MSVC_SEARCH)
@@ -131,15 +181,15 @@
 if(MSVC AND GTEST_MSVC_SEARCH STREQUAL "MD")
     # The provided /MD project files for Google Test add -md suffixes to the
     # library names.
-    _gtest_find_library(GTEST_LIBRARY            gtest-md  gtest)
-    _gtest_find_library(GTEST_LIBRARY_DEBUG      gtest-mdd gtestd)
-    _gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main-md  gtest_main)
-    _gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind)
+    __gtest_find_library(GTEST_LIBRARY            gtest-md  gtest)
+    __gtest_find_library(GTEST_LIBRARY_DEBUG      gtest-mdd gtestd)
+    __gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main-md  gtest_main)
+    __gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind)
 else()
-    _gtest_find_library(GTEST_LIBRARY            gtest)
-    _gtest_find_library(GTEST_LIBRARY_DEBUG      gtestd)
-    _gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main)
-    _gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind)
+    __gtest_find_library(GTEST_LIBRARY            gtest)
+    __gtest_find_library(GTEST_LIBRARY_DEBUG      gtestd)
+    __gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main)
+    __gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind)
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
@@ -147,63 +197,38 @@
 
 if(GTEST_FOUND)
     set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIR})
-    _gtest_append_debugs(GTEST_LIBRARIES      GTEST_LIBRARY)
-    _gtest_append_debugs(GTEST_MAIN_LIBRARIES GTEST_MAIN_LIBRARY)
+    __gtest_append_debugs(GTEST_LIBRARIES      GTEST_LIBRARY)
+    __gtest_append_debugs(GTEST_MAIN_LIBRARIES GTEST_MAIN_LIBRARY)
     set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
 
-    include(CMakeFindDependencyMacro)
-    find_dependency(Threads)
+    find_package(Threads QUIET)
 
     if(NOT TARGET GTest::GTest)
-        add_library(GTest::GTest UNKNOWN IMPORTED)
-        set_target_properties(GTest::GTest PROPERTIES
-            INTERFACE_LINK_LIBRARIES "Threads::Threads")
+        __gtest_determine_library_type(GTEST_LIBRARY)
+        add_library(GTest::GTest ${GTEST_LIBRARY_TYPE} IMPORTED)
+        if(TARGET Threads::Threads)
+            set_target_properties(GTest::GTest PROPERTIES
+                INTERFACE_LINK_LIBRARIES Threads::Threads)
+        endif()
+        if(GTEST_LIBRARY_TYPE STREQUAL "SHARED")
+            set_target_properties(GTest::GTest PROPERTIES
+                INTERFACE_COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
+        endif()
         if(GTEST_INCLUDE_DIRS)
             set_target_properties(GTest::GTest PROPERTIES
                 INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIRS}")
         endif()
-        if(EXISTS "${GTEST_LIBRARY}")
-            set_target_properties(GTest::GTest PROPERTIES
-                IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
-                IMPORTED_LOCATION "${GTEST_LIBRARY}")
-        endif()
-        if(EXISTS "${GTEST_LIBRARY_RELEASE}")
-            set_property(TARGET GTest::GTest APPEND PROPERTY
-                IMPORTED_CONFIGURATIONS RELEASE)
-            set_target_properties(GTest::GTest PROPERTIES
-                IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
-                IMPORTED_LOCATION_RELEASE "${GTEST_LIBRARY_RELEASE}")
-        endif()
-        if(EXISTS "${GTEST_LIBRARY_DEBUG}")
-            set_property(TARGET GTest::GTest APPEND PROPERTY
-                IMPORTED_CONFIGURATIONS DEBUG)
-            set_target_properties(GTest::GTest PROPERTIES
-                IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
-                IMPORTED_LOCATION_DEBUG "${GTEST_LIBRARY_DEBUG}")
-        endif()
-      endif()
-      if(NOT TARGET GTest::Main)
-          add_library(GTest::Main UNKNOWN IMPORTED)
-          set_target_properties(GTest::Main PROPERTIES
-              INTERFACE_LINK_LIBRARIES "GTest::GTest")
-          if(EXISTS "${GTEST_MAIN_LIBRARY}")
-              set_target_properties(GTest::Main PROPERTIES
-                  IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
-                  IMPORTED_LOCATION "${GTEST_MAIN_LIBRARY}")
-          endif()
-          if(EXISTS "${GTEST_MAIN_LIBRARY_RELEASE}")
-            set_property(TARGET GTest::Main APPEND PROPERTY
-                IMPORTED_CONFIGURATIONS RELEASE)
-            set_target_properties(GTest::Main PROPERTIES
-                IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
-                IMPORTED_LOCATION_RELEASE "${GTEST_MAIN_LIBRARY_RELEASE}")
-          endif()
-          if(EXISTS "${GTEST_MAIN_LIBRARY_DEBUG}")
-            set_property(TARGET GTest::Main APPEND PROPERTY
-                IMPORTED_CONFIGURATIONS DEBUG)
-            set_target_properties(GTest::Main PROPERTIES
-                IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
-                IMPORTED_LOCATION_DEBUG "${GTEST_MAIN_LIBRARY_DEBUG}")
-          endif()
+        __gtest_import_library(GTest::GTest GTEST_LIBRARY "")
+        __gtest_import_library(GTest::GTest GTEST_LIBRARY "RELEASE")
+        __gtest_import_library(GTest::GTest GTEST_LIBRARY "DEBUG")
+    endif()
+    if(NOT TARGET GTest::Main)
+        __gtest_determine_library_type(GTEST_MAIN_LIBRARY)
+        add_library(GTest::Main ${GTEST_MAIN_LIBRARY_TYPE} IMPORTED)
+        set_target_properties(GTest::Main PROPERTIES
+            INTERFACE_LINK_LIBRARIES "GTest::GTest")
+        __gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "")
+        __gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "RELEASE")
+        __gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "DEBUG")
     endif()
 endif()
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 37f3255..578fcd2 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -5,27 +5,45 @@
 # FindMPI
 # -------
 #
-# Find a Message Passing Interface (MPI) implementation
+# Find a Message Passing Interface (MPI) implementation.
 #
 # The Message Passing Interface (MPI) is a library used to write
 # high-performance distributed-memory parallel applications, and is
 # typically deployed on a cluster.  MPI is a standard interface (defined
 # by the MPI forum) for which many implementations are available.
 #
-# Variables
-# ^^^^^^^^^
+# Variables for using MPI
+# ^^^^^^^^^^^^^^^^^^^^^^^
+#
+# The module exposes the components ``C``, ``CXX``, ``MPICXX`` and ``Fortran``.
+# Each of these controls the various MPI languages to search for.
+# The difference between ``CXX`` and ``MPICXX`` is that ``CXX`` refers to the
+# MPI C API being usable from C++, whereas ``MPICXX`` refers to the MPI-2 C++ API
+# that was removed again in MPI-3.
+#
+# Depending on the enabled components the following variables will be set:
+#
+# ``MPI_FOUND``
+#   Variable indicating that MPI settings for all requested languages have been found.
+#   If no components are specified, this is true if MPI settings for all enabled languages
+#   were detected. Note that the ``MPICXX`` component does not affect this variable.
+# ``MPI_VERSION``
+#   Minimal version of MPI detected among the requested languages, or all enabled languages
+#   if no components were specified.
 #
 # This module will set the following variables per language in your
 # project, where ``<lang>`` is one of C, CXX, or Fortran:
 #
 # ``MPI_<lang>_FOUND``
-#   Variable indicating the MPI settings for ``<lang>`` were found.
+#   Variable indicating the MPI settings for ``<lang>`` were found and that
+#   simple MPI test programs compile with the provided settings.
 # ``MPI_<lang>_COMPILER``
-#   MPI Compiler wrapper for ``<lang>``.
-# ``MPI_<lang>_COMPILE_FLAGS``
-#   Compilation flags for MPI programs, separated by spaces.
-#   This is *not* a :ref:`;-list <CMake Language Lists>`.
-# ``MPI_<lang>_INCLUDE_PATH``
+#   MPI compiler for ``<lang>`` if such a program exists.
+# ``MPI_<lang>_COMPILE_OPTIONS``
+#   Compilation options for MPI programs in ``<lang>``, given as a :ref:`;-list <CMake Language Lists>`.
+# ``MPI_<lang>_COMPILE_DEFINITIONS``
+#   Compilation definitions for MPI programs in ``<lang>``, given as a :ref:`;-list <CMake Language Lists>`.
+# ``MPI_<lang>_INCLUDE_DIRS``
 #   Include path(s) for MPI header.
 # ``MPI_<lang>_LINK_FLAGS``
 #   Linker flags for MPI programs.
@@ -37,53 +55,172 @@
 # ``MPI::MPI_<lang>``
 #   Target for using MPI from ``<lang>``.
 #
-# Additionally, FindMPI sets the following variables for running MPI
-# programs from the command line:
+# The following variables indicating which bindings are present will be defined:
 #
-# ``MPIEXEC``
-#   Executable for running MPI programs, if provided.
+# ``MPI_MPICXX_FOUND``
+#   Variable indicating whether the MPI-2 C++ bindings are present (introduced in MPI-2, removed with MPI-3).
+# ``MPI_Fortran_HAVE_F77_HEADER``
+#   True if the Fortran 77 header ``mpif.h`` is available.
+# ``MPI_Fortran_HAVE_F90_MODULE``
+#   True if the Fortran 90 module ``mpi`` can be used for accessing MPI (MPI-2 and higher only).
+# ``MPI_Fortran_HAVE_F08_MODULE``
+#   True if the Fortran 2008 ``mpi_f08`` is available to MPI programs (MPI-3 and higher only).
+#
+# If possible, the MPI version will be determined by this module. The facilities to detect the MPI version
+# were introduced with MPI-1.2, and therefore cannot be found for older MPI versions.
+#
+# ``MPI_<lang>_VERSION_MAJOR``
+#   Major version of MPI implemented for ``<lang>`` by the MPI distribution.
+# ``MPI_<lang>_VERSION_MINOR``
+#   Minor version of MPI implemented for ``<lang>`` by the MPI distribution.
+# ``MPI_<lang>_VERSION``
+#   MPI version implemented for ``<lang>`` by the MPI distribution.
+#
+# Note that there's no variable for the C bindings being accessible through ``mpi.h``, since the MPI standards
+# always have required this binding to work in both C and C++ code.
+#
+# For running MPI programs, the module sets the following variables
+#
+# ``MPIEXEC_EXECUTABLE``
+#   Executable for running MPI programs, if such exists.
 # ``MPIEXEC_NUMPROC_FLAG``
-#   Flag to pass to ``MPIEXEC`` before giving it the number of processors to run on.
+#   Flag to pass to ``mpiexec`` before giving it the number of processors to run on.
 # ``MPIEXEC_MAX_NUMPROCS``
 #   Number of MPI processors to utilize. Defaults to the number
 #   of processors detected on the host system.
 # ``MPIEXEC_PREFLAGS``
-#   Flags to pass to ``MPIEXEC`` directly before the executable to run.
+#   Flags to pass to ``mpiexec`` directly before the executable to run.
 # ``MPIEXEC_POSTFLAGS``
-#   Flags to pass to ``MPIEXEC`` after other flags.
+#   Flags to pass to ``mpiexec`` after other flags.
 #
-# Usage
-# ^^^^^
+# Variables for locating MPI
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^
 #
-# To use this module, call ``find_package(MPI)``.  If you are happy with the
-# auto-detected configuration for your language, then you're done.  If
-# not, you have two options:
+# This module performs a three step search for an MPI implementation:
 #
-# 1. Set ``MPI_<lang>_COMPILER`` to the MPI wrapper (e.g. ``mpicc``) of your
-#    choice and reconfigure.  FindMPI will attempt to determine all the
-#    necessary variables using *that* compiler's compile and link flags.
-# 2. If this fails, or if your MPI implementation does not come with
-#    a compiler wrapper, then set both ``MPI_<lang>_LIBRARIES`` and
-#    ``MPI_<lang>_INCLUDE_PATH``.  You may also set any other variables
-#    listed above, but these two are required.  This will circumvent
-#    autodetection entirely.
+# 1. Check if the compiler has MPI support built-in. This is the case if the user passed a
+#    compiler wrapper as ``CMAKE_<LANG>_COMPILER`` or if they're on a Cray system.
+# 2. Attempt to find an MPI compiler wrapper and determine the compiler information from it.
+# 3. Try to find an MPI implementation that does not ship such a wrapper by guessing settings.
+#    Currently, only Microsoft MPI and MPICH2 on Windows are supported.
 #
-# When configuration is successful, ``MPI_<lang>_COMPILER`` will be set to
-# the compiler wrapper for ``<lang>``, if it was found. ``MPI_<lang>_FOUND``
-# and other variables above will be set if any MPI implementation was
-# found for ``<lang>``, regardless of whether a compiler was found.
+# For controlling the second step, the following variables may be set:
 #
-# When using ``MPIEXEC`` to execute MPI applications, you should typically
-# use all of the ``MPIEXEC`` flags as follows:
+# ``MPI_<lang>_COMPILER``
+#   Search for the specified compiler wrapper and use it.
+# ``MPI_<lang>_COMPILER_FLAGS``
+#   Flags to pass to the MPI compiler wrapper during interrogation. Some compiler wrappers
+#   support linking debug or tracing libraries if a specific flag is passed and this variable
+#   may be used to obtain them.
+# ``MPI_COMPILER_FLAGS``
+#   Used to initialize ``MPI_<lang>_COMPILER_FLAGS`` if no language specific flag has been given.
+#   Empty by default.
+# ``MPI_EXECUTABLE_SUFFIX``
+#   A suffix which is appended to all names that are being looked for. For instance you may set this
+#   to ``.mpich`` or ``.openmpi`` to prefer the one or the other on Debian and its derivatives.
+#
+# In order to control the guessing step, the following variable may be set:
+#
+# ``MPI_GUESS_LIBRARY_NAME``
+#   Valid values are ``MSMPI`` and ``MPICH2``. If set, only the given library will be searched for.
+#   By default, ``MSMPI`` will be preferred over ``MPICH2`` if both are available.
+#   This also sets ``MPI_SKIP_COMPILER_WRAPPER`` to ``true``, which may be overridden.
+#
+# Each of the search steps may be skipped with the following control variables:
+#
+# ``MPI_ASSUME_NO_BUILTIN_MPI``
+#   If true, the module assumes that the compiler itself does not provide an MPI implementation and
+#   skips to step 2.
+# ``MPI_SKIP_COMPILER_WRAPPER``
+#   If true, no compiler wrapper will be searched for.
+# ``MPI_SKIP_GUESSING``
+#   If true, the guessing step will be skipped.
+#
+# Additionally, the following control variable is available to change search behavior:
+#
+# ``MPI_CXX_SKIP_MPICXX``
+#   Add some definitions that will disable the MPI-2 C++ bindings.
+#   Currently supported are MPICH, Open MPI, Platform MPI and derivatives thereof,
+#   for example MVAPICH or Intel MPI.
+#
+# If the find procedure fails for a variable ``MPI_<lang>_WORKS``, then the settings detected by or passed to
+# the module did not work and even a simple MPI test program failed to compile.
+#
+# If all of these parameters were not sufficient to find the right MPI implementation, a user may
+# disable the entire autodetection process by specifying both a list of libraries in ``MPI_<lang>_LIBRARIES``
+# and a list of include directories in ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS``.
+# Any other variable may be set in addition to these two. The module will then validate the MPI settings and store the
+# settings in the cache.
+#
+# Cache variables for MPI
+# ^^^^^^^^^^^^^^^^^^^^^^^
+#
+# The variable ``MPI_<lang>_INCLUDE_DIRS`` will be assembled from the following variables.
+# For C and CXX:
+#
+# ``MPI_<lang>_HEADER_DIR``
+#   Location of the ``mpi.h`` header on disk.
+#
+# For Fortran:
+#
+# ``MPI_Fortran_F77_HEADER_DIR``
+#   Location of the Fortran 77 header ``mpif.h``, if it exists.
+# ``MPI_Fortran_MODULE_DIR``
+#   Location of the ``mpi`` or ``mpi_f08`` modules, if available.
+#
+# For all languages the following variables are additionally considered:
+#
+# ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS``
+#   A :ref:`;-list <CMake Language Lists>` of paths needed in addition to the normal include directories.
+# ``MPI_<include_name>_INCLUDE_DIR``
+#   Path variables for include folders referred to by ``<include_name>``.
+# ``MPI_<lang>_ADDITIONAL_INCLUDE_VARS``
+#   A :ref:`;-list <CMake Language Lists>` of ``<include_name>`` that will be added to the include locations of ``<lang>``.
+#
+# The variable ``MPI_<lang>_LIBRARIES`` will be assembled from the following variables:
+#
+# ``MPI_<lib_name>_LIBRARY``
+#   The location of a library called ``<lib_name>`` for use with MPI.
+# ``MPI_<lang>_LIB_NAMES``
+#   A :ref:`;-list <CMake Language Lists>` of ``<lib_name>`` that will be added to the include locations of ``<lang>``.
+#
+# Usage of mpiexec
+# ^^^^^^^^^^^^^^^^
+#
+# When using ``MPIEXEC_EXECUTABLE`` to execute MPI applications, you should typically
+# use all of the ``MPIEXEC_EXECUTABLE`` flags as follows:
 #
 # ::
 #
-#    ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}
+#    ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}
 #      ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS
 #
 # where ``EXECUTABLE`` is the MPI program, and ``ARGS`` are the arguments to
 # pass to the MPI program.
 #
+# Advanced variables for using MPI
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# The module can perform some advanced feature detections upon explicit request.
+#
+# **Important notice:** The following checks cannot be performed without *executing* an MPI test program.
+# Consider the special considerations for the behavior of :command:`try_run` during cross compilation.
+# Moreover, running an MPI program can cause additional issues, like a firewall notification on some systems.
+# You should only enable these detections if you absolutely need the information.
+#
+# If the following variables are set to true, the respective search will be performed:
+#
+# ``MPI_DETERMINE_Fortran_CAPABILITIES``
+#   Determine for all available Fortran bindings what the values of ``MPI_SUBARRAYS_SUPPORTED`` and
+#   ``MPI_ASYNC_PROTECTS_NONBLOCKING`` are and make their values available as ``MPI_Fortran_<binding>_SUBARRAYS``
+#   and ``MPI_Fortran_<binding>_ASYNCPROT``, where ``<binding>`` is one of ``F77_HEADER``, ``F90_MODULE`` and
+#   ``F08_MODULE``.
+# ``MPI_DETERMINE_LIBRARY_VERSION``
+#   For each language, find the output of ``MPI_Get_library_version`` and make it available as ``MPI_<lang>_LIBRARY_VERSION``.
+#   This information is usually tied to the runtime component of an MPI implementation and might differ depending on ``<lang>``.
+#   Note that the return value is entirely implementation defined. This information might be used to identify
+#   the MPI vendor and for example pick the correct one of multiple third party binaries that matches the MPI vendor.
+#
 # Backward Compatibility
 # ^^^^^^^^^^^^^^^^^^^^^^
 #
@@ -92,52 +229,60 @@
 #
 # ::
 #
-#    MPI_FOUND           MPI_COMPILER        MPI_LIBRARY
-#    MPI_COMPILE_FLAGS   MPI_INCLUDE_PATH    MPI_EXTRA_LIBRARY
-#    MPI_LINK_FLAGS      MPI_LIBRARIES
+#    MPI_COMPILER        MPI_LIBRARY        MPI_EXTRA_LIBRARY
+#    MPI_COMPILE_FLAGS   MPI_INCLUDE_PATH   MPI_LINK_FLAGS
+#    MPI_LIBRARIES
 #
 # In new projects, please use the ``MPI_<lang>_XXX`` equivalents.
+# Additionally, the following variables are deprecated:
+#
+# ``MPI_<lang>_COMPILE_FLAGS``
+#   Use ``MPI_<lang>_COMPILE_OPTIONS`` and ``MPI_<lang>_COMPILE_DEFINITIONS`` instead.
+# ``MPI_<lang>_INCLUDE_PATH``
+#   For consumption use ``MPI_<lang>_INCLUDE_DIRS`` and for specifying folders use ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS`` instead.
+# ``MPIEXEC``
+#   Use ``MPIEXEC_EXECUTABLE`` instead.
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0057 NEW) # if IN_LIST
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
-#
-# This part detects MPI compilers, attempting to wade through the mess of compiler names in
-# a sensible way.
-#
-# The compilers are detected in this order:
-#
-# 1. Try to find the most generic available MPI compiler, as this is usually set up by
-#    cluster admins, e.g. if plain old mpicc is available, we'll use it and assume it's
-#    the right compiler.
-#
-# 2. If a generic mpicc is NOT found, then we attempt to find one that matches
-#    CMAKE_<lang>_COMPILER_ID. e.g. if you are using XL compilers, we'll try to find mpixlc
-#    and company, but not mpiicc. This hopefully prevents toolchain mismatches.
-#
-# If you want to force a particular MPI compiler other than what we autodetect (e.g. if you
-# want to compile regular stuff with GNU and parallel stuff with Intel), you can always set
-# your favorite MPI_<lang>_COMPILER explicitly and this stuff will be ignored.
-#
-
-# Start out with the generic MPI compiler names, as these are most commonly used.
-set(_MPI_C_COMPILER_NAMES                  mpicc    mpcc      mpicc_r mpcc_r  mpicc.bat)
-set(_MPI_CXX_COMPILER_NAMES                mpicxx   mpiCC     mpcxx   mpCC    mpic++   mpc++
-                                           mpicxx_r mpiCC_r   mpcxx_r mpCC_r  mpic++_r mpc++_r
-                                           mpicxx.bat)
-set(_MPI_Fortran_COMPILER_NAMES            mpif95   mpif95_r  mpf95   mpf95_r
+# Generic compiler names
+set(_MPI_C_GENERIC_COMPILER_NAMES          mpicc    mpcc      mpicc_r mpcc_r)
+set(_MPI_CXX_GENERIC_COMPILER_NAMES        mpicxx   mpiCC     mpcxx   mpCC    mpic++   mpc++
+                                           mpicxx_r mpiCC_r   mpcxx_r mpCC_r  mpic++_r mpc++_r)
+set(_MPI_Fortran_GENERIC_COMPILER_NAMES    mpif95   mpif95_r  mpf95   mpf95_r
                                            mpif90   mpif90_r  mpf90   mpf90_r
-                                           mpif77   mpif77_r  mpf77   mpf77_r)
+                                           mpif77   mpif77_r  mpf77   mpf77_r
+                                           mpifc)
 
 # GNU compiler names
 set(_MPI_GNU_C_COMPILER_NAMES              mpigcc mpgcc mpigcc_r mpgcc_r)
-set(_MPI_GNU_CXX_COMPILER_NAMES            mpig++ mpg++ mpig++_r mpg++_r)
+set(_MPI_GNU_CXX_COMPILER_NAMES            mpig++ mpg++ mpig++_r mpg++_r mpigxx)
 set(_MPI_GNU_Fortran_COMPILER_NAMES        mpigfortran mpgfortran mpigfortran_r mpgfortran_r
                                            mpig77 mpig77_r mpg77 mpg77_r)
 
-# Intel MPI compiler names
-set(_MPI_Intel_C_COMPILER_NAMES            mpiicc   mpiicc.bat)
-set(_MPI_Intel_CXX_COMPILER_NAMES          mpiicpc  mpiicxx mpiic++ mpiiCC  mpiicpc.bat)
-set(_MPI_Intel_Fortran_COMPILER_NAMES      mpiifort mpiif95 mpiif90 mpiif77 mpiifort.bat)
+# Intel MPI compiler names on Windows
+if(WIN32)
+  list(APPEND _MPI_C_GENERIC_COMPILER_NAMES       mpicc.bat)
+  list(APPEND _MPI_CXX_GENERIC_COMPILER_NAMES     mpicxx.bat)
+  list(APPEND _MPI_Fortran_GENERIC_COMPILER_NAMES mpifc.bat)
+
+  # Intel MPI compiler names
+  set(_MPI_Intel_C_COMPILER_NAMES            mpiicc.bat)
+  set(_MPI_Intel_CXX_COMPILER_NAMES          mpiicpc.bat)
+  set(_MPI_Intel_Fortran_COMPILER_NAMES      mpiifort.bat mpif77.bat mpif90.bat)
+
+  # Intel MPI compiler names for MSMPI
+  set(_MPI_MSVC_C_COMPILER_NAMES             mpicl.bat)
+  set(_MPI_MSVC_CXX_COMPILER_NAMES           mpicl.bat)
+else()
+  # Intel compiler names
+  set(_MPI_Intel_C_COMPILER_NAMES            mpiicc)
+  set(_MPI_Intel_CXX_COMPILER_NAMES          mpiicpc  mpiicxx mpiic++)
+  set(_MPI_Intel_Fortran_COMPILER_NAMES      mpiifort mpiif95 mpiif90 mpiif77)
+endif()
 
 # PGI compiler names
 set(_MPI_PGI_C_COMPILER_NAMES              mpipgcc mppgcc)
@@ -153,411 +298,743 @@
                                            mpixlf77   mpixlf77_r mpxlf77 mpxlf77_r
                                            mpixlf     mpixlf_r   mpxlf   mpxlf_r)
 
-# append vendor-specific compilers to the list if we either don't know the compiler id,
-# or if we know it matches the regular compiler.
-foreach (lang C CXX Fortran)
-  foreach (id GNU Intel PGI XL)
-    if (NOT CMAKE_${lang}_COMPILER_ID OR CMAKE_${lang}_COMPILER_ID STREQUAL id)
-      list(APPEND _MPI_${lang}_COMPILER_NAMES ${_MPI_${id}_${lang}_COMPILER_NAMES})
+# Prepend vendor-specific compiler wrappers to the list. If we don't know the compiler,
+# attempt all of them.
+# By attempting vendor-specific compiler names first, we should avoid situations where the compiler wrapper
+# stems from a proprietary MPI and won't know which compiler it's being used for. For instance, Intel MPI
+# controls its settings via the I_MPI_CC environment variables if the generic name is being used.
+# If we know which compiler we're working with, we can use the most specialized wrapper there is in order to
+# pick up the right settings for it.
+foreach (LANG IN ITEMS C CXX Fortran)
+  set(_MPI_${LANG}_COMPILER_NAMES "")
+  foreach (id IN ITEMS GNU Intel MSVC PGI XL)
+    if (NOT CMAKE_${LANG}_COMPILER_ID OR CMAKE_${LANG}_COMPILER_ID STREQUAL id)
+      list(APPEND _MPI_${LANG}_COMPILER_NAMES ${_MPI_${id}_${LANG}_COMPILER_NAMES}${MPI_EXECUTABLE_SUFFIX})
     endif()
-    unset(_MPI_${id}_${lang}_COMPILER_NAMES)    # clean up the namespace here
+    unset(_MPI_${id}_${LANG}_COMPILER_NAMES)
   endforeach()
+  list(APPEND _MPI_${LANG}_COMPILER_NAMES ${_MPI_${LANG}_GENERIC_COMPILER_NAMES}${MPI_EXECUTABLE_SUFFIX})
+  unset(_MPI_${LANG}_GENERIC_COMPILER_NAMES)
 endforeach()
 
+# Names to try for mpiexec
+# Only mpiexec commands are guaranteed to behave as described in the standard,
+# mpirun commands are not covered by the standard in any way whatsoever.
+# lamexec is the executable for LAM/MPI, srun is for SLURM or Open MPI with SLURM support.
+# srun -n X <executable> is however a valid command, so it behaves 'like' mpiexec.
+set(_MPIEXEC_NAMES_BASE                   mpiexec mpiexec.hydra mpiexec.mpd mpirun lamexec srun)
 
-# Names to try for MPI exec
-set(_MPI_EXEC_NAMES                        mpiexec mpirun lamexec srun)
+unset(_MPIEXEC_NAMES)
+foreach(_MPIEXEC_NAME IN LISTS _MPIEXEC_NAMES_BASE)
+  list(APPEND _MPIEXEC_NAMES "${_MPIEXEC_NAME}${MPI_EXECUTABLE_SUFFIX}")
+endforeach()
+unset(_MPIEXEC_NAMES_BASE)
 
-# Grab the path to MPI from the registry if we're on windows.
-set(_MPI_PREFIX_PATH)
-if(WIN32)
-  # MSMPI
-  file(TO_CMAKE_PATH "$ENV{MSMPI_BIN}" msmpi_bin_path) # The default path ends with a '\' and doesn't mix with ';' when appending.
-  list(APPEND _MPI_PREFIX_PATH "${msmpi_bin_path}")
-  unset(msmpi_bin_path)
-  list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]/Bin")
-  list(APPEND _MPI_PREFIX_PATH "$ENV{MSMPI_INC}/..") # The SDK is installed separately from the runtime
-  # MPICH
-  list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/..")
-  list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]")
-  list(APPEND _MPI_PREFIX_PATH "$ENV{ProgramW6432}/MPICH2/")
+function (_MPI_check_compiler LANG QUERY_FLAG OUTPUT_VARIABLE RESULT_VARIABLE)
+  if(DEFINED MPI_${LANG}_COMPILER_FLAGS)
+    separate_arguments(_MPI_COMPILER_WRAPPER_OPTIONS NATIVE_COMMAND "${MPI_${LANG}_COMPILER_FLAGS}")
+  else()
+    separate_arguments(_MPI_COMPILER_WRAPPER_OPTIONS NATIVE_COMMAND "${MPI_COMPILER_FLAGS}")
+  endif()
+  execute_process(
+    COMMAND ${MPI_${LANG}_COMPILER} ${_MPI_COMPILER_WRAPPER_OPTIONS} ${QUERY_FLAG}
+    OUTPUT_VARIABLE  WRAPPER_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE
+    ERROR_VARIABLE   WRAPPER_OUTPUT ERROR_STRIP_TRAILING_WHITESPACE
+    RESULT_VARIABLE  WRAPPER_RETURN)
+  # Some compiler wrappers will yield spurious zero return values, for example
+  # Intel MPI tolerates unknown arguments and if the MPI wrappers loads a shared
+  # library that has invalid or missing version information there would be warning
+  # messages emitted by ld.so in the compiler output. In either case, we'll treat
+  # the output as invalid.
+  if("${WRAPPER_OUTPUT}" MATCHES "undefined reference|unrecognized|need to set|no version information available")
+    set(WRAPPER_RETURN 255)
+  endif()
+  # Ensure that no error output might be passed upwards.
+  if(NOT WRAPPER_RETURN EQUAL 0)
+    unset(WRAPPER_OUTPUT)
+  endif()
+  set(${OUTPUT_VARIABLE} "${WRAPPER_OUTPUT}" PARENT_SCOPE)
+  set(${RESULT_VARIABLE} "${WRAPPER_RETURN}" PARENT_SCOPE)
+endfunction()
+
+function (_MPI_interrogate_compiler lang)
+  unset(MPI_COMPILE_CMDLINE)
+  unset(MPI_LINK_CMDLINE)
+
+  unset(MPI_COMPILE_OPTIONS_WORK)
+  unset(MPI_COMPILE_DEFINITIONS_WORK)
+  unset(MPI_INCLUDE_DIRS_WORK)
+  unset(MPI_LINK_FLAGS_WORK)
+  unset(MPI_LIB_NAMES_WORK)
+  unset(MPI_LIB_FULLPATHS_WORK)
+
+  # Check whether the -showme:compile option works. This indicates that we have either Open MPI
+  # or a newer version of LAM/MPI, and implies that -showme:link will also work.
+  # Open MPI also supports -show, but separates linker and compiler information
+  _MPI_check_compiler(${LANG} "-showme:compile" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
+  if (MPI_COMPILER_RETURN EQUAL 0)
+    _MPI_check_compiler(${LANG} "-showme:link" MPI_LINK_CMDLINE MPI_COMPILER_RETURN)
+
+    if (NOT MPI_COMPILER_RETURN EQUAL 0)
+      unset(MPI_COMPILE_CMDLINE)
+    endif()
+  endif()
+
+  # MPICH and MVAPICH offer -compile-info and -link-info.
+  # For modern versions, both do the same as -show. However, for old versions, they do differ
+  # when called for mpicxx and mpif90 and it's necessary to use them over -show in order to find the
+  # removed MPI C++ bindings.
+  if (NOT MPI_COMPILER_RETURN EQUAL 0)
+    _MPI_check_compiler(${LANG} "-compile-info" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
+
+    if (MPI_COMPILER_RETURN EQUAL 0)
+      _MPI_check_compiler(${LANG} "-link-info" MPI_LINK_CMDLINE MPI_COMPILER_RETURN)
+
+      if (NOT MPI_COMPILER_RETURN EQUAL 0)
+        unset(MPI_COMPILE_CMDLINE)
+      endif()
+    endif()
+  endif()
+
+  # MPICH, MVAPICH2 and Intel MPI just use "-show". Open MPI also offers this, but the
+  # -showme commands are more specialized.
+  if (NOT MPI_COMPILER_RETURN EQUAL 0)
+    _MPI_check_compiler(${LANG} "-show" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
+  endif()
+
+  # Older versions of LAM/MPI have "-showme". Open MPI also supports this.
+  # Unknown to MPICH, MVAPICH and Intel MPI.
+  if (NOT MPI_COMPILER_RETURN EQUAL 0)
+    _MPI_check_compiler(${LANG} "-showme" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
+  endif()
+
+  if (NOT (MPI_COMPILER_RETURN EQUAL 0) OR NOT (DEFINED MPI_COMPILE_CMDLINE))
+    # Cannot interrogate this compiler, so exit.
+    set(MPI_${LANG}_WRAPPER_FOUND FALSE PARENT_SCOPE)
+    return()
+  endif()
+  unset(MPI_COMPILER_RETURN)
+
+  # We have our command lines, but we might need to copy MPI_COMPILE_CMDLINE
+  # into MPI_LINK_CMDLINE, if we didn't find the link line.
+  if (NOT DEFINED MPI_LINK_CMDLINE)
+    set(MPI_LINK_CMDLINE "${MPI_COMPILE_CMDLINE}")
+  endif()
+
+  # At this point, we obtained some output from a compiler wrapper that works.
+  # We'll now try to parse it into variables with meaning to us.
+  if("${LANG}" STREQUAL "Fortran")
+    # Some MPICH-1 and MVAPICH-1 versions return a three command answer for Fortran, consisting
+    # out of a symlink command for mpif.h, the actual compiler command and a deletion of the
+    # created symlink. We need to detect that case, remember the include path and drop the
+    # symlink/deletion operation to obtain the link/compile lines we'd usually expect.
+    if("${MPI_COMPILE_CMDLINE}" MATCHES "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h")
+      get_filename_component(MPI_INCLUDE_DIRS_WORK "${CMAKE_MATCH_1}" DIRECTORY)
+      string(REGEX REPLACE "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h\n" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}")
+      string(REGEX REPLACE "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h\n" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}")
+      string(REGEX REPLACE "\nrm -f mpif.h$" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}")
+      string(REGEX REPLACE "\nrm -f mpif.h$" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}")
+    endif()
+  endif()
+
+  # The Intel MPI wrapper on Linux will emit some objcopy commands after its compile command
+  # if -static_mpi was passed to the wrapper. To avoid spurious matches, we need to drop these lines.
+  if(UNIX)
+    string(REGEX REPLACE "(^|\n)objcopy[^\n]+(\n|$)" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}")
+    string(REGEX REPLACE "(^|\n)objcopy[^\n]+(\n|$)" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}")
+  endif()
+
+  # Extract compile options from the compile command line.
+  string(REGEX MATCHALL "(^| )-f([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_OPTIONS "${MPI_COMPILE_CMDLINE}")
+
+  foreach(_MPI_COMPILE_OPTION IN LISTS MPI_ALL_COMPILE_OPTIONS)
+    string(REGEX REPLACE "^ " "" _MPI_COMPILE_OPTION "${_MPI_COMPILE_OPTION}")
+    # Ignore -fstack-protector directives: These occur on MPICH and MVAPICH when the libraries
+    # themselves were built with this flag. However, this flag is unrelated to using MPI, and
+    # we won't match the accompanying --param-ssp-size and -Wp,-D_FORTIFY_SOURCE flags and therefore
+    # produce inconsistent results with the regularly flags.
+    # Similarly, aliasing flags do not belong into our flag array.
+    if(NOT "${_MPI_COMPILE_OPTION}" MATCHES "^-f(stack-protector|(no-|)strict-aliasing|PI[CE]|pi[ce])")
+      list(APPEND MPI_COMPILE_OPTIONS_WORK "${_MPI_COMPILE_OPTION}")
+    endif()
+  endforeach()
+
+  # Same deal, with the definitions. We also treat arguments passed to the preprocessor directly.
+  string(REGEX MATCHALL "(^| )(-Wp,|-Xpreprocessor |)[-/]D([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_DEFINITIONS "${MPI_COMPILE_CMDLINE}")
+
+  foreach(_MPI_COMPILE_DEFINITION IN LISTS MPI_ALL_COMPILE_DEFINITIONS)
+    string(REGEX REPLACE "^ ?(-Wp,|-Xpreprocessor )?[-/]D" "" _MPI_COMPILE_DEFINITION "${_MPI_COMPILE_DEFINITION}")
+    string(REPLACE "\"" "" _MPI_COMPILE_DEFINITION "${_MPI_COMPILE_DEFINITION}")
+    if(NOT "${_MPI_COMPILE_DEFINITION}" MATCHES "^_FORTIFY_SOURCE.*")
+      list(APPEND MPI_COMPILE_DEFINITIONS_WORK "${_MPI_COMPILE_DEFINITION}")
+    endif()
+  endforeach()
+
+  # Extract include paths from compile command line
+  string(REGEX MATCHALL "(^| )[-/]I([^\" ]+|\"[^\"]+\")" MPI_ALL_INCLUDE_PATHS "${MPI_COMPILE_CMDLINE}")
+
+  # If extracting failed to work, we'll try using -showme:incdirs.
+  if (NOT MPI_ALL_INCLUDE_PATHS)
+    _MPI_check_compiler(${LANG} "-showme:incdirs" MPI_INCDIRS_CMDLINE MPI_INCDIRS_COMPILER_RETURN)
+    if(MPI_INCDIRS_COMPILER_RETURN)
+      separate_arguments(MPI_ALL_INCLUDE_PATHS NATIVE_COMMAND "${MPI_INCDIRS_CMDLINE}")
+    endif()
+  endif()
+
+  foreach(_MPI_INCLUDE_PATH IN LISTS MPI_ALL_INCLUDE_PATHS)
+    string(REGEX REPLACE "^ ?[-/]I" "" _MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}")
+    string(REPLACE "\"" "" _MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}")
+    get_filename_component(_MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}" REALPATH)
+    list(APPEND MPI_INCLUDE_DIRS_WORK "${_MPI_INCLUDE_PATH}")
+  endforeach()
+
+  # Extract linker paths from the link command line
+  string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker |)(-L|[/-]LIBPATH:|[/-]libpath:)([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_PATHS "${MPI_LINK_CMDLINE}")
+
+  # If extracting failed to work, we'll try using -showme:libdirs.
+  if (NOT MPI_ALL_LINK_PATHS)
+    _MPI_check_compiler(${LANG} "-showme:libdirs" MPI_LIBDIRS_CMDLINE MPI_LIBDIRS_COMPILER_RETURN)
+    if(MPI_LIBDIRS_COMPILER_RETURN)
+      separate_arguments(MPI_ALL_LINK_PATHS NATIVE_COMMAND "${MPI_LIBDIRS_CMDLINE}")
+    endif()
+  endif()
+
+  foreach(_MPI_LPATH IN LISTS MPI_ALL_LINK_PATHS)
+    string(REGEX REPLACE "^ ?(-Wl,|-Xlinker )?(-L|[/-]LIBPATH:|[/-]libpath:)" "" _MPI_LPATH "${_MPI_LPATH}")
+    string(REPLACE "\"" "" _MPI_LPATH "${_MPI_LPATH}")
+    get_filename_component(_MPI_LPATH "${_MPI_LPATH}" REALPATH)
+    list(APPEND MPI_LINK_DIRECTORIES_WORK "${_MPI_LPATH}")
+  endforeach()
+
+  # Extract linker flags from the link command line
+  string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker )([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}")
+
+  foreach(_MPI_LINK_FLAG IN LISTS MPI_ALL_LINK_FLAGS)
+    string(STRIP "${_MPI_LINK_FLAG}" _MPI_LINK_FLAG)
+    # MPI might be marked to build with non-executable stacks but this should not propagate.
+    if (NOT "${_MPI_LINK_FLAG}" MATCHES "(-Wl,|-Xlinker )-z,noexecstack")
+      if (MPI_LINK_FLAGS_WORK)
+        string(APPEND MPI_LINK_FLAGS_WORK " ${_MPI_LINK_FLAG}")
+      else()
+        set(MPI_LINK_FLAGS_WORK "${_MPI_LINK_FLAG}")
+      endif()
+    endif()
+  endforeach()
+
+  # Extract the set of libraries to link against from the link command
+  # line
+  string(REGEX MATCHALL "(^| )-l([^\" ]+|\"[^\"]+\")" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
+
+  foreach(_MPI_LIB_NAME IN LISTS MPI_LIBNAMES)
+    string(REGEX REPLACE "^ ?-l" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
+    string(REPLACE "\"" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
+    get_filename_component(_MPI_LIB_PATH "${_MPI_LIB_NAME}" DIRECTORY)
+    if(NOT "${_MPI_LIB_PATH}" STREQUAL "")
+      list(APPEND MPI_LIB_FULLPATHS_WORK "${_MPI_LIB_NAME}")
+    else()
+      list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}")
+    endif()
+  endforeach()
+
+  if(WIN32)
+    # A compiler wrapper on Windows will just have the name of the
+    # library to link on its link line, potentially with a full path
+    string(REGEX MATCHALL "(^| )([^\" ]+\\.lib|\"[^\"]+\\.lib\")" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
+    foreach(_MPI_LIB_NAME IN LISTS MPI_LIBNAMES)
+      string(REGEX REPLACE "^ " "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
+      string(REPLACE "\"" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
+      get_filename_component(_MPI_LIB_PATH "${_MPI_LIB_NAME}" DIRECTORY)
+      if(NOT "${_MPI_LIB_PATH}" STREQUAL "")
+        list(APPEND MPI_LIB_FULLPATHS_WORK "${_MPI_LIB_NAME}")
+      else()
+        list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}")
+      endif()
+    endforeach()
+  else()
+    # On UNIX platforms, archive libraries can be given with full path.
+    string(REGEX MATCHALL "(^| )([^\" ]+\\.a|\"[^\"]+\\.a\")" MPI_LIBFULLPATHS "${MPI_LINK_CMDLINE}")
+    foreach(_MPI_LIB_NAME IN LISTS MPI_LIBFULLPATHS)
+      string(REGEX REPLACE "^ " "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
+      string(REPLACE "\"" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
+      get_filename_component(_MPI_LIB_PATH "${_MPI_LIB_NAME}" DIRECTORY)
+      if(NOT "${_MPI_LIB_PATH}" STREQUAL "")
+        list(APPEND MPI_LIB_FULLPATHS_WORK "${_MPI_LIB_NAME}")
+      else()
+        list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}")
+      endif()
+    endforeach()
+  endif()
+
+  # An MPI compiler wrapper could have its MPI libraries in the implictly
+  # linked directories of the compiler itself.
+  if(DEFINED CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES)
+    list(APPEND MPI_LINK_DIRECTORIES_WORK "${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}")
+  endif()
+
+  # Determine full path names for all of the libraries that one needs
+  # to link against in an MPI program
+  unset(MPI_PLAIN_LIB_NAMES_WORK)
+  foreach(_MPI_LIB_NAME IN LISTS MPI_LIB_NAMES_WORK)
+    get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB_NAME}" NAME_WE)
+    list(APPEND MPI_PLAIN_LIB_NAMES_WORK "${_MPI_PLAIN_LIB_NAME}")
+    find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY
+      NAMES "${_MPI_LIB_NAME}" "lib${_MPI_LIB_NAME}"
+      HINTS ${MPI_LINK_DIRECTORIES_WORK}
+      DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI"
+    )
+    mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
+  endforeach()
+
+  # Deal with the libraries given with full path next
+  unset(MPI_DIRECT_LIB_NAMES_WORK)
+  foreach(_MPI_LIB_FULLPATH IN LISTS MPI_LIB_FULLPATHS_WORK)
+    get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB_FULLPATH}" NAME_WE)
+    get_filename_component(_MPI_LIB_NAME "${_MPI_LIB_FULLPATH}" NAME)
+    get_filename_component(_MPI_LIB_PATH "${_MPI_LIB_FULLPATH}" DIRECTORY)
+    list(APPEND MPI_DIRECT_LIB_NAMES_WORK "${_MPI_PLAIN_LIB_NAME}")
+    find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY
+      NAMES "${_MPI_LIB_NAME}"
+      HINTS ${_MPI_LIB_PATH}
+      DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI"
+    )
+    mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
+  endforeach()
+  if(MPI_DIRECT_LIB_NAMES_WORK)
+    set(MPI_PLAIN_LIB_NAMES_WORK "${MPI_DIRECT_LIB_NAMES_WORK};${MPI_PLAIN_LIB_NAMES_WORK}")
+  endif()
+
+  # MPI might require pthread to work. The above mechanism wouldn't detect it, but we need to
+  # link it in that case. -lpthread is covered by the normal library treatment on the other hand.
+  if("${MPI_COMPILE_CMDLINE}" MATCHES "-pthread")
+    list(APPEND MPI_COMPILE_OPTIONS_WORK "-pthread")
+    if(MPI_LINK_FLAGS_WORK)
+      string(APPEND MPI_LINK_FLAGS_WORK " -pthread")
+    else()
+      set(MPI_LINK_FLAGS_WORK "-pthread")
+    endif()
+  endif()
+
+  # If we found MPI, set up all of the appropriate cache entries
+  if(NOT MPI_${LANG}_COMPILE_OPTIONS)
+    set(MPI_${LANG}_COMPILE_OPTIONS          ${MPI_COMPILE_OPTIONS_WORK}     CACHE STRING "MPI ${LANG} compilation options"            FORCE)
+  endif()
+  if(NOT MPI_${LANG}_COMPILE_DEFINITIONS)
+    set(MPI_${LANG}_COMPILE_DEFINITIONS      ${MPI_COMPILE_DEFINITIONS_WORK} CACHE STRING "MPI ${LANG} compilation definitions"        FORCE)
+  endif()
+  if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
+    set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS  ${MPI_INCLUDE_DIRS_WORK}        CACHE STRING "MPI ${LANG} additional include directories" FORCE)
+  endif()
+  if(NOT MPI_${LANG}_LINK_FLAGS)
+    set(MPI_${LANG}_LINK_FLAGS               ${MPI_LINK_FLAGS_WORK}          CACHE STRING "MPI ${LANG} linker flags"                   FORCE)
+  endif()
+  if(NOT MPI_${LANG}_LIB_NAMES)
+    set(MPI_${LANG}_LIB_NAMES                ${MPI_PLAIN_LIB_NAMES_WORK}     CACHE STRING "MPI ${LANG} libraries to link against"      FORCE)
+  endif()
+  set(MPI_${LANG}_WRAPPER_FOUND TRUE PARENT_SCOPE)
+endfunction()
+
+function(_MPI_guess_settings LANG)
+  set(MPI_GUESS_FOUND FALSE)
+  # Currently only MSMPI and MPICH2 on Windows are supported, so we can skip this search if we're not targeting that.
+  if(WIN32)
+    # MSMPI
+
+    # The environment variables MSMPI_INC and MSMPILIB32/64 are the only ways of locating the MSMPI_SDK,
+    # which is installed separately from the runtime. Thus it's possible to have mpiexec but not MPI headers
+    # or import libraries and vice versa.
+    if(NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MSMPI")
+      # We first attempt to locate the msmpi.lib. Should be find it, we'll assume that the MPI present is indeed
+      # Microsoft MPI.
+      if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+        set(MPI_MSMPI_LIB_PATH "$ENV{MSMPI_LIB64}")
+        set(MPI_MSMPI_INC_PATH_EXTRA "$ENV{MSMPI_INC}/x64")
+      else()
+        set(MPI_MSMPI_LIB_PATH "$ENV{MSMPI_LIB32}")
+        set(MPI_MSMPI_INC_PATH_EXTRA "$ENV{MSMPI_INC}/x86")
+      endif()
+
+      find_library(MPI_msmpi_LIBRARY
+        NAMES msmpi
+        HINTS ${MPI_MSMPI_LIB_PATH}
+        DOC "Location of the msmpi library for Microsoft MPI")
+      mark_as_advanced(MPI_msmpi_LIBRARY)
+
+      if(MPI_msmpi_LIBRARY)
+        # Next, we attempt to locate the MPI header. Note that for Fortran we know that mpif.h is a way
+        # MSMPI can be used and therefore that header has to be present.
+        if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
+          get_filename_component(MPI_MSMPI_INC_DIR "$ENV{MSMPI_INC}" REALPATH)
+          set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_MSMPI_INC_DIR}" CACHE STRING "MPI ${LANG} additional include directories" FORCE)
+          unset(MPI_MSMPI_INC_DIR)
+        endif()
+
+        # For MSMPI, one can compile the MPI module by building the mpi.f90 shipped with the MSMPI SDK,
+        # thus it might be present or provided by the user. Figuring out which is supported is done later on.
+        # The PGI Fortran compiler for instance ships a prebuilt set of modules in its own include folder.
+        # Should a user be employing PGI or have built its own set and provided it via cache variables, the
+        # splitting routine would have located the module files.
+
+        # For C and C++, we're done here (MSMPI does not ship the MPI-2 C++ bindings) - however, for Fortran
+        # we need some extra library to glue Fortran support together:
+        # MSMPI ships 2-4 Fortran libraries, each for different Fortran compiler behaviors. The library names
+        # ending with a c are using the cdecl calling convention, whereas those ending with an s are for Fortran
+        # implementations using stdcall. Therefore, the 64-bit MSMPI only ships those ending in 'c', whereas the 32-bit
+        # has both variants available.
+        # The second difference is the last but one letter, if it's an e(nd), the length of a string argument is
+        # passed by the Fortran compiler after all other arguments on the parameter list, if it's an m(ixed),
+        # it's passed immediately after the string address.
+
+        # To summarize:
+        #   - msmpifec: CHARACTER length passed after the parameter list and using cdecl calling convention
+        #   - msmpifmc: CHARACTER length passed directly after string address and using cdecl calling convention
+        #   - msmpifes: CHARACTER length passed after the parameter list and using stdcall calling convention
+        #   - msmpifms: CHARACTER length passed directly after string address and using stdcall calling convention
+        # 32-bit MSMPI ships all four libraries, 64-bit MSMPI ships only the first two.
+
+        # As is, Intel Fortran and PGI Fortran both use the 'ec' variant of the calling convention, whereas
+        # the old Compaq Visual Fortran compiler defaulted to the 'ms' version. It's possible to make Intel Fortran
+        # use the CVF calling convention using /iface:cvf, but we assume - and this is also assumed in FortranCInterface -
+        # this isn't the case. It's also possible to make CVF use the 'ec' variant, using /iface=(cref,nomixed_str_len_arg).
+
+        # Our strategy is now to locate all libraries, but enter msmpifec into the LIB_NAMES array.
+        # Should this not be adequate it's a straightforward way for a user to change the LIB_NAMES array and
+        # have his library found. Still, this should not be necessary outside of exceptional cases, as reasoned.
+        if ("${LANG}" STREQUAL "Fortran")
+          set(MPI_MSMPI_CALLINGCONVS c)
+          if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4)
+            list(APPEND MPI_MSMPI_CALLINGCONVS s)
+          endif()
+          foreach(mpistrlenpos IN ITEMS e m)
+            foreach(mpicallingconv IN LISTS MPI_MSMPI_CALLINGCONVS)
+              find_library(MPI_msmpif${mpistrlenpos}${mpicallingconv}_LIBRARY
+                NAMES msmpif${mpistrlenpos}${mpicallingconv}
+                HINTS "${MPI_MSMPI_LIB_PATH}"
+                DOC "Location of the msmpi${mpistrlenpos}${mpicallingconv} library for Microsoft MPI")
+              mark_as_advanced(MPI_msmpif${mpistrlenpos}${mpicallingconv}_LIBRARY)
+            endforeach()
+          endforeach()
+          if(NOT MPI_${LANG}_LIB_NAMES)
+            set(MPI_${LANG}_LIB_NAMES "msmpi;msmpifec" CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
+          endif()
+
+          # At this point we're *not* done. MSMPI requires an additional include file for Fortran giving the value
+          # of MPI_AINT. This file is called mpifptr.h located in the x64 and x86 subfolders, respectively.
+          find_path(MPI_mpifptr_INCLUDE_DIR
+            NAMES "mpifptr.h"
+            HINTS "${MPI_MSMPI_INC_PATH_EXTRA}"
+            DOC "Location of the mpifptr.h extra header for Microsoft MPI")
+          if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
+            set(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS "mpifptr" CACHE STRING "MPI ${LANG} additional include directory variables, given in the form MPI_<name>_INCLUDE_DIR." FORCE)
+          endif()
+          mark_as_advanced(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS MPI_mpifptr_INCLUDE_DIR)
+        else()
+          if(NOT MPI_${LANG}_LIB_NAMES)
+            set(MPI_${LANG}_LIB_NAMES "msmpi" CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
+          endif()
+        endif()
+        mark_as_advanced(MPI_${LANG}_LIB_NAMES)
+        set(MPI_GUESS_FOUND TRUE)
+      endif()
+    endif()
+
+    # At this point there's not many MPIs that we could still consider.
+    # OpenMPI 1.6.x and below supported Windows, but these ship compiler wrappers that still work.
+    # The only other relevant MPI implementation without a wrapper is MPICH2, which had Windows support in 1.4.1p1 and older.
+    if(NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MPICH2")
+      set(MPI_MPICH_PREFIX_PATHS
+        "$ENV{ProgramW6432}/MPICH2/lib"
+        "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/../lib"
+        "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]/lib"
+      )
+
+      # All of C, C++ and Fortran will need mpi.lib, so we'll look for this first
+      find_library(MPI_mpi_LIBRARY
+        NAMES mpi
+        HINTS ${MPI_MPICH_PREFIX_PATHS})
+      mark_as_advanced(MPI_mpi_LIBRARY)
+      # If we found mpi.lib, we detect the rest of MPICH2
+      if(MPI_mpi_LIBRARY)
+        set(MPI_MPICH_LIB_NAMES "mpi")
+        # If MPI-2 C++ bindings are requested, we need to locate cxx.lib as well.
+        # Otherwise, MPICH_SKIP_MPICXX will be defined and these bindings aren't needed.
+        if("${LANG}" STREQUAL "CXX" AND NOT MPI_CXX_SKIP_MPICXX)
+          find_library(MPI_cxx_LIBRARY
+            NAMES cxx
+            HINTS ${MPI_MPICH_PREFIX_PATHS})
+          mark_as_advanced(MPI_cxx_LIBRARY)
+          list(APPEND MPI_MPICH_LIB_NAMES "cxx")
+        # For Fortran, MPICH2 provides three different libraries:
+        #   fmpich2.lib which uses uppercase symbols and cdecl,
+        #   fmpich2s.lib which uses uppercase symbols and stdcall (32-bit only),
+        #   fmpich2g.lib which uses lowercase symbols with double underscores and cdecl.
+        # fmpich2s.lib would be useful for Compaq Visual Fortran, fmpich2g.lib has to be used with GNU g77 and is also
+        # provided in the form of an .a archive for MinGW and Cygwin. From our perspective, fmpich2.lib is the only one
+        # we need to try, and if it doesn't work with the given Fortran compiler we'd find out later on during validation
+        elseif("${LANG}" STREQUAL "Fortran")
+          find_library(MPI_fmpich2_LIBRARY
+            NAMES fmpich2
+            HINTS ${MPI_MPICH_PREFIX_PATHS})
+          find_library(MPI_fmpich2s_LIBRARY
+            NAMES fmpich2s
+            HINTS ${MPI_MPICH_PREFIX_PATHS})
+          find_library(MPI_fmpich2g_LIBRARY
+            NAMES fmpich2g
+            HINTS ${MPI_MPICH_PREFIX_PATHS})
+          mark_as_advanced(MPI_fmpich2_LIBRARY MPI_fmpich2s_LIBRARY MPI_fmpich2g_LIBRARY)
+          list(APPEND MPI_MPICH_LIB_NAMES "fmpich2")
+        endif()
+
+        if(NOT MPI_${LANG}_LIB_NAMES)
+          set(MPI_${LANG}_LIB_NAMES "${MPI_MPICH_LIB_NAMES}" CACHE STRING "MPI ${LANG} libraries to link against" FORCE)
+        endif()
+        unset(MPI_MPICH_LIB_NAMES)
+
+        if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
+          # For MPICH2, the include folder would be in ../include relative to the library folder.
+          get_filename_component(MPI_MPICH_ROOT_DIR "${MPI_mpi_LIBRARY}" DIRECTORY)
+          get_filename_component(MPI_MPICH_ROOT_DIR "${MPI_MPICH_ROOT_DIR}" DIRECTORY)
+          if(IS_DIRECTORY "${MPI_MPICH_ROOT_DIR}/include")
+            set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_MPICH_ROOT_DIR}/include" CACHE STRING "MPI ${LANG} additional include directory variables, given in the form MPI_<name>_INCLUDE_DIR." FORCE)
+          endif()
+          unset(MPI_MPICH_ROOT_DIR)
+        endif()
+        set(MPI_GUESS_FOUND TRUE)
+      endif()
+      unset(MPI_MPICH_PREFIX_PATHS)
+    endif()
+  endif()
+  set(MPI_${LANG}_GUESS_FOUND "${MPI_GUESS_FOUND}" PARENT_SCOPE)
+endfunction()
+
+function(_MPI_adjust_compile_definitions LANG)
+  if("${LANG}" STREQUAL "CXX")
+    # To disable the C++ bindings, we need to pass some definitions since the mpi.h header has to deal with both C and C++
+    # bindings in MPI-2.
+    if(MPI_CXX_SKIP_MPICXX AND NOT MPI_${LANG}_COMPILE_DEFINITIONS MATCHES "SKIP_MPICXX")
+      # MPICH_SKIP_MPICXX is being used in MPICH and derivatives like MVAPICH or Intel MPI
+      # OMPI_SKIP_MPICXX is being used in Open MPI
+      # _MPICC_H is being used for IBM Platform MPI
+      list(APPEND MPI_${LANG}_COMPILE_DEFINITIONS "MPICH_SKIP_MPICXX" "OMPI_SKIP_MPICXX" "_MPICC_H")
+      set(MPI_${LANG}_COMPILE_DEFINITIONS "${MPI_${LANG}_COMPILE_DEFINITIONS}" CACHE STRING "MPI ${LANG} compilation definitions" FORCE)
+    endif()
+  endif()
+endfunction()
+
+macro(_MPI_assemble_libraries LANG)
+  set(MPI_${LANG}_LIBRARIES "")
+  foreach(mpilib IN LISTS MPI_${LANG}_LIB_NAMES)
+    list(APPEND MPI_${LANG}_LIBRARIES ${MPI_${mpilib}_LIBRARY})
+  endforeach()
+endmacro()
+
+macro(_MPI_assemble_include_dirs LANG)
+  set(MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}")
+  if("${LANG}" MATCHES "(C|CXX)")
+    if(MPI_${LANG}_HEADER_DIR)
+      list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}")
+    endif()
+  else() # Fortran
+    if(MPI_${LANG}_F77_HEADER_DIR)
+      list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_F77_HEADER_DIR}")
+    endif()
+    if(MPI_${LANG}_MODULE_DIR AND NOT "${MPI_${LANG}_MODULE_DIR}" IN_LIST MPI_${LANG}_INCLUDE_DIRS)
+      list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_MODULE_DIR}")
+    endif()
+  endif()
+  if(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
+    foreach(mpiadditionalinclude IN LISTS MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
+      list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${mpiadditionalinclude}_INCLUDE_DIR}")
+    endforeach()
+  endif()
+endmacro()
+
+function(_MPI_split_include_dirs LANG)
+  # Backwards compatibility: Search INCLUDE_PATH if given.
+  if(MPI_${LANG}_INCLUDE_PATH)
+    list(APPEND MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_INCLUDE_PATH}")
+  endif()
+
+  # We try to find the headers/modules among those paths (and system paths)
+  # For C/C++, we just need to have a look for mpi.h.
+  if("${LANG}" MATCHES "(C|CXX)")
+    find_path(MPI_${LANG}_HEADER_DIR "mpi.h"
+      HINTS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
+    )
+    mark_as_advanced(MPI_${LANG}_HEADER_DIR)
+    if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
+      list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}")
+    endif()
+  # Fortran is more complicated here: An implementation could provide
+  # any of the Fortran 77/90/2008 APIs for MPI. For example, MSMPI
+  # only provides Fortran 77 and - if mpi.f90 is built - potentially
+  # a Fortran 90 module.
+  elseif("${LANG}" STREQUAL "Fortran")
+    find_path(MPI_${LANG}_F77_HEADER_DIR "mpif.h"
+      HINTS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
+    )
+    find_path(MPI_${LANG}_MODULE_DIR
+      NAMES "mpi.mod" "mpi_f08.mod"
+      HINTS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
+    )
+    if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
+      list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS
+        "${MPI_${LANG}_F77_HEADER_DIR}"
+        "${MPI_${LANG}_MODULE_DIR}"
+      )
+    endif()
+    mark_as_advanced(MPI_${LANG}_F77_HEADER_DIR MPI_${LANG}_MODULE_DIR)
+  endif()
+  set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} additional include directories" FORCE)
+endfunction()
+
+macro(_MPI_create_imported_target LANG)
+  if(NOT TARGET MPI::MPI_${LANG})
+    add_library(MPI::MPI_${LANG} INTERFACE IMPORTED)
+  endif()
+
+  set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "${MPI_${LANG}_COMPILE_OPTIONS}")
+  set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_DEFINITIONS "${MPI_${LANG}_COMPILE_DEFINITIONS}")
+
+  set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_LIBRARIES "")
+  if(MPI_${LANG}_LINK_FLAGS)
+    set_property(TARGET MPI::MPI_${LANG} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${MPI_${LANG}_LINK_FLAGS}")
+  endif()
+  # If the compiler links MPI implicitly, no libraries will be found as they're contained within
+  # CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES already.
+  if(MPI_${LANG}_LIBRARIES)
+    set_property(TARGET MPI::MPI_${LANG} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${MPI_${LANG}_LIBRARIES}")
+  endif()
+  # Given the new design of FindMPI, INCLUDE_DIRS will always be located, even under implicit linking.
+  set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${MPI_${LANG}_INCLUDE_DIRS}")
+endmacro()
+
+function(_MPI_try_staged_settings LANG MPI_TEST_FILE_NAME MODE RUN_BINARY)
+  set(WORK_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI")
+  set(SRC_DIR "${CMAKE_ROOT}/Modules/FindMPI")
+  set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI/${MPI_TEST_FILE_NAME}_${LANG}.bin")
+  unset(MPI_TEST_COMPILE_DEFINITIONS)
+  if("${LANG}" STREQUAL "Fortran")
+    if("${MODE}" STREQUAL "F90_MODULE")
+      set(MPI_Fortran_INCLUDE_LINE "use mpi\n      implicit none")
+    elseif("${MODE}" STREQUAL "F08_MODULE")
+      set(MPI_Fortran_INCLUDE_LINE "use mpi_f08\n      implicit none")
+    else() # F77 header
+      set(MPI_Fortran_INCLUDE_LINE "implicit none\n      include 'mpif.h'")
+    endif()
+    configure_file("${SRC_DIR}/${MPI_TEST_FILE_NAME}.f90.in" "${WORK_DIR}/${MPI_TEST_FILE_NAME}.f90" @ONLY)
+    set(MPI_TEST_SOURCE_FILE "${WORK_DIR}/${MPI_TEST_FILE_NAME}.f90")
+  elseif("${LANG}" STREQUAL "CXX")
+    configure_file("${SRC_DIR}/${MPI_TEST_FILE_NAME}.c" "${WORK_DIR}/${MPI_TEST_FILE_NAME}.cpp" COPYONLY)
+    set(MPI_TEST_SOURCE_FILE "${WORK_DIR}/${MPI_TEST_FILE_NAME}.cpp")
+    if("${MODE}" STREQUAL "TEST_MPICXX")
+      set(MPI_TEST_COMPILE_DEFINITIONS TEST_MPI_MPICXX)
+    endif()
+  else() # C
+    set(MPI_TEST_SOURCE_FILE "${SRC_DIR}/${MPI_TEST_FILE_NAME}.c")
+  endif()
+  if(RUN_BINARY)
+    try_run(MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
+     "${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}"
+      COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS}
+      LINK_LIBRARIES MPI::MPI_${LANG}
+      RUN_OUTPUT_VARIABLE MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE})
+    set(MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} "${MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}}" PARENT_SCOPE)
+  else()
+    try_compile(MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}
+      "${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}"
+      COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS}
+      LINK_LIBRARIES MPI::MPI_${LANG}
+      COPY_FILE "${BIN_FILE}")
+  endif()
+endfunction()
+
+macro(_MPI_check_lang_works LANG)
+  # For Fortran we may have by the MPI-3 standard an implementation that provides:
+  #   - the mpi_f08 module
+  #   - *both*, the mpi module and 'mpif.h'
+  # Since older MPI standards (MPI-1) did not define anything but 'mpif.h', we need to check all three individually.
+  if( NOT MPI_${LANG}_WORKS )
+    if("${LANG}" STREQUAL "Fortran")
+      set(MPI_Fortran_INTEGER_LINE "(kind=MPI_INTEGER_KIND)")
+      _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER FALSE)
+      _MPI_try_staged_settings(${LANG} test_mpi F90_MODULE FALSE)
+      _MPI_try_staged_settings(${LANG} test_mpi F08_MODULE FALSE)
+
+      set(MPI_${LANG}_WORKS FALSE)
+
+      foreach(mpimethod IN ITEMS F77_HEADER F08_MODULE F90_MODULE)
+        if(MPI_RESULT_${LANG}_test_mpi_${mpimethod})
+          set(MPI_${LANG}_WORKS TRUE)
+          set(MPI_${LANG}_HAVE_${mpimethod} TRUE)
+        else()
+          set(MPI_${LANG}_HAVE_${mpimethod} FALSE)
+        endif()
+      endforeach()
+      # MPI-1 versions had no MPI_INTGER_KIND defined, so we need to try without it.
+      # However, MPI-1 also did not define the Fortran 90 and 08 modules, so we only try the F77 header.
+      unset(MPI_Fortran_INTEGER_LINE)
+      if(NOT MPI_${LANG}_WORKS)
+        _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER_NOKIND FALSE)
+        if(MPI_RESULT_${LANG}_test_mpi_F77_HEADER_NOKIND)
+          set(MPI_${LANG}_WORKS TRUE)
+          set(MPI_${LANG}_HAVE_F77_HEADER TRUE)
+        endif()
+      endif()
+    else()
+      _MPI_try_staged_settings(${LANG} test_mpi normal FALSE)
+      # If 'test_mpi' built correctly, we've found valid MPI settings. There might not be MPI-2 C++ support, but there can't
+      # be MPI-2 C++ support without the C bindings being present, so checking for them is sufficient.
+      set(MPI_${LANG}_WORKS "${MPI_RESULT_${LANG}_test_mpi_normal}")
+    endif()
+  endif()
+endmacro()
+
+# Some systems install various MPI implementations in separate folders in some MPI prefix
+# This macro enumerates all such subfolders and adds them to the list of hints that will be searched.
+macro(MPI_search_mpi_prefix_folder PREFIX_FOLDER)
+  if(EXISTS "${PREFIX_FOLDER}")
+    file(GLOB _MPI_folder_children RELATIVE "${PREFIX_FOLDER}" "${PREFIX_FOLDER}/*")
+    foreach(_MPI_folder_child IN LISTS _MPI_folder_children)
+      if(IS_DIRECTORY "${PREFIX_FOLDER}/${_MPI_folder_child}")
+        list(APPEND MPI_HINT_DIRS "${PREFIX_FOLDER}/${_MPI_folder_child}")
+      endif()
+    endforeach()
+  endif()
+endmacro()
+
+set(MPI_HINT_DIRS ${MPI_HOME} $ENV{MPI_HOME} $ENV{I_MPI_ROOT})
+if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Linux")
+  # SUSE Linux Enterprise Server stores its MPI implementations under /usr/lib64/mpi/gcc/<name>
+  # We enumerate the subfolders and append each as a prefix
+  MPI_search_mpi_prefix_folder("/usr/lib64/mpi/gcc")
+elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
+  # MSMPI stores its runtime in a special folder, this adds the possible locations to the hints.
+  list(APPEND MPI_HINT_DIRS $ENV{MSMPI_BIN} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]")
+elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "FreeBSD")
+  # FreeBSD ships mpich under the normal system paths - but available openmpi implementations
+  # will be found in /usr/local/mpi/<name>
+  MPI_search_mpi_prefix_folder("/usr/local/mpi/")
 endif()
 
-# Build a list of prefixes to search for MPI.
-foreach(SystemPrefixDir ${CMAKE_SYSTEM_PREFIX_PATH})
-  foreach(MpiPackageDir ${_MPI_PREFIX_PATH})
-    if(EXISTS ${SystemPrefixDir}/${MpiPackageDir})
-      list(APPEND _MPI_PREFIX_PATH "${SystemPrefixDir}/${MpiPackageDir}")
-    endif()
-  endforeach()
-endforeach()
-
-function (_mpi_check_compiler compiler options cmdvar resvar)
-  execute_process(
-    COMMAND "${compiler}" ${options}
-    OUTPUT_VARIABLE  cmdline OUTPUT_STRIP_TRAILING_WHITESPACE
-    ERROR_VARIABLE   cmdline ERROR_STRIP_TRAILING_WHITESPACE
-    RESULT_VARIABLE  success)
-  # Intel MPI 5.0.1 will return a zero return code even when the
-  # argument to the MPI compiler wrapper is unknown.  Attempt to
-  # catch this case.
-  if(cmdline MATCHES "undefined reference" OR cmdline MATCHES "unrecognized")
-    set(success 255 )
-  endif()
-  set(${cmdvar} "${cmdline}" PARENT_SCOPE)
-  set(${resvar} "${success}" PARENT_SCOPE)
-endfunction()
-
-#
-# interrogate_mpi_compiler(lang try_libs)
-#
-# Attempts to extract compiler and linker args from an MPI compiler. The arguments set
-# by this function are:
-#
-#   MPI_<lang>_INCLUDE_PATH    MPI_<lang>_LINK_FLAGS     MPI_<lang>_FOUND
-#   MPI_<lang>_COMPILE_FLAGS   MPI_<lang>_LIBRARIES
-#
-# MPI_<lang>_COMPILER must be set beforehand to the absolute path to an MPI compiler for
-# <lang>.  Additionally, MPI_<lang>_INCLUDE_PATH and MPI_<lang>_LIBRARIES may be set
-# to skip autodetection.
-#
-# If try_libs is TRUE, this will also attempt to find plain MPI libraries in the usual
-# way.  In general, this is not as effective as interrogating the compilers, as it
-# ignores language-specific flags and libraries.  However, some MPI implementations
-# (Windows implementations) do not have compiler wrappers, so this approach must be used.
-#
-function (interrogate_mpi_compiler lang try_libs)
-  # MPI_${lang}_NO_INTERROGATE will be set to a compiler name when the *regular* compiler was
-  # discovered to be the MPI compiler.  This happens on machines like the Cray XE6 that use
-  # modules to set cc, CC, and ftn to the MPI compilers.  If the user force-sets another MPI
-  # compiler, MPI_${lang}_COMPILER won't be equal to MPI_${lang}_NO_INTERROGATE, and we'll
-  # inspect that compiler anew.  This allows users to set new compilers w/o rm'ing cache.
-  string(COMPARE NOTEQUAL "${MPI_${lang}_NO_INTERROGATE}" "${MPI_${lang}_COMPILER}" interrogate)
-
-  # If MPI is set already in the cache, don't bother with interrogating the compiler.
-  if (interrogate AND ((NOT MPI_${lang}_INCLUDE_PATH) OR (NOT MPI_${lang}_LIBRARIES)))
-    if (MPI_${lang}_COMPILER)
-      # Check whether the -showme:compile option works. This indicates that we have either OpenMPI
-      # or a newer version of LAM-MPI, and implies that -showme:link will also work.
-      _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme:compile" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
-      if (MPI_COMPILER_RETURN EQUAL 0)
-        # If we appear to have -showme:compile, then we should
-        # also have -showme:link. Try it.
-        execute_process(
-          COMMAND ${MPI_${lang}_COMPILER} -showme:link
-          OUTPUT_VARIABLE  MPI_LINK_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
-          ERROR_VARIABLE   MPI_LINK_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
-          RESULT_VARIABLE  MPI_COMPILER_RETURN)
-
-        if (MPI_COMPILER_RETURN EQUAL 0)
-          # We probably have -showme:incdirs and -showme:libdirs as well,
-          # so grab that while we're at it.
-          execute_process(
-            COMMAND ${MPI_${lang}_COMPILER} -showme:incdirs
-            OUTPUT_VARIABLE  MPI_INCDIRS OUTPUT_STRIP_TRAILING_WHITESPACE
-            ERROR_VARIABLE   MPI_INCDIRS ERROR_STRIP_TRAILING_WHITESPACE)
-
-          execute_process(
-            COMMAND ${MPI_${lang}_COMPILER} -showme:libdirs
-            OUTPUT_VARIABLE  MPI_LIBDIRS OUTPUT_STRIP_TRAILING_WHITESPACE
-            ERROR_VARIABLE   MPI_LIBDIRS ERROR_STRIP_TRAILING_WHITESPACE)
-
-        else()
-          # reset things here if something went wrong.
-          set(MPI_COMPILE_CMDLINE)
-          set(MPI_LINK_CMDLINE)
-        endif()
-      endif ()
-
-      # Older versions of LAM-MPI have "-showme". Try to find that.
-      if (NOT MPI_COMPILER_RETURN EQUAL 0)
-        _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
-      endif()
-
-      # MVAPICH uses -compile-info and -link-info.  Try them.
-      if (NOT MPI_COMPILER_RETURN EQUAL 0)
-        _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-compile-info" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
-
-        # If we have compile-info, also have link-info.
-        if (MPI_COMPILER_RETURN EQUAL 0)
-          execute_process(
-            COMMAND ${MPI_${lang}_COMPILER} -link-info
-            OUTPUT_VARIABLE  MPI_LINK_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
-            ERROR_VARIABLE   MPI_LINK_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
-            RESULT_VARIABLE  MPI_COMPILER_RETURN)
-        endif()
-
-        # make sure we got compile and link.  Reset vars if something's wrong.
-        if (NOT MPI_COMPILER_RETURN EQUAL 0)
-          set(MPI_COMPILE_CMDLINE)
-          set(MPI_LINK_CMDLINE)
-        endif()
-      endif()
-
-      # MPICH just uses "-show". Try it.
-      if (NOT MPI_COMPILER_RETURN EQUAL 0)
-        _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-show" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
-      endif()
-
-      if (MPI_COMPILER_RETURN EQUAL 0)
-        # We have our command lines, but we might need to copy MPI_COMPILE_CMDLINE
-        # into MPI_LINK_CMDLINE, if we didn't find the link line.
-        if (NOT MPI_LINK_CMDLINE)
-          set(MPI_LINK_CMDLINE ${MPI_COMPILE_CMDLINE})
-        endif()
-      else()
-        message(STATUS "Unable to determine MPI from MPI driver ${MPI_${lang}_COMPILER}")
-        set(MPI_COMPILE_CMDLINE)
-        set(MPI_LINK_CMDLINE)
-      endif()
-
-      # Here, we're done with the interrogation part, and we'll try to extract args we care
-      # about from what we learned from the compiler wrapper scripts.
-
-      # If interrogation came back with something, extract our variable from the MPI command line
-      if (MPI_COMPILE_CMDLINE OR MPI_LINK_CMDLINE)
-        # Extract compile flags from the compile command line.
-        string(REGEX MATCHALL "(^| )-[Df]([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_FLAGS "${MPI_COMPILE_CMDLINE}")
-        set(MPI_COMPILE_FLAGS_WORK)
-
-        foreach(FLAG ${MPI_ALL_COMPILE_FLAGS})
-          string(REGEX REPLACE "^ " "" FLAG ${FLAG})
-          if (MPI_COMPILE_FLAGS_WORK)
-            string(APPEND MPI_COMPILE_FLAGS_WORK " ${FLAG}")
-          else()
-            set(MPI_COMPILE_FLAGS_WORK ${FLAG})
-          endif()
-        endforeach()
-
-        # Extract include paths from compile command line
-        string(REGEX MATCHALL "(^| )-I([^\" ]+|\"[^\"]+\")" MPI_ALL_INCLUDE_PATHS "${MPI_COMPILE_CMDLINE}")
-        set(MPI_INCLUDE_PATH_WORK)
-
-        foreach(IPATH ${MPI_ALL_INCLUDE_PATHS})
-          string(REGEX REPLACE "^ ?-I" "" IPATH ${IPATH})
-          string(REPLACE "//" "/" IPATH ${IPATH})
-          string(REPLACE "\"" "" IPATH ${IPATH})
-          file(TO_CMAKE_PATH "${IPATH}" IPATH)
-          list(APPEND MPI_INCLUDE_PATH_WORK ${IPATH})
-        endforeach()
-
-        # try using showme:incdirs if extracting didn't work.
-        if (NOT MPI_INCLUDE_PATH_WORK)
-          set(MPI_INCLUDE_PATH_WORK ${MPI_INCDIRS})
-          separate_arguments(MPI_INCLUDE_PATH_WORK)
-        endif()
-
-        # If all else fails, just search for mpi.h in the normal include paths.
-        if (NOT MPI_INCLUDE_PATH_WORK)
-          set(MPI_HEADER_PATH "MPI_HEADER_PATH-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
-          find_path(MPI_HEADER_PATH mpi.h
-            HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
-            PATH_SUFFIXES include)
-          set(MPI_INCLUDE_PATH_WORK ${MPI_HEADER_PATH})
-        endif()
-
-        # Extract linker paths from the link command line
-        string(REGEX MATCHALL "(^| |-Wl,)(-L|/LIBPATH:)([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_PATHS "${MPI_LINK_CMDLINE}")
-        set(MPI_LINK_PATH)
-        foreach(LPATH ${MPI_ALL_LINK_PATHS})
-          string(REGEX REPLACE "^(| |-Wl,)(-L|/LIBPATH:)" "" LPATH ${LPATH})
-          string(REPLACE "//" "/" LPATH ${LPATH})
-          list(APPEND MPI_LINK_PATH ${LPATH})
-        endforeach()
-
-        # try using showme:libdirs if extracting didn't work.
-        if (NOT MPI_LINK_PATH)
-          set(MPI_LINK_PATH ${MPI_LIBDIRS})
-          separate_arguments(MPI_LINK_PATH)
-        endif()
-
-        # Extract linker flags from the link command line
-        string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker )([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}")
-        set(MPI_LINK_FLAGS_WORK)
-        foreach(FLAG ${MPI_ALL_LINK_FLAGS})
-          string(REGEX REPLACE "^ " "" FLAG ${FLAG})
-          if (MPI_LINK_FLAGS_WORK)
-            string(APPEND MPI_LINK_FLAGS_WORK " ${FLAG}")
-          else()
-            set(MPI_LINK_FLAGS_WORK ${FLAG})
-          endif()
-        endforeach()
-
-        # Extract the set of libraries to link against from the link command
-        # line
-        string(REGEX MATCHALL "(^| )-l([^\" ]+|\"[^\"]+\")" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
-        if(WIN32)
-          # The intel wrappers on windows link against static versions of the MPI libraries.
-          # The static libraries are simply listed on the command line without -l.
-          # For instance: " icl ... impi.lib "
-          string(REGEX MATCHALL "(^| )([^\" ]+)\\.lib" tmp "${MPI_LINK_CMDLINE}")
-          list(APPEND MPI_LIBNAMES ${tmp})
-        endif()
-
-        # add the compiler implicit directories because some compilers
-        # such as the intel compiler have libraries that show up
-        # in the showme list that can only be found in the implicit
-        # link directories of the compiler.
-        if (DEFINED CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES)
-          string(APPEND MPI_LINK_PATH
-            ";${CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES}")
-        endif ()
-
-        # Determine full path names for all of the libraries that one needs
-        # to link against in an MPI program
-        foreach(LIB ${MPI_LIBNAMES})
-          string(REGEX REPLACE "^ ?-l" "" LIB ${LIB})
-          if(WIN32)
-            string(REGEX REPLACE "\\.lib$" "" LIB ${LIB})
-          endif()
-          string(STRIP ${LIB} LIB)
-          # MPI_LIB is cached by find_library, but we don't want that.  Clear it first.
-          set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
-          find_library(MPI_LIB NAMES ${LIB} HINTS ${MPI_LINK_PATH})
-
-          if (MPI_LIB)
-            list(APPEND MPI_LIBRARIES_WORK ${MPI_LIB})
-          elseif (NOT MPI_FIND_QUIETLY)
-            message(WARNING "Unable to find MPI library ${LIB}")
-          endif()
-        endforeach()
-
-        # Sanity check MPI_LIBRARIES to make sure there are enough libraries
-        list(LENGTH MPI_LIBRARIES_WORK MPI_NUMLIBS)
-        list(LENGTH MPI_LIBNAMES MPI_NUMLIBS_EXPECTED)
-        if (NOT MPI_NUMLIBS EQUAL MPI_NUMLIBS_EXPECTED)
-          set(MPI_LIBRARIES_WORK "MPI_${lang}_LIBRARIES-NOTFOUND")
-        endif()
-      endif()
-
-    elseif(try_libs)
-      # If we didn't have an MPI compiler script to interrogate, attempt to find everything
-      # with plain old find functions.  This is nasty because MPI implementations have LOTS of
-      # different library names, so this section isn't going to be very generic.  We need to
-      # make sure it works for MS MPI, though, since there are no compiler wrappers for that.
-      find_path(MPI_HEADER_PATH mpi.h
-        HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
-        PATH_SUFFIXES include Inc)
-      set(MPI_INCLUDE_PATH_WORK ${MPI_HEADER_PATH})
-
-      # Decide between 32-bit and 64-bit libraries for Microsoft's MPI
-      if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
-        set(MS_MPI_ARCH_DIR x64)
-        set(MS_MPI_ARCH_DIR2 amd64)
-      else()
-        set(MS_MPI_ARCH_DIR x86)
-        set(MS_MPI_ARCH_DIR2 i386)
-      endif()
-
-      set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
-      find_library(MPI_LIB
-        NAMES         mpi mpich mpich2 msmpi
-        HINTS         ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
-        PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR} Lib/${MS_MPI_ARCH_DIR2})
-      set(MPI_LIBRARIES_WORK ${MPI_LIB})
-
-      # Right now, we only know about the extra libs for C++.
-      # We could add Fortran here (as there is usually libfmpich, etc.), but
-      # this really only has to work with MS MPI on Windows.
-      # Assume that other MPI's are covered by the compiler wrappers.
-      if (${lang} STREQUAL CXX)
-        set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
-        find_library(MPI_LIB
-          NAMES         mpi++ mpicxx cxx mpi_cxx
-          HINTS         ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
-          PATH_SUFFIXES lib)
-        if (MPI_LIBRARIES_WORK AND MPI_LIB)
-          list(APPEND MPI_LIBRARIES_WORK ${MPI_LIB})
-        endif()
-      endif()
-
-      if (NOT MPI_LIBRARIES_WORK)
-        set(MPI_LIBRARIES_WORK "MPI_${lang}_LIBRARIES-NOTFOUND")
-      endif()
-    endif()
-
-    # If we found MPI, set up all of the appropriate cache entries
-    set(MPI_${lang}_COMPILE_FLAGS ${MPI_COMPILE_FLAGS_WORK} CACHE STRING "MPI ${lang} compilation flags"         FORCE)
-    set(MPI_${lang}_INCLUDE_PATH  ${MPI_INCLUDE_PATH_WORK}  CACHE STRING "MPI ${lang} include path"              FORCE)
-    set(MPI_${lang}_LINK_FLAGS    ${MPI_LINK_FLAGS_WORK}    CACHE STRING "MPI ${lang} linking flags"             FORCE)
-    set(MPI_${lang}_LIBRARIES     ${MPI_LIBRARIES_WORK}     CACHE STRING "MPI ${lang} libraries to link against" FORCE)
-    mark_as_advanced(MPI_${lang}_COMPILE_FLAGS MPI_${lang}_INCLUDE_PATH MPI_${lang}_LINK_FLAGS MPI_${lang}_LIBRARIES)
-
-    # clear out our temporary lib/header detection variable here.
-    set(MPI_LIB         "MPI_LIB-NOTFOUND"         CACHE INTERNAL "Scratch variable for MPI lib detection"    FORCE)
-    set(MPI_HEADER_PATH "MPI_HEADER_PATH-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI header detection" FORCE)
-  endif()
-
-  # finally set a found variable for each MPI language
-  if (MPI_${lang}_INCLUDE_PATH AND MPI_${lang}_LIBRARIES)
-    set(MPI_${lang}_FOUND TRUE PARENT_SCOPE)
-  else()
-    set(MPI_${lang}_FOUND FALSE PARENT_SCOPE)
-  endif()
-endfunction()
-
-
-# This function attempts to compile with the regular compiler, to see if MPI programs
-# work with it.  This is a last ditch attempt after we've tried interrogating mpicc and
-# friends, and after we've tried to find generic libraries.  Works on machines like
-# Cray XE6, where the modules environment changes what MPI version cc, CC, and ftn use.
-function(try_regular_compiler lang success)
-  set(scratch_directory ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
-  if (${lang} STREQUAL Fortran)
-    set(test_file ${scratch_directory}/cmake_mpi_test.f90)
-    file(WRITE ${test_file}
-      "program hello\n"
-      "include 'mpif.h'\n"
-      "integer ierror\n"
-      "call MPI_INIT(ierror)\n"
-      "call MPI_FINALIZE(ierror)\n"
-      "end\n")
-  else()
-    if (${lang} STREQUAL CXX)
-      set(test_file ${scratch_directory}/cmake_mpi_test.cpp)
-    else()
-      set(test_file ${scratch_directory}/cmake_mpi_test.c)
-    endif()
-    file(WRITE ${test_file}
-      "#include <mpi.h>\n"
-      "int main(int argc, char **argv) {\n"
-      "  MPI_Init(&argc, &argv);\n"
-      "  MPI_Finalize();\n"
-      "}\n")
-  endif()
-  try_compile(compiler_has_mpi ${scratch_directory} ${test_file})
-  if (compiler_has_mpi)
-    set(MPI_${lang}_NO_INTERROGATE ${CMAKE_${lang}_COMPILER} CACHE STRING "Whether to interrogate MPI ${lang} compiler" FORCE)
-    set(MPI_${lang}_COMPILER       ${CMAKE_${lang}_COMPILER} CACHE STRING "MPI ${lang} compiler"                        FORCE)
-    set(MPI_${lang}_COMPILE_FLAGS  ""                        CACHE STRING "MPI ${lang} compilation flags"               FORCE)
-    set(MPI_${lang}_INCLUDE_PATH   ""                        CACHE STRING "MPI ${lang} include path"                    FORCE)
-    set(MPI_${lang}_LINK_FLAGS     ""                        CACHE STRING "MPI ${lang} linking flags"                   FORCE)
-    set(MPI_${lang}_LIBRARIES      ""                        CACHE STRING "MPI ${lang} libraries to link against"       FORCE)
-  endif()
-  set(${success} ${compiler_has_mpi} PARENT_SCOPE)
-  unset(compiler_has_mpi CACHE)
-endfunction()
-
-# End definitions, commence real work here.
-
-# Most mpi distros have some form of mpiexec which gives us something we can reliably look for.
-find_program(MPIEXEC
-  NAMES ${_MPI_EXEC_NAMES}
-  HINTS ${MPI_HOME} $ENV{MPI_HOME}
-  PATHS ${_MPI_PREFIX_PATH}
-  PATH_SUFFIXES bin
+# Most MPI distributions have some form of mpiexec or mpirun which gives us something we can look for.
+# The MPI standard does not mandate the existence of either, but instead only makes requirements if a distribution
+# ships an mpiexec program (mpirun executables are not regulated by the standard).
+find_program(MPIEXEC_EXECUTABLE
+  NAMES ${_MPIEXEC_NAMES}
+  PATH_SUFFIXES bin sbin
+  HINTS ${MPI_HINT_DIRS}
   DOC "Executable for running MPI programs.")
 
 # call get_filename_component twice to remove mpiexec and the directory it exists in (typically bin).
 # This gives us a fairly reliable base directory to search for /bin /lib and /include from.
-get_filename_component(_MPI_BASE_DIR "${MPIEXEC}" PATH)
+get_filename_component(_MPI_BASE_DIR "${MPIEXEC_EXECUTABLE}" PATH)
 get_filename_component(_MPI_BASE_DIR "${_MPI_BASE_DIR}" PATH)
 
 # According to the MPI standard, section 8.8 -n is a guaranteed, and the only guaranteed way to
 # launch an MPI process using mpiexec if such a program exists.
-set(MPIEXEC_NUMPROC_FLAG "-n"  CACHE STRING "Flag used by MPI to specify the number of processes for MPIEXEC; the next option will be the number of processes.")
-set(MPIEXEC_PREFLAGS     ""    CACHE STRING "These flags will be directly before the executable that is being run by MPIEXEC.")
-set(MPIEXEC_POSTFLAGS    ""    CACHE STRING "These flags will come after all flags given to MPIEXEC.")
+set(MPIEXEC_NUMPROC_FLAG "-n"  CACHE STRING "Flag used by MPI to specify the number of processes for mpiexec; the next option will be the number of processes.")
+set(MPIEXEC_PREFLAGS     ""    CACHE STRING "These flags will be directly before the executable that is being run by mpiexec.")
+set(MPIEXEC_POSTFLAGS    ""    CACHE STRING "These flags will be placed after all flags passed to mpiexec.")
 
 # Set the number of processes to the processor count and the previous default
 # of 2 if that couldn't be determined.
@@ -566,111 +1043,387 @@
 if("${_MPIEXEC_NUMPROCS}" EQUAL "0")
   set(_MPIEXEC_NUMPROCS 2)
 endif()
-set(MPIEXEC_MAX_NUMPROCS "${_MPIEXEC_NUMPROCS}"   CACHE STRING "Maximum number of processors available to run MPI applications.")
+set(MPIEXEC_MAX_NUMPROCS "${_MPIEXEC_NUMPROCS}" CACHE STRING "Maximum number of processors available to run MPI applications.")
 unset(_MPIEXEC_NUMPROCS)
-mark_as_advanced(MPIEXEC MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS MPIEXEC_POSTFLAGS MPIEXEC_MAX_NUMPROCS)
-
+mark_as_advanced(MPIEXEC_EXECUTABLE MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS MPIEXEC_POSTFLAGS MPIEXEC_MAX_NUMPROCS)
 
 #=============================================================================
 # Backward compatibility input hacks.  Propagate the FindMPI hints to C and
 # CXX if the respective new versions are not defined.  Translate the old
-# MPI_LIBRARY and MPI_EXTRA_LIBRARY to respective MPI_${lang}_LIBRARIES.
+# MPI_LIBRARY and MPI_EXTRA_LIBRARY to respective MPI_${LANG}_LIBRARIES.
 #
 # Once we find the new variables, we translate them back into their old
 # equivalents below.
-foreach (lang C CXX)
+foreach (LANG IN ITEMS C CXX)
   # Old input variables.
   set(_MPI_OLD_INPUT_VARS COMPILER COMPILE_FLAGS INCLUDE_PATH LINK_FLAGS)
 
   # Set new vars based on their old equivalents, if the new versions are not already set.
   foreach (var ${_MPI_OLD_INPUT_VARS})
-    if (NOT MPI_${lang}_${var} AND MPI_${var})
-      set(MPI_${lang}_${var} "${MPI_${var}}")
+    if (NOT MPI_${LANG}_${var} AND MPI_${var})
+      set(MPI_${LANG}_${var} "${MPI_${var}}")
     endif()
   endforeach()
 
-  # Special handling for MPI_LIBRARY and MPI_EXTRA_LIBRARY, which we nixed in the
-  # new FindMPI.  These need to be merged into MPI_<lang>_LIBRARIES
-  if (NOT MPI_${lang}_LIBRARIES AND (MPI_LIBRARY OR MPI_EXTRA_LIBRARY))
-    set(MPI_${lang}_LIBRARIES ${MPI_LIBRARY} ${MPI_EXTRA_LIBRARY})
+  # Chop the old compile flags into options and definitions
+  if(MPI_${LANG}_COMPILE_FLAGS)
+    unset(MPI_${LANG}_COMPILE_OPTIONS)
+    unset(MPI_${LANG}_COMPILE_DEFINITIONS)
+    separate_arguments(MPI_SEPARATE_FLAGS NATIVE_COMMAND "${MPI_${LANG}_COMPILE_FLAGS}")
+    foreach(_MPI_FLAG IN LISTS MPI_SEPARATE_FLAGS)
+      if("${_MPI_FLAG}" MATCHES "^ *[-/D]([^ ]+)")
+        list(APPEND MPI_${LANG}_COMPILE_DEFINITIONS "${CMAKE_MATCH_1}")
+      else()
+        list(APPEND MPI_${LANG}_COMPILE_FLAGS "${_MPI_FLAG}")
+      endif()
+    endforeach()
+    unset(MPI_SEPARATE_FLAGS)
+  endif()
+
+  # If a list of libraries was given, we'll split it into new-style cache variables
+  if(NOT MPI_${LANG}_LIB_NAMES)
+    foreach(_MPI_LIB IN LISTS MPI_${LANG}_LIBRARIES MPI_LIBRARY MPI_EXTRA_LIBRARY)
+      get_filename_component(_MPI_PLAIN_LIB_NAME "${_MPI_LIB}" NAME_WE)
+      get_filename_component(_MPI_LIB_NAME "${_MPI_LIB}" NAME)
+      get_filename_component(_MPI_LIB_DIR "${_MPI_LIB}" DIRECTORY)
+      list(APPEND MPI_PLAIN_LIB_NAMES_WORK "${_MPI_PLAIN_LIB_NAME}")
+      find_library(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY
+        NAMES "${_MPI_LIB_NAME}" "lib${_MPI_LIB_NAME}"
+        HINTS ${_MPI_LIB_DIR} $ENV{MPI_LIB}
+        DOC "Location of the ${_MPI_PLAIN_LIB_NAME} library for MPI"
+      )
+      mark_as_advanced(MPI_${_MPI_PLAIN_LIB_NAME}_LIBRARY)
+    endforeach()
   endif()
 endforeach()
 #=============================================================================
 
+unset(MPI_VERSION)
+unset(MPI_VERSION_MAJOR)
+unset(MPI_VERSION_MINOR)
+
+unset(_MPI_MIN_VERSION)
 
 # This loop finds the compilers and sends them off for interrogation.
-foreach (lang C CXX Fortran)
-  if (CMAKE_${lang}_COMPILER_WORKS)
-    # If the user supplies a compiler *name* instead of an absolute path, assume that we need to find THAT compiler.
-    if (MPI_${lang}_COMPILER)
-      if (NOT IS_ABSOLUTE "${MPI_${lang}_COMPILER}")
-        # Get rid of our default list of names and just search for the name the user wants.
-        set(_MPI_${lang}_COMPILER_NAMES ${MPI_${lang}_COMPILER})
-        set(MPI_${lang}_COMPILER "MPI_${lang}_COMPILER-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
-      endif()
-      # If the user specifies a compiler, we don't want to try to search libraries either.
-      set(try_libs FALSE)
+foreach(LANG IN ITEMS C CXX Fortran)
+  if(CMAKE_${LANG}_COMPILER_LOADED)
+    if(NOT MPI_FIND_COMPONENTS)
+      set(_MPI_FIND_${LANG} TRUE)
+    elseif( ${LANG} IN_LIST MPI_FIND_COMPONENTS)
+      set(_MPI_FIND_${LANG} TRUE)
+    elseif( ${LANG} STREQUAL CXX AND NOT MPI_CXX_SKIP_MPICXX AND MPICXX IN_LIST MPI_FIND_COMPONENTS )
+      set(_MPI_FIND_${LANG} TRUE)
     else()
-      set(try_libs TRUE)
+      set(_MPI_FIND_${LANG} FALSE)
+    endif()
+  else()
+    set(_MPI_FIND_${LANG} FALSE)
+  endif()
+  if(_MPI_FIND_${LANG})
+    if( ${LANG} STREQUAL CXX AND NOT MPICXX IN_LIST MPI_FIND_COMPONENTS )
+      set(MPI_CXX_SKIP_MPICXX FALSE CACHE BOOL "If true, the MPI-2 C++ bindings are disabled using definitions.")
+      mark_as_advanced(MPI_CXX_SKIP_MPICXX)
+    endif()
+    if(NOT (MPI_${LANG}_LIB_NAMES AND (MPI_${LANG}_INCLUDE_PATH OR MPI_${LANG}_INCLUDE_DIRS OR MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)))
+      if(NOT MPI_${LANG}_COMPILER AND NOT MPI_ASSUME_NO_BUILTIN_MPI)
+        # Should the imported targets be empty, we effectively try whether the compiler supports MPI on its own, which is the case on e.g.
+        # Cray PrgEnv.
+        _MPI_create_imported_target(${LANG})
+        _MPI_check_lang_works(${LANG})
+
+        # If the compiler can build MPI code on its own, it functions as an MPI compiler and we'll set the variable to point to it.
+        if(MPI_${LANG}_WORKS)
+          set(MPI_${LANG}_COMPILER "${CMAKE_${LANG}_COMPILER}" CACHE FILEPATH "MPI compiler for ${LANG}" FORCE)
+        endif()
+      endif()
+
+      # If the user specified a library name we assume they prefer that library over a wrapper. If not, they can disable skipping manually.
+      if(NOT DEFINED MPI_SKIP_COMPILER_WRAPPER AND MPI_GUESS_LIBRARY_NAME)
+        set(MPI_SKIP_COMPILER_WRAPPER TRUE)
+      endif()
+      if(NOT MPI_SKIP_COMPILER_WRAPPER)
+        if(MPI_${LANG}_COMPILER)
+          # If the user supplies a compiler *name* instead of an absolute path, assume that we need to find THAT compiler.
+          if (NOT IS_ABSOLUTE "${MPI_${LANG}_COMPILER}")
+            # Get rid of our default list of names and just search for the name the user wants.
+            set(_MPI_${LANG}_COMPILER_NAMES "${MPI_${LANG}_COMPILER}")
+            unset(MPI_${LANG}_COMPILER CACHE)
+          endif()
+          # If the user specifies a compiler, we don't want to try to search libraries either.
+          set(MPI_PINNED_COMPILER TRUE)
+        else()
+          set(MPI_PINNED_COMPILER FALSE)
+        endif()
+
+        # If we have an MPI base directory, we'll try all compiler names in that one first.
+        # This should prevent mixing different MPI environments
+        if(_MPI_BASE_DIR)
+          find_program(MPI_${LANG}_COMPILER
+            NAMES  ${_MPI_${LANG}_COMPILER_NAMES}
+            PATH_SUFFIXES bin sbin
+            HINTS  ${_MPI_BASE_DIR}
+            NO_DEFAULT_PATH
+            DOC    "MPI compiler for ${LANG}"
+          )
+        endif()
+
+        # If the base directory did not help (for example because the mpiexec isn't in the same directory as the compilers),
+        # we shall try searching in the default paths.
+        find_program(MPI_${LANG}_COMPILER
+          NAMES  ${_MPI_${LANG}_COMPILER_NAMES}
+          PATH_SUFFIXES bin sbin
+          DOC    "MPI compiler for ${LANG}"
+        )
+
+        if(MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER)
+          set(MPI_SKIP_GUESSING TRUE)
+        elseif(MPI_${LANG}_COMPILER)
+          _MPI_interrogate_compiler(${LANG})
+        else()
+          set(MPI_${LANG}_WRAPPER_FOUND FALSE)
+        endif()
+      else()
+        set(MPI_${LANG}_WRAPPER_FOUND FALSE)
+        set(MPI_PINNED_COMPILER FALSE)
+      endif()
+
+      if(NOT MPI_${LANG}_WRAPPER_FOUND AND NOT MPI_PINNED_COMPILER)
+        # For C++, we may use the settings for C. Should a given compiler wrapper for C++ not exist, but one for C does, we copy over the
+        # settings for C. An MPI distribution that is in this situation would be IBM Platform MPI.
+        if("${LANG}" STREQUAL "CXX" AND MPI_C_WRAPPER_FOUND)
+          set(MPI_${LANG}_COMPILE_OPTIONS          ${MPI_C_COMPILE_OPTIONS}     CACHE STRING "MPI ${LANG} compilation options"           )
+          set(MPI_${LANG}_COMPILE_DEFINITIONS      ${MPI_C_COMPILE_DEFINITIONS} CACHE STRING "MPI ${LANG} compilation definitions"       )
+          set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS  ${MPI_C_INCLUDE_DIRS}        CACHE STRING "MPI ${LANG} additional include directories")
+          set(MPI_${LANG}_LINK_FLAGS               ${MPI_C_LINK_FLAGS}          CACHE STRING "MPI ${LANG} linker flags"                  )
+          set(MPI_${LANG}_LIB_NAMES                ${MPI_C_LIB_NAMES}           CACHE STRING "MPI ${LANG} libraries to link against"     )
+          set(MPI_${LANG}_WRAPPER_FOUND TRUE)
+        elseif(NOT MPI_SKIP_GUESSING)
+          _MPI_guess_settings(${LANG})
+        endif()
+      endif()
     endif()
 
-    find_program(MPI_${lang}_COMPILER
-      NAMES  ${_MPI_${lang}_COMPILER_NAMES}
-      HINTS  ${_MPI_BASE_DIR}/bin
-      PATHS  ${_MPI_PREFIX_PATH}
-      )
-    interrogate_mpi_compiler(${lang} ${try_libs})
-    mark_as_advanced(MPI_${lang}_COMPILER)
+    _MPI_split_include_dirs(${LANG})
+    if(NOT MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER)
+      _MPI_assemble_include_dirs(${LANG})
+      _MPI_assemble_libraries(${LANG})
+    endif()
+    _MPI_adjust_compile_definitions(${LANG})
+    # We always create imported targets even if they're empty
+    _MPI_create_imported_target(${LANG})
 
-    # last ditch try -- if nothing works so far, just try running the regular compiler and
-    # see if we can create an MPI executable.
-    set(regular_compiler_worked 0)
-    if (NOT MPI_${lang}_LIBRARIES OR NOT MPI_${lang}_INCLUDE_PATH)
-      try_regular_compiler(${lang} regular_compiler_worked)
+    if(NOT MPI_${LANG}_WORKS)
+      _MPI_check_lang_works(${LANG})
     endif()
 
-    set(MPI_${lang}_FIND_QUIETLY ${MPI_FIND_QUIETLY})
-    set(MPI_${lang}_FIND_REQUIRED ${MPI_FIND_REQUIRED})
-    set(MPI_${lang}_FIND_VERSION ${MPI_FIND_VERSION})
-    set(MPI_${lang}_FIND_VERSION_EXACT ${MPI_FIND_VERSION_EXACT})
+    # Next, we'll initialize the MPI variables that have not been previously set.
+    set(MPI_${LANG}_COMPILE_OPTIONS          "" CACHE STRING "MPI ${LANG} compilation flags"             )
+    set(MPI_${LANG}_COMPILE_DEFINITIONS      "" CACHE STRING "MPI ${LANG} compilation definitions"       )
+    set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS  "" CACHE STRING "MPI ${LANG} additional include directories")
+    set(MPI_${LANG}_LINK_FLAGS               "" CACHE STRING "MPI ${LANG} linker flags"                  )
+    set(MPI_${LANG}_LIB_NAMES                "" CACHE STRING "MPI ${LANG} libraries to link against"     )
+    mark_as_advanced(MPI_${LANG}_COMPILE_OPTIONS MPI_${LANG}_COMPILE_DEFINITIONS MPI_${LANG}_LINK_FLAGS
+      MPI_${LANG}_LIB_NAMES MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS MPI_${LANG}_COMPILER)
 
-    if (regular_compiler_worked)
-      find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_COMPILER)
+    # If we've found MPI, then we'll perform additional analysis: Determine the MPI version, MPI library version, supported
+    # MPI APIs (i.e. MPI-2 C++ bindings). For Fortran we also need to find specific parameters if we're under MPI-3.
+    if(MPI_${LANG}_WORKS)
+      if("${LANG}" STREQUAL "CXX" AND NOT DEFINED MPI_MPICXX_FOUND)
+        if(NOT MPI_CXX_SKIP_MPICXX AND NOT MPI_CXX_VALIDATE_SKIP_MPICXX)
+          _MPI_try_staged_settings(${LANG} test_mpi MPICXX FALSE)
+          if(MPI_RESULT_${LANG}_test_mpi_MPICXX)
+            set(MPI_MPICXX_FOUND TRUE)
+          else()
+            set(MPI_MPICXX_FOUND FALSE)
+          endif()
+        else()
+          set(MPI_MPICXX_FOUND FALSE)
+        endif()
+      endif()
+
+      # At this point, we know the bindings present but not the MPI version or anything else.
+      if(NOT DEFINED MPI_${LANG}_VERSION)
+        unset(MPI_${LANG}_VERSION_MAJOR)
+        unset(MPI_${LANG}_VERSION_MINOR)
+      endif()
+      set(MPI_BIN_FOLDER ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI)
+
+      # For Fortran, we'll want to use the most modern MPI binding to test capabilities other than the
+      # Fortran parameters, since those depend on the method of consumption.
+      # For C++, we can always use the C bindings, and should do so, since the C++ bindings do not exist in MPI-3
+      # whereas the C bindings do, and the C++ bindings never offered any feature advantage over their C counterparts.
+      if("${LANG}" STREQUAL "Fortran")
+        if(MPI_${LANG}_HAVE_F08_MODULE)
+          set(MPI_${LANG}_HIGHEST_METHOD F08_MODULE)
+        elseif(MPI_${LANG}_HAVE_F90_MODULE)
+          set(MPI_${LANG}_HIGHEST_METHOD F90_MODULE)
+        else()
+          set(MPI_${LANG}_HIGHEST_METHOD F77_HEADER)
+        endif()
+
+        # Another difference between C and Fortran is that we can't use the preprocessor to determine whether MPI_VERSION
+        # and MPI_SUBVERSION are provided. These defines did not exist in MPI 1.0 and 1.1 and therefore might not
+        # exist. For C/C++, test_mpi.c will handle the MPI_VERSION extraction, but for Fortran, we need mpiver.f90.
+        if(NOT DEFINED MPI_${LANG}_VERSION)
+          _MPI_try_staged_settings(${LANG} mpiver ${MPI_${LANG}_HIGHEST_METHOD} FALSE)
+          if(MPI_RESULT_${LANG}_mpiver_${MPI_${LANG}_HIGHEST_METHOD})
+            file(STRINGS ${MPI_BIN_FOLDER}/mpiver_${LANG}.bin _MPI_VERSION_STRING LIMIT_COUNT 1 REGEX "INFO:MPI-VER")
+            if("${_MPI_VERSION_STRING}" MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*")
+              set(MPI_${LANG}_VERSION_MAJOR "${CMAKE_MATCH_1}")
+              set(MPI_${LANG}_VERSION_MINOR "${CMAKE_MATCH_2}")
+              set(MPI_${LANG}_VERSION "${MPI_${LANG}_VERSION_MAJOR}.${MPI_${LANG}_VERSION_MINOR}")
+            endif()
+          endif()
+        endif()
+
+        # Finally, we want to find out which capabilities a given interface supports, compare the MPI-3 standard.
+        # This is determined by interface specific parameters MPI_SUBARRAYS_SUPPORTED and MPI_ASYNC_PROTECTS_NONBLOCKING
+        # and might vary between the different methods of consumption.
+        if(MPI_DETERMINE_Fortran_CAPABILITIES AND NOT MPI_Fortran_CAPABILITIES_DETERMINED)
+          foreach(mpimethod IN ITEMS F08_MODULE F90_MODULE F77_HEADER)
+            if(MPI_${LANG}_HAVE_${mpimethod})
+              set(MPI_${LANG}_${mpimethod}_SUBARRAYS FALSE)
+              set(MPI_${LANG}_${mpimethod}_ASYNCPROT FALSE)
+              _MPI_try_staged_settings(${LANG} fortranparam_mpi ${mpimethod} TRUE)
+              if(MPI_RESULT_${LANG}_fortranparam_mpi_${mpimethod} AND
+                NOT "${MPI_RUN_RESULT_${LANG}_fortranparam_mpi_${mpimethod}}" STREQUAL "FAILED_TO_RUN")
+                if("${MPI_RUN_OUTPUT_${LANG}_fortranparam_mpi_${mpimethod}}" MATCHES
+                  ".*INFO:SUBARRAYS\\[ *([TF]) *\\]-ASYNCPROT\\[ *([TF]) *\\].*")
+                  if("${CMAKE_MATCH_1}" STREQUAL "T")
+                    set(MPI_${LANG}_${mpimethod}_SUBARRAYS TRUE)
+                  endif()
+                  if("${CMAKE_MATCH_2}" STREQUAL "T")
+                    set(MPI_${LANG}_${mpimethod}_ASYNCPROT TRUE)
+                  endif()
+                endif()
+              endif()
+            endif()
+          endforeach()
+          set(MPI_Fortran_CAPABILITIES_DETERMINED TRUE)
+        endif()
+      else()
+        set(MPI_${LANG}_HIGHEST_METHOD normal)
+
+        # By the MPI-2 standard, MPI_VERSION and MPI_SUBVERSION are valid for both C and C++ bindings.
+        if(NOT DEFINED MPI_${LANG}_VERSION)
+          file(STRINGS ${MPI_BIN_FOLDER}/test_mpi_${LANG}.bin _MPI_VERSION_STRING LIMIT_COUNT 1 REGEX "INFO:MPI-VER")
+          if("${_MPI_VERSION_STRING}" MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*")
+            set(MPI_${LANG}_VERSION_MAJOR "${CMAKE_MATCH_1}")
+            set(MPI_${LANG}_VERSION_MINOR "${CMAKE_MATCH_2}")
+            set(MPI_${LANG}_VERSION "${MPI_${LANG}_VERSION_MAJOR}.${MPI_${LANG}_VERSION_MINOR}")
+          endif()
+        endif()
+      endif()
+
+      unset(MPI_BIN_FOLDER)
+
+      # At this point, we have dealt with determining the MPI version and parameters for each Fortran method available.
+      # The one remaining issue is to determine which MPI library is installed.
+      # Determining the version and vendor of the MPI library is only possible via MPI_Get_library_version() at runtime,
+      # and therefore we cannot do this while cross-compiling (a user may still define MPI_<lang>_LIBRARY_VERSION_STRING
+      # themselves and we'll attempt splitting it, which is equivalent to provide the try_run output).
+      # It's also worth noting that the installed version string can depend on the language, or on the system the binary
+      # runs on if MPI is not statically linked.
+      if(MPI_DETERMINE_LIBRARY_VERSION AND NOT MPI_${LANG}_LIBRARY_VERSION_STRING)
+        _MPI_try_staged_settings(${LANG} libver_mpi ${MPI_${LANG}_HIGHEST_METHOD} TRUE)
+        if(MPI_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD} AND
+          "${MPI_RUN_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}" EQUAL "0")
+          string(STRIP "${MPI_RUN_OUTPUT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}"
+            MPI_${LANG}_LIBRARY_VERSION_STRING)
+        else()
+          set(MPI_${LANG}_LIBRARY_VERSION_STRING "NOTFOUND")
+        endif()
+      endif()
+    endif()
+
+    set(MPI_${LANG}_FIND_QUIETLY ${MPI_FIND_QUIETLY})
+    set(MPI_${LANG}_FIND_VERSION ${MPI_FIND_VERSION})
+    set(MPI_${LANG}_FIND_VERSION_EXACT ${MPI_FIND_VERSION_EXACT})
+
+    unset(MPI_${LANG}_REQUIRED_VARS)
+    if (MPI_${LANG}_WRAPPER_FOUND OR MPI_${LANG}_GUESS_FOUND)
+      foreach(mpilibname IN LISTS MPI_${LANG}_LIB_NAMES)
+        list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${mpilibname}_LIBRARY")
+      endforeach()
+      list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_LIB_NAMES")
+      if("${LANG}" STREQUAL "Fortran")
+        # For Fortran we only need one of the module or header directories to have *some* support for MPI.
+        if(NOT MPI_${LANG}_MODULE_DIR)
+          list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_F77_HEADER_DIR")
+        endif()
+        if(NOT MPI_${LANG}_F77_HEADER_DIR)
+          list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_MODULE_DIR")
+        endif()
+      else()
+        list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_HEADER_DIR")
+      endif()
+      if(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
+        foreach(mpiincvar IN LISTS MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
+          list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${mpiincvar}_INCLUDE_DIR")
+        endforeach()
+      endif()
+      # Append the works variable now. If the settings did not work, this will show up properly.
+      list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_WORKS")
     else()
-      find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_LIBRARIES MPI_${lang}_INCLUDE_PATH)
+      # If the compiler worked implicitly, use its path as output.
+      # Should the compiler variable be set, we also require it to work.
+      list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_COMPILER")
+      if(MPI_${LANG}_COMPILER)
+        list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_WORKS")
+      endif()
     endif()
+    find_package_handle_standard_args(MPI_${LANG} REQUIRED_VARS ${MPI_${LANG}_REQUIRED_VARS}
+      VERSION_VAR MPI_${LANG}_VERSION)
 
-    if(MPI_${lang}_FOUND)
-      if(NOT TARGET MPI::MPI_${lang})
-        add_library(MPI::MPI_${lang} INTERFACE IMPORTED)
+    if(DEFINED MPI_${LANG}_VERSION)
+      if(NOT _MPI_MIN_VERSION OR _MPI_MIN_VERSION VERSION_GREATER MPI_${LANG}_VERSION)
+        set(_MPI_MIN_VERSION MPI_${LANG}_VERSION)
       endif()
-      if(MPI_${lang}_COMPILE_FLAGS)
-        separate_arguments(_MPI_${lang}_COMPILE_OPTIONS NATIVE_COMMAND "${MPI_${lang}_COMPILE_FLAGS}")
-        set_property(TARGET MPI::MPI_${lang} PROPERTY
-          INTERFACE_COMPILE_OPTIONS "${_MPI_${lang}_COMPILE_OPTIONS}")
-      endif()
-
-      unset(_MPI_${lang}_LINK_LINE)
-      if(MPI_${lang}_LINK_FLAGS)
-        list(APPEND _MPI_${lang}_LINK_LINE "${MPI_${lang}_LINK_FLAGS}")
-      endif()
-      list(APPEND _MPI_${lang}_LINK_LINE "${MPI_${lang}_LIBRARIES}")
-      set_property(TARGET MPI::MPI_${lang} PROPERTY
-        INTERFACE_LINK_LIBRARIES "${_MPI_${lang}_LINK_LINE}")
-
-      set_property(TARGET MPI::MPI_${lang} PROPERTY
-        INTERFACE_INCLUDE_DIRECTORIES "${MPI_${lang}_INCLUDE_PATH}")
     endif()
   endif()
 endforeach()
 
+unset(_MPI_REQ_VARS)
+foreach(LANG IN ITEMS C CXX Fortran)
+  if((NOT MPI_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST MPI_FIND_COMPONENTS)
+    list(APPEND _MPI_REQ_VARS "MPI_${LANG}_FOUND")
+  endif()
+endforeach()
+
+if(MPICXX IN_LIST MPI_FIND_COMPONENTS)
+  list(APPEND _MPI_REQ_VARS "MPI_MPICXX_FOUND")
+endif()
+
+find_package_handle_standard_args(MPI
+    REQUIRED_VARS ${_MPI_REQ_VARS}
+    VERSION_VAR ${_MPI_MIN_VERSION}
+    HANDLE_COMPONENTS)
 
 #=============================================================================
 # More backward compatibility stuff
-#
-# Bare MPI sans ${lang} vars are set to CXX then C, depending on what was found.
+
+# For compatibility reasons, we also define MPIEXEC
+set(MPIEXEC "${MPIEXEC_EXECUTABLE}")
+
+# Copy over MPI_<LANG>_INCLUDE_PATH from the assembled INCLUDE_DIRS.
+foreach(LANG IN ITEMS C CXX Fortran)
+  if(MPI_${LANG}_FOUND)
+    set(MPI_${LANG}_INCLUDE_PATH "${MPI_${LANG}_INCLUDE_DIRS}")
+    unset(MPI_${LANG}_COMPILE_FLAGS)
+    if(MPI_${LANG}_COMPILE_OPTIONS)
+      set(MPI_${LANG}_COMPILE_FLAGS "${MPI_${LANG}_COMPILE_OPTIONS}")
+    endif()
+    if(MPI_${LANG}_COMPILE_DEFINITIONS)
+      foreach(_MPI_DEF IN LISTS MPI_${LANG}_COMPILE_DEFINITIONS)
+        string(APPEND MPI_${LANG}_COMPILE_FLAGS " -D${_MPI_DEF}")
+      endforeach()
+    endif()
+  endif()
+endforeach()
+
+# Bare MPI sans ${LANG} vars are set to CXX then C, depending on what was found.
 # This mimics the behavior of the old language-oblivious FindMPI.
-set(_MPI_OLD_VARS FOUND COMPILER INCLUDE_PATH COMPILE_FLAGS LINK_FLAGS LIBRARIES)
+set(_MPI_OLD_VARS COMPILER INCLUDE_PATH COMPILE_FLAGS LINK_FLAGS LIBRARIES)
 if (MPI_CXX_FOUND)
   foreach (var ${_MPI_OLD_VARS})
     set(MPI_${var} ${MPI_CXX_${var}})
@@ -679,28 +1432,26 @@
   foreach (var ${_MPI_OLD_VARS})
     set(MPI_${var} ${MPI_C_${var}})
   endforeach()
-else()
-  # Note that we might still have found Fortran, but you'll need to use MPI_Fortran_FOUND
-  set(MPI_FOUND FALSE)
 endif()
 
 # Chop MPI_LIBRARIES into the old-style MPI_LIBRARY and MPI_EXTRA_LIBRARY, and set them in cache.
 if (MPI_LIBRARIES)
   list(GET MPI_LIBRARIES 0 MPI_LIBRARY_WORK)
-  set(MPI_LIBRARY ${MPI_LIBRARY_WORK} CACHE FILEPATH "MPI library to link against" FORCE)
+  set(MPI_LIBRARY "${MPI_LIBRARY_WORK}")
+  unset(MPI_LIBRARY_WORK)
 else()
-  set(MPI_LIBRARY "MPI_LIBRARY-NOTFOUND" CACHE FILEPATH "MPI library to link against" FORCE)
+  set(MPI_LIBRARY "MPI_LIBRARY-NOTFOUND")
 endif()
 
 list(LENGTH MPI_LIBRARIES MPI_NUMLIBS)
 if (MPI_NUMLIBS GREATER 1)
-  set(MPI_EXTRA_LIBRARY_WORK ${MPI_LIBRARIES})
+  set(MPI_EXTRA_LIBRARY_WORK "${MPI_LIBRARIES}")
   list(REMOVE_AT MPI_EXTRA_LIBRARY_WORK 0)
-  set(MPI_EXTRA_LIBRARY ${MPI_EXTRA_LIBRARY_WORK} CACHE STRING "Extra MPI libraries to link against" FORCE)
+  set(MPI_EXTRA_LIBRARY "${MPI_EXTRA_LIBRARY_WORK}")
+  unset(MPI_EXTRA_LIBRARY_WORK)
 else()
-  set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND" CACHE STRING "Extra MPI libraries to link against" FORCE)
+  set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND")
 endif()
-mark_as_advanced(MPI_LIBRARY MPI_EXTRA_LIBRARY)
 #=============================================================================
 
 # unset these vars to cleanup namespace
@@ -708,5 +1459,7 @@
 unset(_MPI_PREFIX_PATH)
 unset(_MPI_BASE_DIR)
 foreach (lang C CXX Fortran)
-  unset(_MPI_${lang}_COMPILER_NAMES)
+  unset(_MPI_${LANG}_COMPILER_NAMES)
 endforeach()
+
+cmake_policy(POP)
diff --git a/Modules/FindMPI/fortranparam_mpi.f90.in b/Modules/FindMPI/fortranparam_mpi.f90.in
new file mode 100644
index 0000000..30f912c
--- /dev/null
+++ b/Modules/FindMPI/fortranparam_mpi.f90.in
@@ -0,0 +1,4 @@
+      program mpi_ver
+      @MPI_Fortran_INCLUDE_LINE@
+      print *, 'INFO:SUBARRAYS[', MPI_SUBARRAYS_SUPPORTED, ']-ASYNCPROT[', MPI_ASYNC_PROTECTS_NONBLOCKING, ']'
+      end program mpi_ver
diff --git a/Modules/FindMPI/libver_mpi.c b/Modules/FindMPI/libver_mpi.c
new file mode 100644
index 0000000..be9d19d
--- /dev/null
+++ b/Modules/FindMPI/libver_mpi.c
@@ -0,0 +1,19 @@
+#include <mpi.h>
+
+#ifdef __cplusplus
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+
+int main(int argc, char* argv[])
+{
+  char mpilibver_str[MPI_MAX_LIBRARY_VERSION_STRING];
+  int mpilibver_len;
+  MPI_Get_library_version(mpilibver_str, &mpilibver_len);
+#ifdef __cplusplus
+  std::puts(mpilibver_str);
+#else
+  puts(mpilibver_str);
+#endif
+}
diff --git a/Modules/FindMPI/libver_mpi.f90.in b/Modules/FindMPI/libver_mpi.f90.in
new file mode 100644
index 0000000..7938587
--- /dev/null
+++ b/Modules/FindMPI/libver_mpi.f90.in
@@ -0,0 +1,7 @@
+      program mpi_ver
+      @MPI_Fortran_INCLUDE_LINE@
+      character(len=MPI_MAX_LIBRARY_VERSION_STRING) :: mpilibver_str
+      integer(kind=MPI_INTEGER_KIND) :: ierror, reslen
+      call MPI_GET_LIBRARY_VERSION(mpilibver_str, reslen, ierror)
+      print *, mpilibver_str
+      end program mpi_ver
diff --git a/Modules/FindMPI/mpiver.f90.in b/Modules/FindMPI/mpiver.f90.in
new file mode 100644
index 0000000..a254523
--- /dev/null
+++ b/Modules/FindMPI/mpiver.f90.in
@@ -0,0 +1,10 @@
+      program mpi_ver
+      @MPI_Fortran_INCLUDE_LINE@
+      integer(kind=kind(MPI_VERSION)), parameter :: zero = ichar('0')
+      character, dimension(17), parameter :: mpiver_str =&
+      (/ 'I', 'N', 'F', 'O', ':', 'M', 'P', 'I', '-', 'V', 'E', 'R', '[', &
+        char(zero + MPI_VERSION), &
+        '.', &
+        char(zero + MPI_SUBVERSION), ']' /)
+      print *, mpiver_str
+      end program mpi_ver
diff --git a/Modules/FindMPI/test_mpi.c b/Modules/FindMPI/test_mpi.c
new file mode 100644
index 0000000..b8a308a
--- /dev/null
+++ b/Modules/FindMPI/test_mpi.c
@@ -0,0 +1,37 @@
+#include <mpi.h>
+
+#ifdef __cplusplus
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+
+#if defined(MPI_VERSION) && defined(MPI_SUBVERSION)
+const char mpiver_str[] = { 'I', 'N',
+                            'F', 'O',
+                            ':', 'M',
+                            'P', 'I',
+                            '-', 'V',
+                            'E', 'R',
+                            '[', ('0' + MPI_VERSION),
+                            '.', ('0' + MPI_SUBVERSION),
+                            ']', '\0' };
+#endif
+
+int main(int argc, char* argv[])
+{
+#if defined(MPI_VERSION) && defined(MPI_SUBVERSION)
+#ifdef __cplusplus
+  std::puts(mpiver_str);
+#else
+  puts(mpiver_str);
+#endif
+#endif
+#ifdef TEST_MPI_MPICXX
+  MPI::MPI_Init(&argc, &argv);
+  MPI::MPI_Finalize();
+#else
+  MPI_Init(&argc, &argv);
+  MPI_Finalize();
+#endif
+}
diff --git a/Modules/FindMPI/test_mpi.f90.in b/Modules/FindMPI/test_mpi.f90.in
new file mode 100644
index 0000000..4d43a04
--- /dev/null
+++ b/Modules/FindMPI/test_mpi.f90.in
@@ -0,0 +1,6 @@
+      program hello
+      @MPI_Fortran_INCLUDE_LINE@
+      integer@MPI_Fortran_INTEGER_LINE@ ierror
+      call MPI_INIT(ierror)
+      call MPI_FINALIZE(ierror)
+      end program
diff --git a/Modules/Platform/FreeBSD-Determine-CXX.cmake b/Modules/Platform/FreeBSD-Determine-CXX.cmake
new file mode 100644
index 0000000..b594dae
--- /dev/null
+++ b/Modules/Platform/FreeBSD-Determine-CXX.cmake
@@ -0,0 +1,3 @@
+if(NOT CMAKE_CXX_COMPILER_NAMES)
+  set(CMAKE_CXX_COMPILER_NAMES c++)
+endif()
diff --git a/Modules/Platform/Midipix.cmake b/Modules/Platform/Midipix.cmake
new file mode 100644
index 0000000..54a156b
--- /dev/null
+++ b/Modules/Platform/Midipix.cmake
@@ -0,0 +1 @@
+include(Platform/UnixPaths)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 3539302..666293c 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 20170916)
+set(CMake_VERSION_PATCH 20170922)
 #set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 97e792a..825a888 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -49,19 +49,15 @@
     ifwCmd += " -p " + this->toplevel + "/packages";
 
     if (!this->PkgsDirsVector.empty()) {
-      for (std::vector<std::string>::iterator it =
-             this->PkgsDirsVector.begin();
-           it != this->PkgsDirsVector.end(); ++it) {
-        ifwCmd += " -p " + *it;
+      for (std::string const& it : this->PkgsDirsVector) {
+        ifwCmd += " -p " + it;
       }
     }
 
     if (!this->RepoDirsVector.empty()) {
       if (!this->IsVersionLess("3.1")) {
-        for (std::vector<std::string>::iterator it =
-               this->RepoDirsVector.begin();
-             it != this->RepoDirsVector.end(); ++it) {
-          ifwCmd += " --repository " + *it;
+        for (std::string const& rd : this->RepoDirsVector) {
+          ifwCmd += " --repository " + rd;
         }
       } else {
         cmCPackIFWLogger(WARNING, "The \"CPACK_IFW_REPOSITORIES_DIRECTORIES\" "
@@ -137,19 +133,15 @@
     ifwCmd += " -p " + this->toplevel + "/packages";
 
     if (!this->PkgsDirsVector.empty()) {
-      for (std::vector<std::string>::iterator it =
-             this->PkgsDirsVector.begin();
-           it != this->PkgsDirsVector.end(); ++it) {
-        ifwCmd += " -p " + *it;
+      for (std::string const& it : this->PkgsDirsVector) {
+        ifwCmd += " -p " + it;
       }
     }
 
     if (!this->RepoDirsVector.empty()) {
       if (!this->IsVersionLess("3.1")) {
-        for (std::vector<std::string>::iterator it =
-               this->RepoDirsVector.begin();
-             it != this->RepoDirsVector.end(); ++it) {
-          ifwCmd += " --repository " + *it;
+        for (std::string const& rd : this->RepoDirsVector) {
+          ifwCmd += " --repository " + rd;
         }
       } else {
         cmCPackIFWLogger(WARNING, "The \"CPACK_IFW_REPOSITORIES_DIRECTORIES\" "
@@ -258,7 +250,7 @@
 
   const char* BinCreatorStr = this->GetOption(BinCreatorOpt);
   if (!BinCreatorStr || cmSystemTools::IsNOTFOUND(BinCreatorStr)) {
-    this->BinCreator = "";
+    this->BinCreator.clear();
   } else {
     this->BinCreator = BinCreatorStr;
   }
@@ -274,7 +266,7 @@
 
   const char* RepoGenStr = this->GetOption(RepoGenOpt);
   if (!RepoGenStr || cmSystemTools::IsNOTFOUND(RepoGenStr)) {
-    this->RepoGen = "";
+    this->RepoGen.clear();
   } else {
     this->RepoGen = RepoGenStr;
   }
@@ -321,9 +313,8 @@
   if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) {
     std::vector<std::string> RepoAllVector;
     cmSystemTools::ExpandListArgument(RepoAllStr, RepoAllVector);
-    for (std::vector<std::string>::iterator rit = RepoAllVector.begin();
-         rit != RepoAllVector.end(); ++rit) {
-      this->GetRepository(*rit);
+    for (std::string const& r : RepoAllVector) {
+      this->GetRepository(r);
     }
   }
 
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.h b/Source/CPack/IFW/cmCPackIFWGenerator.h
index 9fd14bd..919dd46 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.h
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.h
@@ -47,7 +47,7 @@
   /**
    * Destruct IFW generator
    */
-  ~cmCPackIFWGenerator() CM_OVERRIDE;
+  ~cmCPackIFWGenerator() override;
 
 protected:
   // cmCPackGenerator reimplementation
@@ -56,18 +56,18 @@
    * @brief Initialize generator
    * @return 0 on failure
    */
-  int InitializeInternal() CM_OVERRIDE;
-  int PackageFiles() CM_OVERRIDE;
-  const char* GetPackagingInstallPrefix() CM_OVERRIDE;
+  int InitializeInternal() override;
+  int PackageFiles() override;
+  const char* GetPackagingInstallPrefix() override;
 
   /**
    * @brief Target binary extension
    * @return Executable suffix or disk image format
    */
-  const char* GetOutputExtension() CM_OVERRIDE;
+  const char* GetOutputExtension() override;
 
   std::string GetComponentInstallDirNameSuffix(
-    const std::string& componentName) CM_OVERRIDE;
+    const std::string& componentName) override;
 
   /**
    * @brief Get Component
@@ -79,7 +79,7 @@
    * @return Pointer to component
    */
   cmCPackComponent* GetComponent(const std::string& projectName,
-                                 const std::string& componentName) CM_OVERRIDE;
+                                 const std::string& componentName) override;
 
   /**
    * @brief Get group of component
@@ -91,12 +91,12 @@
    * @return Pointer to component group
    */
   cmCPackComponentGroup* GetComponentGroup(
-    const std::string& projectName, const std::string& groupName) CM_OVERRIDE;
+    const std::string& projectName, const std::string& groupName) override;
 
-  enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir() const
-    CM_OVERRIDE;
-  bool SupportsAbsoluteDestination() const CM_OVERRIDE;
-  bool SupportsComponentInstallation() const CM_OVERRIDE;
+  enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir()
+    const override;
+  bool SupportsAbsoluteDestination() const override;
+  bool SupportsComponentInstallation() const override;
 
 protected:
   // Methods
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
index 288e924..422f5d5 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -262,7 +262,7 @@
   std::string path, basePath;
 
 protected:
-  void StartElement(const std::string& name, const char** /*atts*/) CM_OVERRIDE
+  void StartElement(const std::string& name, const char** /*atts*/) override
   {
     this->file = name == "file";
     if (file) {
@@ -270,7 +270,7 @@
     }
   }
 
-  void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
+  void CharacterDataHandler(const char* data, int length) override
   {
     if (this->file) {
       std::string content(data, data + length);
@@ -284,7 +284,7 @@
     }
   }
 
-  void EndElement(const std::string& /*name*/) CM_OVERRIDE {}
+  void EndElement(const std::string& /*name*/) override {}
 };
 
 void cmCPackIFWInstaller::GenerateInstallerFile()
@@ -406,9 +406,8 @@
   // Remote repositories
   if (!this->RemoteRepositories.empty()) {
     xout.StartElement("RemoteRepositories");
-    for (RepositoriesVector::iterator rit = this->RemoteRepositories.begin();
-         rit != this->RemoteRepositories.end(); ++rit) {
-      (*rit)->WriteRepositoryConfig(xout);
+    for (cmCPackIFWRepository* r : this->RemoteRepositories) {
+      r->WriteRepositoryConfig(xout);
     }
     xout.EndElement();
   }
@@ -492,9 +491,8 @@
   }
 
   // Generate packages meta information
-  for (PackagesMap::iterator pit = this->Packages.begin();
-       pit != this->Packages.end(); ++pit) {
-    cmCPackIFWPackage* package = pit->second;
+  for (auto& p : this->Packages) {
+    cmCPackIFWPackage* package = p.second;
     package->GeneratePackageFile();
   }
 }
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index 8461309..7b23005 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -111,19 +111,19 @@
 {
   this->DisplayName.clear();
   this->Description.clear();
-  this->Version = "";
-  this->ReleaseDate = "";
-  this->Script = "";
+  this->Version.clear();
+  this->ReleaseDate.clear();
+  this->Script.clear();
   this->Licenses.clear();
   this->UserInterfaces.clear();
   this->Translations.clear();
-  this->SortingPriority = "";
-  this->UpdateText = "";
-  this->Default = "";
-  this->Essential = "";
-  this->Virtual = "";
-  this->ForcedInstallation = "";
-  this->RequiresAdminRights = "";
+  this->SortingPriority.clear();
+  this->UpdateText.clear();
+  this->Default.clear();
+  this->Essential.clear();
+  this->Virtual.clear();
+  this->ForcedInstallation.clear();
+  this->RequiresAdminRights.clear();
 }
 
 // Defaul configuration (all in one package)
@@ -203,10 +203,8 @@
 
   // CMake dependencies
   if (!component->Dependencies.empty()) {
-    std::vector<cmCPackComponent*>::iterator dit;
-    for (dit = component->Dependencies.begin();
-         dit != component->Dependencies.end(); ++dit) {
-      this->Dependencies.insert(this->Generator->ComponentPackages[*dit]);
+    for (cmCPackComponent* dep : component->Dependencies) {
+      this->Dependencies.insert(this->Generator->ComponentPackages[dep]);
     }
   }
 
@@ -413,9 +411,8 @@
   if (const char* value = this->GetOption(option)) {
     cmSystemTools::ExpandListArgument(value, deps);
   }
-  for (std::vector<std::string>::iterator dit = deps.begin();
-       dit != deps.end(); ++dit) {
-    DependenceStruct dep(*dit);
+  for (std::string const& d : deps) {
+    DependenceStruct dep(d);
     if (this->Generator->Packages.count(dep.Name)) {
       cmCPackIFWPackage& depPkg = this->Generator->Packages[dep.Name];
       dep.Name = depPkg.Name;
@@ -435,9 +432,8 @@
   } else if (const char* value = this->GetOption(option)) {
     std::vector<std::string> depsOn;
     cmSystemTools::ExpandListArgument(value, depsOn);
-    for (std::vector<std::string>::iterator dit = depsOn.begin();
-         dit != depsOn.end(); ++dit) {
-      DependenceStruct dep(*dit);
+    for (std::string const& d : depsOn) {
+      DependenceStruct dep(d);
       if (this->Generator->Packages.count(dep.Name)) {
         cmCPackIFWPackage& depPkg = this->Generator->Packages[dep.Name];
         dep.Name = depPkg.Name;
@@ -521,26 +517,22 @@
   xout.StartElement("Package");
 
   // DisplayName (with translations)
-  for (std::map<std::string, std::string>::iterator it =
-         this->DisplayName.begin();
-       it != this->DisplayName.end(); ++it) {
+  for (auto const& dn : this->DisplayName) {
     xout.StartElement("DisplayName");
-    if (!it->first.empty()) {
-      xout.Attribute("xml:lang", it->first);
+    if (!dn.first.empty()) {
+      xout.Attribute("xml:lang", dn.first);
     }
-    xout.Content(it->second);
+    xout.Content(dn.second);
     xout.EndElement();
   }
 
   // Description (with translations)
-  for (std::map<std::string, std::string>::iterator it =
-         this->Description.begin();
-       it != this->Description.end(); ++it) {
+  for (auto const& d : this->Description) {
     xout.StartElement("Description");
-    if (!it->first.empty()) {
-      xout.Attribute("xml:lang", it->first);
+    if (!d.first.empty()) {
+      xout.Attribute("xml:lang", d.first);
     }
-    xout.Content(it->second);
+    xout.Content(d.second);
     xout.EndElement();
   }
 
@@ -568,46 +560,43 @@
 
   // User Interfaces (copy to meta dir)
   std::vector<std::string> userInterfaces = UserInterfaces;
-  for (size_t i = 0; i < userInterfaces.size(); i++) {
-    std::string name = cmSystemTools::GetFilenameName(userInterfaces[i]);
+  for (std::string& userInterface : userInterfaces) {
+    std::string name = cmSystemTools::GetFilenameName(userInterface);
     std::string path = this->Directory + "/meta/" + name;
-    cmsys::SystemTools::CopyFileIfDifferent(userInterfaces[i], path);
-    userInterfaces[i] = name;
+    cmsys::SystemTools::CopyFileIfDifferent(userInterface, path);
+    userInterface = name;
   }
   if (!userInterfaces.empty()) {
     xout.StartElement("UserInterfaces");
-    for (size_t i = 0; i < userInterfaces.size(); i++) {
-      xout.Element("UserInterface", userInterfaces[i]);
+    for (std::string const& userInterface : userInterfaces) {
+      xout.Element("UserInterface", userInterface);
     }
     xout.EndElement();
   }
 
   // Translations (copy to meta dir)
   std::vector<std::string> translations = Translations;
-  for (size_t i = 0; i < translations.size(); i++) {
-    std::string name = cmSystemTools::GetFilenameName(translations[i]);
+  for (std::string& translation : translations) {
+    std::string name = cmSystemTools::GetFilenameName(translation);
     std::string path = this->Directory + "/meta/" + name;
-    cmsys::SystemTools::CopyFileIfDifferent(translations[i], path);
-    translations[i] = name;
+    cmsys::SystemTools::CopyFileIfDifferent(translation, path);
+    translation = name;
   }
   if (!translations.empty()) {
     xout.StartElement("Translations");
-    for (size_t i = 0; i < translations.size(); i++) {
-      xout.Element("Translation", translations[i]);
+    for (std::string const& translation : translations) {
+      xout.Element("Translation", translation);
     }
     xout.EndElement();
   }
 
   // Dependencies
   std::set<DependenceStruct> compDepSet;
-  for (std::set<DependenceStruct*>::iterator ait =
-         this->AlienDependencies.begin();
-       ait != this->AlienDependencies.end(); ++ait) {
-    compDepSet.insert(*(*ait));
+  for (DependenceStruct* ad : this->AlienDependencies) {
+    compDepSet.insert(*ad);
   }
-  for (std::set<cmCPackIFWPackage*>::iterator it = this->Dependencies.begin();
-       it != this->Dependencies.end(); ++it) {
-    compDepSet.insert(DependenceStruct((*it)->Name));
+  for (cmCPackIFWPackage* d : this->Dependencies) {
+    compDepSet.insert(DependenceStruct(d->Name));
   }
   // Write dependencies
   if (!compDepSet.empty()) {
@@ -624,10 +613,8 @@
 
   // Automatic dependency on
   std::set<DependenceStruct> compAutoDepSet;
-  for (std::set<DependenceStruct*>::iterator ait =
-         this->AlienAutoDependOn.begin();
-       ait != this->AlienAutoDependOn.end(); ++ait) {
-    compAutoDepSet.insert(*(*ait));
+  for (DependenceStruct* aad : this->AlienAutoDependOn) {
+    compAutoDepSet.insert(*aad);
   }
   // Write automatic dependency on
   if (!compAutoDepSet.empty()) {
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx
index b115db0..a01fc4e 100644
--- a/Source/CPack/IFW/cmCPackIFWRepository.cxx
+++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx
@@ -62,49 +62,49 @@
   if (const char* url = this->GetOption(prefix + "URL")) {
     this->Url = url;
   } else {
-    this->Url = "";
+    this->Url.clear();
   }
 
   // Old url
   if (const char* oldUrl = this->GetOption(prefix + "OLD_URL")) {
     this->OldUrl = oldUrl;
   } else {
-    this->OldUrl = "";
+    this->OldUrl.clear();
   }
 
   // New url
   if (const char* newUrl = this->GetOption(prefix + "NEW_URL")) {
     this->NewUrl = newUrl;
   } else {
-    this->NewUrl = "";
+    this->NewUrl.clear();
   }
 
   // Enabled
   if (this->IsOn(prefix + "DISABLED")) {
     this->Enabled = "0";
   } else {
-    this->Enabled = "";
+    this->Enabled.clear();
   }
 
   // Username
   if (const char* username = this->GetOption(prefix + "USERNAME")) {
     this->Username = username;
   } else {
-    this->Username = "";
+    this->Username.clear();
   }
 
   // Password
   if (const char* password = this->GetOption(prefix + "PASSWORD")) {
     this->Password = password;
   } else {
-    this->Password = "";
+    this->Password.clear();
   }
 
   // DisplayName
   if (const char* displayName = this->GetOption(prefix + "DISPLAY_NAME")) {
     this->DisplayName = displayName;
   } else {
-    this->DisplayName = "";
+    this->DisplayName.clear();
   }
 
   return this->IsValid();
@@ -128,7 +128,7 @@
   bool patched;
 
 protected:
-  void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
+  void StartElement(const std::string& name, const char** atts) override
   {
     this->xout.StartElement(name);
     this->StartFragment(atts);
@@ -143,7 +143,7 @@
     }
   }
 
-  void EndElement(const std::string& name) CM_OVERRIDE
+  void EndElement(const std::string& name) override
   {
     if (name == "Updates" && !this->patched) {
       this->repository->WriteRepositoryUpdates(this->xout);
@@ -159,10 +159,10 @@
     }
   }
 
-  void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
+  void CharacterDataHandler(const char* data, int length) override
   {
     std::string content(data, data + length);
-    if (content == "" || content == " " || content == "  " ||
+    if (content.empty() || content == " " || content == "  " ||
         content == "\n") {
       return;
     }
@@ -279,9 +279,8 @@
 {
   if (!this->RepositoryUpdate.empty()) {
     xout.StartElement("RepositoryUpdate");
-    for (RepositoriesVector::iterator rit = this->RepositoryUpdate.begin();
-         rit != this->RepositoryUpdate.end(); ++rit) {
-      (*rit)->WriteRepositoryUpdate(xout);
+    for (cmCPackIFWRepository* r : this->RepositoryUpdate) {
+      r->WriteRepositoryUpdate(xout);
     }
     xout.EndElement();
   }
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/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 274dfd0..ba07d08 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -89,9 +89,8 @@
   command << " -arch " << GetArchitecture();
   command << " -out " << QuotePath(objectFile);
 
-  for (extension_set_t::const_iterator i = CandleExtensions.begin();
-       i != CandleExtensions.end(); ++i) {
-    command << " -ext " << QuotePath(*i);
+  for (std::string const& ext : CandleExtensions) {
+    command << " -ext " << QuotePath(ext);
   }
 
   AddCustomFlags("CPACK_WIX_CANDLE_EXTRA_FLAGS", command);
@@ -113,9 +112,8 @@
   command << " -nologo";
   command << " -out " << QuotePath(packageFileNames.at(0));
 
-  for (extension_set_t::const_iterator i = this->LightExtensions.begin();
-       i != this->LightExtensions.end(); ++i) {
-    command << " -ext " << QuotePath(*i);
+  for (std::string const& ext : this->LightExtensions) {
+    command << " -ext " << QuotePath(ext);
   }
 
   const char* const cultures = GetOption("CPACK_WIX_CULTURES");
@@ -219,8 +217,8 @@
     std::vector<std::string> patchFilePaths;
     cmSystemTools::ExpandListArgument(patchFilePath, patchFilePaths);
 
-    for (size_t i = 0; i < patchFilePaths.size(); ++i) {
-      if (!this->Patch->LoadFragments(patchFilePaths[i])) {
+    for (std::string const& p : patchFilePaths) {
+      if (!this->Patch->LoadFragments(p)) {
         return false;
       }
     }
@@ -254,9 +252,7 @@
   std::set<std::string> usedBaseNames;
 
   std::ostringstream objectFiles;
-  for (size_t i = 0; i < this->WixSources.size(); ++i) {
-    std::string const& sourceFilename = this->WixSources[i];
-
+  for (std::string const& sourceFilename : this->WixSources) {
     std::string baseName =
       cmSystemTools::GetFilenameWithoutLastExtension(sourceFilename);
 
@@ -306,8 +302,8 @@
   cmSystemTools::ExpandListArgument(cpackWixExtraObjects,
                                     expandedExtraObjects);
 
-  for (size_t i = 0; i < expandedExtraObjects.size(); ++i) {
-    stream << " " << QuotePath(expandedExtraObjects[i]);
+  for (std::string const& obj : expandedExtraObjects) {
+    stream << " " << QuotePath(obj);
   }
 }
 
@@ -345,9 +341,7 @@
   std::string prefix = "CPACK_WIX_PROPERTY_";
   std::vector<std::string> options = GetOptions();
 
-  for (size_t i = 0; i < options.size(); ++i) {
-    std::string const& name = options[i];
-
+  for (std::string const& name : options) {
     if (name.length() > prefix.length() &&
         name.substr(0, prefix.length()) == prefix) {
       std::string id = name.substr(prefix.length());
@@ -503,16 +497,14 @@
 
     globalShortcuts.AddShortcutTypes(emittedShortcutTypes);
   } else {
-    for (std::map<std::string, cmCPackComponent>::const_iterator i =
-           this->Components.begin();
-         i != this->Components.end(); ++i) {
-      cmCPackComponent const& component = i->second;
+    for (auto const& i : this->Components) {
+      cmCPackComponent const& component = i.second;
 
       std::string componentPath = toplevel;
       componentPath += "/";
       componentPath += component.Name;
 
-      std::string componentFeatureId = "CM_C_" + component.Name;
+      std::string const componentFeatureId = "CM_C_" + component.Name;
 
       cmWIXShortcuts featureShortcuts;
       AddComponentsToFeature(componentPath, componentFeatureId,
@@ -623,19 +615,15 @@
 bool cmCPackWIXGenerator::CreateFeatureHierarchy(
   cmWIXFeaturesSourceWriter& featureDefinitions)
 {
-  for (std::map<std::string, cmCPackComponentGroup>::const_iterator i =
-         ComponentGroups.begin();
-       i != ComponentGroups.end(); ++i) {
-    cmCPackComponentGroup const& group = i->second;
+  for (auto const& i : ComponentGroups) {
+    cmCPackComponentGroup const& group = i.second;
     if (group.ParentGroup == 0) {
       featureDefinitions.EmitFeatureForComponentGroup(group, *this->Patch);
     }
   }
 
-  for (std::map<std::string, cmCPackComponent>::const_iterator i =
-         this->Components.begin();
-       i != this->Components.end(); ++i) {
-    cmCPackComponent const& component = i->second;
+  for (auto const& i : this->Components) {
+    cmCPackComponent const& component = i.second;
 
     if (!component.Group) {
       featureDefinitions.EmitFeatureForComponent(component, *this->Patch);
@@ -1135,9 +1123,8 @@
   std::vector<std::string> list;
   cmSystemTools::ExpandListArgument(variableContent, list);
 
-  for (std::vector<std::string>::const_iterator i = list.begin();
-       i != list.end(); ++i) {
-    stream << " " << QuotePath(*i);
+  for (std::string const& i : list) {
+    stream << " " << QuotePath(i);
   }
 }
 
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 744a932..1603bf8 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -20,8 +20,8 @@
   std::vector<std::string> entries;
   this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL", entries);
 
-  for (size_t i = 0; i < entries.size(); ++i) {
-    this->CreatePermissionElement(entries[i]);
+  for (std::string const& entry : entries) {
+    this->CreatePermissionElement(entry);
   }
 
   return true;
@@ -56,9 +56,9 @@
   if (!domain.empty()) {
     this->SourceWriter.AddAttribute("Domain", domain);
   }
-  for (size_t i = 0; i < permissions.size(); ++i) {
+  for (std::string const& permission : permissions) {
     this->EmitBooleanAttribute(entry,
-                               cmSystemTools::TrimWhitespace(permissions[i]));
+                               cmSystemTools::TrimWhitespace(permission));
   }
   this->SourceWriter.EndElement("Permission");
 }
diff --git a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
index 0be4377..a7a0648 100644
--- a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
@@ -46,16 +46,12 @@
 
   patch.ApplyFragment("CM_G_" + group.Name, *this);
 
-  for (std::vector<cmCPackComponentGroup*>::const_iterator i =
-         group.Subgroups.begin();
-       i != group.Subgroups.end(); ++i) {
-    EmitFeatureForComponentGroup(**i, patch);
+  for (cmCPackComponentGroup* subgroup : group.Subgroups) {
+    EmitFeatureForComponentGroup(*subgroup, patch);
   }
 
-  for (std::vector<cmCPackComponent*>::const_iterator i =
-         group.Components.begin();
-       i != group.Components.end(); ++i) {
-    EmitFeatureForComponent(**i, patch);
+  for (cmCPackComponent* component : group.Components) {
+    EmitFeatureForComponent(*component, patch);
   }
 
   EndElement("Feature");
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index 287a644..dec95fb 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -29,10 +29,8 @@
     return;
 
   const cmWIXPatchElement& fragment = i->second;
-  for (cmWIXPatchElement::attributes_t::const_iterator attr_i =
-         fragment.attributes.begin();
-       attr_i != fragment.attributes.end(); ++attr_i) {
-    writer.AddAttribute(attr_i->first, attr_i->second);
+  for (auto const& attr : fragment.attributes) {
+    writer.AddAttribute(attr.first, attr.second);
   }
   this->ApplyElementChildren(fragment, writer);
 
@@ -42,11 +40,7 @@
 void cmWIXPatch::ApplyElementChildren(const cmWIXPatchElement& element,
                                       cmWIXSourceWriter& writer)
 {
-  for (cmWIXPatchElement::child_list_t::const_iterator j =
-         element.children.begin();
-       j != element.children.end(); ++j) {
-    cmWIXPatchNode* node = *j;
-
+  for (cmWIXPatchNode* node : element.children) {
     switch (node->type()) {
       case cmWIXPatchNode::ELEMENT:
         ApplyElement(dynamic_cast<const cmWIXPatchElement&>(*node), writer);
@@ -63,10 +57,8 @@
 {
   writer.BeginElement(element.name);
 
-  for (cmWIXPatchElement::attributes_t::const_iterator i =
-         element.attributes.begin();
-       i != element.attributes.end(); ++i) {
-    writer.AddAttribute(i->first, i->second);
+  for (auto const& attr : element.attributes) {
+    writer.AddAttribute(attr.first, attr.second);
   }
 
   this->ApplyElementChildren(element, writer);
@@ -77,14 +69,13 @@
 bool cmWIXPatch::CheckForUnappliedFragments()
 {
   std::string fragmentList;
-  for (cmWIXPatchParser::fragment_map_t::const_iterator i = Fragments.begin();
-       i != Fragments.end(); ++i) {
+  for (auto const& fragment : Fragments) {
     if (!fragmentList.empty()) {
       fragmentList += ", ";
     }
 
     fragmentList += "'";
-    fragmentList += i->first;
+    fragmentList += fragment.first;
     fragmentList += "'";
   }
 
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx
index b050b85..e6aeed3 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.cxx
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -22,8 +22,8 @@
 
 cmWIXPatchElement::~cmWIXPatchElement()
 {
-  for (child_list_t::iterator i = children.begin(); i != children.end(); ++i) {
-    delete *i;
+  for (cmWIXPatchNode* child : children) {
+    delete child;
   }
 }
 
diff --git a/Source/CPack/WiX/cmWIXShortcut.cxx b/Source/CPack/WiX/cmWIXShortcut.cxx
index e5dea94..cd1988a 100644
--- a/Source/CPack/WiX/cmWIXShortcut.cxx
+++ b/Source/CPack/WiX/cmWIXShortcut.cxx
@@ -47,10 +47,9 @@
       return false;
   }
 
-  for (shortcut_id_map_t::const_iterator j = id_map.begin(); j != id_map.end();
-       ++j) {
-    std::string const& id = j->first;
-    shortcut_list_t const& shortcutList = j->second;
+  for (auto const& j : id_map) {
+    std::string const& id = j.first;
+    shortcut_list_t const& shortcutList = j.second;
 
     for (size_t shortcutListIndex = 0; shortcutListIndex < shortcutList.size();
          ++shortcutListIndex) {
@@ -68,9 +67,8 @@
 
 void cmWIXShortcuts::AddShortcutTypes(std::set<Type>& types)
 {
-  for (shortcut_type_map_t::const_iterator i = this->Shortcuts.begin();
-       i != this->Shortcuts.end(); ++i) {
-    types.insert(i->first);
+  for (auto const& shortcut : this->Shortcuts) {
+    types.insert(shortcut.first);
   }
 }
 
@@ -96,9 +94,9 @@
   std::vector<std::string> list;
   installedFile.GetPropertyAsList(propertyName, list);
 
-  for (size_t i = 0; i < list.size(); ++i) {
+  for (std::string const& label : list) {
     cmWIXShortcut shortcut;
-    shortcut.label = list[i];
+    shortcut.label = label;
     shortcut.workingDirectoryId = directoryId;
     insert(type, id, shortcut);
   }
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index a86e28d..dc730e0 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -158,9 +158,7 @@
   std::string result;
   result.reserve(value.size());
 
-  char c = 0;
-  for (size_t i = 0; i < value.size(); ++i) {
-    c = value[i];
+  for (char c : value) {
     switch (c) {
       case '<':
         result += "&lt;";
diff --git a/Source/CPack/cmCPack7zGenerator.h b/Source/CPack/cmCPack7zGenerator.h
index 31c02a4..8af4c4a 100644
--- a/Source/CPack/cmCPack7zGenerator.h
+++ b/Source/CPack/cmCPack7zGenerator.h
@@ -20,10 +20,10 @@
    * Construct generator
    */
   cmCPack7zGenerator();
-  ~cmCPack7zGenerator() CM_OVERRIDE;
+  ~cmCPack7zGenerator() override;
 
 protected:
-  const char* GetOutputExtension() CM_OVERRIDE { return ".7z"; }
+  const char* GetOutputExtension() override { return ".7z"; }
 };
 
 #endif
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 1e45b48..641be38 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -9,7 +9,6 @@
 #include "cmSystemTools.h"
 #include "cmWorkingDirectory.h"
 
-#include <map>
 #include <ostream>
 #include <utility>
 #include <vector>
@@ -74,10 +73,8 @@
     filePrefix += installPrefix + 1;
     filePrefix += "/";
   }
-  std::vector<std::string>::const_iterator fileIt;
-  for (fileIt = component->Files.begin(); fileIt != component->Files.end();
-       ++fileIt) {
-    std::string rp = filePrefix + *fileIt;
+  for (std::string const& file : component->Files) {
+    std::string rp = filePrefix + file;
     cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file: " << rp << std::endl);
     archive.Add(rp, 0, nullptr, false);
     if (!archive) {
@@ -117,53 +114,47 @@
   // The default behavior is to have one package by component group
   // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
   if (!ignoreGroup) {
-    std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
-    for (compGIt = this->ComponentGroups.begin();
-         compGIt != this->ComponentGroups.end(); ++compGIt) {
-      cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
-                      << compGIt->first << std::endl);
+    for (auto const& compG : this->ComponentGroups) {
+      cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+                    "Packaging component group: " << compG.first << std::endl);
       // Begin the archive for this group
       std::string packageFileName = std::string(toplevel) + "/" +
-        this->GetArchiveComponentFileName(compGIt->first, true);
+        this->GetArchiveComponentFileName(compG.first, true);
 
       // open a block in order to automatically close archive
       // at the end of the block
       {
         DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
         // now iterate over the component of this group
-        std::vector<cmCPackComponent*>::iterator compIt;
-        for (compIt = (compGIt->second).Components.begin();
-             compIt != (compGIt->second).Components.end(); ++compIt) {
+        for (cmCPackComponent* comp : (compG.second).Components) {
           // Add the files of this component to the archive
-          addOneComponentToArchive(archive, *compIt);
+          addOneComponentToArchive(archive, comp);
         }
       }
       // add the generated package to package file names list
       packageFileNames.push_back(packageFileName);
     }
     // Handle Orphan components (components not belonging to any groups)
-    std::map<std::string, cmCPackComponent>::iterator compIt;
-    for (compIt = this->Components.begin(); compIt != this->Components.end();
-         ++compIt) {
+    for (auto& comp : this->Components) {
       // Does the component belong to a group?
-      if (compIt->second.Group == nullptr) {
+      if (comp.second.Group == nullptr) {
         cmCPackLogger(
           cmCPackLog::LOG_VERBOSE, "Component <"
-            << compIt->second.Name
+            << comp.second.Name
             << "> does not belong to any group, package it separately."
             << std::endl);
         std::string localToplevel(
           this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
         std::string packageFileName = std::string(toplevel);
 
-        localToplevel += "/" + compIt->first;
+        localToplevel += "/" + comp.first;
         packageFileName +=
-          "/" + this->GetArchiveComponentFileName(compIt->first, false);
+          "/" + this->GetArchiveComponentFileName(comp.first, false);
 
         {
           DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
           // Add the files of this component to the archive
-          addOneComponentToArchive(archive, &(compIt->second));
+          addOneComponentToArchive(archive, &(comp.second));
         }
         // add the generated package to package file names list
         packageFileNames.push_back(packageFileName);
@@ -173,20 +164,18 @@
   // CPACK_COMPONENTS_IGNORE_GROUPS is set
   // We build 1 package per component
   else {
-    std::map<std::string, cmCPackComponent>::iterator compIt;
-    for (compIt = this->Components.begin(); compIt != this->Components.end();
-         ++compIt) {
+    for (auto& comp : this->Components) {
       std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
       std::string packageFileName = std::string(toplevel);
 
-      localToplevel += "/" + compIt->first;
+      localToplevel += "/" + comp.first;
       packageFileName +=
-        "/" + this->GetArchiveComponentFileName(compIt->first, false);
+        "/" + this->GetArchiveComponentFileName(comp.first, false);
 
       {
         DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
         // Add the files of this component to the archive
-        addOneComponentToArchive(archive, &(compIt->second));
+        addOneComponentToArchive(archive, &(comp.second));
       }
       // add the generated package to package file names list
       packageFileNames.push_back(packageFileName);
@@ -217,11 +206,9 @@
   DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);
 
   // The ALL COMPONENTS in ONE package case
-  std::map<std::string, cmCPackComponent>::iterator compIt;
-  for (compIt = this->Components.begin(); compIt != this->Components.end();
-       ++compIt) {
+  for (auto& comp : this->Components) {
     // Add the files of this component to the archive
-    addOneComponentToArchive(archive, &(compIt->second));
+    addOneComponentToArchive(archive, &(comp.second));
   }
 
   // archive goes out of scope so it will finalized and closed.
@@ -249,16 +236,15 @@
 
   // CASE 3 : NON COMPONENT package.
   DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);
-  std::vector<std::string>::const_iterator fileIt;
   cmWorkingDirectory workdir(toplevel);
-  for (fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
+  for (std::string const& file : files) {
     // Get the relative path to the file
     std::string rp =
-      cmSystemTools::RelativePath(toplevel.c_str(), fileIt->c_str());
+      cmSystemTools::RelativePath(toplevel.c_str(), file.c_str());
     archive.Add(rp, 0, nullptr, false);
     if (!archive) {
       cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem while adding file< "
-                      << *fileIt << "> to archive <" << packageFileNames[0]
+                      << file << "> to archive <" << packageFileNames[0]
                       << "> .ERROR =" << archive.GetError() << std::endl);
       return 0;
     }
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
index 72ba1b2..9983854 100644
--- a/Source/CPack/cmCPackArchiveGenerator.h
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -28,11 +28,11 @@
    * Construct generator
    */
   cmCPackArchiveGenerator(cmArchiveWrite::Compress, std::string const& format);
-  ~cmCPackArchiveGenerator() CM_OVERRIDE;
+  ~cmCPackArchiveGenerator() override;
   // Used to add a header to the archive
   virtual int GenerateHeader(std::ostream* os);
   // component support
-  bool SupportsComponentInstallation() const CM_OVERRIDE;
+  bool SupportsComponentInstallation() const override;
 
 private:
   // get archive component filename
@@ -40,7 +40,7 @@
                                           bool isGroupName);
 
 protected:
-  int InitializeInternal() CM_OVERRIDE;
+  int InitializeInternal() override;
   /**
    * Add the files belonging to the specified component
    * to the provided (already opened) archive.
@@ -56,7 +56,7 @@
    * method will call either PackageComponents or
    * PackageComponentsAllInOne.
    */
-  int PackageFiles() CM_OVERRIDE;
+  int PackageFiles() override;
   /**
    * The method used to package files when component
    * install is used. This will create one
@@ -68,7 +68,7 @@
    * components will be put in a single installer.
    */
   int PackageComponentsAllInOne();
-  const char* GetOutputExtension() CM_OVERRIDE = 0;
+  const char* GetOutputExtension() override = 0;
   cmArchiveWrite::Compress Compress;
   std::string ArchiveFormat;
 };
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/cmCPackBundleGenerator.h b/Source/CPack/cmCPackBundleGenerator.h
index e99bf43..27bac3a 100644
--- a/Source/CPack/cmCPackBundleGenerator.h
+++ b/Source/CPack/cmCPackBundleGenerator.h
@@ -21,15 +21,15 @@
   cmCPackTypeMacro(cmCPackBundleGenerator, cmCPackDragNDropGenerator);
 
   cmCPackBundleGenerator();
-  ~cmCPackBundleGenerator() CM_OVERRIDE;
+  ~cmCPackBundleGenerator() override;
 
 protected:
-  int InitializeInternal() CM_OVERRIDE;
-  const char* GetPackagingInstallPrefix() CM_OVERRIDE;
+  int InitializeInternal() override;
+  const char* GetPackagingInstallPrefix() override;
   int ConstructBundle();
   int SignBundle(const std::string& src_dir);
-  int PackageFiles() CM_OVERRIDE;
-  bool SupportsComponentInstallation() const CM_OVERRIDE;
+  int PackageFiles() override;
+  bool SupportsComponentInstallation() const override;
 
   std::string InstallPrefix;
 };
diff --git a/Source/CPack/cmCPackComponentGroup.cxx b/Source/CPack/cmCPackComponentGroup.cxx
index e39398a..f888a5f 100644
--- a/Source/CPack/cmCPackComponentGroup.cxx
+++ b/Source/CPack/cmCPackComponentGroup.cxx
@@ -5,7 +5,6 @@
 #include "cmSystemTools.h"
 
 #include <string>
-#include <vector>
 
 unsigned long cmCPackComponent::GetInstalledSize(
   const std::string& installDir) const
@@ -14,11 +13,10 @@
     return this->TotalSize;
   }
 
-  std::vector<std::string>::const_iterator fileIt;
-  for (fileIt = this->Files.begin(); fileIt != this->Files.end(); ++fileIt) {
+  for (std::string const& file : this->Files) {
     std::string path = installDir;
     path += '/';
-    path += *fileIt;
+    path += file;
     this->TotalSize += cmSystemTools::FileLength(path);
   }
 
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.h b/Source/CPack/cmCPackCygwinBinaryGenerator.h
index b5a0531..f87a134 100644
--- a/Source/CPack/cmCPackCygwinBinaryGenerator.h
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.h
@@ -17,7 +17,7 @@
    * Construct generator
    */
   cmCPackCygwinBinaryGenerator();
-  ~cmCPackCygwinBinaryGenerator() CM_OVERRIDE;
+  ~cmCPackCygwinBinaryGenerator() override;
 
 protected:
   virtual int InitializeInternal();
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.h b/Source/CPack/cmCPackCygwinSourceGenerator.h
index d19f87c..a909b15 100644
--- a/Source/CPack/cmCPackCygwinSourceGenerator.h
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.h
@@ -17,7 +17,7 @@
    * Construct generator
    */
   cmCPackCygwinSourceGenerator();
-  ~cmCPackCygwinSourceGenerator() CM_OVERRIDE;
+  ~cmCPackCygwinSourceGenerator() override;
 
 protected:
   const char* GetPackagingInstallPrefix();
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 18d559e..7fc3c26 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -12,7 +12,6 @@
 #include "cm_sys_stat.h"
 
 #include "cmsys/Glob.hxx"
-#include <map>
 #include <ostream>
 #include <set>
 #include <string.h>
@@ -105,37 +104,31 @@
   // The default behavior is to have one package by component group
   // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
   if (!ignoreGroup) {
-    std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
-    for (compGIt = this->ComponentGroups.begin();
-         compGIt != this->ComponentGroups.end(); ++compGIt) {
-      cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
-                      << compGIt->first << std::endl);
+    for (auto const& compG : this->ComponentGroups) {
+      cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+                    "Packaging component group: " << compG.first << std::endl);
       // Begin the archive for this group
-      retval &= PackageOnePack(initialTopLevel, compGIt->first);
+      retval &= PackageOnePack(initialTopLevel, compG.first);
     }
     // Handle Orphan components (components not belonging to any groups)
-    std::map<std::string, cmCPackComponent>::iterator compIt;
-    for (compIt = this->Components.begin(); compIt != this->Components.end();
-         ++compIt) {
+    for (auto const& comp : this->Components) {
       // Does the component belong to a group?
-      if (compIt->second.Group == nullptr) {
+      if (comp.second.Group == nullptr) {
         cmCPackLogger(
           cmCPackLog::LOG_VERBOSE, "Component <"
-            << compIt->second.Name
+            << comp.second.Name
             << "> does not belong to any group, package it separately."
             << std::endl);
         // Begin the archive for this orphan component
-        retval &= PackageOnePack(initialTopLevel, compIt->first);
+        retval &= PackageOnePack(initialTopLevel, comp.first);
       }
     }
   }
   // CPACK_COMPONENTS_IGNORE_GROUPS is set
   // We build 1 package per component
   else {
-    std::map<std::string, cmCPackComponent>::iterator compIt;
-    for (compIt = this->Components.begin(); compIt != this->Components.end();
-         ++compIt) {
-      retval &= PackageOnePack(initialTopLevel, compIt->first);
+    for (auto const& comp : this->Components) {
+      retval &= PackageOnePack(initialTopLevel, comp.first);
     }
   }
   return retval;
@@ -336,10 +329,8 @@
     {
       std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
       dirName += '/';
-      for (std::vector<std::string>::const_iterator fileIt =
-             packageFiles.begin();
-           fileIt != packageFiles.end(); ++fileIt) {
-        totalSize += cmSystemTools::FileLength(*fileIt);
+      for (std::string const& file : packageFiles) {
+        totalSize += cmSystemTools::FileLength(file);
       }
     }
     out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n";
@@ -400,7 +391,7 @@
     compression_suffix = ".gz";
     tar_compression_type = cmArchiveWrite::CompressGZip;
   } else if (!strcmp(debian_compression_type, "none")) {
-    compression_suffix = "";
+    compression_suffix.clear();
     tar_compression_type = cmArchiveWrite::CompressNone;
   } else {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -446,10 +437,7 @@
 
     // we have to reconstruct the parent folders as well
 
-    for (std::vector<std::string>::const_iterator fileIt =
-           packageFiles.begin();
-         fileIt != packageFiles.end(); ++fileIt) {
-      std::string currentPath = *fileIt;
+    for (std::string currentPath : packageFiles) {
       while (currentPath != strGenWDIR) {
         // the last one IS strGenWDIR, but we do not want this one:
         // XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application
@@ -459,18 +447,17 @@
       }
     }
 
-    for (std::set<std::string>::const_iterator fileIt = orderedFiles.begin();
-         fileIt != orderedFiles.end(); ++fileIt) {
-      cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
+    for (std::string const& file : orderedFiles) {
+      cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << file << "\""
                                                         << std::endl);
-      std::string::size_type slashPos = fileIt->find('/', topLevelLength + 1);
+      std::string::size_type slashPos = file.find('/', topLevelLength + 1);
       std::string relativeDir =
-        fileIt->substr(topLevelLength, slashPos - topLevelLength);
+        file.substr(topLevelLength, slashPos - topLevelLength);
       cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \""
                       << relativeDir << "\"" << std::endl);
 
 #ifdef WIN32
-      std::string mode_t_adt_filename = *fileIt + ":cmake_mode_t";
+      std::string mode_t_adt_filename = file + ":cmake_mode_t";
       cmsys::ifstream permissionStream(mode_t_adt_filename.c_str());
 
       mode_t permissions = 0;
@@ -481,7 +468,7 @@
 
       if (permissions != 0) {
         data_tar.SetPermissions(permissions);
-      } else if (cmSystemTools::FileIsDirectory(*fileIt)) {
+      } else if (cmSystemTools::FileIsDirectory(file)) {
         data_tar.SetPermissions(0755);
       } else {
         data_tar.ClearPermissions();
@@ -489,11 +476,11 @@
 #endif
 
       // do not recurse because the loop will do it
-      if (!data_tar.Add(*fileIt, topLevelLength, ".", false)) {
+      if (!data_tar.Add(file, topLevelLength, ".", false)) {
         cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem adding file to tar:"
                         << std::endl
                         << "#top level directory: " << strGenWDIR << std::endl
-                        << "#file: " << *fileIt << std::endl
+                        << "#file: " << file << std::endl
                         << "#error:" << data_tar.GetError() << std::endl);
         return 0;
       }
@@ -508,23 +495,21 @@
     std::string topLevelWithTrailingSlash =
       this->GetOption("CPACK_TEMPORARY_DIRECTORY");
     topLevelWithTrailingSlash += '/';
-    for (std::vector<std::string>::const_iterator fileIt =
-           packageFiles.begin();
-         fileIt != packageFiles.end(); ++fileIt) {
+    for (std::string const& file : packageFiles) {
       // hash only regular files
-      if (cmSystemTools::FileIsDirectory(*fileIt) ||
-          cmSystemTools::FileIsSymlink(*fileIt)) {
+      if (cmSystemTools::FileIsDirectory(file) ||
+          cmSystemTools::FileIsSymlink(file)) {
         continue;
       }
 
       std::string output =
-        cmSystemTools::ComputeFileHash(*fileIt, cmCryptoHash::AlgoMD5);
+        cmSystemTools::ComputeFileHash(file, cmCryptoHash::AlgoMD5);
       if (output.empty()) {
         cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem computing the md5 of "
-                        << *fileIt << std::endl);
+                        << file << std::endl);
       }
 
-      output += "  " + *fileIt + "\n";
+      output += "  " + file + "\n";
       // debian md5sums entries are like this:
       // 014f3604694729f3bf19263bac599765  usr/bin/ccmake
       // thus strip the full path (with the trailing slash)
@@ -641,9 +626,8 @@
 
       std::vector<std::string> controlExtraList;
       cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
-      for (std::vector<std::string>::iterator i = controlExtraList.begin();
-           i != controlExtraList.end(); ++i) {
-        std::string filenamename = cmsys::SystemTools::GetFilenameName(*i);
+      for (std::string const& i : controlExtraList) {
+        std::string filenamename = cmsys::SystemTools::GetFilenameName(i);
         std::string localcopy = strGenWDIR + "/" + filenamename;
 
         if (permissionStrictPolicy) {
@@ -653,7 +637,7 @@
         }
 
         // if we can copy the file, it means it does exist, let's add it:
-        if (cmsys::SystemTools::CopyFileIfDifferent(*i, localcopy)) {
+        if (cmsys::SystemTools::CopyFileIfDifferent(i, localcopy)) {
           control_tar.Add(localcopy, strGenWDIR.length(), ".");
         }
       }
diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h
index 21fc3be..b4f0c79 100644
--- a/Source/CPack/cmCPackDebGenerator.h
+++ b/Source/CPack/cmCPackDebGenerator.h
@@ -23,7 +23,7 @@
    * Construct generator
    */
   cmCPackDebGenerator();
-  ~cmCPackDebGenerator() CM_OVERRIDE;
+  ~cmCPackDebGenerator() override;
 
   static bool CanGenerate()
   {
@@ -40,7 +40,7 @@
   }
 
 protected:
-  int InitializeInternal() CM_OVERRIDE;
+  int InitializeInternal() override;
   /**
    * This method factors out the work done in component packaging case.
    */
@@ -57,11 +57,11 @@
    * components will be put in a single installer.
    */
   int PackageComponentsAllInOne(const std::string& compInstDirName);
-  int PackageFiles() CM_OVERRIDE;
-  const char* GetOutputExtension() CM_OVERRIDE { return ".deb"; }
-  bool SupportsComponentInstallation() const CM_OVERRIDE;
+  int PackageFiles() override;
+  const char* GetOutputExtension() override { return ".deb"; }
+  bool SupportsComponentInstallation() const override;
   std::string GetComponentInstallDirNameSuffix(
-    const std::string& componentName) CM_OVERRIDE;
+    const std::string& componentName) override;
 
 private:
   int createDeb();
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/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index 4606c3c..8565c68 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -23,20 +23,20 @@
   cmCPackTypeMacro(cmCPackDragNDropGenerator, cmCPackGenerator);
 
   cmCPackDragNDropGenerator();
-  ~cmCPackDragNDropGenerator() CM_OVERRIDE;
+  ~cmCPackDragNDropGenerator() override;
 
 protected:
-  int InitializeInternal() CM_OVERRIDE;
-  const char* GetOutputExtension() CM_OVERRIDE;
-  int PackageFiles() CM_OVERRIDE;
-  bool SupportsComponentInstallation() const CM_OVERRIDE;
+  int InitializeInternal() override;
+  const char* GetOutputExtension() override;
+  int PackageFiles() override;
+  bool SupportsComponentInstallation() const override;
 
   bool CopyFile(std::ostringstream& source, std::ostringstream& target);
   bool CreateEmptyFile(std::ostringstream& target, size_t size);
   bool RunCommand(std::ostringstream& command, std::string* output = 0);
 
   std::string GetComponentInstallDirNameSuffix(
-    const std::string& componentName) CM_OVERRIDE;
+    const std::string& componentName) override;
 
   int CreateDMG(const std::string& src_dir, const std::string& output_file);
 
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index ae17b79..91ae1a2 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -122,7 +122,7 @@
   {
   }
 
-  void write_value(cmGeneratedFileStream& s) const CM_OVERRIDE
+  void write_value(cmGeneratedFileStream& s) const override
   {
     s << EscapeQuotes(value);
   }
@@ -154,7 +154,7 @@
     return *this;
   }
 
-  void write_value(cmGeneratedFileStream& s) const CM_OVERRIDE
+  void write_value(cmGeneratedFileStream& s) const override
   {
     bool with_comma = false;
 
@@ -179,7 +179,7 @@
   {
   }
 
-  void write_value(cmGeneratedFileStream& s) const CM_OVERRIDE
+  void write_value(cmGeneratedFileStream& s) const override
   {
     s << "{\n";
     for (VList::const_iterator it = value.begin(); it != value.end(); ++it) {
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.h b/Source/CPack/cmCPackFreeBSDGenerator.h
index 230f728..99d2e24 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.h
+++ b/Source/CPack/cmCPackFreeBSDGenerator.h
@@ -22,13 +22,13 @@
    * Construct generator
    */
   cmCPackFreeBSDGenerator();
-  ~cmCPackFreeBSDGenerator() CM_OVERRIDE;
+  ~cmCPackFreeBSDGenerator() override;
 
-  int InitializeInternal() CM_OVERRIDE;
-  int PackageFiles() CM_OVERRIDE;
+  int InitializeInternal() override;
+  int PackageFiles() override;
 
 protected:
-  const char* GetOutputExtension() CM_OVERRIDE { return ".txz"; }
+  const char* GetOutputExtension() override { return ".txz"; }
 
   std::string var_lookup(const char* var_name);
   void write_manifest_fields(cmGeneratedFileStream&);
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 44c7915..f56b5fa 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -248,25 +248,23 @@
     cmSystemTools::PutEnv(tempInstallDirectoryEnv);
     std::vector<std::string> installCommandsVector;
     cmSystemTools::ExpandListArgument(installCommands, installCommandsVector);
-    std::vector<std::string>::iterator it;
-    for (it = installCommandsVector.begin(); it != installCommandsVector.end();
-         ++it) {
-      cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << *it << std::endl);
+    for (std::string const& ic : installCommandsVector) {
+      cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ic << std::endl);
       std::string output;
       int retVal = 1;
       bool resB =
-        cmSystemTools::RunSingleCommand(it->c_str(), &output, &output, &retVal,
+        cmSystemTools::RunSingleCommand(ic.c_str(), &output, &output, &retVal,
                                         nullptr, this->GeneratorVerbose, 0);
       if (!resB || retVal) {
         std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
         tmpFile += "/InstallOutput.log";
         cmGeneratedFileStream ofs(tmpFile.c_str());
-        ofs << "# Run command: " << *it << std::endl
+        ofs << "# Run command: " << ic << std::endl
             << "# Output:" << std::endl
             << output << std::endl;
         cmCPackLogger(
           cmCPackLog::LOG_ERROR, "Problem running install command: "
-            << *it << std::endl
+            << ic << std::endl
             << "Please check " << tmpFile << " for errors" << std::endl);
         return 0;
       }
@@ -286,12 +284,10 @@
     std::vector<std::string> ignoreFilesRegexString;
     cmSystemTools::ExpandListArgument(cpackIgnoreFiles,
                                       ignoreFilesRegexString);
-    std::vector<std::string>::iterator it;
-    for (it = ignoreFilesRegexString.begin();
-         it != ignoreFilesRegexString.end(); ++it) {
+    for (std::string const& ifr : ignoreFilesRegexString) {
       cmCPackLogger(cmCPackLog::LOG_VERBOSE,
-                    "Create ignore files regex for: " << *it << std::endl);
-      ignoreFilesRegex.push_back(it->c_str());
+                    "Create ignore files regex for: " << ifr << std::endl);
+      ignoreFilesRegex.push_back(ifr.c_str());
     }
   }
   const char* installDirectories =
@@ -334,15 +330,14 @@
       files = gl.GetFiles();
       std::vector<std::string>::iterator gfit;
       std::vector<cmsys::RegularExpression>::iterator regIt;
-      for (gfit = files.begin(); gfit != files.end(); ++gfit) {
+      for (std::string const& gf : files) {
         bool skip = false;
-        std::string inFile = *gfit;
-        if (cmSystemTools::FileIsDirectory(*gfit)) {
+        std::string inFile = gf;
+        if (cmSystemTools::FileIsDirectory(gf)) {
           inFile += '/';
         }
-        for (regIt = ignoreFilesRegex.begin(); regIt != ignoreFilesRegex.end();
-             ++regIt) {
-          if (regIt->find(inFile.c_str())) {
+        for (cmsys::RegularExpression& reg : ignoreFilesRegex) {
+          if (reg.find(inFile.c_str())) {
             cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                           "Ignore file: " << inFile << std::endl);
             skip = true;
@@ -353,7 +348,7 @@
         }
         std::string filePath = tempDir;
         filePath += "/" + subdir + "/" +
-          cmSystemTools::RelativePath(top.c_str(), gfit->c_str());
+          cmSystemTools::RelativePath(top.c_str(), gf.c_str());
         cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy file: "
                         << inFile << " -> " << filePath << std::endl);
         /* If the file is a symlink we will have to re-create it */
@@ -377,32 +372,30 @@
       }
       /* rebuild symlinks in the installed tree */
       if (!symlinkedFiles.empty()) {
-        std::vector<std::pair<std::string, std::string>>::iterator symlinkedIt;
         std::string curDir = cmSystemTools::GetCurrentWorkingDirectory();
         std::string goToDir = tempDir;
         goToDir += "/" + subdir;
         cmCPackLogger(cmCPackLog::LOG_DEBUG, "Change dir to: " << goToDir
                                                                << std::endl);
         cmWorkingDirectory workdir(goToDir);
-        for (symlinkedIt = symlinkedFiles.begin();
-             symlinkedIt != symlinkedFiles.end(); ++symlinkedIt) {
+        for (auto const& symlinked : symlinkedFiles) {
           cmCPackLogger(cmCPackLog::LOG_DEBUG, "Will create a symlink: "
-                          << symlinkedIt->second << "--> "
-                          << symlinkedIt->first << std::endl);
+                          << symlinked.second << "--> " << symlinked.first
+                          << std::endl);
           // make sure directory exists for symlink
           std::string destDir =
-            cmSystemTools::GetFilenamePath(symlinkedIt->second);
+            cmSystemTools::GetFilenamePath(symlinked.second);
           if (!destDir.empty() && !cmSystemTools::MakeDirectory(destDir)) {
             cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create dir: "
                             << destDir << "\nTrying to create symlink: "
-                            << symlinkedIt->second << "--> "
-                            << symlinkedIt->first << std::endl);
+                            << symlinked.second << "--> " << symlinked.first
+                            << std::endl);
           }
-          if (!cmSystemTools::CreateSymlink(symlinkedIt->first,
-                                            symlinkedIt->second)) {
+          if (!cmSystemTools::CreateSymlink(symlinked.first,
+                                            symlinked.second)) {
             cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create symlink: "
-                            << symlinkedIt->second << "--> "
-                            << symlinkedIt->first << std::endl);
+                            << symlinked.second << "--> " << symlinked.first
+                            << std::endl);
             return 0;
           }
         }
@@ -423,10 +416,7 @@
                                                                 << std::endl);
     std::vector<std::string> cmakeScriptsVector;
     cmSystemTools::ExpandListArgument(cmakeScripts, cmakeScriptsVector);
-    std::vector<std::string>::iterator it;
-    for (it = cmakeScriptsVector.begin(); it != cmakeScriptsVector.end();
-         ++it) {
-      std::string installScript = *it;
+    for (std::string const& installScript : cmakeScriptsVector) {
 
       cmCPackLogger(cmCPackLog::LOG_OUTPUT,
                     "- Install script: " << installScript << std::endl);
@@ -532,10 +522,8 @@
         if (installTypes && *installTypes) {
           std::vector<std::string> installTypesVector;
           cmSystemTools::ExpandListArgument(installTypes, installTypesVector);
-          std::vector<std::string>::iterator installTypeIt;
-          for (installTypeIt = installTypesVector.begin();
-               installTypeIt != installTypesVector.end(); ++installTypeIt) {
-            this->GetInstallationType(installProjectName, *installTypeIt);
+          for (std::string const& installType : installTypesVector) {
+            this->GetInstallationType(installProjectName, installType);
           }
         }
 
@@ -545,10 +533,8 @@
         const char* components = this->GetOption(componentsVar);
         if (components && *components) {
           cmSystemTools::ExpandListArgument(components, componentsVector);
-          std::vector<std::string>::iterator compIt;
-          for (compIt = componentsVector.begin();
-               compIt != componentsVector.end(); ++compIt) {
-            GetComponent(installProjectName, *compIt);
+          for (std::string const& comp : componentsVector) {
+            GetComponent(installProjectName, comp);
           }
           componentInstall = true;
         }
@@ -609,11 +595,9 @@
                     "- Install project: " << installProjectName << std::endl);
 
       // Run the installation for each component
-      std::vector<std::string>::iterator componentIt;
-      for (componentIt = componentsVector.begin();
-           componentIt != componentsVector.end(); ++componentIt) {
+      for (std::string const& component : componentsVector) {
         std::string tempInstallDirectory = baseTempInstallDirectory;
-        installComponent = *componentIt;
+        installComponent = component;
         if (componentInstall) {
           cmCPackLogger(cmCPackLog::LOG_OUTPUT, "-   Install component: "
                           << installComponent << std::endl);
@@ -990,12 +974,11 @@
    */
   cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Copying final package(s) ["
                   << packageFileNames.size() << "]:" << std::endl);
-  std::vector<std::string>::iterator it;
   /* now copy package one by one */
-  for (it = packageFileNames.begin(); it != packageFileNames.end(); ++it) {
+  for (std::string const& pkgFileName : packageFileNames) {
     std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
-    std::string filename(cmSystemTools::GetFilenameName(*it));
-    tempPackageFileName = it->c_str();
+    std::string filename(cmSystemTools::GetFilenameName(pkgFileName));
+    tempPackageFileName = pkgFileName.c_str();
     tmpPF += "/" + filename;
     const char* packageFileName = tmpPF.c_str();
     cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): "
@@ -1016,8 +999,7 @@
     /* Generate checksum file */
     if (crypto.get() != nullptr) {
       std::string hashFile(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
-      hashFile +=
-        "/" + filename.substr(0, filename.rfind(this->GetOutputExtension()));
+      hashFile += "/" + filename;
       hashFile += "." + cmSystemTools::LowerCase(algo);
       cmsys::ofstream outF(hashFile.c_str());
       if (!outF) {
@@ -1419,10 +1401,9 @@
       std::vector<std::string> installTypesVector;
       cmSystemTools::ExpandListArgument(installTypes, installTypesVector);
       std::vector<std::string>::iterator installTypesIt;
-      for (installTypesIt = installTypesVector.begin();
-           installTypesIt != installTypesVector.end(); ++installTypesIt) {
+      for (std::string const& installType : installTypesVector) {
         component->InstallationTypes.push_back(
-          this->GetInstallationType(projectName, *installTypesIt));
+          this->GetInstallationType(projectName, installType));
       }
     }
 
@@ -1432,9 +1413,8 @@
       std::vector<std::string> dependsVector;
       cmSystemTools::ExpandListArgument(depends, dependsVector);
       std::vector<std::string>::iterator dependIt;
-      for (dependIt = dependsVector.begin(); dependIt != dependsVector.end();
-           ++dependIt) {
-        cmCPackComponent* child = GetComponent(projectName, *dependIt);
+      for (std::string const& depend : dependsVector) {
+        cmCPackComponent* child = GetComponent(projectName, depend);
         component->Dependencies.push_back(child);
         child->ReverseDependencies.push_back(component);
       }
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
index 194d4e5..4e3a6e0 100644
--- a/Source/CPack/cmCPackGenerator.h
+++ b/Source/CPack/cmCPackGenerator.h
@@ -299,7 +299,7 @@
 
 #define cmCPackTypeMacro(klass, superclass)                                   \
   typedef superclass Superclass;                                              \
-  const char* GetNameOfClass() CM_OVERRIDE { return #klass; }                 \
+  const char* GetNameOfClass() override { return #klass; }                    \
   static cmCPackGenerator* CreateGenerator() { return new klass; }            \
   class cmCPackTypeMacro_UseTrailingSemicolon
 
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index d04ea13..ddf104c 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -59,11 +59,10 @@
   std::string nsisInstallOptions = nsisFileName + "/NSIS.InstallOptions.ini";
   nsisFileName += "/project.nsi";
   std::ostringstream str;
-  std::vector<std::string>::const_iterator it;
-  for (it = files.begin(); it != files.end(); ++it) {
+  for (std::string const& file : files) {
     std::string outputDir = "$INSTDIR";
     std::string fileN =
-      cmSystemTools::RelativePath(toplevel.c_str(), it->c_str());
+      cmSystemTools::RelativePath(toplevel.c_str(), file.c_str());
     if (!this->Components.empty()) {
       const std::string::size_type pos = fileN.find('/');
 
@@ -87,12 +86,11 @@
   this->SetOptionIfNotSet("CPACK_NSIS_DELETE_FILES", str.str().c_str());
   std::vector<std::string> dirs;
   this->GetListOfSubdirectories(toplevel.c_str(), dirs);
-  std::vector<std::string>::const_iterator sit;
   std::ostringstream dstr;
-  for (sit = dirs.begin(); sit != dirs.end(); ++sit) {
+  for (std::string const& dir : dirs) {
     std::string componentName;
     std::string fileN =
-      cmSystemTools::RelativePath(toplevel.c_str(), sit->c_str());
+      cmSystemTools::RelativePath(toplevel.c_str(), dir.c_str());
     if (fileN.empty()) {
       continue;
     }
@@ -205,65 +203,57 @@
     // in a vector based on the indices, and print them in that order.
     std::vector<cmCPackInstallationType*> installTypes(
       this->InstallationTypes.size());
-    std::map<std::string, cmCPackInstallationType>::iterator installTypeIt;
-    for (installTypeIt = this->InstallationTypes.begin();
-         installTypeIt != this->InstallationTypes.end(); ++installTypeIt) {
-      installTypes[installTypeIt->second.Index - 1] = &installTypeIt->second;
+    for (auto& installType : this->InstallationTypes) {
+      installTypes[installType.second.Index - 1] = &installType.second;
     }
-    std::vector<cmCPackInstallationType*>::iterator installTypeIt2;
-    for (installTypeIt2 = installTypes.begin();
-         installTypeIt2 != installTypes.end(); ++installTypeIt2) {
+    for (cmCPackInstallationType* installType : installTypes) {
       installTypesCode += "InstType \"";
-      installTypesCode += (*installTypeIt2)->DisplayName;
+      installTypesCode += installType->DisplayName;
       installTypesCode += "\"\n";
     }
 
     // Create installation groups first
-    std::map<std::string, cmCPackComponentGroup>::iterator groupIt;
-    for (groupIt = this->ComponentGroups.begin();
-         groupIt != this->ComponentGroups.end(); ++groupIt) {
-      if (groupIt->second.ParentGroup == nullptr) {
+    for (auto& group : this->ComponentGroups) {
+      if (group.second.ParentGroup == nullptr) {
         componentCode +=
-          this->CreateComponentGroupDescription(&groupIt->second, macrosOut);
+          this->CreateComponentGroupDescription(&group.second, macrosOut);
       }
 
       // Add the group description, if any.
-      if (!groupIt->second.Description.empty()) {
+      if (!group.second.Description.empty()) {
         groupDescriptions += "  !insertmacro MUI_DESCRIPTION_TEXT ${" +
-          groupIt->first + "} \"" +
-          this->TranslateNewlines(groupIt->second.Description) + "\"\n";
+          group.first + "} \"" +
+          this->TranslateNewlines(group.second.Description) + "\"\n";
       }
     }
 
     // Create the remaining components, which aren't associated with groups.
-    std::map<std::string, cmCPackComponent>::iterator compIt;
-    for (compIt = this->Components.begin(); compIt != this->Components.end();
-         ++compIt) {
-      if (compIt->second.Files.empty()) {
+    for (auto& comp : this->Components) {
+      if (comp.second.Files.empty()) {
         // NSIS cannot cope with components that have no files.
         continue;
       }
 
       anyDownloadedComponents =
-        anyDownloadedComponents || compIt->second.IsDownloaded;
+        anyDownloadedComponents || comp.second.IsDownloaded;
 
-      if (!compIt->second.Group) {
+      if (!comp.second.Group) {
         componentCode +=
-          this->CreateComponentDescription(&compIt->second, macrosOut);
+          this->CreateComponentDescription(&comp.second, macrosOut);
       }
 
       // Add this component to the various section lists.
       sectionList += "  !insertmacro \"${MacroName}\" \"";
-      sectionList += compIt->first;
+      sectionList += comp.first;
       sectionList += "\"\n";
-      selectedVarsList += "Var " + compIt->first + "_selected\n";
-      selectedVarsList += "Var " + compIt->first + "_was_installed\n";
+      selectedVarsList += "Var " + comp.first + "_selected\n";
+      selectedVarsList += "Var " + comp.first + "_was_installed\n";
 
       // Add the component description, if any.
-      if (!compIt->second.Description.empty()) {
+      if (!comp.second.Description.empty()) {
         componentDescriptions += "  !insertmacro MUI_DESCRIPTION_TEXT ${" +
-          compIt->first + "} \"" +
-          this->TranslateNewlines(compIt->second.Description) + "\"\n";
+          comp.first + "} \"" +
+          this->TranslateNewlines(comp.second.Description) + "\"\n";
       }
     }
 
@@ -463,11 +453,9 @@
 
     cmSystemTools::ExpandListArgument(cpackPackageDeskTopLinks,
                                       cpackPackageDesktopLinksVector);
-    for (std::vector<std::string>::iterator i =
-           cpackPackageDesktopLinksVector.begin();
-         i != cpackPackageDesktopLinksVector.end(); ++i) {
+    for (std::string const& cpdl : cpackPackageDesktopLinksVector) {
       cmCPackLogger(cmCPackLog::LOG_DEBUG,
-                    "CPACK_CREATE_DESKTOP_LINKS: " << *i << std::endl);
+                    "CPACK_CREATE_DESKTOP_LINKS: " << cpdl << std::endl);
     }
   } else {
     cmCPackLogger(cmCPackLog::LOG_DEBUG, "CPACK_CREATE_DESKTOP_LINKS: "
@@ -647,11 +635,9 @@
     componentCode += "  SectionIn RO\n";
   } else if (!component->InstallationTypes.empty()) {
     std::ostringstream out;
-    std::vector<cmCPackInstallationType*>::iterator installTypeIter;
-    for (installTypeIter = component->InstallationTypes.begin();
-         installTypeIter != component->InstallationTypes.end();
-         ++installTypeIter) {
-      out << " " << (*installTypeIter)->Index;
+    for (cmCPackInstallationType const* installType :
+         component->InstallationTypes) {
+      out << " " << installType->Index;
     }
     componentCode += "  SectionIn" + out.str() + "\n";
   }
@@ -730,19 +716,17 @@
     unsigned long totalSize = 0;
     { // the scope is needed for cmGeneratedFileStream
       cmGeneratedFileStream out(zipListFileName.c_str());
-      std::vector<std::string>::iterator fileIt;
-      for (fileIt = component->Files.begin(); fileIt != component->Files.end();
-           ++fileIt) {
+      for (std::string const& file : component->Files) {
         if (needQuotesInFile) {
           out << "\"";
         }
-        out << *fileIt;
+        out << file;
         if (needQuotesInFile) {
           out << "\"";
         }
         out << std::endl;
 
-        totalSize += cmSystemTools::FileLength(dirName + *fileIt);
+        totalSize += cmSystemTools::FileLength(dirName + file);
       }
     }
 
@@ -798,17 +782,14 @@
   macrosOut << "!macro Remove_${" << component->Name << "}\n";
   macrosOut << "  IntCmp $" << component->Name << "_was_installed 0 noremove_"
             << component->Name << "\n";
-  std::vector<std::string>::iterator pathIt;
   std::string path;
-  for (pathIt = component->Files.begin(); pathIt != component->Files.end();
-       ++pathIt) {
-    path = *pathIt;
+  for (std::string const& pathIt : component->Files) {
+    path = pathIt;
     std::replace(path.begin(), path.end(), '/', '\\');
     macrosOut << "  Delete \"" << componentOutputDir << "\\" << path << "\"\n";
   }
-  for (pathIt = component->Directories.begin();
-       pathIt != component->Directories.end(); ++pathIt) {
-    path = *pathIt;
+  for (std::string const& pathIt : component->Directories) {
+    path = pathIt;
     std::replace(path.begin(), path.end(), '/', '\\');
     macrosOut << "  RMDir \"" << componentOutputDir << "\\" << path << "\"\n";
   }
@@ -841,17 +822,14 @@
   visited.insert(component);
 
   std::ostringstream out;
-  std::vector<cmCPackComponent*>::iterator dependIt;
-  for (dependIt = component->Dependencies.begin();
-       dependIt != component->Dependencies.end(); ++dependIt) {
+  for (cmCPackComponent* depend : component->Dependencies) {
     // Write NSIS code to select this dependency
-    out << "  SectionGetFlags ${" << (*dependIt)->Name << "} $0\n";
+    out << "  SectionGetFlags ${" << depend->Name << "} $0\n";
     out << "  IntOp $0 $0 | ${SF_SELECTED}\n";
-    out << "  SectionSetFlags ${" << (*dependIt)->Name << "} $0\n";
-    out << "  IntOp $" << (*dependIt)->Name
-        << "_selected 0 + ${SF_SELECTED}\n";
+    out << "  SectionSetFlags ${" << depend->Name << "} $0\n";
+    out << "  IntOp $" << depend->Name << "_selected 0 + ${SF_SELECTED}\n";
     // Recurse
-    out << CreateSelectionDependenciesDescription(*dependIt, visited).c_str();
+    out << CreateSelectionDependenciesDescription(depend, visited).c_str();
   }
 
   return out.str();
@@ -867,19 +845,16 @@
   visited.insert(component);
 
   std::ostringstream out;
-  std::vector<cmCPackComponent*>::iterator dependIt;
-  for (dependIt = component->ReverseDependencies.begin();
-       dependIt != component->ReverseDependencies.end(); ++dependIt) {
+  for (cmCPackComponent* depend : component->ReverseDependencies) {
     // Write NSIS code to deselect this dependency
-    out << "  SectionGetFlags ${" << (*dependIt)->Name << "} $0\n";
+    out << "  SectionGetFlags ${" << depend->Name << "} $0\n";
     out << "  IntOp $1 ${SF_SELECTED} ~\n";
     out << "  IntOp $0 $0 & $1\n";
-    out << "  SectionSetFlags ${" << (*dependIt)->Name << "} $0\n";
-    out << "  IntOp $" << (*dependIt)->Name << "_selected 0 + 0\n";
+    out << "  SectionSetFlags ${" << depend->Name << "} $0\n";
+    out << "  IntOp $" << depend->Name << "_selected 0 + 0\n";
 
     // Recurse
-    out
-      << CreateDeselectionDependenciesDescription(*dependIt, visited).c_str();
+    out << CreateDeselectionDependenciesDescription(depend, visited).c_str();
   }
 
   return out.str();
@@ -903,20 +878,16 @@
     code += "\"" + group->DisplayName + "\" " + group->Name + "\n";
   }
 
-  std::vector<cmCPackComponentGroup*>::iterator groupIt;
-  for (groupIt = group->Subgroups.begin(); groupIt != group->Subgroups.end();
-       ++groupIt) {
-    code += this->CreateComponentGroupDescription(*groupIt, macrosOut);
+  for (cmCPackComponentGroup* g : group->Subgroups) {
+    code += this->CreateComponentGroupDescription(g, macrosOut);
   }
 
-  std::vector<cmCPackComponent*>::iterator comp;
-  for (comp = group->Components.begin(); comp != group->Components.end();
-       ++comp) {
-    if ((*comp)->Files.empty()) {
+  for (cmCPackComponent* comp : group->Components) {
+    if (comp->Files.empty()) {
       continue;
     }
 
-    code += this->CreateComponentDescription(*comp, macrosOut);
+    code += this->CreateComponentDescription(comp, macrosOut);
   }
   code += "SectionGroupEnd\n";
   return code;
diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h
index bdd1955..fc9ad9a 100644
--- a/Source/CPack/cmCPackNSISGenerator.h
+++ b/Source/CPack/cmCPackNSISGenerator.h
@@ -34,22 +34,22 @@
    * Construct generator
    */
   cmCPackNSISGenerator(bool nsis64 = false);
-  ~cmCPackNSISGenerator() CM_OVERRIDE;
+  ~cmCPackNSISGenerator() override;
 
 protected:
-  int InitializeInternal() CM_OVERRIDE;
+  int InitializeInternal() override;
   void CreateMenuLinks(std::ostream& str, std::ostream& deleteStr);
-  int PackageFiles() CM_OVERRIDE;
-  const char* GetOutputExtension() CM_OVERRIDE { return ".exe"; }
-  const char* GetOutputPostfix() CM_OVERRIDE { return "win32"; }
+  int PackageFiles() override;
+  const char* GetOutputExtension() override { return ".exe"; }
+  const char* GetOutputPostfix() override { return "win32"; }
 
   bool GetListOfSubdirectories(const char* dir,
                                std::vector<std::string>& dirs);
 
-  enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir() const
-    CM_OVERRIDE;
-  bool SupportsAbsoluteDestination() const CM_OVERRIDE;
-  bool SupportsComponentInstallation() const CM_OVERRIDE;
+  enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir()
+    const override;
+  bool SupportsAbsoluteDestination() const override;
+  bool SupportsComponentInstallation() const override;
 
   /// Produce a string that contains the NSIS code to describe a
   /// particular component. Any added macros will be emitted via
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/cmCPackOSXX11Generator.h b/Source/CPack/cmCPackOSXX11Generator.h
index 0a1f686..a6461c8 100644
--- a/Source/CPack/cmCPackOSXX11Generator.h
+++ b/Source/CPack/cmCPackOSXX11Generator.h
@@ -23,13 +23,13 @@
    * Construct generator
    */
   cmCPackOSXX11Generator();
-  ~cmCPackOSXX11Generator() CM_OVERRIDE;
+  ~cmCPackOSXX11Generator() override;
 
 protected:
-  virtual int InitializeInternal() CM_OVERRIDE;
-  int PackageFiles() CM_OVERRIDE;
-  const char* GetPackagingInstallPrefix() CM_OVERRIDE;
-  const char* GetOutputExtension() CM_OVERRIDE { return ".dmg"; }
+  virtual int InitializeInternal() override;
+  int PackageFiles() override;
+  const char* GetPackagingInstallPrefix() override;
+  const char* GetOutputExtension() override { return ".dmg"; }
 
   // bool CopyCreateResourceFile(const std::string& name,
   //                            const std::string& dir);
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/cmCPackPKGGenerator.h b/Source/CPack/cmCPackPKGGenerator.h
index aef795f..69286ff 100644
--- a/Source/CPack/cmCPackPKGGenerator.h
+++ b/Source/CPack/cmCPackPKGGenerator.h
@@ -27,13 +27,13 @@
    * Construct generator
    */
   cmCPackPKGGenerator();
-  ~cmCPackPKGGenerator() CM_OVERRIDE;
+  ~cmCPackPKGGenerator() override;
 
-  bool SupportsComponentInstallation() const CM_OVERRIDE;
+  bool SupportsComponentInstallation() const override;
 
 protected:
-  int InitializeInternal() CM_OVERRIDE;
-  const char* GetOutputPostfix() CM_OVERRIDE { return "darwin"; }
+  int InitializeInternal() override;
+  const char* GetOutputPostfix() override { return "darwin"; }
 
   // Copies or creates the resource file with the given name to the
   // package or package staging directory dirName. The variable
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/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h
index a2f58ff..0575587 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.h
+++ b/Source/CPack/cmCPackPackageMakerGenerator.h
@@ -25,13 +25,13 @@
    * Construct generator
    */
   cmCPackPackageMakerGenerator();
-  ~cmCPackPackageMakerGenerator() CM_OVERRIDE;
-  bool SupportsComponentInstallation() const CM_OVERRIDE;
+  ~cmCPackPackageMakerGenerator() override;
+  bool SupportsComponentInstallation() const override;
 
 protected:
-  int InitializeInternal() CM_OVERRIDE;
-  int PackageFiles() CM_OVERRIDE;
-  const char* GetOutputExtension() CM_OVERRIDE { return ".dmg"; }
+  int InitializeInternal() override;
+  int PackageFiles() override;
+  const char* GetOutputExtension() override { return ".dmg"; }
 
   // Run PackageMaker with the given command line, which will (if
   // successful) produce the given package file. Returns true if
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/cmCPackProductBuildGenerator.h b/Source/CPack/cmCPackProductBuildGenerator.h
index 984dcaa..015fe4a 100644
--- a/Source/CPack/cmCPackProductBuildGenerator.h
+++ b/Source/CPack/cmCPackProductBuildGenerator.h
@@ -25,12 +25,12 @@
    * Construct generator
    */
   cmCPackProductBuildGenerator();
-  ~cmCPackProductBuildGenerator() CM_OVERRIDE;
+  ~cmCPackProductBuildGenerator() override;
 
 protected:
-  int InitializeInternal() CM_OVERRIDE;
-  int PackageFiles() CM_OVERRIDE;
-  const char* GetOutputExtension() CM_OVERRIDE { return ".pkg"; }
+  int InitializeInternal() override;
+  int PackageFiles() override;
+  const char* GetOutputExtension() override { return ".pkg"; }
 
   // Run ProductBuild with the given command line, which will (if
   // successful) produce the given package file. Returns true if
diff --git a/Source/CPack/cmCPackRPMGenerator.h b/Source/CPack/cmCPackRPMGenerator.h
index bfba289..27d3b63 100644
--- a/Source/CPack/cmCPackRPMGenerator.h
+++ b/Source/CPack/cmCPackRPMGenerator.h
@@ -26,7 +26,7 @@
    * Construct generator
    */
   cmCPackRPMGenerator();
-  ~cmCPackRPMGenerator() CM_OVERRIDE;
+  ~cmCPackRPMGenerator() override;
 
   static bool CanGenerate()
   {
@@ -43,8 +43,8 @@
   }
 
 protected:
-  int InitializeInternal() CM_OVERRIDE;
-  int PackageFiles() CM_OVERRIDE;
+  int InitializeInternal() override;
+  int PackageFiles() override;
   /**
    * This method factors out the work done in component packaging case.
    */
@@ -61,10 +61,10 @@
    * components will be put in a single installer.
    */
   int PackageComponentsAllInOne(const std::string& compInstDirName);
-  const char* GetOutputExtension() CM_OVERRIDE { return ".rpm"; }
-  bool SupportsComponentInstallation() const CM_OVERRIDE;
+  const char* GetOutputExtension() override { return ".rpm"; }
+  bool SupportsComponentInstallation() const override;
   std::string GetComponentInstallDirNameSuffix(
-    const std::string& componentName) CM_OVERRIDE;
+    const std::string& componentName) override;
 
   void AddGeneratedPackageNames();
 };
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index c541614..3d7fd3c 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -6,7 +6,6 @@
 #include <sstream>
 #include <stdio.h>
 #include <string>
-#include <vector>
 
 #include "cmCPackGenerator.h"
 #include "cmCPackLog.h"
@@ -48,9 +47,8 @@
    * have generated several packages (component packaging)
    * so we must iterate over generated packages.
    */
-  for (std::vector<std::string>::iterator it = packageFileNames.begin();
-       it != packageFileNames.end(); ++it) {
-    retval &= cmSystemTools::SetPermissions((*it).c_str(),
+  for (std::string const& pfn : packageFileNames) {
+    retval &= cmSystemTools::SetPermissions(pfn.c_str(),
 #if defined(_MSC_VER) || defined(__MINGW32__)
                                             S_IREAD | S_IWRITE | S_IEXEC
 #else
diff --git a/Source/CPack/cmCPackSTGZGenerator.h b/Source/CPack/cmCPackSTGZGenerator.h
index 72f525c..9cf184b 100644
--- a/Source/CPack/cmCPackSTGZGenerator.h
+++ b/Source/CPack/cmCPackSTGZGenerator.h
@@ -23,13 +23,13 @@
    * Construct generator
    */
   cmCPackSTGZGenerator();
-  ~cmCPackSTGZGenerator() CM_OVERRIDE;
+  ~cmCPackSTGZGenerator() override;
 
 protected:
-  int PackageFiles() CM_OVERRIDE;
-  int InitializeInternal() CM_OVERRIDE;
-  int GenerateHeader(std::ostream* os) CM_OVERRIDE;
-  const char* GetOutputExtension() CM_OVERRIDE { return ".sh"; }
+  int PackageFiles() override;
+  int InitializeInternal() override;
+  int GenerateHeader(std::ostream* os) override;
+  const char* GetOutputExtension() override { return ".sh"; }
 };
 
 #endif
diff --git a/Source/CPack/cmCPackTGZGenerator.h b/Source/CPack/cmCPackTGZGenerator.h
index e904ab5..7be3d9d 100644
--- a/Source/CPack/cmCPackTGZGenerator.h
+++ b/Source/CPack/cmCPackTGZGenerator.h
@@ -20,10 +20,10 @@
    * Construct generator
    */
   cmCPackTGZGenerator();
-  ~cmCPackTGZGenerator() CM_OVERRIDE;
+  ~cmCPackTGZGenerator() override;
 
 protected:
-  const char* GetOutputExtension() CM_OVERRIDE { return ".tar.gz"; }
+  const char* GetOutputExtension() override { return ".tar.gz"; }
 };
 
 #endif
diff --git a/Source/CPack/cmCPackTXZGenerator.h b/Source/CPack/cmCPackTXZGenerator.h
index f38758d..4aa5973 100644
--- a/Source/CPack/cmCPackTXZGenerator.h
+++ b/Source/CPack/cmCPackTXZGenerator.h
@@ -20,10 +20,10 @@
    * Construct generator
    */
   cmCPackTXZGenerator();
-  ~cmCPackTXZGenerator() CM_OVERRIDE;
+  ~cmCPackTXZGenerator() override;
 
 protected:
-  const char* GetOutputExtension() CM_OVERRIDE { return ".tar.xz"; }
+  const char* GetOutputExtension() override { return ".tar.xz"; }
 };
 
 #endif
diff --git a/Source/CPack/cmCPackTarBZip2Generator.h b/Source/CPack/cmCPackTarBZip2Generator.h
index f3dd953..7975dda 100644
--- a/Source/CPack/cmCPackTarBZip2Generator.h
+++ b/Source/CPack/cmCPackTarBZip2Generator.h
@@ -19,10 +19,10 @@
    * Construct generator
    */
   cmCPackTarBZip2Generator();
-  ~cmCPackTarBZip2Generator() CM_OVERRIDE;
+  ~cmCPackTarBZip2Generator() override;
 
 protected:
-  const char* GetOutputExtension() CM_OVERRIDE { return ".tar.bz2"; }
+  const char* GetOutputExtension() override { return ".tar.bz2"; }
 };
 
 #endif
diff --git a/Source/CPack/cmCPackTarCompressGenerator.h b/Source/CPack/cmCPackTarCompressGenerator.h
index 8eedb24..37c7f48 100644
--- a/Source/CPack/cmCPackTarCompressGenerator.h
+++ b/Source/CPack/cmCPackTarCompressGenerator.h
@@ -19,10 +19,10 @@
    * Construct generator
    */
   cmCPackTarCompressGenerator();
-  ~cmCPackTarCompressGenerator() CM_OVERRIDE;
+  ~cmCPackTarCompressGenerator() override;
 
 protected:
-  const char* GetOutputExtension() CM_OVERRIDE { return ".tar.Z"; }
+  const char* GetOutputExtension() override { return ".tar.Z"; }
 };
 
 #endif
diff --git a/Source/CPack/cmCPackZIPGenerator.h b/Source/CPack/cmCPackZIPGenerator.h
index 2f81c65..58ec79e 100644
--- a/Source/CPack/cmCPackZIPGenerator.h
+++ b/Source/CPack/cmCPackZIPGenerator.h
@@ -20,10 +20,10 @@
    * Construct generator
    */
   cmCPackZIPGenerator();
-  ~cmCPackZIPGenerator() CM_OVERRIDE;
+  ~cmCPackZIPGenerator() override;
 
 protected:
-  const char* GetOutputExtension() CM_OVERRIDE { return ".zip"; }
+  const char* GetOutputExtension() override { return ".zip"; }
 };
 
 #endif
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 9970721..cc51c60 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -135,7 +135,7 @@
   cpackDefinitions definitions;
   definitions.Log = &log;
 
-  cpackConfigFile = "";
+  cpackConfigFile.clear();
 
   cmsys::CommandLineArguments arg;
   arg.Initialize(argc, argv);
@@ -293,10 +293,8 @@
                                 cpackProjectDirectory.c_str());
       }
     }
-    cpackDefinitions::MapType::iterator cdit;
-    for (cdit = definitions.Map.begin(); cdit != definitions.Map.end();
-         ++cdit) {
-      globalMF->AddDefinition(cdit->first, cdit->second.c_str());
+    for (auto const& cd : definitions.Map) {
+      globalMF->AddDefinition(cd.first, cd.second.c_str());
     }
 
     const char* cpackModulesPath =
@@ -311,9 +309,7 @@
     } else {
       std::vector<std::string> generatorsVector;
       cmSystemTools::ExpandListArgument(genList, generatorsVector);
-      std::vector<std::string>::iterator it;
-      for (it = generatorsVector.begin(); it != generatorsVector.end(); ++it) {
-        const char* gen = it->c_str();
+      for (std::string const& gen : generatorsVector) {
         cmMakefile::ScopePushPop raii(globalMF.get());
         cmMakefile* mf = globalMF.get();
         cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
@@ -354,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;
@@ -413,12 +410,10 @@
     doc.PrependSection("Options", cmDocumentationOptions);
 
     std::vector<cmDocumentationEntry> v;
-    cmCPackGeneratorFactory::DescriptionsMap::const_iterator generatorIt;
-    for (generatorIt = generators.GetGeneratorsList().begin();
-         generatorIt != generators.GetGeneratorsList().end(); ++generatorIt) {
+    for (auto const& g : generators.GetGeneratorsList()) {
       cmDocumentationEntry e;
-      e.Name = generatorIt->first;
-      e.Brief = generatorIt->second;
+      e.Name = g.first;
+      e.Brief = g.second;
       v.push_back(e);
     }
     doc.SetSection("Generators", v);
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index de5b4da..0152200 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -98,7 +98,7 @@
   bool CheckOutFound;
   cmsys::RegularExpression RegexCheckOut;
   cmsys::RegularExpression RegexParent;
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexCheckOut.find(this->Line)) {
       this->BZR->URL = this->RegexCheckOut.match(1);
@@ -123,7 +123,7 @@
 private:
   std::string& Rev;
   cmsys::RegularExpression RegexRevno;
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexRevno.find(this->Line)) {
       this->Rev = this->RegexRevno.match(1);
@@ -182,9 +182,9 @@
   {
     this->InitializeParser();
   }
-  ~LogParser() CM_OVERRIDE { this->CleanupParser(); }
+  ~LogParser() override { this->CleanupParser(); }
 
-  int InitializeParser() CM_OVERRIDE
+  int InitializeParser() override
   {
     int res = cmXMLParser::InitializeParser();
     if (res) {
@@ -207,14 +207,14 @@
 
   cmsys::RegularExpression EmailRegex;
 
-  bool ProcessChunk(const char* data, int length) CM_OVERRIDE
+  bool ProcessChunk(const char* data, int length) override
   {
     this->OutputLogger::ProcessChunk(data, length);
     this->ParseChunk(data, length);
     return true;
   }
 
-  void StartElement(const std::string& name, const char** /*atts*/) CM_OVERRIDE
+  void StartElement(const std::string& name, const char** /*atts*/) override
   {
     this->CData.clear();
     if (name == "log") {
@@ -239,12 +239,12 @@
     }
   }
 
-  void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
+  void CharacterDataHandler(const char* data, int length) override
   {
     this->CData.insert(this->CData.end(), data, data + length);
   }
 
-  void EndElement(const std::string& name) CM_OVERRIDE
+  void EndElement(const std::string& name) override
   {
     if (name == "log") {
       this->BZR->DoRevision(this->Rev, this->Changes);
@@ -274,7 +274,7 @@
     this->CData.clear();
   }
 
-  void ReportError(int /*line*/, int /*column*/, const char* msg) CM_OVERRIDE
+  void ReportError(int /*line*/, int /*column*/, const char* msg) override
   {
     this->BZR->Log << "Error parsing bzr log xml: " << msg << "\n";
   }
@@ -294,7 +294,7 @@
   cmCTestBZR* BZR;
   cmsys::RegularExpression RegexUpdate;
 
-  bool ProcessChunk(const char* first, int length) CM_OVERRIDE
+  bool ProcessChunk(const char* first, int length) override
   {
     bool last_is_new_line = (*first == '\r' || *first == '\n');
 
@@ -309,11 +309,11 @@
 
           // Hand this line to the subclass implementation.
           if (!this->ProcessLine()) {
-            this->Line = "";
+            this->Line.clear();
             return false;
           }
 
-          this->Line = "";
+          this->Line.clear();
           last_is_new_line = true;
         }
       } else {
@@ -325,7 +325,7 @@
     return true;
   }
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexUpdate.find(this->Line)) {
       this->DoPath(this->RegexUpdate.match(1)[0],
@@ -431,7 +431,7 @@
 private:
   cmCTestBZR* BZR;
   cmsys::RegularExpression RegexStatus;
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexStatus.find(this->Line)) {
       this->DoPath(this->RegexStatus.match(1)[0],
diff --git a/Source/CTest/cmCTestBZR.h b/Source/CTest/cmCTestBZR.h
index b313b25..d5c78c7 100644
--- a/Source/CTest/cmCTestBZR.h
+++ b/Source/CTest/cmCTestBZR.h
@@ -22,20 +22,20 @@
   /** Construct with a CTest instance and update log stream.  */
   cmCTestBZR(cmCTest* ctest, std::ostream& log);
 
-  ~cmCTestBZR() CM_OVERRIDE;
+  ~cmCTestBZR() override;
 
 private:
   // Implement cmCTestVC internal API.
-  bool NoteOldRevision() CM_OVERRIDE;
-  bool NoteNewRevision() CM_OVERRIDE;
-  bool UpdateImpl() CM_OVERRIDE;
+  bool NoteOldRevision() override;
+  bool NoteNewRevision() override;
+  bool UpdateImpl() override;
 
   // URL of repository directory checked out in the working tree.
   std::string URL;
 
   std::string LoadInfo();
-  bool LoadModifications() CM_OVERRIDE;
-  bool LoadRevisions() CM_OVERRIDE;
+  bool LoadModifications() override;
+  bool LoadRevisions() override;
 
   // Parsing helper classes.
   class InfoParser;
diff --git a/Source/CTest/cmCTestBatchTestHandler.h b/Source/CTest/cmCTestBatchTestHandler.h
index 3b58b13..42f87bd 100644
--- a/Source/CTest/cmCTestBatchTestHandler.h
+++ b/Source/CTest/cmCTestBatchTestHandler.h
@@ -17,8 +17,8 @@
 class cmCTestBatchTestHandler : public cmCTestMultiProcessHandler
 {
 public:
-  ~cmCTestBatchTestHandler() CM_OVERRIDE;
-  void RunTests() CM_OVERRIDE;
+  ~cmCTestBatchTestHandler() override;
+  void RunTests() override;
 
 protected:
   void WriteBatchScript();
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index aae3c63..a0d68a0 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -32,7 +32,7 @@
 }
 int cmCTestBuildAndTestHandler::ProcessHandler()
 {
-  this->Output = "";
+  this->Output.clear();
   std::string output;
   cmSystemTools::ResetErrorOccuredFlag();
   int retv = this->RunCMakeAndTest(&this->Output);
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h
index a0d3674..f19cb67 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.h
+++ b/Source/CTest/cmCTestBuildAndTestHandler.h
@@ -26,12 +26,12 @@
   /*
    * The main entry point for this class
    */
-  int ProcessHandler() CM_OVERRIDE;
+  int ProcessHandler() override;
 
   //! Set all the build and test arguments
-  int ProcessCommandLineArguments(const std::string& currentArg, size_t& idx,
-                                  const std::vector<std::string>& allArgs)
-    CM_OVERRIDE;
+  int ProcessCommandLineArguments(
+    const std::string& currentArg, size_t& idx,
+    const std::vector<std::string>& allArgs) override;
 
   /*
    * Get the output variable
@@ -40,7 +40,7 @@
 
   cmCTestBuildAndTestHandler();
 
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 
 protected:
   ///! Run CMake and build a test and then run it as a single test.
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
index f03bb2c..77b0549 100644
--- a/Source/CTest/cmCTestBuildCommand.h
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -25,12 +25,12 @@
 {
 public:
   cmCTestBuildCommand();
-  ~cmCTestBuildCommand() CM_OVERRIDE;
+  ~cmCTestBuildCommand() override;
 
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestBuildCommand* ni = new cmCTestBuildCommand;
     ni->CTest = this->CTest;
@@ -41,10 +41,10 @@
   /**
    * The name of the command as specified in CMakeList.txt.
    */
-  std::string GetName() const CM_OVERRIDE { return "ctest_build"; }
+  std::string GetName() const override { return "ctest_build"; }
 
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   cmGlobalGenerator* GlobalGenerator;
 
@@ -62,7 +62,7 @@
     ctb_LAST
   };
 
-  cmCTestGenericHandler* InitializeHandler() CM_OVERRIDE;
+  cmCTestGenericHandler* InitializeHandler() override;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 361b43b..1da42d4 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -171,8 +171,8 @@
 void cmCTestBuildHandler::Initialize()
 {
   this->Superclass::Initialize();
-  this->StartBuild = "";
-  this->EndBuild = "";
+  this->StartBuild.clear();
+  this->EndBuild.clear();
   this->CustomErrorMatches.clear();
   this->CustomErrorExceptions.clear();
   this->CustomWarningMatches.clear();
@@ -190,8 +190,8 @@
   this->BuildOutputLogSize = 0;
   this->CurrentProcessingLine.clear();
 
-  this->SimplifySourceDir = "";
-  this->SimplifyBuildDir = "";
+  this->SimplifySourceDir.clear();
+  this->SimplifyBuildDir.clear();
   this->OutputLineCounter = 0;
   this->ErrorsAndWarnings.clear();
   this->LastErrorOrWarning = this->ErrorsAndWarnings.end();
@@ -260,11 +260,11 @@
                      "MakeCommand:" << makeCommand << "\n", this->Quiet);
 
   std::string configType = this->CTest->GetConfigType();
-  if (configType == "") {
+  if (configType.empty()) {
     configType =
       this->CTest->GetCTestConfiguration("DefaultCTestConfigurationType");
   }
-  if (configType == "") {
+  if (configType.empty()) {
     configType = "Release";
   }
 
@@ -371,8 +371,8 @@
                                          this->WarningExceptionRegex);
 
   // Determine source and binary tree substitutions to simplify the output.
-  this->SimplifySourceDir = "";
-  this->SimplifyBuildDir = "";
+  this->SimplifySourceDir.clear();
+  this->SimplifyBuildDir.clear();
   if (this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20) {
     std::string srcdir =
       this->CTest->GetCTestConfiguration("SourceDirectory") + "/";
@@ -888,8 +888,8 @@
         errorwarning.Text =
           "*** WARNING non-zero return value in ctest from: ";
         errorwarning.Text += argv[0];
-        errorwarning.PreContext = "";
-        errorwarning.PostContext = "";
+        errorwarning.PreContext.clear();
+        errorwarning.PostContext.clear();
         errorwarning.Error = false;
         this->ErrorsAndWarnings.push_back(errorwarning);
         this->TotalWarnings++;
@@ -911,8 +911,8 @@
     errorwarning.LogLine = 1;
     errorwarning.Text = "*** ERROR executing: ";
     errorwarning.Text += cmsysProcess_GetErrorString(cp);
-    errorwarning.PreContext = "";
-    errorwarning.PostContext = "";
+    errorwarning.PreContext.clear();
+    errorwarning.PostContext.clear();
     errorwarning.Error = true;
     this->ErrorsAndWarnings.push_back(errorwarning);
     this->TotalErrors++;
@@ -996,8 +996,8 @@
         // This is an error or warning, so generate report
         errorwarning.LogLine = static_cast<int>(this->OutputLineCounter + 1);
         errorwarning.Text = line;
-        errorwarning.PreContext = "";
-        errorwarning.PostContext = "";
+        errorwarning.PreContext.clear();
+        errorwarning.PostContext.clear();
 
         // Copy pre-context to report
         for (std::string const& pc : this->PreContext) {
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
index ca11143..6e71ad6 100644
--- a/Source/CTest/cmCTestBuildHandler.h
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -31,16 +31,16 @@
   /*
    * The main entry point for this class
    */
-  int ProcessHandler() CM_OVERRIDE;
+  int ProcessHandler() override;
 
   cmCTestBuildHandler();
 
-  void PopulateCustomVectors(cmMakefile* mf) CM_OVERRIDE;
+  void PopulateCustomVectors(cmMakefile* mf) override;
 
   /**
    * Initialize handler
    */
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 
   int GetTotalErrors() { return this->TotalErrors; }
   int GetTotalWarnings() { return this->TotalWarnings; }
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 6eeb135..5779935 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -46,7 +46,7 @@
   cmsys::RegularExpression RegexFileRemoved1;
   cmsys::RegularExpression RegexFileRemoved2;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexFileUpdated.find(this->Line)) {
       this->DoFile(PathUpdated, this->RegexFileUpdated.match(2));
@@ -132,7 +132,7 @@
   SectionType Section;
   Revision Rev;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->Line == ("======================================="
                        "======================================")) {
diff --git a/Source/CTest/cmCTestCVS.h b/Source/CTest/cmCTestCVS.h
index 171460e..77fc3cc 100644
--- a/Source/CTest/cmCTestCVS.h
+++ b/Source/CTest/cmCTestCVS.h
@@ -25,12 +25,12 @@
   /** Construct with a CTest instance and update log stream.  */
   cmCTestCVS(cmCTest* ctest, std::ostream& log);
 
-  ~cmCTestCVS() CM_OVERRIDE;
+  ~cmCTestCVS() override;
 
 private:
   // Implement cmCTestVC internal API.
-  bool UpdateImpl() CM_OVERRIDE;
-  bool WriteXMLUpdates(cmXMLWriter& xml) CM_OVERRIDE;
+  bool UpdateImpl() override;
+  bool WriteXMLUpdates(cmXMLWriter& xml) override;
 
   // Update status for files in each directory.
   class Directory : public std::map<std::string, PathStatus>
diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h
index dfb3a59..0cbcbfa 100644
--- a/Source/CTest/cmCTestConfigureCommand.h
+++ b/Source/CTest/cmCTestConfigureCommand.h
@@ -25,7 +25,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestConfigureCommand* ni = new cmCTestConfigureCommand;
     ni->CTest = this->CTest;
@@ -36,10 +36,10 @@
   /**
    * The name of the command as specified in CMakeList.txt.
    */
-  std::string GetName() const CM_OVERRIDE { return "ctest_configure"; }
+  std::string GetName() const override { return "ctest_configure"; }
 
 protected:
-  cmCTestGenericHandler* InitializeHandler() CM_OVERRIDE;
+  cmCTestGenericHandler* InitializeHandler() override;
 
   enum
   {
diff --git a/Source/CTest/cmCTestConfigureHandler.h b/Source/CTest/cmCTestConfigureHandler.h
index 32a6ba7..680401c 100644
--- a/Source/CTest/cmCTestConfigureHandler.h
+++ b/Source/CTest/cmCTestConfigureHandler.h
@@ -19,11 +19,11 @@
   /*
    * The main entry point for this class
    */
-  int ProcessHandler() CM_OVERRIDE;
+  int ProcessHandler() override;
 
   cmCTestConfigureHandler();
 
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h
index 9ea0223..1ae2d86 100644
--- a/Source/CTest/cmCTestCoverageCommand.h
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -26,7 +26,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestCoverageCommand* ni = new cmCTestCoverageCommand;
     ni->CTest = this->CTest;
@@ -37,15 +37,15 @@
   /**
    * The name of the command as specified in CMakeList.txt.
    */
-  std::string GetName() const CM_OVERRIDE { return "ctest_coverage"; }
+  std::string GetName() const override { return "ctest_coverage"; }
 
   typedef cmCTestHandlerCommand Superclass;
 
 protected:
-  cmCTestGenericHandler* InitializeHandler() CM_OVERRIDE;
+  cmCTestGenericHandler* InitializeHandler() override;
 
-  bool CheckArgumentKeyword(std::string const& arg) CM_OVERRIDE;
-  bool CheckArgumentValue(std::string const& arg) CM_OVERRIDE;
+  bool CheckArgumentKeyword(std::string const& arg) override;
+  bool CheckArgumentValue(std::string const& arg) override;
 
   enum
   {
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 5ae4ed5..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;
@@ -860,6 +862,24 @@
   return static_cast<int>(cont->TotalCoverage.size());
 }
 
+static std::string joinCommandLine(const std::vector<std::string>& args)
+{
+  std::string ret;
+
+  for (std::string const& s : args) {
+    if (s.find(' ') == std::string::npos) {
+      ret += s + ' ';
+    } else {
+      ret += "\"" + s + "\" ";
+    }
+  }
+
+  // drop trailing whitespace
+  ret.erase(ret.size() - 1);
+
+  return ret;
+}
+
 int cmCTestCoverageHandler::HandleBlanketJSCoverage(
   cmCTestCoverageHandlerContainer* cont)
 {
@@ -974,6 +994,11 @@
   cmCTestCoverageHandlerLocale locale_C;
   static_cast<void>(locale_C);
 
+  std::vector<std::string> basecovargs =
+    cmSystemTools::ParseArguments(gcovExtraFlags.c_str());
+  basecovargs.insert(basecovargs.begin(), gcovCommand);
+  basecovargs.push_back("-o");
+
   // files is a list of *.da and *.gcda files with coverage data in them.
   // These are binary files that you give as input to gcov so that it will
   // give us text output we can analyze to summarize coverage.
@@ -985,8 +1010,10 @@
     // Call gcov to get coverage data for this *.gcda file:
     //
     std::string fileDir = cmSystemTools::GetFilenamePath(f);
-    std::string command = "\"" + gcovCommand + "\" " + gcovExtraFlags + " " +
-      "-o \"" + fileDir + "\" " + "\"" + f + "\"";
+    std::vector<std::string> covargs = basecovargs;
+    covargs.push_back(fileDir);
+    covargs.push_back(f);
+    const std::string command = joinCommandLine(covargs);
 
     cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                        command << std::endl, this->Quiet);
@@ -996,9 +1023,8 @@
     int retVal = 0;
     *cont->OFS << "* Run coverage for: " << fileDir << std::endl;
     *cont->OFS << "  Command: " << command << std::endl;
-    int res =
-      this->CTest->RunCommand(command.c_str(), &output, &errors, &retVal,
-                              tempDir.c_str(), 0 /*this->TimeOut*/);
+    int res = this->CTest->RunCommand(covargs, &output, &errors, &retVal,
+                                      tempDir.c_str(), 0 /*this->TimeOut*/);
 
     *cont->OFS << "  Output: " << output << std::endl;
     *cont->OFS << "  Errors: " << errors << std::endl;
@@ -1049,7 +1075,7 @@
           break;
         }
 
-        actualSourceFile = "";
+        actualSourceFile.clear();
         sourceFile = st1re1.match(2);
       } else if (st1re2.find(line.c_str())) {
         if (gcovStyle == 0) {
@@ -1074,7 +1100,7 @@
           break;
         }
 
-        actualSourceFile = "";
+        actualSourceFile.clear();
         sourceFile = st2re1.match(1);
       } else if (st2re2.find(line.c_str())) {
         if (gcovStyle == 0) {
@@ -1216,11 +1242,11 @@
           }
         }
 
-        actualSourceFile = "";
+        actualSourceFile.clear();
       }
 
       if (!sourceFile.empty() && actualSourceFile.empty()) {
-        gcovFile = "";
+        gcovFile.clear();
 
         // Is it in the source dir or the binary dir?
         //
@@ -1337,6 +1363,11 @@
   cmCTestCoverageHandlerLocale locale_C;
   static_cast<void>(locale_C);
 
+  std::vector<std::string> covargs =
+    cmSystemTools::ParseArguments(lcovExtraFlags.c_str());
+  covargs.insert(covargs.begin(), lcovCommand);
+  const std::string command = joinCommandLine(covargs);
+
   // In intel compiler we have to call codecov only once in each executable
   // directory. It collects all *.dyn files to generate .dpi file.
   for (std::string const& f : files) {
@@ -1344,7 +1375,6 @@
                        this->Quiet);
     std::string fileDir = cmSystemTools::GetFilenamePath(f);
     cmWorkingDirectory workdir(fileDir);
-    std::string command = "\"" + lcovCommand + "\" " + lcovExtraFlags + " ";
 
     cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                        "Current coverage dir: " << fileDir << std::endl,
@@ -1357,9 +1387,8 @@
     int retVal = 0;
     *cont->OFS << "* Run coverage for: " << fileDir << std::endl;
     *cont->OFS << "  Command: " << command << std::endl;
-    int res =
-      this->CTest->RunCommand(command.c_str(), &output, &errors, &retVal,
-                              fileDir.c_str(), 0 /*this->TimeOut*/);
+    int res = this->CTest->RunCommand(covargs, &output, &errors, &retVal,
+                                      fileDir.c_str(), 0 /*this->TimeOut*/);
 
     *cont->OFS << "  Output: " << output << std::endl;
     *cont->OFS << "  Errors: " << errors << std::endl;
@@ -1514,7 +1543,7 @@
             }
           }
 
-          actualSourceFile = "";
+          actualSourceFile.clear();
         }
       }
     }
@@ -1989,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,
@@ -2291,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 83eb561..6492fe9 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -42,23 +42,23 @@
   /*
    * The main entry point for this class
    */
-  int ProcessHandler() CM_OVERRIDE;
+  int ProcessHandler() override;
 
   cmCTestCoverageHandler();
 
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 
   /**
    * This method is called when reading CTest custom file
    */
-  void PopulateCustomVectors(cmMakefile* mf) CM_OVERRIDE;
+  void PopulateCustomVectors(cmMakefile* mf) override;
 
   /** Report coverage only for sources with these labels.  */
   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/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx
index 022afd2..7b5ea60 100644
--- a/Source/CTest/cmCTestCurl.cxx
+++ b/Source/CTest/cmCTestCurl.cxx
@@ -109,7 +109,7 @@
                              std::string const& url, std::string const& fields,
                              std::string& response)
 {
-  response = "";
+  response.clear();
   if (!this->InitCurl()) {
     cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed");
     return false;
@@ -185,7 +185,7 @@
 bool cmCTestCurl::HttpRequest(std::string const& url,
                               std::string const& fields, std::string& response)
 {
-  response = "";
+  response.clear();
   cmCTestOptionalLog(this->CTest, DEBUG, "HttpRequest\n"
                        << "url: " << url << "\n"
                        << "fields " << fields << "\n",
@@ -240,10 +240,10 @@
 
 void cmCTestCurl::SetProxyType()
 {
-  this->HTTPProxy = "";
+  this->HTTPProxy.clear();
   // this is the default
   this->HTTPProxyType = CURLPROXY_HTTP;
-  this->HTTPProxyAuth = "";
+  this->HTTPProxyAuth.clear();
   if (cmSystemTools::GetEnv("HTTP_PROXY", this->HTTPProxy)) {
     std::string port;
     if (cmSystemTools::GetEnv("HTTP_PROXY_PORT", port)) {
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
index 9a8b735..9425ece 100644
--- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
@@ -27,7 +27,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestEmptyBinaryDirectoryCommand* ni =
       new cmCTestEmptyBinaryDirectoryCommand;
@@ -41,7 +41,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index fa5388a..7fe74af 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -46,7 +46,7 @@
 
 private:
   std::string& Line1;
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     // Only the first line is of interest.
     this->Line1 = this->Line;
@@ -354,7 +354,7 @@
     this->Changes.clear();
   }
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->Line[0] == ':') {
       this->DiffField = DiffFieldChange;
@@ -512,7 +512,7 @@
     person.TimeZone = strtol(c, const_cast<char**>(&c), 10);
   }
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->Line.empty()) {
       if (this->Section == SectionBody && this->LineEnd == '\0') {
diff --git a/Source/CTest/cmCTestGIT.h b/Source/CTest/cmCTestGIT.h
index 222bc50..ade430f 100644
--- a/Source/CTest/cmCTestGIT.h
+++ b/Source/CTest/cmCTestGIT.h
@@ -22,15 +22,15 @@
   /** Construct with a CTest instance and update log stream.  */
   cmCTestGIT(cmCTest* ctest, std::ostream& log);
 
-  ~cmCTestGIT() CM_OVERRIDE;
+  ~cmCTestGIT() override;
 
 private:
   unsigned int CurrentGitVersion;
   unsigned int GetGitVersion();
   std::string GetWorkingRevision();
-  bool NoteOldRevision() CM_OVERRIDE;
-  bool NoteNewRevision() CM_OVERRIDE;
-  bool UpdateImpl() CM_OVERRIDE;
+  bool NoteOldRevision() override;
+  bool NoteNewRevision() override;
+  bool UpdateImpl() override;
 
   std::string FindGitDir();
   std::string FindTopDir();
@@ -39,8 +39,8 @@
   bool UpdateByCustom(std::string const& custom);
   bool UpdateInternal();
 
-  bool LoadRevisions() CM_OVERRIDE;
-  bool LoadModifications() CM_OVERRIDE;
+  bool LoadRevisions() override;
+  bool LoadModifications() override;
 
   // "public" needed by older Sun compilers
 public:
diff --git a/Source/CTest/cmCTestGlobalVC.h b/Source/CTest/cmCTestGlobalVC.h
index b4bf077..76377ed 100644
--- a/Source/CTest/cmCTestGlobalVC.h
+++ b/Source/CTest/cmCTestGlobalVC.h
@@ -26,11 +26,11 @@
   /** Construct with a CTest instance and update log stream.  */
   cmCTestGlobalVC(cmCTest* ctest, std::ostream& log);
 
-  ~cmCTestGlobalVC() CM_OVERRIDE;
+  ~cmCTestGlobalVC() override;
 
 protected:
   // Implement cmCTestVC internal API.
-  bool WriteXMLUpdates(cmXMLWriter& xml) CM_OVERRIDE;
+  bool WriteXMLUpdates(cmXMLWriter& xml) override;
 
   /** Represent a vcs-reported action for one path in a revision.  */
   struct Change
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
index 78353b3..525dacc 100644
--- a/Source/CTest/cmCTestHG.cxx
+++ b/Source/CTest/cmCTestHG.cxx
@@ -36,7 +36,7 @@
   std::string& Rev;
   cmsys::RegularExpression RegexIdentify;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexIdentify.find(this->Line)) {
       this->Rev = this->RegexIdentify.match(1);
@@ -60,7 +60,7 @@
   cmCTestHG* HG;
   cmsys::RegularExpression RegexStatus;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexStatus.find(this->Line)) {
       this->DoPath(this->RegexStatus.match(1)[0], this->RegexStatus.match(2));
@@ -167,7 +167,7 @@
   {
     this->InitializeParser();
   }
-  ~LogParser() CM_OVERRIDE { this->CleanupParser(); }
+  ~LogParser() override { this->CleanupParser(); }
 private:
   cmCTestHG* HG;
 
@@ -178,14 +178,14 @@
   Change CurChange;
   std::vector<char> CData;
 
-  bool ProcessChunk(const char* data, int length) CM_OVERRIDE
+  bool ProcessChunk(const char* data, int length) override
   {
     this->OutputLogger::ProcessChunk(data, length);
     this->ParseChunk(data, length);
     return true;
   }
 
-  void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
+  void StartElement(const std::string& name, const char** atts) override
   {
     this->CData.clear();
     if (name == "logentry") {
@@ -197,12 +197,12 @@
     }
   }
 
-  void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
+  void CharacterDataHandler(const char* data, int length) override
   {
     this->CData.insert(this->CData.end(), data, data + length);
   }
 
-  void EndElement(const std::string& name) CM_OVERRIDE
+  void EndElement(const std::string& name) override
   {
     if (name == "logentry") {
       this->HG->DoRevision(this->Rev, this->Changes);
@@ -250,14 +250,14 @@
         currPath += i;
       } else {
         output.push_back(currPath);
-        currPath = "";
+        currPath.clear();
       }
     }
     output.push_back(currPath);
     return output;
   }
 
-  void ReportError(int /*line*/, int /*column*/, const char* msg) CM_OVERRIDE
+  void ReportError(int /*line*/, int /*column*/, const char* msg) override
   {
     this->HG->Log << "Error parsing hg log xml: " << msg << "\n";
   }
diff --git a/Source/CTest/cmCTestHG.h b/Source/CTest/cmCTestHG.h
index 90c38dc..c12d618 100644
--- a/Source/CTest/cmCTestHG.h
+++ b/Source/CTest/cmCTestHG.h
@@ -22,16 +22,16 @@
   /** Construct with a CTest instance and update log stream.  */
   cmCTestHG(cmCTest* ctest, std::ostream& log);
 
-  ~cmCTestHG() CM_OVERRIDE;
+  ~cmCTestHG() override;
 
 private:
   std::string GetWorkingRevision();
-  bool NoteOldRevision() CM_OVERRIDE;
-  bool NoteNewRevision() CM_OVERRIDE;
-  bool UpdateImpl() CM_OVERRIDE;
+  bool NoteOldRevision() override;
+  bool NoteNewRevision() override;
+  bool UpdateImpl() override;
 
-  bool LoadRevisions() CM_OVERRIDE;
-  bool LoadModifications() CM_OVERRIDE;
+  bool LoadRevisions() override;
+  bool LoadModifications() override;
 
   // Parsing helper classes.
   class IdentifyParser;
diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h
index b838074..79d61f3 100644
--- a/Source/CTest/cmCTestHandlerCommand.h
+++ b/Source/CTest/cmCTestHandlerCommand.h
@@ -34,7 +34,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   enum
   {
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
index aaa8c6b..b6b3c40 100644
--- a/Source/CTest/cmCTestMemCheckCommand.h
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -23,7 +23,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestMemCheckCommand* ni = new cmCTestMemCheckCommand;
     ni->CTest = this->CTest;
@@ -32,9 +32,9 @@
   }
 
 protected:
-  cmCTestGenericHandler* InitializeActualHandler() CM_OVERRIDE;
+  cmCTestGenericHandler* InitializeActualHandler() override;
 
-  void ProcessAdditionalValues(cmCTestGenericHandler* handler) CM_OVERRIDE;
+  void ProcessAdditionalValues(cmCTestGenericHandler* handler) override;
 
   enum
   {
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 1058806..3efb039 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -47,7 +47,7 @@
     this->CTest = c;
     this->SetErrorCallback(xmlReportError, c);
   }
-  void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
+  void StartElement(const std::string& name, const char** atts) override
   {
     if (name == "MemoryLeak" || name == "ResourceLeak") {
       this->Errors.push_back(cmCTestMemCheckHandler::MLK);
@@ -64,7 +64,7 @@
     ostr << "\n";
     this->Log += ostr.str();
   }
-  void EndElement(const std::string& /*name*/) CM_OVERRIDE {}
+  void EndElement(const std::string& /*name*/) override {}
 
   const char* GetAttribute(const char* name, const char** atts)
   {
@@ -122,11 +122,11 @@
   this->LogWithPID = false;
   this->CustomMaximumPassedTestOutputSize = 0;
   this->CustomMaximumFailedTestOutputSize = 0;
-  this->MemoryTester = "";
+  this->MemoryTester.clear();
   this->MemoryTesterDynamicOptions.clear();
   this->MemoryTesterOptions.clear();
   this->MemoryTesterStyle = UNKNOWN;
-  this->MemoryTesterOutputFile = "";
+  this->MemoryTesterOutputFile.clear();
   this->DefectCount = 0;
 }
 
@@ -417,8 +417,8 @@
 
 bool cmCTestMemCheckHandler::InitializeMemoryChecking()
 {
-  this->MemoryTesterEnvironmentVariable = "";
-  this->MemoryTester = "";
+  this->MemoryTesterEnvironmentVariable.clear();
+  this->MemoryTester.clear();
   // Setup the command
   if (cmSystemTools::FileExists(
         this->CTest->GetCTestConfiguration("MemoryCheckCommand").c_str())) {
@@ -725,7 +725,7 @@
   std::vector<std::string> lines;
   cmSystemTools::Split(str.c_str(), lines);
   std::ostringstream ostr;
-  log = "";
+  log.clear();
   for (std::string const& l : lines) {
     std::string resultFound;
     if (leakWarning.find(l)) {
@@ -755,7 +755,7 @@
   std::vector<std::string> lines;
   cmSystemTools::Split(str.c_str(), lines);
   std::ostringstream ostr;
-  log = "";
+  log.clear();
 
   cmsys::RegularExpression pfW("^\\[[WEI]\\] ([A-Z][A-Z][A-Z][A-Z]*): ");
 
@@ -805,7 +805,7 @@
   std::string::size_type cc;
 
   std::ostringstream ostr;
-  log = "";
+  log.clear();
 
   int defects = 0;
 
@@ -928,7 +928,7 @@
 bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
   const std::string& str, std::string& log, std::vector<int>& results)
 {
-  log = "";
+  log.clear();
   double sttime = cmSystemTools::GetTime();
   std::vector<std::string> lines;
   cmSystemTools::Split(str.c_str(), lines);
@@ -1079,7 +1079,7 @@
     if (g.GetFiles().empty()) {
       std::string log = "Cannot find memory tester output file: " + ofile;
       cmCTestLog(this->CTest, ERROR_MESSAGE, log << std::endl);
-      ofile = "";
+      ofile.clear();
     } else {
       files = g.GetFiles();
       return;
@@ -1087,7 +1087,7 @@
   } else if (!cmSystemTools::FileExists(ofile.c_str())) {
     std::string log = "Cannot find memory tester output file: " + ofile;
     cmCTestLog(this->CTest, ERROR_MESSAGE, log << std::endl);
-    ofile = "";
+    ofile.clear();
   }
   files.push_back(ofile);
 }
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index 1228c42..9218294 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -24,19 +24,18 @@
 public:
   typedef cmCTestTestHandler Superclass;
 
-  void PopulateCustomVectors(cmMakefile* mf) CM_OVERRIDE;
+  void PopulateCustomVectors(cmMakefile* mf) override;
 
   cmCTestMemCheckHandler();
 
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 
   int GetDefectCount();
 
 protected:
-  int PreProcessHandler() CM_OVERRIDE;
-  int PostProcessHandler() CM_OVERRIDE;
-  void GenerateTestCommand(std::vector<std::string>& args,
-                           int test) CM_OVERRIDE;
+  int PreProcessHandler() override;
+  int PostProcessHandler() override;
+  void GenerateTestCommand(std::vector<std::string>& args, int test) override;
 
 private:
   enum
@@ -121,7 +120,7 @@
   /**
    * Generate the Dart compatible output
    */
-  void GenerateDartOutput(cmXMLWriter& xml) CM_OVERRIDE;
+  void GenerateDartOutput(cmXMLWriter& xml) override;
 
   std::vector<std::string> CustomPreMemCheck;
   std::vector<std::string> CustomPostMemCheck;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index c853373..6a7bdc0 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -491,7 +491,7 @@
     }
     // Next part of the file is the failed tests
     while (std::getline(fin, line)) {
-      if (line != "") {
+      if (!line.empty()) {
         this->LastTestsFailed.push_back(line);
       }
     }
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 1206b9a..11f6a00 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -37,7 +37,7 @@
   std::string& Rev;
   cmsys::RegularExpression RegexIdentify;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexIdentify.find(this->Line)) {
       this->Rev = this->RegexIdentify.match(1);
@@ -61,7 +61,7 @@
   cmsys::RegularExpression RegexIdentify;
   cmCTestP4* P4;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexIdentify.find(this->Line)) {
       P4->ChangeLists.push_back(this->RegexIdentify.match(1));
@@ -84,7 +84,7 @@
   cmsys::RegularExpression RegexUser;
   cmCTestP4* P4;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexUser.find(this->Line)) {
       User NewUser;
@@ -127,7 +127,7 @@
   std::string CurrentPath;
   cmsys::RegularExpression RegexDiff;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (!this->Line.empty() && this->Line[0] == '=' &&
         this->RegexDiff.find(this->Line)) {
@@ -217,7 +217,7 @@
   SectionType Section;
   Revision Rev;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->Line.empty()) {
       this->NextSection();
diff --git a/Source/CTest/cmCTestP4.h b/Source/CTest/cmCTestP4.h
index faeeaf2..b14edf7 100644
--- a/Source/CTest/cmCTestP4.h
+++ b/Source/CTest/cmCTestP4.h
@@ -24,7 +24,7 @@
   /** Construct with a CTest instance and update log stream.  */
   cmCTestP4(cmCTest* ctest, std::ostream& log);
 
-  ~cmCTestP4() CM_OVERRIDE;
+  ~cmCTestP4() override;
 
 private:
   std::vector<std::string> ChangeLists;
@@ -51,13 +51,13 @@
   void SetP4Options(std::vector<char const*>& options);
 
   std::string GetWorkingRevision();
-  bool NoteOldRevision() CM_OVERRIDE;
-  bool NoteNewRevision() CM_OVERRIDE;
-  bool UpdateImpl() CM_OVERRIDE;
+  bool NoteOldRevision() override;
+  bool NoteNewRevision() override;
+  bool UpdateImpl() override;
   bool UpdateCustom(const std::string& custom);
 
-  bool LoadRevisions() CM_OVERRIDE;
-  bool LoadModifications() CM_OVERRIDE;
+  bool LoadRevisions() override;
+  bool LoadModifications() override;
 
   class ChangesParser;
   class DescribeParser;
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h
index 157710a..ba25c51 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.h
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.h
@@ -27,7 +27,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestReadCustomFilesCommand* ni = new cmCTestReadCustomFilesCommand;
     ni->CTest = this->CTest;
@@ -39,7 +39,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h
index 9821c2e..9d8b4b5 100644
--- a/Source/CTest/cmCTestRunScriptCommand.h
+++ b/Source/CTest/cmCTestRunScriptCommand.h
@@ -27,7 +27,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestRunScriptCommand* ni = new cmCTestRunScriptCommand;
     ni->CTest = this->CTest;
@@ -40,7 +40,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index a71e2ec..abdb643 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -30,8 +30,8 @@
   this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
   this->TestResult.TestCount = 0;
   this->TestResult.Properties = nullptr;
-  this->ProcessOutput = "";
-  this->CompressedOutput = "";
+  this->ProcessOutput.clear();
+  this->CompressedOutput.clear();
   this->CompressionRatio = 2;
   this->StopTimePassed = false;
   this->NumberOfRunsLeft = 1; // default to 1 run of the test
@@ -426,7 +426,7 @@
     this->TestResult.Path = this->TestProperties->Directory;
     this->TestProcess = new cmProcess;
     this->TestResult.Output = "Disabled";
-    this->TestResult.FullCommandLine = "";
+    this->TestResult.FullCommandLine.clear();
     return false;
   }
 
@@ -451,7 +451,7 @@
     *this->TestHandler->LogFile << msg << std::endl;
     cmCTestLog(this->CTest, HANDLER_OUTPUT, msg << std::endl);
     this->TestResult.Output = msg;
-    this->TestResult.FullCommandLine = "";
+    this->TestResult.FullCommandLine.clear();
     this->TestResult.CompletionStatus = "Fixture dependency failed";
     this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
     return false;
@@ -471,7 +471,7 @@
     *this->TestHandler->LogFile << msg << std::endl;
     cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl);
     this->TestResult.Output = msg;
-    this->TestResult.FullCommandLine = "";
+    this->TestResult.FullCommandLine.clear();
     this->TestResult.CompletionStatus = "Missing Configuration";
     this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
     return false;
@@ -487,14 +487,14 @@
       cmCTestLog(this->CTest, ERROR_MESSAGE,
                  "Unable to find required file: " << file << std::endl);
       this->TestResult.Output = "Unable to find required file: " + file;
-      this->TestResult.FullCommandLine = "";
+      this->TestResult.FullCommandLine.clear();
       this->TestResult.CompletionStatus = "Required Files Missing";
       this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
       return false;
     }
   }
   // log and return if we did not find the executable
-  if (this->ActualCommand == "") {
+  if (this->ActualCommand.empty()) {
     // if the command was not found create a TestResult object
     // that has that information
     this->TestProcess = new cmProcess;
@@ -503,7 +503,7 @@
     cmCTestLog(this->CTest, ERROR_MESSAGE,
                "Unable to find executable: " << args[1] << std::endl);
     this->TestResult.Output = "Unable to find executable: " + args[1];
-    this->TestResult.FullCommandLine = "";
+    this->TestResult.FullCommandLine.clear();
     this->TestResult.CompletionStatus = "Unable to find executable";
     this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
     return false;
@@ -595,7 +595,7 @@
 {
   double timeout = this->TestProperties->Timeout;
 
-  if (this->CTest->GetStopTime() == "") {
+  if (this->CTest->GetStopTime().empty()) {
     return timeout;
   }
   struct tm* lctime;
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 5936d0e..ce96224 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -59,7 +59,7 @@
   cmsys::RegularExpression RegexRev;
   cmsys::RegularExpression RegexURL;
   cmsys::RegularExpression RegexRoot;
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexRev.find(this->Line)) {
       this->Rev = this->RegexRev.match(1);
@@ -199,7 +199,7 @@
   cmCTestSVN* SVN;
   cmsys::RegularExpression RegexUpdate;
 
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexUpdate.find(this->Line)) {
       this->DoPath(this->RegexUpdate.match(1)[0],
@@ -301,7 +301,7 @@
   {
     this->InitializeParser();
   }
-  ~LogParser() CM_OVERRIDE { this->CleanupParser(); }
+  ~LogParser() override { this->CleanupParser(); }
 private:
   cmCTestSVN* SVN;
   cmCTestSVN::SVNInfo& SVNRepo;
@@ -313,14 +313,14 @@
   Change CurChange;
   std::vector<char> CData;
 
-  bool ProcessChunk(const char* data, int length) CM_OVERRIDE
+  bool ProcessChunk(const char* data, int length) override
   {
     this->OutputLogger::ProcessChunk(data, length);
     this->ParseChunk(data, length);
     return true;
   }
 
-  void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
+  void StartElement(const std::string& name, const char** atts) override
   {
     this->CData.clear();
     if (name == "logentry") {
@@ -338,12 +338,12 @@
     }
   }
 
-  void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
+  void CharacterDataHandler(const char* data, int length) override
   {
     this->CData.insert(this->CData.end(), data, data + length);
   }
 
-  void EndElement(const std::string& name) CM_OVERRIDE
+  void EndElement(const std::string& name) override
   {
     if (name == "logentry") {
       this->SVN->DoRevisionSVN(this->Rev, this->Changes);
@@ -362,7 +362,7 @@
     this->CData.clear();
   }
 
-  void ReportError(int /*line*/, int /*column*/, const char* msg) CM_OVERRIDE
+  void ReportError(int /*line*/, int /*column*/, const char* msg) override
   {
     this->SVN->Log << "Error parsing svn log xml: " << msg << "\n";
   }
@@ -410,7 +410,7 @@
 
   // Ignore changes in the old revision for external repositories
   if (revision.Rev == revision.SVNInfo->OldRevision &&
-      revision.SVNInfo->LocalPath != "") {
+      !revision.SVNInfo->LocalPath.empty()) {
     return;
   }
 
@@ -430,7 +430,7 @@
 private:
   cmCTestSVN* SVN;
   cmsys::RegularExpression RegexStatus;
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexStatus.find(this->Line)) {
       this->DoPath(this->RegexStatus.match(1)[0],
@@ -496,7 +496,7 @@
 private:
   cmCTestSVN* SVN;
   cmsys::RegularExpression RegexExternal;
-  bool ProcessLine() CM_OVERRIDE
+  bool ProcessLine() override
   {
     if (this->RegexExternal.find(this->Line)) {
       this->DoPath(this->RegexExternal.match(1));
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index 94af837..dbc7fde 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -24,14 +24,14 @@
   /** Construct with a CTest instance and update log stream.  */
   cmCTestSVN(cmCTest* ctest, std::ostream& log);
 
-  ~cmCTestSVN() CM_OVERRIDE;
+  ~cmCTestSVN() override;
 
 private:
   // Implement cmCTestVC internal API.
-  void CleanupImpl() CM_OVERRIDE;
-  bool NoteOldRevision() CM_OVERRIDE;
-  bool NoteNewRevision() CM_OVERRIDE;
-  bool UpdateImpl() CM_OVERRIDE;
+  void CleanupImpl() override;
+  bool NoteOldRevision() override;
+  bool NoteNewRevision() override;
+  bool UpdateImpl() override;
 
   bool RunSVNCommand(std::vector<char const*> const& parameters,
                      OutputParser* out, OutputParser* err);
@@ -77,8 +77,8 @@
 
   std::string LoadInfo(SVNInfo& svninfo);
   bool LoadRepositories();
-  bool LoadModifications() CM_OVERRIDE;
-  bool LoadRevisions() CM_OVERRIDE;
+  bool LoadModifications() override;
+  bool LoadRevisions() override;
   bool LoadRevisions(SVNInfo& svninfo);
 
   void GuessBase(SVNInfo& svninfo, std::vector<Change> const& changes);
@@ -86,7 +86,7 @@
   void DoRevisionSVN(Revision const& revision,
                      std::vector<Change> const& changes);
 
-  void WriteXMLGlobal(cmXMLWriter& xml) CM_OVERRIDE;
+  void WriteXMLGlobal(cmXMLWriter& xml) override;
 
   class ExternalParser;
   // Parsing helper classes.
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 7d1c24f..fdd9622 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -52,9 +52,9 @@
 {
 public:
   cmCTestScriptFunctionBlocker() {}
-  ~cmCTestScriptFunctionBlocker() CM_OVERRIDE {}
+  ~cmCTestScriptFunctionBlocker() override {}
   bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
-                         cmExecutionStatus& /*status*/) CM_OVERRIDE;
+                         cmExecutionStatus& /*status*/) override;
   // virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
   // virtual void ScopeEnded(cmMakefile &mf);
 
@@ -93,18 +93,18 @@
   this->EmptyBinDir = false;
   this->EmptyBinDirOnce = false;
 
-  this->SourceDir = "";
-  this->BinaryDir = "";
-  this->BackupSourceDir = "";
-  this->BackupBinaryDir = "";
-  this->CTestRoot = "";
-  this->CVSCheckOut = "";
-  this->CTestCmd = "";
-  this->UpdateCmd = "";
-  this->CTestEnv = "";
-  this->InitialCache = "";
-  this->CMakeCmd = "";
-  this->CMOutFile = "";
+  this->SourceDir.clear();
+  this->BinaryDir.clear();
+  this->BackupSourceDir.clear();
+  this->BackupBinaryDir.clear();
+  this->CTestRoot.clear();
+  this->CVSCheckOut.clear();
+  this->CTestCmd.clear();
+  this->UpdateCmd.clear();
+  this->CTestEnv.clear();
+  this->InitialCache.clear();
+  this->CMakeCmd.clear();
+  this->CMOutFile.clear();
   this->ExtraUpdates.clear();
 
   this->MinimumInterval = 20 * 60;
@@ -593,7 +593,7 @@
   if (!cmSystemTools::FileExists(this->SourceDir.c_str()) &&
       !this->CVSCheckOut.empty()) {
     // we must now checkout the src dir
-    output = "";
+    output.clear();
     cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                "Run cvs: " << this->CVSCheckOut << std::endl);
     res = cmSystemTools::RunSingleCommand(
@@ -659,7 +659,7 @@
       std::string fullCommand = command;
       fullCommand += " update ";
       fullCommand += cvsArgs[1];
-      output = "";
+      output.clear();
       retVal = 0;
       cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                  "Run Update: " << fullCommand << std::endl);
@@ -762,7 +762,7 @@
     command = this->CMakeCmd;
     command += " \"";
     command += this->SourceDir;
-    output = "";
+    output.clear();
     command += "\"";
     retVal = 0;
     cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -802,7 +802,7 @@
   // for each variable/argument do a putenv
   for (std::string const& ctestCommand : ctestCommands) {
     command = ctestCommand;
-    output = "";
+    output.clear();
     retVal = 0;
     cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                "Run ctest command: " << command << std::endl);
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index c2631ce..b6cd97b 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -65,7 +65,7 @@
   /**
    * Run a dashboard using a specified confiuration script
    */
-  int ProcessHandler() CM_OVERRIDE;
+  int ProcessHandler() override;
 
   /*
    * Run a script
@@ -98,9 +98,9 @@
   double GetRemainingTimeAllowed();
 
   cmCTestScriptHandler();
-  ~cmCTestScriptHandler() CM_OVERRIDE;
+  ~cmCTestScriptHandler() override;
 
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 
   void CreateCMake();
   cmake* GetCMake() { return this->CMake; }
diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h
index ade9c96..5cd185a 100644
--- a/Source/CTest/cmCTestSleepCommand.h
+++ b/Source/CTest/cmCTestSleepCommand.h
@@ -27,7 +27,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestSleepCommand* ni = new cmCTestSleepCommand;
     ni->CTest = this->CTest;
@@ -40,7 +40,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h
index 2e02838..542f27c 100644
--- a/Source/CTest/cmCTestStartCommand.h
+++ b/Source/CTest/cmCTestStartCommand.h
@@ -27,7 +27,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestStartCommand* ni = new cmCTestStartCommand;
     ni->CTest = this->CTest;
@@ -42,7 +42,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   /**
    * Will this invocation of ctest_start create a new TAG file?
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index 44f0d68..c4b84ce 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -38,7 +38,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestSubmitCommand* ni = new cmCTestSubmitCommand;
     ni->CTest = this->CTest;
@@ -47,20 +47,20 @@
   }
 
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   /**
    * The name of the command as specified in CMakeList.txt.
    */
-  std::string GetName() const CM_OVERRIDE { return "ctest_submit"; }
+  std::string GetName() const override { return "ctest_submit"; }
 
   typedef cmCTestHandlerCommand Superclass;
 
 protected:
-  cmCTestGenericHandler* InitializeHandler() CM_OVERRIDE;
+  cmCTestGenericHandler* InitializeHandler() override;
 
-  bool CheckArgumentKeyword(std::string const& arg) CM_OVERRIDE;
-  bool CheckArgumentValue(std::string const& arg) CM_OVERRIDE;
+  bool CheckArgumentKeyword(std::string const& arg) override;
+  bool CheckArgumentValue(std::string const& arg) override;
 
   enum
   {
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 18c06d3..e51e168 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -38,7 +38,7 @@
 {
 public:
   ResponseParser() { this->Status = STATUS_OK; }
-  ~ResponseParser() CM_OVERRIDE {}
+  ~ResponseParser() override {}
 
 public:
   enum StatusType
@@ -66,17 +66,17 @@
   }
 
   void StartElement(const std::string& /*name*/,
-                    const char** /*atts*/) CM_OVERRIDE
+                    const char** /*atts*/) override
   {
     this->CurrentValue.clear();
   }
 
-  void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
+  void CharacterDataHandler(const char* data, int length) override
   {
     this->CurrentValue.insert(this->CurrentValue.end(), data, data + length);
   }
 
-  void EndElement(const std::string& name) CM_OVERRIDE
+  void EndElement(const std::string& name) override
   {
     if (name == "status") {
       std::string status = cmSystemTools::UpperCase(this->GetCurrentValue());
@@ -140,10 +140,10 @@
   this->HasWarnings = false;
   this->HasErrors = false;
   this->Superclass::Initialize();
-  this->HTTPProxy = "";
+  this->HTTPProxy.clear();
   this->HTTPProxyType = 0;
-  this->HTTPProxyAuth = "";
-  this->FTPProxy = "";
+  this->HTTPProxyAuth.clear();
+  this->FTPProxy.clear();
   this->FTPProxyType = 0;
   this->LogFile = nullptr;
   this->Files.clear();
@@ -496,11 +496,11 @@
           ? ""
           : this->GetOption("RetryCount");
 
-        int delay = retryDelay == ""
+        int delay = retryDelay.empty()
           ? atoi(this->CTest->GetCTestConfiguration("CTestSubmitRetryDelay")
                    .c_str())
           : atoi(retryDelay.c_str());
-        int count = retryCount == ""
+        int count = retryCount.empty()
           ? atoi(this->CTest->GetCTestConfiguration("CTestSubmitRetryCount")
                    .c_str())
           : atoi(retryCount.c_str());
@@ -1032,14 +1032,14 @@
     ? ""
     : this->GetOption("RetryCount");
   unsigned long retryDelay = 0;
-  if (retryDelayString != "") {
+  if (!retryDelayString.empty()) {
     if (!cmSystemTools::StringToULong(retryDelayString.c_str(), &retryDelay)) {
       cmCTestLog(this->CTest, WARNING, "Invalid value for 'RETRY_DELAY' : "
                    << retryDelayString << std::endl);
     }
   }
   unsigned long retryCount = 0;
-  if (retryCountString != "") {
+  if (!retryCountString.empty()) {
     if (!cmSystemTools::StringToULong(retryCountString.c_str(), &retryCount)) {
       cmCTestLog(this->CTest, WARNING, "Invalid value for 'RETRY_DELAY' : "
                    << retryCountString << std::endl);
@@ -1361,7 +1361,7 @@
 
   std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
 
-  if (dropMethod == "" || dropMethod == "ftp") {
+  if (dropMethod.empty() || dropMethod == "ftp") {
     ofs << "Using drop method: FTP" << std::endl;
     cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
                        "   Using FTP submit method" << std::endl
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h
index 7b409fb..b4d0e77 100644
--- a/Source/CTest/cmCTestSubmitHandler.h
+++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -25,14 +25,14 @@
   typedef cmCTestGenericHandler Superclass;
 
   cmCTestSubmitHandler();
-  ~cmCTestSubmitHandler() CM_OVERRIDE { this->LogFile = nullptr; }
+  ~cmCTestSubmitHandler() override { this->LogFile = nullptr; }
 
   /*
    * The main entry point for this class
    */
-  int ProcessHandler() CM_OVERRIDE;
+  int ProcessHandler() override;
 
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 
   /** Specify a set of parts (by name) to submit.  */
   void SelectParts(std::set<cmCTest::Part> const& parts);
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index e8c8c60..11c0db9 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -25,7 +25,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestTestCommand* ni = new cmCTestTestCommand;
     ni->CTest = this->CTest;
@@ -36,11 +36,11 @@
   /**
    * The name of the command as specified in CMakeList.txt.
    */
-  std::string GetName() const CM_OVERRIDE { return "ctest_test"; }
+  std::string GetName() const override { return "ctest_test"; }
 
 protected:
   virtual cmCTestGenericHandler* InitializeActualHandler();
-  cmCTestGenericHandler* InitializeHandler() CM_OVERRIDE;
+  cmCTestGenericHandler* InitializeHandler() override;
 
   enum
   {
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 05bf4bc..5896014 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -41,7 +41,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestSubdirCommand* c = new cmCTestSubdirCommand;
     c->TestHandler = this->TestHandler;
@@ -53,7 +53,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& /*unused*/) CM_OVERRIDE;
+                   cmExecutionStatus& /*unused*/) override;
 
   cmCTestTestHandler* TestHandler;
 };
@@ -115,7 +115,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestAddSubdirectoryCommand* c = new cmCTestAddSubdirectoryCommand;
     c->TestHandler = this->TestHandler;
@@ -127,7 +127,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& /*unused*/) CM_OVERRIDE;
+                   cmExecutionStatus& /*unused*/) override;
 
   cmCTestTestHandler* TestHandler;
 };
@@ -180,7 +180,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestAddTestCommand* c = new cmCTestAddTestCommand;
     c->TestHandler = this->TestHandler;
@@ -192,7 +192,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& /*args*/,
-                   cmExecutionStatus& /*unused*/) CM_OVERRIDE;
+                   cmExecutionStatus& /*unused*/) override;
 
   cmCTestTestHandler* TestHandler;
 };
@@ -213,7 +213,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestSetTestsPropertiesCommand* c = new cmCTestSetTestsPropertiesCommand;
     c->TestHandler = this->TestHandler;
@@ -225,7 +225,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& /*args*/,
-                   cmExecutionStatus& /*unused*/) CM_OVERRIDE;
+                   cmExecutionStatus& /*unused*/) override;
 
   cmCTestTestHandler* TestHandler;
 };
@@ -242,7 +242,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestSetDirectoryPropertiesCommand* c =
       new cmCTestSetDirectoryPropertiesCommand;
@@ -255,7 +255,7 @@
    * the CMakeLists.txt file.
   */
   bool InitialPass(std::vector<std::string> const& /*unused*/,
-                   cmExecutionStatus& /*unused*/) CM_OVERRIDE;
+                   cmExecutionStatus& /*unused*/) override;
 
   cmCTestTestHandler* TestHandler;
 };
@@ -351,8 +351,8 @@
   this->TestResults.clear();
 
   this->CustomTestsIgnore.clear();
-  this->StartTest = "";
-  this->EndTest = "";
+  this->StartTest.clear();
+  this->EndTest.clear();
 
   this->CustomPreTest.clear();
   this->CustomPostTest.clear();
@@ -368,13 +368,13 @@
   this->UseExcludeRegExpFirst = false;
   this->IncludeLabelRegularExpression = "";
   this->ExcludeLabelRegularExpression = "";
-  this->IncludeRegExp = "";
-  this->ExcludeRegExp = "";
+  this->IncludeRegExp.clear();
+  this->ExcludeRegExp.clear();
   this->ExcludeFixtureRegExp.clear();
   this->ExcludeFixtureSetupRegExp.clear();
   this->ExcludeFixtureCleanupRegExp.clear();
 
-  TestsToRunString = "";
+  TestsToRunString.clear();
   this->UseUnion = false;
   this->TestList.clear();
 }
@@ -1595,9 +1595,9 @@
   // if everything else failed, check the users path, but only if a full path
   // wasn't specified
   if (fullPath.empty() && filepath.empty()) {
-    std::string path = cmSystemTools::FindProgram(filename.c_str());
-    if (path != "") {
-      resultingConfig = "";
+    std::string const path = cmSystemTools::FindProgram(filename.c_str());
+    if (!path.empty()) {
+      resultingConfig.clear();
       return path;
     }
   }
@@ -1802,7 +1802,7 @@
     if (fileNameSubstring != pattern) {
       continue;
     }
-    if (logName == "") {
+    if (logName.empty()) {
       logName = fileName;
     } else {
       // if multiple matching logs were found we use the most recently
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index eaa7a33..394d20e 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -36,7 +36,7 @@
   /**
    * The main entry point for this class
    */
-  int ProcessHandler() CM_OVERRIDE;
+  int ProcessHandler() override;
 
   /**
    * When both -R and -I are used should te resulting test list be the
@@ -54,7 +54,7 @@
   /**
    * This method is called when reading CTest custom file
    */
-  void PopulateCustomVectors(cmMakefile* mf) CM_OVERRIDE;
+  void PopulateCustomVectors(cmMakefile* mf) override;
 
   ///! Control the use of the regular expresisons, call these methods to turn
   /// them on
@@ -95,7 +95,7 @@
    */
   bool SetDirectoryProperties(const std::vector<std::string>& args);
 
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 
   // NOTE: This struct is Saved/Restored
   // in cmCTestTestHandler, if you add to this class
diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h
index ac8e85c..3b2f3e1 100644
--- a/Source/CTest/cmCTestUpdateCommand.h
+++ b/Source/CTest/cmCTestUpdateCommand.h
@@ -25,7 +25,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestUpdateCommand* ni = new cmCTestUpdateCommand;
     ni->CTest = this->CTest;
@@ -36,10 +36,10 @@
   /**
    * The name of the command as specified in CMakeList.txt.
    */
-  std::string GetName() const CM_OVERRIDE { return "ctest_update"; }
+  std::string GetName() const override { return "ctest_update"; }
 
 protected:
-  cmCTestGenericHandler* InitializeHandler() CM_OVERRIDE;
+  cmCTestGenericHandler* InitializeHandler() override;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
index 0504f90..7173439 100644
--- a/Source/CTest/cmCTestUpdateHandler.cxx
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -39,7 +39,7 @@
 void cmCTestUpdateHandler::Initialize()
 {
   this->Superclass::Initialize();
-  this->UpdateCommand = "";
+  this->UpdateCommand.clear();
   this->UpdateType = e_CVS;
 }
 
diff --git a/Source/CTest/cmCTestUpdateHandler.h b/Source/CTest/cmCTestUpdateHandler.h
index 5e7237c..0f51d3f 100644
--- a/Source/CTest/cmCTestUpdateHandler.h
+++ b/Source/CTest/cmCTestUpdateHandler.h
@@ -23,7 +23,7 @@
   /*
    * The main entry point for this class
    */
-  int ProcessHandler() CM_OVERRIDE;
+  int ProcessHandler() override;
 
   cmCTestUpdateHandler();
 
@@ -42,7 +42,7 @@
   /**
    * Initialize handler
    */
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 
 private:
   // Some structures needed for update
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
index e8e882f..61bf1cc 100644
--- a/Source/CTest/cmCTestUploadCommand.h
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -27,7 +27,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmCTestUploadCommand* ni = new cmCTestUploadCommand;
     ni->CTest = this->CTest;
@@ -38,15 +38,15 @@
   /**
    * The name of the command as specified in CMakeList.txt.
    */
-  std::string GetName() const CM_OVERRIDE { return "ctest_upload"; }
+  std::string GetName() const override { return "ctest_upload"; }
 
   typedef cmCTestHandlerCommand Superclass;
 
 protected:
-  cmCTestGenericHandler* InitializeHandler() CM_OVERRIDE;
+  cmCTestGenericHandler* InitializeHandler() override;
 
-  bool CheckArgumentKeyword(std::string const& arg) CM_OVERRIDE;
-  bool CheckArgumentValue(std::string const& arg) CM_OVERRIDE;
+  bool CheckArgumentKeyword(std::string const& arg) override;
+  bool CheckArgumentValue(std::string const& arg) override;
 
   enum
   {
diff --git a/Source/CTest/cmCTestUploadHandler.h b/Source/CTest/cmCTestUploadHandler.h
index 3dc9c10..ff50574 100644
--- a/Source/CTest/cmCTestUploadHandler.h
+++ b/Source/CTest/cmCTestUploadHandler.h
@@ -20,14 +20,14 @@
   typedef cmCTestGenericHandler Superclass;
 
   cmCTestUploadHandler();
-  ~cmCTestUploadHandler() CM_OVERRIDE {}
+  ~cmCTestUploadHandler() override {}
 
   /*
    * The main entry point for this class
    */
-  int ProcessHandler() CM_OVERRIDE;
+  int ProcessHandler() override;
 
-  void Initialize() CM_OVERRIDE;
+  void Initialize() override;
 
   /** Specify a set of files to submit.  */
   void SetFiles(cmCTest::SetOfStrings const& files);
diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx
index bf03c45..4cd6588 100644
--- a/Source/CTest/cmParseCacheCoverage.cxx
+++ b/Source/CTest/cmParseCacheCoverage.cxx
@@ -146,7 +146,7 @@
         cmCTestLog(this->CTest, ERROR_MESSAGE,
                    "Could not find mumps file for routine: " << routine
                                                              << "\n");
-        filepath = "";
+        filepath.clear();
         continue; // move to next line
       }
     }
@@ -154,8 +154,8 @@
     else {
       // Totals in arg 0 marks the end of a routine
       if (separateLine[0].substr(0, 6) == "Totals") {
-        routine = ""; // at the end of this routine
-        filepath = "";
+        routine.clear(); // at the end of this routine
+        filepath.clear();
         continue; // move to next line
       }
     }
diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h
index 7b0442a..081f5fa 100644
--- a/Source/CTest/cmParseCacheCoverage.h
+++ b/Source/CTest/cmParseCacheCoverage.h
@@ -26,7 +26,7 @@
 
 protected:
   // implement virtual from parent
-  bool LoadCoverageData(const char* dir) CM_OVERRIDE;
+  bool LoadCoverageData(const char* dir) override;
   // remove files with no coverage
   void RemoveUnCoveredFiles();
   // Read a single mcov file
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
index 71eb467..61ce7d4 100644
--- a/Source/CTest/cmParseCoberturaCoverage.cxx
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -21,13 +21,13 @@
     this->SkipThisClass = false;
     this->FilePaths.push_back(this->Coverage.SourceDir);
     this->FilePaths.push_back(this->Coverage.BinaryDir);
-    this->CurFileName = "";
+    this->CurFileName.clear();
   }
 
-  ~XMLParser() CM_OVERRIDE {}
+  ~XMLParser() override {}
 
 protected:
-  void EndElement(const std::string& name) CM_OVERRIDE
+  void EndElement(const std::string& name) override
   {
     if (name == "source") {
       this->InSource = false;
@@ -38,7 +38,7 @@
     }
   }
 
-  void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
+  void CharacterDataHandler(const char* data, int length) override
   {
     std::string tmp;
     tmp.insert(0, data, length);
@@ -50,7 +50,7 @@
     }
   }
 
-  void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
+  void StartElement(const std::string& name, const char** atts) override
   {
     std::string FoundSource;
     std::string finalpath;
@@ -67,7 +67,7 @@
                                               << std::endl,
                              this->Coverage.Quiet);
           std::string filename = atts[tagCount + 1];
-          this->CurFileName = "";
+          this->CurFileName.clear();
 
           // Check if this is an absolute path that falls within our
           // source or binary directories.
@@ -78,7 +78,7 @@
             }
           }
 
-          if (this->CurFileName == "") {
+          if (this->CurFileName.empty()) {
             // Check if this is a path that is relative to our source or
             // binary directories.
             for (std::string const& filePath : FilePaths) {
@@ -91,7 +91,7 @@
           }
 
           cmsys::ifstream fin(this->CurFileName.c_str());
-          if (this->CurFileName == "" || !fin) {
+          if (this->CurFileName.empty() || !fin) {
             this->CurFileName =
               this->Coverage.BinaryDir + "/" + atts[tagCount + 1];
             fin.open(this->CurFileName.c_str());
diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx
index 4b781a6..6d82cb2 100644
--- a/Source/CTest/cmParseDelphiCoverage.cxx
+++ b/Source/CTest/cmParseDelphiCoverage.cxx
@@ -71,7 +71,8 @@
         }
       }
       // Based up what was found, add a line to the coverageVector
-      if (!beginSet.empty() && line != "" && !blockComFlag && !lineComFlag) {
+      if (!beginSet.empty() && !line.empty() && !blockComFlag &&
+          !lineComFlag) {
         coverageVector.push_back(0);
       } else {
         coverageVector.push_back(-1);
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index e4ee699..9948ede 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -182,7 +182,7 @@
       // save the argument into the argument vector
       args.push_back(arg);
       // start on a new argument
-      arg = "";
+      arg.clear();
       // if we are at the end of the ), then finish while loop
       if (cur == ')') {
         done = true;
@@ -233,8 +233,8 @@
     // To avoid double counting of line 0 of each entry point,
     // Don't count the lines that do not give an explicit line
     // number.
-    routine = "";
-    function = "";
+    routine.clear();
+    function.clear();
   } else {
     // this is the format for this line
     // ^COVERAGE("%RSEL","SRC",count)
diff --git a/Source/CTest/cmParseGTMCoverage.h b/Source/CTest/cmParseGTMCoverage.h
index 81766f9..13afbbc 100644
--- a/Source/CTest/cmParseGTMCoverage.h
+++ b/Source/CTest/cmParseGTMCoverage.h
@@ -25,7 +25,7 @@
 
 protected:
   // implement virtual from parent
-  bool LoadCoverageData(const char* dir) CM_OVERRIDE;
+  bool LoadCoverageData(const char* dir) override;
   // Read a single mcov file
   bool ReadMCovFile(const char* f);
   // find out what line in a mumps file (filepath) the given entry point
diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx
index 1bd24b4..7acb5ca 100644
--- a/Source/CTest/cmParseJacocoCoverage.cxx
+++ b/Source/CTest/cmParseJacocoCoverage.cxx
@@ -18,25 +18,25 @@
     : CTest(ctest)
     , Coverage(cont)
   {
-    this->FilePath = "";
-    this->PackagePath = "";
-    this->PackageName = "";
+    this->FilePath.clear();
+    this->PackagePath.clear();
+    this->PackageName.clear();
   }
 
-  ~XMLParser() CM_OVERRIDE {}
+  ~XMLParser() override {}
 
 protected:
-  void EndElement(const std::string& /*name*/) CM_OVERRIDE {}
+  void EndElement(const std::string& /*name*/) override {}
 
-  void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
+  void StartElement(const std::string& name, const char** atts) override
   {
     if (name == "package") {
       this->PackageName = atts[1];
-      this->PackagePath = "";
+      this->PackagePath.clear();
     } else if (name == "sourcefile") {
       std::string fileName = atts[1];
 
-      if (this->PackagePath == "") {
+      if (this->PackagePath.empty()) {
         if (!this->FindPackagePath(fileName)) {
           cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find file: "
                        << this->PackageName << "/" << fileName << std::endl);
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index 7f2b8a0..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)
@@ -51,5 +54,4 @@
 if(CMake_HAVE_CXX_MAKE_UNIQUE)
   set(CMake_HAVE_CXX_UNIQUE_PTR 1)
 endif()
-cm_check_cxx_feature(override)
 cm_check_cxx_feature(unique_ptr)
diff --git a/Source/Checks/cm_cxx_override.cxx b/Source/Checks/cm_cxx_override.cxx
deleted file mode 100644
index 5a33fbb..0000000
--- a/Source/Checks/cm_cxx_override.cxx
+++ /dev/null
@@ -1,24 +0,0 @@
-struct Foo
-{
-  Foo() {}
-  virtual ~Foo() {}
-  virtual int test() const = 0;
-};
-
-struct Bar : Foo
-{
-  Bar() {}
-  ~Bar() override {}
-  int test() const override { return 0; }
-};
-
-int test(Foo const& foo)
-{
-  return foo.test();
-}
-
-int main()
-{
-  Bar const bar;
-  return test(bar);
-}
diff --git a/Source/CursesDialog/cmCursesBoolWidget.h b/Source/CursesDialog/cmCursesBoolWidget.h
index bd565cd..cdb9478 100644
--- a/Source/CursesDialog/cmCursesBoolWidget.h
+++ b/Source/CursesDialog/cmCursesBoolWidget.h
@@ -21,7 +21,7 @@
   // Handle user input. Called by the container of this widget
   // when this widget has focus. Returns true if the input was
   // handled.
-  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) CM_OVERRIDE;
+  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) override;
 
   // Description:
   // Set/Get the value (on/off).
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/cmCursesDummyWidget.h b/Source/CursesDialog/cmCursesDummyWidget.h
index b0c270c..c509ae7 100644
--- a/Source/CursesDialog/cmCursesDummyWidget.h
+++ b/Source/CursesDialog/cmCursesDummyWidget.h
@@ -21,7 +21,7 @@
   // Handle user input. Called by the container of this widget
   // when this widget has focus. Returns true if the input was
   // handled.
-  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) CM_OVERRIDE;
+  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) override;
 };
 
 #endif // cmCursesDummyWidget_h
diff --git a/Source/CursesDialog/cmCursesLabelWidget.h b/Source/CursesDialog/cmCursesLabelWidget.h
index 79ae241..aab559b 100644
--- a/Source/CursesDialog/cmCursesLabelWidget.h
+++ b/Source/CursesDialog/cmCursesLabelWidget.h
@@ -19,13 +19,13 @@
 public:
   cmCursesLabelWidget(int width, int height, int left, int top,
                       const std::string& name);
-  ~cmCursesLabelWidget() CM_OVERRIDE;
+  ~cmCursesLabelWidget() override;
 
   // Description:
   // Handle user input. Called by the container of this widget
   // when this widget has focus. Returns true if the input was
   // handled
-  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) CM_OVERRIDE;
+  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) override;
 };
 
 #endif // cmCursesLabelWidget_h
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.h b/Source/CursesDialog/cmCursesLongMessageForm.h
index 099c722..2bcc15a 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.h
+++ b/Source/CursesDialog/cmCursesLongMessageForm.h
@@ -18,16 +18,16 @@
 public:
   cmCursesLongMessageForm(std::vector<std::string> const& messages,
                           const char* title);
-  ~cmCursesLongMessageForm() CM_OVERRIDE;
+  ~cmCursesLongMessageForm() override;
 
   // Description:
   // Handle user input.
-  void HandleInput() CM_OVERRIDE;
+  void HandleInput() override;
 
   // Description:
   // Display form. Use a window of size width x height, starting
   // at top, left.
-  void Render(int left, int top, int width, int height) CM_OVERRIDE;
+  void Render(int left, int top, int width, int height) override;
 
   // Description:
   // This method should normally  called only by the form.
@@ -37,7 +37,7 @@
   // Description:
   // This method should normally  called only by the form.
   // The only exception is during a resize.
-  void UpdateStatusBar() CM_OVERRIDE;
+  void UpdateStatusBar() override;
 
 protected:
   std::string Messages;
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
index 96dd5c0..7f5b3ca 100644
--- a/Source/CursesDialog/cmCursesMainForm.h
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -27,7 +27,7 @@
 
 public:
   cmCursesMainForm(std::vector<std::string> const& args, int initwidth);
-  ~cmCursesMainForm() CM_OVERRIDE;
+  ~cmCursesMainForm() override;
 
   /**
    * Set the widgets which represent the cache entries.
@@ -37,13 +37,13 @@
   /**
    * Handle user input.
    */
-  void HandleInput() CM_OVERRIDE;
+  void HandleInput() override;
 
   /**
    * Display form. Use a window of size width x height, starting
    * at top, left.
    */
-  void Render(int left, int top, int width, int height) CM_OVERRIDE;
+  void Render(int left, int top, int width, int height) override;
 
   /**
    * Returns true if an entry with the given key is in the
@@ -64,7 +64,7 @@
    * exception is during a resize. The optional argument specifies the
    * string to be displayed in the status bar.
    */
-  void UpdateStatusBar() CM_OVERRIDE { this->UpdateStatusBar(nullptr); }
+  void UpdateStatusBar() override { this->UpdateStatusBar(nullptr); }
   virtual void UpdateStatusBar(const char* message);
 
   /**
@@ -80,7 +80,7 @@
    * During a CMake run, an error handle should add errors
    * to be displayed afterwards.
    */
-  void AddError(const char* message, const char* title) CM_OVERRIDE;
+  void AddError(const char* message, const char* title) override;
 
   /**
    * Used to do a configure. If argument is specified, it does only the check
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/cmCursesOptionsWidget.h b/Source/CursesDialog/cmCursesOptionsWidget.h
index 86a6946..3e50e2d 100644
--- a/Source/CursesDialog/cmCursesOptionsWidget.h
+++ b/Source/CursesDialog/cmCursesOptionsWidget.h
@@ -24,7 +24,7 @@
   // Handle user input. Called by the container of this widget
   // when this widget has focus. Returns true if the input was
   // handled.
-  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) CM_OVERRIDE;
+  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) override;
   void SetOption(const std::string&);
   void AddOption(std::string const&);
   void NextOption();
diff --git a/Source/CursesDialog/cmCursesPathWidget.h b/Source/CursesDialog/cmCursesPathWidget.h
index 6a72402..bfa0ea3 100644
--- a/Source/CursesDialog/cmCursesPathWidget.h
+++ b/Source/CursesDialog/cmCursesPathWidget.h
@@ -23,9 +23,9 @@
    * This method is called when different keys are pressed. The
    * subclass can have a special implementation handler for this.
    */
-  void OnTab(cmCursesMainForm* fm, WINDOW* w) CM_OVERRIDE;
-  void OnReturn(cmCursesMainForm* fm, WINDOW* w) CM_OVERRIDE;
-  void OnType(int& key, cmCursesMainForm* fm, WINDOW* w) CM_OVERRIDE;
+  void OnTab(cmCursesMainForm* fm, WINDOW* w) override;
+  void OnReturn(cmCursesMainForm* fm, WINDOW* w) override;
+  void OnType(int& key, cmCursesMainForm* fm, WINDOW* w) override;
 
 protected:
   std::string LastString;
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/CursesDialog/cmCursesStringWidget.h b/Source/CursesDialog/cmCursesStringWidget.h
index 5787098..90310f6 100644
--- a/Source/CursesDialog/cmCursesStringWidget.h
+++ b/Source/CursesDialog/cmCursesStringWidget.h
@@ -30,14 +30,14 @@
    * when this widget has focus. Returns true if the input was
    * handled.
    */
-  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) CM_OVERRIDE;
+  bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) override;
 
   /**
    * Set/Get the string.
    */
   void SetString(const std::string& value);
   const char* GetString();
-  const char* GetValue() CM_OVERRIDE;
+  const char* GetValue() override;
 
   /**
    * Set/Get InEdit flag. Can be used to tell the widget to leave
@@ -59,7 +59,7 @@
    * in the toolbar and return true. Otherwise, return false
    * and the parent widget will print.
    */
-  bool PrintKeys() CM_OVERRIDE;
+  bool PrintKeys() override;
 
 protected:
   // true if the widget is in edit mode
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 9f881e2..ca0b015 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -92,6 +92,10 @@
   cmAddPluginPath();
 #endif
 
+#if QT_VERSION >= 0x050600
+  QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+#endif
+
   QApplication app(argc, argv);
 
   setlocale(LC_NUMERIC, "C");
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index c6b007d..1b3fb15 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -23,7 +23,7 @@
   }
 
 protected:
-  bool filterAcceptsRow(int row, const QModelIndex& p) const CM_OVERRIDE
+  bool filterAcceptsRow(int row, const QModelIndex& p) const override
   {
     QStringList strs;
     const QAbstractItemModel* m = this->sourceModel();
@@ -77,7 +77,7 @@
 protected:
   bool ShowAdvanced;
 
-  bool filterAcceptsRow(int row, const QModelIndex& p) const CM_OVERRIDE
+  bool filterAcceptsRow(int row, const QModelIndex& p) const override
   {
     const QAbstractItemModel* m = this->sourceModel();
     QModelIndex idx = m->index(row, 0, p);
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 05e1c66..2eb47f3 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -218,7 +218,7 @@
           *    The name of the Function entry points
           */
           if (pSymbolTable->N.Name.Short != 0) {
-            symbol = "";
+            symbol.clear();
             symbol.insert(0, (const char*)pSymbolTable->N.ShortName, 8);
           } else {
             symbol = stringTable + pSymbolTable->N.Name.Long;
diff --git a/Source/cmAddCompileOptionsCommand.h b/Source/cmAddCompileOptionsCommand.h
index 7eac314..3d53d09 100644
--- a/Source/cmAddCompileOptionsCommand.h
+++ b/Source/cmAddCompileOptionsCommand.h
@@ -18,14 +18,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAddCompileOptionsCommand; }
+  cmCommand* Clone() override { return new cmAddCompileOptionsCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h
index 95c58d9..6af4f10 100644
--- a/Source/cmAddCustomCommandCommand.h
+++ b/Source/cmAddCustomCommandCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAddCustomCommandCommand; }
+  cmCommand* Clone() override { return new cmAddCustomCommandCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 protected:
   bool CheckOutputs(const std::vector<std::string>& outputs);
diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h
index 8d9d09f..1a55116 100644
--- a/Source/cmAddCustomTargetCommand.h
+++ b/Source/cmAddCustomTargetCommand.h
@@ -25,14 +25,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAddCustomTargetCommand; }
+  cmCommand* Clone() override { return new cmAddCustomTargetCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h
index a58d430..7b75638 100644
--- a/Source/cmAddDefinitionsCommand.h
+++ b/Source/cmAddDefinitionsCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAddDefinitionsCommand; }
+  cmCommand* Clone() override { return new cmAddDefinitionsCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h
index 10f3c57..e10df71 100644
--- a/Source/cmAddDependenciesCommand.h
+++ b/Source/cmAddDependenciesCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAddDependenciesCommand; }
+  cmCommand* Clone() override { return new cmAddDependenciesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h
index 570b35f..bdf607d 100644
--- a/Source/cmAddExecutableCommand.h
+++ b/Source/cmAddExecutableCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAddExecutableCommand; }
+  cmCommand* Clone() override { return new cmAddExecutableCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
index 1656312..aa21261 100644
--- a/Source/cmAddLibraryCommand.h
+++ b/Source/cmAddLibraryCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAddLibraryCommand; }
+  cmCommand* Clone() override { return new cmAddLibraryCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h
index a6c92a8..0ea4423 100644
--- a/Source/cmAddSubDirectoryCommand.h
+++ b/Source/cmAddSubDirectoryCommand.h
@@ -25,14 +25,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAddSubDirectoryCommand; }
+  cmCommand* Clone() override { return new cmAddSubDirectoryCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h
index a296904..bea3f3d 100644
--- a/Source/cmAddTestCommand.h
+++ b/Source/cmAddTestCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAddTestCommand; }
+  cmCommand* Clone() override { return new cmAddTestCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   bool HandleNameMode(std::vector<std::string> const& args);
diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h
index ea22855..3742e3e 100644
--- a/Source/cmAuxSourceDirectoryCommand.h
+++ b/Source/cmAuxSourceDirectoryCommand.h
@@ -27,14 +27,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmAuxSourceDirectoryCommand; }
+  cmCommand* Clone() override { return new cmAuxSourceDirectoryCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h
index c0a5e11..3b18567 100644
--- a/Source/cmBreakCommand.h
+++ b/Source/cmBreakCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmBreakCommand; }
+  cmCommand* Clone() override { return new cmBreakCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h
index 17e9636..e0529a4 100644
--- a/Source/cmBuildCommand.h
+++ b/Source/cmBuildCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmBuildCommand; }
+  cmCommand* Clone() override { return new cmBuildCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   /**
    * The primary command signature with optional, KEYWORD-based args.
diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx
index 9d2c0c6..5f54338 100644
--- a/Source/cmBuildNameCommand.cxx
+++ b/Source/cmBuildNameCommand.cxx
@@ -36,7 +36,7 @@
 
   std::string buildname = "WinNT";
   if (this->Makefile->GetDefinition("UNIX")) {
-    buildname = "";
+    buildname.clear();
     cmSystemTools::RunSingleCommand("uname -a", &buildname, &buildname);
     if (!buildname.empty()) {
       std::string RegExp = "([^ ]*) [^ ]* ([^ ]*) ";
diff --git a/Source/cmBuildNameCommand.h b/Source/cmBuildNameCommand.h
index e3d2f2a..4bb72d1 100644
--- a/Source/cmBuildNameCommand.h
+++ b/Source/cmBuildNameCommand.h
@@ -15,9 +15,9 @@
 class cmBuildNameCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmBuildNameCommand; }
+  cmCommand* Clone() override { return new cmBuildNameCommand; }
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmCMakeHostSystemInformationCommand.h b/Source/cmCMakeHostSystemInformationCommand.h
index b3c05d4..bfff8f1 100644
--- a/Source/cmCMakeHostSystemInformationCommand.h
+++ b/Source/cmCMakeHostSystemInformationCommand.h
@@ -28,7 +28,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     return new cmCMakeHostSystemInformationCommand;
   }
@@ -38,7 +38,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   bool GetValue(cmsys::SystemInformation& info, std::string const& key,
diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h
index 4a979de..18d9460 100644
--- a/Source/cmCMakeMinimumRequired.h
+++ b/Source/cmCMakeMinimumRequired.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmCMakeMinimumRequired; }
+  cmCommand* Clone() override { return new cmCMakeMinimumRequired; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   std::vector<std::string> UnknownArguments;
diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h
index f9c51c3..b18576c 100644
--- a/Source/cmCMakePolicyCommand.h
+++ b/Source/cmCMakePolicyCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmCMakePolicyCommand; }
+  cmCommand* Clone() override { return new cmCMakePolicyCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   bool HandleSetMode(std::vector<std::string> const& args);
diff --git a/Source/cmCPackPropertiesGenerator.h b/Source/cmCPackPropertiesGenerator.h
index c5885f2..e580e04 100644
--- a/Source/cmCPackPropertiesGenerator.h
+++ b/Source/cmCPackPropertiesGenerator.h
@@ -29,7 +29,7 @@
 
 protected:
   void GenerateScriptForConfig(std::ostream& os, const std::string& config,
-                               Indent indent) CM_OVERRIDE;
+                               Indent indent) override;
 
   cmLocalGenerator* LG;
   cmInstalledFile const& InstalledFile;
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 1325fd3..ba50986 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -147,7 +147,7 @@
 std::string cmCTest::GetCostDataFile()
 {
   std::string fname = this->GetCTestConfiguration("CostDataFile");
-  if (fname == "") {
+  if (fname.empty()) {
     fname = this->GetBinaryDir() + "/Testing/Temporary/CTestCostData.txt";
   }
   return fname;
@@ -281,9 +281,9 @@
   this->GlobalTimeout = 0;
   this->LastStopTimeout = 24 * 60 * 60;
   this->CompressXMLFiles = false;
-  this->CTestConfigFile = "";
-  this->ScheduleType = "";
-  this->StopTime = "";
+  this->CTestConfigFile.clear();
+  this->ScheduleType.clear();
+  this->StopTime.clear();
   this->NextDayStopTime = false;
   this->OutputLogFile = nullptr;
   this->OutputLogFileLastTag = -1;
@@ -477,7 +477,7 @@
                &min);
         if (year != lctime->tm_year + 1900 || mon != lctime->tm_mon + 1 ||
             day != lctime->tm_mday) {
-          tag = "";
+          tag.clear();
         }
         std::string tagmode;
         if (cmSystemTools::GetLineFromStream(tfin, tagmode)) {
@@ -975,7 +975,7 @@
   }
   argv.push_back(nullptr);
 
-  output = "";
+  output.clear();
   cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Run command:");
   for (char const* arg : argv) {
     if (!arg) {
@@ -1147,7 +1147,7 @@
   }
   std::vector<char> tempOutput;
   if (output) {
-    *output = "";
+    output->clear();
   }
 
   CM_AUTO_PTR<cmSystemTools::SaveRestoreEnvironment> saveEnv;
@@ -1235,7 +1235,7 @@
 {
   std::string safevalue(value);
 
-  if (safevalue != "") {
+  if (!safevalue.empty()) {
     // Disallow non-filename and non-space whitespace characters.
     // If they occur, replace them with ""
     //
@@ -1254,7 +1254,7 @@
     }
   }
 
-  if (safevalue == "") {
+  if (safevalue.empty()) {
     safevalue = "(empty)";
   }
 
@@ -2513,7 +2513,7 @@
 void cmCTest::SetSpecificTrack(const char* track)
 {
   if (!track) {
-    this->SpecificTrack = "";
+    this->SpecificTrack.clear();
     return;
   }
   this->SpecificTrack = track;
@@ -2565,24 +2565,18 @@
   return true;
 }
 
-bool cmCTest::RunCommand(const char* command, std::string* stdOut,
-                         std::string* stdErr, int* retVal, const char* dir,
-                         double timeout, Encoding encoding)
+bool cmCTest::RunCommand(std::vector<std::string> const& args,
+                         std::string* stdOut, std::string* stdErr, int* retVal,
+                         const char* dir, double timeout, Encoding encoding)
 {
-  std::vector<std::string> args = cmSystemTools::ParseArguments(command);
-
-  if (args.empty()) {
-    return false;
-  }
-
   std::vector<const char*> argv;
   for (std::string const& a : args) {
     argv.push_back(a.c_str());
   }
   argv.push_back(nullptr);
 
-  *stdOut = "";
-  *stdErr = "";
+  stdOut->clear();
+  stdErr->clear();
 
   cmsysProcess* cp = cmsysProcess_New();
   cmsysProcess_SetCommand(cp, &*argv.begin());
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 66e6a26..dbd67dc 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -245,13 +245,8 @@
    * exit code will be stored. If the retVal is not specified and
    * the program exits with a code other than 0, then the this
    * function will return false.
-   *
-   * If the command has spaces in the path the caller MUST call
-   * cmSystemTools::ConvertToRunCommandPath on the command before passing
-   * it into this function or it will not work.  The command must be correctly
-   * escaped for this to with spaces.
    */
-  bool RunCommand(const char* command, std::string* stdOut,
+  bool RunCommand(std::vector<std::string> const& args, std::string* stdOut,
                   std::string* stdErr, int* retVal = nullptr,
                   const char* dir = nullptr, double timeout = 0.0,
                   Encoding encoding = cmProcessOutput::Auto);
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index 56f48c3..44095ec 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -480,7 +480,7 @@
     e.Value = value;
     e.Initialized = true;
   } else {
-    e.Value = "";
+    e.Value.clear();
   }
   e.Type = type;
   // make sure we only use unix style paths
@@ -543,7 +543,7 @@
     entry->Value = value;
     entry->Initialized = true;
   } else {
-    entry->Value = "";
+    entry->Value.clear();
   }
 }
 
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index f9daf5f..6ae58d6 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -234,7 +234,7 @@
   this->InputBufferPos = 0;
   this->CurrentLine = 0;
 
-  this->Result = "";
+  this->Result.clear();
 
   yyscan_t yyscanner;
   cmCommandArgument_yylex_init(&yyscanner);
@@ -298,7 +298,7 @@
 void cmCommandArgumentParserHelper::SetResult(const char* value)
 {
   if (!value) {
-    this->Result = "";
+    this->Result.clear();
     return;
   }
   this->Result = value;
diff --git a/Source/cmCommandArgumentsHelper.cxx b/Source/cmCommandArgumentsHelper.cxx
index 651b3c8..968b17c 100644
--- a/Source/cmCommandArgumentsHelper.cxx
+++ b/Source/cmCommandArgumentsHelper.cxx
@@ -133,7 +133,7 @@
 
 void cmCAString::DoReset()
 {
-  this->String = "";
+  this->String.clear();
 }
 
 cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args, const char* key,
diff --git a/Source/cmCommandArgumentsHelper.h b/Source/cmCommandArgumentsHelper.h
index 56d88e9..d3f102c 100644
--- a/Source/cmCommandArgumentsHelper.h
+++ b/Source/cmCommandArgumentsHelper.h
@@ -103,8 +103,8 @@
   unsigned int DataStart;
   const char* Ignore;
   cmCAStringVector();
-  bool DoConsume(const std::string& arg, unsigned int index) CM_OVERRIDE;
-  void DoReset() CM_OVERRIDE;
+  bool DoConsume(const std::string& arg, unsigned int index) override;
+  void DoReset() override;
 };
 
 /** cmCAString is to be used for arguments which consist of one value,
@@ -121,8 +121,8 @@
 private:
   std::string String;
   unsigned int DataStart;
-  bool DoConsume(const std::string& arg, unsigned int index) CM_OVERRIDE;
-  void DoReset() CM_OVERRIDE;
+  bool DoConsume(const std::string& arg, unsigned int index) override;
+  void DoReset() override;
   cmCAString();
 };
 
@@ -138,8 +138,8 @@
   bool IsEnabled() const { return this->Enabled; }
 private:
   bool Enabled;
-  bool DoConsume(const std::string& arg, unsigned int index) CM_OVERRIDE;
-  void DoReset() CM_OVERRIDE;
+  bool DoConsume(const std::string& arg, unsigned int index) override;
+  void DoReset() override;
   cmCAEnabler();
 };
 
@@ -155,8 +155,8 @@
   bool IsEnabled() const { return this->Enabled; }
 private:
   bool Enabled;
-  bool DoConsume(const std::string& arg, unsigned int index) CM_OVERRIDE;
-  void DoReset() CM_OVERRIDE;
+  bool DoConsume(const std::string& arg, unsigned int index) override;
+  void DoReset() override;
   cmCADisabler();
 };
 
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 0311043..fb13a58 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -1483,7 +1483,7 @@
       if (!line.empty() && (line.size() + i.size() + 2) > max_size) {
         os << line << "\n";
         sep = "  ";
-        line = "";
+        line.clear();
       }
       line += sep;
       line += i;
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index f4d48d2..90b3f6d 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -83,7 +83,7 @@
   const std::vector<cmExpandedCommandArgument>& args, std::string& errorString,
   cmake::MessageType& status)
 {
-  errorString = "";
+  errorString.clear();
 
   // handle empty invocation
   if (args.empty()) {
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index e91471c..9d11fff 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -25,7 +25,6 @@
 #cmakedefine CMake_HAVE_CXX_GNU_FALLTHROUGH
 #cmakedefine CMake_HAVE_CXX_ATTRIBUTE_FALLTHROUGH
 #cmakedefine CMake_HAVE_CXX_MAKE_UNIQUE
-#cmakedefine CMake_HAVE_CXX_OVERRIDE
 #cmakedefine CMake_HAVE_CXX_UNIQUE_PTR
 #define CMAKE_BIN_DIR "/@CMAKE_BIN_DIR@"
 #define CMAKE_DATA_DIR "/@CMAKE_DATA_DIR@"
@@ -46,12 +45,6 @@
 #define CM_FALLTHROUGH
 #endif
 
-#ifdef CMake_HAVE_CXX_OVERRIDE
-#define CM_OVERRIDE override
-#else
-#define CM_OVERRIDE
-#endif
-
 #define CM_DISABLE_COPY(Class)                                                \
   Class(Class const&) CM_EQ_DELETE;                                           \
   Class& operator=(Class const&) CM_EQ_DELETE;
diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h
index 54ca0bf..cff934b 100644
--- a/Source/cmConfigureFileCommand.h
+++ b/Source/cmConfigureFileCommand.h
@@ -16,14 +16,14 @@
 class cmConfigureFileCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmConfigureFileCommand; }
+  cmCommand* Clone() override { return new cmConfigureFileCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   int ConfigureFile();
diff --git a/Source/cmContinueCommand.h b/Source/cmContinueCommand.h
index 51f991d..d383d1d 100644
--- a/Source/cmContinueCommand.h
+++ b/Source/cmContinueCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmContinueCommand; }
+  cmCommand* Clone() override { return new cmContinueCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index d1270a0..fd258fe 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -71,7 +71,7 @@
                                      bool isTryRun)
 {
   this->BinaryDirectory = argv[1];
-  this->OutputFile = "";
+  this->OutputFile.clear();
   // which signature were we called with ?
   this->SrcFileSignature = true;
 
@@ -919,8 +919,8 @@
 void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
                                       cmStateEnums::TargetType targetType)
 {
-  this->FindErrorMessage = "";
-  this->OutputFile = "";
+  this->FindErrorMessage.clear();
+  this->OutputFile.clear();
   std::string tmpOutputFile = "/";
   if (targetType == cmStateEnums::EXECUTABLE) {
     tmpOutputFile += targetName;
diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h
index 47fb610..005b32c 100644
--- a/Source/cmCreateTestSourceList.h
+++ b/Source/cmCreateTestSourceList.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmCreateTestSourceList; }
+  cmCommand* Clone() override { return new cmCreateTestSourceList; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h
index 43f6c58..a9c1856 100644
--- a/Source/cmDefinePropertyCommand.h
+++ b/Source/cmDefinePropertyCommand.h
@@ -15,14 +15,14 @@
 class cmDefinePropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmDefinePropertyCommand; }
+  cmCommand* Clone() override { return new cmDefinePropertyCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   std::string PropertyName;
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 7780ccf..2f76f62 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -33,13 +33,13 @@
              const std::map<std::string, DependencyVector>* validDeps);
 
   /** Virtual destructor to cleanup subclasses properly.  */
-  ~cmDependsC() CM_OVERRIDE;
+  ~cmDependsC() override;
 
 protected:
   // Implement writing/checking methods required by superclass.
   bool WriteDependencies(const std::set<std::string>& sources,
                          const std::string& obj, std::ostream& makeDepends,
-                         std::ostream& internalDepends) CM_OVERRIDE;
+                         std::ostream& internalDepends) override;
 
   // Method to scan a single file.
   void Scan(std::istream& is, const char* directory,
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index f209f3c..fdbc086 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -219,7 +219,7 @@
                                           info.Provides.end());
 
     for (std::string const& r : info.Requires) {
-      this->Internal->TargetRequires[r] = "";
+      this->Internal->TargetRequires[r].clear();
     }
   }
 
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 42879f1..ccf267b 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -35,7 +35,7 @@
   cmDependsFortran(cmLocalGenerator* lg);
 
   /** Virtual destructor to cleanup subclasses properly.  */
-  ~cmDependsFortran() CM_OVERRIDE;
+  ~cmDependsFortran() override;
 
   /** Callback from build system after a .mod file has been generated
       by a Fortran90 compiler to copy the .mod file to the
@@ -50,7 +50,7 @@
 protected:
   // Finalize the dependency information for the target.
   bool Finalize(std::ostream& makeDepends,
-                std::ostream& internalDepends) CM_OVERRIDE;
+                std::ostream& internalDepends) override;
 
   // Find all the modules required by the target.
   void LocateModules();
@@ -62,7 +62,7 @@
   // Implement writing/checking methods required by superclass.
   bool WriteDependencies(const std::set<std::string>& sources,
                          const std::string& file, std::ostream& makeDepends,
-                         std::ostream& internalDepends) CM_OVERRIDE;
+                         std::ostream& internalDepends) override;
 
   // Actually write the depenencies to the streams.
   bool WriteDependenciesReal(const char* obj, cmFortranSourceInfo const& info,
diff --git a/Source/cmDependsJava.h b/Source/cmDependsJava.h
index 4fd5960..d070840 100644
--- a/Source/cmDependsJava.h
+++ b/Source/cmDependsJava.h
@@ -25,16 +25,16 @@
   cmDependsJava();
 
   /** Virtual destructor to cleanup subclasses properly.  */
-  ~cmDependsJava() CM_OVERRIDE;
+  ~cmDependsJava() override;
 
 protected:
   // Implement writing/checking methods required by superclass.
   bool WriteDependencies(const std::set<std::string>& sources,
                          const std::string& file, std::ostream& makeDepends,
-                         std::ostream& internalDepends) CM_OVERRIDE;
+                         std::ostream& internalDepends) override;
   bool CheckDependencies(
     std::istream& internalDepends, const char* internalDependsFileName,
-    std::map<std::string, DependencyVector>& validDeps) CM_OVERRIDE;
+    std::map<std::string, DependencyVector>& validDeps) override;
 };
 
 #endif
diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx
index 85dfc7d..f227cf2 100644
--- a/Source/cmDependsJavaParserHelper.cxx
+++ b/Source/cmDependsJavaParserHelper.cxx
@@ -310,7 +310,7 @@
 void cmDependsJavaParserHelper::UpdateCombine(const char* str1,
                                               const char* str2)
 {
-  if (this->CurrentCombine == "" && str1 != nullptr) {
+  if (this->CurrentCombine.empty() && str1 != nullptr) {
     this->CurrentCombine = str1;
   }
   this->CurrentCombine += ".";
diff --git a/Source/cmDisallowedCommand.h b/Source/cmDisallowedCommand.h
index d5bb79a..d85c00f 100644
--- a/Source/cmDisallowedCommand.h
+++ b/Source/cmDisallowedCommand.h
@@ -24,23 +24,20 @@
   {
   }
 
-  ~cmDisallowedCommand() CM_OVERRIDE { delete this->Command; }
+  ~cmDisallowedCommand() override { delete this->Command; }
 
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     return new cmDisallowedCommand(this->Command->Clone(), this->Policy,
                                    this->Message);
   }
 
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
-  void FinalPass() CM_OVERRIDE { this->Command->FinalPass(); }
+  void FinalPass() override { this->Command->FinalPass(); }
 
-  bool HasFinalPass() const CM_OVERRIDE
-  {
-    return this->Command->HasFinalPass();
-  }
+  bool HasFinalPass() const override { return this->Command->HasFinalPass(); }
 
 private:
   cmCommand* Command;
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 62d875c..2d6d8f9 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -235,23 +235,23 @@
                     ByteOrderType order);
 
   // Return the number of sections as specified by the ELF header.
-  unsigned int GetNumberOfSections() const CM_OVERRIDE
+  unsigned int GetNumberOfSections() const override
   {
     return static_cast<unsigned int>(this->ELFHeader.e_shnum);
   }
 
   // Get the file position of a dynamic section entry.
-  unsigned long GetDynamicEntryPosition(int j) CM_OVERRIDE;
+  unsigned long GetDynamicEntryPosition(int j) override;
 
-  cmELF::DynamicEntryList GetDynamicEntries() CM_OVERRIDE;
-  std::vector<char> EncodeDynamicEntries(const cmELF::DynamicEntryList&)
-    CM_OVERRIDE;
+  cmELF::DynamicEntryList GetDynamicEntries() override;
+  std::vector<char> EncodeDynamicEntries(
+    const cmELF::DynamicEntryList&) override;
 
   // Lookup a string from the dynamic section with the given tag.
-  StringEntry const* GetDynamicSectionString(unsigned int tag) CM_OVERRIDE;
+  StringEntry const* GetDynamicSectionString(unsigned int tag) override;
 
   // Print information about the ELF file.
-  void PrintInfo(std::ostream& os) const CM_OVERRIDE
+  void PrintInfo(std::ostream& os) const override
   {
     os << "ELF " << Types::GetName();
     if (this->ByteOrder == ByteOrderMSB) {
diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h
index 2b8cc24..97645a9 100644
--- a/Source/cmEnableLanguageCommand.h
+++ b/Source/cmEnableLanguageCommand.h
@@ -26,14 +26,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmEnableLanguageCommand; }
+  cmCommand* Clone() override { return new cmEnableLanguageCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h
index 1743b25..88a17b9 100644
--- a/Source/cmEnableTestingCommand.h
+++ b/Source/cmEnableTestingCommand.h
@@ -31,14 +31,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmEnableTestingCommand; }
+  cmCommand* Clone() override { return new cmEnableTestingCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) CM_OVERRIDE;
+                   cmExecutionStatus&) override;
 };
 
 #endif
diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h
index e3d696e..dc5da74 100644
--- a/Source/cmExecProgramCommand.h
+++ b/Source/cmExecProgramCommand.h
@@ -27,14 +27,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmExecProgramCommand; }
+  cmCommand* Clone() override { return new cmExecProgramCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   static bool RunCommand(const char* command, std::string& output, int& retVal,
diff --git a/Source/cmExecuteProcessCommand.h b/Source/cmExecuteProcessCommand.h
index dcf7b1c..b415deb 100644
--- a/Source/cmExecuteProcessCommand.h
+++ b/Source/cmExecuteProcessCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmExecuteProcessCommand; }
+  cmCommand* Clone() override { return new cmExecuteProcessCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmExportBuildAndroidMKGenerator.h b/Source/cmExportBuildAndroidMKGenerator.h
index db386f0..c80839b 100644
--- a/Source/cmExportBuildAndroidMKGenerator.h
+++ b/Source/cmExportBuildAndroidMKGenerator.h
@@ -42,25 +42,24 @@
 
 protected:
   // Implement virtual methods from the superclass.
-  void GeneratePolicyHeaderCode(std::ostream&) CM_OVERRIDE {}
-  void GeneratePolicyFooterCode(std::ostream&) CM_OVERRIDE {}
+  void GeneratePolicyHeaderCode(std::ostream&) override {}
+  void GeneratePolicyFooterCode(std::ostream&) override {}
   void GenerateImportHeaderCode(std::ostream& os,
-                                const std::string& config = "") CM_OVERRIDE;
-  void GenerateImportFooterCode(std::ostream& os) CM_OVERRIDE;
+                                const std::string& config = "") override;
+  void GenerateImportFooterCode(std::ostream& os) override;
   void GenerateImportTargetCode(std::ostream& os,
-                                const cmGeneratorTarget* target) CM_OVERRIDE;
+                                const cmGeneratorTarget* target) override;
   void GenerateExpectedTargetsCode(
-    std::ostream& os, const std::string& expectedTargets) CM_OVERRIDE;
-  void GenerateImportPropertyCode(std::ostream& os, const std::string& config,
-                                  cmGeneratorTarget const* target,
-                                  ImportPropertyMap const& properties)
-    CM_OVERRIDE;
+    std::ostream& os, const std::string& expectedTargets) override;
+  void GenerateImportPropertyCode(
+    std::ostream& os, const std::string& config,
+    cmGeneratorTarget const* target,
+    ImportPropertyMap const& properties) override;
   void GenerateMissingTargetsCheckCode(
-    std::ostream& os,
-    const std::vector<std::string>& missingTargets) CM_OVERRIDE;
+    std::ostream& os, const std::vector<std::string>& missingTargets) override;
   void GenerateInterfaceProperties(
     cmGeneratorTarget const* target, std::ostream& os,
-    const ImportPropertyMap& properties) CM_OVERRIDE;
+    const ImportPropertyMap& properties) override;
 };
 
 #endif
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index d509453..6457a77 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -49,14 +49,14 @@
 
 protected:
   // Implement virtual methods from the superclass.
-  bool GenerateMainFile(std::ostream& os) CM_OVERRIDE;
+  bool GenerateMainFile(std::ostream& os) override;
   void GenerateImportTargetsConfig(
     std::ostream& os, const std::string& config, std::string const& suffix,
-    std::vector<std::string>& missingTargets) CM_OVERRIDE;
+    std::vector<std::string>& missingTargets) override;
   void HandleMissingTarget(std::string& link_libs,
                            std::vector<std::string>& missingTargets,
                            cmGeneratorTarget* depender,
-                           cmGeneratorTarget* dependee) CM_OVERRIDE;
+                           cmGeneratorTarget* dependee) override;
 
   void ComplainAboutMissingTarget(cmGeneratorTarget* depender,
                                   cmGeneratorTarget* dependee,
@@ -69,7 +69,7 @@
                                  ImportPropertyMap& properties);
 
   std::string InstallNameDir(cmGeneratorTarget* target,
-                             const std::string& config) CM_OVERRIDE;
+                             const std::string& config) override;
 
   std::vector<std::string> FindNamespaces(cmGlobalGenerator* gg,
                                           const std::string& name);
diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h
index 7b6ad11..a5c6751 100644
--- a/Source/cmExportCommand.h
+++ b/Source/cmExportCommand.h
@@ -27,14 +27,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmExportCommand; }
+  cmCommand* Clone() override { return new cmExportCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   cmCommandArgumentsHelper Helper;
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 52f0e27..e729632 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -137,7 +137,7 @@
   if (input) {
     if (!*input) {
       // Set to empty
-      properties[outputName] = "";
+      properties[outputName].clear();
       return;
     }
 
@@ -313,7 +313,7 @@
 {
   std::vector<std::string> entries;
   cmGeneratorExpression::Split(exportDirs, entries);
-  exportDirs = "";
+  exportDirs.clear();
   const char* sep = "";
   for (std::string const& e : entries) {
     exportDirs += sep;
@@ -341,7 +341,7 @@
   }
 
   if (!*input) {
-    properties[propName] = "";
+    properties[propName].clear();
     return;
   }
 
@@ -394,7 +394,7 @@
   }
   if ((input && !*input) && exportDirs.empty()) {
     // Set to empty
-    properties[propName] = "";
+    properties[propName].clear();
     return;
   }
 
@@ -565,7 +565,7 @@
   cmGeneratorExpression::Split(input, parts);
 
   std::string sep;
-  input = "";
+  input.clear();
   for (std::string& li : parts) {
     if (cmGeneratorExpression::Find(li) == std::string::npos) {
       this->AddTargetNamespace(li, target, missingTargets);
@@ -713,7 +713,7 @@
   }
 
   if (!*propContent) {
-    properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = "";
+    properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix].clear();
     return;
   }
 
diff --git a/Source/cmExportInstallAndroidMKGenerator.h b/Source/cmExportInstallAndroidMKGenerator.h
index bb43513..3165982 100644
--- a/Source/cmExportInstallAndroidMKGenerator.h
+++ b/Source/cmExportInstallAndroidMKGenerator.h
@@ -36,37 +36,36 @@
 
 protected:
   // Implement virtual methods from the superclass.
-  void GeneratePolicyHeaderCode(std::ostream&) CM_OVERRIDE {}
-  void GeneratePolicyFooterCode(std::ostream&) CM_OVERRIDE {}
+  void GeneratePolicyHeaderCode(std::ostream&) override {}
+  void GeneratePolicyFooterCode(std::ostream&) override {}
   void GenerateImportHeaderCode(std::ostream& os,
-                                const std::string& config = "") CM_OVERRIDE;
-  void GenerateImportFooterCode(std::ostream& os) CM_OVERRIDE;
+                                const std::string& config = "") override;
+  void GenerateImportFooterCode(std::ostream& os) override;
   void GenerateImportTargetCode(std::ostream& os,
-                                const cmGeneratorTarget* target) CM_OVERRIDE;
+                                const cmGeneratorTarget* target) override;
   void GenerateExpectedTargetsCode(
-    std::ostream& os, const std::string& expectedTargets) CM_OVERRIDE;
-  void GenerateImportPropertyCode(std::ostream& os, const std::string& config,
-                                  cmGeneratorTarget const* target,
-                                  ImportPropertyMap const& properties)
-    CM_OVERRIDE;
+    std::ostream& os, const std::string& expectedTargets) override;
+  void GenerateImportPropertyCode(
+    std::ostream& os, const std::string& config,
+    cmGeneratorTarget const* target,
+    ImportPropertyMap const& properties) override;
   void GenerateMissingTargetsCheckCode(
-    std::ostream& os,
-    const std::vector<std::string>& missingTargets) CM_OVERRIDE;
+    std::ostream& os, const std::vector<std::string>& missingTargets) override;
   void GenerateInterfaceProperties(
     cmGeneratorTarget const* target, std::ostream& os,
-    const ImportPropertyMap& properties) CM_OVERRIDE;
-  void GenerateImportPrefix(std::ostream& os) CM_OVERRIDE;
-  void LoadConfigFiles(std::ostream&) CM_OVERRIDE;
+    const ImportPropertyMap& properties) override;
+  void GenerateImportPrefix(std::ostream& os) override;
+  void LoadConfigFiles(std::ostream&) override;
   void GenerateRequiredCMakeVersion(std::ostream& os,
-                                    const char* versionString) CM_OVERRIDE;
-  void CleanupTemporaryVariables(std::ostream&) CM_OVERRIDE;
-  void GenerateImportedFileCheckLoop(std::ostream& os) CM_OVERRIDE;
+                                    const char* versionString) override;
+  void CleanupTemporaryVariables(std::ostream&) override;
+  void GenerateImportedFileCheckLoop(std::ostream& os) override;
   void GenerateImportedFileChecksCode(
     std::ostream& os, cmGeneratorTarget* target,
     ImportPropertyMap const& properties,
-    const std::set<std::string>& importedLocations) CM_OVERRIDE;
+    const std::set<std::string>& importedLocations) override;
   bool GenerateImportFileConfig(const std::string& config,
-                                std::vector<std::string>&) CM_OVERRIDE;
+                                std::vector<std::string>&) override;
 };
 
 #endif
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index e535873..cda8433 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -53,16 +53,16 @@
 
 protected:
   // Implement virtual methods from the superclass.
-  bool GenerateMainFile(std::ostream& os) CM_OVERRIDE;
+  bool GenerateMainFile(std::ostream& os) override;
   void GenerateImportTargetsConfig(
     std::ostream& os, const std::string& config, std::string const& suffix,
-    std::vector<std::string>& missingTargets) CM_OVERRIDE;
+    std::vector<std::string>& missingTargets) override;
   void HandleMissingTarget(std::string& link_libs,
                            std::vector<std::string>& missingTargets,
                            cmGeneratorTarget* depender,
-                           cmGeneratorTarget* dependee) CM_OVERRIDE;
+                           cmGeneratorTarget* dependee) override;
 
-  void ReplaceInstallPrefix(std::string& input) CM_OVERRIDE;
+  void ReplaceInstallPrefix(std::string& input) override;
 
   void ComplainAboutMissingTarget(cmGeneratorTarget* depender,
                                   cmGeneratorTarget* dependee,
@@ -91,7 +91,7 @@
                                  std::set<std::string>& importedLocations);
 
   std::string InstallNameDir(cmGeneratorTarget* target,
-                             const std::string& config) CM_OVERRIDE;
+                             const std::string& config) override;
 
   cmInstallExportGenerator* IEGen;
 
diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h
index 286a3e0..bf5e9bc 100644
--- a/Source/cmExportLibraryDependenciesCommand.h
+++ b/Source/cmExportLibraryDependenciesCommand.h
@@ -15,15 +15,15 @@
 class cmExportLibraryDependenciesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     return new cmExportLibraryDependenciesCommand;
   }
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
-  void FinalPass() CM_OVERRIDE;
-  bool HasFinalPass() const CM_OVERRIDE { return true; }
+  void FinalPass() override;
+  bool HasFinalPass() const override { return true; }
 
 private:
   std::string Filename;
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index 9f6ac03..70c3857 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -27,15 +27,15 @@
   void SetConfig(const std::string& config) { this->Config = config; }
 protected:
   // Implement virtual methods from the superclass.
-  bool GenerateMainFile(std::ostream& os) CM_OVERRIDE;
+  bool GenerateMainFile(std::ostream& os) override;
 
   void GenerateImportTargetsConfig(std::ostream&, const std::string&,
                                    std::string const&,
-                                   std::vector<std::string>&) CM_OVERRIDE
+                                   std::vector<std::string>&) override
   {
   }
   void HandleMissingTarget(std::string&, std::vector<std::string>&,
-                           cmGeneratorTarget*, cmGeneratorTarget*) CM_OVERRIDE
+                           cmGeneratorTarget*, cmGeneratorTarget*) override
   {
   }
 
@@ -44,7 +44,7 @@
                           std::set<const cmGeneratorTarget*>& emitted);
 
   std::string InstallNameDir(cmGeneratorTarget* target,
-                             const std::string& config) CM_OVERRIDE;
+                             const std::string& config) override;
 
 private:
   std::string FindTargets(const std::string& prop,
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
index 6b89037..a1734ee 100644
--- a/Source/cmExternalMakefileProjectGenerator.h
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -99,7 +99,7 @@
   }
 
   cmExternalMakefileProjectGenerator* CreateExternalMakefileProjectGenerator()
-    const CM_OVERRIDE
+    const override
   {
     T* p = new T;
     p->SetName(GetName());
diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h
index 9397733..be3af25 100644
--- a/Source/cmExtraCodeBlocksGenerator.h
+++ b/Source/cmExtraCodeBlocksGenerator.h
@@ -25,7 +25,7 @@
 
   static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
 private:
   struct CbpUnit
diff --git a/Source/cmExtraCodeLiteGenerator.h b/Source/cmExtraCodeLiteGenerator.h
index 549802e..029054f 100644
--- a/Source/cmExtraCodeLiteGenerator.h
+++ b/Source/cmExtraCodeLiteGenerator.h
@@ -60,7 +60,7 @@
 
   static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
   void CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs);
 
   void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index b2c1589..a200385 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -222,7 +222,7 @@
   std::string valueToUse;
   if (!envVarSet && cacheValue == nullptr) {
     // nothing known, do nothing
-    valueToUse = "";
+    valueToUse.clear();
   } else if (envVarSet && cacheValue == nullptr) {
     // The variable is in the env, but not in the cache. Use it and put it
     // in the cache
@@ -891,7 +891,7 @@
     std::string subdir = lgen->ConvertToRelativePath(
       this->HomeOutputDirectory, lgen->GetCurrentBinaryDirectory());
     if (subdir == ".") {
-      subdir = "";
+      subdir.clear();
     }
 
     for (cmGeneratorTarget* target : targets) {
diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h
index 5d2ca10..5136660 100644
--- a/Source/cmExtraEclipseCDT4Generator.h
+++ b/Source/cmExtraEclipseCDT4Generator.h
@@ -35,9 +35,9 @@
   static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
-                      bool optional) CM_OVERRIDE;
+                      bool optional) override;
 
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
 private:
   // create .project file in the source tree
diff --git a/Source/cmExtraKateGenerator.h b/Source/cmExtraKateGenerator.h
index 7e80314..9716fe7 100644
--- a/Source/cmExtraKateGenerator.h
+++ b/Source/cmExtraKateGenerator.h
@@ -22,7 +22,7 @@
 
   static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
 private:
   void CreateKateProjectFile(const cmLocalGenerator* lg) const;
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 78cf3ec..73a9c85 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -274,7 +274,7 @@
         if (flagRegex.end() < workString.size()) {
           workString = workString.substr(flagRegex.end());
         } else {
-          workString = "";
+          workString.clear();
         }
       }
     }
diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h
index 58fcd22..7fb304e 100644
--- a/Source/cmExtraSublimeTextGenerator.h
+++ b/Source/cmExtraSublimeTextGenerator.h
@@ -27,7 +27,7 @@
   typedef std::map<std::string, std::vector<std::string>> MapSourceFileFlags;
   cmExtraSublimeTextGenerator();
 
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
 private:
   void CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs);
diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h
index 64c29f8..044755e 100644
--- a/Source/cmFLTKWrapUICommand.h
+++ b/Source/cmFLTKWrapUICommand.h
@@ -25,14 +25,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmFLTKWrapUICommand; }
+  cmCommand* Clone() override { return new cmFLTKWrapUICommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   /**
    * This is called at the end after all the information
@@ -40,8 +40,8 @@
    * not implement this method.  At this point, reading and
    * writing to the cache can be done.
    */
-  void FinalPass() CM_OVERRIDE;
-  bool HasFinalPass() const CM_OVERRIDE { return true; }
+  void FinalPass() override;
+  bool HasFinalPass() const override { return true; }
 
 private:
   /**
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 4eb74cc..98c5733 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -656,7 +656,7 @@
           c = current_str[current_str.size() - 1 - j];
           fin.putback(static_cast<char>(c));
         }
-        current_str = "";
+        current_str.clear();
       }
     }
 
@@ -667,14 +667,14 @@
       if (s.length() >= minlen && (!have_regex || regex.find(s.c_str()))) {
         output_size += static_cast<int>(s.size()) + 1;
         if (limit_output >= 0 && output_size >= limit_output) {
-          s = "";
+          s.clear();
           break;
         }
         strings.push_back(s);
       }
 
       // Reset the string to empty.
-      s = "";
+      s.clear();
     } else if (current_str.empty()) {
       // A non-string character has been found.  Check if the current
       // string matches the requirements.  We require that the length
@@ -683,14 +683,14 @@
           (!have_regex || regex.find(s.c_str()))) {
         output_size += static_cast<int>(s.size()) + 1;
         if (limit_output >= 0 && output_size >= limit_output) {
-          s = "";
+          s.clear();
           break;
         }
         strings.push_back(s);
       }
 
       // Reset the string to empty.
-      s = "";
+      s.clear();
     } else {
       s += current_str;
     }
@@ -700,12 +700,12 @@
       if (s.length() >= minlen && (!have_regex || regex.find(s.c_str()))) {
         output_size += static_cast<int>(s.size()) + 1;
         if (limit_output >= 0 && output_size >= limit_output) {
-          s = "";
+          s.clear();
           break;
         }
         strings.push_back(s);
       }
-      s = "";
+      s.clear();
     }
   }
 
@@ -1706,7 +1706,7 @@
     this->Manifest =
       this->Makefile->GetSafeDefinition("CMAKE_INSTALL_MANIFEST_FILES");
   }
-  ~cmFileInstaller() CM_OVERRIDE
+  ~cmFileInstaller() override
   {
     // Save the updated install manifest.
     this->Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES",
@@ -1731,12 +1731,12 @@
     this->Manifest += file.substr(this->DestDirLength);
   }
 
-  std::string const& ToName(std::string const& fromName) CM_OVERRIDE
+  std::string const& ToName(std::string const& fromName) override
   {
     return this->Rename.empty() ? fromName : this->Rename;
   }
 
-  void ReportCopy(const char* toFile, Type type, bool copy) CM_OVERRIDE
+  void ReportCopy(const char* toFile, Type type, bool copy) override
   {
     if (!this->MessageNever && (copy || !this->MessageLazy)) {
       std::string message = (copy ? "Installing: " : "Up-to-date: ");
@@ -1748,11 +1748,11 @@
       this->ManifestAppend(toFile);
     }
   }
-  bool ReportMissing(const char* fromFile) CM_OVERRIDE
+  bool ReportMissing(const char* fromFile) override
   {
     return (this->Optional || this->cmFileCopier::ReportMissing(fromFile));
   }
-  bool Install(const char* fromFile, const char* toFile) CM_OVERRIDE
+  bool Install(const char* fromFile, const char* toFile) override
   {
     // Support installing from empty source to make a directory.
     if (this->InstallType == cmInstallType_DIRECTORY && !*fromFile) {
@@ -1761,16 +1761,16 @@
     return this->cmFileCopier::Install(fromFile, toFile);
   }
 
-  bool Parse(std::vector<std::string> const& args) CM_OVERRIDE;
+  bool Parse(std::vector<std::string> const& args) override;
   enum
   {
     DoingType = DoingLast1,
     DoingRename,
     DoingLast2
   };
-  bool CheckKeyword(std::string const& arg) CM_OVERRIDE;
-  bool CheckValue(std::string const& arg) CM_OVERRIDE;
-  void DefaultFilePermissions() CM_OVERRIDE
+  bool CheckKeyword(std::string const& arg) override;
+  bool CheckValue(std::string const& arg) override;
+  void DefaultFilePermissions() override
   {
     this->cmFileCopier::DefaultFilePermissions();
     // Add execute permissions based on the target type.
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 1de8b59..17269f3 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -22,14 +22,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmFileCommand; }
+  cmCommand* Clone() override { return new cmFileCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 protected:
   bool HandleRename(std::vector<std::string> const& args);
diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx
index 786d6c6..f309241 100644
--- a/Source/cmFileLock.cxx
+++ b/Source/cmFileLock.cxx
@@ -42,7 +42,7 @@
   }
 
   if (!result.IsOk()) {
-    this->Filename = "";
+    this->Filename.clear();
   }
 
   return result;
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index 32542f0..b237f1b 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -25,7 +25,7 @@
 {
 public:
   cmFindCommon();
-  ~cmFindCommon() CM_OVERRIDE;
+  ~cmFindCommon() override;
 
 protected:
   friend class cmSearchPath;
diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h
index 88c2372..4309449 100644
--- a/Source/cmFindFileCommand.h
+++ b/Source/cmFindFileCommand.h
@@ -24,7 +24,7 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmFindFileCommand; }
+  cmCommand* Clone() override { return new cmFindFileCommand; }
 };
 
 #endif
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 09a9648..b8b51ba 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -68,8 +68,8 @@
     this->AddArchitecturePaths("x32");
   }
 
-  std::string library = this->FindLibrary();
-  if (library != "") {
+  std::string const library = this->FindLibrary();
+  if (!library.empty()) {
     // Save the value in the cache
     this->Makefile->AddCacheDefinition(this->VariableName, library.c_str(),
                                        this->VariableDocumentation.c_str(),
diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h
index fb0a44f..fb8a700 100644
--- a/Source/cmFindLibraryCommand.h
+++ b/Source/cmFindLibraryCommand.h
@@ -27,14 +27,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmFindLibraryCommand; }
+  cmCommand* Clone() override { return new cmFindLibraryCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 protected:
   void AddArchitecturePaths(const char* suffix);
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 9b79931..cd55e89 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -1662,7 +1662,7 @@
   }
 
 private:
-  bool Visit(std::string const& fullPath) CM_OVERRIDE
+  bool Visit(std::string const& fullPath) override
   {
     if (this->UseSuffixes) {
       return this->FPC->SearchDirectory(fullPath);
@@ -1710,12 +1710,12 @@
 
 private:
   std::string String;
-  bool Search(std::string const& parent, cmFileList& lister) CM_OVERRIDE
+  bool Search(std::string const& parent, cmFileList& lister) override
   {
     std::string fullPath = parent + this->String;
     return this->Consider(fullPath, lister);
   }
-  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const CM_OVERRIDE
+  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const override
   {
     CM_AUTO_PTR<cmFileListGeneratorBase> g(
       new cmFileListGeneratorFixed(*this));
@@ -1739,7 +1739,7 @@
 
 private:
   std::vector<std::string> const& Vector;
-  bool Search(std::string const& parent, cmFileList& lister) CM_OVERRIDE
+  bool Search(std::string const& parent, cmFileList& lister) override
   {
     for (std::string const& i : this->Vector) {
       if (this->Consider(parent + i, lister)) {
@@ -1748,7 +1748,7 @@
     }
     return false;
   }
-  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const CM_OVERRIDE
+  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const override
   {
     CM_AUTO_PTR<cmFileListGeneratorBase> g(
       new cmFileListGeneratorEnumerate(*this));
@@ -1788,7 +1788,7 @@
 
 private:
   std::vector<std::string> const& Names;
-  bool Search(std::string const& parent, cmFileList& lister) CM_OVERRIDE
+  bool Search(std::string const& parent, cmFileList& lister) override
   {
     // Construct a list of matches.
     std::vector<std::string> matches;
@@ -1820,7 +1820,7 @@
     }
     return false;
   }
-  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const CM_OVERRIDE
+  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const override
   {
     CM_AUTO_PTR<cmFileListGeneratorBase> g(
       new cmFileListGeneratorProject(*this));
@@ -1848,7 +1848,7 @@
 private:
   std::vector<std::string> const& Names;
   std::string Extension;
-  bool Search(std::string const& parent, cmFileList& lister) CM_OVERRIDE
+  bool Search(std::string const& parent, cmFileList& lister) override
   {
     // Construct a list of matches.
     std::vector<std::string> matches;
@@ -1874,7 +1874,7 @@
     }
     return false;
   }
-  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const CM_OVERRIDE
+  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const override
   {
     CM_AUTO_PTR<cmFileListGeneratorBase> g(
       new cmFileListGeneratorMacProject(*this));
@@ -1899,7 +1899,7 @@
 
 private:
   std::string String;
-  bool Search(std::string const& parent, cmFileList& lister) CM_OVERRIDE
+  bool Search(std::string const& parent, cmFileList& lister) override
   {
     // Look for matching files.
     std::vector<std::string> matches;
@@ -1918,7 +1918,7 @@
     }
     return false;
   }
-  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const CM_OVERRIDE
+  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const override
   {
     CM_AUTO_PTR<cmFileListGeneratorBase> g(
       new cmFileListGeneratorCaseInsensitive(*this));
@@ -1942,7 +1942,7 @@
 
 private:
   std::string Pattern;
-  bool Search(std::string const& parent, cmFileList& lister) CM_OVERRIDE
+  bool Search(std::string const& parent, cmFileList& lister) override
   {
     // Glob the set of matching files.
     std::string expr = parent;
@@ -1963,7 +1963,7 @@
     }
     return false;
   }
-  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const CM_OVERRIDE
+  CM_AUTO_PTR<cmFileListGeneratorBase> Clone() const override
   {
     CM_AUTO_PTR<cmFileListGeneratorBase> g(new cmFileListGeneratorGlob(*this));
     return g;
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 69deb13..150a51d 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -51,14 +51,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmFindPackageCommand; }
+  cmCommand* Clone() override { return new cmFindPackageCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   class PathLabel : public cmFindCommon::PathLabel
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 35a8a44..ea26410 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -85,7 +85,7 @@
     // if the framework has a path in it then just use the filename
     if (frameWorkName.find('/') != std::string::npos) {
       fileName = file;
-      frameWorkName = "";
+      frameWorkName.clear();
     }
     if (!frameWorkName.empty()) {
       std::string fpath = dir;
diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h
index 5b9ddf8..cb0db4c 100644
--- a/Source/cmFindPathCommand.h
+++ b/Source/cmFindPathCommand.h
@@ -27,14 +27,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmFindPathCommand; }
+  cmCommand* Clone() override { return new cmFindPathCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   bool IncludeFileInPath;
 
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index a290229..2059b3d 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -97,8 +97,8 @@
     return true;
   }
 
-  std::string result = FindProgram();
-  if (result != "") {
+  std::string const result = FindProgram();
+  if (!result.empty()) {
     // Save the value in the cache
     this->Makefile->AddCacheDefinition(this->VariableName, result.c_str(),
                                        this->VariableDocumentation.c_str(),
@@ -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/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h
index f4d78b4..147936c 100644
--- a/Source/cmFindProgramCommand.h
+++ b/Source/cmFindProgramCommand.h
@@ -28,14 +28,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmFindProgramCommand; }
+  cmCommand* Clone() override { return new cmFindProgramCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   std::string FindProgram();
diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h
index 6787023..5131a4f 100644
--- a/Source/cmForEachCommand.h
+++ b/Source/cmForEachCommand.h
@@ -19,10 +19,10 @@
 {
 public:
   cmForEachFunctionBlocker(cmMakefile* mf);
-  ~cmForEachFunctionBlocker() CM_OVERRIDE;
+  ~cmForEachFunctionBlocker() override;
   bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
-                         cmExecutionStatus&) CM_OVERRIDE;
-  bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) CM_OVERRIDE;
+                         cmExecutionStatus&) override;
+  bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
 
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
@@ -39,14 +39,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmForEachCommand; }
+  cmCommand* Clone() override { return new cmForEachCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   bool HandleInMode(std::vector<std::string> const& args);
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
index ce98c6b..81f1286 100644
--- a/Source/cmFortranParserImpl.cxx
+++ b/Source/cmFortranParserImpl.cxx
@@ -126,7 +126,7 @@
 
 void cmFortranParser_StringStart(cmFortranParser* parser)
 {
-  parser->TokenString = "";
+  parser->TokenString.clear();
 }
 
 const char* cmFortranParser_StringEnd(cmFortranParser* parser)
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 74230b0..774df84 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -18,12 +18,12 @@
   cmFunctionHelperCommand() {}
 
   ///! clean up any memory allocated by the function
-  ~cmFunctionHelperCommand() CM_OVERRIDE {}
+  ~cmFunctionHelperCommand() override {}
 
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmFunctionHelperCommand* newC = new cmFunctionHelperCommand;
     // we must copy when we clone
@@ -39,10 +39,10 @@
    * the CMakeLists.txt file.
    */
   bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
-                         cmExecutionStatus&) CM_OVERRIDE;
+                         cmExecutionStatus&) override;
 
   bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) CM_OVERRIDE
+                   cmExecutionStatus&) override
   {
     return false;
   }
diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h
index 48d6b36..3352b92 100644
--- a/Source/cmFunctionCommand.h
+++ b/Source/cmFunctionCommand.h
@@ -19,10 +19,10 @@
 {
 public:
   cmFunctionFunctionBlocker() { this->Depth = 0; }
-  ~cmFunctionFunctionBlocker() CM_OVERRIDE {}
+  ~cmFunctionFunctionBlocker() override {}
   bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf,
-                         cmExecutionStatus&) CM_OVERRIDE;
-  bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) CM_OVERRIDE;
+                         cmExecutionStatus&) override;
+  bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
 
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
@@ -36,14 +36,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmFunctionCommand; }
+  cmCommand* Clone() override { return new cmFunctionCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index 5144772..a96f38f 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -94,7 +94,7 @@
    * file was successfully written before allowing the original to be
    * replaced.
    */
-  ~cmGeneratedFileStream() CM_OVERRIDE;
+  ~cmGeneratedFileStream() override;
 
   /**
    * Open an output file by name.  This should be used only with a
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index dd76ad5..d4b501f 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -68,7 +68,7 @@
     return this->Input.c_str();
   }
 
-  this->Output = "";
+  this->Output.clear();
 
   std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it =
     this->Evaluators.begin();
@@ -81,7 +81,7 @@
     this->SeenTargetProperties.insert(context.SeenTargetProperties.begin(),
                                       context.SeenTargetProperties.end());
     if (context.HadError) {
-      this->Output = "";
+      this->Output.clear();
       break;
     }
   }
@@ -296,7 +296,7 @@
       std::string::size_type startPos = input.rfind(';', pos);
       if (startPos == std::string::npos) {
         preGenex = part;
-        part = "";
+        part.clear();
       } else if (startPos != pos - 1 && startPos >= lastPos) {
         part = input.substr(lastPos, startPos - lastPos);
         preGenex = input.substr(startPos + 1, pos - startPos - 1);
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index cdf89d7..92dac79 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -42,12 +42,12 @@
   }
 
   std::string Evaluate(cmGeneratorExpressionContext*,
-                       cmGeneratorExpressionDAGChecker*) const CM_OVERRIDE
+                       cmGeneratorExpressionDAGChecker*) const override
   {
     return std::string(this->Content, this->Length);
   }
 
-  Type GetType() const CM_OVERRIDE
+  Type GetType() const override
   {
     return cmGeneratorExpressionEvaluator::Text;
   }
@@ -77,17 +77,17 @@
     this->ParamChildren = parameters;
   }
 
-  Type GetType() const CM_OVERRIDE
+  Type GetType() const override
   {
     return cmGeneratorExpressionEvaluator::Generator;
   }
 
   std::string Evaluate(cmGeneratorExpressionContext* context,
-                       cmGeneratorExpressionDAGChecker*) const CM_OVERRIDE;
+                       cmGeneratorExpressionDAGChecker*) const override;
 
   std::string GetOriginalExpression() const;
 
-  ~GeneratorExpressionContent() CM_OVERRIDE;
+  ~GeneratorExpressionContent() override;
 
 private:
   std::string EvaluateParameters(const cmGeneratorExpressionNode* node,
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 0f6170f..8f32410 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -57,15 +57,15 @@
 {
   ZeroNode() {}
 
-  bool GeneratesContent() const CM_OVERRIDE { return false; }
+  bool GeneratesContent() const override { return false; }
 
-  bool AcceptsArbitraryContentParameter() const CM_OVERRIDE { return true; }
+  bool AcceptsArbitraryContentParameter() const override { return true; }
 
-  std::string Evaluate(const std::vector<std::string>& /*parameters*/,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& /*parameters*/,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return std::string();
   }
@@ -75,13 +75,13 @@
 {
   OneNode() {}
 
-  bool AcceptsArbitraryContentParameter() const CM_OVERRIDE { return true; }
+  bool AcceptsArbitraryContentParameter() const override { return true; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return parameters.front();
   }
@@ -128,11 +128,11 @@
 {
   NotNode() {}
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     if (*parameters.begin() != "0" && *parameters.begin() != "1") {
       reportError(
@@ -148,13 +148,13 @@
 {
   BoolNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 1; }
+  int NumExpectedParameters() const override { return 1; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return !cmSystemTools::IsOff(parameters.begin()->c_str()) ? "1" : "0";
   }
@@ -164,12 +164,12 @@
 {
   IfNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 3; }
+  int NumExpectedParameters() const override { return 3; }
 
   std::string Evaluate(const std::vector<std::string>& parameters,
                        cmGeneratorExpressionContext* context,
                        const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker*) const CM_OVERRIDE
+                       cmGeneratorExpressionDAGChecker*) const override
   {
     if (parameters[0] != "1" && parameters[0] != "0") {
       reportError(context, content->GetOriginalExpression(),
@@ -185,13 +185,13 @@
 {
   StrEqualNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 2; }
+  int NumExpectedParameters() const override { return 2; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return *parameters.begin() == parameters[1] ? "1" : "0";
   }
@@ -201,13 +201,13 @@
 {
   EqualNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 2; }
+  int NumExpectedParameters() const override { return 2; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     char* pEnd;
 
@@ -279,13 +279,13 @@
 {
   LowerCaseNode() {}
 
-  bool AcceptsArbitraryContentParameter() const CM_OVERRIDE { return true; }
+  bool AcceptsArbitraryContentParameter() const override { return true; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return cmSystemTools::LowerCase(parameters.front());
   }
@@ -295,13 +295,13 @@
 {
   UpperCaseNode() {}
 
-  bool AcceptsArbitraryContentParameter() const CM_OVERRIDE { return true; }
+  bool AcceptsArbitraryContentParameter() const override { return true; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return cmSystemTools::UpperCase(parameters.front());
   }
@@ -311,13 +311,13 @@
 {
   MakeCIdentifierNode() {}
 
-  bool AcceptsArbitraryContentParameter() const CM_OVERRIDE { return true; }
+  bool AcceptsArbitraryContentParameter() const override { return true; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return cmSystemTools::MakeCidentifier(parameters.front());
   }
@@ -327,13 +327,13 @@
 {
   Angle_RNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 0; }
+  int NumExpectedParameters() const override { return 0; }
 
-  std::string Evaluate(const std::vector<std::string>& /*parameters*/,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& /*parameters*/,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return ">";
   }
@@ -343,13 +343,13 @@
 {
   CommaNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 0; }
+  int NumExpectedParameters() const override { return 0; }
 
-  std::string Evaluate(const std::vector<std::string>& /*parameters*/,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& /*parameters*/,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return ",";
   }
@@ -359,13 +359,13 @@
 {
   SemicolonNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 0; }
+  int NumExpectedParameters() const override { return 0; }
 
-  std::string Evaluate(const std::vector<std::string>& /*parameters*/,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& /*parameters*/,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return ";";
   }
@@ -375,7 +375,7 @@
 {
   CompilerIdNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return OneOrZeroParameters; }
+  int NumExpectedParameters() const override { return OneOrZeroParameters; }
 
   std::string EvaluateWithLanguage(const std::vector<std::string>& parameters,
                                    cmGeneratorExpressionContext* context,
@@ -427,11 +427,11 @@
 {
   CCompilerIdNode() {}
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* dagChecker) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
     if (!context->HeadTarget) {
       reportError(
@@ -449,11 +449,11 @@
 {
   CXXCompilerIdNode() {}
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* dagChecker) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
     if (!context->HeadTarget) {
       reportError(
@@ -471,7 +471,7 @@
 {
   CompilerVersionNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return OneOrZeroParameters; }
+  int NumExpectedParameters() const override { return OneOrZeroParameters; }
 
   std::string EvaluateWithLanguage(const std::vector<std::string>& parameters,
                                    cmGeneratorExpressionContext* context,
@@ -508,11 +508,11 @@
 {
   CCompilerVersionNode() {}
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* dagChecker) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
     if (!context->HeadTarget) {
       reportError(
@@ -530,11 +530,11 @@
 {
   CxxCompilerVersionNode() {}
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* dagChecker) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
     if (!context->HeadTarget) {
       reportError(
@@ -552,13 +552,13 @@
 {
   PlatformIdNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return OneOrZeroParameters; }
+  int NumExpectedParameters() const override { return OneOrZeroParameters; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     const char* platformId =
       context->LG->GetMakefile()->GetSafeDefinition("CMAKE_SYSTEM_NAME");
@@ -581,13 +581,13 @@
 {
   VersionGreaterNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 2; }
+  int NumExpectedParameters() const override { return 2; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER,
                                          parameters.front().c_str(),
@@ -601,13 +601,13 @@
 {
   VersionGreaterEqNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 2; }
+  int NumExpectedParameters() const override { return 2; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL,
                                          parameters.front().c_str(),
@@ -621,13 +621,13 @@
 {
   VersionLessNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 2; }
+  int NumExpectedParameters() const override { return 2; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
                                          parameters.front().c_str(),
@@ -641,13 +641,13 @@
 {
   VersionLessEqNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 2; }
+  int NumExpectedParameters() const override { return 2; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS_EQUAL,
                                          parameters.front().c_str(),
@@ -661,13 +661,13 @@
 {
   VersionEqualNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 2; }
+  int NumExpectedParameters() const override { return 2; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
                                          parameters.front().c_str(),
@@ -681,11 +681,11 @@
 {
   LinkOnlyNode() {}
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* dagChecker) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
     if (!dagChecker) {
       reportError(context, content->GetOriginalExpression(),
@@ -703,13 +703,13 @@
 {
   ConfigurationNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 0; }
+  int NumExpectedParameters() const override { return 0; }
 
-  std::string Evaluate(const std::vector<std::string>& /*parameters*/,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& /*parameters*/,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     context->HadContextSensitiveCondition = true;
     return context->Config;
@@ -720,13 +720,13 @@
 {
   ConfigurationTestNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return OneOrZeroParameters; }
+  int NumExpectedParameters() const override { return OneOrZeroParameters; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     if (parameters.empty()) {
       return configurationNode.Evaluate(parameters, context, content, nullptr);
@@ -779,15 +779,15 @@
 {
   JoinNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 2; }
+  int NumExpectedParameters() const override { return 2; }
 
-  bool AcceptsArbitraryContentParameter() const CM_OVERRIDE { return true; }
+  bool AcceptsArbitraryContentParameter() const override { return true; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     std::vector<std::string> list;
     cmSystemTools::ExpandListArgument(parameters.front(), list);
@@ -799,13 +799,13 @@
 {
   CompileLanguageNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return OneOrZeroParameters; }
+  int NumExpectedParameters() const override { return OneOrZeroParameters; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* dagChecker) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
     if (context->Language.empty()) {
       reportError(
@@ -903,13 +903,13 @@
   TargetPropertyNode() {}
 
   // This node handles errors on parameter count itself.
-  int NumExpectedParameters() const CM_OVERRIDE { return OneOrMoreParameters; }
+  int NumExpectedParameters() const override { return OneOrMoreParameters; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* dagCheckerParent) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
   {
     if (parameters.size() != 1 && parameters.size() != 2) {
       reportError(
@@ -1196,21 +1196,21 @@
 {
   TargetNameNode() {}
 
-  bool GeneratesContent() const CM_OVERRIDE { return true; }
+  bool GeneratesContent() const override { return true; }
 
-  bool AcceptsArbitraryContentParameter() const CM_OVERRIDE { return true; }
-  bool RequiresLiteralInput() const CM_OVERRIDE { return true; }
+  bool AcceptsArbitraryContentParameter() const override { return true; }
+  bool RequiresLiteralInput() const override { return true; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* /*context*/,
-                       const GeneratorExpressionContent* /*content*/,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* /*context*/,
+    const GeneratorExpressionContent* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     return parameters.front();
   }
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 1; }
+  int NumExpectedParameters() const override { return 1; }
 
 } targetNameNode;
 
@@ -1218,11 +1218,11 @@
 {
   TargetObjectsNode() {}
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     std::string tgtName = parameters.front();
     cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
@@ -1299,13 +1299,13 @@
 {
   CompileFeaturesNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return OneOrMoreParameters; }
+  int NumExpectedParameters() const override { return OneOrMoreParameters; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* dagChecker) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
     cmGeneratorTarget const* target = context->HeadTarget;
     if (!target) {
@@ -1424,13 +1424,13 @@
 {
   TargetPolicyNode() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 1; }
+  int NumExpectedParameters() const override { return 1; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     if (!context->HeadTarget) {
       reportError(
@@ -1485,14 +1485,14 @@
 {
   InstallPrefixNode() {}
 
-  bool GeneratesContent() const CM_OVERRIDE { return true; }
-  int NumExpectedParameters() const CM_OVERRIDE { return 0; }
+  bool GeneratesContent() const override { return true; }
+  int NumExpectedParameters() const override { return 0; }
 
-  std::string Evaluate(const std::vector<std::string>& /*parameters*/,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& /*parameters*/,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     reportError(context, content->GetOriginalExpression(),
                 "INSTALL_PREFIX is a marker for install(EXPORT) only.  It "
@@ -1705,13 +1705,13 @@
 {
   TargetFilesystemArtifact() {}
 
-  int NumExpectedParameters() const CM_OVERRIDE { return 1; }
+  int NumExpectedParameters() const override { return 1; }
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* dagChecker) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
     // Lookup the referenced target.
     std::string name = *parameters.begin();
@@ -1787,11 +1787,11 @@
 {
   ShellPathNode() {}
 
-  std::string Evaluate(const std::vector<std::string>& parameters,
-                       cmGeneratorExpressionContext* context,
-                       const GeneratorExpressionContent* content,
-                       cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
-    CM_OVERRIDE
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     if (!cmSystemTools::FileIsFullPath(parameters.front())) {
       reportError(context, content->GetOriginalExpression(),
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 9946b1e..28b43e7 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -3023,7 +3023,7 @@
     impName =
       this->GetFullNameInternal(config, cmStateEnums::ImportLibraryArtifact);
   } else {
-    impName = "";
+    impName.clear();
   }
 
   // The program database file name.
@@ -3126,9 +3126,9 @@
       this->GetType() != cmStateEnums::SHARED_LIBRARY &&
       this->GetType() != cmStateEnums::MODULE_LIBRARY &&
       this->GetType() != cmStateEnums::EXECUTABLE) {
-    outPrefix = "";
+    outPrefix.clear();
     outBase = this->GetName();
-    outSuffix = "";
+    outSuffix.clear();
     return;
   }
 
@@ -3139,9 +3139,9 @@
   // does not support import libraries.
   if (isImportedLibraryArtifact &&
       !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
-    outPrefix = "";
-    outBase = "";
-    outSuffix = "";
+    outPrefix.clear();
+    outBase.clear();
+    outSuffix.clear();
     return;
   }
 
@@ -4488,7 +4488,7 @@
     out = cge->Evaluate(this->LocalGenerator, config);
 
     // Skip per-configuration subdirectory.
-    conf = "";
+    conf.clear();
   } else if (const char* outdir = this->GetProperty(propertyName)) {
     // Use the user-specified output directory.
     cmGeneratorExpression ge;
@@ -4498,7 +4498,7 @@
     // Skip per-configuration subdirectory if the value contained a
     // generator expression.
     if (out != outdir) {
-      conf = "";
+      conf.clear();
     }
   } else if (this->GetType() == cmStateEnums::EXECUTABLE) {
     // Lookup the output path for executables.
@@ -4564,7 +4564,7 @@
     out = config_outdir;
 
     // Skip per-configuration subdirectory.
-    conf = "";
+    conf.clear();
   } else if (const char* outdir = this->GetProperty(propertyName)) {
     // Use the user-specified output directory.
     out = outdir;
diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h
index 803f051..1f29c78 100644
--- a/Source/cmGetCMakePropertyCommand.h
+++ b/Source/cmGetCMakePropertyCommand.h
@@ -15,14 +15,14 @@
 class cmGetCMakePropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmGetCMakePropertyCommand; }
+  cmCommand* Clone() override { return new cmGetCMakePropertyCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h
index f373bc2..02ea056 100644
--- a/Source/cmGetDirectoryPropertyCommand.h
+++ b/Source/cmGetDirectoryPropertyCommand.h
@@ -15,14 +15,14 @@
 class cmGetDirectoryPropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmGetDirectoryPropertyCommand; }
+  cmCommand* Clone() override { return new cmGetDirectoryPropertyCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   void StoreResult(const std::string& variable, const char* prop);
diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h
index b7141b2..8c26655 100644
--- a/Source/cmGetFilenameComponentCommand.h
+++ b/Source/cmGetFilenameComponentCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmGetFilenameComponentCommand; }
+  cmCommand* Clone() override { return new cmGetFilenameComponentCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h
index 44a3852..c3f653e 100644
--- a/Source/cmGetPropertyCommand.h
+++ b/Source/cmGetPropertyCommand.h
@@ -17,14 +17,14 @@
 public:
   cmGetPropertyCommand();
 
-  cmCommand* Clone() CM_OVERRIDE { return new cmGetPropertyCommand; }
+  cmCommand* Clone() override { return new cmGetPropertyCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   enum OutType
diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h
index d4fef01..43bc330 100644
--- a/Source/cmGetSourceFilePropertyCommand.h
+++ b/Source/cmGetSourceFilePropertyCommand.h
@@ -15,14 +15,14 @@
 class cmGetSourceFilePropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmGetSourceFilePropertyCommand; }
+  cmCommand* Clone() override { return new cmGetSourceFilePropertyCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h
index e74b7e1..63ee5fd 100644
--- a/Source/cmGetTargetPropertyCommand.h
+++ b/Source/cmGetTargetPropertyCommand.h
@@ -15,14 +15,14 @@
 class cmGetTargetPropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmGetTargetPropertyCommand; }
+  cmCommand* Clone() override { return new cmGetTargetPropertyCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h
index 5a3ef40..4a74f59 100644
--- a/Source/cmGetTestPropertyCommand.h
+++ b/Source/cmGetTestPropertyCommand.h
@@ -15,14 +15,14 @@
 class cmGetTestPropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmGetTestPropertyCommand; }
+  cmCommand* Clone() override { return new cmGetTestPropertyCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
index 842a7c4..e19118b 100644
--- a/Source/cmGlobalCommonGenerator.h
+++ b/Source/cmGlobalCommonGenerator.h
@@ -16,7 +16,7 @@
 {
 public:
   cmGlobalCommonGenerator(cmake* cm);
-  ~cmGlobalCommonGenerator() CM_OVERRIDE;
+  ~cmGlobalCommonGenerator() override;
 };
 
 #endif
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
index 125a9e2..4e3e770 100644
--- a/Source/cmGlobalGeneratorFactory.h
+++ b/Source/cmGlobalGeneratorFactory.h
@@ -45,7 +45,7 @@
 public:
   /** Create a GlobalGenerator */
   cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
-                                           cmake* cm) const CM_OVERRIDE
+                                           cmake* cm) const override
   {
     if (name != T::GetActualName()) {
       return nullptr;
@@ -54,22 +54,22 @@
   }
 
   /** Get the documentation entry for this factory */
-  void GetDocumentation(cmDocumentationEntry& entry) const CM_OVERRIDE
+  void GetDocumentation(cmDocumentationEntry& entry) const override
   {
     T::GetDocumentation(entry);
   }
 
   /** Get the names of the current registered generators */
-  void GetGenerators(std::vector<std::string>& names) const CM_OVERRIDE
+  void GetGenerators(std::vector<std::string>& names) const override
   {
     names.push_back(T::GetActualName());
   }
 
   /** Determine whether or not this generator supports toolsets */
-  bool SupportsToolset() const CM_OVERRIDE { return T::SupportsToolset(); }
+  bool SupportsToolset() const override { return T::SupportsToolset(); }
 
   /** Determine whether or not this generator supports platforms */
-  bool SupportsPlatform() const CM_OVERRIDE { return T::SupportsPlatform(); }
+  bool SupportsPlatform() const override { return T::SupportsPlatform(); }
 };
 
 #endif
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index 05a3a3c..7d4b2ba 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -57,7 +57,7 @@
   /*
   * Determine what program to use for building the project.
   */
-  bool FindMakeProgram(cmMakefile* mf) CM_OVERRIDE;
+  bool FindMakeProgram(cmMakefile* mf) override;
 
   cmGeneratedFileStream* GetBuildFileStream()
   {
diff --git a/Source/cmGlobalKdevelopGenerator.h b/Source/cmGlobalKdevelopGenerator.h
index fd57782..d6c43f3 100644
--- a/Source/cmGlobalKdevelopGenerator.h
+++ b/Source/cmGlobalKdevelopGenerator.h
@@ -30,7 +30,7 @@
 
   static cmExternalMakefileProjectGeneratorFactory* GetFactory();
 
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
 private:
   /*** Create the foo.kdevelop.filelist file, return false if it doesn't
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index 6eb2124..05ab904 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -27,7 +27,7 @@
   static std::string GetActualName() { return "NMake Makefiles"; }
 
   /** Get encoding used by generator for makefile files */
-  codecvt::Encoding GetMakefileEncoding() const CM_OVERRIDE
+  codecvt::Encoding GetMakefileEncoding() const override
   {
     return codecvt::ANSI;
   }
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 4a8ebe7..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>
 
@@ -78,7 +79,7 @@
 
   cmLinkLineComputer* CreateLinkLineComputer(
     cmOutputConverter* outputConverter,
-    cmStateDirectory const& stateDir) const CM_OVERRIDE;
+    cmStateDirectory const& stateDir) const override;
 
   /**
    * Write the given @a comment to the output stream @a os. It
@@ -98,7 +99,7 @@
    */
   static bool SupportsPlatform() { return false; }
 
-  bool IsIPOSupported() const CM_OVERRIDE { return true; }
+  bool IsIPOSupported() const override { return true; }
 
   /**
    * Write a build statement to @a os with the @a comment using
@@ -183,11 +184,11 @@
     return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>();
   }
 
-  ~cmGlobalNinjaGenerator() CM_OVERRIDE {}
+  ~cmGlobalNinjaGenerator() override {}
 
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) CM_OVERRIDE;
+  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
 
-  std::string GetName() const CM_OVERRIDE
+  std::string GetName() const override
   {
     return cmGlobalNinjaGenerator::GetActualName();
   }
@@ -195,12 +196,12 @@
   static std::string GetActualName() { return "Ninja"; }
 
   /** Get encoding used by generator for ninja files */
-  codecvt::Encoding GetMakefileEncoding() const CM_OVERRIDE;
+  codecvt::Encoding GetMakefileEncoding() const override;
 
   static void GetDocumentation(cmDocumentationEntry& entry);
 
   void EnableLanguage(std::vector<std::string> const& languages,
-                      cmMakefile* mf, bool optional) CM_OVERRIDE;
+                      cmMakefile* mf, bool optional) override;
 
   void GenerateBuildCommand(std::vector<std::string>& makeCommand,
                             const std::string& makeProgram,
@@ -209,34 +210,31 @@
                             const std::string& targetName,
                             const std::string& config, bool fast, bool verbose,
                             std::vector<std::string> const& makeOptions =
-                              std::vector<std::string>()) CM_OVERRIDE;
+                              std::vector<std::string>()) override;
 
   // Setup target names
-  const char* GetAllTargetName() const CM_OVERRIDE { return "all"; }
-  const char* GetInstallTargetName() const CM_OVERRIDE { return "install"; }
-  const char* GetInstallLocalTargetName() const CM_OVERRIDE
+  const char* GetAllTargetName() const override { return "all"; }
+  const char* GetInstallTargetName() const override { return "install"; }
+  const char* GetInstallLocalTargetName() const override
   {
     return "install/local";
   }
-  const char* GetInstallStripTargetName() const CM_OVERRIDE
+  const char* GetInstallStripTargetName() const override
   {
     return "install/strip";
   }
-  const char* GetTestTargetName() const CM_OVERRIDE { return "test"; }
-  const char* GetPackageTargetName() const CM_OVERRIDE { return "package"; }
-  const char* GetPackageSourceTargetName() const CM_OVERRIDE
+  const char* GetTestTargetName() const override { return "test"; }
+  const char* GetPackageTargetName() const override { return "package"; }
+  const char* GetPackageSourceTargetName() const override
   {
     return "package_source";
   }
-  const char* GetEditCacheTargetName() const CM_OVERRIDE
-  {
-    return "edit_cache";
-  }
-  const char* GetRebuildCacheTargetName() const CM_OVERRIDE
+  const char* GetEditCacheTargetName() const override { return "edit_cache"; }
+  const char* GetRebuildCacheTargetName() const override
   {
     return "rebuild_cache";
   }
-  const char* GetCleanTargetName() const CM_OVERRIDE { return "clean"; }
+  const char* GetCleanTargetName() const override { return "clean"; }
 
   cmGeneratedFileStream* GetBuildFileStream() const
   {
@@ -248,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
   {
@@ -323,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);
 
@@ -340,7 +340,7 @@
 
   void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target);
 
-  void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const CM_OVERRIDE;
+  void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
 
   // Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3
   static std::string RequiredNinjaVersion() { return "1.3"; }
@@ -363,16 +363,16 @@
                        std::vector<std::string> const& linked_target_dirs);
 
 protected:
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
-  bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const CM_OVERRIDE { return true; }
+  bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
 
 private:
-  std::string GetEditCacheCommand() const CM_OVERRIDE;
-  bool FindMakeProgram(cmMakefile* mf) CM_OVERRIDE;
+  std::string GetEditCacheCommand() const override;
+  bool FindMakeProgram(cmMakefile* mf) override;
   void CheckNinjaFeatures();
   bool CheckLanguages(std::vector<std::string> const& languages,
-                      cmMakefile* mf) const CM_OVERRIDE;
+                      cmMakefile* mf) const override;
   bool CheckFortran(cmMakefile* mf) const;
 
   void OpenBuildFileStream();
@@ -451,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/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 15ddeff..be40126 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -230,7 +230,7 @@
 
   // The all and preinstall rules might never have any dependencies
   // added to them.
-  if (this->EmptyRuleHackDepends != "") {
+  if (!this->EmptyRuleHackDepends.empty()) {
     depends.push_back(this->EmptyRuleHackDepends);
   }
 
@@ -438,7 +438,7 @@
 
   // Work-around for makes that drop rules that have no dependencies
   // or commands.
-  if (depends.empty() && this->EmptyRuleHackDepends != "") {
+  if (depends.empty() && !this->EmptyRuleHackDepends.empty()) {
     depends.push_back(this->EmptyRuleHackDepends);
   }
 
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index bc03c44..d601f88 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -68,7 +68,7 @@
   }
 
   ///! Get the name for the generator.
-  std::string GetName() const CM_OVERRIDE
+  std::string GetName() const override
   {
     return cmGlobalUnixMakefileGenerator3::GetActualName();
   }
@@ -89,23 +89,23 @@
   /** Get the documentation entry for this generator.  */
   static void GetDocumentation(cmDocumentationEntry& entry);
 
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) CM_OVERRIDE;
+  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
 
   /**
    * Try to determine system information such as shared library
    * extension, pthreads, byte order etc.
    */
   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
-                      bool optional) CM_OVERRIDE;
+                      bool optional) override;
 
-  void Configure() CM_OVERRIDE;
+  void Configure() override;
 
   /**
    * Generate the all required files for building this project/tree. This
    * basically creates a series of LocalGenerators for each directory and
    * requests that they Generate.
    */
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
   void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
                                        std::vector<cmLocalGenerator*>&);
@@ -134,7 +134,7 @@
                             const std::string& targetName,
                             const std::string& config, bool fast, bool verbose,
                             std::vector<std::string> const& makeOptions =
-                              std::vector<std::string>()) CM_OVERRIDE;
+                              std::vector<std::string>()) override;
 
   /** Record per-target progress information.  */
   void RecordTargetProgress(cmMakefileTargetGenerator* tg);
@@ -149,9 +149,9 @@
   /** Does the make tool tolerate .DELETE_ON_ERROR? */
   virtual bool AllowDeleteOnError() const { return true; }
 
-  bool IsIPOSupported() const CM_OVERRIDE { return true; }
+  bool IsIPOSupported() const override { return true; }
 
-  void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const CM_OVERRIDE;
+  void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
 
   std::string IncludeDirective;
   bool DefineWindowsNULL;
@@ -178,37 +178,31 @@
   bool NeedRequiresStep(cmGeneratorTarget const*);
 
   // Target name hooks for superclass.
-  const char* GetAllTargetName() const CM_OVERRIDE { return "all"; }
-  const char* GetInstallTargetName() const CM_OVERRIDE { return "install"; }
-  const char* GetInstallLocalTargetName() const CM_OVERRIDE
+  const char* GetAllTargetName() const override { return "all"; }
+  const char* GetInstallTargetName() const override { return "install"; }
+  const char* GetInstallLocalTargetName() const override
   {
     return "install/local";
   }
-  const char* GetInstallStripTargetName() const CM_OVERRIDE
+  const char* GetInstallStripTargetName() const override
   {
     return "install/strip";
   }
-  const char* GetPreinstallTargetName() const CM_OVERRIDE
-  {
-    return "preinstall";
-  }
-  const char* GetTestTargetName() const CM_OVERRIDE { return "test"; }
-  const char* GetPackageTargetName() const CM_OVERRIDE { return "package"; }
-  const char* GetPackageSourceTargetName() const CM_OVERRIDE
+  const char* GetPreinstallTargetName() const override { return "preinstall"; }
+  const char* GetTestTargetName() const override { return "test"; }
+  const char* GetPackageTargetName() const override { return "package"; }
+  const char* GetPackageSourceTargetName() const override
   {
     return "package_source";
   }
-  const char* GetEditCacheTargetName() const CM_OVERRIDE
-  {
-    return "edit_cache";
-  }
-  const char* GetRebuildCacheTargetName() const CM_OVERRIDE
+  const char* GetEditCacheTargetName() const override { return "edit_cache"; }
+  const char* GetRebuildCacheTargetName() const override
   {
     return "rebuild_cache";
   }
-  const char* GetCleanTargetName() const CM_OVERRIDE { return "clean"; }
+  const char* GetCleanTargetName() const override { return "clean"; }
 
-  bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const CM_OVERRIDE { return true; }
+  bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
 
   // Some make programs (Borland) do not keep a rule if there are no
   // dependencies or commands.  This is a problem for creating rules
@@ -247,13 +241,13 @@
   cmGeneratedFileStream* CommandDatabase;
 
 private:
-  const char* GetBuildIgnoreErrorsFlag() const CM_OVERRIDE { return "-i"; }
-  std::string GetEditCacheCommand() const CM_OVERRIDE;
+  const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; }
+  std::string GetEditCacheCommand() const override;
 
   std::map<cmStateSnapshot, std::set<cmGeneratorTarget const*>,
            cmStateSnapshot::StrictWeakOrder>
     DirectoryTargetsMap;
-  void InitializeProgressMarks() CM_OVERRIDE;
+  void InitializeProgressMarks() override;
 };
 
 #endif
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 5db81ce..8c9e461 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -51,7 +51,7 @@
 {
 public:
   cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
-                                           cmake* cm) const CM_OVERRIDE
+                                           cmake* cm) const override
   {
     std::string genName;
     const char* p = cmVS10GenName(name, genName);
@@ -73,22 +73,22 @@
     return 0;
   }
 
-  void GetDocumentation(cmDocumentationEntry& entry) const CM_OVERRIDE
+  void GetDocumentation(cmDocumentationEntry& entry) const override
   {
     entry.Name = std::string(vs10generatorName) + " [arch]";
     entry.Brief = "Generates Visual Studio 2010 project files.  "
                   "Optional [arch] can be \"Win64\" or \"IA64\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const CM_OVERRIDE
+  void GetGenerators(std::vector<std::string>& names) const override
   {
     names.push_back(vs10generatorName);
     names.push_back(vs10generatorName + std::string(" IA64"));
     names.push_back(vs10generatorName + std::string(" Win64"));
   }
 
-  bool SupportsToolset() const CM_OVERRIDE { return true; }
-  bool SupportsPlatform() const CM_OVERRIDE { return true; }
+  bool SupportsToolset() const override { return true; }
+  bool SupportsPlatform() const override { return true; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio10Generator::NewFactory()
@@ -407,14 +407,14 @@
 bool cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(
   std::string& toolset) const
 {
-  toolset = "";
+  toolset.clear();
   return false;
 }
 
 bool cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(
   std::string& toolset) const
 {
-  toolset = "";
+  toolset.clear();
   return false;
 }
 
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 4a5c245..5f80c73 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -98,7 +98,7 @@
 
   virtual const char* GetToolsVersion() { return "4.0"; }
 
-  bool FindMakeProgram(cmMakefile* mf) CM_OVERRIDE;
+  bool FindMakeProgram(cmMakefile* mf) override;
 
   static std::string GetInstalledNsightTegraVersion();
 
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index d37d4b0..cb3b047 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -35,7 +35,7 @@
 {
 public:
   cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
-                                           cmake* cm) const CM_OVERRIDE
+                                           cmake* cm) const override
   {
     std::string genName;
     const char* p = cmVS11GenName(name, genName);
@@ -68,14 +68,14 @@
     return ret;
   }
 
-  void GetDocumentation(cmDocumentationEntry& entry) const CM_OVERRIDE
+  void GetDocumentation(cmDocumentationEntry& entry) const override
   {
     entry.Name = std::string(vs11generatorName) + " [arch]";
     entry.Brief = "Generates Visual Studio 2012 project files.  "
                   "Optional [arch] can be \"Win64\" or \"ARM\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const CM_OVERRIDE
+  void GetGenerators(std::vector<std::string>& names) const override
   {
     names.push_back(vs11generatorName);
     names.push_back(vs11generatorName + std::string(" ARM"));
@@ -89,8 +89,8 @@
     }
   }
 
-  bool SupportsToolset() const CM_OVERRIDE { return true; }
-  bool SupportsPlatform() const CM_OVERRIDE { return true; }
+  bool SupportsToolset() const override { return true; }
+  bool SupportsPlatform() const override { return true; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index de62ff0..a9c605c 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -35,7 +35,7 @@
 {
 public:
   cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
-                                           cmake* cm) const CM_OVERRIDE
+                                           cmake* cm) const override
   {
     std::string genName;
     const char* p = cmVS12GenName(name, genName);
@@ -57,22 +57,22 @@
     return 0;
   }
 
-  void GetDocumentation(cmDocumentationEntry& entry) const CM_OVERRIDE
+  void GetDocumentation(cmDocumentationEntry& entry) const override
   {
     entry.Name = std::string(vs12generatorName) + " [arch]";
     entry.Brief = "Generates Visual Studio 2013 project files.  "
                   "Optional [arch] can be \"Win64\" or \"ARM\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const CM_OVERRIDE
+  void GetGenerators(std::vector<std::string>& names) const override
   {
     names.push_back(vs12generatorName);
     names.push_back(vs12generatorName + std::string(" ARM"));
     names.push_back(vs12generatorName + std::string(" Win64"));
   }
 
-  bool SupportsToolset() const CM_OVERRIDE { return true; }
-  bool SupportsPlatform() const CM_OVERRIDE { return true; }
+  bool SupportsToolset() const override { return true; }
+  bool SupportsPlatform() const override { return true; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio12Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
index d032782..5ba21a6 100644
--- a/Source/cmGlobalVisualStudio12Generator.h
+++ b/Source/cmGlobalVisualStudio12Generator.h
@@ -32,7 +32,7 @@
   virtual const char* GetToolsVersion() { return "12.0"; }
 protected:
   bool ProcessGeneratorToolsetField(std::string const& key,
-                                    std::string const& value) CM_OVERRIDE;
+                                    std::string const& value) override;
 
   virtual bool InitializeWindowsPhone(cmMakefile* mf);
   virtual bool InitializeWindowsStore(cmMakefile* mf);
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index e2120b8..97d5313 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -35,7 +35,7 @@
 {
 public:
   cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
-                                           cmake* cm) const CM_OVERRIDE
+                                           cmake* cm) const override
   {
     std::string genName;
     const char* p = cmVS14GenName(name, genName);
@@ -57,22 +57,22 @@
     return 0;
   }
 
-  void GetDocumentation(cmDocumentationEntry& entry) const CM_OVERRIDE
+  void GetDocumentation(cmDocumentationEntry& entry) const override
   {
     entry.Name = std::string(vs14generatorName) + " [arch]";
     entry.Brief = "Generates Visual Studio 2015 project files.  "
                   "Optional [arch] can be \"Win64\" or \"ARM\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const CM_OVERRIDE
+  void GetGenerators(std::vector<std::string>& names) const override
   {
     names.push_back(vs14generatorName);
     names.push_back(vs14generatorName + std::string(" ARM"));
     names.push_back(vs14generatorName + std::string(" Win64"));
   }
 
-  bool SupportsToolset() const CM_OVERRIDE { return true; }
-  bool SupportsPlatform() const CM_OVERRIDE { return true; }
+  bool SupportsToolset() const override { return true; }
+  bool SupportsPlatform() const override { return true; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio14Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio15Generator.cxx b/Source/cmGlobalVisualStudio15Generator.cxx
index ce1ba00..d2bf7cc 100644
--- a/Source/cmGlobalVisualStudio15Generator.cxx
+++ b/Source/cmGlobalVisualStudio15Generator.cxx
@@ -69,8 +69,8 @@
     names.push_back(vs15generatorName + std::string(" Win64"));
   }
 
-  bool SupportsToolset() const CM_OVERRIDE { return true; }
-  bool SupportsPlatform() const CM_OVERRIDE { return true; }
+  bool SupportsToolset() const override { return true; }
+  bool SupportsPlatform() const override { return true; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio15Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudio15Generator.h b/Source/cmGlobalVisualStudio15Generator.h
index 730784b..e934882 100644
--- a/Source/cmGlobalVisualStudio15Generator.h
+++ b/Source/cmGlobalVisualStudio15Generator.h
@@ -28,7 +28,7 @@
 
   virtual const char* GetToolsVersion() { return "15.0"; }
 protected:
-  bool InitializeWindows(cmMakefile* mf) CM_OVERRIDE;
+  bool InitializeWindows(cmMakefile* mf) override;
   virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
 
   virtual const char* GetIDEVersion() { return "15.0"; }
@@ -44,8 +44,8 @@
   // Check for a Win 8 SDK known to the registry or VS installer tool.
   bool IsWin81SDKInstalled() const;
 
-  std::string FindMSBuildCommand() CM_OVERRIDE;
-  std::string FindDevEnvCommand() CM_OVERRIDE;
+  std::string FindMSBuildCommand() override;
+  std::string FindDevEnvCommand() override;
 
 private:
   class Factory;
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 2ed51a0..8c1111e 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -403,7 +403,7 @@
         std::string dir = lg->GetCurrentBinaryDirectory();
         dir = root->ConvertToRelativePath(rootBinaryDir, dir.c_str());
         if (dir == ".") {
-          dir = ""; // msbuild cannot handle ".\" prefix
+          dir.clear(); // msbuild cannot handle ".\" prefix
         }
         this->WriteProject(fout, vcprojName, dir.c_str(), target);
         written = true;
@@ -418,7 +418,7 @@
         std::vector<cmsys::String> tokens =
           cmSystemTools::SplitString(targetFolder, '/', false);
 
-        std::string cumulativePath = "";
+        std::string cumulativePath;
 
         for (std::vector<cmsys::String>::iterator iter = tokens.begin();
              iter != tokens.end(); ++iter) {
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 788c431..c5aced4 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -91,7 +91,7 @@
 
   const char* GetIntelProjectVersion();
 
-  bool FindMakeProgram(cmMakefile* mf) CM_OVERRIDE;
+  bool FindMakeProgram(cmMakefile* mf) override;
 
   /** Is the Microsoft Assembler enabled?  */
   bool IsMasmEnabled() const { return this->MasmEnabled; }
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index f56c78b..cc1d1a2 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -17,7 +17,7 @@
 {
 public:
   cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
-                                           cmake* cm) const CM_OVERRIDE
+                                           cmake* cm) const override
   {
     if (strncmp(name.c_str(), vs8generatorName,
                 sizeof(vs8generatorName) - 1) != 0) {
@@ -51,14 +51,14 @@
     return ret;
   }
 
-  void GetDocumentation(cmDocumentationEntry& entry) const CM_OVERRIDE
+  void GetDocumentation(cmDocumentationEntry& entry) const override
   {
     entry.Name = std::string(vs8generatorName) + " [arch]";
     entry.Brief = "Deprecated.  Generates Visual Studio 2005 project files.  "
                   "Optional [arch] can be \"Win64\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const CM_OVERRIDE
+  void GetGenerators(std::vector<std::string>& names) const override
   {
     names.push_back(vs8generatorName);
     names.push_back(vs8generatorName + std::string(" Win64"));
@@ -73,8 +73,8 @@
     }
   }
 
-  bool SupportsToolset() const CM_OVERRIDE { return false; }
-  bool SupportsPlatform() const CM_OVERRIDE { return true; }
+  bool SupportsToolset() const override { return false; }
+  bool SupportsPlatform() const override { return true; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio8Generator::NewFactory()
@@ -301,7 +301,7 @@
     // file as the main dependency because it would get
     // overwritten by the CreateVCProjBuildRule.
     // (this could be avoided with per-target source files)
-    std::string no_main_dependency = "";
+    std::string no_main_dependency;
     std::vector<std::string> no_byproducts;
     if (cmSourceFile* file = mf->AddCustomCommandToOutput(
           stamps, no_byproducts, listFiles, no_main_dependency, commandLines,
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index b1634e2..0abb348 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -14,7 +14,7 @@
 {
 public:
   cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
-                                           cmake* cm) const CM_OVERRIDE
+                                           cmake* cm) const override
   {
     if (strncmp(name.c_str(), vs9generatorName,
                 sizeof(vs9generatorName) - 1) != 0) {
@@ -52,14 +52,14 @@
     return ret;
   }
 
-  void GetDocumentation(cmDocumentationEntry& entry) const CM_OVERRIDE
+  void GetDocumentation(cmDocumentationEntry& entry) const override
   {
     entry.Name = std::string(vs9generatorName) + " [arch]";
     entry.Brief = "Generates Visual Studio 2008 project files.  "
                   "Optional [arch] can be \"Win64\" or \"IA64\".";
   }
 
-  void GetGenerators(std::vector<std::string>& names) const CM_OVERRIDE
+  void GetGenerators(std::vector<std::string>& names) const override
   {
     names.push_back(vs9generatorName);
     names.push_back(vs9generatorName + std::string(" Win64"));
@@ -75,8 +75,8 @@
     }
   }
 
-  bool SupportsToolset() const CM_OVERRIDE { return false; }
-  bool SupportsPlatform() const CM_OVERRIDE { return true; }
+  bool SupportsToolset() const override { return false; }
+  bool SupportsPlatform() const override { return true; }
 };
 
 cmGlobalGeneratorFactory* cmGlobalVisualStudio9Generator::NewFactory()
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index ece2a77..0651536 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -150,7 +150,7 @@
 {
   std::string dir = this->GetUserMacrosDirectory();
 
-  if (dir != "") {
+  if (!dir.empty()) {
     std::string src = cmSystemTools::GetCMakeRoot();
     src += "/Templates/" CMAKE_VSMACROS_FILENAME;
 
@@ -190,7 +190,7 @@
   //  - the CMake vsmacros file is registered
   //  - there were .sln/.vcproj files changed during generation
   //
-  if (dir != "") {
+  if (!dir.empty()) {
     std::string macrosFile = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
     std::string nextSubkeyName;
     if (cmSystemTools::FileExists(macrosFile.c_str()) &&
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 399b6e0..62bfd3b 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -118,7 +118,7 @@
   };
   class OrderedTargetDependSet;
 
-  bool FindMakeProgram(cmMakefile*) CM_OVERRIDE;
+  bool FindMakeProgram(cmMakefile*) override;
 
   virtual std::string ExpandCFGIntDir(const std::string& str,
                                       const std::string& config) const;
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index bd09715..e8b3a73 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -29,7 +29,7 @@
     return new cmGlobalGeneratorSimpleFactory<cmGlobalWatcomWMakeGenerator>();
   }
   ///! Get the name for the generator.
-  std::string GetName() const CM_OVERRIDE
+  std::string GetName() const override
   {
     return cmGlobalWatcomWMakeGenerator::GetActualName();
   }
@@ -43,10 +43,10 @@
    * extension, pthreads, byte order etc.
    */
   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
-                      bool optional) CM_OVERRIDE;
+                      bool optional) override;
 
-  bool AllowNotParallel() const CM_OVERRIDE { return false; }
-  bool AllowDeleteOnError() const CM_OVERRIDE { return false; }
+  bool AllowNotParallel() const override { return false; }
+  bool AllowDeleteOnError() const override { return false; }
 };
 
 #endif
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index bfc8d9b..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) {
@@ -117,20 +117,20 @@
 {
 public:
   cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
-                                           cmake* cm) const CM_OVERRIDE;
+                                           cmake* cm) const override;
 
-  void GetDocumentation(cmDocumentationEntry& entry) const CM_OVERRIDE
+  void GetDocumentation(cmDocumentationEntry& entry) const override
   {
     cmGlobalXCodeGenerator::GetDocumentation(entry);
   }
 
-  void GetGenerators(std::vector<std::string>& names) const CM_OVERRIDE
+  void GetGenerators(std::vector<std::string>& names) const override
   {
     names.push_back(cmGlobalXCodeGenerator::GetActualName());
   }
 
-  bool SupportsToolset() const CM_OVERRIDE { return true; }
-  bool SupportsPlatform() const CM_OVERRIDE { return false; }
+  bool SupportsToolset() const override { return true; }
+  bool SupportsPlatform() const override { return false; }
 };
 
 cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(
@@ -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/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 7f57335..81d1bd0 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -37,7 +37,7 @@
   static cmGlobalGeneratorFactory* NewFactory();
 
   ///! Get the name for the generator.
-  std::string GetName() const CM_OVERRIDE
+  std::string GetName() const override
   {
     return cmGlobalXCodeGenerator::GetActualName();
   }
@@ -47,14 +47,14 @@
   static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
-  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) CM_OVERRIDE;
+  cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
 
   /**
    * Try to determine system information such as shared library
    * extension, pthreads, byte order etc.
    */
   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
-                      bool optional) CM_OVERRIDE;
+                      bool optional) override;
   /**
    * Try running cmake and building a file. This is used for dynalically
    * loaded commands, not as part of the usual build process.
@@ -66,42 +66,42 @@
                             const std::string& targetName,
                             const std::string& config, bool fast, bool verbose,
                             std::vector<std::string> const& makeOptions =
-                              std::vector<std::string>()) CM_OVERRIDE;
+                              std::vector<std::string>()) override;
 
   /** Append the subdirectory for the given configuration.  */
   void AppendDirectoryForConfig(const std::string& prefix,
                                 const std::string& config,
                                 const std::string& suffix,
-                                std::string& dir) CM_OVERRIDE;
+                                std::string& dir) override;
 
-  bool FindMakeProgram(cmMakefile*) CM_OVERRIDE;
+  bool FindMakeProgram(cmMakefile*) override;
 
   ///! What is the configurations directory variable called?
-  const char* GetCMakeCFGIntDir() const CM_OVERRIDE;
+  const char* GetCMakeCFGIntDir() const override;
   ///! expand CFGIntDir
   std::string ExpandCFGIntDir(const std::string& str,
-                              const std::string& config) const CM_OVERRIDE;
+                              const std::string& config) const override;
 
   void SetCurrentLocalGenerator(cmLocalGenerator*);
 
   /** Return true if the generated build tree may contain multiple builds.
       i.e. "Can I build Debug and Release in the same tree?" */
-  bool IsMultiConfig() const CM_OVERRIDE;
+  bool IsMultiConfig() const override;
 
-  bool HasKnownObjectFileLocation(std::string* reason) const CM_OVERRIDE;
+  bool HasKnownObjectFileLocation(std::string* reason) const override;
 
-  bool IsIPOSupported() const CM_OVERRIDE { return true; }
+  bool IsIPOSupported() const override { return true; }
 
-  bool UseEffectivePlatformName(cmMakefile* mf) const CM_OVERRIDE;
+  bool UseEffectivePlatformName(cmMakefile* mf) const override;
 
-  bool ShouldStripResourcePath(cmMakefile*) const CM_OVERRIDE;
+  bool ShouldStripResourcePath(cmMakefile*) const override;
 
-  bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) CM_OVERRIDE;
+  bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
   void AppendFlag(std::string& flags, std::string const& flag);
 
 protected:
-  void AddExtraIDETargets() CM_OVERRIDE;
-  void Generate() CM_OVERRIDE;
+  void AddExtraIDETargets() override;
+  void Generate() override;
 
 private:
   cmXCodeObject* CreateOrGetPBXGroup(cmGeneratorTarget* gtgt,
@@ -144,7 +144,7 @@
   cmXCodeObject* CreateFlatClone(cmXCodeObject*);
   cmXCodeObject* CreateXCodeTarget(cmGeneratorTarget* gtgt,
                                    cmXCodeObject* buildPhases);
-  void ForceLinkerLanguages() CM_OVERRIDE;
+  void ForceLinkerLanguages() override;
   void ForceLinkerLanguage(cmGeneratorTarget* gtgt);
   const char* GetTargetLinkFlagsVar(const cmGeneratorTarget* target) const;
   const char* GetTargetFileType(cmGeneratorTarget* target);
@@ -219,11 +219,11 @@
                      std::vector<std::string> const& defines,
                      bool dflag = false);
 
-  void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const CM_OVERRIDE;
+  void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
 
 protected:
-  const char* GetInstallTargetName() const CM_OVERRIDE { return "install"; }
-  const char* GetPackageTargetName() const CM_OVERRIDE { return "package"; }
+  const char* GetInstallTargetName() const override { return "install"; }
+  const char* GetPackageTargetName() const override { return "package"; }
 
   unsigned int XcodeVersion;
   std::string VersionString;
@@ -238,7 +238,7 @@
   bool XcodeBuildCommandInitialized;
 
   void PrintCompilerAdvice(std::ostream&, std::string const&,
-                           const char*) const CM_OVERRIDE
+                           const char*) const override
   {
   }
 
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index da2fce9..e3d30dd 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -25,10 +25,10 @@
     this->ElseSeen = false;
     this->ScopeDepth = 0;
   }
-  ~cmIfFunctionBlocker() CM_OVERRIDE {}
+  ~cmIfFunctionBlocker() override {}
   bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
-                         cmExecutionStatus&) CM_OVERRIDE;
-  bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) CM_OVERRIDE;
+                         cmExecutionStatus&) override;
+  bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
 
   std::vector<cmListFileArgument> Args;
   std::vector<cmListFileFunction> Functions;
@@ -45,21 +45,21 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmIfCommand; }
+  cmCommand* Clone() override { return new cmIfCommand; }
 
   /**
    * This overrides the default InvokeInitialPass implementation.
    * It records the arguments before expansion.
    */
   bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
-                         cmExecutionStatus&) CM_OVERRIDE;
+                         cmExecutionStatus&) override;
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) CM_OVERRIDE
+                   cmExecutionStatus&) override
   {
     return false;
   }
diff --git a/Source/cmIncludeCommand.h b/Source/cmIncludeCommand.h
index ceda931..3b843b2 100644
--- a/Source/cmIncludeCommand.h
+++ b/Source/cmIncludeCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmIncludeCommand; }
+  cmCommand* Clone() override { return new cmIncludeCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
index b81f7cb..4c30607 100644
--- a/Source/cmIncludeDirectoryCommand.cxx
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -116,7 +116,7 @@
   if ((b != std::string::npos) && (e != std::string::npos)) {
     inc.assign(inc, b, 1 + e - b); // copy the remaining substring
   } else {
-    inc = "";
+    inc.clear();
     return;
   }
 
diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h
index a7b3685..01d98db 100644
--- a/Source/cmIncludeDirectoryCommand.h
+++ b/Source/cmIncludeDirectoryCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmIncludeDirectoryCommand; }
+  cmCommand* Clone() override { return new cmIncludeDirectoryCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 protected:
   // used internally
diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h
index 88ee2f8..945acdc 100644
--- a/Source/cmIncludeExternalMSProjectCommand.h
+++ b/Source/cmIncludeExternalMSProjectCommand.h
@@ -25,17 +25,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
-  {
-    return new cmIncludeExternalMSProjectCommand;
-  }
+  cmCommand* Clone() override { return new cmIncludeExternalMSProjectCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmIncludeGuardCommand.h b/Source/cmIncludeGuardCommand.h
index 4dc3d90..eaad9b8 100644
--- a/Source/cmIncludeGuardCommand.h
+++ b/Source/cmIncludeGuardCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmIncludeGuardCommand; }
+  cmCommand* Clone() override { return new cmIncludeGuardCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h
index 3ea0443..8da991d 100644
--- a/Source/cmIncludeRegularExpressionCommand.h
+++ b/Source/cmIncludeRegularExpressionCommand.h
@@ -24,17 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
-  {
-    return new cmIncludeRegularExpressionCommand;
-  }
+  cmCommand* Clone() override { return new cmIncludeRegularExpressionCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
index b34f560..8bd0159 100644
--- a/Source/cmInstallCommand.h
+++ b/Source/cmInstallCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmInstallCommand; }
+  cmCommand* Clone() override { return new cmInstallCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   bool HandleScriptMode(std::vector<std::string> const& args);
diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
index 179521e..ff6420d 100644
--- a/Source/cmInstallCommandArguments.cxx
+++ b/Source/cmInstallCommandArguments.cxx
@@ -153,7 +153,7 @@
 
 bool cmInstallCommandArguments::CheckPermissions()
 {
-  this->PermissionsString = "";
+  this->PermissionsString.clear();
   for (std::string const& perm : this->Permissions.GetVector()) {
     if (!this->CheckPermissions(perm, this->PermissionsString)) {
       return false;
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index d699599..ac6e504 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -27,16 +27,16 @@
                               const char* component, MessageLevel message,
                               bool exclude_from_all, const char* literal_args,
                               bool optional = false);
-  ~cmInstallDirectoryGenerator() CM_OVERRIDE;
+  ~cmInstallDirectoryGenerator() override;
 
-  void Compute(cmLocalGenerator* lg) CM_OVERRIDE;
+  void Compute(cmLocalGenerator* lg) override;
 
   std::string GetDestination(std::string const& config) const;
 
 protected:
-  void GenerateScriptActions(std::ostream& os, Indent indent) CM_OVERRIDE;
+  void GenerateScriptActions(std::ostream& os, Indent indent) override;
   void GenerateScriptForConfig(std::ostream& os, const std::string& config,
-                               Indent indent) CM_OVERRIDE;
+                               Indent indent) override;
   void AddDirectoryInstallRule(std::ostream& os, const std::string& config,
                                Indent indent,
                                std::vector<std::string> const& dirs);
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index 35c7743..d23cf06 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -30,11 +30,11 @@
                            bool exclude_from_all, const char* filename,
                            const char* name_space, bool exportOld,
                            bool android);
-  ~cmInstallExportGenerator() CM_OVERRIDE;
+  ~cmInstallExportGenerator() override;
 
   cmExportSet* GetExportSet() { return this->ExportSet; }
 
-  void Compute(cmLocalGenerator* lg) CM_OVERRIDE;
+  void Compute(cmLocalGenerator* lg) override;
 
   cmLocalGenerator* GetLocalGenerator() const { return this->LocalGenerator; }
 
@@ -43,9 +43,9 @@
   std::string const& GetDestination() const { return this->Destination; }
 
 protected:
-  void GenerateScript(std::ostream& os) CM_OVERRIDE;
-  void GenerateScriptConfigs(std::ostream& os, Indent indent) CM_OVERRIDE;
-  void GenerateScriptActions(std::ostream& os, Indent indent) CM_OVERRIDE;
+  void GenerateScript(std::ostream& os) override;
+  void GenerateScriptConfigs(std::ostream& os, Indent indent) override;
+  void GenerateScriptActions(std::ostream& os, Indent indent) override;
   void GenerateImportFile(cmExportSet const* exportSet);
   void GenerateImportFile(const char* config, cmExportSet const* exportSet);
   void ComputeTempDir();
diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h
index 702b332..19f2559 100644
--- a/Source/cmInstallFilesCommand.h
+++ b/Source/cmInstallFilesCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmInstallFilesCommand; }
+  cmCommand* Clone() override { return new cmInstallFilesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   /**
    * This is called at the end after all the information
@@ -39,8 +39,8 @@
    * not implement this method.  At this point, reading and
    * writing to the cache can be done.
    */
-  void FinalPass() CM_OVERRIDE;
-  bool HasFinalPass() const CM_OVERRIDE { return !this->IsFilesForm; }
+  void FinalPass() override;
+  bool HasFinalPass() const override { return !this->IsFilesForm; }
 
 protected:
   void CreateInstallGenerator() const;
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index b2c7c4b..0ef2a06 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -27,16 +27,16 @@
                           const char* component, MessageLevel message,
                           bool exclude_from_all, const char* rename,
                           bool optional = false);
-  ~cmInstallFilesGenerator() CM_OVERRIDE;
+  ~cmInstallFilesGenerator() override;
 
-  void Compute(cmLocalGenerator* lg) CM_OVERRIDE;
+  void Compute(cmLocalGenerator* lg) override;
 
   std::string GetDestination(std::string const& config) const;
 
 protected:
-  void GenerateScriptActions(std::ostream& os, Indent indent) CM_OVERRIDE;
+  void GenerateScriptActions(std::ostream& os, Indent indent) override;
   void GenerateScriptForConfig(std::ostream& os, const std::string& config,
-                               Indent indent) CM_OVERRIDE;
+                               Indent indent) override;
   void AddFilesInstallRule(std::ostream& os, std::string const& config,
                            Indent indent,
                            std::vector<std::string> const& files);
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index 813cbe8..fc1ce86 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -36,7 +36,7 @@
                      std::vector<std::string> const& configurations,
                      const char* component, MessageLevel message,
                      bool exclude_from_all);
-  ~cmInstallGenerator() CM_OVERRIDE;
+  ~cmInstallGenerator() override;
 
   void AddInstallRule(
     std::ostream& os, std::string const& dest, cmInstallType type,
@@ -58,7 +58,7 @@
   virtual void Compute(cmLocalGenerator*) {}
 
 protected:
-  void GenerateScript(std::ostream& os) CM_OVERRIDE;
+  void GenerateScript(std::ostream& os) override;
 
   std::string CreateComponentTest(const char* component,
                                   bool exclude_from_all);
diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h
index e0ecbda..5c705eb 100644
--- a/Source/cmInstallProgramsCommand.h
+++ b/Source/cmInstallProgramsCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmInstallProgramsCommand; }
+  cmCommand* Clone() override { return new cmInstallProgramsCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   /**
    * This is called at the end after all the information
@@ -39,9 +39,9 @@
    * not implement this method.  At this point, reading and
    * writing to the cache can be done.
    */
-  void FinalPass() CM_OVERRIDE;
+  void FinalPass() override;
 
-  bool HasFinalPass() const CM_OVERRIDE { return true; }
+  bool HasFinalPass() const override { return true; }
 
 protected:
   std::string FindInstallSource(const char* name) const;
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
index 7e19aa6..fe0f7c6 100644
--- a/Source/cmInstallScriptGenerator.h
+++ b/Source/cmInstallScriptGenerator.h
@@ -18,10 +18,10 @@
 public:
   cmInstallScriptGenerator(const char* script, bool code,
                            const char* component, bool exclude_from_all);
-  ~cmInstallScriptGenerator() CM_OVERRIDE;
+  ~cmInstallScriptGenerator() override;
 
 protected:
-  void GenerateScript(std::ostream& os) CM_OVERRIDE;
+  void GenerateScript(std::ostream& os) override;
   std::string Script;
   bool Code;
 };
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 385d995..f6bec20 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -26,7 +26,7 @@
                            std::vector<std::string> const& configurations,
                            const char* component, MessageLevel message,
                            bool exclude_from_all, bool optional);
-  ~cmInstallTargetGenerator() CM_OVERRIDE;
+  ~cmInstallTargetGenerator() override;
 
   /** Select the policy for installing shared library linkable name
       symlinks.  */
@@ -56,7 +56,7 @@
                                         const std::string& config,
                                         NameType nameType = NameNormal);
 
-  void Compute(cmLocalGenerator* lg) CM_OVERRIDE;
+  void Compute(cmLocalGenerator* lg) override;
 
   cmGeneratorTarget* GetTarget() const { return this->Target; }
 
@@ -65,9 +65,9 @@
   std::string GetDestination(std::string const& config) const;
 
 protected:
-  void GenerateScript(std::ostream& os) CM_OVERRIDE;
+  void GenerateScript(std::ostream& os) override;
   void GenerateScriptForConfig(std::ostream& os, const std::string& config,
-                               Indent indent) CM_OVERRIDE;
+                               Indent indent) override;
   void GenerateScriptForConfigObjectLibrary(std::ostream& os,
                                             const std::string& config,
                                             Indent indent);
diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h
index 17622fb..9950fb7 100644
--- a/Source/cmInstallTargetsCommand.h
+++ b/Source/cmInstallTargetsCommand.h
@@ -25,14 +25,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmInstallTargetsCommand; }
+  cmCommand* Clone() override { return new cmInstallTargetsCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h
index 6297073..3fd4e50 100644
--- a/Source/cmLinkDirectoriesCommand.h
+++ b/Source/cmLinkDirectoriesCommand.h
@@ -26,14 +26,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmLinkDirectoriesCommand; }
+  cmCommand* Clone() override { return new cmLinkDirectoriesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   void AddLinkDir(std::string const& dir);
diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h
index 54121dd..af25fba 100644
--- a/Source/cmLinkLibrariesCommand.h
+++ b/Source/cmLinkLibrariesCommand.h
@@ -25,14 +25,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmLinkLibrariesCommand; }
+  cmCommand* Clone() override { return new cmLinkLibrariesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h
index 66941d3..81b48b3 100644
--- a/Source/cmLinkLineDeviceComputer.h
+++ b/Source/cmLinkLineDeviceComputer.h
@@ -23,14 +23,13 @@
 public:
   cmLinkLineDeviceComputer(cmOutputConverter* outputConverter,
                            cmStateDirectory const& stateDir);
-  ~cmLinkLineDeviceComputer() CM_OVERRIDE;
+  ~cmLinkLineDeviceComputer() override;
 
   std::string ComputeLinkLibraries(cmComputeLinkInformation& cli,
-                                   std::string const& stdLibString)
-    CM_OVERRIDE;
+                                   std::string const& stdLibString) override;
 
   std::string GetLinkerLanguage(cmGeneratorTarget* target,
-                                std::string const& config) CM_OVERRIDE;
+                                std::string const& config) override;
 };
 
 class cmNinjaLinkLineDeviceComputer : public cmLinkLineDeviceComputer
@@ -42,8 +41,7 @@
                                 cmStateDirectory const& stateDir,
                                 cmGlobalNinjaGenerator const* gg);
 
-  std::string ConvertToLinkReference(std::string const& input) const
-    CM_OVERRIDE;
+  std::string ConvertToLinkReference(std::string const& input) const override;
 
 private:
   cmGlobalNinjaGenerator const* GG;
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index 7d3800a..2965399 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -22,14 +22,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmListCommand; }
+  cmCommand* Clone() override { return new cmListCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 protected:
   bool HandleLengthCommand(std::vector<std::string> const& args);
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index 419b2e4..32fdef5 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -124,7 +124,7 @@
         if (i != end) {
           // Completed a line.
           this->CheckLine(line.c_str());
-          line = "";
+          line.clear();
 
           // Skip the newline character.
           ++i;
diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h
index e46144d..e0f6e4f 100644
--- a/Source/cmLoadCacheCommand.h
+++ b/Source/cmLoadCacheCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmLoadCacheCommand; }
+  cmCommand* Clone() override { return new cmLoadCacheCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 protected:
   std::set<std::string> VariablesToRead;
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index a871df9..6bfac17 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -34,12 +34,12 @@
   }
 
   ///! clean up any memory allocated by the plugin
-  ~cmLoadedCommand() CM_OVERRIDE;
+  ~cmLoadedCommand() override;
 
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmLoadedCommand* newC = new cmLoadedCommand;
     // we must copy when we clone
@@ -52,7 +52,7 @@
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus&) CM_OVERRIDE;
+                   cmExecutionStatus&) override;
 
   /**
    * This is called at the end after all the information
@@ -60,8 +60,8 @@
    * not implement this method.  At this point, reading and
    * writing to the cache can be done.
    */
-  void FinalPass() CM_OVERRIDE;
-  bool HasFinalPass() const CM_OVERRIDE
+  void FinalPass() override;
+  bool HasFinalPass() const override
   {
     return this->info.FinalPass != nullptr;
   }
@@ -197,7 +197,7 @@
 
   // Try to find the program.
   std::string fullPath = cmSystemTools::FindFile(moduleName, path);
-  if (fullPath == "") {
+  if (fullPath.empty()) {
     std::ostringstream e;
     e << "Attempt to load command failed from file \"" << moduleName << "\"";
     this->SetError(e.str());
diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h
index 30bb7da..021e6c7 100644
--- a/Source/cmLoadCommandCommand.h
+++ b/Source/cmLoadCommandCommand.h
@@ -15,9 +15,9 @@
 class cmLoadCommandCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmLoadCommandCommand; }
+  cmCommand* Clone() override { return new cmLoadCommandCommand; }
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index d255173..50ebfa1 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -22,7 +22,7 @@
     this->ConfigName = config;
   } else {
     // No configuration type given.
-    this->ConfigName = "";
+    this->ConfigName.clear();
   }
 }
 
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
index 999085e..a60573c 100644
--- a/Source/cmLocalCommonGenerator.h
+++ b/Source/cmLocalCommonGenerator.h
@@ -21,14 +21,14 @@
 public:
   cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf,
                          std::string const& wd);
-  ~cmLocalCommonGenerator() CM_OVERRIDE;
+  ~cmLocalCommonGenerator() override;
 
   std::string const& GetConfigName() { return this->ConfigName; }
 
   std::string GetWorkingDirectory() const { return this->WorkingDirectory; }
 
   std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
-                                    std::string const& config) CM_OVERRIDE;
+                                    std::string const& config) override;
 
 protected:
   std::string WorkingDirectory;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index e1662ac..1a088ea 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1410,7 +1410,7 @@
 
   // If the input name is the empty string, there is no real
   // dependency. Short-circuit the other checks:
-  if (name == "") {
+  if (name.empty()) {
     return false;
   }
 
@@ -2096,7 +2096,7 @@
     }
 
     // Install this target if a destination is given.
-    if (l->Target->GetInstallPath() != "") {
+    if (!l->Target->GetInstallPath().empty()) {
       // Compute the full install destination.  Note that converting
       // to unix slashes also removes any trailing slash.
       // We also skip over the leading slash given by the user.
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 8a7f455..73f5a16 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -55,7 +55,7 @@
   this->HomeRelativeOutputPath = this->ConvertToRelativePath(
     this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory());
   if (this->HomeRelativeOutputPath == ".") {
-    this->HomeRelativeOutputPath = "";
+    this->HomeRelativeOutputPath.clear();
   }
 
   this->WriteProcessedMakefile(this->GetBuildFileStream());
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index b0eb1da..bb16899 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -38,14 +38,14 @@
 public:
   cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
 
-  ~cmLocalNinjaGenerator() CM_OVERRIDE;
+  ~cmLocalNinjaGenerator() override;
 
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
-  cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const CM_OVERRIDE;
+  cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const override;
 
-  std::string GetTargetDirectory(cmGeneratorTarget const* target) const
-    CM_OVERRIDE;
+  std::string GetTargetDirectory(
+    cmGeneratorTarget const* target) const override;
 
   const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const;
   cmGlobalNinjaGenerator* GetGlobalNinjaGenerator();
@@ -76,13 +76,13 @@
 
   void ComputeObjectFilenames(
     std::map<cmSourceFile const*, std::string>& mapping,
-    cmGeneratorTarget const* gt = nullptr) CM_OVERRIDE;
+    cmGeneratorTarget const* gt = nullptr) override;
 
 protected:
   std::string ConvertToIncludeReference(
     std::string const& path,
     cmOutputConverter::OutputFormat format = cmOutputConverter::SHELL,
-    bool forceFullPaths = false) CM_OVERRIDE;
+    bool forceFullPaths = false) override;
 
 private:
   cmGeneratedFileStream& GetBuildFileStream() const;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 7f7ec4f..df02f84 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -144,7 +144,7 @@
   this->HomeRelativeOutputPath = this->MaybeConvertToRelativePath(
     this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory());
   if (this->HomeRelativeOutputPath == ".") {
-    this->HomeRelativeOutputPath = "";
+    this->HomeRelativeOutputPath.clear();
   }
   if (!this->HomeRelativeOutputPath.empty()) {
     this->HomeRelativeOutputPath += "/";
@@ -1163,7 +1163,7 @@
       }
 
       // Reset the line to emtpy.
-      line = "";
+      line.clear();
 
       // Progress appears only on first line.
       progress = nullptr;
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 16c305a..b149524 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -31,14 +31,14 @@
 {
 public:
   cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
-  ~cmLocalUnixMakefileGenerator3() CM_OVERRIDE;
+  ~cmLocalUnixMakefileGenerator3() override;
 
-  void ComputeHomeRelativeOutputPath() CM_OVERRIDE;
+  void ComputeHomeRelativeOutputPath() override;
 
   /**
    * Generate the makefile for this directory.
    */
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
   // this returns the relative path between the HomeOutputDirectory and this
   // local generators StartOutputDirectory
@@ -88,9 +88,8 @@
                                    const std::string& tgt);
 
   // append flags to a string
-  void AppendFlags(std::string& flags,
-                   const std::string& newFlags) CM_OVERRIDE;
-  void AppendFlags(std::string& flags, const char* newFlags) CM_OVERRIDE;
+  void AppendFlags(std::string& flags, const std::string& newFlags) override;
+  void AppendFlags(std::string& flags, const char* newFlags) override;
 
   // append an echo command
   enum EchoColor
@@ -113,8 +112,8 @@
   /** Get whether the makefile is to have color.  */
   bool GetColorMakefile() const { return this->ColorMakefile; }
 
-  std::string GetTargetDirectory(cmGeneratorTarget const* target) const
-    CM_OVERRIDE;
+  std::string GetTargetDirectory(
+    cmGeneratorTarget const* target) const override;
 
   // create a command that cds to the start dir then runs the commands
   void CreateCDCommand(std::vector<std::string>& commands,
@@ -129,10 +128,10 @@
   /** Called from command-line hook to bring dependencies up to date
       for a target.  */
   bool UpdateDependencies(const char* tgtInfo, bool verbose,
-                          bool color) CM_OVERRIDE;
+                          bool color) override;
 
   /** Called from command-line hook to clear dependencies.  */
-  void ClearDependencies(cmMakefile* mf, bool verbose) CM_OVERRIDE;
+  void ClearDependencies(cmMakefile* mf, bool verbose) override;
 
   /** write some extra rules such as make test etc */
   void WriteSpecialTargetsTop(std::ostream& makefileStream);
@@ -254,7 +253,7 @@
 
   void ComputeObjectFilenames(
     std::map<cmSourceFile const*, std::string>& mapping,
-    cmGeneratorTarget const* gt = nullptr) CM_OVERRIDE;
+    cmGeneratorTarget const* gt = nullptr) override;
 
   friend class cmMakefileTargetGenerator;
   friend class cmMakefileExecutableTargetGenerator;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index fc42d6e..a1771ee 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -121,7 +121,7 @@
       force_command.push_back(".");
       cmCustomCommandLines force_commands;
       force_commands.push_back(force_command);
-      std::string no_main_dependency = "";
+      std::string no_main_dependency;
       std::string force = this->GetCurrentBinaryDirectory();
       force += cmake::GetCMakeFilesDirectory();
       force += "/";
@@ -1591,7 +1591,7 @@
 
   // If the group has a name, write the header.
   std::string name = sg->GetName();
-  if (name != "") {
+  if (!name.empty()) {
     this->WriteVCProjBeginGroup(fout, name.c_str(), "");
   }
 
@@ -1709,7 +1709,7 @@
   }
 
   // If the group has a name, write the footer.
-  if (name != "") {
+  if (!name.empty()) {
     this->WriteVCProjEndGroup(fout);
   }
 
@@ -2006,7 +2006,7 @@
        i != props.end(); ++i) {
     if (i->find("VS_GLOBAL_") == 0) {
       std::string name = i->substr(10);
-      if (name != "") {
+      if (!name.empty()) {
         /* clang-format off */
         fout << "\t\t<Global\n"
              << "\t\t\tName=\"" << name << "\"\n"
@@ -2081,7 +2081,7 @@
             this->GUID = atts[i + 1];
             this->GUID = this->GUID.substr(1, this->GUID.size() - 2);
           } else {
-            this->GUID = "";
+            this->GUID.clear();
           }
           return;
         }
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index d772d95..718c8cd 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -135,7 +135,7 @@
   std::string workingDirectory = ccg.GetWorkingDirectory();
 
   // Avoid leading or trailing newlines.
-  std::string newline = "";
+  std::string newline;
 
   // Line to check for error between commands.
   std::string check_error = newline_text;
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/cmMSVC60LinkLineComputer.h b/Source/cmMSVC60LinkLineComputer.h
index 19e2c16..31223ec 100644
--- a/Source/cmMSVC60LinkLineComputer.h
+++ b/Source/cmMSVC60LinkLineComputer.h
@@ -21,8 +21,7 @@
   cmMSVC60LinkLineComputer(cmOutputConverter* outputConverter,
                            cmStateDirectory const& stateDir);
 
-  std::string ConvertToLinkReference(std::string const& input) const
-    CM_OVERRIDE;
+  std::string ConvertToLinkReference(std::string const& input) const override;
 };
 
 #endif
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/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 003c443..74a1da0 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -19,12 +19,12 @@
   cmMacroHelperCommand() {}
 
   ///! clean up any memory allocated by the macro
-  ~cmMacroHelperCommand() CM_OVERRIDE {}
+  ~cmMacroHelperCommand() override {}
 
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     cmMacroHelperCommand* newC = new cmMacroHelperCommand;
     // we must copy when we clone
@@ -40,10 +40,10 @@
    * the CMakeLists.txt file.
    */
   bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
-                         cmExecutionStatus&) CM_OVERRIDE;
+                         cmExecutionStatus&) override;
 
   bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) CM_OVERRIDE
+                   cmExecutionStatus&) override
   {
     return false;
   }
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
index cbfb60f..d967388 100644
--- a/Source/cmMacroCommand.h
+++ b/Source/cmMacroCommand.h
@@ -19,10 +19,10 @@
 {
 public:
   cmMacroFunctionBlocker() { this->Depth = 0; }
-  ~cmMacroFunctionBlocker() CM_OVERRIDE {}
+  ~cmMacroFunctionBlocker() override {}
   bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf,
-                         cmExecutionStatus&) CM_OVERRIDE;
-  bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) CM_OVERRIDE;
+                         cmExecutionStatus&) override;
+  bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
 
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
@@ -36,14 +36,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmMacroCommand; }
+  cmCommand* Clone() override { return new cmMacroCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h
index 214cf92..d2637f3 100644
--- a/Source/cmMakeDirectoryCommand.h
+++ b/Source/cmMakeDirectoryCommand.h
@@ -27,14 +27,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmMakeDirectoryCommand; }
+  cmCommand* Clone() override { return new cmMakeDirectoryCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 845568b..c96b892 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1645,7 +1645,7 @@
       nvalue = value ? value : "";
 
       cmSystemTools::ExpandListArgument(nvalue, files);
-      nvalue = "";
+      nvalue.clear();
       for (cc = 0; cc < files.size(); cc++) {
         if (!cmSystemTools::IsOff(files[cc].c_str())) {
           files[cc] = cmSystemTools::CollapseFullPath(files[cc]);
@@ -2448,7 +2448,7 @@
     std::string input = source;
 
     // Start with empty output.
-    source = "";
+    source.clear();
 
     // Look for one @VAR@ at a time.
     const char* in = input.c_str();
@@ -3082,9 +3082,18 @@
 cmSourceFile* cmMakefile::GetSource(const std::string& sourceName) const
 {
   cmSourceFileLocation sfl(this, sourceName);
-  for (cmSourceFile* sf : this->SourceFiles) {
-    if (sf->Matches(sfl)) {
-      return sf;
+
+#if defined(_WIN32) || defined(__APPLE__)
+  const auto& name = cmSystemTools::LowerCase(sfl.GetName());
+#else
+  const auto& name = sfl.GetName();
+#endif
+  auto sfsi = this->SourceFileSearchIndex.find(name);
+  if (sfsi != this->SourceFileSearchIndex.end()) {
+    for (auto sf : sfsi->second) {
+      if (sf->Matches(sfl)) {
+        return sf;
+      }
     }
   }
   return nullptr;
@@ -3098,6 +3107,41 @@
     sf->SetProperty("GENERATED", "1");
   }
   this->SourceFiles.push_back(sf);
+
+  auto name = sf->GetLocation().GetName();
+#if defined(_WIN32) || defined(__APPLE__)
+  name = cmSystemTools::LowerCase(name);
+#endif
+
+  // For a file in the form "a.b.c" add the cmSourceFile to the index
+  // at "a.b.c", "a.b" and "a".
+  auto partial = name;
+  while (true) {
+    this->SourceFileSearchIndex[partial].insert(sf);
+    auto i = partial.rfind('.');
+    if (i == std::string::npos) {
+      break;
+    }
+    partial = partial.substr(0, i);
+  }
+
+  if (sf->GetLocation().ExtensionIsAmbiguous()) {
+    // For an ambiguous extension also add the various "known"
+    // extensions to the original filename.
+
+    const auto& srcExts = this->GetCMakeInstance()->GetSourceExtensions();
+    for (const auto& ext : srcExts) {
+      auto name_ext = name + "." + cmSystemTools::LowerCase(ext);
+      this->SourceFileSearchIndex[name_ext].insert(sf);
+    }
+
+    const auto& hdrExts = this->GetCMakeInstance()->GetHeaderExtensions();
+    for (const auto& ext : hdrExts) {
+      auto name_ext = name + "." + cmSystemTools::LowerCase(ext);
+      this->SourceFileSearchIndex[name_ext].insert(sf);
+    }
+  }
+
   return sf;
 }
 
@@ -3348,7 +3392,7 @@
   moduleInCMakeRoot += filename;
   cmSystemTools::ConvertToUnixSlashes(moduleInCMakeRoot);
   if (!cmSystemTools::FileExists(moduleInCMakeRoot.c_str())) {
-    moduleInCMakeRoot = "";
+    moduleInCMakeRoot.clear();
   }
 
   // Normally, prefer the files found in CMAKE_MODULE_PATH. Only when the file
@@ -3532,7 +3576,7 @@
     std::string inLine;
     std::string outLine;
     while (cmSystemTools::GetLineFromStream(fin, inLine)) {
-      outLine = "";
+      outLine.clear();
       this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
       fout << outLine << newLineCharacters;
     }
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 398604d..2cae659 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -13,6 +13,7 @@
 #include <stddef.h>
 #include <string>
 #include <unordered_map>
+#include <unordered_set>
 #include <vector>
 
 #include "cmAlgorithms.h"
@@ -623,7 +624,6 @@
   {
     return this->SourceFiles;
   }
-  std::vector<cmSourceFile*>& GetSourceFiles() { return this->SourceFiles; }
 
   /**
    * Is there a source file that has the provided source file as an output?
@@ -809,7 +809,17 @@
   // libraries, classes, and executables
   mutable cmTargets Targets;
   std::map<std::string, std::string> AliasTargets;
+
   std::vector<cmSourceFile*> SourceFiles;
+  // Because cmSourceFile names are compared in a fuzzy way (see
+  // cmSourceFileLocation::Match()) we can't have a straight mapping from
+  // filename to cmSourceFile.  To make lookups more efficient we store the
+  // Name portion of the cmSourceFileLocation and then compare on the list of
+  // cmSourceFiles that might match that name.  Note that on platforms which
+  // have a case-insensitive filesystem we store the key in all lowercase.
+  typedef std::unordered_set<cmSourceFile*> SourceFileSet;
+  typedef std::unordered_map<std::string, SourceFileSet> SourceFileMap;
+  SourceFileMap SourceFileSearchIndex;
 
   // Tests
   std::map<std::string, cmTest*> Tests;
diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h
index 122e817..b9bbe86 100644
--- a/Source/cmMakefileExecutableTargetGenerator.h
+++ b/Source/cmMakefileExecutableTargetGenerator.h
@@ -15,11 +15,11 @@
 {
 public:
   cmMakefileExecutableTargetGenerator(cmGeneratorTarget* target);
-  ~cmMakefileExecutableTargetGenerator() CM_OVERRIDE;
+  ~cmMakefileExecutableTargetGenerator() override;
 
   /* the main entry point for this class. Writes the Makefiles associated
      with this target */
-  void WriteRuleFiles() CM_OVERRIDE;
+  void WriteRuleFiles() override;
 
 protected:
   virtual void WriteExecutableRule(bool relink);
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
index 307cd15..02fa029 100644
--- a/Source/cmMakefileLibraryTargetGenerator.h
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -15,11 +15,11 @@
 {
 public:
   cmMakefileLibraryTargetGenerator(cmGeneratorTarget* target);
-  ~cmMakefileLibraryTargetGenerator() CM_OVERRIDE;
+  ~cmMakefileLibraryTargetGenerator() override;
 
   /* the main entry point for this class. Writes the Makefiles associated
      with this target */
-  void WriteRuleFiles() CM_OVERRIDE;
+  void WriteRuleFiles() override;
 
 protected:
   void WriteObjectLibraryRules();
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 1e4e02e..d0aad30 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1261,7 +1261,7 @@
         (this->CurrentString.length() + 1 + this->NextObject.length() >
          this->LengthLimit)) {
       this->Strings.push_back(this->CurrentString);
-      this->CurrentString = "";
+      this->CurrentString.clear();
       this->Space = "";
     }
 
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index e0e9580..5ab7e36 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -33,7 +33,7 @@
 public:
   // constructor to set the ivars
   cmMakefileTargetGenerator(cmGeneratorTarget* target);
-  ~cmMakefileTargetGenerator() CM_OVERRIDE;
+  ~cmMakefileTargetGenerator() override;
 
   // construct using this factory call
   static cmMakefileTargetGenerator* New(cmGeneratorTarget* tgt);
@@ -81,8 +81,7 @@
     {
     }
 
-    void operator()(cmSourceFile const& source,
-                    const char* pkgloc) CM_OVERRIDE;
+    void operator()(cmSourceFile const& source, const char* pkgloc) override;
 
   private:
     cmMakefileTargetGenerator* Generator;
@@ -168,8 +167,7 @@
   /** Add commands for generate def files */
   void GenDefFile(std::vector<std::string>& real_link_commands);
 
-  void AddIncludeFlags(std::string& flags,
-                       const std::string& lang) CM_OVERRIDE;
+  void AddIncludeFlags(std::string& flags, const std::string& lang) override;
 
   virtual void CloseFileStreams();
   cmLocalUnixMakefileGenerator3* LocalGenerator;
diff --git a/Source/cmMakefileUtilityTargetGenerator.h b/Source/cmMakefileUtilityTargetGenerator.h
index 2826392..be243a7 100644
--- a/Source/cmMakefileUtilityTargetGenerator.h
+++ b/Source/cmMakefileUtilityTargetGenerator.h
@@ -13,11 +13,11 @@
 {
 public:
   cmMakefileUtilityTargetGenerator(cmGeneratorTarget* target);
-  ~cmMakefileUtilityTargetGenerator() CM_OVERRIDE;
+  ~cmMakefileUtilityTargetGenerator() override;
 
   /* the main entry point for this class. Writes the Makefiles associated
      with this target */
-  void WriteRuleFiles() CM_OVERRIDE;
+  void WriteRuleFiles() override;
 
 protected:
 };
diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h
index 6c22d4c..5dd198f 100644
--- a/Source/cmMarkAsAdvancedCommand.h
+++ b/Source/cmMarkAsAdvancedCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmMarkAsAdvancedCommand; }
+  cmCommand* Clone() override { return new cmMarkAsAdvancedCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h
index bc97402..0c6c76b 100644
--- a/Source/cmMathCommand.h
+++ b/Source/cmMathCommand.h
@@ -19,14 +19,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmMathCommand; }
+  cmCommand* Clone() override { return new cmMathCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 protected:
   bool HandleExprCommand(std::vector<std::string> const& args);
diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h
index 59ee458..819ebda 100644
--- a/Source/cmMessageCommand.h
+++ b/Source/cmMessageCommand.h
@@ -22,14 +22,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmMessageCommand; }
+  cmCommand* Clone() override { return new cmMessageCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmNinjaLinkLineComputer.h b/Source/cmNinjaLinkLineComputer.h
index a75de05..0ed53f4 100644
--- a/Source/cmNinjaLinkLineComputer.h
+++ b/Source/cmNinjaLinkLineComputer.h
@@ -23,8 +23,7 @@
                           cmStateDirectory const& stateDir,
                           cmGlobalNinjaGenerator const* gg);
 
-  std::string ConvertToLinkReference(std::string const& input) const
-    CM_OVERRIDE;
+  std::string ConvertToLinkReference(std::string const& input) const override;
 
 private:
   cmGlobalNinjaGenerator const* GG;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 8b331d5..e0844e8 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -667,7 +667,7 @@
     std::string t = vars["ARCH_FLAGS"];
     localGen.AddArchitectureFlags(t, &genTarget, cudaLinkLanguage, cfgName);
     vars["ARCH_FLAGS"] = t;
-    t = "";
+    t.clear();
     localGen.AddLanguageFlagsForLinking(t, &genTarget, cudaLinkLanguage,
                                         cfgName);
     vars["LANGUAGE_COMPILE_FLAGS"] = t;
@@ -884,7 +884,7 @@
     std::string t = vars["ARCH_FLAGS"];
     localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
     vars["ARCH_FLAGS"] = t;
-    t = "";
+    t.clear();
     t += lwyuFlags;
     localGen.AddLanguageFlagsForLinking(t, &genTarget, TargetLinkLanguage,
                                         cfgName);
@@ -1070,7 +1070,7 @@
       if (targetOutputReal == soName || targetOutput == soName) {
         symlinkVars["SONAME"] = soName;
       } else {
-        symlinkVars["SONAME"] = "";
+        symlinkVars["SONAME"].clear();
         symlinks.push_back(soName);
       }
       symlinks.push_back(targetOutput);
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index d8baa67..01cc881 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -16,9 +16,9 @@
 {
 public:
   cmNinjaNormalTargetGenerator(cmGeneratorTarget* target);
-  ~cmNinjaNormalTargetGenerator() CM_OVERRIDE;
+  ~cmNinjaNormalTargetGenerator() override;
 
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 
 private:
   std::string LanguageLinkerRule() const;
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 3c1463a..a464d6e 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -425,7 +425,7 @@
     // The explicit preprocessing step will handle dependency scanning.
   } else if (this->NeedDepTypeMSVC(lang)) {
     deptype = "msvc";
-    depfile = "";
+    depfile.clear();
     flags += " /showIncludes";
   } else if (mf->IsOn("CMAKE_NINJA_CMCLDEPS_" + lang)) {
     // For the MS resource compiler we need cmcldeps, but skip dependencies
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index e15ba25..770a99d 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -31,7 +31,7 @@
   cmNinjaTargetGenerator(cmGeneratorTarget* target);
 
   /// Destructor.
-  ~cmNinjaTargetGenerator() CM_OVERRIDE;
+  ~cmNinjaTargetGenerator() override;
 
   virtual void Generate() = 0;
 
@@ -77,8 +77,7 @@
   std::string ComputeFlagsForObject(cmSourceFile const* source,
                                     const std::string& language);
 
-  void AddIncludeFlags(std::string& flags,
-                       std::string const& lang) CM_OVERRIDE;
+  void AddIncludeFlags(std::string& flags, std::string const& lang) override;
 
   std::string ComputeDefines(cmSourceFile const* source,
                              const std::string& language);
@@ -142,8 +141,7 @@
     {
     }
 
-    void operator()(cmSourceFile const& source,
-                    const char* pkgloc) CM_OVERRIDE;
+    void operator()(cmSourceFile const& source, const char* pkgloc) override;
 
   private:
     cmNinjaTargetGenerator* Generator;
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/cmNinjaUtilityTargetGenerator.h b/Source/cmNinjaUtilityTargetGenerator.h
index 361befe..01cc459 100644
--- a/Source/cmNinjaUtilityTargetGenerator.h
+++ b/Source/cmNinjaUtilityTargetGenerator.h
@@ -13,9 +13,9 @@
 {
 public:
   cmNinjaUtilityTargetGenerator(cmGeneratorTarget* target);
-  ~cmNinjaUtilityTargetGenerator() CM_OVERRIDE;
+  ~cmNinjaUtilityTargetGenerator() override;
 
-  void Generate() CM_OVERRIDE;
+  void Generate() override;
 };
 
 #endif // ! cmNinjaUtilityTargetGenerator_h
diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h
index d6e51a5..34e0e6f 100644
--- a/Source/cmOptionCommand.h
+++ b/Source/cmOptionCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmOptionCommand; }
+  cmCommand* Clone() override { return new cmOptionCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index 1ee0578..27ad710 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -149,7 +149,7 @@
     }
   }
 
-  void Report(std::ostream& e) CM_OVERRIDE
+  void Report(std::ostream& e) override
   {
     e << "runtime library [";
     if (this->SOName.empty()) {
@@ -160,7 +160,7 @@
     e << "]";
   }
 
-  bool FindConflict(std::string const& dir) CM_OVERRIDE;
+  bool FindConflict(std::string const& dir) override;
 
 private:
   // The soname of the shared library if it is known.
@@ -204,12 +204,12 @@
   {
   }
 
-  void Report(std::ostream& e) CM_OVERRIDE
+  void Report(std::ostream& e) override
   {
     e << "link library [" << this->FileName << "]";
   }
 
-  bool FindConflict(std::string const& dir) CM_OVERRIDE;
+  bool FindConflict(std::string const& dir) override;
 };
 
 bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir)
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index 26816cb..cde9037 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -362,7 +362,7 @@
       } else {
         // Destroy the name of the file so that it won't be output as a
         // dependency.
-        info->FullPath = "";
+        info->FullPath.clear();
       }
     }
   }
@@ -510,7 +510,7 @@
   // now recurse with info's dependencies
   for (cmDependInformation* d : info->DependencySet) {
     if (visited->find(d) == visited->end()) {
-      if (info->FullPath != "") {
+      if (!info->FullPath.empty()) {
         std::string tmp = d->FullPath;
         std::string::size_type pos = tmp.rfind('.');
         if (pos != std::string::npos && (tmp.substr(pos) != ".h")) {
diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h
index 6dcb888..09e622b 100644
--- a/Source/cmOutputRequiredFilesCommand.h
+++ b/Source/cmOutputRequiredFilesCommand.h
@@ -18,9 +18,9 @@
 class cmOutputRequiredFilesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmOutputRequiredFilesCommand; }
+  cmCommand* Clone() override { return new cmOutputRequiredFilesCommand; }
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   void ListDependencies(cmDependInformation const* info, FILE* fout,
                         std::set<cmDependInformation const*>* visited);
diff --git a/Source/cmParseArgumentsCommand.h b/Source/cmParseArgumentsCommand.h
index 469a76a..b8ba61d 100644
--- a/Source/cmParseArgumentsCommand.h
+++ b/Source/cmParseArgumentsCommand.h
@@ -21,14 +21,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmParseArgumentsCommand; }
+  cmCommand* Clone() override { return new cmParseArgumentsCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index a1f346a..e7d1b72 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -140,7 +140,7 @@
     *defaultSetting = cmPolicies::NEW;
   } else if (defaultValue == "OLD") {
     *defaultSetting = cmPolicies::OLD;
-  } else if (defaultValue == "") {
+  } else if (defaultValue.empty()) {
     *defaultSetting = cmPolicies::WARN;
   } else {
     std::ostringstream e;
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index 67b4a97..05b1b00 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -73,11 +73,11 @@
 
       // Hand this line to the subclass implementation.
       if (!this->ProcessLine()) {
-        this->Line = "";
+        this->Line.clear();
         return false;
       }
 
-      this->Line = "";
+      this->Line.clear();
     } else if (*c != '\r' || !this->IgnoreCR) {
       // Append this character to the line under construction.
       this->Line.append(1, *c);
diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h
index 5b357cd..23fa74e 100644
--- a/Source/cmProcessTools.h
+++ b/Source/cmProcessTools.h
@@ -59,7 +59,7 @@
     char Separator;
     char LineEnd;
     bool IgnoreCR;
-    bool ProcessChunk(const char* data, int length) CM_OVERRIDE;
+    bool ProcessChunk(const char* data, int length) override;
 
     /** Implement in a subclass to process one line of input.  It
         should return true only if it is interested in more data.  */
@@ -76,7 +76,7 @@
     }
 
   private:
-    bool ProcessLine() CM_OVERRIDE { return true; }
+    bool ProcessLine() override { return true; }
   };
 
   /** Run a process and send output to given parsers.  */
diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h
index afe489a..80fa235 100644
--- a/Source/cmProjectCommand.h
+++ b/Source/cmProjectCommand.h
@@ -26,14 +26,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmProjectCommand; }
+  cmCommand* Clone() override { return new cmProjectCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h
index 014a4ab..c1dcd54 100644
--- a/Source/cmQTWrapCPPCommand.h
+++ b/Source/cmQTWrapCPPCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmQTWrapCPPCommand; }
+  cmCommand* Clone() override { return new cmQTWrapCPPCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h
index f7e6bdd..15cab40 100644
--- a/Source/cmQTWrapUICommand.h
+++ b/Source/cmQTWrapUICommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmQTWrapUICommand; }
+  cmCommand* Clone() override { return new cmQTWrapUICommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index 95cd122..d9b1fd3 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmQtAutoGen.h"
 #include "cmAlgorithms.h"
+#include "cmProcessOutput.h"
 #include "cmSystemTools.h"
 
 #include "cmsys/FStream.hxx"
@@ -158,15 +159,18 @@
     std::string rccStdOut;
     std::string rccStdErr;
     int retVal = 0;
-    bool result =
-      cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
-                                      nullptr, cmSystemTools::OUTPUT_NONE);
+    bool result = cmSystemTools::RunSingleCommand(
+      command, &rccStdOut, &rccStdErr, &retVal, nullptr,
+      cmSystemTools::OUTPUT_NONE, 0.0, cmProcessOutput::Auto);
     if (result && retVal == 0 &&
         rccStdOut.find("--list") != std::string::npos) {
       hasDashDashList = true;
     }
   }
 
+  std::string const fileDir = cmSystemTools::GetFilenamePath(fileName);
+  std::string const fileNameName = cmSystemTools::GetFilenameName(fileName);
+
   // Run rcc list command
   bool result = false;
   int retVal = 0;
@@ -176,16 +180,16 @@
     std::vector<std::string> command;
     command.push_back(rccCommand);
     command.push_back(hasDashDashList ? "--list" : "-list");
-    command.push_back(fileName);
-    result =
-      cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
-                                      nullptr, cmSystemTools::OUTPUT_NONE);
+    command.push_back(fileNameName);
+    result = cmSystemTools::RunSingleCommand(
+      command, &rccStdOut, &rccStdErr, &retVal, fileDir.c_str(),
+      cmSystemTools::OUTPUT_NONE, 0.0, cmProcessOutput::Auto);
   }
   if (!result || retVal) {
     if (errorMessage != nullptr) {
       std::ostringstream ost;
-      ost << "rcc list process for " << cmQtAutoGen::Quoted(fileName)
-          << " failed:\n"
+      ost << "rcc list process failed for\n  " << cmQtAutoGen::Quoted(fileName)
+          << "\n"
           << rccStdOut << "\n"
           << rccStdErr << "\n";
       *errorMessage = ost.str();
@@ -230,6 +234,11 @@
     }
   }
 
+  // Convert relative paths to absolute paths
+  for (std::string& resFile : files) {
+    resFile = cmSystemTools::CollapseCombinedPath(fileDir, resFile);
+  }
+
   return true;
 }
 
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index 8c03045..e8a9006 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -8,6 +8,7 @@
 #include <algorithm>
 #include <array>
 #include <list>
+#include <memory>
 #include <sstream>
 #include <string.h>
 #include <utility>
@@ -35,14 +36,23 @@
 
 // -- Static functions
 
-static std::string QuotedCommand(const std::vector<std::string>& command)
+static std::string HeadLine(std::string const& title)
+{
+  std::string head = title;
+  head += '\n';
+  head.append(head.size() - 1, '-');
+  head += '\n';
+  return head;
+}
+
+static std::string QuotedCommand(std::vector<std::string> const& command)
 {
   std::string res;
   for (std::string const& item : command) {
     if (!res.empty()) {
       res.push_back(' ');
     }
-    const std::string cesc = cmQtAutoGen::Quoted(item);
+    std::string const cesc = cmQtAutoGen::Quoted(item);
     if (item.empty() || (cesc.size() > (item.size() + 2)) ||
         (cesc.find(' ') != std::string::npos)) {
       res += cesc;
@@ -53,7 +63,7 @@
   return res;
 }
 
-static std::string SubDirPrefix(const std::string& fileName)
+static std::string SubDirPrefix(std::string const& fileName)
 {
   std::string res(cmSystemTools::GetFilenamePath(fileName));
   if (!res.empty()) {
@@ -62,36 +72,58 @@
   return res;
 }
 
-static bool ReadAll(std::string& content, const std::string& filename)
+static bool ReadFile(std::string& content, std::string const& filename,
+                     std::string* error = nullptr)
 {
   bool success = false;
-  {
-    cmsys::ifstream ifs(filename.c_str());
+  if (cmSystemTools::FileExists(filename)) {
+    std::size_t const length = cmSystemTools::FileLength(filename);
+    cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary));
     if (ifs) {
-      std::ostringstream osst;
-      osst << ifs.rdbuf();
-      content = osst.str();
-      success = true;
+      content.resize(length);
+      ifs.read(&content.front(), content.size());
+      if (ifs) {
+        success = true;
+      } else {
+        content.clear();
+        if (error != nullptr) {
+          error->append("Reading from the file failed.");
+        }
+      }
+    } else if (error != nullptr) {
+      error->append("Opening the file for reading failed.");
     }
+  } else if (error != nullptr) {
+    error->append("The file does not exist.");
   }
   return success;
 }
 
 /**
- * @brief Tests if buildFile doesn't exist or is older than sourceFile
- * @return True if buildFile doesn't exist or is older than sourceFile
+ * @brief Tests if buildFile is older than sourceFile
+ * @return True if buildFile  is older than sourceFile.
+ *         False may indicate an error.
  */
-static bool FileAbsentOrOlder(const std::string& buildFile,
-                              const std::string& sourceFile)
+static bool FileIsOlderThan(std::string const& buildFile,
+                            std::string const& sourceFile,
+                            std::string* error = nullptr)
 {
   int result = 0;
-  bool success =
-    cmSystemTools::FileTimeCompare(buildFile, sourceFile, &result);
-  return (!success || (result <= 0));
+  if (cmSystemTools::FileTimeCompare(buildFile, sourceFile, &result)) {
+    return (result < 0);
+  }
+  if (error != nullptr) {
+    error->append(
+      "File modification time comparison failed for the files\n  ");
+    error->append(cmQtAutoGen::Quoted(buildFile));
+    error->append("\nand\n  ");
+    error->append(cmQtAutoGen::Quoted(sourceFile));
+  }
+  return false;
 }
 
-static bool ListContains(const std::vector<std::string>& list,
-                         const std::string& entry)
+static bool ListContains(std::vector<std::string> const& list,
+                         std::string const& entry)
 {
   return (std::find(list.begin(), list.end(), entry) != list.end());
 }
@@ -99,24 +131,20 @@
 // -- Class methods
 
 cmQtAutoGenerators::cmQtAutoGenerators()
-  : Verbose(cmSystemTools::HasEnv("VERBOSE"))
+  : IncludeProjectDirsBefore(false)
+  , Verbose(cmSystemTools::HasEnv("VERBOSE"))
   , ColorOutput(true)
   , MocSettingsChanged(false)
   , MocPredefsChanged(false)
-  , MocRunFailed(false)
+  , MocRelaxedMode(false)
   , UicSettingsChanged(false)
-  , UicRunFailed(false)
   , RccSettingsChanged(false)
-  , RccRunFailed(false)
 {
-
-  std::string colorEnv;
-  cmSystemTools::GetEnv("COLOR", colorEnv);
-  if (!colorEnv.empty()) {
-    if (cmSystemTools::IsOn(colorEnv.c_str())) {
-      this->ColorOutput = true;
-    } else {
-      this->ColorOutput = false;
+  {
+    std::string colorEnv;
+    cmSystemTools::GetEnv("COLOR", colorEnv);
+    if (!colorEnv.empty()) {
+      this->ColorOutput = cmSystemTools::IsOn(colorEnv.c_str());
     }
   }
 
@@ -134,8 +162,8 @@
                                  "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
 }
 
-bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
-                             const std::string& config)
+bool cmQtAutoGenerators::Run(std::string const& targetDirectory,
+                             std::string const& config)
 {
   cmake cm(cmake::RoleScript);
   cm.SetHomeOutputDirectory(targetDirectory);
@@ -147,16 +175,14 @@
   snapshot.GetDirectory().SetCurrentBinary(targetDirectory);
   snapshot.GetDirectory().SetCurrentSource(targetDirectory);
 
-  std::unique_ptr<cmMakefile> makefile(new cmMakefile(&gg, snapshot));
+  auto makefile = cm::make_unique<cmMakefile>(&gg, snapshot);
   gg.SetCurrentMakefile(makefile.get());
 
   bool success = false;
-  if (this->ReadAutogenInfoFile(makefile.get(), targetDirectory, config)) {
-    // Read old settings
+  if (this->InitInfoFile(makefile.get(), targetDirectory, config)) {
+    // Read latest settings
     this->SettingsFileRead(makefile.get());
-    // Init and run
-    this->Init(makefile.get());
-    if (this->RunAutogen()) {
+    if (this->Process()) {
       // Write current settings
       if (this->SettingsFileWrite()) {
         success = true;
@@ -166,46 +192,11 @@
   return success;
 }
 
-bool cmQtAutoGenerators::MocDependFilterPush(const std::string& key,
-                                             const std::string& regExp)
+bool cmQtAutoGenerators::InitInfoFile(cmMakefile* makefile,
+                                      std::string const& targetDirectory,
+                                      std::string const& config)
 {
-  std::string error;
-  if (!key.empty()) {
-    if (!regExp.empty()) {
-      KeyRegExp filter;
-      filter.Key = key;
-      if (filter.RegExp.compile(regExp)) {
-        this->MocDependFilters.push_back(std::move(filter));
-      } else {
-        error = "Regular expression compiling failed";
-      }
-    } else {
-      error = "Regular expression is empty";
-    }
-  } else {
-    error = "Key is empty";
-  }
-  if (!error.empty()) {
-    std::string emsg = "AUTOMOC_DEPEND_FILTERS: ";
-    emsg += error;
-    emsg += "\n";
-    emsg += "  Key:    ";
-    emsg += cmQtAutoGen::Quoted(key);
-    emsg += "\n";
-    emsg += "  RegExp: ";
-    emsg += cmQtAutoGen::Quoted(regExp);
-    emsg += "\n";
-    this->LogError(cmQtAutoGen::MOC, emsg);
-    return false;
-  }
-  return true;
-}
-
-bool cmQtAutoGenerators::ReadAutogenInfoFile(
-  cmMakefile* makefile, const std::string& targetDirectory,
-  const std::string& config)
-{
-  // Lambdas
+  // Utility lambdas
   auto InfoGet = [makefile](const char* key) {
     return makefile->GetSafeDefinition(key);
   };
@@ -221,7 +212,7 @@
     [makefile](const char* key) -> std::vector<std::vector<std::string>> {
     std::vector<std::vector<std::string>> lists;
     {
-      const std::string value = makefile->GetSafeDefinition(key);
+      std::string const value = makefile->GetSafeDefinition(key);
       std::string::size_type pos = 0;
       while (pos < value.size()) {
         std::string::size_type next = value.find(cmQtAutoGen::listSep, pos);
@@ -266,16 +257,18 @@
     return list;
   };
 
-  std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
-  cmSystemTools::ConvertToUnixSlashes(filename);
-  filename += "/AutogenInfo.cmake";
+  this->InfoFile = cmSystemTools::CollapseFullPath(targetDirectory);
+  cmSystemTools::ConvertToUnixSlashes(this->InfoFile);
+  this->InfoFile += "/AutogenInfo.cmake";
 
-  if (!makefile->ReadListFile(filename.c_str())) {
-    this->LogFileError(cmQtAutoGen::GEN, filename, "File processing failed");
+  if (!makefile->ReadListFile(this->InfoFile.c_str())) {
+    this->LogFileError(cmQtAutoGen::GEN, this->InfoFile,
+                       "File processing failed");
     return false;
   }
 
   // -- Meta
+  this->HeaderExtensions = makefile->GetCMakeInstance()->GetHeaderExtensions();
   this->ConfigSuffix = InfoGetConfig("AM_CONFIG_SUFFIX");
 
   // - Old settings file
@@ -296,12 +289,10 @@
     InfoGetBool("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
   this->AutogenBuildDir = InfoGet("AM_BUILD_DIR");
   if (this->AutogenBuildDir.empty()) {
-    this->LogFileError(cmQtAutoGen::GEN, filename,
+    this->LogFileError(cmQtAutoGen::GEN, this->InfoFile,
                        "Autogen build directory missing");
     return false;
   }
-  this->Sources = InfoGetList("AM_SOURCES");
-  this->Headers = InfoGetList("AM_HEADERS");
 
   // - Qt environment
   this->QtMajorVersion = InfoGet("AM_QT_VERSION_MAJOR");
@@ -312,7 +303,8 @@
 
   // Check Qt version
   if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) {
-    this->LogFileError(cmQtAutoGen::GEN, filename, "Unsupported Qt version: " +
+    this->LogFileError(cmQtAutoGen::GEN, this->InfoFile,
+                       "Unsupported Qt version: " +
                          cmQtAutoGen::Quoted(this->QtMajorVersion));
     return false;
   }
@@ -323,7 +315,7 @@
     this->MocDefinitions = InfoGetConfigList("AM_MOC_DEFINITIONS");
 #ifdef _WIN32
     {
-      const std::string win32("WIN32");
+      std::string const win32("WIN32");
       if (!ListContains(this->MocDefinitions, win32)) {
         this->MocDefinitions.push_back(win32);
       }
@@ -333,7 +325,7 @@
     this->MocOptions = InfoGetList("AM_MOC_OPTIONS");
     this->MocRelaxedMode = InfoGetBool("AM_MOC_RELAXED_MODE");
     {
-      const std::vector<std::string> MocMacroNames =
+      std::vector<std::string> const MocMacroNames =
         InfoGetList("AM_MOC_MACRO_NAMES");
       for (std::string const& item : MocMacroNames) {
         this->MocMacroFilters.emplace_back(
@@ -341,7 +333,7 @@
       }
     }
     {
-      const std::vector<std::string> mocDependFilters =
+      std::vector<std::string> const mocDependFilters =
         InfoGetList("AM_MOC_DEPEND_FILTERS");
       // Insert Q_PLUGIN_METADATA dependency filter
       if (this->QtMajorVersion != "4") {
@@ -361,7 +353,7 @@
         }
       } else {
         this->LogFileError(
-          cmQtAutoGen::MOC, filename,
+          cmQtAutoGen::MOC, this->InfoFile,
           "AUTOMOC_DEPEND_FILTERS list size is not a multiple of 2");
         return false;
       }
@@ -378,22 +370,21 @@
       auto sources = InfoGetList("AM_UIC_OPTIONS_FILES");
       auto options = InfoGetLists("AM_UIC_OPTIONS_OPTIONS");
       // Compare list sizes
-      if (sources.size() == options.size()) {
-        auto fitEnd = sources.cend();
-        auto fit = sources.begin();
-        auto oit = options.begin();
-        while (fit != fitEnd) {
-          this->UicOptions[*fit] = std::move(*oit);
-          ++fit;
-          ++oit;
-        }
-      } else {
+      if (sources.size() != options.size()) {
         std::ostringstream ost;
         ost << "files/options lists sizes missmatch (" << sources.size() << "/"
             << options.size() << ")";
-        this->LogFileError(cmQtAutoGen::UIC, filename, ost.str());
+        this->LogFileError(cmQtAutoGen::UIC, this->InfoFile, ost.str());
         return false;
       }
+      auto fitEnd = sources.cend();
+      auto fit = sources.begin();
+      auto oit = options.begin();
+      while (fit != fitEnd) {
+        this->UicOptions[*fit] = std::move(*oit);
+        ++fit;
+        ++oit;
+      }
     }
   }
 
@@ -409,24 +400,23 @@
       std::ostringstream ost;
       ost << "sources, builds lists sizes missmatch (" << sources.size() << "/"
           << builds.size() << ")";
-      this->LogFileError(cmQtAutoGen::RCC, filename, ost.str());
+      this->LogFileError(cmQtAutoGen::RCC, this->InfoFile, ost.str());
       return false;
     }
     if (sources.size() != options.size()) {
       std::ostringstream ost;
       ost << "sources, options lists sizes missmatch (" << sources.size()
           << "/" << options.size() << ")";
-      this->LogFileError(cmQtAutoGen::RCC, filename, ost.str());
+      this->LogFileError(cmQtAutoGen::RCC, this->InfoFile, ost.str());
       return false;
     }
     if (sources.size() != inputs.size()) {
       std::ostringstream ost;
       ost << "sources, inputs lists sizes missmatch (" << sources.size() << "/"
           << inputs.size() << ")";
-      this->LogFileError(cmQtAutoGen::RCC, filename, ost.str());
+      this->LogFileError(cmQtAutoGen::RCC, this->InfoFile, ost.str());
       return false;
     }
-
     {
       auto srcItEnd = sources.end();
       auto srcIt = sources.begin();
@@ -445,6 +435,156 @@
     }
   }
 
+  // Initialize source file jobs
+  {
+    // Utility lambdas
+    auto AddJob = [this](std::map<std::string, SourceJob>& jobs,
+                         std::string&& sourceFile) {
+      const bool moc = !this->MocSkip(sourceFile);
+      const bool uic = !this->UicSkip(sourceFile);
+      if (moc || uic) {
+        SourceJob& job = jobs[std::move(sourceFile)];
+        job.Moc = moc;
+        job.Uic = uic;
+      }
+    };
+
+    // Add header jobs
+    for (std::string& hdr : InfoGetList("AM_HEADERS")) {
+      AddJob(this->HeaderJobs, std::move(hdr));
+    }
+    // Add source jobs
+    {
+      std::vector<std::string> sources = InfoGetList("AM_SOURCES");
+      // Add header(s) for the source file
+      for (std::string const& src : sources) {
+        const bool srcMoc = !this->MocSkip(src);
+        const bool srcUic = !this->UicSkip(src);
+        if (!srcMoc && !srcUic) {
+          continue;
+        }
+        // Search for the default header file and a private header
+        std::array<std::string, 2> headerBases;
+        headerBases[0] = SubDirPrefix(src);
+        headerBases[0] += cmSystemTools::GetFilenameWithoutLastExtension(src);
+        headerBases[1] = headerBases[0];
+        headerBases[1] += "_p";
+        for (std::string const& headerBase : headerBases) {
+          std::string header;
+          if (this->FindHeader(header, headerBase)) {
+            const bool moc = srcMoc && !this->MocSkip(header);
+            const bool uic = srcUic && !this->UicSkip(header);
+            if (moc || uic) {
+              SourceJob& job = this->HeaderJobs[std::move(header)];
+              job.Moc = moc;
+              job.Uic = uic;
+            }
+          }
+        }
+      }
+      // Add Source jobs
+      for (std::string& src : sources) {
+        AddJob(this->SourceJobs, std::move(src));
+      }
+    }
+  }
+
+  // Init derived information
+  // ------------------------
+
+  // Init file path checksum generator
+  this->FilePathChecksum.setupParentDirs(
+    this->CurrentSourceDir, this->CurrentBinaryDir, this->ProjectSourceDir,
+    this->ProjectBinaryDir);
+
+  // include directory
+  this->AutogenIncludeDir = "include";
+  this->AutogenIncludeDir += this->ConfigSuffix;
+  this->AutogenIncludeDir += "/";
+
+  if (this->MocEnabled()) {
+    // Mocs compilation file
+    this->MocCompFileRel = "mocs_compilation.cpp";
+    this->MocCompFileAbs = cmSystemTools::CollapseCombinedPath(
+      this->AutogenBuildDir, this->MocCompFileRel);
+
+    // Moc predefs file
+    if (!this->MocPredefsCmd.empty()) {
+      this->MocPredefsFileRel = "moc_predefs";
+      this->MocPredefsFileRel += this->ConfigSuffix;
+      this->MocPredefsFileRel += ".h";
+      this->MocPredefsFileAbs = cmSystemTools::CollapseCombinedPath(
+        this->AutogenBuildDir, this->MocPredefsFileRel);
+    }
+
+    // Sort include directories on demand
+    if (this->IncludeProjectDirsBefore) {
+      // Move strings to temporary list
+      std::list<std::string> includes;
+      includes.insert(includes.end(), this->MocIncludePaths.begin(),
+                      this->MocIncludePaths.end());
+      this->MocIncludePaths.clear();
+      this->MocIncludePaths.reserve(includes.size());
+      // Append project directories only
+      {
+        std::array<std::string const*, 2> const movePaths = {
+          { &this->ProjectBinaryDir, &this->ProjectSourceDir }
+        };
+        for (std::string const* ppath : movePaths) {
+          std::list<std::string>::iterator it = includes.begin();
+          while (it != includes.end()) {
+            std::string const& path = *it;
+            if (cmSystemTools::StringStartsWith(path, ppath->c_str())) {
+              this->MocIncludePaths.push_back(path);
+              it = includes.erase(it);
+            } else {
+              ++it;
+            }
+          }
+        }
+      }
+      // Append remaining directories
+      this->MocIncludePaths.insert(this->MocIncludePaths.end(),
+                                   includes.begin(), includes.end());
+    }
+    // Compose moc includes list
+    {
+      std::set<std::string> frameworkPaths;
+      for (std::string const& path : this->MocIncludePaths) {
+        this->MocIncludes.push_back("-I" + path);
+        // Extract framework path
+        if (cmHasLiteralSuffix(path, ".framework/Headers")) {
+          // Go up twice to get to the framework root
+          std::vector<std::string> pathComponents;
+          cmSystemTools::SplitPath(path, pathComponents);
+          std::string frameworkPath = cmSystemTools::JoinPath(
+            pathComponents.begin(), pathComponents.end() - 2);
+          frameworkPaths.insert(frameworkPath);
+        }
+      }
+      // Append framework includes
+      for (std::string const& path : frameworkPaths) {
+        this->MocIncludes.push_back("-F");
+        this->MocIncludes.push_back(path);
+      }
+    }
+    // Setup single list with all options
+    {
+      // Add includes
+      this->MocAllOptions.insert(this->MocAllOptions.end(),
+                                 this->MocIncludes.begin(),
+                                 this->MocIncludes.end());
+      // Add definitions
+      for (std::string const& def : this->MocDefinitions) {
+        this->MocAllOptions.push_back("-D" + def);
+      }
+      // Add options
+      this->MocAllOptions.insert(this->MocAllOptions.end(),
+                                 this->MocOptions.begin(),
+                                 this->MocOptions.end());
+    }
+  }
+
   return true;
 }
 
@@ -453,16 +593,12 @@
   // Compose current settings strings
   {
     cmCryptoHash crypt(cmCryptoHash::AlgoSHA256);
-    const std::string sep(" ~~~ ");
+    std::string const sep(" ~~~ ");
     if (this->MocEnabled()) {
       std::string str;
       str += this->MocExecutable;
       str += sep;
-      str += cmJoin(this->MocDefinitions, ";");
-      str += sep;
-      str += cmJoin(this->MocIncludePaths, ";");
-      str += sep;
-      str += cmJoin(this->MocOptions, ";");
+      str += cmJoin(this->MocAllOptions, ";");
       str += sep;
       str += this->IncludeProjectDirsBefore ? "TRUE" : "FALSE";
       str += sep;
@@ -503,7 +639,7 @@
   // Read old settings
   if (makefile->ReadListFile(this->SettingsFile.c_str())) {
     {
-      auto SMatch = [makefile](const char* key, const std::string& value) {
+      auto SMatch = [makefile](const char* key, std::string const& value) {
         return (value == makefile->GetSafeDefinition(key));
       };
       if (!SMatch(SettingsKeyMoc, this->SettingsStringMoc)) {
@@ -519,7 +655,7 @@
     // In case any setting changed remove the old settings file.
     // This triggers a full rebuild on the next run if the current
     // build is aborted before writing the current settings in the end.
-    if (this->AnySettingsChanged()) {
+    if (this->SettingsChanged()) {
       cmSystemTools::RemoveFile(this->SettingsFile);
     }
   } else {
@@ -534,7 +670,7 @@
 {
   bool success = true;
   // Only write if any setting changed
-  if (this->AnySettingsChanged()) {
+  if (this->SettingsChanged()) {
     if (this->Verbose) {
       this->LogInfo(cmQtAutoGen::GEN, "Writing settings file " +
                       cmQtAutoGen::Quoted(this->SettingsFile));
@@ -543,7 +679,7 @@
     std::string settings;
     {
       auto SettingAppend = [&settings](const char* key,
-                                       const std::string& value) {
+                                       std::string const& value) {
         settings += "set(";
         settings += key;
         settings += " ";
@@ -557,7 +693,7 @@
     // Write settings file
     if (!this->FileWrite(cmQtAutoGen::GEN, this->SettingsFile, settings)) {
       this->LogFileError(cmQtAutoGen::GEN, this->SettingsFile,
-                         "File writing failed");
+                         "Settings file writing failed");
       // Remove old settings file to trigger a full rebuild on the next run
       cmSystemTools::RemoveFile(this->SettingsFile);
       success = false;
@@ -566,89 +702,7 @@
   return success;
 }
 
-void cmQtAutoGenerators::Init(cmMakefile* makefile)
-{
-  // Mocs compilation file
-  this->MocCompFileRel = "mocs_compilation.cpp";
-  this->MocCompFileAbs = cmSystemTools::CollapseCombinedPath(
-    this->AutogenBuildDir, this->MocCompFileRel);
-
-  // Mocs include directory
-  this->AutogenIncludeDir = "include";
-  this->AutogenIncludeDir += this->ConfigSuffix;
-  this->AutogenIncludeDir += "/";
-
-  // Moc predefs file
-  if (!this->MocPredefsCmd.empty()) {
-    this->MocPredefsFileRel = "moc_predefs";
-    this->MocPredefsFileRel += this->ConfigSuffix;
-    this->MocPredefsFileRel += ".h";
-    this->MocPredefsFileAbs = cmSystemTools::CollapseCombinedPath(
-      this->AutogenBuildDir, this->MocPredefsFileRel);
-  }
-
-  // Init file path checksum generator
-  FPathChecksum.setupParentDirs(this->CurrentSourceDir, this->CurrentBinaryDir,
-                                this->ProjectSourceDir,
-                                this->ProjectBinaryDir);
-
-  // Acquire header extensions
-  this->HeaderExtensions = makefile->GetCMakeInstance()->GetHeaderExtensions();
-
-  // Sort include directories on demand
-  if (this->IncludeProjectDirsBefore) {
-    // Move strings to temporary list
-    std::list<std::string> includes;
-    includes.insert(includes.end(), this->MocIncludePaths.begin(),
-                    this->MocIncludePaths.end());
-    this->MocIncludePaths.clear();
-    this->MocIncludePaths.reserve(includes.size());
-    // Append project directories only
-    {
-      const std::array<const std::string*, 2> movePaths = {
-        { &this->ProjectBinaryDir, &this->ProjectSourceDir }
-      };
-      for (const std::string* ppath : movePaths) {
-        std::list<std::string>::iterator it = includes.begin();
-        while (it != includes.end()) {
-          const std::string& path = *it;
-          if (cmSystemTools::StringStartsWith(path, ppath->c_str())) {
-            this->MocIncludePaths.push_back(path);
-            it = includes.erase(it);
-          } else {
-            ++it;
-          }
-        }
-      }
-    }
-    // Append remaining directories
-    this->MocIncludePaths.insert(this->MocIncludePaths.end(), includes.begin(),
-                                 includes.end());
-  }
-  // Compose moc includes list
-  {
-    std::set<std::string> frameworkPaths;
-    for (std::string const& path : this->MocIncludePaths) {
-      this->MocIncludes.push_back("-I" + path);
-      // Extract framework path
-      if (cmHasLiteralSuffix(path, ".framework/Headers")) {
-        // Go up twice to get to the framework root
-        std::vector<std::string> pathComponents;
-        cmSystemTools::SplitPath(path, pathComponents);
-        std::string frameworkPath = cmSystemTools::JoinPath(
-          pathComponents.begin(), pathComponents.end() - 2);
-        frameworkPaths.insert(frameworkPath);
-      }
-    }
-    // Append framework includes
-    for (std::string const& path : frameworkPaths) {
-      this->MocIncludes.push_back("-F");
-      this->MocIncludes.push_back(path);
-    }
-  }
-}
-
-bool cmQtAutoGenerators::RunAutogen()
+bool cmQtAutoGenerators::Process()
 {
   // the program goes through all .cpp files to see which moc files are
   // included. It is not really interesting how the moc file is named, but
@@ -660,7 +714,7 @@
 
   // Create AUTOGEN include directory
   {
-    const std::string incDirAbs = cmSystemTools::CollapseCombinedPath(
+    std::string const incDirAbs = cmSystemTools::CollapseCombinedPath(
       this->AutogenBuildDir, this->AutogenIncludeDir);
     if (!cmSystemTools::MakeDirectory(incDirAbs)) {
       this->LogFileError(cmQtAutoGen::GEN, incDirAbs,
@@ -669,45 +723,28 @@
     }
   }
 
-  // key = moc source filepath, value = moc output filepath
-  std::map<std::string, std::string> mocsIncluded;
-  std::map<std::string, std::string> mocsNotIncluded;
-  std::map<std::string, std::set<std::string>> mocDepends;
-  std::map<std::string, std::vector<std::string>> uisIncluded;
-  // collects all headers which may need to be mocced
-  std::set<std::string> mocHeaderFiles;
-  std::set<std::string> uicHeaderFiles;
-
-  // Parse sources
-  for (std::string const& src : this->Sources) {
-    // Parse source file for MOC/UIC
-    if (!this->ParseSourceFile(src, mocsIncluded, mocDepends, uisIncluded,
-                               this->MocRelaxedMode)) {
+  // Parse source files
+  for (const auto& item : this->SourceJobs) {
+    if (!this->ParseSourceFile(item.first, item.second)) {
       return false;
     }
-    // Find additional headers
-    this->SearchHeadersForSourceFile(src, mocHeaderFiles, uicHeaderFiles);
   }
-
-  // Parse headers
-  for (std::string const& hdr : this->Headers) {
-    if (!this->MocSkip(hdr)) {
-      mocHeaderFiles.insert(hdr);
-    }
-    if (!this->UicSkip(hdr)) {
-      uicHeaderFiles.insert(hdr);
+  // Parse header files
+  for (const auto& item : this->HeaderJobs) {
+    if (!this->ParseHeaderFile(item.first, item.second)) {
+      return false;
     }
   }
-  if (!this->ParseHeaders(mocHeaderFiles, uicHeaderFiles, mocsIncluded,
-                          mocsNotIncluded, mocDepends, uisIncluded)) {
+  // Read missing dependency information
+  if (!this->ParsePostprocess()) {
     return false;
-  };
+  }
 
   // Generate files
-  if (!this->MocGenerateAll(mocsIncluded, mocsNotIncluded, mocDepends)) {
+  if (!this->MocGenerateAll()) {
     return false;
   }
-  if (!this->UicGenerateAll(uisIncluded)) {
+  if (!this->UicGenerateAll()) {
     return false;
   }
   if (!this->RccGenerateAll()) {
@@ -718,10 +755,111 @@
 }
 
 /**
+ * @return True on success
+ */
+bool cmQtAutoGenerators::ParseSourceFile(std::string const& absFilename,
+                                         const SourceJob& job)
+{
+  std::string contentText;
+  std::string error;
+  bool success = ReadFile(contentText, absFilename, &error);
+  if (success) {
+    if (!contentText.empty()) {
+      if (job.Moc) {
+        success = this->MocParseSourceContent(absFilename, contentText);
+      }
+      if (success && job.Uic) {
+        success = this->UicParseContent(absFilename, contentText);
+      }
+    } else {
+      this->LogFileWarning(cmQtAutoGen::GEN, absFilename,
+                           "The source file is empty");
+    }
+  } else {
+    this->LogFileError(cmQtAutoGen::GEN, absFilename,
+                       "Could not read the source file: " + error);
+  }
+  return success;
+}
+
+/**
+ * @return True on success
+ */
+bool cmQtAutoGenerators::ParseHeaderFile(std::string const& absFilename,
+                                         const SourceJob& job)
+{
+  std::string contentText;
+  std::string error;
+  bool success = ReadFile(contentText, absFilename, &error);
+  if (success) {
+    if (!contentText.empty()) {
+      if (job.Moc) {
+        this->MocParseHeaderContent(absFilename, contentText);
+      }
+      if (job.Uic) {
+        success = this->UicParseContent(absFilename, contentText);
+      }
+    } else {
+      this->LogFileWarning(cmQtAutoGen::GEN, absFilename,
+                           "The header file is empty");
+    }
+  } else {
+    this->LogFileError(cmQtAutoGen::GEN, absFilename,
+                       "Could not read the header file: " + error);
+  }
+  return success;
+}
+
+/**
+ * @return True on success
+ */
+bool cmQtAutoGenerators::ParsePostprocess()
+{
+  bool success = true;
+  // Read missin dependecies
+  for (auto& item : this->MocJobsIncluded) {
+    if (!item->DependsValid) {
+      std::string content;
+      std::string error;
+      if (ReadFile(content, item->SourceFile, &error)) {
+        this->MocFindDepends(item->SourceFile, content, item->Depends);
+        item->DependsValid = true;
+      } else {
+        std::string emsg = "Could not read file\n  ";
+        emsg += item->SourceFile;
+        emsg += "\nrequired by moc include \"";
+        emsg += item->IncludeString;
+        emsg += "\".\n";
+        emsg += error;
+        this->LogFileError(cmQtAutoGen::MOC, item->Includer, emsg);
+        success = false;
+        break;
+      }
+    }
+  }
+  return success;
+}
+
+/**
+ * @brief Tests if the file should be ignored for moc scanning
+ * @return True if the file should be ignored
+ */
+bool cmQtAutoGenerators::MocSkip(std::string const& absFilename) const
+{
+  if (this->MocEnabled()) {
+    // Test if the file name is on the skip list
+    if (!ListContains(this->MocSkipList, absFilename)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+/**
  * @brief Tests if the C++ content requires moc processing
  * @return True if moc is required
  */
-bool cmQtAutoGenerators::MocRequired(const std::string& contentText,
+bool cmQtAutoGenerators::MocRequired(std::string const& contentText,
                                      std::string* macroName)
 {
   for (KeyRegExp& filter : this->MocMacroFilters) {
@@ -740,120 +878,7 @@
   return false;
 }
 
-void cmQtAutoGenerators::MocFindDepends(
-  const std::string& absFilename, const std::string& contentText,
-  std::map<std::string, std::set<std::string>>& mocDepends)
-{
-  for (KeyRegExp& filter : this->MocDependFilters) {
-    // Run a simple find string operation before the expensive
-    // regular expression check
-    if (contentText.find(filter.Key) != std::string::npos) {
-      // Run regular expression check loop
-      const std::string sourcePath = SubDirPrefix(absFilename);
-      const char* contentChars = contentText.c_str();
-      while (filter.RegExp.find(contentChars)) {
-        // Evaluate match
-        const std::string match = filter.RegExp.match(1);
-        if (!match.empty()) {
-          // Find the dependency file
-          std::string incFile;
-          if (this->MocFindIncludedFile(incFile, sourcePath, match)) {
-            mocDepends[absFilename].insert(incFile);
-            if (this->Verbose) {
-              this->LogInfo(cmQtAutoGen::MOC, "Found dependency:\n  " +
-                              cmQtAutoGen::Quoted(absFilename) + "\n  " +
-                              cmQtAutoGen::Quoted(incFile));
-            }
-          } else {
-            this->LogFileWarning(cmQtAutoGen::MOC, absFilename,
-                                 "Could not find dependency file " +
-                                   cmQtAutoGen::Quoted(match));
-          }
-        }
-        contentChars += filter.RegExp.end();
-      }
-    }
-  }
-}
-
-/**
- * @brief Tests if the file should be ignored for moc scanning
- * @return True if the file should be ignored
- */
-bool cmQtAutoGenerators::MocSkip(const std::string& absFilename) const
-{
-  if (this->MocEnabled()) {
-    // Test if the file name is on the skip list
-    if (!ListContains(this->MocSkipList, absFilename)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-/**
- * @brief Tests if the file name is in the skip list
- */
-bool cmQtAutoGenerators::UicSkip(const std::string& absFilename) const
-{
-  if (this->UicEnabled()) {
-    // Test if the file name is on the skip list
-    if (!ListContains(this->UicSkipList, absFilename)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-/**
- * @return True on success
- */
-bool cmQtAutoGenerators::ParseSourceFile(
-  const std::string& absFilename,
-  std::map<std::string, std::string>& mocsIncluded,
-  std::map<std::string, std::set<std::string>>& mocDepends,
-  std::map<std::string, std::vector<std::string>>& uisIncluded, bool relaxed)
-{
-  std::string contentText;
-  bool success = ReadAll(contentText, absFilename);
-  if (success) {
-    if (!contentText.empty()) {
-      // Parse source contents for MOC
-      if (success && !this->MocSkip(absFilename)) {
-        success = this->MocParseSourceContent(
-          absFilename, contentText, mocsIncluded, mocDepends, relaxed);
-      }
-      // Parse source contents for UIC
-      if (success && !this->UicSkip(absFilename)) {
-        this->UicParseContent(absFilename, contentText, uisIncluded);
-      }
-    } else {
-      this->LogFileWarning(cmQtAutoGen::GEN, absFilename, "The file is empty");
-    }
-  } else {
-    this->LogFileError(cmQtAutoGen::GEN, absFilename, "Could not read file");
-  }
-  return success;
-}
-
-void cmQtAutoGenerators::UicParseContent(
-  const std::string& absFilename, const std::string& contentText,
-  std::map<std::string, std::vector<std::string>>& uisIncluded)
-{
-  if (this->Verbose) {
-    this->LogInfo(cmQtAutoGen::UIC, "Checking " + absFilename);
-  }
-
-  const char* contentChars = contentText.c_str();
-  if (strstr(contentChars, "ui_") != nullptr) {
-    while (this->UicRegExpInclude.find(contentChars)) {
-      uisIncluded[absFilename].push_back(this->UicRegExpInclude.match(1));
-      contentChars += this->UicRegExpInclude.end();
-    }
-  }
-}
-
-std::string cmQtAutoGenerators::MocMacroNamesString() const
+std::string cmQtAutoGenerators::MocStringMacros() const
 {
   std::string res;
   const auto itB = this->MocMacroFilters.cbegin();
@@ -875,339 +900,479 @@
   return res;
 }
 
-std::string cmQtAutoGenerators::MocHeaderSuffixesString() const
+std::string cmQtAutoGenerators::MocStringHeaders(
+  std::string const& fileBase) const
 {
-  std::string res = ".{";
+  std::string res = fileBase;
+  res += ".{";
   res += cmJoin(this->HeaderExtensions, ",");
   res += "}";
   return res;
 }
 
-/**
- * @return True on success
- */
-bool cmQtAutoGenerators::MocParseSourceContent(
-  const std::string& absFilename, const std::string& contentText,
-  std::map<std::string, std::string>& mocsIncluded,
-  std::map<std::string, std::set<std::string>>& mocDepends, bool relaxed)
+std::string cmQtAutoGenerators::MocFindIncludedHeader(
+  std::string const& sourcePath, std::string const& includeBase) const
 {
-  if (this->Verbose) {
-    this->LogInfo(cmQtAutoGen::MOC, "Checking " + absFilename);
-  }
-
-  const std::string scanFileDir = SubDirPrefix(absFilename);
-  const std::string scanFileBase =
-    cmSystemTools::GetFilenameWithoutLastExtension(absFilename);
-
-  std::string selfMacroName;
-  const bool selfRequiresMoc = this->MocRequired(contentText, &selfMacroName);
-  bool ownDotMocIncluded = false;
-  std::string ownMocUnderscoreInclude;
-  std::string ownMocUnderscoreHeader;
-
-  // first a simple string check for "moc" is *much* faster than the regexp,
-  // and if the string search already fails, we don't have to try the
-  // expensive regexp
-  const char* contentChars = contentText.c_str();
-  if (strstr(contentChars, "moc") != nullptr) {
-    // Iterate over all included moc files
-    while (this->MocRegExpInclude.find(contentChars)) {
-      const std::string incString = this->MocRegExpInclude.match(1);
-      // Basename of the moc include
-      const std::string incDir(SubDirPrefix(incString));
-      const std::string incBase =
-        cmSystemTools::GetFilenameWithoutLastExtension(incString);
-
-      // If the moc include is of the moc_foo.cpp style we expect
-      // the Q_OBJECT class declaration in a header file.
-      // If the moc include is of the foo.moc style we need to look for
-      // a Q_OBJECT macro in the current source file, if it contains the
-      // macro we generate the moc file from the source file.
-      if (cmHasLiteralPrefix(incBase, "moc_")) {
-        // Include: moc_FOO.cxx
-        // Remove the moc_ part
-        const std::string incRealBase = incBase.substr(4);
-        const std::string headerToMoc =
-          this->MocFindHeader(scanFileDir, incDir + incRealBase);
-        if (!headerToMoc.empty()) {
-          if (!this->MocSkip(headerToMoc)) {
-            // Register moc job
-            mocsIncluded[headerToMoc] = incString;
-            this->MocFindDepends(headerToMoc, contentText, mocDepends);
-            // Store meta information for relaxed mode
-            if (relaxed && (incRealBase == scanFileBase)) {
-              ownMocUnderscoreInclude = incString;
-              ownMocUnderscoreHeader = headerToMoc;
-            }
-          }
-        } else {
-          std::ostringstream ost;
-          ost << "The file includes the moc file "
-              << cmQtAutoGen::Quoted(incString)
-              << ", but could not find header ";
-          ost << cmQtAutoGen::Quoted(incRealBase +
-                                     this->MocHeaderSuffixesString());
-          this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str());
-          return false;
-        }
-      } else {
-        // Include: FOO.moc
-        bool ownDotMoc = (incBase == scanFileBase);
-        std::string fileToMoc;
-        if (relaxed) {
-          // Mode: Relaxed
-          if (selfRequiresMoc && ownDotMoc) {
-            // Include self
-            fileToMoc = absFilename;
-            ownDotMocIncluded = true;
-          } else {
-            // In relaxed mode try to find a header instead but issue a warning
-            const std::string headerToMoc =
-              this->MocFindHeader(scanFileDir, incDir + incBase);
-            if (!headerToMoc.empty()) {
-              if (!this->MocSkip(headerToMoc)) {
-                // This is for KDE4 compatibility:
-                fileToMoc = headerToMoc;
-
-                auto quoted_inc = cmQtAutoGen::Quoted(incString);
-                auto quoted_header = cmQtAutoGen::Quoted(headerToMoc);
-                auto quoted_base =
-                  cmQtAutoGen::Quoted("moc_" + incBase + ".cpp");
-                if (!selfRequiresMoc) {
-                  if (ownDotMoc) {
-                    std::ostringstream ost;
-                    ost << "The file includes the moc file " << quoted_inc
-                        << ", but does not contain a "
-                        << this->MocMacroNamesString() << " macro.\n"
-                        << "Running moc on\n"
-                        << "  " << quoted_header << "!\n"
-                        << "Better include " << quoted_base
-                        << " for a compatibility with strict mode.\n"
-                           "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n";
-                    this->LogFileWarning(cmQtAutoGen::MOC, absFilename,
-                                         ost.str());
-                  } else if (!ownDotMoc) {
-                    std::ostringstream ost;
-                    ost << "The file includes the moc file " << quoted_inc
-                        << " instead of " << quoted_base << ".\n";
-                    ost << "Running moc on\n"
-                        << "  " << quoted_header << "!\n"
-                        << "Better include " << quoted_base
-                        << " for compatibility with strict mode.\n"
-                           "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n";
-                    this->LogFileWarning(cmQtAutoGen::MOC, absFilename,
-                                         ost.str());
-                  }
-                } else {
-                  if (!ownDotMoc) {
-                    // Handled further down
-                  }
-                }
-              }
-            } else {
-              std::ostringstream ost;
-              ost << "The file includes the moc file "
-                  << cmQtAutoGen::Quoted(incString)
-                  << ", which seems to be the moc file from a different "
-                     "source file. CMake also could not find a matching "
-                     "header.";
-              this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str());
-              return false;
-            }
-          }
-        } else {
-          // Mode: Strict
-          if (ownDotMoc) {
-            // Include self
-            fileToMoc = absFilename;
-            ownDotMocIncluded = true;
-            // Accept but issue a warning if moc isn't required
-            if (!selfRequiresMoc) {
-              std::ostringstream ost;
-              ost << "The file includes the moc file "
-                  << cmQtAutoGen::Quoted(incString)
-                  << ", but does not contain a " << this->MocMacroNamesString()
-                  << " macro.";
-              this->LogFileWarning(cmQtAutoGen::MOC, absFilename, ost.str());
-            }
-          } else {
-            // Don't allow FOO.moc include other than self in strict mode
-            std::ostringstream ost;
-            ost << "The file includes the moc file "
-                << cmQtAutoGen::Quoted(incString)
-                << ", which seems to be the moc file from a different "
-                   "source file. This is not supported. Include "
-                << cmQtAutoGen::Quoted(scanFileBase + ".moc")
-                << " to run moc on this source file.";
-            this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str());
-            return false;
-          }
-        }
-        if (!fileToMoc.empty()) {
-          mocsIncluded[fileToMoc] = incString;
-          this->MocFindDepends(fileToMoc, contentText, mocDepends);
-        }
+  std::string header;
+  // Search in vicinity of the source
+  if (!this->FindHeader(header, sourcePath + includeBase)) {
+    // Search in include directories
+    for (std::string const& path : this->MocIncludePaths) {
+      std::string fullPath = path;
+      fullPath.push_back('/');
+      fullPath += includeBase;
+      if (this->FindHeader(header, fullPath)) {
+        break;
       }
-      // Forward content pointer
-      contentChars += this->MocRegExpInclude.end();
     }
   }
-
-  if (selfRequiresMoc && !ownDotMocIncluded) {
-    // In this case, check whether the scanned file itself contains a
-    // Q_OBJECT.
-    // If this is the case, the moc_foo.cpp should probably be generated from
-    // foo.cpp instead of foo.h, because otherwise it won't build.
-    // But warn, since this is not how it is supposed to be used.
-    if (relaxed && !ownMocUnderscoreInclude.empty()) {
-      // This is for KDE4 compatibility:
-      std::ostringstream ost;
-      ost << "The file contains a " << selfMacroName
-          << " macro, but does not include "
-          << cmQtAutoGen::Quoted(scanFileBase + ".moc")
-          << ". Instead it includes "
-          << cmQtAutoGen::Quoted(ownMocUnderscoreInclude) << ".\n"
-          << "Running moc on\n"
-          << "  " << cmQtAutoGen::Quoted(absFilename) << "!\n"
-          << "Better include " << cmQtAutoGen::Quoted(scanFileBase + ".moc")
-          << " for compatibility with strict mode.\n"
-             "(CMAKE_AUTOMOC_RELAXED_MODE warning)";
-      this->LogFileWarning(cmQtAutoGen::MOC, absFilename, ost.str());
-
-      // Use scanned source file instead of scanned header file as moc source
-      mocsIncluded[absFilename] = ownMocUnderscoreInclude;
-      this->MocFindDepends(absFilename, contentText, mocDepends);
-      // Remove
-      mocsIncluded.erase(ownMocUnderscoreHeader);
-    } else {
-      // Otherwise always error out since it will not compile:
-      std::ostringstream ost;
-      ost << "The file contains a " << selfMacroName
-          << " macro, but does not include "
-          << cmQtAutoGen::Quoted(scanFileBase + ".moc") << "!\n"
-          << "Consider adding the include or enabling SKIP_AUTOMOC for this "
-             "file.";
-      this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str());
-      return false;
-    }
+  // Sanitize
+  if (!header.empty()) {
+    header = cmSystemTools::GetRealPath(header);
   }
-
-  return true;
+  return header;
 }
 
-void cmQtAutoGenerators::MocParseHeaderContent(
-  const std::string& absFilename, const std::string& contentText,
-  std::map<std::string, std::string>& mocsNotIncluded,
-  std::map<std::string, std::set<std::string>>& mocDepends)
+bool cmQtAutoGenerators::MocFindIncludedFile(
+  std::string& absFile, std::string const& sourcePath,
+  std::string const& includeString) const
 {
-  // Log
-  if (this->Verbose) {
-    this->LogInfo(cmQtAutoGen::MOC, "Checking " + absFilename);
-  }
-  if (this->MocRequired(contentText)) {
-    // Register moc job
-    mocsNotIncluded[absFilename] =
-      this->ChecksumedPath(absFilename, "moc_", this->ConfigSuffix + ".cpp");
-    this->MocFindDepends(absFilename, contentText, mocDepends);
-  }
-}
-
-void cmQtAutoGenerators::SearchHeadersForSourceFile(
-  const std::string& absFilename, std::set<std::string>& mocHeaderFiles,
-  std::set<std::string>& uicHeaderFiles) const
-{
-  std::array<std::string, 2> basepaths;
+  bool success = false;
+  // Search in vicinity of the source
   {
-    std::string bpath = SubDirPrefix(absFilename);
-    bpath += cmSystemTools::GetFilenameWithoutLastExtension(absFilename);
-    // search for default header files and private header files
-    basepaths[0] = bpath;
-    basepaths[1] = bpath;
-    basepaths[1] += "_p";
-  }
-
-  for (const std::string& bPath : basepaths) {
-    std::string headerName;
-    if (this->FindHeader(headerName, bPath)) {
-      // Moc headers
-      if (!this->MocSkip(absFilename) && !this->MocSkip(headerName)) {
-        mocHeaderFiles.insert(headerName);
-      }
-      // Uic headers
-      if (!this->UicSkip(absFilename) && !this->UicSkip(headerName)) {
-        uicHeaderFiles.insert(headerName);
-      }
+    std::string testPath = sourcePath;
+    testPath += includeString;
+    if (cmSystemTools::FileExists(testPath.c_str())) {
+      absFile = cmSystemTools::GetRealPath(testPath);
+      success = true;
     }
   }
-}
-
-bool cmQtAutoGenerators::ParseHeaders(
-  const std::set<std::string>& mocHeaderFiles,
-  const std::set<std::string>& uicHeaderFiles,
-  const std::map<std::string, std::string>& mocsIncluded,
-  std::map<std::string, std::string>& mocsNotIncluded,
-  std::map<std::string, std::set<std::string>>& mocDepends,
-  std::map<std::string, std::vector<std::string>>& uisIncluded)
-{
-  bool success = true;
-  // Merged header files list to read files only once
-  std::set<std::string> headerFiles;
-  headerFiles.insert(mocHeaderFiles.begin(), mocHeaderFiles.end());
-  headerFiles.insert(uicHeaderFiles.begin(), uicHeaderFiles.end());
-
-  for (std::string const& headerName : headerFiles) {
-    std::string contentText;
-    if (ReadAll(contentText, headerName)) {
-      // Parse header content for MOC
-      if ((mocHeaderFiles.find(headerName) != mocHeaderFiles.end()) &&
-          (mocsIncluded.find(headerName) == mocsIncluded.end())) {
-        this->MocParseHeaderContent(headerName, contentText, mocsNotIncluded,
-                                    mocDepends);
+  // Search in include directories
+  if (!success) {
+    for (std::string const& path : this->MocIncludePaths) {
+      std::string fullPath = path;
+      fullPath.push_back('/');
+      fullPath += includeString;
+      if (cmSystemTools::FileExists(fullPath.c_str())) {
+        absFile = cmSystemTools::GetRealPath(fullPath);
+        success = true;
+        break;
       }
-      // Parse header content for UIC
-      if (uicHeaderFiles.find(headerName) != uicHeaderFiles.end()) {
-        this->UicParseContent(headerName, contentText, uisIncluded);
-      }
-    } else {
-      this->LogFileError(cmQtAutoGen::GEN, headerName,
-                         "Could not read header file");
-      success = false;
-      break;
     }
   }
   return success;
 }
 
-bool cmQtAutoGenerators::MocGenerateAll(
-  const std::map<std::string, std::string>& mocsIncluded,
-  const std::map<std::string, std::string>& mocsNotIncluded,
-  const std::map<std::string, std::set<std::string>>& mocDepends)
+bool cmQtAutoGenerators::MocDependFilterPush(std::string const& key,
+                                             std::string const& regExp)
+{
+  std::string error;
+  if (!key.empty()) {
+    if (!regExp.empty()) {
+      KeyRegExp filter;
+      filter.Key = key;
+      if (filter.RegExp.compile(regExp)) {
+        this->MocDependFilters.push_back(std::move(filter));
+      } else {
+        error = "Regular expression compiling failed";
+      }
+    } else {
+      error = "Regular expression is empty";
+    }
+  } else {
+    error = "Key is empty";
+  }
+  if (!error.empty()) {
+    std::string emsg = "AUTOMOC_DEPEND_FILTERS: ";
+    emsg += error;
+    emsg += "\n";
+    emsg += "  Key:    ";
+    emsg += cmQtAutoGen::Quoted(key);
+    emsg += "\n";
+    emsg += "  RegExp: ";
+    emsg += cmQtAutoGen::Quoted(regExp);
+    emsg += "\n";
+    this->LogError(cmQtAutoGen::MOC, emsg);
+    return false;
+  }
+  return true;
+}
+
+void cmQtAutoGenerators::MocFindDepends(std::string const& absFilename,
+                                        std::string const& contentText,
+                                        std::set<std::string>& depends)
+{
+  if (this->MocDependFilters.empty() && contentText.empty()) {
+    return;
+  }
+
+  std::vector<std::string> matches;
+  for (KeyRegExp& filter : this->MocDependFilters) {
+    // Run a simple find string check
+    if (contentText.find(filter.Key) != std::string::npos) {
+      // Run the expensive regular expression check loop
+      const char* contentChars = contentText.c_str();
+      while (filter.RegExp.find(contentChars)) {
+        std::string match = filter.RegExp.match(1);
+        if (!match.empty()) {
+          matches.emplace_back(std::move(match));
+        }
+        contentChars += filter.RegExp.end();
+      }
+    }
+  }
+
+  if (!matches.empty()) {
+    std::string const sourcePath = SubDirPrefix(absFilename);
+    for (std::string const& match : matches) {
+      // Find the dependency file
+      std::string incFile;
+      if (this->MocFindIncludedFile(incFile, sourcePath, match)) {
+        depends.insert(incFile);
+        if (this->Verbose) {
+          this->LogInfo(cmQtAutoGen::MOC, "Found dependency:\n  " +
+                          cmQtAutoGen::Quoted(absFilename) + "\n  " +
+                          cmQtAutoGen::Quoted(incFile));
+        }
+      } else {
+        this->LogFileWarning(cmQtAutoGen::MOC, absFilename,
+                             "Could not find dependency file " +
+                               cmQtAutoGen::Quoted(match));
+      }
+    }
+  }
+}
+
+/**
+ * @return True on success
+ */
+bool cmQtAutoGenerators::MocParseSourceContent(std::string const& absFilename,
+                                               std::string const& contentText)
+{
+  if (this->Verbose) {
+    this->LogInfo(cmQtAutoGen::MOC, "Checking: " + absFilename);
+  }
+
+  auto AddJob = [this, &absFilename](std::string const& sourceFile,
+                                     std::string const& includeString,
+                                     std::string const* content) {
+    auto job = cm::make_unique<MocJobIncluded>();
+    job->SourceFile = sourceFile;
+    job->BuildFileRel = this->AutogenIncludeDir;
+    job->BuildFileRel += includeString;
+    job->Includer = absFilename;
+    job->IncludeString = includeString;
+    job->DependsValid = (content != nullptr);
+    if (job->DependsValid) {
+      this->MocFindDepends(sourceFile, *content, job->Depends);
+    }
+    this->MocJobsIncluded.push_back(std::move(job));
+  };
+
+  struct MocInc
+  {
+    std::string Inc;  // full include string
+    std::string Dir;  // include string directory
+    std::string Base; // include string file base
+  };
+
+  // Extract moc includes from file
+  std::vector<MocInc> mocIncsUsc;
+  std::vector<MocInc> mocIncsDot;
+  {
+    const char* contentChars = contentText.c_str();
+    if (strstr(contentChars, "moc") != nullptr) {
+      while (this->MocRegExpInclude.find(contentChars)) {
+        std::string incString = this->MocRegExpInclude.match(1);
+        std::string incDir(SubDirPrefix(incString));
+        std::string incBase =
+          cmSystemTools::GetFilenameWithoutLastExtension(incString);
+        if (cmHasLiteralPrefix(incBase, "moc_")) {
+          // moc_<BASE>.cxx
+          // Remove the moc_ part from the base name
+          mocIncsUsc.push_back(MocInc{ std::move(incString), std::move(incDir),
+                                       incBase.substr(4) });
+        } else {
+          // <BASE>.moc
+          mocIncsDot.push_back(MocInc{ std::move(incString), std::move(incDir),
+                                       std::move(incBase) });
+        }
+        // Forward content pointer
+        contentChars += this->MocRegExpInclude.end();
+      }
+    }
+  }
+
+  std::string selfMacroName;
+  const bool selfRequiresMoc = this->MocRequired(contentText, &selfMacroName);
+
+  // Check if there is anything to do
+  if (!selfRequiresMoc && mocIncsUsc.empty() && mocIncsDot.empty()) {
+    return true;
+  }
+
+  // Scan file variables
+  std::string const scanFileDir = SubDirPrefix(absFilename);
+  std::string const scanFileBase =
+    cmSystemTools::GetFilenameWithoutLastExtension(absFilename);
+  // Relaxed mode variables
+  bool ownDotMocIncluded = false;
+  std::string ownMocUscInclude;
+  std::string ownMocUscHeader;
+
+  // Process moc_<BASE>.cxx includes
+  for (const MocInc& mocInc : mocIncsUsc) {
+    std::string const header =
+      this->MocFindIncludedHeader(scanFileDir, mocInc.Dir + mocInc.Base);
+    if (!header.empty()) {
+      // Check if header is skipped
+      if (this->MocSkip(header)) {
+        continue;
+      }
+      // Register moc job
+      AddJob(header, mocInc.Inc, nullptr);
+      // Store meta information for relaxed mode
+      if (this->MocRelaxedMode && (mocInc.Base == scanFileBase)) {
+        ownMocUscInclude = mocInc.Inc;
+        ownMocUscHeader = header;
+      }
+    } else {
+      std::string emsg = "The file includes the moc file ";
+      emsg += cmQtAutoGen::Quoted(mocInc.Inc);
+      emsg += ", but could not find the header ";
+      emsg += cmQtAutoGen::Quoted(this->MocStringHeaders(mocInc.Base));
+      this->LogFileError(cmQtAutoGen::MOC, absFilename, emsg);
+      return false;
+    }
+  }
+
+  // Process <BASE>.moc includes
+  for (const MocInc& mocInc : mocIncsDot) {
+    const bool ownMoc = (mocInc.Base == scanFileBase);
+    if (this->MocRelaxedMode) {
+      // Relaxed mode
+      if (selfRequiresMoc && ownMoc) {
+        // Add self
+        AddJob(absFilename, mocInc.Inc, &contentText);
+        ownDotMocIncluded = true;
+      } else {
+        // In relaxed mode try to find a header instead but issue a warning.
+        // This is for KDE4 compatibility
+        std::string const header =
+          this->MocFindIncludedHeader(scanFileDir, mocInc.Dir + mocInc.Base);
+        if (!header.empty()) {
+          // Check if header is skipped
+          if (this->MocSkip(header)) {
+            continue;
+          }
+          // Register moc job
+          AddJob(header, mocInc.Inc, nullptr);
+          if (!selfRequiresMoc) {
+            if (ownMoc) {
+              std::string emsg = "The file includes the moc file ";
+              emsg += cmQtAutoGen::Quoted(mocInc.Inc);
+              emsg += ", but does not contain a ";
+              emsg += this->MocStringMacros();
+              emsg += " macro.\nRunning moc on\n  ";
+              emsg += cmQtAutoGen::Quoted(header);
+              emsg += "!\nBetter include ";
+              emsg += cmQtAutoGen::Quoted("moc_" + mocInc.Base + ".cpp");
+              emsg += " for a compatibility with strict mode.\n"
+                      "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n";
+              this->LogFileWarning(cmQtAutoGen::MOC, absFilename, emsg);
+            } else {
+              std::string emsg = "The file includes the moc file ";
+              emsg += cmQtAutoGen::Quoted(mocInc.Inc);
+              emsg += " instead of ";
+              emsg += cmQtAutoGen::Quoted("moc_" + mocInc.Base + ".cpp");
+              emsg += ".\nRunning moc on\n  ";
+              emsg += cmQtAutoGen::Quoted(header);
+              emsg += "!\nBetter include ";
+              emsg += cmQtAutoGen::Quoted("moc_" + mocInc.Base + ".cpp");
+              emsg += " for compatibility with strict mode.\n"
+                      "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n";
+              this->LogFileWarning(cmQtAutoGen::MOC, absFilename, emsg);
+            }
+          }
+        } else {
+          std::string emsg = "The file includes the moc file ";
+          emsg += cmQtAutoGen::Quoted(mocInc.Inc);
+          emsg += ", which seems to be the moc file from a different "
+                  "source file. CMake also could not find a matching "
+                  "header.";
+          this->LogFileError(cmQtAutoGen::MOC, absFilename, emsg);
+          return false;
+        }
+      }
+    } else {
+      // Strict mode
+      if (ownMoc) {
+        // Include self
+        AddJob(absFilename, mocInc.Inc, &contentText);
+        ownDotMocIncluded = true;
+        // Accept but issue a warning if moc isn't required
+        if (!selfRequiresMoc) {
+          std::string emsg = "The file includes the moc file ";
+          emsg += cmQtAutoGen::Quoted(mocInc.Inc);
+          emsg += ", but does not contain a ";
+          emsg += this->MocStringMacros();
+          emsg += " macro.";
+          this->LogFileWarning(cmQtAutoGen::MOC, absFilename, emsg);
+        }
+      } else {
+        // Don't allow <BASE>.moc include other than self in strict mode
+        std::string emsg = "The file includes the moc file ";
+        emsg += cmQtAutoGen::Quoted(mocInc.Inc);
+        emsg += ", which seems to be the moc file from a different "
+                "source file.\nThis is not supported. Include ";
+        emsg += cmQtAutoGen::Quoted(scanFileBase + ".moc");
+        emsg += " to run moc on this source file.";
+        this->LogFileError(cmQtAutoGen::MOC, absFilename, emsg);
+        return false;
+      }
+    }
+  }
+
+  if (selfRequiresMoc && !ownDotMocIncluded) {
+    // In this case, check whether the scanned file itself contains a Q_OBJECT.
+    // If this is the case, the moc_foo.cpp should probably be generated from
+    // foo.cpp instead of foo.h, because otherwise it won't build.
+    // But warn, since this is not how it is supposed to be used.
+    if (this->MocRelaxedMode && !ownMocUscInclude.empty()) {
+      // This is for KDE4 compatibility:
+      std::string emsg = "The file contains a ";
+      emsg += selfMacroName;
+      emsg += " macro, but does not include ";
+      emsg += cmQtAutoGen::Quoted(scanFileBase + ".moc");
+      emsg += ". Instead it includes ";
+      emsg += cmQtAutoGen::Quoted(ownMocUscInclude);
+      emsg += ".\nRunning moc on\n  ";
+      emsg += cmQtAutoGen::Quoted(absFilename);
+      emsg += "!\nBetter include ";
+      emsg += cmQtAutoGen::Quoted(scanFileBase + ".moc");
+      emsg += " for compatibility with strict mode.\n"
+              "(CMAKE_AUTOMOC_RELAXED_MODE warning)";
+      this->LogFileWarning(cmQtAutoGen::MOC, absFilename, emsg);
+
+      // Remove own header job
+      {
+        auto itC = this->MocJobsIncluded.begin();
+        auto itE = this->MocJobsIncluded.end();
+        for (; itC != itE; ++itC) {
+          if ((*itC)->SourceFile == ownMocUscHeader) {
+            if ((*itC)->IncludeString == ownMocUscInclude) {
+              this->MocJobsIncluded.erase(itC);
+              break;
+            }
+          }
+        }
+      }
+      // Add own source job
+      AddJob(absFilename, ownMocUscInclude, &contentText);
+    } else {
+      // Otherwise always error out since it will not compile:
+      std::string emsg = "The file contains a ";
+      emsg += selfMacroName;
+      emsg += " macro, but does not include ";
+      emsg += cmQtAutoGen::Quoted(scanFileBase + ".moc");
+      emsg += "!\nConsider to\n - add #include \"";
+      emsg += scanFileBase;
+      emsg += ".moc\"\n - enable SKIP_AUTOMOC for this file";
+      this->LogFileError(cmQtAutoGen::MOC, absFilename, emsg);
+      return false;
+    }
+  }
+  return true;
+}
+
+void cmQtAutoGenerators::MocParseHeaderContent(std::string const& absFilename,
+                                               std::string const& contentText)
+{
+  if (this->Verbose) {
+    this->LogInfo(cmQtAutoGen::MOC, "Checking: " + absFilename);
+  }
+
+  auto const fit =
+    std::find_if(this->MocJobsIncluded.cbegin(), this->MocJobsIncluded.cend(),
+                 [&absFilename](std::unique_ptr<MocJobIncluded> const& job) {
+                   return job->SourceFile == absFilename;
+                 });
+  if (fit == this->MocJobsIncluded.cend()) {
+    if (this->MocRequired(contentText)) {
+      static std::string const prefix = "moc_";
+      static std::string const suffix = this->ConfigSuffix + ".cpp";
+
+      auto job = cm::make_unique<MocJobAuto>();
+      job->SourceFile = absFilename;
+      {
+        std::string& bld = job->BuildFileRel;
+        bld = this->FilePathChecksum.getPart(absFilename);
+        bld += "/";
+        bld += prefix;
+        bld += cmSystemTools::GetFilenameWithoutLastExtension(absFilename);
+        bld += suffix;
+      }
+      this->MocFindDepends(absFilename, contentText, job->Depends);
+      this->MocJobsAuto.push_back(std::move(job));
+    }
+  }
+}
+
+bool cmQtAutoGenerators::MocGenerateAll()
 {
   if (!this->MocEnabled()) {
     return true;
   }
 
-  // Look for name collisions
+  // Look for name collisions in included moc files
   {
-    std::multimap<std::string, std::string> collisions;
-    // Test merged map of included and notIncluded
-    std::map<std::string, std::string> mergedMocs(mocsIncluded);
-    mergedMocs.insert(mocsNotIncluded.begin(), mocsNotIncluded.end());
-    if (this->NameCollisionTest(mergedMocs, collisions)) {
-      std::string msg = "The same moc file will be generated "
-                        "from different sources.\n"
-                        "To avoid this error either\n"
-                        " - rename the source files or\n"
-                        " - do not include the (moc_NAME.cpp|NAME.moc) file";
-      this->LogNameCollisionError(cmQtAutoGen::MOC, msg, collisions);
+    bool collision = false;
+    std::map<std::string, std::vector<MocJobIncluded const*>> collisions;
+    for (auto const& job : this->MocJobsIncluded) {
+      auto& list = collisions[job->IncludeString];
+      if (!list.empty()) {
+        collision = true;
+      }
+      list.push_back(job.get());
+    }
+    if (collision) {
+      std::string emsg =
+        "Included moc files with the same name will be "
+        "generated from different sources.\n"
+        "Consider to\n"
+        " - not include the \"moc_<NAME>.cpp\" file\n"
+        " - add a directory prefix to a \"<NAME>.moc\" include "
+        "(e.g \"sub/<NAME>.moc\")\n"
+        " - rename the source file(s)\n"
+        "Include conflicts\n"
+        "-----------------\n";
+      const auto& colls = collisions;
+      for (auto const& coll : colls) {
+        if (coll.second.size() > 1) {
+          emsg += cmQtAutoGen::Quoted(coll.first);
+          emsg += " included in\n";
+          for (const MocJobIncluded* job : coll.second) {
+            emsg += " - ";
+            emsg += cmQtAutoGen::Quoted(job->Includer);
+            emsg += "\n";
+          }
+          emsg += "would be generated from\n";
+          for (const MocJobIncluded* job : coll.second) {
+            emsg += " - ";
+            emsg += cmQtAutoGen::Quoted(job->SourceFile);
+            emsg += "\n";
+          }
+        }
+      }
+      this->LogError(cmQtAutoGen::MOC, emsg);
       return false;
     }
   }
 
-  // Generate moc_predefs
+  // (Re)generate moc_predefs.h on demand
   if (!this->MocPredefsCmd.empty()) {
     if (this->MocSettingsChanged ||
-        FileAbsentOrOlder(this->MocPredefsFileAbs, this->SettingsFile)) {
+        !cmSystemTools::FileExists(this->MocPredefsFileAbs)) {
       if (this->Verbose) {
         this->LogBold("Generating MOC predefs " + this->MocPredefsFileRel);
       }
@@ -1216,16 +1381,9 @@
       {
         // Compose command
         std::vector<std::string> cmd = this->MocPredefsCmd;
-        // Add includes
-        cmd.insert(cmd.end(), this->MocIncludes.begin(),
-                   this->MocIncludes.end());
-        // Add definitions
-        for (std::string const& def : this->MocDefinitions) {
-          cmd.push_back("-D" + def);
-        }
         // Add options
-        cmd.insert(cmd.end(), this->MocOptions.begin(),
-                   this->MocOptions.end());
+        cmd.insert(cmd.end(), this->MocAllOptions.begin(),
+                   this->MocAllOptions.end());
         // Execute command
         if (!this->RunCommand(cmd, output)) {
           this->LogCommandError(cmQtAutoGen::MOC,
@@ -1240,6 +1398,8 @@
                             output)) {
           this->MocPredefsChanged = true;
         } else {
+          this->LogFileError(cmQtAutoGen::MOC, this->MocPredefsFileAbs,
+                             "moc_predefs file writing failed");
           return false;
         }
       } else {
@@ -1251,104 +1411,157 @@
         cmSystemTools::Touch(this->MocPredefsFileAbs, false);
       }
     }
-  }
 
-  // Generate moc files that are included by source files.
-  for (auto const& it : mocsIncluded) {
-    if (!this->MocGenerateFile(it.first, it.second, mocDepends, true)) {
-      if (this->MocRunFailed) {
-        return false;
-      }
+    // Add moc_predefs.h to moc file dependecies
+    for (auto const& item : this->MocJobsIncluded) {
+      item->Depends.insert(this->MocPredefsFileAbs);
+    }
+    for (auto const& item : this->MocJobsAuto) {
+      item->Depends.insert(this->MocPredefsFileAbs);
     }
   }
 
+  // Generate moc files that are included by source files.
+  for (auto const& item : this->MocJobsIncluded) {
+    if (!this->MocGenerateFile(*item)) {
+      return false;
+    }
+  }
   // Generate moc files that are _not_ included by source files.
-  bool mocCompFileGenerated = false;
-  for (auto const& it : mocsNotIncluded) {
-    if (this->MocGenerateFile(it.first, it.second, mocDepends, false)) {
-      mocCompFileGenerated = true;
-    } else {
-      if (this->MocRunFailed) {
-        return false;
-      }
+  bool autoNameGenerated = false;
+  for (auto const& item : this->MocJobsAuto) {
+    if (!this->MocGenerateFile(*item, &autoNameGenerated)) {
+      return false;
     }
   }
 
   // Compose mocs compilation file content
-  std::string automocSource;
   {
-    std::ostringstream ost;
-    ost << "/* This file is autogenerated, do not edit*/\n";
-    if (mocsNotIncluded.empty()) {
+    std::string mocs = "/* This file is autogenerated, do not edit*/\n";
+    if (this->MocJobsAuto.empty()) {
       // Dummy content
-      ost << "enum some_compilers { need_more_than_nothing };\n";
+      mocs += "enum some_compilers { need_more_than_nothing };\n";
     } else {
       // Valid content
-      for (auto const& it : mocsNotIncluded) {
-        ost << "#include \"" << it.second << "\"\n";
+      for (const auto& item : this->MocJobsAuto) {
+        mocs += "#include \"";
+        mocs += item->BuildFileRel;
+        mocs += "\"\n";
       }
     }
-    automocSource = ost.str();
-  }
 
-  if (this->FileDiffers(this->MocCompFileAbs, automocSource)) {
-    // Actually write mocs compilation file
-    if (this->Verbose) {
-      this->LogBold("Generating MOC compilation " + this->MocCompFileRel);
+    if (this->FileDiffers(this->MocCompFileAbs, mocs)) {
+      // Actually write mocs compilation file
+      if (this->Verbose) {
+        this->LogBold("Generating MOC compilation " + this->MocCompFileRel);
+      }
+      if (!this->FileWrite(cmQtAutoGen::MOC, this->MocCompFileAbs, mocs)) {
+        this->LogFileError(cmQtAutoGen::MOC, this->MocCompFileAbs,
+                           "mocs compilation file writing failed");
+        return false;
+      }
+    } else if (autoNameGenerated) {
+      // Only touch mocs compilation file
+      if (this->Verbose) {
+        this->LogInfo(cmQtAutoGen::MOC,
+                      "Touching mocs compilation " + this->MocCompFileRel);
+      }
+      cmSystemTools::Touch(this->MocCompFileAbs, false);
     }
-    if (!this->FileWrite(cmQtAutoGen::MOC, this->MocCompFileAbs,
-                         automocSource)) {
-      return false;
-    }
-  } else if (mocCompFileGenerated) {
-    // Only touch mocs compilation file
-    if (this->Verbose) {
-      this->LogInfo(cmQtAutoGen::MOC,
-                    "Touching mocs compilation " + this->MocCompFileRel);
-    }
-    cmSystemTools::Touch(this->MocCompFileAbs, false);
   }
 
   return true;
 }
 
 /**
- * @return True if a moc file was created. False may indicate an error.
+ * @return True on success
  */
-bool cmQtAutoGenerators::MocGenerateFile(
-  const std::string& sourceFile, const std::string& mocFileName,
-  const std::map<std::string, std::set<std::string>>& mocDepends,
-  bool included)
+bool cmQtAutoGenerators::MocGenerateFile(const MocJobAuto& mocJob,
+                                         bool* generated)
 {
-  bool mocGenerated = false;
-  bool generateMoc = this->MocSettingsChanged || this->MocPredefsChanged;
+  bool success = true;
 
-  const std::string mocFileRel =
-    included ? (this->AutogenIncludeDir + mocFileName) : mocFileName;
-  const std::string mocFileAbs =
-    cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, mocFileRel);
+  std::string const mocFileAbs = cmSystemTools::CollapseCombinedPath(
+    this->AutogenBuildDir, mocJob.BuildFileRel);
 
-  if (!generateMoc) {
-    // Test if the source file is newer that the build file
-    generateMoc = FileAbsentOrOlder(mocFileAbs, sourceFile);
-    if (!generateMoc) {
-      // Test if a dependency file changed
-      std::map<std::string, std::set<std::string>>::const_iterator dit =
-        mocDepends.find(sourceFile);
-      if (dit != mocDepends.end()) {
-        for (std::string const& fit : dit->second) {
-          if (FileAbsentOrOlder(mocFileAbs, fit)) {
-            generateMoc = true;
-            break;
-          }
-        }
+  bool generate = false;
+  std::string generateReason;
+  if (!generate && !cmSystemTools::FileExists(mocFileAbs.c_str())) {
+    if (this->Verbose) {
+      generateReason = "Generating ";
+      generateReason += cmQtAutoGen::Quoted(mocFileAbs);
+      generateReason += " from its source file ";
+      generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
+      generateReason += " because it doesn't exist";
+    }
+    generate = true;
+  }
+  if (!generate && this->MocSettingsChanged) {
+    if (this->Verbose) {
+      generateReason = "Generating ";
+      generateReason += cmQtAutoGen::Quoted(mocFileAbs);
+      generateReason += " from ";
+      generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
+      generateReason += " because the MOC settings changed";
+    }
+    generate = true;
+  }
+  if (!generate && this->MocPredefsChanged) {
+    if (this->Verbose) {
+      generateReason = "Generating ";
+      generateReason += cmQtAutoGen::Quoted(mocFileAbs);
+      generateReason += " from ";
+      generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
+      generateReason += " because moc_predefs.h changed";
+    }
+    generate = true;
+  }
+  if (!generate) {
+    std::string error;
+    if (FileIsOlderThan(mocFileAbs, mocJob.SourceFile, &error)) {
+      if (this->Verbose) {
+        generateReason = "Generating ";
+        generateReason += cmQtAutoGen::Quoted(mocFileAbs);
+        generateReason += " because it's older than its source file ";
+        generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
+      }
+      generate = true;
+    } else {
+      if (!error.empty()) {
+        this->LogError(cmQtAutoGen::MOC, error);
+        success = false;
       }
     }
   }
-  if (generateMoc) {
+  if (success && !generate) {
+    // Test if a dependency file is newer
+    std::string error;
+    for (std::string const& depFile : mocJob.Depends) {
+      if (FileIsOlderThan(mocFileAbs, depFile, &error)) {
+        if (this->Verbose) {
+          generateReason = "Generating ";
+          generateReason += cmQtAutoGen::Quoted(mocFileAbs);
+          generateReason += " from ";
+          generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
+          generateReason += " because it is older than ";
+          generateReason += cmQtAutoGen::Quoted(depFile);
+        }
+        generate = true;
+        break;
+      }
+      if (!error.empty()) {
+        this->LogError(cmQtAutoGen::MOC, error);
+        success = false;
+        break;
+      }
+    }
+  }
+
+  if (generate) {
     // Log
     if (this->Verbose) {
-      this->LogBold("Generating MOC source " + mocFileRel);
+      this->LogBold("Generating MOC source " + mocJob.BuildFileRel);
+      this->LogInfo(cmQtAutoGen::MOC, generateReason);
     }
 
     // Make sure the parent directory exists
@@ -1356,15 +1569,9 @@
       // Compose moc command
       std::vector<std::string> cmd;
       cmd.push_back(this->MocExecutable);
-      // Add includes
-      cmd.insert(cmd.end(), this->MocIncludes.begin(),
-                 this->MocIncludes.end());
-      // Add definitions
-      for (std::string const& def : this->MocDefinitions) {
-        cmd.push_back("-D" + def);
-      }
       // Add options
-      cmd.insert(cmd.end(), this->MocOptions.begin(), this->MocOptions.end());
+      cmd.insert(cmd.end(), this->MocAllOptions.begin(),
+                 this->MocAllOptions.end());
       // Add predefs include
       if (!this->MocPredefsFileAbs.empty()) {
         cmd.push_back("--include");
@@ -1372,37 +1579,111 @@
       }
       cmd.push_back("-o");
       cmd.push_back(mocFileAbs);
-      cmd.push_back(sourceFile);
+      cmd.push_back(mocJob.SourceFile);
 
       // Execute moc command
       std::string output;
       if (this->RunCommand(cmd, output)) {
         // Success
-        mocGenerated = true;
+        if (generated != nullptr) {
+          *generated = true;
+        }
       } else {
-        this->LogCommandError(cmQtAutoGen::MOC, "moc failed for\n  " +
-                                cmQtAutoGen::Quoted(sourceFile),
-                              cmd, output);
+        // Moc command failed
+        {
+          std::string emsg = "moc failed for\n  ";
+          emsg += cmQtAutoGen::Quoted(mocJob.SourceFile);
+          this->LogCommandError(cmQtAutoGen::MOC, emsg, cmd, output);
+        }
         cmSystemTools::RemoveFile(mocFileAbs);
-        this->MocRunFailed = true;
+        success = false;
       }
     } else {
       // Parent directory creation failed
-      this->MocRunFailed = true;
+      success = false;
     }
   }
-  return mocGenerated;
+  return success;
+}
+
+/**
+ * @brief Tests if the file name is in the skip list
+ */
+bool cmQtAutoGenerators::UicSkip(std::string const& absFilename) const
+{
+  if (this->UicEnabled()) {
+    // Test if the file name is on the skip list
+    if (!ListContains(this->UicSkipList, absFilename)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool cmQtAutoGenerators::UicParseContent(std::string const& absFilename,
+                                         std::string const& contentText)
+{
+  if (this->Verbose) {
+    this->LogInfo(cmQtAutoGen::UIC, "Checking: " + absFilename);
+  }
+
+  std::vector<std::string> includes;
+  // Extracte includes
+  {
+    const char* contentChars = contentText.c_str();
+    if (strstr(contentChars, "ui_") != nullptr) {
+      while (this->UicRegExpInclude.find(contentChars)) {
+        includes.push_back(this->UicRegExpInclude.match(1));
+        contentChars += this->UicRegExpInclude.end();
+      }
+    }
+  }
+
+  for (std::string const& includeString : includes) {
+    std::string uiInputFile;
+    if (!UicFindIncludedFile(uiInputFile, absFilename, includeString)) {
+      return false;
+    }
+    // Check if this file should be skipped
+    if (this->UicSkip(uiInputFile)) {
+      continue;
+    }
+    // Check if the job already exists
+    bool jobExists = false;
+    for (const auto& job : this->UicJobs) {
+      if ((job->SourceFile == uiInputFile) &&
+          (job->IncludeString == includeString)) {
+        jobExists = true;
+        break;
+      }
+    }
+    if (!jobExists) {
+      auto job = cm::make_unique<UicJob>();
+      job->SourceFile = uiInputFile;
+      job->BuildFileRel = this->AutogenIncludeDir;
+      job->BuildFileRel += includeString;
+      job->Includer = absFilename;
+      job->IncludeString = includeString;
+      this->UicJobs.push_back(std::move(job));
+    }
+  }
+
+  return true;
 }
 
 bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile,
-                                             const std::string& sourceFile,
-                                             const std::string& searchPath,
-                                             const std::string& searchFile)
+                                             std::string const& sourceFile,
+                                             std::string const& includeString)
 {
   bool success = false;
-  std::vector<std::string> testFiles;
+  std::string searchFile =
+    cmSystemTools::GetFilenameWithoutLastExtension(includeString).substr(3);
+  searchFile += ".ui";
   // Collect search paths list
+  std::vector<std::string> testFiles;
   {
+    std::string const searchPath = SubDirPrefix(includeString);
+
     std::string searchFileFull;
     if (!searchPath.empty()) {
       searchFileFull = searchPath;
@@ -1410,7 +1691,7 @@
     }
     // Vicinity of the source
     {
-      const std::string sourcePath = SubDirPrefix(sourceFile);
+      std::string const sourcePath = SubDirPrefix(sourceFile);
       testFiles.push_back(sourcePath + searchFile);
       if (!searchPath.empty()) {
         testFiles.push_back(sourcePath + searchFileFull);
@@ -1440,76 +1721,75 @@
 
   // Log error
   if (!success) {
-    std::ostringstream ost;
-    ost << "Could not find " << cmQtAutoGen::Quoted(searchFile) << " in\n";
+    std::string emsg = "Could not find ";
+    emsg += cmQtAutoGen::Quoted(searchFile);
+    emsg += " in\n";
     for (std::string const& testFile : testFiles) {
-      ost << "  " << cmQtAutoGen::Quoted(testFile) << "\n";
+      emsg += "  ";
+      emsg += cmQtAutoGen::Quoted(testFile);
+      emsg += "\n";
     }
-    this->LogFileError(cmQtAutoGen::UIC, sourceFile, ost.str());
+    this->LogFileError(cmQtAutoGen::UIC, sourceFile, emsg);
   }
 
   return success;
 }
 
-bool cmQtAutoGenerators::UicGenerateAll(
-  const std::map<std::string, std::vector<std::string>>& uisIncluded)
+bool cmQtAutoGenerators::UicGenerateAll()
 {
   if (!this->UicEnabled()) {
     return true;
   }
 
-  // single map with input / output names
-  std::map<std::string, std::map<std::string, std::string>> sourceGenMap;
+  // Look for name collisions in included uic files
   {
-    // Collision lookup map
-    std::map<std::string, std::string> testMap;
-    // Compile maps
-    for (auto const& sit : uisIncluded) {
-      const std::string& source(sit.first);
-      const std::vector<std::string>& sourceIncs(sit.second);
-      // insert new source/destination map
-      std::map<std::string, std::string>& uiGenMap = sourceGenMap[source];
-      for (std::string const& inc : sourceIncs) {
-        // Remove ui_ from the begin filename by substr()
-        const std::string uiBasePath = SubDirPrefix(inc);
-        const std::string uiBaseName =
-          cmSystemTools::GetFilenameWithoutLastExtension(inc).substr(3);
-        const std::string uiFileName = uiBaseName + ".ui";
-        std::string uiInputFile;
-        if (UicFindIncludedFile(uiInputFile, source, uiBasePath, uiFileName)) {
-          std::string uiOutputFile = uiBasePath;
-          uiOutputFile += "ui_";
-          uiOutputFile += uiBaseName;
-          uiOutputFile += ".h";
-          cmSystemTools::ReplaceString(uiOutputFile, "..", "__");
-          uiGenMap[uiInputFile] = uiOutputFile;
-          testMap[uiInputFile] = uiOutputFile;
-        } else {
-          return false;
+    bool collision = false;
+    std::map<std::string, std::vector<UicJob const*>> collisions;
+    for (auto const& job : this->UicJobs) {
+      auto& list = collisions[job->IncludeString];
+      if (!list.empty()) {
+        collision = true;
+      }
+      list.push_back(job.get());
+    }
+    if (collision) {
+      std::string emsg =
+        "Included uic files with the same name will be "
+        "generated from different sources.\n"
+        "Consider to\n"
+        " - add a directory prefix to a \"ui_<NAME>.h\" include "
+        "(e.g \"sub/ui_<NAME>.h\")\n"
+        " - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" "
+        "include(s)\n"
+        "Include conflicts\n"
+        "-----------------\n";
+      const auto& colls = collisions;
+      for (auto const& coll : colls) {
+        if (coll.second.size() > 1) {
+          emsg += cmQtAutoGen::Quoted(coll.first);
+          emsg += " included in\n";
+          for (const UicJob* job : coll.second) {
+            emsg += " - ";
+            emsg += cmQtAutoGen::Quoted(job->Includer);
+            emsg += "\n";
+          }
+          emsg += "would be generated from\n";
+          for (const UicJob* job : coll.second) {
+            emsg += " - ";
+            emsg += cmQtAutoGen::Quoted(job->SourceFile);
+            emsg += "\n";
+          }
         }
       }
-    }
-    // look for name collisions
-    {
-      std::multimap<std::string, std::string> collisions;
-      if (this->NameCollisionTest(testMap, collisions)) {
-        std::string msg = "The same ui_NAME.h file will be generated "
-                          "from different sources.\n"
-                          "To avoid this error rename the source files.\n";
-        this->LogNameCollisionError(cmQtAutoGen::UIC, msg, collisions);
-        return false;
-      }
+      this->LogError(cmQtAutoGen::UIC, emsg);
+      return false;
     }
   }
 
-  // generate ui files
-  for (auto const& srcItem : sourceGenMap) {
-    for (auto const& item : srcItem.second) {
-      if (!this->UicGenerateFile(srcItem.first, item.first, item.second)) {
-        if (this->UicRunFailed) {
-          return false;
-        }
-      }
+  // Generate ui header files
+  for (const auto& item : this->UicJobs) {
+    if (!this->UicGenerateFile(*item)) {
+      return false;
     }
   }
 
@@ -1517,27 +1797,59 @@
 }
 
 /**
- * @return True if a uic file was created. False may indicate an error.
+ * @return True on success
  */
-bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName,
-                                         const std::string& uiInputFile,
-                                         const std::string& uiOutputFile)
+bool cmQtAutoGenerators::UicGenerateFile(const UicJob& uicJob)
 {
-  bool uicGenerated = false;
-  bool generateUic = this->UicSettingsChanged;
+  bool success = true;
 
-  const std::string uicFileRel = this->AutogenIncludeDir + uiOutputFile;
-  const std::string uicFileAbs =
-    cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, uicFileRel);
+  std::string const uicFileAbs = cmSystemTools::CollapseCombinedPath(
+    this->AutogenBuildDir, uicJob.BuildFileRel);
 
-  if (!generateUic) {
-    // Test if the source file is newer that the build file
-    generateUic = FileAbsentOrOlder(uicFileAbs, uiInputFile);
+  bool generate = false;
+  std::string generateReason;
+  if (!generate && !cmSystemTools::FileExists(uicFileAbs.c_str())) {
+    if (this->Verbose) {
+      generateReason = "Generating ";
+      generateReason += cmQtAutoGen::Quoted(uicFileAbs);
+      generateReason += " from its source file ";
+      generateReason += cmQtAutoGen::Quoted(uicJob.SourceFile);
+      generateReason += " because it doesn't exist";
+    }
+    generate = true;
   }
-  if (generateUic) {
+  if (!generate && this->UicSettingsChanged) {
+    if (this->Verbose) {
+      generateReason = "Generating ";
+      generateReason += cmQtAutoGen::Quoted(uicFileAbs);
+      generateReason += " from ";
+      generateReason += cmQtAutoGen::Quoted(uicJob.SourceFile);
+      generateReason += " because the UIC settings changed";
+    }
+    generate = true;
+  }
+  if (!generate) {
+    std::string error;
+    if (FileIsOlderThan(uicFileAbs, uicJob.SourceFile, &error)) {
+      if (this->Verbose) {
+        generateReason = "Generating ";
+        generateReason += cmQtAutoGen::Quoted(uicFileAbs);
+        generateReason += " because it's older than its source file ";
+        generateReason += cmQtAutoGen::Quoted(uicJob.SourceFile);
+      }
+      generate = true;
+    } else {
+      if (!error.empty()) {
+        this->LogError(cmQtAutoGen::UIC, error);
+        success = false;
+      }
+    }
+  }
+  if (generate) {
     // Log
     if (this->Verbose) {
-      this->LogBold("Generating UIC header " + uicFileRel);
+      this->LogBold("Generating UIC header " + uicJob.BuildFileRel);
+      this->LogInfo(cmQtAutoGen::UIC, generateReason);
     }
 
     // Make sure the parent directory exists
@@ -1547,7 +1859,7 @@
       cmd.push_back(this->UicExecutable);
       {
         std::vector<std::string> allOpts = this->UicTargetOptions;
-        auto optionIt = this->UicOptions.find(uiInputFile);
+        auto optionIt = this->UicOptions.find(uicJob.SourceFile);
         if (optionIt != this->UicOptions.end()) {
           cmQtAutoGen::UicMergeOptions(allOpts, optionIt->second,
                                        (this->QtMajorVersion == "5"));
@@ -1556,31 +1868,29 @@
       }
       cmd.push_back("-o");
       cmd.push_back(uicFileAbs);
-      cmd.push_back(uiInputFile);
+      cmd.push_back(uicJob.SourceFile);
 
       std::string output;
       if (this->RunCommand(cmd, output)) {
         // Success
-        uicGenerated = true;
       } else {
         // Command failed
         {
-          std::ostringstream ost;
-          ost << "uic failed for\n"
-              << "  " << cmQtAutoGen::Quoted(uiInputFile) << "\n"
-              << "needed by\n"
-              << "  " << cmQtAutoGen::Quoted(realName);
-          this->LogCommandError(cmQtAutoGen::UIC, ost.str(), cmd, output);
+          std::string emsg = "uic failed for\n  ";
+          emsg += cmQtAutoGen::Quoted(uicJob.SourceFile);
+          emsg += "\nincluded by\n  ";
+          emsg += cmQtAutoGen::Quoted(uicJob.Includer);
+          this->LogCommandError(cmQtAutoGen::UIC, emsg, cmd, output);
         }
         cmSystemTools::RemoveFile(uicFileAbs);
-        this->UicRunFailed = true;
+        success = false;
       }
     } else {
       // Parent directory creation failed
-      this->UicRunFailed = true;
+      success = false;
     }
   }
-  return uicGenerated;
+  return success;
 }
 
 bool cmQtAutoGenerators::RccGenerateAll()
@@ -1589,24 +1899,22 @@
     return true;
   }
 
-  // Generate qrc files
-  for (RccJob const& rccJob : this->RccJobs) {
+  // Generate rcc files
+  for (const RccJob& rccJob : this->RccJobs) {
     if (!this->RccGenerateFile(rccJob)) {
-      if (this->RccRunFailed) {
-        return false;
-      }
+      return false;
     }
   }
   return true;
 }
 
 /**
- * @return True if a rcc file was created. False may indicate an error.
+ * @return True on success
  */
 bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob)
 {
+  bool success = true;
   bool rccGenerated = false;
-  bool generateRcc = this->RccSettingsChanged;
 
   std::string rccFileAbs;
   if (this->ConfigSuffix.empty()) {
@@ -1618,46 +1926,114 @@
     rccFileAbs += this->ConfigSuffix;
     rccFileAbs += cmSystemTools::GetFilenameLastExtension(rccJob.RccFile);
   }
-  const std::string rccFileRel = cmSystemTools::RelativePath(
+  std::string const rccFileRel = cmSystemTools::RelativePath(
     this->AutogenBuildDir.c_str(), rccFileAbs.c_str());
 
   // Check if regeneration is required
-  if (!generateRcc) {
-    // Test if the resources list file is newer than build file
-    generateRcc = FileAbsentOrOlder(rccFileAbs, rccJob.QrcFile);
-    if (!generateRcc) {
-      // Acquire input file list
-      std::vector<std::string> readFiles;
-      const std::vector<std::string>* files = &rccJob.Inputs;
-      if (files->empty()) {
-        // Read input file list from qrc file
-        std::string error;
-        if (cmQtAutoGen::RccListInputs(this->QtMajorVersion,
-                                       this->RccExecutable, rccJob.QrcFile,
-                                       readFiles, &error)) {
-          files = &readFiles;
-        } else {
-          files = nullptr;
-          this->LogFileError(cmQtAutoGen::RCC, rccJob.QrcFile, error);
-          this->RccRunFailed = true;
+  bool generate = false;
+  std::string generateReason;
+  if (!cmSystemTools::FileExists(rccJob.QrcFile)) {
+    {
+      std::string error = "Could not find the file\n  ";
+      error += cmQtAutoGen::Quoted(rccJob.QrcFile);
+      this->LogError(cmQtAutoGen::RCC, error);
+    }
+    success = false;
+  }
+  if (success && !generate && !cmSystemTools::FileExists(rccFileAbs.c_str())) {
+    if (this->Verbose) {
+      generateReason = "Generating ";
+      generateReason += cmQtAutoGen::Quoted(rccFileAbs);
+      generateReason += " from its source file ";
+      generateReason += cmQtAutoGen::Quoted(rccJob.QrcFile);
+      generateReason += " because it doesn't exist";
+    }
+    generate = true;
+  }
+  if (success && !generate && this->RccSettingsChanged) {
+    if (this->Verbose) {
+      generateReason = "Generating ";
+      generateReason += cmQtAutoGen::Quoted(rccFileAbs);
+      generateReason += " from ";
+      generateReason += cmQtAutoGen::Quoted(rccJob.QrcFile);
+      generateReason += " because the RCC settings changed";
+    }
+    generate = true;
+  }
+  if (success && !generate) {
+    std::string error;
+    if (FileIsOlderThan(rccFileAbs, rccJob.QrcFile, &error)) {
+      if (this->Verbose) {
+        generateReason = "Generating ";
+        generateReason += cmQtAutoGen::Quoted(rccFileAbs);
+        generateReason += " because it is older than ";
+        generateReason += cmQtAutoGen::Quoted(rccJob.QrcFile);
+      }
+      generate = true;
+    } else {
+      if (!error.empty()) {
+        this->LogError(cmQtAutoGen::RCC, error);
+        success = false;
+      }
+    }
+  }
+  if (success && !generate) {
+    // Acquire input file list
+    std::vector<std::string> readFiles;
+    std::vector<std::string> const* files = nullptr;
+    if (!rccJob.Inputs.empty()) {
+      files = &rccJob.Inputs;
+    } else {
+      // Read input file list from qrc file
+      std::string error;
+      if (cmQtAutoGen::RccListInputs(this->QtMajorVersion, this->RccExecutable,
+                                     rccJob.QrcFile, readFiles, &error)) {
+        files = &readFiles;
+      } else {
+        this->LogFileError(cmQtAutoGen::RCC, rccJob.QrcFile, error);
+        success = false;
+      }
+    }
+    // Test if any input file is newer than the build file
+    if (files != nullptr) {
+      std::string error;
+      for (std::string const& resFile : *files) {
+        if (!cmSystemTools::FileExists(resFile.c_str())) {
+          error = "Could not find the file\n  ";
+          error += cmQtAutoGen::Quoted(resFile);
+          error += "\nwhich is listed in\n  ";
+          error += cmQtAutoGen::Quoted(rccJob.QrcFile);
+          break;
+        }
+        if (FileIsOlderThan(rccFileAbs, resFile, &error)) {
+          if (this->Verbose) {
+            generateReason = "Generating ";
+            generateReason += cmQtAutoGen::Quoted(rccFileAbs);
+            generateReason += " from ";
+            generateReason += cmQtAutoGen::Quoted(rccJob.QrcFile);
+            generateReason += " because it is older than ";
+            generateReason += cmQtAutoGen::Quoted(resFile);
+          }
+          generate = true;
+          break;
+        }
+        if (!error.empty()) {
+          break;
         }
       }
-      // Test if any input file is newer than the build file
-      if (files != nullptr) {
-        for (std::string const& file : *files) {
-          if (FileAbsentOrOlder(rccFileAbs, file)) {
-            generateRcc = true;
-            break;
-          }
-        }
+      // Print error
+      if (!error.empty()) {
+        this->LogError(cmQtAutoGen::RCC, error);
+        success = false;
       }
     }
   }
   // Regenerate on demand
-  if (generateRcc) {
+  if (generate) {
     // Log
     if (this->Verbose) {
       this->LogBold("Generating RCC source " + rccFileRel);
+      this->LogInfo(cmQtAutoGen::RCC, generateReason);
     }
 
     // Make sure the parent directory exists
@@ -1675,22 +2051,24 @@
         // Success
         rccGenerated = true;
       } else {
-        this->LogCommandError(cmQtAutoGen::RCC, "rcc failed for\n  " +
-                                cmQtAutoGen::Quoted(rccJob.QrcFile),
-                              cmd, output);
+        {
+          std::string emsg = "rcc failed for\n  ";
+          emsg += cmQtAutoGen::Quoted(rccJob.QrcFile);
+          this->LogCommandError(cmQtAutoGen::RCC, emsg, cmd, output);
+        }
         cmSystemTools::RemoveFile(rccFileAbs);
-        this->RccRunFailed = true;
+        success = false;
       }
     } else {
       // Parent directory creation failed
-      this->RccRunFailed = true;
+      success = false;
     }
   }
   // For a multi configuration generator generate a wrapper file
-  if (!this->ConfigSuffix.empty() && !this->RccRunFailed) {
+  if (success && !this->ConfigSuffix.empty()) {
     // Wrapper file name
-    const std::string& wrapperFileAbs = rccJob.RccFile;
-    const std::string wrapperFileRel = cmSystemTools::RelativePath(
+    std::string const& wrapperFileAbs = rccJob.RccFile;
+    std::string const wrapperFileRel = cmSystemTools::RelativePath(
       this->AutogenBuildDir.c_str(), wrapperFileAbs.c_str());
     // Wrapper file content
     std::string content = "// This is an autogenerated configuration "
@@ -1700,17 +2078,17 @@
     content += "\"\n";
     // Write content to file
     if (this->FileDiffers(wrapperFileAbs, content)) {
-      // Write new wrapper file if the content differs
+      // Write new wrapper file
       if (this->Verbose) {
         this->LogBold("Generating RCC wrapper " + wrapperFileRel);
       }
       if (!this->FileWrite(cmQtAutoGen::RCC, wrapperFileAbs, content)) {
-        // Error
-        rccGenerated = false;
-        this->RccRunFailed = true;
+        this->LogFileError(cmQtAutoGen::RCC, wrapperFileAbs,
+                           "rcc wrapper file writing failed");
+        success = false;
       }
     } else if (rccGenerated) {
-      // Only touch wrapper file if the content matches
+      // Just touch the wrapper file
       if (this->Verbose) {
         this->LogInfo(cmQtAutoGen::RCC,
                       "Touching RCC wrapper " + wrapperFileRel);
@@ -1719,10 +2097,10 @@
     }
   }
 
-  return rccGenerated;
+  return success;
 }
 
-void cmQtAutoGenerators::LogBold(const std::string& message) const
+void cmQtAutoGenerators::LogBold(std::string const& message) const
 {
   cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue |
                                      cmsysTerminal_Color_ForegroundBold,
@@ -1730,7 +2108,7 @@
 }
 
 void cmQtAutoGenerators::LogInfo(cmQtAutoGen::GeneratorType genType,
-                                 const std::string& message) const
+                                 std::string const& message) const
 {
   std::string msg = cmQtAutoGen::GeneratorName(genType);
   msg += ": ";
@@ -1742,7 +2120,7 @@
 }
 
 void cmQtAutoGenerators::LogWarning(cmQtAutoGen::GeneratorType genType,
-                                    const std::string& message) const
+                                    std::string const& message) const
 {
   std::string msg = cmQtAutoGen::GeneratorName(genType);
   msg += " warning:";
@@ -1758,182 +2136,102 @@
   if (msg.back() != '\n') {
     msg.push_back('\n');
   }
-  msg += "\n";
+  msg.push_back('\n');
   cmSystemTools::Stdout(msg.c_str(), msg.size());
 }
 
 void cmQtAutoGenerators::LogFileWarning(cmQtAutoGen::GeneratorType genType,
-                                        const std::string& filename,
-                                        const std::string& message) const
+                                        std::string const& filename,
+                                        std::string const& message) const
 {
-  std::string emsg = "  ";
-  emsg += cmQtAutoGen::Quoted(filename);
-  emsg += "\n";
+  std::string msg = "  ";
+  msg += cmQtAutoGen::Quoted(filename);
+  msg.push_back('\n');
   // Message
-  emsg += message;
-  this->LogWarning(genType, emsg);
+  msg += message;
+  this->LogWarning(genType, msg);
 }
 
 void cmQtAutoGenerators::LogError(cmQtAutoGen::GeneratorType genType,
-                                  const std::string& message) const
+                                  std::string const& message) const
 {
   std::string msg;
   msg.push_back('\n');
-  msg = cmQtAutoGen::GeneratorName(genType);
-  msg += " error:";
-  if (message.find('\n') == std::string::npos) {
-    // Single line message
-    msg.push_back(' ');
-  } else {
-    // Multi line message
-    msg.push_back('\n');
-  }
+  msg += HeadLine(cmQtAutoGen::GeneratorName(genType) + " error");
   // Message
   msg += message;
   if (msg.back() != '\n') {
     msg.push_back('\n');
   }
-  msg += "\n";
+  msg.push_back('\n');
   cmSystemTools::Stderr(msg.c_str(), msg.size());
 }
 
 void cmQtAutoGenerators::LogFileError(cmQtAutoGen::GeneratorType genType,
-                                      const std::string& filename,
-                                      const std::string& message) const
+                                      std::string const& filename,
+                                      std::string const& message) const
 {
   std::string emsg = "  ";
   emsg += cmQtAutoGen::Quoted(filename);
-  emsg += "\n";
+  emsg += '\n';
   // Message
   emsg += message;
   this->LogError(genType, emsg);
 }
 
-void cmQtAutoGenerators::LogNameCollisionError(
-  cmQtAutoGen::GeneratorType genType, const std::string& message,
-  const std::multimap<std::string, std::string>& collisions) const
-{
-  std::string emsg;
-  // Add message
-  if (!message.empty()) {
-    emsg += message;
-    if (emsg.back() != '\n') {
-      emsg.push_back('\n');
-    }
-  }
-  // Append collision list
-  for (auto const& item : collisions) {
-    emsg += "  ";
-    emsg += item.first;
-    emsg += " -> ";
-    emsg += item.second;
-    emsg += "\n";
-  }
-  this->LogError(genType, emsg);
-}
-
 void cmQtAutoGenerators::LogCommandError(
-  cmQtAutoGen::GeneratorType genType, const std::string& message,
-  const std::vector<std::string>& command, const std::string& output) const
+  cmQtAutoGen::GeneratorType genType, std::string const& message,
+  std::vector<std::string> const& command, std::string const& output) const
 {
   std::string msg;
   msg.push_back('\n');
-  msg += cmQtAutoGen::GeneratorName(genType);
-  msg += " subprocess error: ";
+  msg += HeadLine(cmQtAutoGen::GeneratorName(genType) + " subprocess error");
   msg += message;
   if (msg.back() != '\n') {
     msg.push_back('\n');
   }
   msg.push_back('\n');
-  msg += "Command\n";
-  msg += "-------\n";
+  msg += HeadLine("Command");
   msg += QuotedCommand(command);
   if (msg.back() != '\n') {
     msg.push_back('\n');
   }
   msg.push_back('\n');
-  msg += "Output\n";
-  msg += "------\n";
+  msg += HeadLine("Output");
   msg += output;
   if (msg.back() != '\n') {
     msg.push_back('\n');
   }
-  msg += "\n";
+  msg.push_back('\n');
   cmSystemTools::Stderr(msg.c_str(), msg.size());
 }
 
 /**
- * @brief Collects name collisions as output/input pairs
- * @return True if there were collisions
- */
-bool cmQtAutoGenerators::NameCollisionTest(
-  const std::map<std::string, std::string>& genFiles,
-  std::multimap<std::string, std::string>& collisions) const
-{
-  typedef std::map<std::string, std::string>::const_iterator Iter;
-  typedef std::map<std::string, std::string>::value_type VType;
-  for (Iter ait = genFiles.begin(); ait != genFiles.end(); ++ait) {
-    bool first_match(true);
-    for (Iter bit = (++Iter(ait)); bit != genFiles.end(); ++bit) {
-      if (ait->second == bit->second) {
-        if (first_match) {
-          if (collisions.find(ait->second) != collisions.end()) {
-            // We already know of this collision from before
-            break;
-          }
-          collisions.insert(VType(ait->second, ait->first));
-          first_match = false;
-        }
-        collisions.insert(VType(bit->second, bit->first));
-      }
-    }
-  }
-
-  return !collisions.empty();
-}
-
-/**
- * @brief Generates a file path based on the checksum of the source file path
- * @return The path
- */
-std::string cmQtAutoGenerators::ChecksumedPath(
-  const std::string& sourceFile, const std::string& basePrefix,
-  const std::string& baseSuffix) const
-{
-  std::string res = FPathChecksum.getPart(sourceFile);
-  res += "/";
-  res += basePrefix;
-  res += cmSystemTools::GetFilenameWithoutLastExtension(sourceFile);
-  res += baseSuffix;
-  return res;
-}
-
-/**
  * @brief Generates the parent directory of the given file on demand
  * @return True on success
  */
 bool cmQtAutoGenerators::MakeParentDirectory(
-  cmQtAutoGen::GeneratorType genType, const std::string& filename) const
+  cmQtAutoGen::GeneratorType genType, std::string const& filename) const
 {
   bool success = true;
-  const std::string dirName = cmSystemTools::GetFilenamePath(filename);
+  std::string const dirName = cmSystemTools::GetFilenamePath(filename);
   if (!dirName.empty()) {
-    success = cmSystemTools::MakeDirectory(dirName);
-    if (!success) {
+    if (!cmSystemTools::MakeDirectory(dirName)) {
       this->LogFileError(genType, filename,
                          "Could not create parent directory");
+      success = false;
     }
   }
   return success;
 }
 
-bool cmQtAutoGenerators::FileDiffers(const std::string& filename,
-                                     const std::string& content)
+bool cmQtAutoGenerators::FileDiffers(std::string const& filename,
+                                     std::string const& content)
 {
   bool differs = true;
   {
     std::string oldContents;
-    if (ReadAll(oldContents, filename)) {
+    if (ReadFile(oldContents, filename)) {
       differs = (oldContents != content);
     }
   }
@@ -1941,14 +2239,15 @@
 }
 
 bool cmQtAutoGenerators::FileWrite(cmQtAutoGen::GeneratorType genType,
-                                   const std::string& filename,
-                                   const std::string& content)
+                                   std::string const& filename,
+                                   std::string const& content)
 {
   std::string error;
   // Make sure the parent directory exists
   if (this->MakeParentDirectory(genType, filename)) {
     cmsys::ofstream outfile;
-    outfile.open(filename.c_str(), std::ios::trunc);
+    outfile.open(filename.c_str(),
+                 (std::ios::out | std::ios::binary | std::ios::trunc));
     if (outfile) {
       outfile << content;
       // Check for write errors
@@ -1970,7 +2269,7 @@
  * @brief Runs a command and returns true on success
  * @return True on success
  */
-bool cmQtAutoGenerators::RunCommand(const std::vector<std::string>& command,
+bool cmQtAutoGenerators::RunCommand(std::vector<std::string> const& command,
                                     std::string& output) const
 {
   // Log command
@@ -1992,7 +2291,7 @@
  * @return True on success
  */
 bool cmQtAutoGenerators::FindHeader(std::string& header,
-                                    const std::string& testBasePath) const
+                                    std::string const& testBasePath) const
 {
   for (std::string const& ext : this->HeaderExtensions) {
     std::string testFilePath(testBasePath);
@@ -2005,56 +2304,3 @@
   }
   return false;
 }
-
-std::string cmQtAutoGenerators::MocFindHeader(
-  const std::string& sourcePath, const std::string& includeBase) const
-{
-  std::string header;
-  // Search in vicinity of the source
-  if (!this->FindHeader(header, sourcePath + includeBase)) {
-    // Search in include directories
-    for (std::string const& path : this->MocIncludePaths) {
-      std::string fullPath = path;
-      fullPath.push_back('/');
-      fullPath += includeBase;
-      if (FindHeader(header, fullPath)) {
-        break;
-      }
-    }
-  }
-  // Sanitize
-  if (!header.empty()) {
-    header = cmSystemTools::GetRealPath(header);
-  }
-  return header;
-}
-
-bool cmQtAutoGenerators::MocFindIncludedFile(
-  std::string& absFile, const std::string& sourcePath,
-  const std::string& includeString) const
-{
-  bool success = false;
-  // Search in vicinity of the source
-  {
-    std::string testPath = sourcePath;
-    testPath += includeString;
-    if (cmSystemTools::FileExists(testPath.c_str())) {
-      absFile = cmSystemTools::GetRealPath(testPath);
-      success = true;
-    }
-  }
-  // Search in include directories
-  if (!success) {
-    for (std::string const& path : this->MocIncludePaths) {
-      std::string fullPath = path;
-      fullPath.push_back('/');
-      fullPath += includeString;
-      if (cmSystemTools::FileExists(fullPath.c_str())) {
-        absFile = cmSystemTools::GetRealPath(fullPath);
-        success = true;
-        break;
-      }
-    }
-  }
-  return success;
-}
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index 5d3ad74..0b502de 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -10,6 +10,7 @@
 #include "cmsys/RegularExpression.hxx"
 
 #include <map>
+#include <memory> // IWYU pragma: keep
 #include <set>
 #include <string>
 #include <vector>
@@ -21,7 +22,7 @@
   CM_DISABLE_COPY(cmQtAutoGenerators)
 public:
   cmQtAutoGenerators();
-  bool Run(const std::string& targetDirectory, const std::string& config);
+  bool Run(std::string const& targetDirectory, std::string const& config);
 
 private:
   // -- Types
@@ -37,7 +38,7 @@
     {
     }
 
-    KeyRegExp(const std::string& key, const std::string& regExp)
+    KeyRegExp(std::string const& key, std::string const& regExp)
       : Key(key)
       , RegExp(regExp)
     {
@@ -47,6 +48,38 @@
     cmsys::RegularExpression RegExp;
   };
 
+  /// @brief Source file job
+  struct SourceJob
+  {
+    bool Moc = false;
+    bool Uic = false;
+  };
+
+  /// @brief MOC job
+  struct MocJobAuto
+  {
+    std::string SourceFile;
+    std::string BuildFileRel;
+    std::set<std::string> Depends;
+  };
+
+  /// @brief MOC job
+  struct MocJobIncluded : MocJobAuto
+  {
+    bool DependsValid = false;
+    std::string Includer;
+    std::string IncludeString;
+  };
+
+  /// @brief UIC job
+  struct UicJob
+  {
+    std::string SourceFile;
+    std::string BuildFileRel;
+    std::string Includer;
+    std::string IncludeString;
+  };
+
   /// @brief RCC job
   struct RccJob
   {
@@ -56,149 +89,110 @@
     std::vector<std::string> Inputs;
   };
 
-  // -- Configuration
-  bool MocDependFilterPush(const std::string& key, const std::string& regExp);
-  bool ReadAutogenInfoFile(cmMakefile* makefile,
-                           const std::string& targetDirectory,
-                           const std::string& config);
-
-  bool MocEnabled() const { return !this->MocExecutable.empty(); }
-  bool UicEnabled() const { return !this->UicExecutable.empty(); }
-  bool RccEnabled() const { return !this->RccExecutable.empty(); }
+  // -- Initialization
+  bool InitInfoFile(cmMakefile* makefile, std::string const& targetDirectory,
+                    std::string const& config);
 
   // -- Settings file
   void SettingsFileRead(cmMakefile* makefile);
   bool SettingsFileWrite();
-
-  bool AnySettingsChanged() const
+  bool SettingsChanged() const
   {
     return (this->MocSettingsChanged || this->RccSettingsChanged ||
             this->UicSettingsChanged);
   }
 
-  // -- Init and run
-  void Init(cmMakefile* makefile);
-  bool RunAutogen();
+  // -- Central processing
+  bool Process();
 
-  // -- Content analysis
-  bool MocRequired(const std::string& contentText,
+  // -- Source parsing
+  bool ParseSourceFile(std::string const& absFilename, const SourceJob& job);
+  bool ParseHeaderFile(std::string const& absFilename, const SourceJob& job);
+  bool ParsePostprocess();
+
+  // -- Moc
+  bool MocEnabled() const { return !this->MocExecutable.empty(); }
+  bool MocSkip(std::string const& absFilename) const;
+  bool MocRequired(std::string const& contentText,
                    std::string* macroName = nullptr);
-  void MocFindDepends(
-    const std::string& absFilename, const std::string& contentText,
-    std::map<std::string, std::set<std::string>>& mocDepends);
+  // Moc strings
+  std::string MocStringMacros() const;
+  std::string MocStringHeaders(std::string const& fileBase) const;
+  std::string MocFindIncludedHeader(std::string const& sourcePath,
+                                    std::string const& includeBase) const;
+  bool MocFindIncludedFile(std::string& absFile, std::string const& sourceFile,
+                           std::string const& includeString) const;
+  // Moc depends
+  bool MocDependFilterPush(std::string const& key, std::string const& regExp);
+  void MocFindDepends(std::string const& absFilename,
+                      std::string const& contentText,
+                      std::set<std::string>& depends);
+  // Moc
+  bool MocParseSourceContent(std::string const& absFilename,
+                             std::string const& contentText);
+  void MocParseHeaderContent(std::string const& absFilename,
+                             std::string const& contentText);
 
-  bool MocSkip(const std::string& absFilename) const;
-  bool UicSkip(const std::string& absFilename) const;
+  bool MocGenerateAll();
+  bool MocGenerateFile(const MocJobAuto& mocJob, bool* generated = nullptr);
 
-  bool ParseSourceFile(
-    const std::string& absFilename,
-    std::map<std::string, std::string>& mocsIncluded,
-    std::map<std::string, std::set<std::string>>& mocDepends,
-    std::map<std::string, std::vector<std::string>>& includedUis,
-    bool relaxed);
+  // -- Uic
+  bool UicEnabled() const { return !this->UicExecutable.empty(); }
+  bool UicSkip(std::string const& absFilename) const;
+  bool UicParseContent(std::string const& fileName,
+                       std::string const& contentText);
+  bool UicFindIncludedFile(std::string& absFile, std::string const& sourceFile,
+                           std::string const& includeString);
+  bool UicGenerateAll();
+  bool UicGenerateFile(const UicJob& uicJob);
 
-  void SearchHeadersForSourceFile(const std::string& absFilename,
-                                  std::set<std::string>& mocHeaderFiles,
-                                  std::set<std::string>& uicHeaderFiles) const;
-
-  bool ParseHeaders(
-    const std::set<std::string>& mocHeaderFiles,
-    const std::set<std::string>& uicHeaderFiles,
-    const std::map<std::string, std::string>& mocsIncluded,
-    std::map<std::string, std::string>& mocsNotIncluded,
-    std::map<std::string, std::set<std::string>>& mocDepends,
-    std::map<std::string, std::vector<std::string>>& includedUis);
-
-  void UicParseContent(
-    const std::string& fileName, const std::string& contentText,
-    std::map<std::string, std::vector<std::string>>& includedUis);
-
-  std::string MocMacroNamesString() const;
-  std::string MocHeaderSuffixesString() const;
-
-  bool MocParseSourceContent(
-    const std::string& absFilename, const std::string& contentText,
-    std::map<std::string, std::string>& mocsIncluded,
-    std::map<std::string, std::set<std::string>>& mocDepends, bool relaxed);
-
-  void MocParseHeaderContent(
-    const std::string& absFilename, const std::string& contentText,
-    std::map<std::string, std::string>& mocsNotIncluded,
-    std::map<std::string, std::set<std::string>>& mocDepends);
-
-  // -- Moc file generation
-  bool MocGenerateAll(
-    const std::map<std::string, std::string>& mocsIncluded,
-    const std::map<std::string, std::string>& mocsNotIncluded,
-    const std::map<std::string, std::set<std::string>>& mocDepends);
-  bool MocGenerateFile(
-    const std::string& sourceFile, const std::string& mocFileName,
-    const std::map<std::string, std::set<std::string>>& mocDepends,
-    bool included);
-
-  // -- Uic file generation
-  bool UicFindIncludedFile(std::string& absFile, const std::string& sourceFile,
-                           const std::string& searchPath,
-                           const std::string& searchFile);
-  bool UicGenerateAll(
-    const std::map<std::string, std::vector<std::string>>& includedUis);
-  bool UicGenerateFile(const std::string& realName,
-                       const std::string& uiInputFile,
-                       const std::string& uiOutputFile);
-
-  // -- Rcc file generation
+  // -- Rcc
+  bool RccEnabled() const { return !this->RccExecutable.empty(); }
   bool RccGenerateAll();
   bool RccGenerateFile(const RccJob& rccJob);
 
   // -- Log info
-  void LogBold(const std::string& message) const;
+  void LogBold(std::string const& message) const;
   void LogInfo(cmQtAutoGen::GeneratorType genType,
-               const std::string& message) const;
+               std::string const& message) const;
   // -- Log warning
   void LogWarning(cmQtAutoGen::GeneratorType genType,
-                  const std::string& message) const;
+                  std::string const& message) const;
   void LogFileWarning(cmQtAutoGen::GeneratorType genType,
-                      const std::string& filename,
-                      const std::string& message) const;
+                      std::string const& filename,
+                      std::string const& message) const;
   // -- Log error
   void LogError(cmQtAutoGen::GeneratorType genType,
-                const std::string& message) const;
+                std::string const& message) const;
   void LogFileError(cmQtAutoGen::GeneratorType genType,
-                    const std::string& filename,
-                    const std::string& message) const;
+                    std::string const& filename,
+                    std::string const& message) const;
   void LogCommandError(cmQtAutoGen::GeneratorType genType,
-                       const std::string& message,
-                       const std::vector<std::string>& command,
-                       const std::string& output) const;
-  void LogNameCollisionError(
-    cmQtAutoGen::GeneratorType genType, const std::string& message,
-    const std::multimap<std::string, std::string>& collisions) const;
+                       std::string const& message,
+                       std::vector<std::string> const& command,
+                       std::string const& output) const;
 
   // -- Utility
-  bool NameCollisionTest(
-    const std::map<std::string, std::string>& genFiles,
-    std::multimap<std::string, std::string>& collisions) const;
-  std::string ChecksumedPath(const std::string& sourceFile,
-                             const std::string& basePrefix,
-                             const std::string& baseSuffix) const;
   bool MakeParentDirectory(cmQtAutoGen::GeneratorType genType,
-                           const std::string& filename) const;
-  bool FileDiffers(const std::string& filename, const std::string& content);
+                           std::string const& filename) const;
+  bool FileDiffers(std::string const& filename, std::string const& content);
   bool FileWrite(cmQtAutoGen::GeneratorType genType,
-                 const std::string& filename, const std::string& content);
-
-  bool RunCommand(const std::vector<std::string>& command,
+                 std::string const& filename, std::string const& content);
+  bool FindHeader(std::string& header, std::string const& testBasePath) const;
+  bool RunCommand(std::vector<std::string> const& command,
                   std::string& output) const;
 
-  bool FindHeader(std::string& header, const std::string& testBasePath) const;
-
-  std::string MocFindHeader(const std::string& sourcePath,
-                            const std::string& includeBase) const;
-  bool MocFindIncludedFile(std::string& absFile, const std::string& sourceFile,
-                           const std::string& includeString) const;
-
   // -- Meta
   std::string ConfigSuffix;
+  std::string InfoFile;
+  // -- Settings
+  bool IncludeProjectDirsBefore;
+  bool Verbose;
+  bool ColorOutput;
+  std::string SettingsFile;
+  std::string SettingsStringMoc;
+  std::string SettingsStringUic;
+  std::string SettingsStringRcc;
   // -- Directories
   std::string ProjectSourceDir;
   std::string ProjectBinaryDir;
@@ -213,23 +207,14 @@
   std::string UicExecutable;
   std::string RccExecutable;
   // -- File lists
-  std::vector<std::string> Sources;
-  std::vector<std::string> Headers;
+  std::map<std::string, SourceJob> HeaderJobs;
+  std::map<std::string, SourceJob> SourceJobs;
   std::vector<std::string> HeaderExtensions;
-  cmFilePathChecksum FPathChecksum;
-  // -- Settings
-  bool IncludeProjectDirsBefore;
-  bool Verbose;
-  bool ColorOutput;
-  std::string SettingsFile;
-  std::string SettingsStringMoc;
-  std::string SettingsStringUic;
-  std::string SettingsStringRcc;
+  cmFilePathChecksum FilePathChecksum;
   // -- Moc
   bool MocSettingsChanged;
   bool MocPredefsChanged;
   bool MocRelaxedMode;
-  bool MocRunFailed;
   std::string MocCompFileRel;
   std::string MocCompFileAbs;
   std::string MocPredefsFileRel;
@@ -239,21 +224,23 @@
   std::vector<std::string> MocIncludes;
   std::vector<std::string> MocDefinitions;
   std::vector<std::string> MocOptions;
+  std::vector<std::string> MocAllOptions;
   std::vector<std::string> MocPredefsCmd;
   std::vector<KeyRegExp> MocDependFilters;
   std::vector<KeyRegExp> MocMacroFilters;
   cmsys::RegularExpression MocRegExpInclude;
+  std::vector<std::unique_ptr<MocJobIncluded>> MocJobsIncluded;
+  std::vector<std::unique_ptr<MocJobAuto>> MocJobsAuto;
   // -- Uic
   bool UicSettingsChanged;
-  bool UicRunFailed;
   std::vector<std::string> UicSkipList;
   std::vector<std::string> UicTargetOptions;
   std::map<std::string, std::vector<std::string>> UicOptions;
   std::vector<std::string> UicSearchPaths;
   cmsys::RegularExpression UicRegExpInclude;
+  std::vector<std::unique_ptr<UicJob>> UicJobs;
   // -- Rcc
   bool RccSettingsChanged;
-  bool RccRunFailed;
   std::vector<RccJob> RccJobs;
 };
 
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 783e308..112be4d 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -86,7 +86,7 @@
         if (line[0] != '#') {
           this->ProcessLine(line.substr(0, pos));
         }
-        rst = "";
+        rst.clear();
         this->Reset();
         this->OutputLinePending = true;
       }
@@ -101,7 +101,7 @@
           this->ProcessLine(line.substr(2));
           continue;
         }
-        rst = "";
+        rst.clear();
         this->Reset();
         this->OutputLinePending = true;
       }
@@ -345,7 +345,7 @@
   // Record markup lines as replacement text.
   std::string& replacement = this->Replace[this->ReplaceName];
   replacement += cmJoin(this->MarkupLines, " ");
-  this->ReplaceName = "";
+  this->ReplaceName.clear();
 }
 
 void cmRST::ProcessDirectiveTocTree()
diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h
index 9e035d7..7b11849 100644
--- a/Source/cmRemoveCommand.h
+++ b/Source/cmRemoveCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmRemoveCommand; }
+  cmCommand* Clone() override { return new cmRemoveCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h
index c2c6b0e..a5cb204 100644
--- a/Source/cmRemoveDefinitionsCommand.h
+++ b/Source/cmRemoveDefinitionsCommand.h
@@ -25,14 +25,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmRemoveDefinitionsCommand; }
+  cmCommand* Clone() override { return new cmRemoveDefinitionsCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h
index 53c91cd..ef39614 100644
--- a/Source/cmReturnCommand.h
+++ b/Source/cmReturnCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmReturnCommand; }
+  cmCommand* Clone() override { return new cmReturnCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx
index 5346b77..2cae714 100644
--- a/Source/cmScriptGenerator.cxx
+++ b/Source/cmScriptGenerator.cxx
@@ -26,7 +26,7 @@
   this->ConfigurationName = config;
   this->ConfigurationTypes = &configurationTypes;
   this->GenerateScript(os);
-  this->ConfigurationName = "";
+  this->ConfigurationName.clear();
   this->ConfigurationTypes = nullptr;
 }
 
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index 26c0de2..a40c987 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -172,7 +172,7 @@
   } else if (this->FC->CMakePathName == "LIBRARY") {
     subdir = "lib";
   } else if (this->FC->CMakePathName == "FRAMEWORK") {
-    subdir = ""; // ? what to do for frameworks ?
+    subdir.clear(); // ? what to do for frameworks ?
   }
 
   for (std::string const& path : paths) {
diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h
index 2d4c7cd..988ad23 100644
--- a/Source/cmSeparateArgumentsCommand.h
+++ b/Source/cmSeparateArgumentsCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmSeparateArgumentsCommand; }
+  cmCommand* Clone() override { return new cmSeparateArgumentsCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index 30d0f51..e923c22 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -84,7 +84,7 @@
   const cmServerRequest request(this, connection, value[kTYPE_KEY].asString(),
                                 value[kCOOKIE_KEY].asString(), value);
 
-  if (request.Type == "") {
+  if (request.Type.empty()) {
     cmServerResponse response(request);
     response.SetError("No type given in request.");
     this->WriteResponse(connection, response, nullptr);
diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h
index 3faec6f..76e3eae 100644
--- a/Source/cmSetCommand.h
+++ b/Source/cmSetCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmSetCommand; }
+  cmCommand* Clone() override { return new cmSetCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h
index 16a07da..473347c 100644
--- a/Source/cmSetDirectoryPropertiesCommand.h
+++ b/Source/cmSetDirectoryPropertiesCommand.h
@@ -16,17 +16,14 @@
 class cmSetDirectoryPropertiesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE
-  {
-    return new cmSetDirectoryPropertiesCommand;
-  }
+  cmCommand* Clone() override { return new cmSetDirectoryPropertiesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   /**
    * Static entry point for use by other commands
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index 4d3d996..f1126bb 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -22,14 +22,14 @@
 public:
   cmSetPropertyCommand();
 
-  cmCommand* Clone() CM_OVERRIDE { return new cmSetPropertyCommand; }
+  cmCommand* Clone() override { return new cmSetPropertyCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   std::set<std::string> Names;
diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h
index ca3d74d..afb19f6 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.h
+++ b/Source/cmSetSourceFilesPropertiesCommand.h
@@ -16,17 +16,14 @@
 class cmSetSourceFilesPropertiesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE
-  {
-    return new cmSetSourceFilesPropertiesCommand;
-  }
+  cmCommand* Clone() override { return new cmSetSourceFilesPropertiesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   static bool RunCommand(cmMakefile* mf,
                          std::vector<std::string>::const_iterator filebeg,
diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h
index de20a7b..c9755da 100644
--- a/Source/cmSetTargetPropertiesCommand.h
+++ b/Source/cmSetTargetPropertiesCommand.h
@@ -16,14 +16,14 @@
 class cmSetTargetPropertiesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmSetTargetPropertiesCommand; }
+  cmCommand* Clone() override { return new cmSetTargetPropertiesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   /**
    *  Used by this command and cmSetPropertiesCommand
diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h
index cd9f486..84b2645 100644
--- a/Source/cmSetTestsPropertiesCommand.h
+++ b/Source/cmSetTestsPropertiesCommand.h
@@ -16,14 +16,14 @@
 class cmSetTestsPropertiesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmSetTestsPropertiesCommand; }
+  cmCommand* Clone() override { return new cmSetTestsPropertiesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the input file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   static bool SetOneTest(const std::string& tname,
                          std::vector<std::string>& propertyPairs,
diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h
index c042a13..2d8dc17 100644
--- a/Source/cmSiteNameCommand.h
+++ b/Source/cmSiteNameCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmSiteNameCommand; }
+  cmCommand* Clone() override { return new cmSiteNameCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 727adeb..4f337f2 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -28,21 +28,6 @@
   this->Name = loc.Name;
 }
 
-cmSourceFileLocation& cmSourceFileLocation::operator=(
-  const cmSourceFileLocation& loc)
-{
-  if (this == &loc) {
-    return *this;
-  }
-  this->Makefile = loc.Makefile;
-  this->AmbiguousDirectory = loc.AmbiguousDirectory;
-  this->AmbiguousExtension = loc.AmbiguousExtension;
-  this->Directory = loc.Directory;
-  this->Name = loc.Name;
-  this->UpdateExtension(this->Name);
-  return *this;
-}
-
 cmSourceFileLocation::cmSourceFileLocation(cmMakefile const* mf,
                                            const std::string& name)
   : Makefile(mf)
diff --git a/Source/cmSourceFileLocation.h b/Source/cmSourceFileLocation.h
index 6dbc2da..fb5b330 100644
--- a/Source/cmSourceFileLocation.h
+++ b/Source/cmSourceFileLocation.h
@@ -29,7 +29,6 @@
   cmSourceFileLocation(cmMakefile const* mf, const std::string& name);
   cmSourceFileLocation();
   cmSourceFileLocation(const cmSourceFileLocation& loc);
-  cmSourceFileLocation& operator=(const cmSourceFileLocation& loc);
 
   /**
    * Return whether the given source file location could refers to the
@@ -79,7 +78,7 @@
    */
   cmMakefile const* GetMakefile() const { return this->Makefile; }
 private:
-  cmMakefile const* Makefile;
+  cmMakefile const* const Makefile;
   bool AmbiguousDirectory;
   bool AmbiguousExtension;
   std::string Directory;
@@ -90,6 +89,9 @@
   // Update the location with additional knowledge.
   void Update(cmSourceFileLocation const& loc);
   void UpdateExtension(const std::string& name);
+
+  cmSourceFileLocation& operator=(const cmSourceFileLocation& loc)
+    CM_EQ_DELETE;
 };
 
 #endif
diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h
index 1af5274..ed02ca5 100644
--- a/Source/cmSourceGroupCommand.h
+++ b/Source/cmSourceGroupCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmSourceGroupCommand; }
+  cmCommand* Clone() override { return new cmSourceGroupCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   bool processTree(const std::vector<std::string>& args,
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 418f051..5aa8e5b 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -80,7 +80,7 @@
   if (result.size() < 2 || result.substr(0, 2) != "//") {
     this->DirectoryState->RelativePathTopBinary = result;
   } else {
-    this->DirectoryState->RelativePathTopBinary = "";
+    this->DirectoryState->RelativePathTopBinary.clear();
   }
 }
 
@@ -422,7 +422,7 @@
                                           bool chain) const
 {
   static std::string output;
-  output = "";
+  output.clear();
   if (prop == "PARENT_DIRECTORY") {
     cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent();
     if (parent.IsValid()) {
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index f19f871..b287e37 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -22,14 +22,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmStringCommand; }
+  cmCommand* Clone() override { return new cmStringCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 protected:
   bool HandleConfigureCommand(std::vector<std::string> const& args);
diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h
index e5fbb7d..adab757 100644
--- a/Source/cmSubdirCommand.h
+++ b/Source/cmSubdirCommand.h
@@ -25,14 +25,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmSubdirCommand; }
+  cmCommand* Clone() override { return new cmSubdirCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h
index bcda82e..2db28c6 100644
--- a/Source/cmSubdirDependsCommand.h
+++ b/Source/cmSubdirDependsCommand.h
@@ -15,9 +15,9 @@
 class cmSubdirDependsCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmSubdirDependsCommand; }
+  cmCommand* Clone() override { return new cmSubdirDependsCommand; }
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 4118664..58adc43 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -458,7 +458,7 @@
           arg.append(1, *c);
         } else if (in_argument) {
           args.push_back(arg);
-          arg = "";
+          arg.clear();
           in_argument = false;
         }
       } else {
@@ -559,7 +559,7 @@
     while (*c == ' ' || *c == '\t') {
       ++c;
     }
-    arg = "";
+    arg.clear();
     if (*c == '"') {
       // Parse a quoted argument.
       ++c;
@@ -1184,7 +1184,7 @@
           if (!newArg.empty() || emptyArgs) {
             // Add the last argument if the string is not empty.
             newargs.push_back(newArg);
-            newArg = "";
+            newArg.clear();
           }
         }
       } break;
@@ -1375,7 +1375,7 @@
   if (fileComponents.empty()) {
     return dir;
   }
-  if (fileComponents[0] != "") {
+  if (!fileComponents[0].empty()) {
     // File is not a relative path.
     return file;
   }
@@ -1771,7 +1771,7 @@
                                double timeout, std::vector<char>& out,
                                std::vector<char>& err)
 {
-  line = "";
+  line.clear();
   std::vector<char>::iterator outiter = out.begin();
   std::vector<char>::iterator erriter = err.begin();
   cmProcessOutput processOutput;
@@ -2111,19 +2111,19 @@
   cmSystemToolsCMakeGUICommand += "/cmake-gui";
   cmSystemToolsCMakeGUICommand += cmSystemTools::GetExecutableExtension();
   if (!cmSystemTools::FileExists(cmSystemToolsCMakeGUICommand.c_str())) {
-    cmSystemToolsCMakeGUICommand = "";
+    cmSystemToolsCMakeGUICommand.clear();
   }
   cmSystemToolsCMakeCursesCommand = exe_dir;
   cmSystemToolsCMakeCursesCommand += "/ccmake";
   cmSystemToolsCMakeCursesCommand += cmSystemTools::GetExecutableExtension();
   if (!cmSystemTools::FileExists(cmSystemToolsCMakeCursesCommand.c_str())) {
-    cmSystemToolsCMakeCursesCommand = "";
+    cmSystemToolsCMakeCursesCommand.clear();
   }
   cmSystemToolsCMClDepsCommand = exe_dir;
   cmSystemToolsCMClDepsCommand += "/cmcldeps";
   cmSystemToolsCMClDepsCommand += cmSystemTools::GetExecutableExtension();
   if (!cmSystemTools::FileExists(cmSystemToolsCMClDepsCommand.c_str())) {
-    cmSystemToolsCMClDepsCommand = "";
+    cmSystemToolsCMClDepsCommand.clear();
   }
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 8d21e68..49b0664 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5,6 +5,7 @@
 #include "cmsys/RegularExpression.hxx"
 #include <algorithm>
 #include <assert.h>
+#include <iterator>
 #include <map>
 #include <set>
 #include <sstream>
@@ -592,8 +593,9 @@
   {
     std::vector<std::string> files;
     cmSystemTools::ExpandListArgument(entry, files);
-    std::vector<cmSourceFileLocation> locations(files.size());
-    std::transform(files.begin(), files.end(), locations.begin(),
+    std::vector<cmSourceFileLocation> locations;
+    locations.reserve(files.size());
+    std::transform(files.begin(), files.end(), std::back_inserter(locations),
                    CreateLocation(this->Needle.GetMakefile()));
 
     return std::find_if(locations.begin(), locations.end(),
@@ -1530,7 +1532,7 @@
       }
       // If it was found, set the suffix.
       if (*loc || *imp) {
-        suffix = "";
+        suffix.clear();
       }
     } else {
       std::string mcUpper = cmSystemTools::UpperCase(*mci);
@@ -1577,7 +1579,7 @@
   // configurations and no exact match.
   if (!*loc && !*imp) {
     // The suffix computed above is not useful.
-    suffix = "";
+    suffix.clear();
 
     // Look for a configuration-less location.  This may be set by
     // manually-written code.
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index 957123a..f910452 100644
--- a/Source/cmTargetCompileDefinitionsCommand.h
+++ b/Source/cmTargetCompileDefinitionsCommand.h
@@ -20,26 +20,23 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
-  {
-    return new cmTargetCompileDefinitionsCommand;
-  }
+  cmCommand* Clone() override { return new cmTargetCompileDefinitionsCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
-  void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
-  void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
+  void HandleImportedTarget(const std::string& tgt) override;
+  void HandleMissingTarget(const std::string& name) override;
 
   bool HandleDirectContent(cmTarget* tgt,
                            const std::vector<std::string>& content,
-                           bool prepend, bool system) CM_OVERRIDE;
-  std::string Join(const std::vector<std::string>& content) CM_OVERRIDE;
+                           bool prepend, bool system) override;
+  std::string Join(const std::vector<std::string>& content) override;
 };
 
 #endif
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
index d28cf62..444d260 100644
--- a/Source/cmTargetCompileFeaturesCommand.h
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -16,19 +16,19 @@
 
 class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
 {
-  cmCommand* Clone() CM_OVERRIDE { return new cmTargetCompileFeaturesCommand; }
+  cmCommand* Clone() override { return new cmTargetCompileFeaturesCommand; }
 
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
-  void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
-  void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
+  void HandleImportedTarget(const std::string& tgt) override;
+  void HandleMissingTarget(const std::string& name) override;
 
   bool HandleDirectContent(cmTarget* tgt,
                            const std::vector<std::string>& content,
-                           bool prepend, bool system) CM_OVERRIDE;
-  std::string Join(const std::vector<std::string>& content) CM_OVERRIDE;
+                           bool prepend, bool system) override;
+  std::string Join(const std::vector<std::string>& content) override;
 };
 
 #endif
diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h
index 7786896..3fab238 100644
--- a/Source/cmTargetCompileOptionsCommand.h
+++ b/Source/cmTargetCompileOptionsCommand.h
@@ -20,23 +20,23 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmTargetCompileOptionsCommand; }
+  cmCommand* Clone() override { return new cmTargetCompileOptionsCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
-  void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
-  void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
+  void HandleImportedTarget(const std::string& tgt) override;
+  void HandleMissingTarget(const std::string& name) override;
 
   bool HandleDirectContent(cmTarget* tgt,
                            const std::vector<std::string>& content,
-                           bool prepend, bool system) CM_OVERRIDE;
-  std::string Join(const std::vector<std::string>& content) CM_OVERRIDE;
+                           bool prepend, bool system) override;
+  std::string Join(const std::vector<std::string>& content) override;
 };
 
 #endif
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index 96eedc8..27a2f43 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -20,30 +20,27 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE
-  {
-    return new cmTargetIncludeDirectoriesCommand;
-  }
+  cmCommand* Clone() override { return new cmTargetIncludeDirectoriesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
-  void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
-  void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
+  void HandleImportedTarget(const std::string& tgt) override;
+  void HandleMissingTarget(const std::string& name) override;
 
   bool HandleDirectContent(cmTarget* tgt,
                            const std::vector<std::string>& content,
-                           bool prepend, bool system) CM_OVERRIDE;
+                           bool prepend, bool system) override;
   void HandleInterfaceContent(cmTarget* tgt,
                               const std::vector<std::string>& content,
-                              bool prepend, bool system) CM_OVERRIDE;
+                              bool prepend, bool system) override;
 
-  std::string Join(const std::vector<std::string>& content) CM_OVERRIDE;
+  std::string Join(const std::vector<std::string>& content) override;
 };
 
 #endif
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index 333ab07..f41af49 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -27,14 +27,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmTargetLinkLibrariesCommand; }
+  cmCommand* Clone() override { return new cmTargetLinkLibrariesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   void LinkLibraryTypeSpecifierWarning(int left, int right);
diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h
index b4e08e4..0639e98 100644
--- a/Source/cmTargetSourcesCommand.h
+++ b/Source/cmTargetSourcesCommand.h
@@ -20,24 +20,24 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmTargetSourcesCommand; }
+  cmCommand* Clone() override { return new cmTargetSourcesCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
-  void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
-  void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
+  void HandleImportedTarget(const std::string& tgt) override;
+  void HandleMissingTarget(const std::string& name) override;
 
   bool HandleDirectContent(cmTarget* tgt,
                            const std::vector<std::string>& content,
-                           bool prepend, bool system) CM_OVERRIDE;
+                           bool prepend, bool system) override;
 
-  std::string Join(const std::vector<std::string>& content) CM_OVERRIDE;
+  std::string Join(const std::vector<std::string>& content) override;
 };
 
 #endif
diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h
index ab0f635..1ca61c2 100644
--- a/Source/cmTestGenerator.h
+++ b/Source/cmTestGenerator.h
@@ -26,17 +26,17 @@
   cmTestGenerator(cmTest* test,
                   std::vector<std::string> const& configurations =
                     std::vector<std::string>());
-  ~cmTestGenerator() CM_OVERRIDE;
+  ~cmTestGenerator() override;
 
   void Compute(cmLocalGenerator* lg);
 
 protected:
-  void GenerateScriptConfigs(std::ostream& os, Indent indent) CM_OVERRIDE;
-  void GenerateScriptActions(std::ostream& os, Indent indent) CM_OVERRIDE;
+  void GenerateScriptConfigs(std::ostream& os, Indent indent) override;
+  void GenerateScriptActions(std::ostream& os, Indent indent) override;
   void GenerateScriptForConfig(std::ostream& os, const std::string& config,
-                               Indent indent) CM_OVERRIDE;
-  void GenerateScriptNoConfig(std::ostream& os, Indent indent) CM_OVERRIDE;
-  bool NeedsScriptNoConfig() const CM_OVERRIDE;
+                               Indent indent) override;
+  void GenerateScriptNoConfig(std::ostream& os, Indent indent) override;
+  bool NeedsScriptNoConfig() const override;
   void GenerateOldStyle(std::ostream& os, Indent indent);
 
   cmLocalGenerator* LG;
diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h
index b1f0da9..fbe0d78 100644
--- a/Source/cmTryCompileCommand.h
+++ b/Source/cmTryCompileCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmTryCompileCommand; }
+  cmCommand* Clone() override { return new cmTryCompileCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index cc93b03..dcaa493 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -33,11 +33,11 @@
   // build an arg list for TryCompile and extract the runArgs,
   std::vector<std::string> tryCompile;
 
-  this->CompileResultVariable = "";
-  this->RunResultVariable = "";
-  this->OutputVariable = "";
-  this->RunOutputVariable = "";
-  this->CompileOutputVariable = "";
+  this->CompileResultVariable.clear();
+  this->RunResultVariable.clear();
+  this->OutputVariable.clear();
+  this->RunOutputVariable.clear();
+  this->CompileOutputVariable.clear();
 
   std::string runArgs;
   unsigned int i;
diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h
index 732dff1..b632ef5 100644
--- a/Source/cmTryRunCommand.h
+++ b/Source/cmTryRunCommand.h
@@ -24,14 +24,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmTryRunCommand; }
+  cmCommand* Clone() override { return new cmTryRunCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   void RunExecutable(const std::string& runArgs,
diff --git a/Source/cmUnexpectedCommand.h b/Source/cmUnexpectedCommand.h
index 5e3ac74..7154881 100644
--- a/Source/cmUnexpectedCommand.h
+++ b/Source/cmUnexpectedCommand.h
@@ -21,13 +21,13 @@
   {
   }
 
-  cmCommand* Clone() CM_OVERRIDE
+  cmCommand* Clone() override
   {
     return new cmUnexpectedCommand(this->Name, this->Error);
   }
 
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 private:
   std::string Name;
diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h
index 96d7010..4e1208a 100644
--- a/Source/cmUnsetCommand.h
+++ b/Source/cmUnsetCommand.h
@@ -23,14 +23,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmUnsetCommand; }
+  cmCommand* Clone() override { return new cmUnsetCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h
index 86ebbf1..78f8616 100644
--- a/Source/cmUseMangledMesaCommand.h
+++ b/Source/cmUseMangledMesaCommand.h
@@ -15,9 +15,9 @@
 class cmUseMangledMesaCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmUseMangledMesaCommand; }
+  cmCommand* Clone() override { return new cmUseMangledMesaCommand; }
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
 protected:
   void CopyAndFullPathMesaHeader(const char* source, const char* outdir);
diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h
index 404ef3e..165ecef 100644
--- a/Source/cmUtilitySourceCommand.h
+++ b/Source/cmUtilitySourceCommand.h
@@ -15,9 +15,9 @@
 class cmUtilitySourceCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmUtilitySourceCommand; }
+  cmCommand* Clone() override { return new cmUtilitySourceCommand; }
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmVS10LinkFlagTable.h b/Source/cmVS10LinkFlagTable.h
index c30ea9a..6a0313a 100644
--- a/Source/cmVS10LinkFlagTable.h
+++ b/Source/cmVS10LinkFlagTable.h
@@ -29,6 +29,8 @@
   { "CreateHotPatchableImage", "FUNCTIONPADMIN:16", "Itanium Image Only",
     "ItaniumImage", 0 },
 
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACExecutionLevel", "level='asInvoker'", "asInvoker", "AsInvoker", 0 },
   { "UACExecutionLevel", "level='highestAvailable'", "highestAvailable",
     "HighestAvailable", 0 },
@@ -123,8 +125,12 @@
   { "GenerateManifest", "MANIFEST:NO", "", "false", 0 },
   { "GenerateManifest", "MANIFEST", "", "true", 0 },
   { "AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0 },
+
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACUIAccess", "uiAccess='false'", "", "false", 0 },
   { "UACUIAccess", "uiAccess='true'", "", "true", 0 },
+
   { "GenerateDebugInformation", "DEBUG", "", "true",
     cmVS7FlagTable::CaseInsensitive },
   { "MapExports", "MAPINFO:EXPORTS", "", "true", 0 },
@@ -162,11 +168,8 @@
   { "LinkDLL", "DLL", "", "true", 0 },
 
   // Bool Properties With Argument
-  { "EnableUAC", "MANIFESTUAC:NO", "", "false", 0 },
-  { "EnableUAC", "MANIFESTUAC:", "", "true",
-    cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
-  { "UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
-    cmVS7FlagTable::UserValueRequired },
+  { "EnableUAC", "MANIFESTUAC:", "", "",
+    cmVS7FlagTable::UserValueRequired | cmVS7FlagTable::SpaceAppendable },
   { "GenerateMapFile", "MAP", "", "true",
     cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
   { "MapFileName", "MAP:", "Generate Map File", "",
diff --git a/Source/cmVS11LinkFlagTable.h b/Source/cmVS11LinkFlagTable.h
index 1b3a046..24ba8fd 100644
--- a/Source/cmVS11LinkFlagTable.h
+++ b/Source/cmVS11LinkFlagTable.h
@@ -29,6 +29,8 @@
   { "CreateHotPatchableImage", "FUNCTIONPADMIN:16", "Itanium Image Only",
     "ItaniumImage", 0 },
 
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACExecutionLevel", "level='asInvoker'", "asInvoker", "AsInvoker", 0 },
   { "UACExecutionLevel", "level='highestAvailable'", "highestAvailable",
     "HighestAvailable", 0 },
@@ -135,8 +137,12 @@
   { "GenerateManifest", "MANIFEST:NO", "", "false", 0 },
   { "GenerateManifest", "MANIFEST", "", "true", 0 },
   { "AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0 },
+
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACUIAccess", "uiAccess='false'", "", "false", 0 },
   { "UACUIAccess", "uiAccess='true'", "", "true", 0 },
+
   { "ManifestEmbed", "manifest:embed", "", "true", 0 },
   { "GenerateDebugInformation", "DEBUG", "", "true",
     cmVS7FlagTable::CaseInsensitive },
@@ -179,11 +185,8 @@
   { "LinkDLL", "DLL", "", "true", 0 },
 
   // Bool Properties With Argument
-  { "EnableUAC", "MANIFESTUAC:NO", "", "false", 0 },
-  { "EnableUAC", "MANIFESTUAC:", "", "true",
-    cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
-  { "UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
-    cmVS7FlagTable::UserValueRequired },
+  { "EnableUAC", "MANIFESTUAC:", "", "",
+    cmVS7FlagTable::UserValueRequired | cmVS7FlagTable::SpaceAppendable },
   { "GenerateMapFile", "MAP", "", "true",
     cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
   { "MapFileName", "MAP:", "Generate Map File", "",
diff --git a/Source/cmVS12LinkFlagTable.h b/Source/cmVS12LinkFlagTable.h
index 168c34c..fc667c3 100644
--- a/Source/cmVS12LinkFlagTable.h
+++ b/Source/cmVS12LinkFlagTable.h
@@ -29,6 +29,8 @@
   { "CreateHotPatchableImage", "FUNCTIONPADMIN:16", "Itanium Image Only",
     "ItaniumImage", 0 },
 
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACExecutionLevel", "level='asInvoker'", "asInvoker", "AsInvoker", 0 },
   { "UACExecutionLevel", "level='highestAvailable'", "highestAvailable",
     "HighestAvailable", 0 },
@@ -135,8 +137,12 @@
   { "GenerateManifest", "MANIFEST:NO", "", "false", 0 },
   { "GenerateManifest", "MANIFEST", "", "true", 0 },
   { "AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0 },
+
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACUIAccess", "uiAccess='false'", "", "false", 0 },
   { "UACUIAccess", "uiAccess='true'", "", "true", 0 },
+
   { "ManifestEmbed", "manifest:embed", "", "true", 0 },
   { "GenerateDebugInformation", "DEBUG", "", "true",
     cmVS7FlagTable::CaseInsensitive },
@@ -179,11 +185,8 @@
   { "LinkDLL", "DLL", "", "true", 0 },
 
   // Bool Properties With Argument
-  { "EnableUAC", "MANIFESTUAC:NO", "", "false", 0 },
-  { "EnableUAC", "MANIFESTUAC:", "", "true",
-    cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
-  { "UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
-    cmVS7FlagTable::UserValueRequired },
+  { "EnableUAC", "MANIFESTUAC:", "", "",
+    cmVS7FlagTable::UserValueRequired | cmVS7FlagTable::SpaceAppendable },
   { "GenerateMapFile", "MAP", "", "true",
     cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
   { "MapFileName", "MAP:", "Generate Map File", "",
diff --git a/Source/cmVS140LinkFlagTable.h b/Source/cmVS140LinkFlagTable.h
index b9a4dc3..7c9452a 100644
--- a/Source/cmVS140LinkFlagTable.h
+++ b/Source/cmVS140LinkFlagTable.h
@@ -29,6 +29,8 @@
   { "CreateHotPatchableImage", "FUNCTIONPADMIN:16", "Itanium Image Only",
     "ItaniumImage", 0 },
 
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACExecutionLevel", "level='asInvoker'", "asInvoker", "AsInvoker", 0 },
   { "UACExecutionLevel", "level='highestAvailable'", "highestAvailable",
     "HighestAvailable", 0 },
@@ -148,8 +150,12 @@
   { "GenerateManifest", "MANIFEST:NO", "", "false", 0 },
   { "GenerateManifest", "MANIFEST", "", "true", 0 },
   { "AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0 },
+
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACUIAccess", "uiAccess='false'", "", "false", 0 },
   { "UACUIAccess", "uiAccess='true'", "", "true", 0 },
+
   { "ManifestEmbed", "manifest:embed", "", "true", 0 },
   { "MapExports", "MAPINFO:EXPORTS", "", "true", 0 },
   { "AssemblyDebug", "ASSEMBLYDEBUG:DISABLE", "", "false", 0 },
@@ -190,11 +196,8 @@
   { "LinkDLL", "DLL", "", "true", 0 },
 
   // Bool Properties With Argument
-  { "EnableUAC", "MANIFESTUAC:NO", "", "false", 0 },
-  { "EnableUAC", "MANIFESTUAC:", "", "true",
-    cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
-  { "UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
-    cmVS7FlagTable::UserValueRequired },
+  { "EnableUAC", "MANIFESTUAC:", "", "",
+    cmVS7FlagTable::UserValueRequired | cmVS7FlagTable::SpaceAppendable },
   { "GenerateMapFile", "MAP", "", "true",
     cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
   { "MapFileName", "MAP:", "Generate Map File", "",
diff --git a/Source/cmVS141LinkFlagTable.h b/Source/cmVS141LinkFlagTable.h
index a440ee7..f159f70 100644
--- a/Source/cmVS141LinkFlagTable.h
+++ b/Source/cmVS141LinkFlagTable.h
@@ -29,6 +29,8 @@
   { "CreateHotPatchableImage", "FUNCTIONPADMIN:16", "Itanium Image Only",
     "ItaniumImage", 0 },
 
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACExecutionLevel", "level='asInvoker'", "asInvoker", "AsInvoker", 0 },
   { "UACExecutionLevel", "level='highestAvailable'", "highestAvailable",
     "HighestAvailable", 0 },
@@ -150,8 +152,12 @@
   { "GenerateManifest", "MANIFEST:NO", "", "false", 0 },
   { "GenerateManifest", "MANIFEST", "", "true", 0 },
   { "AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0 },
+
+  // correct flags for uac should be /MANIFESTUAC, but some projects already
+  // use this bug to access uac field, so keep these for compatibility
   { "UACUIAccess", "uiAccess='false'", "", "false", 0 },
   { "UACUIAccess", "uiAccess='true'", "", "true", 0 },
+
   { "ManifestEmbed", "manifest:embed", "", "true", 0 },
   { "MapExports", "MAPINFO:EXPORTS", "", "true", 0 },
   { "AssemblyDebug", "ASSEMBLYDEBUG:DISABLE", "", "false", 0 },
@@ -192,11 +198,8 @@
   { "LinkDLL", "DLL", "", "true", 0 },
 
   // Bool Properties With Argument
-  { "EnableUAC", "MANIFESTUAC:NO", "", "false", 0 },
-  { "EnableUAC", "MANIFESTUAC:", "", "true",
-    cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
-  { "UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
-    cmVS7FlagTable::UserValueRequired },
+  { "EnableUAC", "MANIFESTUAC:", "", "",
+    cmVS7FlagTable::UserValueRequired | cmVS7FlagTable::SpaceAppendable },
   { "GenerateMapFile", "MAP", "", "true",
     cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
   { "MapFileName", "MAP:", "Generate Map File", "",
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index 7168f26..3c50403 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -218,7 +218,7 @@
 
 bool cmVSSetupAPIHelper::GetVSInstanceInfo(std::string& vsInstallLocation)
 {
-  vsInstallLocation = "";
+  vsInstallLocation.clear();
   bool isInstalled = this->EnumerateAndChooseVSInstance();
 
   if (isInstalled) {
diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h
index 811e02e..94970c5 100644
--- a/Source/cmVariableRequiresCommand.h
+++ b/Source/cmVariableRequiresCommand.h
@@ -15,9 +15,9 @@
 class cmVariableRequiresCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() CM_OVERRIDE { return new cmVariableRequiresCommand; }
+  cmCommand* Clone() override { return new cmVariableRequiresCommand; }
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
index 0e072b8..bd5d19c 100644
--- a/Source/cmVariableWatch.cxx
+++ b/Source/cmVariableWatch.cxx
@@ -2,11 +2,9 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmVariableWatch.h"
 
-#include "cmAlgorithms.h"
-
-#include "cm_auto_ptr.hxx"
-#include <algorithm>
+#include <memory>
 #include <utility>
+#include <vector>
 
 static const char* const cmVariableWatchAccessStrings[] = {
   "READ_ACCESS",     "UNKNOWN_READ_ACCESS", "UNKNOWN_DEFINED_ACCESS",
@@ -25,35 +23,27 @@
 {
 }
 
-template <typename C>
-void deleteAllSecond(typename C::value_type it)
-{
-  cmDeleteAll(it.second);
-}
-
 cmVariableWatch::~cmVariableWatch()
 {
-  std::for_each(this->WatchMap.begin(), this->WatchMap.end(),
-                deleteAllSecond<cmVariableWatch::StringToVectorOfPairs>);
 }
 
 bool cmVariableWatch::AddWatch(const std::string& variable, WatchMethod method,
                                void* client_data /*=0*/,
                                DeleteData delete_data /*=0*/)
 {
-  CM_AUTO_PTR<cmVariableWatch::Pair> p(new cmVariableWatch::Pair);
+  auto p = std::make_shared<cmVariableWatch::Pair>();
   p->Method = method;
   p->ClientData = client_data;
   p->DeleteDataCall = delete_data;
   cmVariableWatch::VectorOfPairs& vp = this->WatchMap[variable];
-  for (cmVariableWatch::Pair* pair : vp) {
+  for (auto& pair : vp) {
     if (pair->Method == method && client_data &&
         client_data == pair->ClientData) {
       // Callback already exists
       return false;
     }
   }
-  vp.push_back(p.release());
+  vp.push_back(std::move(p));
   return true;
 }
 
@@ -70,7 +60,6 @@
         // If client_data is NULL, we want to disconnect all watches against
         // the given method; otherwise match ClientData as well.
         (!client_data || (client_data == (*it)->ClientData))) {
-      delete *it;
       vp->erase(it);
       return;
     }
@@ -84,9 +73,17 @@
   cmVariableWatch::StringToVectorOfPairs::const_iterator mit =
     this->WatchMap.find(variable);
   if (mit != this->WatchMap.end()) {
-    const cmVariableWatch::VectorOfPairs* vp = &mit->second;
-    for (cmVariableWatch::Pair* it : *vp) {
-      it->Method(variable, access_type, it->ClientData, newValue, mf);
+    // The strategy here is to copy the list of callbacks, and ignore
+    // new callbacks that existing ones may add.
+    std::vector<std::weak_ptr<Pair>> vp(mit->second.begin(),
+                                        mit->second.end());
+    for (auto& weak_it : vp) {
+      // In the case where a callback was removed, the weak_ptr will not be
+      // lockable, and so this ensures we don't attempt to call into freed
+      // memory
+      if (auto it = weak_it.lock()) {
+        it->Method(variable, access_type, it->ClientData, newValue, mf);
+      }
     }
     return true;
   }
diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h
index 05a0a56..27d1b12 100644
--- a/Source/cmVariableWatch.h
+++ b/Source/cmVariableWatch.h
@@ -6,6 +6,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <map>
+#include <memory> // IWYU pragma: keep
 #include <string>
 #include <vector>
 
@@ -79,7 +80,7 @@
     }
   };
 
-  typedef std::vector<Pair*> VectorOfPairs;
+  typedef std::vector<std::shared_ptr<Pair>> VectorOfPairs;
   typedef std::map<std::string, VectorOfPairs> StringToVectorOfPairs;
 
   StringToVectorOfPairs WatchMap;
diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h
index 59baa4d..6a8115d 100644
--- a/Source/cmVariableWatchCommand.h
+++ b/Source/cmVariableWatchCommand.h
@@ -23,24 +23,24 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmVariableWatchCommand; }
+  cmCommand* Clone() override { return new cmVariableWatchCommand; }
 
   //! Default constructor
   cmVariableWatchCommand();
 
   //! Destructor.
-  ~cmVariableWatchCommand() CM_OVERRIDE;
+  ~cmVariableWatchCommand() override;
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 
   /** This command does not really have a final pass but it needs to
       stay alive since it owns variable watch callback information. */
-  bool HasFinalPass() const CM_OVERRIDE { return true; }
+  bool HasFinalPass() const override { return true; }
 
 protected:
   std::set<std::string> WatchedVariables;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index cbc5173..8dce028 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -407,7 +407,7 @@
       continue;
     std::string globalKey = keyIt->substr(strlen(prefix));
     // Skip invalid or separately-handled properties.
-    if (globalKey == "" || globalKey == "PROJECT_TYPES" ||
+    if (globalKey.empty() || globalKey == "PROJECT_TYPES" ||
         globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") {
       continue;
     }
@@ -614,7 +614,7 @@
        ++i) {
     if (i->first.find("VS_DOTNET_REFERENCE_") == 0) {
       std::string name = i->first.substr(20);
-      if (name != "") {
+      if (!name.empty()) {
         std::string path = i->second.GetValue();
         if (!cmsys::SystemTools::FileIsFullPath(path)) {
           path = std::string(this->GeneratorTarget->Target->GetMakefile()
@@ -1612,7 +1612,7 @@
       std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
       std::string binDir = this->Makefile->GetCurrentBinaryDirectory();
       if (fullFileName.find(binDir) != std::string::npos) {
-        sourceLink = "";
+        sourceLink.clear();
       } else if (fullFileName.find(srcDir) != std::string::npos) {
         sourceLink = fullFileName.substr(srcDir.length() + 1);
       } else {
@@ -3260,6 +3260,7 @@
   }
 
   linkOptions.Parse(flags.c_str());
+  linkOptions.FixManifestUACFlags();
 
   if (this->MSTools) {
     cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 51944fa..b1686be 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -256,6 +256,74 @@
   }
 }
 
+void cmVisualStudioGeneratorOptions::FixManifestUACFlags()
+{
+  static const char* ENABLE_UAC = "EnableUAC";
+  if (!HasFlag(ENABLE_UAC)) {
+    return;
+  }
+
+  const std::string uacFlag = GetFlag(ENABLE_UAC);
+  std::vector<std::string> subOptions;
+  cmsys::SystemTools::Split(uacFlag, subOptions, ' ');
+  if (subOptions.empty()) {
+    AddFlag(ENABLE_UAC, "true");
+    return;
+  }
+
+  if (subOptions.size() == 1 && subOptions[0] == "NO") {
+    AddFlag(ENABLE_UAC, "false");
+    return;
+  }
+
+  std::map<std::string, std::string> uacMap;
+  uacMap["level"] = "UACExecutionLevel";
+  uacMap["uiAccess"] = "UACUIAccess";
+
+  std::map<std::string, std::string> uacExecuteLevelMap;
+  uacExecuteLevelMap["asInvoker"] = "AsInvoker";
+  uacExecuteLevelMap["highestAvailable"] = "HighestAvailable";
+  uacExecuteLevelMap["requireAdministrator"] = "RequireAdministrator";
+
+  for (auto const& subopt : subOptions) {
+    std::vector<std::string> keyValue;
+    cmsys::SystemTools::Split(subopt, keyValue, '=');
+    if (keyValue.size() != 2 || (uacMap.find(keyValue[0]) == uacMap.end())) {
+      // ignore none key=value option or unknown flags
+      continue;
+    }
+
+    if (keyValue[1].front() == '\'' && keyValue[1].back() == '\'') {
+      keyValue[1] =
+        keyValue[1].substr(1, std::max<int>(0, keyValue[1].size() - 2));
+    }
+
+    if (keyValue[0] == "level") {
+      if (uacExecuteLevelMap.find(keyValue[1]) == uacExecuteLevelMap.end()) {
+        // unknown level value
+        continue;
+      }
+
+      AddFlag(uacMap[keyValue[0]].c_str(),
+              uacExecuteLevelMap[keyValue[1]].c_str());
+      continue;
+    }
+
+    if (keyValue[0] == "uiAccess") {
+      if (keyValue[1] != "true" && keyValue[1] != "false") {
+        // unknown uiAccess value
+        continue;
+      }
+      AddFlag(uacMap[keyValue[0]].c_str(), keyValue[1].c_str());
+      continue;
+    }
+
+    // unknwon sub option
+  }
+
+  AddFlag(ENABLE_UAC, "true");
+}
+
 void cmVisualStudioGeneratorOptions::Parse(const char* flags)
 {
   // Parse the input string as a windows command line since the string
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index 8d7942b..7c08a2c 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -77,6 +77,8 @@
 
   void FixCudaCodeGeneration();
 
+  void FixManifestUACFlags();
+
   bool IsDebug() const;
   bool IsWinRt() const;
   bool IsManaged() const;
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index 1a32aba..a9acb3f 100644
--- a/Source/cmVisualStudioSlnParser.cxx
+++ b/Source/cmVisualStudioSlnParser.cxx
@@ -329,7 +329,7 @@
     case FileStateIgnore:
       if (line.GetTag() == this->EndIgnoreTag) {
         this->Stack.pop();
-        this->EndIgnoreTag = "";
+        this->EndIgnoreTag.clear();
       }
       break;
     default:
diff --git a/Source/cmVisualStudioWCEPlatformParser.cxx b/Source/cmVisualStudioWCEPlatformParser.cxx
index fc64d0f..3b113aa 100644
--- a/Source/cmVisualStudioWCEPlatformParser.cxx
+++ b/Source/cmVisualStudioWCEPlatformParser.cxx
@@ -56,12 +56,12 @@
     return;
   }
 
-  this->CharacterData = "";
+  this->CharacterData.clear();
 
   if (name == "PlatformData") {
-    this->PlatformName = "";
-    this->OSMajorVersion = "";
-    this->OSMinorVersion = "";
+    this->PlatformName.clear();
+    this->OSMajorVersion.clear();
+    this->OSMinorVersion.clear();
     this->Macros.clear();
   }
 
diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h
index dfd5afc..6f6d405 100644
--- a/Source/cmWhileCommand.h
+++ b/Source/cmWhileCommand.h
@@ -19,10 +19,10 @@
 {
 public:
   cmWhileFunctionBlocker(cmMakefile* mf);
-  ~cmWhileFunctionBlocker() CM_OVERRIDE;
+  ~cmWhileFunctionBlocker() override;
   bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
-                         cmExecutionStatus&) CM_OVERRIDE;
-  bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) CM_OVERRIDE;
+                         cmExecutionStatus&) override;
+  bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
 
   std::vector<cmListFileArgument> Args;
   std::vector<cmListFileFunction> Functions;
@@ -39,21 +39,21 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmWhileCommand; }
+  cmCommand* Clone() override { return new cmWhileCommand; }
 
   /**
    * This overrides the default InvokeInitialPass implementation.
    * It records the arguments before expansion.
    */
   bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
-                         cmExecutionStatus&) CM_OVERRIDE;
+                         cmExecutionStatus&) override;
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) CM_OVERRIDE
+                   cmExecutionStatus&) override
   {
     return false;
   }
diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h
index 36a08a4..9028f84 100644
--- a/Source/cmWriteFileCommand.h
+++ b/Source/cmWriteFileCommand.h
@@ -22,14 +22,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() CM_OVERRIDE { return new cmWriteFileCommand; }
+  cmCommand* Clone() override { return new cmWriteFileCommand; }
 
   /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
   bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) CM_OVERRIDE;
+                   cmExecutionStatus& status) override;
 };
 
 #endif
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/cm_codecvt.hxx b/Source/cm_codecvt.hxx
index 30c6d54..3a5606b 100644
--- a/Source/cm_codecvt.hxx
+++ b/Source/cm_codecvt.hxx
@@ -3,7 +3,7 @@
 #ifndef cm_codecvt_hxx
 #define cm_codecvt_hxx
 
-#include "cmConfigure.h"
+#include "cmConfigure.h" // IWYU pragma: keep
 
 #include <locale>
 #include <wchar.h>
@@ -23,15 +23,15 @@
   codecvt(Encoding e);
 
 protected:
-  ~codecvt() CM_OVERRIDE;
-  bool do_always_noconv() const throw() CM_OVERRIDE;
+  ~codecvt() override;
+  bool do_always_noconv() const throw() override;
   result do_out(mbstate_t& state, const char* from, const char* from_end,
                 const char*& from_next, char* to, char* to_end,
-                char*& to_next) const CM_OVERRIDE;
+                char*& to_next) const override;
   result do_unshift(mbstate_t& state, char* to, char*,
-                    char*& to_next) const CM_OVERRIDE;
-  int do_max_length() const throw() CM_OVERRIDE;
-  int do_encoding() const throw() CM_OVERRIDE;
+                    char*& to_next) const override;
+  int do_max_length() const throw() override;
+  int do_encoding() const throw() override;
 
 private:
   // The mbstate_t argument to do_out and do_unshift is responsible
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 9ffb9f8..e61acb1 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1072,10 +1072,10 @@
 
   // Save the environment variables CXX and CC
   if (!cmSystemTools::GetEnv("CXX", this->CXXEnvironment)) {
-    this->CXXEnvironment = "";
+    this->CXXEnvironment.clear();
   }
   if (!cmSystemTools::GetEnv("CC", this->CCEnvironment)) {
-    this->CCEnvironment = "";
+    this->CCEnvironment.clear();
   }
 }
 
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 09dcb6d..a1dfc3e 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -14,12 +14,13 @@
 #ifdef CMAKE_BUILD_WITH_CMAKE
 #include "cmDocumentation.h"
 #include "cmDynamicLoader.h"
+#endif
+
 #ifdef _WIN32
 #include <fcntl.h>  /* _O_TEXT */
 #include <stdlib.h> /* _set_fmode, _fmode */
 #endif
 #include "cm_uv.h"
-#endif
 
 #include "cmsys/Encoding.hxx"
 #if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
@@ -167,7 +168,7 @@
   ac = args.argc();
   av = args.argv();
 
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32)
+#if defined(_WIN32)
   // Perform libuv one-time initialization now, and then un-do its
   // global _fmode setting so that using libuv does not change the
   // default file text/binary mode.  See libuv issue 840.
@@ -192,8 +193,8 @@
   int ret = do_cmake(ac, av);
 #ifdef CMAKE_BUILD_WITH_CMAKE
   cmDynamicLoader::FlushCache();
-  uv_loop_close(uv_default_loop());
 #endif
+  uv_loop_close(uv_default_loop());
   return ret;
 }
 
@@ -372,7 +373,7 @@
         hasTarget = true;
       } else {
         std::cerr << "'--target' may not be specified more than once.\n\n";
-        dir = "";
+        dir.clear();
         break;
       }
     } else if (strcmp(av[i], "--config") == 0) {
@@ -400,7 +401,7 @@
           break;
         default:
           std::cerr << "Unknown argument " << av[i] << std::endl;
-          dir = "";
+          dir.clear();
           break;
       }
     }
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/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index 01c6951..e67d436 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -265,6 +265,12 @@
 #ifdef TEST_KWSYS_CXX_HAS_UTIMENSAT
 #include <fcntl.h>
 #include <sys/stat.h>
+#if defined(__APPLE__)
+#include <AvailabilityMacros.h>
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101300
+#error "utimensat not available on macOS < 10.13"
+#endif
+#endif
 int main()
 {
   struct timespec times[2] = { { 0, UTIME_OMIT }, { 0, UTIME_NOW } };
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/CMakeLists.txt b/Tests/CMakeLists.txt
index 640b542..ce53454 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -268,7 +268,7 @@
   endif()
 
   add_test(NAME CMake.Copyright
-    COMMAND cmake -P ${CMAKE_CURRENT_SOURCE_DIR}/CMakeCopyright.cmake)
+    COMMAND ${CMAKE_CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMakeCopyright.cmake)
 
   # add a bunch of standard build-and-test style tests
   ADD_TEST_MACRO(CommandLineTest CommandLineTest)
@@ -329,7 +329,7 @@
       set(CMAKE_SKIP_VSGNUFortran TRUE)
     endif()
     if(NOT CMAKE_SKIP_VSGNUFortran)
-      ADD_TEST_MACRO(VSGNUFortran ${CMAKE_COMMAND} -P runtest.cmake)
+      ADD_TEST_MACRO(VSGNUFortran ${CMAKE_CMAKE_COMMAND} -P runtest.cmake)
     endif()
   endif()
 
@@ -813,31 +813,6 @@
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommandWorkingDirectory")
 
-   #add_test(SimpleExclude ${CMAKE_CTEST_COMMAND}
-   #  --build-and-test
-   #  "${CMake_SOURCE_DIR}/Tests/SimpleExclude"
-   #  "${CMake_BINARY_DIR}/Tests/SimpleExclude"
-   #  ${build_generator_args}
-   #  --build-project SimpleExclude
-   #  --build-two-config
-   #  --build-options ${build_options}
-   #  --test-command t4
-   #--test-command "${CMAKE_COMMAND}"
-   #"-DCONFIGURATION=\${CTEST_CONFIGURATION_TYPE}"
-   #-P "${CMake_BINARY_DIR}/Tests/SimpleExclude/run.cmake"
-   #)
-
-#  add_test(SameName  ${CMAKE_CTEST_COMMAND}
-#    --build-and-test
-#    "${CMake_SOURCE_DIR}/Tests/SameName"
-#    "${CMake_BINARY_DIR}/Tests/SameName"
-#    ${build_generator_args}
-#    --build-project SameName
-#    --build-two-config
-#    --build-options ${build_options}
-#    --test-command
-#    "${CMake_BINARY_DIR}/Tests/SameName/Exe1/mytest2")
-
   add_test(OutOfSource ${CMAKE_CTEST_COMMAND}
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/OutOfSource"
@@ -2666,7 +2641,7 @@
   file(COPY "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/VistA-FOIA"
     DESTINATION "${CMake_BINARY_DIR}/Testing/MumpsCoverage")
   add_test(NAME CTestGTMCoverage
-    COMMAND cmake -E chdir
+    COMMAND ${CMAKE_CMAKE_COMMAND} -E chdir
     ${CMake_BINARY_DIR}/Testing/MumpsCoverage
     $<TARGET_FILE:ctest> -T Coverage --debug)
   set_tests_properties(CTestGTMCoverage PROPERTIES
@@ -2684,7 +2659,7 @@
   file(COPY "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/VistA-FOIA"
     DESTINATION "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage")
   add_test(NAME CTestCacheCoverage
-    COMMAND cmake -E chdir
+    COMMAND ${CMAKE_CMAKE_COMMAND} -E chdir
     ${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage
     $<TARGET_FILE:ctest> -T Coverage --debug)
   set_tests_properties(CTestCacheCoverage PROPERTIES
@@ -2702,7 +2677,7 @@
   file(COPY "${CMake_SOURCE_DIR}/Tests/PythonCoverage/coveragetest"
     DESTINATION "${CMake_BINARY_DIR}/Testing/PythonCoverage")
   add_test(NAME CTestPythonCoverage
-    COMMAND cmake -E chdir
+    COMMAND ${CMAKE_CMAKE_COMMAND} -E chdir
     ${CMake_BINARY_DIR}/Testing/PythonCoverage
     $<TARGET_FILE:ctest> -T Coverage --debug)
   set_tests_properties(CTestPythonCoverage PROPERTIES
@@ -2720,7 +2695,7 @@
   file(COPY "${CMake_SOURCE_DIR}/Tests/CoberturaCoverage/src"
     DESTINATION "${CMake_BINARY_DIR}/Testing/CoberturaCoverage")
   add_test(NAME CTestCoberturaCoverage
-    COMMAND cmake -E chdir
+    COMMAND ${CMAKE_CMAKE_COMMAND} -E chdir
     ${CMake_BINARY_DIR}/Testing/CoberturaCoverage
     $<TARGET_FILE:ctest> -T Coverage --debug)
   set_tests_properties(CTestCoberturaCoverage PROPERTIES
@@ -2739,7 +2714,7 @@
   configure_file("${CMake_BINARY_DIR}/Testing/JacocoCoverage/Coverage/target/site/jacoco.xml.in"
     "${CMake_BINARY_DIR}/Testing/JacocoCoverage/Coverage/target/site/jacoco.xml")
   add_test(NAME CTestJacocoCoverage
-    COMMAND cmake -E chdir
+    COMMAND ${CMAKE_CMAKE_COMMAND} -E chdir
     ${CMake_BINARY_DIR}/Testing/JacocoCoverage
     $<TARGET_FILE:ctest> -T Coverage --debug)
   set_tests_properties(CTestJacocoCoverage PROPERTIES
@@ -2758,7 +2733,7 @@
     DESTINATION "${CMake_BINARY_DIR}/Testing/JavascriptCoverage"
     FILES_MATCHING PATTERN "*.js")
   add_test(NAME CTestJavascriptCoverage
-    COMMAND cmake -E chdir
+    COMMAND ${CMAKE_CMAKE_COMMAND} -E chdir
     ${CMake_BINARY_DIR}/Testing/JavascriptCoverage
     $<TARGET_FILE:ctest> -T Coverage --debug)
   set_tests_properties(CTestJavascriptCoverage PROPERTIES
@@ -2776,7 +2751,7 @@
     "${CMake_SOURCE_DIR}/Tests/DelphiCoverage/UTCovTest(UTCovTest.pas).html.in"
     "${CMake_BINARY_DIR}/Testing/DelphiCoverage/UTCovTest(UTCovTest.pas).html")
   add_test(NAME CTestDelphiCoverage
-    COMMAND cmake -E chdir
+    COMMAND ${CMAKE_CMAKE_COMMAND} -E chdir
     ${CMake_BINARY_DIR}/Testing/DelphiCoverage
     $<TARGET_FILE:ctest> -T Coverage --debug)
   set_tests_properties(CTestDelphiCoverage PROPERTIES
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend1.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend1.cmake
index 70d6edf..73fd0ab 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend1.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend1.cmake
@@ -6,7 +6,7 @@
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend2.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend2.cmake
index 415d536..81dbbc5 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend2.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend2.cmake
@@ -6,7 +6,7 @@
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 set(config_verbose -V)
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake
index 337cc16..ad52f56 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake
@@ -6,7 +6,7 @@
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake
index 35ca74c..af27c51 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake
@@ -7,7 +7,7 @@
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake
index f1391cd..1fe9258 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake
@@ -5,7 +5,7 @@
 include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 
 # TODO: currently debian doens't produce lower cased names
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-shlibdeps1.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-shlibdeps1.cmake
index fcfc7ea..e57488c 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-shlibdeps1.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-shlibdeps1.cmake
@@ -9,7 +9,7 @@
 # requirements
 
 # debian now produces lower case names
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake
index 351bf21..5ee057a 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake
@@ -6,7 +6,7 @@
 
 
 # expected results
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib-*_1.0.2_*.deb")
 set(expected_count 3)
 
 set(config_verbose -V)
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-compression.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-compression.cmake
index c97ecb0..13a626a 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-compression.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-compression.cmake
@@ -5,7 +5,7 @@
 include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
 
 # TODO: currently debian doens't produce lower cased names
-set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib_1.0.2-1_*.deb")
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/mylib_1.0.2_*.deb")
 set(expected_count 1)
 
 set(actual_output)
diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
index a5b38fd..2c3a849 100644
--- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
+++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
@@ -60,7 +60,7 @@
         set(expected_count 1)
     endif ()
 elseif (CPackGen MATCHES "DEB")
-    set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/mylib*_1.0.2-1_*.deb")
+    set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/mylib*_1.0.2_*.deb")
     if (${CPackComponentWay} STREQUAL "default")
         set(expected_count 1)
     elseif (${CPackComponentWay} STREQUAL "OnePackPerGroup")
diff --git a/Tests/FindGTest/Test/main.cxx b/Tests/FindGTest/Test/main.cxx
index 0572a5d..19d2967 100644
--- a/Tests/FindGTest/Test/main.cxx
+++ b/Tests/FindGTest/Test/main.cxx
@@ -2,5 +2,7 @@
 
 TEST(FindCMake, LinksAndRuns)
 {
+  using namespace testing;
+  EXPECT_FALSE(GTEST_FLAG(list_tests));
   ASSERT_TRUE(true);
 }
diff --git a/Tests/FindMPI/Test/CMakeLists.txt b/Tests/FindMPI/Test/CMakeLists.txt
index 3910c25..efe8c62 100644
--- a/Tests/FindMPI/Test/CMakeLists.txt
+++ b/Tests/FindMPI/Test/CMakeLists.txt
@@ -20,12 +20,17 @@
   endif()
 endforeach()
 
+set(MPI_CXX_SKIP_MPICXX TRUE)
+set(MPI_CXX_VALIDATE_SKIP_MPICXX TRUE)
 find_package(MPI REQUIRED)
 
 foreach(c C CXX Fortran)
   if(NOT "${MPI_TEST_${c}}")
     continue()
   endif()
+  if(${c} STREQUAL CXX AND MPI_MPICXX_FOUND)
+    message(FATAL_ERROR "Could not suppress MPI-2 C++ bindings for this MPI.")
+  endif()
   source_code_mapper_helper(${c})
   add_executable(test_tgt_${c} ${MPITEST_SOURCE_FILE})
   target_link_libraries(test_tgt_${c} MPI::MPI_${c})
diff --git a/Tests/QtAutogen/sameName/CMakeLists.txt b/Tests/QtAutogen/sameName/CMakeLists.txt
index 4d2dcd9..f695875 100644
--- a/Tests/QtAutogen/sameName/CMakeLists.txt
+++ b/Tests/QtAutogen/sameName/CMakeLists.txt
@@ -17,7 +17,10 @@
   main.cpp
 )
 target_link_libraries(sameName ${QT_LIBRARIES})
-set_target_properties(sameName PROPERTIES AUTOMOC TRUE AUTORCC TRUE)
+set_target_properties(sameName PROPERTIES
+  AUTOMOC TRUE
+  AUTOUIC TRUE
+  AUTORCC TRUE)
 
 # Set different compression levels
 if (QT_TEST_VERSION STREQUAL 4)
diff --git a/Tests/QtAutogen/sameName/aaa/bbb/item.cpp b/Tests/QtAutogen/sameName/aaa/bbb/item.cpp
index 20d0044..850206f 100644
--- a/Tests/QtAutogen/sameName/aaa/bbb/item.cpp
+++ b/Tests/QtAutogen/sameName/aaa/bbb/item.cpp
@@ -3,8 +3,20 @@
 namespace aaa {
 namespace bbb {
 
+class MocLocal : public QObject
+{
+  Q_OBJECT;
+
+public:
+  MocLocal() = default;
+  ~MocLocal() = default;
+};
+
 void Item::go()
 {
+  MocLocal obj;
 }
 }
 }
+
+#include "aaa/bbb/item.moc"
diff --git a/Tests/QtAutogen/sameName/aaa/item.cpp b/Tests/QtAutogen/sameName/aaa/item.cpp
index 95dd3b6..e35d3d1 100644
--- a/Tests/QtAutogen/sameName/aaa/item.cpp
+++ b/Tests/QtAutogen/sameName/aaa/item.cpp
@@ -1,8 +1,22 @@
 #include "item.hpp"
+// Include ui_view.h only in header
 
 namespace aaa {
 
+class MocLocal : public QObject
+{
+  Q_OBJECT;
+
+public:
+  MocLocal() = default;
+  ~MocLocal() = default;
+};
+
 void Item::go()
 {
+  Ui_ViewAAA ui;
+  MocLocal obj;
 }
 }
+
+#include "aaa/item.moc"
diff --git a/Tests/QtAutogen/sameName/aaa/item.hpp b/Tests/QtAutogen/sameName/aaa/item.hpp
index b63466f..875f72f 100644
--- a/Tests/QtAutogen/sameName/aaa/item.hpp
+++ b/Tests/QtAutogen/sameName/aaa/item.hpp
@@ -2,6 +2,8 @@
 #define AAA_ITEM_HPP
 
 #include <QObject>
+// Include ui_view.h only in header
+#include <aaa/ui_view.h>
 
 namespace aaa {
 
diff --git a/Tests/QtAutogen/sameName/aaa/view.ui b/Tests/QtAutogen/sameName/aaa/view.ui
new file mode 100644
index 0000000..0f09980
--- /dev/null
+++ b/Tests/QtAutogen/sameName/aaa/view.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ViewAAA</class>
+ <widget class="QWidget" name="Base">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <widget class="QTreeView" name="treeView"/>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/sameName/bbb/aaa/item.cpp b/Tests/QtAutogen/sameName/bbb/aaa/item.cpp
index ac4b2c2..7ad01c3 100644
--- a/Tests/QtAutogen/sameName/bbb/aaa/item.cpp
+++ b/Tests/QtAutogen/sameName/bbb/aaa/item.cpp
@@ -3,8 +3,20 @@
 namespace bbb {
 namespace aaa {
 
+class MocLocal : public QObject
+{
+  Q_OBJECT;
+
+public:
+  MocLocal() = default;
+  ~MocLocal() = default;
+};
+
 void Item::go()
 {
+  MocLocal obj;
 }
 }
 }
+
+#include "bbb/aaa/item.moc"
diff --git a/Tests/QtAutogen/sameName/bbb/item.cpp b/Tests/QtAutogen/sameName/bbb/item.cpp
index f97a143..9ef128e 100644
--- a/Tests/QtAutogen/sameName/bbb/item.cpp
+++ b/Tests/QtAutogen/sameName/bbb/item.cpp
@@ -1,8 +1,23 @@
 #include "item.hpp"
+// Include ui_view.h only in source
+#include <bbb/ui_view.h>
 
 namespace bbb {
 
+class MocLocal : public QObject
+{
+  Q_OBJECT;
+
+public:
+  MocLocal() = default;
+  ~MocLocal() = default;
+};
+
 void Item::go()
 {
+  Ui_ViewBBB ui;
+  MocLocal obj;
 }
 }
+
+#include "bbb/item.moc"
diff --git a/Tests/QtAutogen/sameName/bbb/item.hpp b/Tests/QtAutogen/sameName/bbb/item.hpp
index 5b7f985..d39a9d7 100644
--- a/Tests/QtAutogen/sameName/bbb/item.hpp
+++ b/Tests/QtAutogen/sameName/bbb/item.hpp
@@ -2,6 +2,7 @@
 #define BBB_ITEM_HPP
 
 #include <QObject>
+// Include ui_view.h only in source
 
 namespace bbb {
 
diff --git a/Tests/QtAutogen/sameName/bbb/view.ui b/Tests/QtAutogen/sameName/bbb/view.ui
new file mode 100644
index 0000000..a8f506e
--- /dev/null
+++ b/Tests/QtAutogen/sameName/bbb/view.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ViewBBB</class>
+ <widget class="QWidget" name="Base">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <widget class="QTreeView" name="treeView"/>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/sameName/ccc/item.cpp b/Tests/QtAutogen/sameName/ccc/item.cpp
index d90b2b8..ab8a281 100644
--- a/Tests/QtAutogen/sameName/ccc/item.cpp
+++ b/Tests/QtAutogen/sameName/ccc/item.cpp
@@ -1,23 +1,25 @@
 #include "item.hpp"
+// Include ui_view.h in source and header
+#include <ccc/ui_view.h>
 
 namespace ccc {
 
-void Item::go()
-{
-}
-
-class MocTest : public QObject
+class MocLocal : public QObject
 {
   Q_OBJECT;
-  Q_SLOT
-  void go();
+
+public:
+  MocLocal() = default;
+  ~MocLocal() = default;
 };
 
-void MocTest::go()
+void Item::go()
 {
+  Ui_ViewCCC ui;
+  MocLocal obj;
 }
 }
 
 // Include own moc files
-#include "item.moc"
+#include "ccc/item.moc"
 #include "moc_item.cpp"
diff --git a/Tests/QtAutogen/sameName/ccc/item.hpp b/Tests/QtAutogen/sameName/ccc/item.hpp
index 96fcc24..20d9dd9 100644
--- a/Tests/QtAutogen/sameName/ccc/item.hpp
+++ b/Tests/QtAutogen/sameName/ccc/item.hpp
@@ -2,6 +2,8 @@
 #define CCC_ITEM_HPP
 
 #include <QObject>
+// Include ui_view.h in source and header
+#include <ccc/ui_view.h>
 
 namespace ccc {
 
diff --git a/Tests/QtAutogen/sameName/ccc/view.ui b/Tests/QtAutogen/sameName/ccc/view.ui
new file mode 100644
index 0000000..7989c69
--- /dev/null
+++ b/Tests/QtAutogen/sameName/ccc/view.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ViewCCC</class>
+ <widget class="QWidget" name="Base">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <widget class="QTreeView" name="treeView"/>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/sameName/item.cpp b/Tests/QtAutogen/sameName/item.cpp
index e013cf3..3d1fbe7 100644
--- a/Tests/QtAutogen/sameName/item.cpp
+++ b/Tests/QtAutogen/sameName/item.cpp
@@ -1,5 +1,20 @@
 #include "item.hpp"
+// Include ui_view.h in source and header
+#include <ui_view.h>
+
+class MocLocal : public QObject
+{
+  Q_OBJECT;
+
+public:
+  MocLocal() = default;
+  ~MocLocal() = default;
+};
 
 void Item::go()
 {
+  Ui_View ui;
+  MocLocal obj;
 }
+
+#include "item.moc"
diff --git a/Tests/QtAutogen/sameName/item.hpp b/Tests/QtAutogen/sameName/item.hpp
index 91bba3b..75e83f4 100644
--- a/Tests/QtAutogen/sameName/item.hpp
+++ b/Tests/QtAutogen/sameName/item.hpp
@@ -2,6 +2,8 @@
 #define ITEM_HPP
 
 #include <QObject>
+// Include ui_view.h in source and header
+#include <ui_view.h>
 
 class Item : public QObject
 {
diff --git a/Tests/QtAutogen/sameName/view.ui b/Tests/QtAutogen/sameName/view.ui
new file mode 100644
index 0000000..2ffe734
--- /dev/null
+++ b/Tests/QtAutogen/sameName/view.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>View</class>
+ <widget class="QWidget" name="Base">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <widget class="QTreeView" name="treeView"/>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogenRerun/CMakeLists.txt b/Tests/QtAutogenRerun/CMakeLists.txt
index 088025f..e72c191 100644
--- a/Tests/QtAutogenRerun/CMakeLists.txt
+++ b/Tests/QtAutogenRerun/CMakeLists.txt
@@ -36,204 +36,17 @@
 
 endif()
 
-# -- Test
-# Dummy test to generate clean target
+# Dummy executable to generate clean target
 add_executable(dummy dummy.cpp)
 
 # -- Test
-# When a file listed in a .qrc file changes the target must be rebuilt
-set(timeformat "%Y%j%H%M%S")
-set(RCC_DEPENDS_SRC "${CMAKE_CURRENT_SOURCE_DIR}/rccDepends")
-set(RCC_DEPENDS_BIN "${CMAKE_CURRENT_BINARY_DIR}/rccDepends")
-configure_file(${RCC_DEPENDS_SRC}/res1a.qrc.in ${RCC_DEPENDS_BIN}/res1.qrc COPYONLY)
-configure_file(${RCC_DEPENDS_SRC}/res2a.qrc.in ${RCC_DEPENDS_BIN}/res2.qrc.in COPYONLY)
-try_compile(RCC_DEPENDS
-  "${RCC_DEPENDS_BIN}"
-  "${RCC_DEPENDS_SRC}"
-  rccDepends
-  CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
-              "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
-              "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
-  OUTPUT_VARIABLE output
-)
-if (NOT RCC_DEPENDS)
-  message(SEND_ERROR "Initial build of rccDepends failed. Output: ${output}")
-endif()
-# Get name and timestamp of the output binary
-file(STRINGS "${RCC_DEPENDS_BIN}/target.txt" targetList ENCODING UTF-8)
-list(GET targetList 0 rccDependsBin)
-file(TIMESTAMP "${rccDependsBin}" timeBegin "${timeformat}")
-# Sleep, touch regular qrc input file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res1/input.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
-  message(SEND_ERROR "Second build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep1 "${timeformat}")
-if (NOT timeStep1 GREATER timeBegin)
-  message(SEND_ERROR "File (${rccDependsBin}) should have changed in the first step!")
-endif()
-# Sleep, update regular qrc file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-configure_file(${RCC_DEPENDS_SRC}/res1b.qrc.in ${RCC_DEPENDS_BIN}/res1.qrc COPYONLY)
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
-  message(SEND_ERROR "Third build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep2 "${timeformat}")
-if (NOT timeStep2 GREATER timeStep1)
-  message(SEND_ERROR "File (${rccDependsBin}) should have changed in the second step!")
-endif()
-# Sleep, touch regular qrc newly added input file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res1/inputAdded.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
-  message(SEND_ERROR "Fourth build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep3 "${timeformat}")
-if (NOT timeStep3 GREATER timeStep2)
-  message(SEND_ERROR "File (${rccDependsBin}) should have changed in the third step!")
-endif()
-# Sleep, touch generated qrc input file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res2/input.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
-  message(SEND_ERROR "Fifth build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep4 "${timeformat}")
-if (NOT timeStep4 GREATER timeStep3)
-  message(SEND_ERROR "File (${rccDependsBin}) should have changed in the fourth step!")
-endif()
-# Sleep, update generated qrc file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-configure_file(${RCC_DEPENDS_SRC}/res2b.qrc.in ${RCC_DEPENDS_BIN}/res2.qrc.in COPYONLY)
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
-  message(SEND_ERROR "Sixth build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep5 "${timeformat}")
-if (NOT timeStep5 GREATER timeStep4)
-  message(SEND_ERROR "File (${rccDependsBin}) should have changed in the fitfh step!")
-endif()
-# Sleep, touch generated qrc newly added input file, rebuild and compare timestamp
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${RCC_DEPENDS_BIN}/res2/inputAdded.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${RCC_DEPENDS_BIN}" RESULT_VARIABLE result)
-if (result)
-  message(SEND_ERROR "Seventh build of rccDepends failed.")
-endif()
-file(TIMESTAMP "${rccDependsBin}" timeStep6 "${timeformat}")
-if (NOT timeStep6 GREATER timeStep5)
-  message(SEND_ERROR "File (${rccDependsBin}) should have changed in the sixth step!")
-endif()
-
-
-# -- Test
-# Ensure a repeated build succeeds when a header containing a QObject changes
-set(timeformat "%Y%j%H%M%S")
-configure_file(mocRerun/test1a.h.in mocRerun/test1.h COPYONLY)
-try_compile(MOC_RERUN
-  "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
-  "${CMAKE_CURRENT_SOURCE_DIR}/mocRerun"
-  mocRerun
-  CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
-              "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
-              "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
-  OUTPUT_VARIABLE output
-)
-if (NOT MOC_RERUN)
-  message(SEND_ERROR "Initial build of mocRerun failed. Output: ${output}")
-endif()
-# Get name and timestamp of the output binary
-file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/mocRerun/target1.txt" target1List ENCODING UTF-8)
-list(GET target1List 0 binFile)
-file(TIMESTAMP "${binFile}" timeBegin "${timeformat}")
-# Change file content and rebuild
-execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
-configure_file(mocRerun/test1b.h.in mocRerun/test1.h COPYONLY)
-execute_process(COMMAND "${CMAKE_COMMAND}" --build .
-  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
-  RESULT_VARIABLE mocRerun_result
-  )
-if (mocRerun_result)
-  message(SEND_ERROR "Second build of mocRerun failed.")
-endif()
-# Compare timestamps
-file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}")
-if (NOT timeStep1 GREATER timeBegin)
-  message(SEND_ERROR "File (${binFile}) should have changed in the first step!")
-endif()
-
+include("mocRerun.cmake")
 
 # -- Test
 # Tests Q_PLUGIN_METADATA json file change detection
 if (NOT QT_TEST_VERSION STREQUAL 4)
-  try_compile(MOC_PLUGIN
-    "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin"
-    "${CMAKE_CURRENT_SOURCE_DIR}/mocPlugin"
-    mocPlugin
-    CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
-                "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
-    OUTPUT_VARIABLE output
-  )
-  if (NOT MOC_PLUGIN)
-    message(SEND_ERROR "Initial build of mocPlugin failed. Output: ${output}")
-  endif()
-
-  set(timeformat "%Y%j%H%M%S")
-  set(mocPlugSrcDir "${CMAKE_CURRENT_SOURCE_DIR}/mocPlugin")
-  set(mocPlugBinDir "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin")
-  find_library(plAFile "PlugA" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
-  find_library(plBFile "PlugB" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
-  find_library(plCFile "PlugC" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
-  find_library(plDFile "PlugD" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
-
-  file(TIMESTAMP "${plAFile}" plABefore "${timeformat}")
-  file(TIMESTAMP "${plBFile}" plBBefore "${timeformat}")
-  file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
-  file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")
-
-  # Ensure that the timestamp will change and change the json files
-  execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
-  configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleC.json")
-  configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD.json")
-  execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")
-
-  file(TIMESTAMP "${plAFile}" plAAfter "${timeformat}")
-  file(TIMESTAMP "${plBFile}" plBAfter "${timeformat}")
-  file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
-  file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")
-
-  if (plAAfter GREATER plABefore)
-    message(SEND_ERROR "file (${plAFile}) should not have changed!")
-  endif()
-  if (plBAfter GREATER plBBefore)
-    message(SEND_ERROR "file (${plBFile}) should not have changed!")
-  endif()
-  if (NOT plCAfter GREATER plCBefore)
-    message(SEND_ERROR "file (${plCFile}) should have changed!")
-  endif()
-  if (NOT plDAfter GREATER plDBefore)
-    message(SEND_ERROR "file (${plDFile}) should have changed!")
-  endif()
-
-  # Test custom macro
-  file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
-  file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")
-  execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
-  configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleC_Custom.json")
-  configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD_Custom.json")
-  execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")
-  file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
-  file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")
-  if (NOT plCAfter GREATER plCBefore)
-    message(SEND_ERROR "file (${plCFile}) should have changed!")
-  endif()
-  if (NOT plDAfter GREATER plDBefore)
-    message(SEND_ERROR "file (${plDFile}) should have changed!")
-  endif()
-
+  include("mocPlugin.cmake")
 endif()
+
+# -- Test
+include("rccDepends.cmake")
diff --git a/Tests/QtAutogenRerun/mocPlugin.cmake b/Tests/QtAutogenRerun/mocPlugin.cmake
new file mode 100644
index 0000000..7ad5ccb
--- /dev/null
+++ b/Tests/QtAutogenRerun/mocPlugin.cmake
@@ -0,0 +1,96 @@
+
+# Utility variables
+set(timeformat "%Y%j%H%M%S")
+set(mocPlugSrcDir "${CMAKE_CURRENT_SOURCE_DIR}/mocPlugin")
+set(mocPlugBinDir "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin")
+
+# Initial buid
+try_compile(MOC_PLUGIN
+  "${mocPlugBinDir}"
+  "${mocPlugSrcDir}"
+  mocPlugin
+  CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+              "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
+  OUTPUT_VARIABLE output
+)
+if (NOT MOC_PLUGIN)
+  message(SEND_ERROR "Initial build of mocPlugin failed. Output: ${output}")
+endif()
+
+find_library(plAFile "PlugA" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
+find_library(plBFile "PlugB" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
+find_library(plCFile "PlugC" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
+find_library(plDFile "PlugD" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
+find_library(plEFile "PlugE" PATHS "${mocPlugBinDir}/Debug" "${mocPlugBinDir}" NO_DEFAULT_PATH)
+
+# - Ensure that the timestamp will change.
+# - Change the json files referenced by Q_PLUGIN_METADATA
+# - Rebuild
+file(TIMESTAMP "${plAFile}" plABefore "${timeformat}")
+file(TIMESTAMP "${plBFile}" plBBefore "${timeformat}")
+file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
+file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")
+file(TIMESTAMP "${plEFile}" plEBefore "${timeformat}")
+
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleC.json")
+configure_file("${mocPlugSrcDir}/jsonIn/StyleE.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD.json")
+configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/StyleE.json")
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")
+
+file(TIMESTAMP "${plAFile}" plAAfter "${timeformat}")
+file(TIMESTAMP "${plBFile}" plBAfter "${timeformat}")
+file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
+file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")
+file(TIMESTAMP "${plEFile}" plEAfter "${timeformat}")
+
+if (plAAfter GREATER plABefore)
+  message(SEND_ERROR "file (${plAFile}) should not have changed!")
+endif()
+if (plBAfter GREATER plBBefore)
+  message(SEND_ERROR "file (${plBFile}) should not have changed!")
+endif()
+if (NOT plCAfter GREATER plCBefore)
+  message(SEND_ERROR "file (${plCFile}) should have changed!")
+endif()
+if (NOT plDAfter GREATER plDBefore)
+  message(SEND_ERROR "file (${plDFile}) should have changed!")
+endif()
+if (NOT plEAfter GREATER plEBefore)
+  # There's a bug in Ninja on Windows
+  # https://gitlab.kitware.com/cmake/cmake/issues/16776
+  if(NOT ("${CMAKE_GENERATOR}" MATCHES "Ninja"))
+    message(SEND_ERROR "file (${plEFile}) should have changed!")
+  endif()
+endif()
+
+# - Ensure that the timestamp will change.
+# - Change the json files referenced by A_CUSTOM_MACRO
+# - Rebuild
+file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
+file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")
+file(TIMESTAMP "${plEFile}" plEBefore "${timeformat}")
+
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+configure_file("${mocPlugSrcDir}/jsonIn/StyleE.json" "${mocPlugBinDir}/jsonFiles/StyleC_Custom.json")
+configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD_Custom.json")
+configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleE_Custom.json")
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")
+
+file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
+file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")
+file(TIMESTAMP "${plEFile}" plEAfter "${timeformat}")
+
+if (NOT plCAfter GREATER plCBefore)
+  message(SEND_ERROR "file (${plCFile}) should have changed!")
+endif()
+if (NOT plDAfter GREATER plDBefore)
+  message(SEND_ERROR "file (${plDFile}) should have changed!")
+endif()
+if (NOT plEAfter GREATER plEBefore)
+  # There's a bug in Ninja on Windows
+  # https://gitlab.kitware.com/cmake/cmake/issues/16776
+  if(NOT ("${CMAKE_GENERATOR}" MATCHES "Ninja"))
+    message(SEND_ERROR "file (${plEFile}) should have changed!")
+  endif()
+endif()
diff --git a/Tests/QtAutogenRerun/mocPlugin/CMakeLists.txt b/Tests/QtAutogenRerun/mocPlugin/CMakeLists.txt
index 9b224fb..b7cc5e9 100644
--- a/Tests/QtAutogenRerun/mocPlugin/CMakeLists.txt
+++ b/Tests/QtAutogenRerun/mocPlugin/CMakeLists.txt
@@ -16,9 +16,11 @@
 endif()
 
 configure_file(jsonIn/StyleC.json jsonFiles/StyleC.json)
-configure_file(jsonIn/StyleD.json jsonFiles/sub/StyleD.json)
 configure_file(jsonIn/StyleC.json jsonFiles/StyleC_Custom.json)
+configure_file(jsonIn/StyleD.json jsonFiles/sub/StyleD.json)
 configure_file(jsonIn/StyleD.json jsonFiles/sub/StyleD_Custom.json)
+configure_file(jsonIn/StyleE.json jsonFiles/StyleE.json)
+configure_file(jsonIn/StyleE.json jsonFiles/StyleE_Custom.json)
 
 # Enable automoc
 set(CMAKE_AUTOMOC TRUE)
diff --git a/Tests/QtAutogenRerun/mocPlugin/StyleA.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleA.hpp
index 1b6154d..35158a4 100644
--- a/Tests/QtAutogenRerun/mocPlugin/StyleA.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleA.hpp
@@ -1,13 +1,13 @@
 #ifndef STYLEA_HPP
 #define STYLEA_HPP
 
-#include "StyleCommon.hpp"
+#include "UtilityMacros.hpp"
 #include <QStylePlugin>
 
 class StyleA : public QStylePlugin
 {
   Q_OBJECT
-  // Json file in local directory
+  // Json file in source local directory
   Q_PLUGIN_METADATA(IID "org.styles.A" FILE "StyleA.json")
   A_CUSTOM_MACRO(SomeArg, "StyleA_Custom.json", AnotherArg)
 public:
diff --git a/Tests/QtAutogenRerun/mocPlugin/StyleB.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleB.hpp
index 163c9b2..15b79c5 100644
--- a/Tests/QtAutogenRerun/mocPlugin/StyleB.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleB.hpp
@@ -1,13 +1,13 @@
 #ifndef STYLEB_HPP
 #define STYLEB_HPP
 
-#include "StyleCommon.hpp"
+#include "UtilityMacros.hpp"
 #include <QStylePlugin>
 
 class StyleB : public QStylePlugin
 {
   Q_OBJECT
-  // Json file in local subdirectory
+  // Json file in source local subdirectory
   Q_PLUGIN_METADATA(IID "org.styles.B" FILE "jsonIn/StyleB.json")
   A_CUSTOM_MACRO(SomeArg, "jsonIn/StyleB_Custom.json", AnotherArg)
 public:
diff --git a/Tests/QtAutogenRerun/mocPlugin/StyleC.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleC.hpp
index 52a887a..b0a4115 100644
--- a/Tests/QtAutogenRerun/mocPlugin/StyleC.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleC.hpp
@@ -1,7 +1,7 @@
 #ifndef STYLEC_HPP
 #define STYLEC_HPP
 
-#include "StyleCommon.hpp"
+#include "UtilityMacros.hpp"
 #include <QStylePlugin>
 
 class StyleC : public QStylePlugin
diff --git a/Tests/QtAutogenRerun/mocPlugin/StyleD.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleD.hpp
index df8a439..9696aaa 100644
--- a/Tests/QtAutogenRerun/mocPlugin/StyleD.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleD.hpp
@@ -1,7 +1,7 @@
 #ifndef STYLED_HPP
 #define STYLED_HPP
 
-#include "StyleCommon.hpp"
+#include "UtilityMacros.hpp"
 #include <QStylePlugin>
 
 class StyleD : public QStylePlugin
diff --git a/Tests/QtAutogenRerun/mocPlugin/StyleE.cpp b/Tests/QtAutogenRerun/mocPlugin/StyleE.cpp
index 8fc9a7f..3448319 100644
--- a/Tests/QtAutogenRerun/mocPlugin/StyleE.cpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleE.cpp
@@ -4,3 +4,6 @@
 {
   return 0;
 }
+
+// AUTOMOC the StyleEInclude.hpp header
+#include "moc_StyleEInclude.cpp"
diff --git a/Tests/QtAutogenRerun/mocPlugin/StyleE.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleE.hpp
index e7915a8..a069034 100644
--- a/Tests/QtAutogenRerun/mocPlugin/StyleE.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleE.hpp
@@ -1,17 +1,10 @@
 #ifndef STYLEE_HPP
 #define STYLEE_HPP
 
-#include "StyleCommon.hpp"
-#include <QStylePlugin>
-
-class StyleE : public QStylePlugin
-{
-  Q_OBJECT
-  // No Json file
-  Q_PLUGIN_METADATA(IID "org.styles.E")
-  A_CUSTOM_MACRO(SomeArg, InvalidFileArg, AnotherArg)
-public:
-  QStyle* create(const QString& key);
-};
+// The included file is not in the sources list and won't be detected by
+// AUTOMOC source file with the same base name.
+// It is registered to AUTOMOCed via a moc_<NAME>.cpp include in StyleE.cpp
+// though.
+#include "StyleEInclude.hpp"
 
 #endif
diff --git a/Tests/QtAutogenRerun/mocPlugin/StyleEInclude.hpp b/Tests/QtAutogenRerun/mocPlugin/StyleEInclude.hpp
new file mode 100644
index 0000000..f9734db
--- /dev/null
+++ b/Tests/QtAutogenRerun/mocPlugin/StyleEInclude.hpp
@@ -0,0 +1,17 @@
+#ifndef STYLEE_INCLUDE_HPP
+#define STYLEE_INCLUDE_HPP
+
+#include "UtilityMacros.hpp"
+#include <QStylePlugin>
+
+class StyleE : public QStylePlugin
+{
+  Q_OBJECT
+  // Json files in global root directory
+  Q_PLUGIN_METADATA(IID "org.styles.E" FILE "StyleE.json")
+  A_CUSTOM_MACRO(SomeArg, "StyleE_Custom.json", AnotherArg)
+public:
+  QStyle* create(const QString& key);
+};
+
+#endif
diff --git a/Tests/QtAutogenRerun/mocPlugin/StyleCommon.hpp b/Tests/QtAutogenRerun/mocPlugin/UtilityMacros.hpp
similarity index 65%
rename from Tests/QtAutogenRerun/mocPlugin/StyleCommon.hpp
rename to Tests/QtAutogenRerun/mocPlugin/UtilityMacros.hpp
index f1a7ec6..53a4284 100644
--- a/Tests/QtAutogenRerun/mocPlugin/StyleCommon.hpp
+++ b/Tests/QtAutogenRerun/mocPlugin/UtilityMacros.hpp
@@ -1,5 +1,5 @@
-#ifndef STYLECOMMON_HPP
-#define STYLECOMMON_HPP
+#ifndef UTILITYMACROS_HPP
+#define UTILITYMACROS_HPP
 
 // Empty test macro definition
 #define A_CUSTOM_MACRO(name, jsonFile, pluginRegistrations)
diff --git a/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB.json b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB.json
index 129cac4..cd155dc 100644
--- a/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB.json
+++ b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleB.json
@@ -1 +1 @@
-{ "Keys": [ "Rocket", "StarbusterB" ] }
+{ "Keys": [ "Red", "Green" ] }
diff --git a/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleE.json b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleE.json
new file mode 100644
index 0000000..5412c94
--- /dev/null
+++ b/Tests/QtAutogenRerun/mocPlugin/jsonIn/StyleE.json
@@ -0,0 +1 @@
+{ "Keys": [ "Floor", "Ceiling" ] }
diff --git a/Tests/QtAutogenRerun/mocRerun.cmake b/Tests/QtAutogenRerun/mocRerun.cmake
new file mode 100644
index 0000000..a92912b
--- /dev/null
+++ b/Tests/QtAutogenRerun/mocRerun.cmake
@@ -0,0 +1,60 @@
+
+set(timeformat "%Y%j%H%M%S")
+set(mocRerunSrcDir "${CMAKE_CURRENT_SOURCE_DIR}/mocRerun")
+set(mocRerunBinDir "${CMAKE_CURRENT_BINARY_DIR}/mocRerun")
+
+# Initial build
+configure_file("${mocRerunSrcDir}/test1a.h.in" "${mocRerunBinDir}/test1.h" COPYONLY)
+try_compile(MOC_RERUN
+  "${mocRerunBinDir}"
+  "${mocRerunSrcDir}"
+  mocRerun
+  CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+              "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+              "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
+  OUTPUT_VARIABLE output
+)
+if (NOT MOC_RERUN)
+  message(SEND_ERROR "Initial build of mocRerun failed. Output: ${output}")
+endif()
+# Get name of the output binary
+file(STRINGS "${mocRerunBinDir}/mocRerun.txt" mocRerunList ENCODING UTF-8)
+list(GET mocRerunList 0 mocRerunBin)
+
+message("Changing the header content for a MOC rerun")
+# - Acquire binary timestamps before the build
+file(TIMESTAMP "${mocRerunBin}" timeBefore "${timeformat}")
+# - Ensure that the timestamp will change
+# - Change header file content and rebuild
+# - Rebuild
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+configure_file("${mocRerunSrcDir}/test1b.h.in" "${mocRerunBinDir}/test1.h" COPYONLY)
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocRerunBinDir}" RESULT_VARIABLE result )
+if (result)
+  message(SEND_ERROR "Second build of mocRerun failed.")
+endif()
+# - Acquire binary timestamps after the build
+file(TIMESTAMP "${mocRerunBin}" timeAfter "${timeformat}")
+# - Test if timestamps changed
+if (NOT timeAfter GREATER timeBefore)
+  message(SEND_ERROR "File (${mocRerunBin}) should have changed!")
+endif()
+
+
+message("Changing nothing for a MOC rerun")
+# - Acquire binary timestamps before the build
+file(TIMESTAMP "${mocRerunBin}" timeBefore "${timeformat}")
+# - Ensure that the timestamp would change
+# - Change nothing
+# - Rebuild
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocRerunBinDir}" RESULT_VARIABLE result )
+if (result)
+  message(SEND_ERROR "Third build of mocRerun failed.")
+endif()
+# - Acquire binary timestamps after the build
+file(TIMESTAMP "${mocRerunBin}" timeAfter "${timeformat}")
+# - Test if timestamps changed
+if (timeAfter GREATER timeBefore)
+  message(SEND_ERROR "File (${mocRerunBin}) should not have changed!")
+endif()
diff --git a/Tests/QtAutogenRerun/mocRerun/CMakeLists.txt b/Tests/QtAutogenRerun/mocRerun/CMakeLists.txt
index 7380bdd..bafd9cf 100644
--- a/Tests/QtAutogenRerun/mocRerun/CMakeLists.txt
+++ b/Tests/QtAutogenRerun/mocRerun/CMakeLists.txt
@@ -19,17 +19,15 @@
 
 # Generated source file
 add_custom_command(OUTPUT main.cpp
-                   COMMAND ${CMAKE_COMMAND} -E sleep 2
-                   COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
-                   )
+  COMMAND ${CMAKE_COMMAND} -E sleep 2
+  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/main.cpp)
 
 add_executable(mocRerun
   ${CMAKE_CURRENT_BINARY_DIR}/test1.h
   ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
-  res1.qrc
-  )
+  res1.qrc)
 target_include_directories(mocRerun PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
 target_link_libraries(mocRerun ${QT_CORE_TARGET})
 # Write target name to text file
 add_custom_command(TARGET mocRerun POST_BUILD COMMAND
-  ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:mocRerun>" > target1.txt)
+  ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:mocRerun>" > mocRerun.txt)
diff --git a/Tests/QtAutogenRerun/rccDepends.cmake b/Tests/QtAutogenRerun/rccDepends.cmake
new file mode 100644
index 0000000..68e1482
--- /dev/null
+++ b/Tests/QtAutogenRerun/rccDepends.cmake
@@ -0,0 +1,131 @@
+# When a .qrc or a file listed in a .qrc file changes,
+# the target must be rebuilt
+set(timeformat "%Y%j%H%M%S")
+set(rccDepSD "${CMAKE_CURRENT_SOURCE_DIR}/rccDepends")
+set(rccDepBD "${CMAKE_CURRENT_BINARY_DIR}/rccDepends")
+
+# Initial build
+configure_file(${rccDepSD}/resPlainA.qrc.in ${rccDepBD}/resPlain.qrc COPYONLY)
+configure_file(${rccDepSD}/resGenA.qrc.in ${rccDepBD}/resGen.qrc.in COPYONLY)
+try_compile(RCC_DEPENDS
+  "${rccDepBD}"
+  "${rccDepSD}"
+  rccDepends
+  CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+              "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+              "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
+  OUTPUT_VARIABLE output
+)
+if (NOT RCC_DEPENDS)
+  message(SEND_ERROR "Initial build of rccDepends failed. Output: ${output}")
+endif()
+
+# Get name of the output binaries
+file(STRINGS "${rccDepBD}/targetPlain.txt" targetListPlain ENCODING UTF-8)
+file(STRINGS "${rccDepBD}/targetGen.txt" targetListGen ENCODING UTF-8)
+list(GET targetListPlain 0 rccDepBinPlain)
+list(GET targetListGen 0 rccDepBinGen)
+message("Target that uses a plain .qrc file is:\n  ${rccDepBinPlain}")
+message("Target that uses a GENERATED .qrc file is:\n  ${rccDepBinGen}")
+
+
+message("Changing a resource files listed in the .qrc file")
+# - Acquire binary timestamps before the build
+file(TIMESTAMP "${rccDepBinPlain}" rdPlainBefore "${timeformat}")
+file(TIMESTAMP "${rccDepBinGen}" rdGenBefore "${timeformat}")
+# - Ensure that the timestamp will change
+# - Change a resource files listed in the .qrc file
+# - Rebuild
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resPlain/input.txt")
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resGen/input.txt")
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
+if (result)
+  message(SEND_ERROR "Second build of rccDepends failed.")
+endif()
+# - Acquire binary timestamps after the build
+file(TIMESTAMP "${rccDepBinPlain}" rdPlainAfter "${timeformat}")
+file(TIMESTAMP "${rccDepBinGen}" rdGenAfter "${timeformat}")
+# - Test if timestamps changed
+if (NOT rdPlainAfter GREATER rdPlainBefore)
+  message(SEND_ERROR "Plain .qrc binary ${rccDepBinPlain}) should have changed!")
+endif()
+if (NOT rdGenAfter GREATER rdGenBefore)
+  message(SEND_ERROR "GENERATED .qrc binary ${rccDepBinGen} should have changed!")
+endif()
+
+
+message("Changing a the .qrc file")
+# - Acquire binary timestamps before the build
+file(TIMESTAMP "${rccDepBinPlain}" rdPlainBefore "${timeformat}")
+file(TIMESTAMP "${rccDepBinGen}" rdGenBefore "${timeformat}")
+# - Ensure that the timestamp will change
+# - Change the .qrc file
+# - Rebuild
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+configure_file(${rccDepSD}/resPlainB.qrc.in ${rccDepBD}/resPlain.qrc COPYONLY)
+configure_file(${rccDepSD}/resGenB.qrc.in ${rccDepBD}/resGen.qrc.in COPYONLY)
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
+if (result)
+  message(SEND_ERROR "Third build of rccDepends failed.")
+endif()
+# - Acquire binary timestamps after the build
+file(TIMESTAMP "${rccDepBinPlain}" rdPlainAfter "${timeformat}")
+file(TIMESTAMP "${rccDepBinGen}" rdGenAfter "${timeformat}")
+# - Test if timestamps changed
+if (NOT rdPlainAfter GREATER rdPlainBefore)
+  message(SEND_ERROR "Plain .qrc binary ${rccDepBinPlain}) should have changed!")
+endif()
+if (NOT rdGenAfter GREATER rdGenBefore)
+  message(SEND_ERROR "GENERATED .qrc binary ${rccDepBinGen} should have changed!")
+endif()
+
+
+message("Changing a newly added resource files listed in the .qrc file")
+# - Acquire binary timestamps before the build
+file(TIMESTAMP "${rccDepBinPlain}" rdPlainBefore "${timeformat}")
+file(TIMESTAMP "${rccDepBinGen}" rdGenBefore "${timeformat}")
+# - Ensure that the timestamp will change
+# - Change a newly added resource files listed in the .qrc file
+# - Rebuild
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resPlain/inputAdded.txt")
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resGen/inputAdded.txt")
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
+if (result)
+  message(SEND_ERROR "Fourth build of rccDepends failed.")
+endif()
+# - Acquire binary timestamps after the build
+file(TIMESTAMP "${rccDepBinPlain}" rdPlainAfter "${timeformat}")
+file(TIMESTAMP "${rccDepBinGen}" rdGenAfter "${timeformat}")
+# - Test if timestamps changed
+if (NOT rdPlainAfter GREATER rdPlainBefore)
+  message(SEND_ERROR "Plain .qrc binary ${rccDepBinPlain}) should have changed!")
+endif()
+if (NOT rdGenAfter GREATER rdGenBefore)
+  message(SEND_ERROR "GENERATED .qrc binary ${rccDepBinGen} should have changed!")
+endif()
+
+
+message("Changing nothing in the .qrc file")
+# - Acquire binary timestamps before the build
+file(TIMESTAMP "${rccDepBinPlain}" rdPlainBefore "${timeformat}")
+file(TIMESTAMP "${rccDepBinGen}" rdGenBefore "${timeformat}")
+# - Ensure that the timestamp will change
+# - Change nothing
+# - Rebuild
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
+if (result)
+  message(SEND_ERROR "Fifth build of rccDepends failed.")
+endif()
+# - Acquire binary timestamps after the build
+file(TIMESTAMP "${rccDepBinPlain}" rdPlainAfter "${timeformat}")
+file(TIMESTAMP "${rccDepBinGen}" rdGenAfter "${timeformat}")
+# - Test if timestamps changed
+if (rdPlainAfter GREATER rdPlainBefore)
+  message(SEND_ERROR "Plain .qrc binary ${rccDepBinPlain}) should NOT have changed!")
+endif()
+if (rdGenAfter GREATER rdGenBefore)
+  message(SEND_ERROR "GENERATED .qrc binary ${rccDepBinGen} should NOT have changed!")
+endif()
diff --git a/Tests/QtAutogenRerun/rccDepends/CMakeLists.txt b/Tests/QtAutogenRerun/rccDepends/CMakeLists.txt
index edc0ac3..291592e 100644
--- a/Tests/QtAutogenRerun/rccDepends/CMakeLists.txt
+++ b/Tests/QtAutogenRerun/rccDepends/CMakeLists.txt
@@ -1,8 +1,6 @@
 cmake_minimum_required(VERSION 3.9)
 project(rccDepends CXX)
 
-set(CMAKE_AUTORCC ON)
-
 if (QT_TEST_VERSION STREQUAL 4)
   find_package(Qt4 REQUIRED)
   set(QT_CORE_TARGET Qt4::QtCore)
@@ -15,21 +13,29 @@
   set(QT_CORE_TARGET Qt5::Core)
 endif()
 
-configure_file(res/input1.txt.in res1/input.txt COPYONLY)
-configure_file(res/input1.txt.in res1/inputAdded.txt COPYONLY)
-configure_file(res/input2.txt.in res2/input.txt COPYONLY)
-configure_file(res/input2.txt.in res2/inputAdded.txt COPYONLY)
-# Dependency generated qrc file
-add_custom_command(OUTPUT res2.qrc
-                   DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/res2.qrc.in
-                   COMMAND ${CMAKE_COMMAND} -E sleep 2
-                   COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/res2.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/res2.qrc
-                   )
+# Enable AUTORCC for all targets
+set(CMAKE_AUTORCC ON)
 
-add_executable(rccDepends
-  main.cpp
-  ${CMAKE_CURRENT_BINARY_DIR}/res1.qrc
-  ${CMAKE_CURRENT_BINARY_DIR}/res2.qrc )
-target_link_libraries(rccDepends ${QT_CORE_TARGET})
-add_custom_command(TARGET rccDepends POST_BUILD COMMAND
-  ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:rccDepends>" > target.txt)
+# Initial resource files setup
+configure_file(resPlain/input.txt.in resPlain/input.txt COPYONLY)
+configure_file(resPlain/input.txt.in resPlain/inputAdded.txt COPYONLY)
+configure_file(resGen/input.txt.in resGen/input.txt COPYONLY)
+configure_file(resGen/input.txt.in resGen/inputAdded.txt COPYONLY)
+
+# Generated qrc file with dependency
+add_custom_command(OUTPUT resGen.qrc
+  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/resGen.qrc.in
+  COMMAND ${CMAKE_COMMAND} -E sleep 2
+  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/resGen.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/resGen.qrc)
+
+# Target that uses a plain .qrc file
+add_executable(rccDependsPlain main.cpp ${CMAKE_CURRENT_BINARY_DIR}/resPlain.qrc)
+target_link_libraries(rccDependsPlain ${QT_CORE_TARGET})
+add_custom_command(TARGET rccDependsPlain POST_BUILD COMMAND
+  ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:rccDependsPlain>" > targetPlain.txt)
+
+# Target that uses a GENERATED .qrc file
+add_executable(rccDependsGen main.cpp ${CMAKE_CURRENT_BINARY_DIR}/resGen.qrc )
+target_link_libraries(rccDependsGen ${QT_CORE_TARGET})
+add_custom_command(TARGET rccDependsGen POST_BUILD COMMAND
+  ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:rccDependsGen>" > targetGen.txt)
diff --git a/Tests/QtAutogenRerun/rccDepends/res/input1.txt.in b/Tests/QtAutogenRerun/rccDepends/res/input1.txt.in
deleted file mode 100644
index da62762..0000000
--- a/Tests/QtAutogenRerun/rccDepends/res/input1.txt.in
+++ /dev/null
@@ -1 +0,0 @@
-Res1 input.
diff --git a/Tests/QtAutogenRerun/rccDepends/res/input2.txt.in b/Tests/QtAutogenRerun/rccDepends/res/input2.txt.in
deleted file mode 100644
index 08e14b7..0000000
--- a/Tests/QtAutogenRerun/rccDepends/res/input2.txt.in
+++ /dev/null
@@ -1 +0,0 @@
-Res2 input.
diff --git a/Tests/QtAutogenRerun/rccDepends/res1a.qrc.in b/Tests/QtAutogenRerun/rccDepends/res1a.qrc.in
deleted file mode 100644
index d111ffb..0000000
--- a/Tests/QtAutogenRerun/rccDepends/res1a.qrc.in
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
-    <qresource prefix="/Texts1">
-        <file>res1/input.txt</file>
-    </qresource>
-</RCC>
diff --git a/Tests/QtAutogenRerun/rccDepends/res1b.qrc.in b/Tests/QtAutogenRerun/rccDepends/res1b.qrc.in
deleted file mode 100644
index 4cb3f04..0000000
--- a/Tests/QtAutogenRerun/rccDepends/res1b.qrc.in
+++ /dev/null
@@ -1,6 +0,0 @@
-<RCC>
-    <qresource prefix="/Texts1">
-        <file>res1/input.txt</file>
-        <file alias="Added">res1/inputAdded.txt</file>
-    </qresource>
-</RCC>
diff --git a/Tests/QtAutogenRerun/rccDepends/res2a.qrc.in b/Tests/QtAutogenRerun/rccDepends/res2a.qrc.in
deleted file mode 100644
index 19f34ac..0000000
--- a/Tests/QtAutogenRerun/rccDepends/res2a.qrc.in
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
-    <qresource prefix="/Texts2">
-        <file>res2/input.txt</file>
-    </qresource>
-</RCC>
diff --git a/Tests/QtAutogenRerun/rccDepends/res2b.qrc.in b/Tests/QtAutogenRerun/rccDepends/res2b.qrc.in
deleted file mode 100644
index 19e8ba1..0000000
--- a/Tests/QtAutogenRerun/rccDepends/res2b.qrc.in
+++ /dev/null
@@ -1,6 +0,0 @@
-<RCC>
-    <qresource prefix="/Texts2">
-        <file>res2/input.txt</file>
-        <file alias="Added">res2/inputAdded.txt</file>
-    </qresource>
-</RCC>
diff --git a/Tests/QtAutogenRerun/rccDepends/resGen/input.txt.in b/Tests/QtAutogenRerun/rccDepends/resGen/input.txt.in
new file mode 100644
index 0000000..4f24589
--- /dev/null
+++ b/Tests/QtAutogenRerun/rccDepends/resGen/input.txt.in
@@ -0,0 +1 @@
+Generated resource input.
diff --git a/Tests/QtAutogenRerun/rccDepends/resGen/inputAdded.txt.in b/Tests/QtAutogenRerun/rccDepends/resGen/inputAdded.txt.in
new file mode 100644
index 0000000..4f24589
--- /dev/null
+++ b/Tests/QtAutogenRerun/rccDepends/resGen/inputAdded.txt.in
@@ -0,0 +1 @@
+Generated resource input.
diff --git a/Tests/QtAutogenRerun/rccDepends/resGenA.qrc.in b/Tests/QtAutogenRerun/rccDepends/resGenA.qrc.in
new file mode 100644
index 0000000..c131a34
--- /dev/null
+++ b/Tests/QtAutogenRerun/rccDepends/resGenA.qrc.in
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/TextsGenerated">
+        <file>resGen/input.txt</file>
+    </qresource>
+</RCC>
diff --git a/Tests/QtAutogenRerun/rccDepends/resGenB.qrc.in b/Tests/QtAutogenRerun/rccDepends/resGenB.qrc.in
new file mode 100644
index 0000000..8c7e643
--- /dev/null
+++ b/Tests/QtAutogenRerun/rccDepends/resGenB.qrc.in
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/TextsGenerated">
+        <file>resGen/input.txt</file>
+        <file alias="Added">resGen/inputAdded.txt</file>
+    </qresource>
+</RCC>
diff --git a/Tests/QtAutogenRerun/rccDepends/resPlain/input.txt.in b/Tests/QtAutogenRerun/rccDepends/resPlain/input.txt.in
new file mode 100644
index 0000000..a5e407a
--- /dev/null
+++ b/Tests/QtAutogenRerun/rccDepends/resPlain/input.txt.in
@@ -0,0 +1 @@
+Plaint resource input.
diff --git a/Tests/QtAutogenRerun/rccDepends/resPlain/inputAdded.txt.in b/Tests/QtAutogenRerun/rccDepends/resPlain/inputAdded.txt.in
new file mode 100644
index 0000000..a5e407a
--- /dev/null
+++ b/Tests/QtAutogenRerun/rccDepends/resPlain/inputAdded.txt.in
@@ -0,0 +1 @@
+Plaint resource input.
diff --git a/Tests/QtAutogenRerun/rccDepends/resPlainA.qrc.in b/Tests/QtAutogenRerun/rccDepends/resPlainA.qrc.in
new file mode 100644
index 0000000..c135d85
--- /dev/null
+++ b/Tests/QtAutogenRerun/rccDepends/resPlainA.qrc.in
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/TextsPlain">
+        <file>resPlain/input.txt</file>
+    </qresource>
+</RCC>
diff --git a/Tests/QtAutogenRerun/rccDepends/resPlainB.qrc.in b/Tests/QtAutogenRerun/rccDepends/resPlainB.qrc.in
new file mode 100644
index 0000000..186b653
--- /dev/null
+++ b/Tests/QtAutogenRerun/rccDepends/resPlainB.qrc.in
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/TextsPlain">
+        <file>resPlain/input.txt</file>
+        <file alias="Added">resPlain/inputAdded.txt</file>
+    </qresource>
+</RCC>
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/DEB/Helpers.cmake b/Tests/RunCMake/CPack/DEB/Helpers.cmake
index ad1b47b..6d8e84a 100644
--- a/Tests/RunCMake/CPack/DEB/Helpers.cmake
+++ b/Tests/RunCMake/CPack/DEB/Helpers.cmake
@@ -23,7 +23,7 @@
   endif()
 
   if(GENERATOR_SPECIFIC_FORMAT)
-    set(${RESULT_VAR} "${NAME}${COMPONENT}_${VERSION}-${REVISION}_*.deb" PARENT_SCOPE)
+    set(${RESULT_VAR} "${NAME}${COMPONENT}_${VERSION}_*.deb" PARENT_SCOPE)
   else()
     set(${RESULT_VAR} "${NAME}-${VERSION}-*${COMPONENT}.deb" PARENT_SCOPE)
   endif()
diff --git a/Tests/RunCMake/CPack/RPM/Helpers.cmake b/Tests/RunCMake/CPack/RPM/Helpers.cmake
index d8012b1..88fc231 100644
--- a/Tests/RunCMake/CPack/RPM/Helpers.cmake
+++ b/Tests/RunCMake/CPack/RPM/Helpers.cmake
@@ -23,6 +23,9 @@
   endif()
 
   if(GENERATOR_SPECIFIC_FORMAT)
+    if(NOT REVISION)
+      set(REVISION "1")
+    endif()
     set(${RESULT_VAR} "${NAME}${COMPONENT}-${VERSION}-${REVISION}.*.rpm" PARENT_SCOPE)
   else()
     set(${RESULT_VAR} "${NAME}-${VERSION}-*${COMPONENT}.rpm" PARENT_SCOPE)
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index faf151a..04ac584 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -10,6 +10,7 @@
 run_cpack_test(DEPENDENCIES "RPM;DEB" true "COMPONENT")
 run_cpack_test(DIST "RPM" false "MONOLITHIC")
 run_cpack_test(EMPTY_DIR "RPM;DEB;TGZ" true "MONOLITHIC;COMPONENT")
+run_cpack_test(VERSION "RPM;DEB" false "MONOLITHIC;COMPONENT")
 run_cpack_test(EXTRA "DEB" false "COMPONENT")
 run_cpack_test(GENERATE_SHLIBS "DEB" true "COMPONENT")
 run_cpack_test(GENERATE_SHLIBS_LDCONFIG "DEB" true "COMPONENT")
@@ -27,3 +28,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/VerifyResult.cmake b/Tests/RunCMake/CPack/VerifyResult.cmake
index 470ebf7..1f5ab87 100644
--- a/Tests/RunCMake/CPack/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/VerifyResult.cmake
@@ -8,9 +8,7 @@
     endif()
     if(NOT DEFINED EXPECTED_FILE_${FILE_NO}_VERSION)
       set(EXPECTED_FILE_${FILE_NO}_VERSION "0.1.1")
-    endif()
-    if(NOT DEFINED EXPECTED_FILE_${FILE_NO}_REVISION)
-      set(EXPECTED_FILE_${FILE_NO}_REVISION "1")
+      set(EXPECTED_FILE_${FILE_NO}_VERSION "0.1.1" PARENT_SCOPE)
     endif()
 
     getPackageNameGlobexpr("${EXPECTED_FILE_${FILE_NO}_NAME}"
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/CPack/tests/PACKAGE_CHECKSUM/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/PACKAGE_CHECKSUM/VerifyResult.cmake
index e4f9618..2bb4d3f 100644
--- a/Tests/RunCMake/CPack/tests/PACKAGE_CHECKSUM/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/tests/PACKAGE_CHECKSUM/VerifyResult.cmake
@@ -1,8 +1,7 @@
 if(NOT ${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid")
-  string(TOLOWER ${RunCMake_SUBTEST_SUFFIX} EXTENSION)
+  string(TOLOWER ${RunCMake_SUBTEST_SUFFIX} CHECKSUM_EXTENSION)
   file(GLOB PACKAGE RELATIVE ${bin_dir} "*.tar.gz")
-  file(GLOB CSUMFILE RELATIVE ${bin_dir} "*.${EXTENSION}")
-  file(STRINGS ${CSUMFILE} CHSUM_VALUE)
+  file(STRINGS ${PACKAGE}.${CHECKSUM_EXTENSION} CHSUM_VALUE)
   file(${RunCMake_SUBTEST_SUFFIX} ${PACKAGE} expected_value )
   set(expected_value "${expected_value}  ${PACKAGE}")
 
diff --git a/Tests/RunCMake/CPack/tests/VERSION/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/VERSION/ExpectedFiles.cmake
new file mode 100644
index 0000000..85c571c
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/VERSION/ExpectedFiles.cmake
@@ -0,0 +1,3 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_CONTENT_1_LIST "/usr;/usr/foo;/usr/foo/CMakeLists.txt")
+set(EXPECTED_FILE_1_REVISION "1")
diff --git a/Tests/RunCMake/CPack/tests/VERSION/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/VERSION/VerifyResult.cmake
new file mode 100644
index 0000000..eed9696
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/VERSION/VerifyResult.cmake
@@ -0,0 +1,17 @@
+function(checkPackageInfo_ TYPE FILE REGEX)
+  getPackageInfo("${FILE}" "FILE_INFO_")
+  if(NOT FILE_INFO_ MATCHES "${REGEX}")
+    message(FATAL_ERROR "Unexpected ${TYPE} in '${FILE}' ${EXPECTED_FILE_1_VERSION} ${EXPECTED_FILE_1_REVISION}; file info: '${FILE_INFO_}'")
+  endif()
+endfunction()
+
+set(whitespaces_ "[\t\n\r ]*")
+
+if(GENERATOR_TYPE STREQUAL "RPM")
+  checkPackageInfo_("package version" "${FOUND_FILE_1}" "Version${whitespaces_}:${whitespaces_}${EXPECTED_FILE_1_VERSION}")
+  checkPackageInfo_("package revision" "${FOUND_FILE_1}" "Release${whitespaces_}:${whitespaces_}${EXPECTED_FILE_1_REVISION}")
+  checkPackageInfo_("epoch version" "${FOUND_FILE_1}" "Epoch${whitespaces_}:${whitespaces_}3")
+else() # DEB
+  checkPackageInfo_("version" "${FOUND_FILE_1}"
+    ".*Version${whitespaces_}:${whitespaces_}3:${EXPECTED_FILE_1_VERSION}-${EXPECTED_FILE_1_REVISION}")
+endif()
diff --git a/Tests/RunCMake/CPack/tests/VERSION/test.cmake b/Tests/RunCMake/CPack/tests/VERSION/test.cmake
new file mode 100644
index 0000000..301ab61
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/VERSION/test.cmake
@@ -0,0 +1,14 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+if(GENERATOR_TYPE STREQUAL "DEB")
+  set(package_type_ "DEBIAN")
+  set(CPACK_DEBIAN_PACKAGE_RELEASE "1")
+else()
+  set(package_type_ "${GENERATOR_TYPE}")
+endif()
+
+set(CPACK_${package_type_}_PACKAGE_EPOCH "3")
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+  set(CPACK_COMPONENTS_ALL test)
+endif()
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/Tests/RunCMake/variable_watch/ModifyWatchInCallback.cmake b/Tests/RunCMake/variable_watch/ModifyWatchInCallback.cmake
new file mode 100644
index 0000000..1dee837
--- /dev/null
+++ b/Tests/RunCMake/variable_watch/ModifyWatchInCallback.cmake
@@ -0,0 +1,17 @@
+function (watch2)
+
+endfunction ()
+
+function (watch1)
+  variable_watch(watched watch2)
+  variable_watch(watched watch2)
+  variable_watch(watched watch2)
+  variable_watch(watched watch2)
+  variable_watch(watched watch2)
+  variable_watch(watched watch2)
+endfunction ()
+
+variable_watch(watched watch1)
+variable_watch(watched watch2)
+
+set(access "${watched}")
diff --git a/Tests/RunCMake/variable_watch/RunCMakeTest.cmake b/Tests/RunCMake/variable_watch/RunCMakeTest.cmake
index 9becb4c..2fa6275 100644
--- a/Tests/RunCMake/variable_watch/RunCMakeTest.cmake
+++ b/Tests/RunCMake/variable_watch/RunCMakeTest.cmake
@@ -3,3 +3,4 @@
 run_cmake(ModifiedAccess)
 run_cmake(NoWatcher)
 run_cmake(WatchTwice)
+run_cmake(ModifyWatchInCallback)
diff --git a/Tests/SameName/CMakeLists.txt b/Tests/SameName/CMakeLists.txt
deleted file mode 100644
index d78879d..0000000
--- a/Tests/SameName/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-cmake_minimum_required (VERSION 2.6)
-project(SameName C)
-
-add_subdirectory(Lib1)
-
-include_directories(${PROJECT_SOURCE_DIR}/Lib1)
-add_subdirectory(Exe1)
diff --git a/Tests/SameName/Exe1/CMakeLists.txt b/Tests/SameName/Exe1/CMakeLists.txt
deleted file mode 100644
index b9182f2..0000000
--- a/Tests/SameName/Exe1/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-# a target with the same name as a target in a different dir
-add_executable(mytest_exe conly.c)
-set_target_properties(mytest_exe PROPERTIES OUTPUT_NAME mytest)
-target_link_libraries(mytest_exe mytest)
-
-# and two targets in the same dir with the same name
-add_library(mytest2 ../Lib1/libc1.c)
-
-add_executable(mytest2_exe conly.c)
-set_target_properties(mytest2_exe PROPERTIES OUTPUT_NAME mytest2)
-target_link_libraries(mytest2_exe mytest2)
diff --git a/Tests/SameName/Exe1/conly.c b/Tests/SameName/Exe1/conly.c
deleted file mode 100644
index 8f2ce05..0000000
--- a/Tests/SameName/Exe1/conly.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "libc1.h"
-#include <stdio.h>
-
-int main()
-{
-  if (LibC1Func() != 2.0) {
-    printf("Problem with libc1\n");
-    return 1;
-  }
-  return 0;
-}
diff --git a/Tests/SameName/Lib1/CMakeLists.txt b/Tests/SameName/Lib1/CMakeLists.txt
deleted file mode 100644
index 40fa154..0000000
--- a/Tests/SameName/Lib1/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_library(mytest libc1.c)
diff --git a/Tests/SameName/Lib1/libc1.c b/Tests/SameName/Lib1/libc1.c
deleted file mode 100644
index b01e1e1..0000000
--- a/Tests/SameName/Lib1/libc1.c
+++ /dev/null
@@ -1,4 +0,0 @@
-float LibC1Func()
-{
-  return 2.0;
-}
diff --git a/Tests/SameName/Lib1/libc1.h b/Tests/SameName/Lib1/libc1.h
deleted file mode 100644
index 84c94a9..0000000
--- a/Tests/SameName/Lib1/libc1.h
+++ /dev/null
@@ -1 +0,0 @@
-extern float LibC1Func();
diff --git a/Tests/SimpleExclude/CMakeLists.txt b/Tests/SimpleExclude/CMakeLists.txt
deleted file mode 100644
index baca23e..0000000
--- a/Tests/SimpleExclude/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-cmake_minimum_required (VERSION 2.6)
-project(SimpleExclude C)
-
-set(EXECUTABLE_OUTPUT_PATH "${SimpleExclude_BINARY_DIR}" CACHE INTERNAL "" FORCE)
-set(LIBRARY_OUTPUT_PATH "${SimpleExclude_BINARY_DIR}" CACHE INTERNAL "" FORCE)
-
-add_subdirectory(dirC EXCLUDE_FROM_ALL)
-add_subdirectory(dirD)
-
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/run.cmake.in"
-  "${CMAKE_CURRENT_BINARY_DIR}/run.cmake" @ONLY)
diff --git a/Tests/SimpleExclude/dirC/CMakeLists.txt b/Tests/SimpleExclude/dirC/CMakeLists.txt
deleted file mode 100644
index 9b59fda..0000000
--- a/Tests/SimpleExclude/dirC/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-add_subdirectory(dirA EXCLUDE_FROM_ALL)
-add_subdirectory(dirB)
-
diff --git a/Tests/SimpleExclude/dirC/dirA/CMakeLists.txt b/Tests/SimpleExclude/dirC/dirA/CMakeLists.txt
deleted file mode 100644
index 52fac81..0000000
--- a/Tests/SimpleExclude/dirC/dirA/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_library(t1 STATIC t1.c)
-
-add_library(t2 STATIC t2.c)
-
-add_executable(t3 t3.c)
-
-add_executable(t4 t4.c)
-
-add_executable(t5 t5.c)
-target_link_libraries(t5 t1)
diff --git a/Tests/SimpleExclude/dirC/dirA/t1.c b/Tests/SimpleExclude/dirC/dirA/t1.c
deleted file mode 100644
index 67fe06f..0000000
--- a/Tests/SimpleExclude/dirC/dirA/t1.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <stdio.h>
-
-int tlib1func()
-{
-  Should not be build unless target directory A, B, or C are build;
-  printf("This is T1\n");
-  return 5;
-}
diff --git a/Tests/SimpleExclude/dirC/dirA/t2.c b/Tests/SimpleExclude/dirC/dirA/t2.c
deleted file mode 100644
index 6aaf406..0000000
--- a/Tests/SimpleExclude/dirC/dirA/t2.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-
-int tlib2func()
-{
-  printf("This is T2\n");
-  return 2;
-}
diff --git a/Tests/SimpleExclude/dirC/dirA/t3.c b/Tests/SimpleExclude/dirC/dirA/t3.c
deleted file mode 100644
index 1366dc0..0000000
--- a/Tests/SimpleExclude/dirC/dirA/t3.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-
-int main(int argc, char* argv[])
-{
-  Should not be build unless target directory A, B, or C are build;
-  return 0;
-}
diff --git a/Tests/SimpleExclude/dirC/dirA/t4.c b/Tests/SimpleExclude/dirC/dirA/t4.c
deleted file mode 100644
index b0e4000..0000000
--- a/Tests/SimpleExclude/dirC/dirA/t4.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <stdio.h>
-
-#ifdef __CLASSIC_C__
-int main()
-{
-  int ac;
-  char* av[];
-#else
-int main(int ac, char* av[])
-{
-#endif
-  if (ac > 1000) {
-    return *av[0];
-  }
-  printf("This is T4. This one should work.\n");
-  return 0;
-}
diff --git a/Tests/SimpleExclude/dirC/dirA/t5.c b/Tests/SimpleExclude/dirC/dirA/t5.c
deleted file mode 100644
index 1fba212..0000000
--- a/Tests/SimpleExclude/dirC/dirA/t5.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-
-int main(int argc, char* argv[])
-{
-  Should not be build unless target directory A, B, or C are build;
-  return 5;
-}
diff --git a/Tests/SimpleExclude/dirC/dirB/CMakeLists.txt b/Tests/SimpleExclude/dirC/dirB/CMakeLists.txt
deleted file mode 100644
index ea4650c..0000000
--- a/Tests/SimpleExclude/dirC/dirB/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-add_library(t6 STATIC t6.c)
-
-add_library(t7 STATIC t7.c)
-target_link_libraries(t7 t2)
-
diff --git a/Tests/SimpleExclude/dirC/dirB/t6.c b/Tests/SimpleExclude/dirC/dirB/t6.c
deleted file mode 100644
index e8877df..0000000
--- a/Tests/SimpleExclude/dirC/dirB/t6.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <stdio.h>
-
-int tlib6func()
-{
-  Should not be build unless target directory B, or C are build;
-  printf("This is T6\n");
-  return 6;
-}
diff --git a/Tests/SimpleExclude/dirC/dirB/t7.c b/Tests/SimpleExclude/dirC/dirB/t7.c
deleted file mode 100644
index b613e91..0000000
--- a/Tests/SimpleExclude/dirC/dirB/t7.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <stdio.h>
-
-extern int tlib2func();
-
-int tlib7func()
-{
-  printf("This is T7\n");
-
-  if (tlib2func() != 2) {
-    fprintf(stderr, "Something wrong with T2\n");
-    return 1;
-  }
-
-  return 7;
-}
diff --git a/Tests/SimpleExclude/dirD/CMakeLists.txt b/Tests/SimpleExclude/dirD/CMakeLists.txt
deleted file mode 100644
index 44b8c27..0000000
--- a/Tests/SimpleExclude/dirD/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-add_library(t8 STATIC t8.c)
-
-add_executable(t9 t9.c)
-target_link_libraries(t9 t7)
-
-add_custom_target(t4_custom ALL)
-add_dependencies(t4_custom t4)
diff --git a/Tests/SimpleExclude/dirD/t8.c b/Tests/SimpleExclude/dirD/t8.c
deleted file mode 100644
index bddec6f..0000000
--- a/Tests/SimpleExclude/dirD/t8.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-
-int tlib8func()
-{
-  printf("This is T8\n");
-  return 8;
-}
diff --git a/Tests/SimpleExclude/dirD/t9.c b/Tests/SimpleExclude/dirD/t9.c
deleted file mode 100644
index 9954ea5..0000000
--- a/Tests/SimpleExclude/dirD/t9.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <stdio.h>
-
-extern int tlib7func();
-
-#ifdef __CLASSIC_C__
-int main()
-{
-  int ac;
-  char* av[];
-#else
-int main(int ac, char* av[])
-{
-#endif
-  if (ac > 1000) {
-    return *av[0];
-  }
-  printf("This is T9. This one should work.\n");
-
-  if (tlib7func() != 7) {
-    fprintf(stderr, "Something wrong with T7\n");
-    return 1;
-  }
-  return 0;
-}
diff --git a/Tests/SimpleExclude/run.cmake.in b/Tests/SimpleExclude/run.cmake.in
deleted file mode 100644
index d31d2e5..0000000
--- a/Tests/SimpleExclude/run.cmake.in
+++ /dev/null
@@ -1,13 +0,0 @@
-set(t4_name "\"@CMAKE_CURRENT_BINARY_DIR@${CFG_DIR}/t4\"")
-exec_program("${t4_name}" RETURN_VALUE "t4_var")
-message("T4 ${t4_name} resulted ${t4_var}")
-
-set(t9_name "\"@CMAKE_CURRENT_BINARY_DIR@${CFG_DIR}/t9\"")
-exec_program("${t9_name}" RETURN_VALUE "t9_var")
-message("T9 ${t9_name} resulted ${t9_var}")
-
-if ( "${t4_var}" EQUAL "0" AND "${t9_var}" EQUAL "0" )
-  message("Everything is good, Yoshimi won...")
-else ()
-  message(FATAL_ERROR "Yoshimi lost... The evil pink robots will take over the world")
-endif ()
diff --git a/Tests/VSGNUFortran/runtest.cmake.in b/Tests/VSGNUFortran/runtest.cmake.in
index 987207b..fc05715 100644
--- a/Tests/VSGNUFortran/runtest.cmake.in
+++ b/Tests/VSGNUFortran/runtest.cmake.in
@@ -14,7 +14,7 @@
 string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}")
 message("${MINGW_PATH}")
 set(test_exe "@VSGNUFortran_BINARY_DIR@/bin/c_using_fortran.exe")
-set(ENV{PATH} "${MINGW_PATH}";$ENV{PATH})
+set(ENV{PATH} "${MINGW_PATH};$ENV{PATH}")
 message("run ${test_exe}")
 execute_process(COMMAND "${test_exe}"
   RESULT_VARIABLE res)
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
diff --git a/Utilities/cmlibuv/include/uv-unix.h b/Utilities/cmlibuv/include/uv-unix.h
index d775450..ff59bcb 100644
--- a/Utilities/cmlibuv/include/uv-unix.h
+++ b/Utilities/cmlibuv/include/uv-unix.h
@@ -44,7 +44,9 @@
 
 #include "uv-threadpool.h"
 
-#if defined(__linux__)
+#ifdef CMAKE_BOOTSTRAP
+# include "uv-posix.h"
+#elif defined(__linux__)
 # include "uv-linux.h"
 #elif defined (__MVS__)
 # include "uv-os390.h"
@@ -124,6 +126,17 @@
 typedef int uv_os_sock_t;
 typedef int uv_os_fd_t;
 
+#ifdef CMAKE_BOOTSTRAP
+#define UV_ONCE_INIT 0
+typedef int uv_once_t;
+typedef int uv_thread_t;
+typedef int uv_mutex_t;
+typedef int uv_rwlock_t;
+typedef int uv_sem_t;
+typedef int uv_cond_t;
+typedef int uv_key_t;
+typedef int uv_barrier_t;
+#else
 #define UV_ONCE_INIT PTHREAD_ONCE_INIT
 
 typedef pthread_once_t uv_once_t;
@@ -134,6 +147,7 @@
 typedef pthread_cond_t uv_cond_t;
 typedef pthread_key_t uv_key_t;
 typedef pthread_barrier_t uv_barrier_t;
+#endif
 
 
 /* Platform-specific definitions for uv_spawn support. */
diff --git a/Utilities/cmlibuv/src/unix/cmake-bootstrap.c b/Utilities/cmlibuv/src/unix/cmake-bootstrap.c
new file mode 100644
index 0000000..4f32d03
--- /dev/null
+++ b/Utilities/cmlibuv/src/unix/cmake-bootstrap.c
@@ -0,0 +1,139 @@
+#include "uv.h"
+#include "internal.h"
+
+int uv__tcp_nodelay(int fd, int on) {
+  errno = EINVAL;
+  return -1;
+}
+
+int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
+  errno = EINVAL;
+  return -1;
+}
+
+int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
+  return -EINVAL;
+}
+
+int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
+  return -EINVAL;
+}
+
+void uv__tcp_close(uv_tcp_t* handle) {
+}
+
+void uv__udp_close(uv_udp_t* handle) {
+}
+
+void uv__udp_finish_close(uv_udp_t* handle) {
+}
+
+void uv__fs_poll_close(uv_fs_poll_t* handle) {
+}
+
+int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
+  return 0;
+}
+
+void uv__async_close(uv_async_t* handle) {
+}
+
+int uv__async_fork(uv_loop_t* loop) {
+  return 0;
+}
+
+void uv__async_stop(uv_loop_t* loop) {
+}
+
+void uv__work_submit(uv_loop_t* loop, struct uv__work* w,
+                     void (*work)(struct uv__work* w),
+                     void (*done)(struct uv__work* w, int status)) {
+  abort();
+}
+
+void uv__work_done(uv_async_t* handle) {
+}
+
+int uv__pthread_atfork(void (*prepare)(void), void (*parent)(void),
+                       void (*child)(void)) {
+  return 0;
+}
+
+int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset) {
+  return 0;
+}
+
+int uv_mutex_init(uv_mutex_t* mutex) {
+  return 0;
+}
+
+void uv_mutex_destroy(uv_mutex_t* mutex) {
+}
+
+void uv_mutex_lock(uv_mutex_t* mutex) {
+}
+
+void uv_mutex_unlock(uv_mutex_t* mutex) {
+}
+
+int uv_rwlock_init(uv_rwlock_t* rwlock) {
+  return 0;
+}
+
+void uv_rwlock_destroy(uv_rwlock_t* rwlock) {
+}
+
+void uv_rwlock_wrlock(uv_rwlock_t* rwlock) {
+}
+
+void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
+}
+
+void uv_rwlock_rdlock(uv_rwlock_t* rwlock) {
+}
+
+void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) {
+}
+
+void uv_once(uv_once_t* guard, void (*callback)(void)) {
+  if (*guard) {
+    return;
+  }
+  *guard = 1;
+  callback();
+}
+
+#if defined(__linux__)
+int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
+  errno = ENOSYS;
+  return -1;
+}
+
+int uv__dup3(int oldfd, int newfd, int flags) {
+  errno = ENOSYS;
+  return -1;
+}
+
+int uv__pipe2(int pipefd[2], int flags) {
+  errno = ENOSYS;
+  return -1;
+}
+
+ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt,
+                   int64_t offset) {
+  errno = ENOSYS;
+  return -1;
+}
+
+ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt,
+                    int64_t offset) {
+  errno = ENOSYS;
+  return -1;
+}
+
+int uv__utimesat(int dirfd, const char* path, const struct timespec times[2],
+                 int flags) {
+  errno = ENOSYS;
+  return -1;
+}
+#endif
diff --git a/Utilities/cmlibuv/src/unix/fs.c b/Utilities/cmlibuv/src/unix/fs.c
index 8a4ba7a..82c91ef 100644
--- a/Utilities/cmlibuv/src/unix/fs.c
+++ b/Utilities/cmlibuv/src/unix/fs.c
@@ -244,7 +244,7 @@
 #endif
 }
 
-#if defined(__sun) && _XOPEN_SOURCE < 600
+#if defined(__sun) && (_XOPEN_SOURCE < 600 || defined(CMAKE_BOOTSTRAP))
 static char* uv__mkdtemp(char *template)
 {
   if (!mktemp(template) || mkdir(template, 0700))
diff --git a/Utilities/cmlibuv/src/unix/internal.h b/Utilities/cmlibuv/src/unix/internal.h
index 2e3afa6..e9f7908 100644
--- a/Utilities/cmlibuv/src/unix/internal.h
+++ b/Utilities/cmlibuv/src/unix/internal.h
@@ -59,7 +59,17 @@
 # include <AvailabilityMacros.h>
 #endif
 
-#if defined(__ANDROID__)
+#if defined(CMAKE_BOOTSTRAP)
+# undef pthread_atfork
+# define pthread_atfork(prepare, parent, child) \
+     uv__pthread_atfork(prepare, parent, child)
+int uv__pthread_atfork(void (*prepare)(void), void (*parent)(void),
+                       void (*child)(void));
+# undef pthread_sigmask
+# define pthread_sigmask(how, set, oldset) \
+     uv__pthread_sigmask(how, set, oldset)
+int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
+#elif defined(__ANDROID__)
 int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
 # ifdef pthread_sigmask
 # undef pthread_sigmask
@@ -261,7 +271,7 @@
 int uv__getpwuid_r(uv_passwd_t* pwd);
 
 
-#if defined(__APPLE__)
+#if defined(__APPLE__) && !defined(CMAKE_BOOTSTRAP)
 int uv___stream_fd(const uv_stream_t* handle);
 #define uv__stream_fd(handle) (uv___stream_fd((const uv_stream_t*) (handle)))
 #else
diff --git a/Utilities/cmlibuv/src/unix/pipe.c b/Utilities/cmlibuv/src/unix/pipe.c
index 7ba1bf8..e3d436d 100644
--- a/Utilities/cmlibuv/src/unix/pipe.c
+++ b/Utilities/cmlibuv/src/unix/pipe.c
@@ -136,7 +136,7 @@
   if (err)
     return err;
 
-#if defined(__APPLE__)
+#if defined(__APPLE__) && !defined(CMAKE_BOOTSTRAP)
   err = uv__stream_try_select((uv_stream_t*) handle, &fd);
   if (err)
     return err;
diff --git a/Utilities/cmlibuv/src/unix/posix-hrtime.c b/Utilities/cmlibuv/src/unix/posix-hrtime.c
index 323dfc2..a264250 100644
--- a/Utilities/cmlibuv/src/unix/posix-hrtime.c
+++ b/Utilities/cmlibuv/src/unix/posix-hrtime.c
@@ -22,6 +22,29 @@
 #include "uv.h"
 #include "internal.h"
 
+#if defined(__APPLE__)
+/* Special case for CMake bootstrap: no clock_gettime on macOS < 10.12 */
+
+#ifndef CMAKE_BOOTSTRAP
+#error "This code path meant only for use during CMake bootstrap."
+#endif
+
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+
+uint64_t uv__hrtime(uv_clocktype_t type) {
+  static mach_timebase_info_data_t info;
+
+  if ((ACCESS_ONCE(uint32_t, info.numer) == 0 ||
+       ACCESS_ONCE(uint32_t, info.denom) == 0) &&
+      mach_timebase_info(&info) != KERN_SUCCESS)
+    abort();
+
+  return mach_absolute_time() * info.numer / info.denom;
+}
+
+#else
+
 #include <stdint.h>
 #include <time.h>
 
@@ -33,3 +56,5 @@
   clock_gettime(CLOCK_MONOTONIC, &ts);
   return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
 }
+
+#endif
diff --git a/Utilities/cmlibuv/src/unix/stream.c b/Utilities/cmlibuv/src/unix/stream.c
index 7b23d16..3857bc8 100644
--- a/Utilities/cmlibuv/src/unix/stream.c
+++ b/Utilities/cmlibuv/src/unix/stream.c
@@ -98,7 +98,7 @@
       loop->emfile_fd = err;
   }
 
-#if defined(__APPLE__)
+#if defined(__APPLE__) && !defined(CMAKE_BOOTSTRAP)
   stream->select = NULL;
 #endif /* defined(__APPLE_) */
 
@@ -107,7 +107,7 @@
 
 
 static void uv__stream_osx_interrupt_select(uv_stream_t* stream) {
-#if defined(__APPLE__)
+#if defined(__APPLE__) && !defined(CMAKE_BOOTSTRAP)
   /* Notify select() thread about state change */
   uv__stream_select_t* s;
   int r;
@@ -131,7 +131,7 @@
 }
 
 
-#if defined(__APPLE__)
+#if defined(__APPLE__) && !defined(CMAKE_BOOTSTRAP)
 static void uv__stream_osx_select(void* arg) {
   uv_stream_t* stream;
   uv__stream_select_t* s;
@@ -1598,7 +1598,7 @@
 }
 
 
-#if defined(__APPLE__)
+#if defined(__APPLE__) && !defined(CMAKE_BOOTSTRAP)
 int uv___stream_fd(const uv_stream_t* handle) {
   const uv__stream_select_t* s;
 
@@ -1619,7 +1619,7 @@
   unsigned int i;
   uv__stream_queued_fds_t* queued_fds;
 
-#if defined(__APPLE__)
+#if defined(__APPLE__) && !defined(CMAKE_BOOTSTRAP)
   /* Terminate select loop first */
   if (handle->select != NULL) {
     uv__stream_select_t* s;
diff --git a/Utilities/cmlibuv/src/uv-common.c b/Utilities/cmlibuv/src/uv-common.c
index bc7d137..fcb910f 100644
--- a/Utilities/cmlibuv/src/uv-common.c
+++ b/Utilities/cmlibuv/src/uv-common.c
@@ -175,6 +175,7 @@
 }
 #undef UV_STRERROR_GEN
 
+#if !defined(CMAKE_BOOTSTRAP) || defined(_WIN32)
 
 int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
   memset(addr, 0, sizeof(*addr));
@@ -343,6 +344,7 @@
     return uv__udp_recv_stop(handle);
 }
 
+#endif
 
 void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
   QUEUE queue;
diff --git a/bootstrap b/bootstrap
index 5afc43b..f7f45cf 100755
--- a/bootstrap
+++ b/bootstrap
@@ -480,6 +480,59 @@
   SystemTools.hxx \
   Terminal.h"
 
+if ${cmake_system_mingw}; then
+  LIBUV_C_SOURCES="\
+    src/fs-poll.c \
+    src/inet.c \
+    src/threadpool.c \
+    src/uv-common.c \
+    src/win/async.c \
+    src/win/core.c \
+    src/win/detect-wakeup.c \
+    src/win/dl.c \
+    src/win/error.c \
+    src/win/fs-event.c \
+    src/win/fs.c \
+    src/win/getaddrinfo.c \
+    src/win/getnameinfo.c \
+    src/win/handle.c \
+    src/win/loop-watcher.c \
+    src/win/pipe.c \
+    src/win/poll.c \
+    src/win/process-stdio.c \
+    src/win/process.c \
+    src/win/req.c \
+    src/win/signal.c \
+    src/win/stream.c \
+    src/win/tcp.c \
+    src/win/thread.c \
+    src/win/timer.c \
+    src/win/tty.c \
+    src/win/udp.c \
+    src/win/util.c \
+    src/win/winapi.c \
+    src/win/winsock.c \
+    "
+else
+  LIBUV_C_SOURCES="\
+    src/uv-common.c \
+    src/unix/cmake-bootstrap.c \
+    src/unix/core.c \
+    src/unix/fs.c \
+    src/unix/loop.c \
+    src/unix/loop-watcher.c \
+    src/unix/no-fsevents.c \
+    src/unix/pipe.c \
+    src/unix/poll.c \
+    src/unix/posix-hrtime.c \
+    src/unix/posix-poll.c \
+    src/unix/process.c \
+    src/unix/signal.c \
+    src/unix/stream.c \
+    src/unix/timer.c \
+    "
+fi
+
 # Display CMake bootstrap usage
 cmake_usage()
 {
@@ -641,6 +694,12 @@
   echo $1 | sed "s/ /\\\\ /g"
 }
 
+# Encode object file names.
+cmake_obj ()
+{
+  echo $1 | sed 's/\//-/g' | sed 's/$/\.o/'
+}
+
 # Strip prefix from argument
 cmake_arg ()
 {
@@ -941,6 +1000,10 @@
 # error "The CMAKE_C_COMPILER is set to a C++ compiler"
 #endif
 
+#if defined(__sun) && __STDC_VERSION__ < 199901L
+#error "On Solaris we need C99."
+#endif
+
 #include <stdio.h>
 
 int main(int argc, char* argv[])
@@ -1180,6 +1243,8 @@
  * ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES}
  * kwSys Sources:
  * ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}
+ * libuv Sources:
+ * ${LIBUV_C_SOURCES}
  */
 "
 
@@ -1207,7 +1272,6 @@
 cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP"
 cmake_report cmConfigure.h${_tmp} "#define CM_EQ_DELETE"
 cmake_report cmConfigure.h${_tmp} "#define CM_FALLTHROUGH"
-cmake_report cmConfigure.h${_tmp} "#define CM_OVERRIDE"
 cmake_report cmConfigure.h${_tmp} "#define CM_DISABLE_COPY(Class)"
 
 # Regenerate configured headers
@@ -1242,6 +1306,48 @@
 for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do
   objs="${objs} ${a}.o"
 done
+for a in ${LIBUV_C_SOURCES}; do
+  objs="${objs} uv-`cmake_obj ${a}`"
+done
+
+libs=""
+
+uv_c_flags=""
+if ${cmake_system_mingw}; then
+  uv_c_flags="${uv_c_flags} -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0600"
+  libs="${libs} -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv"
+else
+  uv_c_flags="${uv_c_flags} -DCMAKE_BOOTSTRAP"
+  case "${cmake_system}" in
+    *AIX*)
+      uv_c_flags="${uv_c_flags} -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT -D_THREAD_SAFE"
+      libs="${libs} -lperfstat"
+      ;;
+    *Darwin*)
+      uv_c_flags="${uv_c_flags} -D_DARWIN_USE_64_BIT_INODE=1 -D_DARWIN_UNLIMITED_SELECT=1"
+      ;;
+    *Linux*)
+      uv_c_flags="${uv_c_flags} -D_GNU_SOURCE"
+      libs="${libs} -ldl -lrt"
+      ;;
+    *BSD*)
+      libs="${libs} -lkvm"
+      ;;
+    *SunOS*)
+      # Normally libuv uses '-D_XOPEN_SOURCE=500 -std=c90' on Solaris 5.10,
+      # but we do not need to do that because we bootstrap using POSIX APIs.
+      uv_c_flags="${uv_c_flags} -D__EXTENSIONS__ -D_XOPEN_SOURCE=600"
+      libs="${libs} -lkstat -lnsl -lsendfile -lsocket -lrt"
+      ;;
+  esac
+fi
+uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/include"`"
+if ${cmake_system_mingw}; then
+  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/win"`"
+else
+  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/unix"`"
+fi
+uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src"`"
 
 if [ "x${cmake_ansi_cxx_flags}" != "x" ]; then
   cmake_cxx_flags="${cmake_ansi_cxx_flags} ${cmake_cxx_flags}"
@@ -1279,7 +1385,7 @@
   -I`cmake_escape \"${cmake_source_dir}/Source/LexerParser\"` \
   -I`cmake_escape \"${cmake_source_dir}/Utilities\"`"
 echo "cmake: ${objs}" > "${cmake_bootstrap_dir}/Makefile"
-echo "	${cmake_cxx_compiler} ${cmake_ld_flags} ${cmake_cxx_flags} ${objs} -o cmake" >> "${cmake_bootstrap_dir}/Makefile"
+echo "	${cmake_cxx_compiler} ${cmake_ld_flags} ${cmake_cxx_flags} ${objs} ${libs} -o cmake" >> "${cmake_bootstrap_dir}/Makefile"
 for a in ${CMAKE_CXX_SOURCES}; do
   src=`cmake_escape "${cmake_source_dir}/Source/${a}.cxx"`
   src_flags=`eval echo \\${cmake_cxx_flags_\${a}}`
@@ -1314,6 +1420,11 @@
   echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
   echo "	${cmake_cxx_compiler} ${cmake_cxx_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
 done
+for a in ${LIBUV_C_SOURCES}; do
+  src=`cmake_escape "${cmake_source_dir}/Utilities/cmlibuv/${a}"`
+  echo "uv-`cmake_obj ${a}` : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+  echo "	${cmake_c_compiler} ${cmake_c_flags} ${uv_c_flags} -c ${src} -o uv-`cmake_obj ${a}`" >> "${cmake_bootstrap_dir}/Makefile"
+done
 echo '
 rebuild_cache:
 	cd "${cmake_binary_dir}" && "${cmake_source_dir}/bootstrap"