Merge topic 'vs-dotnet-standard-core'

ae1e1909a1 VS: Add support for .NET Standard and .NET Core

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4240
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6f4c111..c7d139b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -264,7 +264,6 @@
       ${CMake_BINARY_DIR}/Testing/HTML/TestingResults/Icons/Logo.gif COPYONLY)
   endif()
   mark_as_advanced(DART_ROOT)
-  mark_as_advanced(CURL_TESTING)
 endmacro()
 
 
diff --git a/Help/command/mark_as_advanced.rst b/Help/command/mark_as_advanced.rst
index 5712fb4..e52e623 100644
--- a/Help/command/mark_as_advanced.rst
+++ b/Help/command/mark_as_advanced.rst
@@ -22,3 +22,9 @@
 new values will be marked as advanced, but if a
 variable already has an advanced/non-advanced state,
 it will not be changed.
+
+.. note::
+
+  Policy :policy:`CMP0102` affects the behavior of the ``mark_as_advanced``
+  call. When set to ``NEW``, variables passed to this command which are not
+  already in the cache are ignored. See policy :policy:`CMP0102`.
diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst
index 248eb05..41cd5c2 100644
--- a/Help/generator/Ninja Multi-Config.rst
+++ b/Help/generator/Ninja Multi-Config.rst
@@ -78,4 +78,13 @@
 As a convenience, ``Ninja Multi-Config`` offers a
 :variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE` setting. If this variable is
 specified, a ``build.ninja`` file will be generated which points to the
-specified ``build-<Config>.ninja`` file.
+specified ``build-<Config>.ninja`` file. In addition, if
+:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE` is used in conjunction with
+:variable:`CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE`, you can also specify
+:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS`, which changes the config
+of the ``<target>`` targets in ``build.ninja``. For example, if you set
+:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE` to ``Release``, but set
+:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS` to ``Debug`` or ``all``,
+all ``<target>`` aliases in ``build.ninja`` will resolve to ``<target>:Debug``
+or ``<target>:all``, but custom commands will still use the ``Release``
+configuration.
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 53cf264..c256250 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@
 .. toctree::
    :maxdepth: 1
 
+   CMP0102: mark_as_advanced() does nothing if a cache entry does not exist. </policy/CMP0102>
    CMP0101: target_compile_options honors BEFORE keyword in all scopes. </policy/CMP0101>
    CMP0100: Let AUTOMOC and AUTOUIC process .hh header files. </policy/CMP0100>
    CMP0099: Link properties are transitive over private dependency on static libraries. </policy/CMP0099>
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index a8a0d66..bac8415 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -426,6 +426,7 @@
    /variable/CMAKE_MSVCIDE_RUN_PATH
    /variable/CMAKE_MSVC_RUNTIME_LIBRARY
    /variable/CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE
+   /variable/CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS
    /variable/CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE
    /variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX
    /variable/CMAKE_NO_BUILTIN_CHRPATH
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 4315f0a..44b1f2f 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -279,7 +279,9 @@
          "file": "/full/path/to/the/CMake/file.txt",
          "line": 0,
          "cmd": "add_executable",
-         "args": ["foo", "bar"]
+         "args": ["foo", "bar"],
+         "time": 1579512535.9687231,
+         "frame": 2
        }
 
      The members are:
@@ -288,8 +290,8 @@
        The full path to the CMake source file where the function
        was called.
 
-      ``line``
-       The line in `file` of the function call.
+     ``line``
+       The line in ``file`` of the function call.
 
      ``cmd``
        The name of the function that was called.
@@ -297,6 +299,12 @@
      ``args``
        A string list of all function parameters.
 
+     ``time``
+       Timestamp (seconds since epoch) of the function call.
+
+     ``frame``
+       Stack frame depth of the function that was called.
+
      Additionally, the first JSON document outputted contains the
      ``version`` key for the current major and minor version of the
 
diff --git a/Help/policy/CMP0102.rst b/Help/policy/CMP0102.rst
new file mode 100644
index 0000000..9859006
--- /dev/null
+++ b/Help/policy/CMP0102.rst
@@ -0,0 +1,25 @@
+CMP0102
+-------
+
+The :command:`mark_as_advanced` command no longer creates a cache entry if one
+does not already exist.
+
+In CMake 3.16 and below, if a variable was not defined at all or just defined
+locally, the :command:`mark_as_advanced` command would create a new cache
+entry with an ``UNINITIALIZED`` type and no value. When a :command:`find_path`
+(or other similar ``find_`` command) would next run, it would find this
+undefined cache entry and set it up with an empty string value. This process
+would end up deleting the local variable in the process (due to the way the
+cache works), effectively clearing any stored ``find_`` results that were only
+available in the local scope.
+
+The ``OLD`` behavior for this policy is to create the empty cache definition.
+The ``NEW`` behavior of this policy is to ignore variables which do not
+already exist in the cache.
+
+This policy was introduced in CMake version 3.17.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/dev/fphsa-detect-name-mismatch.rst b/Help/release/dev/fphsa-detect-name-mismatch.rst
new file mode 100644
index 0000000..be51a43
--- /dev/null
+++ b/Help/release/dev/fphsa-detect-name-mismatch.rst
@@ -0,0 +1,5 @@
+fphsa-name-mismatch
+-------------------
+
+* The :module:`FindPackageHandleStandardArgs` module learned to check the
+  package name passed in for typo mistakes.
diff --git a/Help/release/dev/mingw-find-no-dll.rst b/Help/release/dev/mingw-find-no-dll.rst
new file mode 100644
index 0000000..84e7431
--- /dev/null
+++ b/Help/release/dev/mingw-find-no-dll.rst
@@ -0,0 +1,6 @@
+mingw-find-no-dll
+-----------------
+
+* When using MinGW tools, the :command:`find_library` command no longer
+  finds ``.dll`` files by default.  Instead it expects ``.dll.a`` import
+  libraries to be available.
diff --git a/Help/variable/CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS.rst b/Help/variable/CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS.rst
new file mode 100644
index 0000000..a997e9b
--- /dev/null
+++ b/Help/variable/CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS.rst
@@ -0,0 +1,6 @@
+CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS
+-------------------------------------
+
+Controls the config of ``<target>`` aliases in ``build.ninja`` for the
+:generator:`Ninja Multi-Config` generator. See the generator's documentation
+for more details.
diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
index fc52e7b..de71d0e 100644
--- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
@@ -23,6 +23,8 @@
   policy :policy:`CMP0082`.
 * ``CMAKE_POLICY_WARNING_CMP0089`` controls the warning for
   policy :policy:`CMP0089`.
+* ``CMAKE_POLICY_WARNING_CMP0102`` controls the warning for
+  policy :policy:`CMP0102`.
 
 This variable should not be set by a project in CMake code.  Project
 developers running CMake may set this variable in their cache to
diff --git a/Modules/CMakeASM_MASMInformation.cmake b/Modules/CMakeASM_MASMInformation.cmake
index a38c114..9f7e934 100644
--- a/Modules/CMakeASM_MASMInformation.cmake
+++ b/Modules/CMakeASM_MASMInformation.cmake
@@ -10,5 +10,11 @@
 
 set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /c  /Fo <OBJECT> <SOURCE>")
 
+# The ASM_MASM compiler id for this compiler is "MSVC", so fill out the runtime library table.
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded         "")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL      "")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug    "")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
+
 include(CMakeASMInformation)
 set(ASM_DIALECT)
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index e4f75d5..3b46ca5 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -565,8 +565,16 @@
         option(CPACK_BINARY_OSXX11       "Enable to build OSX X11 packages"      OFF)
         option(CPACK_BINARY_PACKAGEMAKER "Enable to build PackageMaker packages" OFF)
         option(CPACK_BINARY_PRODUCTBUILD "Enable to build productbuild packages" OFF)
+        mark_as_advanced(
+          CPACK_BINARY_BUNDLE
+          CPACK_BINARY_DRAGNDROP
+          CPACK_BINARY_OSXX11
+          CPACK_BINARY_PACKAGEMAKER
+          CPACK_BINARY_PRODUCTBUILD
+          )
       else()
         option(CPACK_BINARY_TZ  "Enable to build TZ packages"     ON)
+        mark_as_advanced(CPACK_BINARY_TZ)
       endif()
       option(CPACK_BINARY_DEB  "Enable to build Debian packages"  OFF)
       option(CPACK_BINARY_FREEBSD  "Enable to build FreeBSD packages"  OFF)
@@ -576,6 +584,16 @@
       option(CPACK_BINARY_TBZ2 "Enable to build TBZ2 packages"    OFF)
       option(CPACK_BINARY_TGZ  "Enable to build TGZ packages"     ON)
       option(CPACK_BINARY_TXZ  "Enable to build TXZ packages"     OFF)
+      mark_as_advanced(
+        CPACK_BINARY_DEB
+        CPACK_BINARY_FREEBSD
+        CPACK_BINARY_NSIS
+        CPACK_BINARY_RPM
+        CPACK_BINARY_STGZ
+        CPACK_BINARY_TBZ2
+        CPACK_BINARY_TGZ
+        CPACK_BINARY_TXZ
+        )
     endif()
   else()
     option(CPACK_BINARY_7Z    "Enable to build 7-Zip packages" OFF)
@@ -583,8 +601,16 @@
     option(CPACK_BINARY_NUGET "Enable to build NuGet packages" OFF)
     option(CPACK_BINARY_WIX   "Enable to build WiX packages" OFF)
     option(CPACK_BINARY_ZIP   "Enable to build ZIP packages" OFF)
+    mark_as_advanced(
+      CPACK_BINARY_7Z
+      CPACK_BINARY_NSIS
+      CPACK_BINARY_NUGET
+      CPACK_BINARY_WIX
+      CPACK_BINARY_ZIP
+      )
   endif()
   option(CPACK_BINARY_IFW "Enable to build IFW packages" OFF)
+  mark_as_advanced(CPACK_BINARY_IFW)
 
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_7Z           7Z)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_BUNDLE       Bundle)
@@ -614,6 +640,7 @@
   if(UNIX)
     if(CYGWIN)
       option(CPACK_SOURCE_CYGWIN "Enable to build Cygwin source packages" ON)
+      mark_as_advanced(CPACK_SOURCE_CYGWIN)
     else()
       option(CPACK_SOURCE_RPM  "Enable to build RPM source packages"  OFF)
       option(CPACK_SOURCE_TBZ2 "Enable to build TBZ2 source packages" ON)
@@ -621,10 +648,22 @@
       option(CPACK_SOURCE_TXZ  "Enable to build TXZ source packages"  ON)
       option(CPACK_SOURCE_TZ   "Enable to build TZ source packages"   ON)
       option(CPACK_SOURCE_ZIP  "Enable to build ZIP source packages"  OFF)
+      mark_as_advanced(
+        CPACK_SOURCE_RPM
+        CPACK_SOURCE_TBZ2
+        CPACK_SOURCE_TGZ
+        CPACK_SOURCE_TXZ
+        CPACK_SOURCE_TZ
+        CPACK_SOURCE_ZIP
+        )
     endif()
   else()
     option(CPACK_SOURCE_7Z  "Enable to build 7-Zip source packages" ON)
     option(CPACK_SOURCE_ZIP "Enable to build ZIP source packages" ON)
+    mark_as_advanced(
+      CPACK_SOURCE_7Z
+      CPACK_SOURCE_ZIP
+      )
   endif()
 
   cpack_optional_append(CPACK_SOURCE_GENERATOR  CPACK_SOURCE_7Z      7Z)
@@ -637,38 +676,6 @@
   cpack_optional_append(CPACK_SOURCE_GENERATOR  CPACK_SOURCE_ZIP     ZIP)
 endif()
 
-# mark the above options as advanced
-mark_as_advanced(
-  CPACK_BINARY_7Z
-  CPACK_BINARY_BUNDLE
-  CPACK_BINARY_CYGWIN
-  CPACK_BINARY_DEB
-  CPACK_BINARY_DRAGNDROP
-  CPACK_BINARY_FREEBSD
-  CPACK_BINARY_IFW
-  CPACK_BINARY_NSIS
-  CPACK_BINARY_NUGET
-  CPACK_BINARY_OSXX11
-  CPACK_BINARY_PACKAGEMAKER
-  CPACK_BINARY_PRODUCTBUILD
-  CPACK_BINARY_RPM
-  CPACK_BINARY_STGZ
-  CPACK_BINARY_TBZ2
-  CPACK_BINARY_TGZ
-  CPACK_BINARY_TXZ
-  CPACK_BINARY_TZ
-  CPACK_BINARY_WIX
-  CPACK_BINARY_ZIP
-  CPACK_SOURCE_7Z
-  CPACK_SOURCE_CYGWIN
-  CPACK_SOURCE_RPM
-  CPACK_SOURCE_TBZ2
-  CPACK_SOURCE_TGZ
-  CPACK_SOURCE_TXZ
-  CPACK_SOURCE_TZ
-  CPACK_SOURCE_ZIP
-  )
-
 # Set some other variables
 _cpack_set_default(CPACK_INSTALL_CMAKE_PROJECTS
   "${CMAKE_BINARY_DIR};${CMAKE_PROJECT_NAME};ALL;/")
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake
index 1a51bc8..8109108 100644
--- a/Modules/CTest.cmake
+++ b/Modules/CTest.cmake
@@ -243,7 +243,6 @@
 
   mark_as_advanced(
     BZRCOMMAND
-    BZR_UPDATE_OPTIONS
     COVERAGE_COMMAND
     COVERAGE_EXTRA_FLAGS
     CTEST_SUBMIT_RETRY_DELAY
@@ -257,13 +256,10 @@
     MAKECOMMAND
     MEMORYCHECK_COMMAND
     MEMORYCHECK_SUPPRESSIONS_FILE
-    PURIFYCOMMAND
-    SCPCOMMAND
     SLURM_SBATCH_COMMAND
     SLURM_SRUN_COMMAND
     SITE
     SVNCOMMAND
-    SVN_UPDATE_OPTIONS
     )
   if(NOT RUN_FROM_DART)
     set(RUN_FROM_CTEST_OR_DART 1)
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index dc73f16..23b5fa7 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -8,8 +8,9 @@
 Find Basic Linear Algebra Subprograms (BLAS) library
 
 This module finds an installed Fortran library that implements the
-BLAS linear-algebra interface (see http://www.netlib.org/blas/).  The
-list of libraries searched for is taken from the ``autoconf`` macro file,
+BLAS linear-algebra interface (see http://www.netlib.org/blas/).
+
+The approach follows that taken for the ``autoconf`` macro file,
 ``acx_blas.m4`` (distributed at
 http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
 
@@ -25,28 +26,28 @@
   If set, checks only the specified vendor, if not set checks all the
   possibilities.  List of vendors valid in this module:
 
-  * Goto
-  * OpenBLAS
-  * FLAME
-  * ATLAS PhiPACK
-  * CXML
-  * DXML
-  * SunPerf
-  * SCSL
-  * SGIMATH
-  * IBMESSL
-  * Intel10_32 (intel mkl v10 32 bit)
-  * Intel10_64lp (intel mkl v10+ 64 bit, threaded code, lp64 model)
-  * Intel10_64lp_seq (intel mkl v10+ 64 bit, sequential code, lp64 model)
-  * Intel10_64ilp (intel mkl v10+ 64 bit, threaded code, ilp64 model)
-  * Intel10_64ilp_seq (intel mkl v10+ 64 bit, sequential code, ilp64 model)
-  * Intel (obsolete versions of mkl 32 and 64 bit)
-  * ACML
-  * ACML_MP
-  * ACML_GPU
-  * Apple
-  * NAS
-  * Generic
+  * ``Goto``
+  * ``OpenBLAS``
+  * ``FLAME``
+  * ``ATLAS PhiPACK``
+  * ``CXML``
+  * ``DXML``
+  * ``SunPerf``
+  * ``SCSL``
+  * ``SGIMATH``
+  * ``IBMESSL``
+  * ``Intel10_32`` (intel mkl v10 32 bit)
+  * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model)
+  * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model)
+  * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model)
+  * ``Intel10_64ilp_seq`` (intel mkl v10+ 64 bit, sequential code, ilp64 model)
+  * ``Intel`` (obsolete versions of mkl 32 and 64 bit)
+  * ``ACML``
+  * ``ACML_MP``
+  * ``ACML_GPU``
+  * ``Apple``
+  * ``NAS``
+  * ``Generic``
 
 ``BLA_F95``
   if ``ON`` tries to find the BLAS95 interfaces
@@ -92,17 +93,8 @@
 
 #]=======================================================================]
 
-include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-cmake_push_check_state()
-set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY})
-
-set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
-
 # Check the language being used
-if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED) )
+if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED))
   if(BLAS_FIND_REQUIRED)
     message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
   else()
@@ -111,6 +103,18 @@
   endif()
 endif()
 
+if(CMAKE_Fortran_COMPILER_LOADED)
+  include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
+else()
+  include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
+endif()
+include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+cmake_push_check_state()
+set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY})
+
+set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+
 if(BLA_PREFER_PKGCONFIG)
   find_package(PkgConfig)
   pkg_check_modules(PKGC_BLAS blas)
@@ -121,7 +125,9 @@
   endif()
 endif()
 
-macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread)
+# TODO: move this stuff to a separate module
+
+macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs)
   # This macro checks for the existence of the combination of fortran libraries
   # given by _list.  If the combination is found, this macro checks (using the
   # Check_Fortran_Function_Exists macro) whether can link against that library
@@ -138,53 +144,54 @@
   set(_libraries_work TRUE)
   set(${LIBRARIES})
   set(_combined_name)
-  if (NOT _libdir)
-    if (WIN32)
+  if(NOT _libdir)
+    if(WIN32)
       set(_libdir ENV LIB)
-    elseif (APPLE)
+    elseif(APPLE)
       set(_libdir ENV DYLD_LIBRARY_PATH)
-    else ()
+    else()
       set(_libdir ENV LD_LIBRARY_PATH)
-    endif ()
-  endif ()
+    endif()
+  endif()
 
   list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
 
   foreach(_library ${_list})
     set(_combined_name ${_combined_name}_${_library})
-    if(NOT "${_thread}" STREQUAL "")
-      set(_combined_name ${_combined_name}_thread)
+    if(NOT "${_threadlibs}" STREQUAL "")
+      set(_combined_name ${_combined_name}_threadlibs)
     endif()
     if(_libraries_work)
-      if (BLA_STATIC)
-        if (WIN32)
+      if(BLA_STATIC)
+        if(WIN32)
           set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
-        endif ()
-        if (APPLE)
+        endif()
+        if(APPLE)
           set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
-        else ()
+        else()
           set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
-        endif ()
-      else ()
-        if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+        endif()
+      else()
+        if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
           # for ubuntu's libblas3gf and liblapack3gf packages
           set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
-        endif ()
-      endif ()
+        endif()
+      endif()
       find_library(${_prefix}_${_library}_LIBRARY
         NAMES ${_library}
         PATHS ${_libdir}
-        )
+      )
       mark_as_advanced(${_prefix}_${_library}_LIBRARY)
       set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
       set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
     endif()
   endforeach()
+
   if(_libraries_work)
     # Test this combination of libraries.
-    set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_thread})
-    #  message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
-    if (CMAKE_Fortran_COMPILER_LOADED)
+    set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_threadlibs})
+    #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
+    if(CMAKE_Fortran_COMPILER_LOADED)
       check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
     else()
       check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
@@ -192,11 +199,12 @@
     set(CMAKE_REQUIRED_LIBRARIES)
     set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
   endif()
+
   if(_libraries_work)
     if("${_list}" STREQUAL "")
       set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
     else()
-      set(${LIBRARIES} ${${LIBRARIES}} ${_thread})  # for static link
+      set(${LIBRARIES} ${${LIBRARIES}} ${_threadlibs})
     endif()
   else()
     set(${LIBRARIES} FALSE)
@@ -207,18 +215,18 @@
 set(BLAS_LINKER_FLAGS)
 set(BLAS_LIBRARIES)
 set(BLAS95_LIBRARIES)
-if (NOT $ENV{BLA_VENDOR} STREQUAL "")
+if(NOT $ENV{BLA_VENDOR} STREQUAL "")
   set(BLA_VENDOR $ENV{BLA_VENDOR})
-else ()
+else()
   if(NOT BLA_VENDOR)
     set(BLA_VENDOR "All")
   endif()
-endif ()
+endif()
 
-if (BLA_VENDOR STREQUAL "All")
+# Implicitly linked BLAS libraries?
+if(BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    # Implicitly linked BLAS libraries
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -227,71 +235,70 @@
       ""
       )
   endif()
-endif ()
+endif()
 
-#BLAS in intel mkl 10+ library? (em64t 64bit)
-if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
-  if (NOT BLAS_LIBRARIES)
-
-    # System-specific settings
-    if (WIN32)
-      if (BLA_STATIC)
-        set(BLAS_mkl_DLL_SUFFIX "")
+# BLAS in the Intel MKL 10+ library?
+if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
+  if(NOT BLAS_LIBRARIES)
+    if(CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
+      # System-specific settings
+      if(WIN32)
+        if(BLA_STATIC)
+          set(BLAS_mkl_DLL_SUFFIX "")
+        else()
+          set(BLAS_mkl_DLL_SUFFIX "_dll")
+        endif()
       else()
-        set(BLAS_mkl_DLL_SUFFIX "_dll")
+        # Switch to GNU Fortran support layer if needed (but not on Apple, where MKL does not provide it)
+        if(CMAKE_Fortran_COMPILER_LOADED AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND NOT APPLE)
+            set(BLAS_mkl_INTFACE "gf")
+            set(BLAS_mkl_THREADING "gnu")
+            set(BLAS_mkl_OMP "gomp")
+        else()
+            set(BLAS_mkl_INTFACE "intel")
+            set(BLAS_mkl_THREADING "intel")
+            set(BLAS_mkl_OMP "iomp5")
+        endif()
+        set(BLAS_mkl_LM "-lm")
+        set(BLAS_mkl_LDL "-ldl")
       endif()
-    else()
-      # Switch to GNU Fortran support layer if needed (but not on Apple, where MKL does not provide it)
-      if(CMAKE_Fortran_COMPILER_LOADED AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND NOT APPLE)
-          set(BLAS_mkl_INTFACE "gf")
-          set(BLAS_mkl_THREADING "gnu")
-          set(BLAS_mkl_OMP "gomp")
-      else()
-          set(BLAS_mkl_INTFACE "intel")
-          set(BLAS_mkl_THREADING "intel")
-          set(BLAS_mkl_OMP "iomp5")
-      endif()
-      set(BLAS_mkl_LM "-lm")
-      set(BLAS_mkl_LDL "-ldl")
-    endif()
 
-    if (BLA_VENDOR MATCHES "_64ilp")
-      set(BLAS_mkl_ILP_MODE "ilp64")
-    else ()
-      set(BLAS_mkl_ILP_MODE "lp64")
-    endif ()
-
-    if (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
       if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
         find_package(Threads)
       else()
         find_package(Threads REQUIRED)
       endif()
 
+      if(BLA_VENDOR MATCHES "_64ilp")
+        set(BLAS_mkl_ILP_MODE "ilp64")
+      else()
+        set(BLAS_mkl_ILP_MODE "lp64")
+      endif()
+
       set(BLAS_SEARCH_LIBS "")
 
       if(BLA_F95)
-        set(BLAS_mkl_SEARCH_SYMBOL sgemm_f95)
+        set(BLAS_mkl_SEARCH_SYMBOL "sgemm_f95")
         set(_LIBRARIES BLAS95_LIBRARIES)
-        if (WIN32)
+        if(WIN32)
           # Find the main file (32-bit or 64-bit)
           set(BLAS_SEARCH_LIBS_WIN_MAIN "")
-          if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+          if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
               "mkl_blas95${BLAS_mkl_DLL_SUFFIX} mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
           endif()
-          if (BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
+          if(BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
               "mkl_blas95_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX} mkl_intel_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX}")
-          endif ()
+          endif()
 
           # Add threading/sequential libs
           set(BLAS_SEARCH_LIBS_WIN_THREAD "")
-          if (BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+          if(BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
               "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
           endif()
-          if (NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+          if(NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
             # old version
             list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
               "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
@@ -301,14 +308,14 @@
           endif()
 
           # Cartesian product of the above
-          foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
-            foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
+          foreach(MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
+            foreach(THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
               list(APPEND BLAS_SEARCH_LIBS
                 "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
             endforeach()
           endforeach()
-        else ()
-          if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+        else()
+          if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
             # old version
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
@@ -316,8 +323,8 @@
             # mkl >= 10.3
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}")
-          endif ()
-          if (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
+          endif()
+          if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
             # old version
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_blas95 mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
@@ -325,30 +332,30 @@
             # mkl >= 10.3
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}")
-          endif ()
-          if (BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
+          endif()
+          if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core")
-          endif ()
-        endif ()
-      else ()
+          endif()
+        endif()
+      else()
         set(BLAS_mkl_SEARCH_SYMBOL sgemm)
         set(_LIBRARIES BLAS_LIBRARIES)
-        if (WIN32)
+        if(WIN32)
           # Find the main file (32-bit or 64-bit)
           set(BLAS_SEARCH_LIBS_WIN_MAIN "")
-          if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+          if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
               "mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
           endif()
-          if (BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
+          if(BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
               "mkl_intel_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX}")
-          endif ()
+          endif()
 
           # Add threading/sequential libs
           set(BLAS_SEARCH_LIBS_WIN_THREAD "")
-          if (NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+          if(NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
             # old version
             list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
               "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
@@ -356,20 +363,20 @@
             list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
               "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
           endif()
-          if (BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+          if(BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
               "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
           endif()
 
           # Cartesian product of the above
-          foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
-            foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
+          foreach(MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
+            foreach(THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
               list(APPEND BLAS_SEARCH_LIBS
                 "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
             endforeach()
           endforeach()
-        else ()
-          if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+        else()
+          if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
             # old version
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
@@ -377,8 +384,8 @@
             # mkl >= 10.3
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}")
-          endif ()
-          if (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
+          endif()
+          if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
             # old version
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
@@ -386,45 +393,45 @@
             # mkl >= 10.3
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}")
-          endif ()
-          if (BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
+          endif()
+          if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core")
-          endif ()
+          endif()
 
           #older vesions of intel mkl libs
-          if (BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
+          if(BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS
               "mkl")
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_ia32")
             list(APPEND BLAS_SEARCH_LIBS
               "mkl_em64t")
-          endif ()
-        endif ()
-      endif ()
+          endif()
+        endif()
+      endif()
 
-      if (DEFINED ENV{MKLROOT})
-        if (BLA_VENDOR STREQUAL "Intel10_32")
+      if(DEFINED ENV{MKLROOT})
+        if(BLA_VENDOR STREQUAL "Intel10_32")
           set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}/lib/ia32")
-        elseif (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$")
+        elseif(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$")
           set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}/lib/intel64")
-        endif ()
-      endif ()
-      if (_BLAS_MKLROOT_LIB_DIR)
-        if (WIN32)
+        endif()
+      endif()
+      if(_BLAS_MKLROOT_LIB_DIR)
+        if(WIN32)
           string(APPEND _BLAS_MKLROOT_LIB_DIR "_win")
-        elseif (APPLE)
+        elseif(APPLE)
           string(APPEND _BLAS_MKLROOT_LIB_DIR "_mac")
-        else ()
+        else()
           string(APPEND _BLAS_MKLROOT_LIB_DIR "_lin")
-        endif ()
-      endif ()
+        endif()
+      endif()
 
-      foreach (IT ${BLAS_SEARCH_LIBS})
+      foreach(IT ${BLAS_SEARCH_LIBS})
         string(REPLACE " " ";" SEARCH_LIBS ${IT})
-        if (NOT ${_LIBRARIES})
-          check_fortran_libraries(
+        if(NOT ${_LIBRARIES})
+          check_blas_libraries(
             ${_LIBRARIES}
             BLAS
             ${BLAS_mkl_SEARCH_SYMBOL}
@@ -433,19 +440,19 @@
             "${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}"
             "${_BLAS_MKLROOT_LIB_DIR}"
             )
-        endif ()
-      endforeach ()
+        endif()
+      endforeach()
 
-    endif ()
-    unset(BLAS_mkl_ILP_MODE)
-    unset(BLAS_mkl_INTFACE)
-    unset(BLAS_mkl_THREADING)
-    unset(BLAS_mkl_OMP)
-    unset(BLAS_mkl_DLL_SUFFIX)
-    unset(BLAS_mkl_LM)
-    unset(BLAS_mkl_LDL)
-  endif ()
-endif ()
+      unset(BLAS_mkl_ILP_MODE)
+      unset(BLAS_mkl_INTFACE)
+      unset(BLAS_mkl_THREADING)
+      unset(BLAS_mkl_OMP)
+      unset(BLAS_mkl_DLL_SUFFIX)
+      unset(BLAS_mkl_LM)
+      unset(BLAS_mkl_LDL)
+    endif()
+  endif()
+endif()
 
 if(BLA_F95)
   find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS95_LIBRARIES)
@@ -455,10 +462,10 @@
   endif()
 endif()
 
-if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+# gotoblas? (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
+if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -467,12 +474,12 @@
       ""
       )
   endif()
-endif ()
+endif()
 
-if (BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
+# OpenBLAS? (http://www.openblas.net)
+if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    # OpenBLAS (http://www.openblas.net)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -487,8 +494,7 @@
     else()
       find_package(Threads REQUIRED)
     endif()
-    # OpenBLAS (http://www.openblas.net)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -497,12 +503,12 @@
       "${CMAKE_THREAD_LIBS_INIT}"
       )
   endif()
-endif ()
+endif()
 
-if (BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
+# FLAME's blis library? (https://github.com/flame/blis)
+if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    # FLAME's blis library (https://github.com/flame/blis)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -511,12 +517,12 @@
       ""
       )
   endif()
-endif ()
+endif()
 
-if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
+# BLAS in the ATLAS library? (http://math-atlas.sourceforge.net/)
+if(BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       dgemm
@@ -525,12 +531,12 @@
       ""
       )
   endif()
-endif ()
+endif()
 
 # BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
-if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -539,12 +545,12 @@
       ""
       )
   endif()
-endif ()
+endif()
 
 # BLAS in Alpha CXML library?
-if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -553,12 +559,12 @@
       ""
       )
   endif()
-endif ()
+endif()
 
 # BLAS in Alpha DXML library? (now called CXML, see above)
-if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -567,12 +573,12 @@
       ""
       )
   endif()
-endif ()
+endif()
 
 # BLAS in Sun Performance library?
-if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -584,12 +590,12 @@
       set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
     endif()
   endif()
-endif ()
+endif()
 
 # BLAS in SCSL library?  (SGI/Cray Scientific Library)
-if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -598,12 +604,12 @@
       ""
       )
   endif()
-endif ()
+endif()
 
 # BLAS in SGIMATH library?
-if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -612,12 +618,12 @@
       ""
       )
   endif()
-endif ()
+endif()
 
 # BLAS in IBM ESSL library? (requires generic BLAS lib, too)
-if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -626,107 +632,107 @@
       ""
       )
   endif()
-endif ()
+endif()
 
-#BLAS in acml library?
-if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
-  if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
+# BLAS in acml library?
+if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
+  if(((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
     ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR
     ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS))
     )
   # try to find acml in "standard" paths
-  if( WIN32 )
-    file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" )
+  if(WIN32)
+    file(GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt")
   else()
-    file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" )
+    file(GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt")
   endif()
-  if( WIN32 )
-    file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" )
+  if(WIN32)
+    file(GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples")
   else()
-    file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" )
+    file(GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples")
   endif()
   list(GET _ACML_ROOT 0 _ACML_ROOT)
   list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
-  if( _ACML_ROOT )
-    get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH )
-    if( SIZEOF_INTEGER EQUAL 8 )
-      set( _ACML_PATH_SUFFIX "_int64" )
+  if(_ACML_ROOT)
+    get_filename_component(_ACML_ROOT ${_ACML_ROOT} PATH)
+    if(SIZEOF_INTEGER EQUAL 8)
+      set(_ACML_PATH_SUFFIX "_int64")
     else()
-      set( _ACML_PATH_SUFFIX "" )
+      set(_ACML_PATH_SUFFIX "")
     endif()
-    if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" )
-      set( _ACML_COMPILER32 "ifort32" )
-      set( _ACML_COMPILER64 "ifort64" )
-    elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" )
-      set( _ACML_COMPILER32 "sun32" )
-      set( _ACML_COMPILER64 "sun64" )
-    elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" )
-      set( _ACML_COMPILER32 "pgi32" )
-      if( WIN32 )
-        set( _ACML_COMPILER64 "win64" )
+    if(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
+      set(_ACML_COMPILER32 "ifort32")
+      set(_ACML_COMPILER64 "ifort64")
+    elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro")
+      set(_ACML_COMPILER32 "sun32")
+      set(_ACML_COMPILER64 "sun64")
+    elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "PGI")
+      set(_ACML_COMPILER32 "pgi32")
+      if(WIN32)
+        set(_ACML_COMPILER64 "win64")
       else()
-        set( _ACML_COMPILER64 "pgi64" )
+        set(_ACML_COMPILER64 "pgi64")
       endif()
-    elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" )
+    elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Open64")
       # 32 bit builds not supported on Open64 but for code simplicity
       # We'll just use the same directory twice
-      set( _ACML_COMPILER32 "open64_64" )
-      set( _ACML_COMPILER64 "open64_64" )
-    elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" )
-      set( _ACML_COMPILER32 "nag32" )
-      set( _ACML_COMPILER64 "nag64" )
+      set(_ACML_COMPILER32 "open64_64")
+      set(_ACML_COMPILER64 "open64_64")
+    elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "NAG")
+      set(_ACML_COMPILER32 "nag32")
+      set(_ACML_COMPILER64 "nag64")
     else()
-      set( _ACML_COMPILER32 "gfortran32" )
-      set( _ACML_COMPILER64 "gfortran64" )
+      set(_ACML_COMPILER32 "gfortran32")
+      set(_ACML_COMPILER64 "gfortran64")
     endif()
 
-    if( BLA_VENDOR STREQUAL "ACML_MP" )
+    if(BLA_VENDOR STREQUAL "ACML_MP")
       set(_ACML_MP_LIB_DIRS
         "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib"
-        "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" )
+        "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib")
     else()
       set(_ACML_LIB_DIRS
         "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib"
-        "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" )
+        "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib")
     endif()
   endif()
 elseif(BLAS_${BLA_VENDOR}_LIB_DIRS)
   set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS})
 endif()
 
-if( BLA_VENDOR STREQUAL "ACML_MP" )
-  foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
-    check_fortran_libraries (
+if(BLA_VENDOR STREQUAL "ACML_MP")
+  foreach(BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
       "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS}
       )
-    if( BLAS_LIBRARIES )
+    if(BLAS_LIBRARIES)
       break()
     endif()
   endforeach()
-elseif( BLA_VENDOR STREQUAL "ACML_GPU" )
-  foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
-    check_fortran_libraries (
+elseif(BLA_VENDOR STREQUAL "ACML_GPU")
+  foreach(BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
       "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS}
       )
-    if( BLAS_LIBRARIES )
+    if(BLAS_LIBRARIES)
       break()
     endif()
   endforeach()
 else()
-  foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} )
-    check_fortran_libraries (
+  foreach(BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS})
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
       "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS}
       )
-    if( BLAS_LIBRARIES )
+    if(BLAS_LIBRARIES)
       break()
     endif()
   endforeach()
@@ -734,7 +740,7 @@
 
 # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both
 if(NOT BLAS_LIBRARIES)
-  check_fortran_libraries(
+  check_blas_libraries(
     BLAS_LIBRARIES
     BLAS
     sgemm
@@ -744,7 +750,7 @@
     )
 endif()
 if(NOT BLAS_LIBRARIES)
-  check_fortran_libraries(
+  check_blas_libraries(
     BLAS_LIBRARIES
     BLAS
     sgemm
@@ -754,7 +760,7 @@
     )
 endif()
 if(NOT BLAS_LIBRARIES)
-  check_fortran_libraries(
+  check_blas_libraries(
     BLAS_LIBRARIES
     BLAS
     sgemm
@@ -763,12 +769,12 @@
     ""
     )
 endif()
-endif () # ACML
+endif() # ACML
 
 # Apple BLAS library?
-if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       dgemm
@@ -777,11 +783,12 @@
       ""
       )
   endif()
-endif ()
+endif()
 
-if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
-  if ( NOT BLAS_LIBRARIES )
-    check_fortran_libraries(
+# Apple NAS (vecLib) library?
+if(BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+  if(NOT BLAS_LIBRARIES)
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       dgemm
@@ -789,13 +796,13 @@
       "vecLib"
       ""
       )
-  endif ()
-endif ()
+  endif()
+endif()
 
 # Generic BLAS library?
-if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
-    check_fortran_libraries(
+    check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
@@ -804,7 +811,7 @@
       ""
       )
   endif()
-endif ()
+endif()
 
 if(NOT BLA_F95)
   find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS_LIBRARIES)
@@ -812,7 +819,7 @@
 
 # On compilers that implicitly link BLAS (such as ftn, cc, and CC on Cray HPC machines)
 # we used a placeholder for empty BLAS_LIBRARIES to get through our logic above.
-if (BLAS_LIBRARIES STREQUAL "BLAS_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
+if(BLAS_LIBRARIES STREQUAL "BLAS_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
   set(BLAS_LIBRARIES "")
 endif()
 
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 0e84fab..deac9ef 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -248,6 +248,7 @@
 # Save project's policies
 cmake_policy(PUSH)
 cmake_policy(SET CMP0057 NEW) # if IN_LIST
+cmake_policy(SET CMP0102 NEW) # if mark_as_advanced(non_cache_var)
 
 function(_boost_get_existing_target component target_var)
   set(names "${component}")
@@ -441,7 +442,9 @@
   # Note that args are passed in the Boost_FIND_xxxxx variables, so there is no
   # need to delegate them to this find_package call.
   find_package(Boost QUIET NO_MODULE)
-  mark_as_advanced(Boost_DIR)
+  if (DEFINED Boost_DIR)
+    mark_as_advanced(Boost_DIR)
+  endif ()
 
   # If we found a boost cmake package, then we're done. Print out what we found.
   # Otherwise let the rest of the module try to find it.
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index f7f68ca..6a40ace 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -408,6 +408,11 @@
     The path to the CUDA Toolkit library directory that contains the CUDA
     Runtime library ``cudart``.
 
+``CUDAToolkit_TARGET_DIR``
+    The path to the CUDA Toolkit directory including the target architecture
+    when cross-compiling. When not cross-compiling this will be equivalant to
+    ``CUDAToolkit_ROOT_DIR``.
+
 ``CUDAToolkit_NVCC_EXECUTABLE``
     The path to the NVIDIA CUDA compiler ``nvcc``.  Note that this path may
     **not** be the same as
@@ -641,8 +646,37 @@
 
 get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
 
-# Now that we have the real ROOT_DIR, find components inside it.
-list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR})
+# Handle cross compilation
+if(CMAKE_CROSSCOMPILING)
+  if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a")
+    # Support for NVPACK
+    set (CUDAToolkit_TARGET_NAME "armv7-linux-androideabi")
+  elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
+    # Support for arm cross compilation
+    set(CUDAToolkit_TARGET_NAME "armv7-linux-gnueabihf")
+  elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
+    # Support for aarch64 cross compilation
+    if (ANDROID_ARCH_NAME STREQUAL "arm64")
+      set(CUDAToolkit_TARGET_NAME "aarch64-linux-androideabi")
+    else()
+      set(CUDAToolkit_TARGET_NAME "aarch64-linux")
+    endif (ANDROID_ARCH_NAME STREQUAL "arm64")
+  elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+      set(CUDAToolkit_TARGET_NAME "x86_64-linux")
+  endif()
+
+  if (EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
+    set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
+    # add known CUDA target root path to the set of directories we search for programs, libraries and headers
+    list(APPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}")
+  endif()
+else()
+  # Not cross compiling
+  set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}")
+  # Now that we have the real ROOT_DIR, find components inside it.
+  list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR})
+endif()
+
 
 # Find the include/ directory
 find_path(CUDAToolkit_INCLUDE_DIR
@@ -652,14 +686,20 @@
 # And find the CUDA Runtime Library libcudart
 find_library(CUDA_CUDART
   NAMES cudart
-  PATH_SUFFIXES lib64 lib/x64
+  PATH_SUFFIXES lib64 lib64/stubs lib/x64
 )
 if (NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY)
   message(STATUS "Unable to find cudart library.")
 endif()
 
 unset(CUDAToolkit_ROOT_DIR)
-list(REMOVE_AT CMAKE_PREFIX_PATH -1)
+if(CMAKE_CROSSCOMPILING)
+  if(CUDAToolkit_TARGET_DIR)
+    list(REMOVE_AT CMAKE_FIND_ROOT_PATH -1)
+  endif()
+else()
+  list(REMOVE_AT CMAKE_PREFIX_PATH -1)
+endif()
 
 #-----------------------------------------------------------------------------
 # Perform version comparison and validate all required variables are set.
@@ -696,7 +736,7 @@
       NAMES ${search_names}
       PATHS ${CUDAToolkit_LIBRARY_DIR}
             ENV CUDA_PATH
-      PATH_SUFFIXES nvidia/current lib64 lib/x64 lib
+      PATH_SUFFIXES nvidia/current lib64 lib64/stubs lib/x64 lib lib/stubs
     )
 
     if (NOT CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY)
diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake
index e3e7273..ba56078 100644
--- a/Modules/FindCurses.cmake
+++ b/Modules/FindCurses.cmake
@@ -159,6 +159,10 @@
   if(NOT CURSES_NCURSES_HAS_CBREAK)
     find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" HINTS "${_cursesLibDir}")
     find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" )
+
+    mark_as_advanced(
+      CURSES_EXTRA_LIBRARY
+      )
   endif()
 else()
   get_filename_component(_cursesLibDir "${CURSES_CURSES_LIBRARY}" PATH)
@@ -262,6 +266,5 @@
   CURSES_INCLUDE_PATH
   CURSES_CURSES_LIBRARY
   CURSES_NCURSES_LIBRARY
-  CURSES_EXTRA_LIBRARY
   CURSES_FORM_LIBRARY
   )
diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake
index 83091f3..565763d 100644
--- a/Modules/FindGTK2.cmake
+++ b/Modules/FindGTK2.cmake
@@ -5,96 +5,83 @@
 FindGTK2
 --------
 
-Find the GTK2 widget libraries and several of its
-other optional components like ``gtkmm``, ``glade``, and ``glademm``.
-
-NOTE: If you intend to use version checking, CMake 2.6.2 or later is
-
-::
-
-       required.
-
-
+Find the GTK2 widget libraries and several of its other optional components
+like ``gtkmm``, ``glade``, and ``glademm``.
 
 Specify one or more of the following components as you call this find
 module.  See example below.
 
-::
+* ``gtk``
+* ``gtkmm``
+* ``glade``
+* ``glademm``
 
-   gtk
-   gtkmm
-   glade
-   glademm
-
-
+Result Variables
+^^^^^^^^^^^^^^^^
 
 The following variables will be defined for your use
 
-::
+``GTK2_FOUND``
+  Were all of your specified components found?
+``GTK2_INCLUDE_DIRS``
+  All include directories
+``GTK2_LIBRARIES``
+  All libraries
+``GTK2_TARGETS``
+  All imported targets
+``GTK2_DEFINITIONS``
+  Additional compiler flags
+``GTK2_VERSION``
+  The version of GTK2 found (x.y.z)
+``GTK2_MAJOR_VERSION``
+  The major version of GTK2
+``GTK2_MINOR_VERSION``
+  The minor version of GTK2
+``GTK2_PATCH_VERSION``
+  The patch version of GTK2
 
-   GTK2_FOUND - Were all of your specified components found?
-   GTK2_INCLUDE_DIRS - All include directories
-   GTK2_LIBRARIES - All libraries
-   GTK2_TARGETS - All imported targets
-   GTK2_DEFINITIONS - Additional compiler flags
-
-
-
-::
-
-   GTK2_VERSION - The version of GTK2 found (x.y.z)
-   GTK2_MAJOR_VERSION - The major version of GTK2
-   GTK2_MINOR_VERSION - The minor version of GTK2
-   GTK2_PATCH_VERSION - The patch version of GTK2
-
-
+Input Variables
+^^^^^^^^^^^^^^^
 
 Optional variables you can define prior to calling this module:
 
-::
+``GTK2_DEBUG``
+  Enables verbose debugging of the module
+``GTK2_ADDITIONAL_SUFFIXES``
+  Allows defining additional directories to search for include files
 
-   GTK2_DEBUG - Enables verbose debugging of the module
-   GTK2_ADDITIONAL_SUFFIXES - Allows defining additional directories to
-                              search for include files
+Example Usage
+^^^^^^^^^^^^^
 
+Call :command:`find_package` once.  Here are some examples to pick from:
 
+Require GTK 2.6 or later:
 
-================= Example Usage:
+.. code-block:: cmake
 
-::
+  find_package(GTK2 2.6 REQUIRED gtk)
 
-   Call find_package() once, here are some examples to pick from:
+Require GTK 2.10 or later and Glade:
 
+.. code-block:: cmake
 
+  find_package(GTK2 2.10 REQUIRED gtk glade)
 
-::
+Search for GTK/GTKMM 2.8 or later:
 
-   Require GTK 2.6 or later
-       find_package(GTK2 2.6 REQUIRED gtk)
+.. code-block:: cmake
 
+  find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
 
+Use the results:
 
-::
+.. code-block:: cmake
 
-   Require GTK 2.10 or later and Glade
-       find_package(GTK2 2.10 REQUIRED gtk glade)
-
-
-
-::
-
-   Search for GTK/GTKMM 2.8 or later
-       find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
-
-
-
-::
-
-   if(GTK2_FOUND)
-      include_directories(${GTK2_INCLUDE_DIRS})
-      add_executable(mygui mygui.cc)
-      target_link_libraries(mygui ${GTK2_LIBRARIES})
-   endif()
+  if(GTK2_FOUND)
+    include_directories(${GTK2_INCLUDE_DIRS})
+    add_executable(mygui mygui.cc)
+    target_link_libraries(mygui ${GTK2_LIBRARIES})
+  endif()
 #]=======================================================================]
 
 # Version 1.6 (CMake 3.0)
@@ -881,6 +868,7 @@
 
     set(GTK2_${_COMPONENT_UPPER}_FIND_QUIETLY ${GTK2_FIND_QUIETLY})
 
+    set(FPHSA_NAME_MISMATCHED 1)
     if(_GTK2_component STREQUAL "gtk")
         FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtk libraries were not found."
             GTK2_GTK_LIBRARY
@@ -923,6 +911,7 @@
             GTK2_GLADEMMCONFIG_INCLUDE_DIR
         )
     endif()
+    unset(FPHSA_NAME_MISMATCHED)
 
     if(NOT GTK2_${_COMPONENT_UPPER}_FOUND)
         set(_GTK2_did_we_find_everything false)
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index 3cb3653..3aa3de4 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -7,10 +7,10 @@
 
 Find Linear Algebra PACKage (LAPACK) library
 
-This module finds an installed fortran library that implements the
+This module finds an installed Fortran library that implements the
 LAPACK linear-algebra interface (see http://www.netlib.org/lapack/).
 
-The approach follows that taken for the autoconf macro file,
+The approach follows that taken for the ``autoconf`` macro file,
 ``acx_lapack.m4`` (distributed at
 http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
 
@@ -26,21 +26,21 @@
   If set, checks only the specified vendor, if not set checks all the
   possibilities.  List of vendors valid in this module:
 
+  * ``OpenBLAS``
+  * ``FLAME``
   * ``Intel10_32`` (intel mkl v10 32 bit)
   * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model)
   * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model)
   * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model)
   * ``Intel10_64ilp_seq`` (intel mkl v10+ 64 bit, sequential code, ilp64 model)
   * ``Intel`` (obsolete versions of mkl 32 and 64 bit)
-  * ``OpenBLAS``
-  * ``FLAME``
   * ``ACML``
   * ``Apple``
   * ``NAS``
   * ``Generic``
 
 ``BLA_F95``
-  if ``ON`` tries to find BLAS95/LAPACK95
+  if ``ON`` tries to find the BLAS95/LAPACK95 interfaces
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -50,7 +50,7 @@
 ``LAPACK_FOUND``
   library implementing the LAPACK interface is found
 ``LAPACK_LINKER_FLAGS``
-  uncached list of required linker flags (excluding -l and -L).
+  uncached list of required linker flags (excluding ``-l`` and ``-L``).
 ``LAPACK_LIBRARIES``
   uncached list of libraries (using full path name) to link against
   to use LAPACK
@@ -62,7 +62,7 @@
 
 .. note::
 
-  C or CXX must be enabled to use Intel MKL
+  C or CXX must be enabled to use Intel Math Kernel Library (MKL)
 
   For example, to use Intel MKL libraries and/or Intel compiler:
 
@@ -72,10 +72,8 @@
     find_package(LAPACK)
 #]=======================================================================]
 
-set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
-
 # Check the language being used
-if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED) )
+if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED))
   if(LAPACK_FIND_REQUIRED)
     message(FATAL_ERROR "FindLAPACK requires Fortran, C, or C++ to be enabled.")
   else()
@@ -84,303 +82,308 @@
   endif()
 endif()
 
-if (CMAKE_Fortran_COMPILER_LOADED)
-include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
-else ()
-include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
-endif ()
+if(CMAKE_Fortran_COMPILER_LOADED)
+  include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
+else()
+  include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
+endif()
 include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
 
 cmake_push_check_state()
 set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY})
 
+set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+
 set(LAPACK_FOUND FALSE)
 set(LAPACK95_FOUND FALSE)
 
-# TODO: move this stuff to separate module
+# TODO: move this stuff to a separate module
 
-macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas _threads)
-# This macro checks for the existence of the combination of fortran libraries
-# given by _list.  If the combination is found, this macro checks (using the
-# Check_Fortran_Function_Exists macro) whether can link against that library
-# combination using the name of a routine given by _name using the linker
-# flags given by _flags.  If the combination of libraries is found and passes
-# the link test, LIBRARIES is set to the list of complete library paths that
-# have been found.  Otherwise, LIBRARIES is set to FALSE.
+macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _blas)
+  # This macro checks for the existence of the combination of fortran libraries
+  # given by _list.  If the combination is found, this macro checks (using the
+  # Check_Fortran_Function_Exists macro) whether can link against that library
+  # combination using the name of a routine given by _name using the linker
+  # flags given by _flags.  If the combination of libraries is found and passes
+  # the link test, LIBRARIES is set to the list of complete library paths that
+  # have been found.  Otherwise, LIBRARIES is set to FALSE.
 
-# N.B. _prefix is the prefix applied to the names of all cached variables that
-# are generated internally and marked advanced by this macro.
+  # N.B. _prefix is the prefix applied to the names of all cached variables that
+  # are generated internally and marked advanced by this macro.
 
-set(_libraries_work TRUE)
-set(${LIBRARIES})
-set(_combined_name)
-if (NOT _libdir)
-  if (WIN32)
-    set(_libdir ENV LIB)
-  elseif (APPLE)
-    set(_libdir ENV DYLD_LIBRARY_PATH)
-  else ()
-    set(_libdir ENV LD_LIBRARY_PATH)
-  endif ()
-endif ()
+  set(_libraries_work TRUE)
+  set(${LIBRARIES})
+  set(_combined_name)
+  if(NOT _libdir)
+    if(WIN32)
+      set(_libdir ENV LIB)
+    elseif(APPLE)
+      set(_libdir ENV DYLD_LIBRARY_PATH)
+    else()
+      set(_libdir ENV LD_LIBRARY_PATH)
+    endif()
+  endif()
 
-list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+  list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
 
-foreach(_library ${_list})
-  set(_combined_name ${_combined_name}_${_library})
+  foreach(_library ${_list})
+    set(_combined_name ${_combined_name}_${_library})
+
+    if(_libraries_work)
+      if(BLA_STATIC)
+        if(WIN32)
+          set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+        endif()
+        if(APPLE)
+          set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+        else()
+          set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+        endif()
+      else()
+        if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+          # for ubuntu's libblas3gf and liblapack3gf packages
+          set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
+        endif()
+      endif()
+      find_library(${_prefix}_${_library}_LIBRARY
+        NAMES ${_library}
+        PATHS ${_libdir}
+      )
+      mark_as_advanced(${_prefix}_${_library}_LIBRARY)
+      set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
+      set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+    endif()
+  endforeach()
 
   if(_libraries_work)
-    if (BLA_STATIC)
-      if (WIN32)
-        set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
-      endif ()
-      if (APPLE)
-        set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
-      else ()
-        set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
-      endif ()
-    else ()
-      if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
-        # for ubuntu's libblas3gf and liblapack3gf packages
-        set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
-      endif ()
-    endif ()
-    find_library(${_prefix}_${_library}_LIBRARY
-      NAMES ${_library}
-      PATHS ${_libdir}
-      )
-    mark_as_advanced(${_prefix}_${_library}_LIBRARY)
-    set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
-    set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+    # Test this combination of libraries.
+    if(UNIX AND BLA_STATIC)
+      set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threadlibs})
+    else()
+      set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threadlibs})
+    endif()
+    #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
+    if(CMAKE_Fortran_COMPILER_LOADED)
+      check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
+    else()
+      check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
+    endif()
+    set(CMAKE_REQUIRED_LIBRARIES)
+    set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
   endif()
-endforeach()
 
-if(_libraries_work)
-  # Test this combination of libraries.
-  if(UNIX AND BLA_STATIC)
-    set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threads})
+  if(_libraries_work)
+    if("${_list}${_blas}" STREQUAL "")
+      set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
+    else()
+      set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threadlibs})
+    endif()
   else()
-    set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads})
-  endif()
-#  message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
-  if (NOT CMAKE_Fortran_COMPILER_LOADED)
-    check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
-  else ()
-    check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS)
-  endif ()
-  set(CMAKE_REQUIRED_LIBRARIES)
-  set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
-  #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
-endif()
-
- if(_libraries_work)
-   if("${_list}${_blas}" STREQUAL "")
-     set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
-   else()
-     set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threads})
-   endif()
- else()
     set(${LIBRARIES} FALSE)
- endif()
-
+  endif()
+  #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
 endmacro()
 
-
 set(LAPACK_LINKER_FLAGS)
 set(LAPACK_LIBRARIES)
 set(LAPACK95_LIBRARIES)
 
-
 if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
   find_package(BLAS)
 else()
   find_package(BLAS REQUIRED)
 endif()
 
-
 if(BLAS_FOUND)
   set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
-  if (NOT $ENV{BLA_VENDOR} STREQUAL "")
+  if(NOT $ENV{BLA_VENDOR} STREQUAL "")
     set(BLA_VENDOR $ENV{BLA_VENDOR})
-  else ()
+  else()
     if(NOT BLA_VENDOR)
       set(BLA_VENDOR "All")
     endif()
-  endif ()
+  endif()
 
-#intel lapack
-if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
-  if(NOT LAPACK_LIBRARIES)
-  if (NOT WIN32)
-    set(LAPACK_mkl_LM "-lm")
-    set(LAPACK_mkl_LDL "-ldl")
-  endif ()
-  if (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
-    if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
-      find_PACKAGE(Threads)
-    else()
-      find_package(Threads REQUIRED)
-    endif()
+  # LAPACK in the Intel MKL 10+ library?
+  if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
+    if(NOT LAPACK_LIBRARIES)
+      if(CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
+        # System-specific settings
+        if(NOT WIN32)
+          set(LAPACK_mkl_LM "-lm")
+          set(LAPACK_mkl_LDL "-ldl")
+        endif()
 
-    if (BLA_VENDOR MATCHES "_64ilp")
-      set(LAPACK_mkl_ILP_MODE "ilp64")
-    else ()
-      set(LAPACK_mkl_ILP_MODE "lp64")
-    endif ()
+        if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+          find_package(Threads)
+        else()
+          find_package(Threads REQUIRED)
+        endif()
 
-    set(LAPACK_SEARCH_LIBS "")
+        if(BLA_VENDOR MATCHES "_64ilp")
+          set(LAPACK_mkl_ILP_MODE "ilp64")
+        else()
+          set(LAPACK_mkl_ILP_MODE "lp64")
+        endif()
 
-    if (BLA_F95)
-      set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95")
-      set(_LIBRARIES LAPACK95_LIBRARIES)
-      set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES})
+        set(LAPACK_SEARCH_LIBS "")
 
-      # old
-      list(APPEND LAPACK_SEARCH_LIBS
-        "mkl_lapack95")
-      # new >= 10.3
-      list(APPEND LAPACK_SEARCH_LIBS
-        "mkl_intel_c")
-      list(APPEND LAPACK_SEARCH_LIBS
-        "mkl_lapack95_${LAPACK_mkl_ILP_MODE}")
-    else()
-      set(LAPACK_mkl_SEARCH_SYMBOL "cheev")
-      set(_LIBRARIES LAPACK_LIBRARIES)
-      set(_BLAS_LIBRARIES ${BLAS_LIBRARIES})
+        if(BLA_F95)
+          set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95")
+          set(_LIBRARIES LAPACK95_LIBRARIES)
+          set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES})
 
-      # old
-      list(APPEND LAPACK_SEARCH_LIBS
-        "mkl_lapack")
-    endif()
+          # old
+          list(APPEND LAPACK_SEARCH_LIBS
+            "mkl_lapack95")
+          # new >= 10.3
+          list(APPEND LAPACK_SEARCH_LIBS
+            "mkl_intel_c")
+          list(APPEND LAPACK_SEARCH_LIBS
+            "mkl_lapack95_${LAPACK_mkl_ILP_MODE}")
+        else()
+          set(LAPACK_mkl_SEARCH_SYMBOL "cheev")
+          set(_LIBRARIES LAPACK_LIBRARIES)
+          set(_BLAS_LIBRARIES ${BLAS_LIBRARIES})
 
-    # First try empty lapack libs
-    if (NOT ${_LIBRARIES})
-      check_lapack_libraries(
-        ${_LIBRARIES}
-        LAPACK
-        ${LAPACK_mkl_SEARCH_SYMBOL}
-        ""
-        ""
-        "${_BLAS_LIBRARIES}"
-        ""
-        )
-    endif ()
-    # Then try the search libs
-    foreach (IT ${LAPACK_SEARCH_LIBS})
-      if (NOT ${_LIBRARIES})
-        check_lapack_libraries(
-          ${_LIBRARIES}
-          LAPACK
-          ${LAPACK_mkl_SEARCH_SYMBOL}
-          ""
-          "${IT}"
-          "${_BLAS_LIBRARIES}"
-          "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
+          # old
+          list(APPEND LAPACK_SEARCH_LIBS
+            "mkl_lapack")
+        endif()
+
+        # First try empty lapack libs
+        if(NOT ${_LIBRARIES})
+          check_lapack_libraries(
+            ${_LIBRARIES}
+            LAPACK
+            ${LAPACK_mkl_SEARCH_SYMBOL}
+            ""
+            ""
+            ""
+            "${_BLAS_LIBRARIES}"
           )
-      endif ()
-    endforeach ()
+        endif()
+        # Then try the search libs
+        foreach(IT ${LAPACK_SEARCH_LIBS})
+          if(NOT ${_LIBRARIES})
+            check_lapack_libraries(
+              ${_LIBRARIES}
+              LAPACK
+              ${LAPACK_mkl_SEARCH_SYMBOL}
+              ""
+              "${IT}"
+              "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
+              "${_BLAS_LIBRARIES}"
+            )
+          endif()
+        endforeach()
 
-    unset(LAPACK_mkl_ILP_MODE)
-    unset(LAPACK_mkl_SEARCH_SYMBOL)
-    unset(LAPACK_mkl_LM)
-    unset(LAPACK_mkl_LDL)
-  endif ()
+        unset(LAPACK_mkl_ILP_MODE)
+        unset(LAPACK_mkl_SEARCH_SYMBOL)
+        unset(LAPACK_mkl_LM)
+        unset(LAPACK_mkl_LDL)
+      endif()
+    endif()
   endif()
-endif()
 
-if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
- if(NOT LAPACK_LIBRARIES)
-  check_lapack_libraries(
-  LAPACK_LIBRARIES
-  LAPACK
-  cheev
-  ""
-  "goto2"
-  "${BLAS_LIBRARIES}"
-  ""
-  )
- endif()
-endif ()
-
-if (BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
- if(NOT LAPACK_LIBRARIES)
-  check_lapack_libraries(
-  LAPACK_LIBRARIES
-  LAPACK
-  cheev
-  ""
-  "openblas"
-  "${BLAS_LIBRARIES}"
-  ""
-  )
- endif()
-endif ()
-
-if (BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
- if(NOT LAPACK_LIBRARIES)
-  check_lapack_libraries(
-  LAPACK_LIBRARIES
-  LAPACK
-  cheev
-  ""
-  "flame"
-  "${BLAS_LIBRARIES}"
-  ""
-  )
- endif()
-endif ()
-
-#acml lapack
-if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
-  if (BLAS_LIBRARIES MATCHES ".+acml.+")
-    set (LAPACK_LIBRARIES ${BLAS_LIBRARIES})
-  endif ()
-endif ()
-
-# Apple LAPACK library?
-if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
-  if(NOT LAPACK_LIBRARIES)
-    check_lapack_libraries(
-    LAPACK_LIBRARIES
-    LAPACK
-    cheev
-    ""
-    "Accelerate"
-    "${BLAS_LIBRARIES}"
-    ""
-    )
+  # gotoblas? (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
+  if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+    if(NOT LAPACK_LIBRARIES)
+      check_lapack_libraries(
+        LAPACK_LIBRARIES
+        LAPACK
+        cheev
+        ""
+        "goto2"
+        ""
+        "${BLAS_LIBRARIES}"
+      )
+    endif()
   endif()
-endif ()
-if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
-  if ( NOT LAPACK_LIBRARIES )
-    check_lapack_libraries(
-    LAPACK_LIBRARIES
-    LAPACK
-    cheev
-    ""
-    "vecLib"
-    "${BLAS_LIBRARIES}"
-    ""
-    )
-  endif ()
-endif ()
-# Generic LAPACK library?
-if (BLA_VENDOR STREQUAL "Generic" OR
-    BLA_VENDOR STREQUAL "ATLAS" OR
-    BLA_VENDOR STREQUAL "All")
-  if ( NOT LAPACK_LIBRARIES )
-    check_lapack_libraries(
-    LAPACK_LIBRARIES
-    LAPACK
-    cheev
-    ""
-    "lapack"
-    "${BLAS_LIBRARIES}"
-    ""
-    )
-  endif ()
-endif ()
 
+  # OpenBLAS? (http://www.openblas.net)
+  if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
+    if(NOT LAPACK_LIBRARIES)
+      check_lapack_libraries(
+        LAPACK_LIBRARIES
+        LAPACK
+        cheev
+        ""
+        "openblas"
+        ""
+        "${BLAS_LIBRARIES}"
+      )
+    endif()
+  endif()
+
+  # FLAME's blis library? (https://github.com/flame/blis)
+  if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
+    if(NOT LAPACK_LIBRARIES)
+      check_lapack_libraries(
+        LAPACK_LIBRARIES
+        LAPACK
+        cheev
+        ""
+        "flame"
+        ""
+        "${BLAS_LIBRARIES}"
+      )
+    endif()
+  endif()
+
+  # BLAS in acml library?
+  if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
+    if(BLAS_LIBRARIES MATCHES ".+acml.+")
+      set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
+    endif()
+  endif()
+
+  # Apple LAPACK library?
+  if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+    if(NOT LAPACK_LIBRARIES)
+      check_lapack_libraries(
+        LAPACK_LIBRARIES
+        LAPACK
+        cheev
+        ""
+        "Accelerate"
+        ""
+        "${BLAS_LIBRARIES}"
+      )
+    endif()
+  endif()
+
+  # Apple NAS (vecLib) library?
+  if(BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+    if(NOT LAPACK_LIBRARIES)
+      check_lapack_libraries(
+        LAPACK_LIBRARIES
+        LAPACK
+        cheev
+        ""
+        "vecLib"
+        ""
+        "${BLAS_LIBRARIES}"
+      )
+    endif()
+  endif()
+
+  # Generic LAPACK library?
+  if(BLA_VENDOR STREQUAL "Generic" OR
+      BLA_VENDOR STREQUAL "ATLAS" OR
+      BLA_VENDOR STREQUAL "All")
+    if(NOT LAPACK_LIBRARIES)
+      check_lapack_libraries(
+        LAPACK_LIBRARIES
+        LAPACK
+        cheev
+        ""
+        "lapack"
+        ""
+        "${BLAS_LIBRARIES}"
+      )
+    endif()
+  endif()
 else()
   message(STATUS "LAPACK requires BLAS")
 endif()
@@ -397,11 +400,11 @@
     else()
       if(LAPACK_FIND_REQUIRED)
         message(FATAL_ERROR
-        "A required library with LAPACK95 API not found. Please specify library location."
+          "A required library with LAPACK95 API not found. Please specify library location."
         )
       else()
         message(STATUS
-        "A library with LAPACK95 API not found. Please specify library location."
+          "A library with LAPACK95 API not found. Please specify library location."
         )
       endif()
     endif()
@@ -421,11 +424,11 @@
     else()
       if(LAPACK_FIND_REQUIRED)
         message(FATAL_ERROR
-        "A required library with LAPACK API not found. Please specify library location."
+          "A required library with LAPACK API not found. Please specify library location."
         )
       else()
         message(STATUS
-        "A library with LAPACK API not found. Please specify library location."
+          "A library with LAPACK API not found. Please specify library location."
         )
       endif()
     endif()
@@ -434,7 +437,7 @@
 
 # On compilers that implicitly link LAPACK (such as ftn, cc, and CC on Cray HPC machines)
 # we used a placeholder for empty LAPACK_LIBRARIES to get through our logic above.
-if (LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
+if(LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
   set(LAPACK_LIBRARIES "")
 endif()
 
diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake
index caf9d69..0b0c970 100644
--- a/Modules/FindLua.cmake
+++ b/Modules/FindLua.cmake
@@ -211,6 +211,7 @@
   # include the math library for Unix
   if (UNIX AND NOT APPLE AND NOT BEOS)
     find_library(LUA_MATH_LIBRARY m)
+    mark_as_advanced(LUA_MATH_LIBRARY)
     set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}")
 
     # include dl library for statically-linked Lua library
@@ -232,6 +233,6 @@
                                   REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
                                   VERSION_VAR LUA_VERSION_STRING)
 
-mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)
+mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY)
 
 cmake_policy(POP)
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index d1257c9..3e42386 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -96,15 +96,27 @@
 Variables for locating MPI
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-This module performs a three step search for an MPI implementation:
+This module performs a four step search for an MPI implementation:
 
-1. Check if the compiler has MPI support built-in. This is the case if the user passed a
+1. Search for ``MPIEXEC_EXECUTABLE`` and, if found, use its base directory.
+2. 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.
+3. Attempt to find an MPI compiler wrapper and determine the compiler information from it.
+4. 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.
 
-For controlling the second step, the following variables may be set:
+For controlling the ``MPIEXEC_EXECUTABLE`` step, the following variables may be set:
+
+``MPIEXEC_EXECUTABLE``
+  Manually specify the location of ``mpiexec``.
+``MPI_HOME``
+  Specify the base directory of the MPI installation.
+``ENV{MPI_HOME}``
+  Environment variable to specify the base directory of the MPI installation.
+``ENV{I_MPI_ROOT}``
+  Environment variable to specify the base directory of the MPI installation.
+
+For controlling the compiler wrapper step, the following variables may be set:
 
 ``MPI_<lang>_COMPILER``
   Search for the specified compiler wrapper and use it.
@@ -1060,9 +1072,6 @@
 endmacro()
 
 macro(_MPI_split_include_dirs LANG)
-  if("${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
-    return()
-  endif()
   # Backwards compatibility: Search INCLUDE_PATH if given.
   if(MPI_${LANG}_INCLUDE_PATH)
     list(APPEND MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_INCLUDE_PATH}")
@@ -1475,7 +1484,9 @@
       endif()
     endif()
 
-    _MPI_split_include_dirs(${LANG})
+    if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
+      _MPI_split_include_dirs(${LANG})
+    endif()
     _MPI_assemble_libraries(${LANG})
 
     _MPI_adjust_compile_definitions(${LANG})
@@ -1644,7 +1655,8 @@
         list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_WORKS")
       endif()
     endif()
-    find_package_handle_standard_args(MPI_${LANG} REQUIRED_VARS ${MPI_${LANG}_REQUIRED_VARS}
+    find_package_handle_standard_args(MPI_${LANG} NAME_MISMATCHED
+      REQUIRED_VARS ${MPI_${LANG}_REQUIRED_VARS}
       VERSION_VAR MPI_${LANG}_VERSION)
 
     if(DEFINED MPI_${LANG}_VERSION)
diff --git a/Modules/FindOpenACC.cmake b/Modules/FindOpenACC.cmake
index 743e0e2..398dcf5 100644
--- a/Modules/FindOpenACC.cmake
+++ b/Modules/FindOpenACC.cmake
@@ -254,6 +254,7 @@
     _OPENACC_SET_VERSION_BY_SPEC_DATE("${LANG}")
 
     find_package_handle_standard_args(OpenACC_${LANG}
+      NAME_MISMATCHED
       REQUIRED_VARS OpenACC_${LANG}_FLAGS
       VERSION_VAR OpenACC_${LANG}_VERSION
     )
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index 23bb001d..74392da 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -130,6 +130,8 @@
   set(OPENGL_USE_${_COMPONENT} 1)
 endforeach()
 
+set(_OpenGL_CACHE_VARS)
+
 if (CYGWIN)
   find_path(OPENGL_INCLUDE_DIR GL/gl.h )
   list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR)
@@ -137,6 +139,11 @@
   find_library(OPENGL_gl_LIBRARY opengl32 )
   find_library(OPENGL_glu_LIBRARY glu32 )
 
+  list(APPEND _OpenGL_CACHE_VARS
+    OPENGL_INCLUDE_DIR
+    OPENGL_gl_LIBRARY
+    OPENGL_glu_LIBRARY
+    )
 elseif (WIN32)
 
   if(BORLAND)
@@ -147,6 +154,10 @@
     set (OPENGL_glu_LIBRARY glu32 CACHE STRING "GLU library for win32")
   endif()
 
+  list(APPEND _OpenGL_CACHE_VARS
+    OPENGL_gl_LIBRARY
+    OPENGL_glu_LIBRARY
+    )
 elseif (APPLE)
   # The OpenGL.framework provides both gl and glu
   find_library(OPENGL_gl_LIBRARY OpenGL DOC "OpenGL library for OS X")
@@ -155,6 +166,11 @@
   find_path(OPENGL_INCLUDE_DIR OpenGL/gl.h DOC "Include for OpenGL on OS X")
   list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR)
 
+  list(APPEND _OpenGL_CACHE_VARS
+    OPENGL_INCLUDE_DIR
+    OPENGL_gl_LIBRARY
+    OPENGL_glu_LIBRARY
+    )
 else()
   if (CMAKE_SYSTEM_NAME MATCHES "HP-UX")
     # Handle HP-UX cases where we only want to find OpenGL in either hpux64
@@ -194,6 +210,12 @@
     /usr/openwin/share/include
     /opt/graphics/OpenGL/include
   )
+  list(APPEND _OpenGL_CACHE_VARS
+    OPENGL_INCLUDE_DIR
+    OPENGL_GLX_INCLUDE_DIR
+    OPENGL_EGL_INCLUDE_DIR
+    OPENGL_xmesa_INCLUDE_DIR
+    )
 
   # Search for the GLVND libraries.  We do this regardless of COMPONENTS; we'll
   # take into account the COMPONENTS logic later.
@@ -222,6 +244,13 @@
           /usr/shlib
   )
 
+  list(APPEND _OpenGL_CACHE_VARS
+    OPENGL_opengl_LIBRARY
+    OPENGL_glx_LIBRARY
+    OPENGL_egl_LIBRARY
+    OPENGL_glu_LIBRARY
+    )
+
   set(_OpenGL_GL_POLICY_WARN 0)
   if(NOT DEFINED OpenGL_GL_PREFERENCE)
     set(OpenGL_GL_PREFERENCE "")
@@ -268,6 +297,7 @@
             ${_OPENGL_LIB_PATH}
       PATH_SUFFIXES libglvnd
       )
+    list(APPEND _OpenGL_CACHE_VARS OPENGL_gl_LIBRARY)
   endif()
 
   if(_OpenGL_GL_POLICY_WARN AND OPENGL_gl_LIBRARY AND OPENGL_opengl_LIBRARY AND OPENGL_glx_LIBRARY)
@@ -532,14 +562,5 @@
 # This deprecated setting is for backward compatibility with CMake1.4
 set(OPENGL_INCLUDE_PATH ${OPENGL_INCLUDE_DIR})
 
-mark_as_advanced(
-  OPENGL_INCLUDE_DIR
-  OPENGL_xmesa_INCLUDE_DIR
-  OPENGL_egl_LIBRARY
-  OPENGL_glu_LIBRARY
-  OPENGL_glx_LIBRARY
-  OPENGL_gl_LIBRARY
-  OPENGL_opengl_LIBRARY
-  OPENGL_EGL_INCLUDE_DIR
-  OPENGL_GLX_INCLUDE_DIR
-)
+mark_as_advanced(${_OpenGL_CACHE_VARS})
+unset(_OpenGL_CACHE_VARS)
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index 90d1c3e..26fed41 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -509,6 +509,7 @@
     endif()
 
     find_package_handle_standard_args(OpenMP_${LANG}
+      NAME_MISMATCHED
       REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
       VERSION_VAR OpenMP_${LANG}_VERSION
     )
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index 043fc6c..af713d6 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -458,7 +458,7 @@
     "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
 )
 
-mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
+mark_as_advanced(OPENSSL_INCLUDE_DIR)
 
 if(OPENSSL_FOUND)
   if(NOT TARGET OpenSSL::Crypto AND
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index d824ee8..a078049 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -27,6 +27,7 @@
       [VERSION_VAR <version-var>]
       [HANDLE_COMPONENTS]
       [CONFIG_MODE]
+      [NAME_MISMATCHED]
       [REASON_FAILURE_MESSAGE <reason-failure-message>]
       [FAIL_MESSAGE <custom-failure-message>]
       )
@@ -90,6 +91,12 @@
     Specify a custom failure message instead of using the default
     generated message.  Not recommended.
 
+  ``NAME_MISMATCHED``
+    Indicate that the ``<PackageName>`` does not match
+    ``${CMAKE_FIND_PACKAGE_NAME}``. This is usually a mistake and raises a
+    warning, but it may be intentional for usage of the command for components
+    of a larger package.
+
 Example for the simple signature:
 
 .. code-block:: cmake
@@ -106,6 +113,17 @@
 the content of the first ``<required-var>``.  On repeated CMake runs,
 the same message will not be printed again.
 
+.. note::
+
+  If ``<PackageName>`` does not match ``CMAKE_FIND_PACKAGE_NAME`` for the
+  calling module, a warning that there is a mismatch is given. The
+  ``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using
+  the old signature and the ``NAME_MISMATCHED`` argument using the new
+  signature. To avoid forcing the caller to require newer versions of CMake for
+  usage, the variable's value will be used if defined when the
+  ``NAME_MISMATCHED`` argument is not passed for the new signature (but using
+  both is an error)..
+
 Example for the full signature:
 
 .. code-block:: cmake
@@ -190,15 +208,32 @@
 
 function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
 
-# Set up the arguments for `cmake_parse_arguments`.
-  set(options  CONFIG_MODE  HANDLE_COMPONENTS)
+  # Set up the arguments for `cmake_parse_arguments`.
+  set(options  CONFIG_MODE  HANDLE_COMPONENTS NAME_MISMATCHED)
   set(oneValueArgs  FAIL_MESSAGE  REASON_FAILURE_MESSAGE VERSION_VAR  FOUND_VAR)
   set(multiValueArgs REQUIRED_VARS)
 
-# Check whether we are in 'simple' or 'extended' mode:
+  # Check whether we are in 'simple' or 'extended' mode:
   set(_KEYWORDS_FOR_EXTENDED_MODE  ${options} ${oneValueArgs} ${multiValueArgs} )
   list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
 
+  unset(FPHSA_NAME_MISMATCHED_override)
+  if (DEFINED FPHSA_NAME_MISMATCHED)
+    # If the variable NAME_MISMATCHED variable is set, error if it is passed as
+    # an argument. The former is for old signatures, the latter is for new
+    # signatures.
+    list(FIND ARGN "NAME_MISMATCHED" name_mismatched_idx)
+    if (NOT name_mismatched_idx EQUAL "-1")
+      message(FATAL_ERROR
+        "The `NAME_MISMATCHED` argument may only be specified by the argument or "
+        "the variable, not both.")
+    endif ()
+
+    # But use the variable if it is not an argument to avoid forcing minimum
+    # CMake version bumps for calling modules.
+    set(FPHSA_NAME_MISMATCHED_override "${FPHSA_NAME_MISMATCHED}")
+  endif ()
+
   if(${INDEX} EQUAL -1)
     set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
     set(FPHSA_REQUIRED_VARS ${ARGN})
@@ -227,6 +262,21 @@
     endif()
   endif()
 
+  if (DEFINED FPHSA_NAME_MISMATCHED_override)
+    set(FPHSA_NAME_MISMATCHED "${FPHSA_NAME_MISMATCHED_override}")
+  endif ()
+
+  if (DEFINED CMAKE_FIND_PACKAGE_NAME
+      AND NOT FPHSA_NAME_MISMATCHED
+      AND NOT _NAME STREQUAL CMAKE_FIND_PACKAGE_NAME)
+    message(AUTHOR_WARNING
+      "The package name passed to `find_package_handle_standard_args` "
+      "(${_NAME}) does not match the name of the calling package "
+      "(${CMAKE_FIND_PACKAGE_NAME}). This can lead to problems in calling "
+      "code that expects `find_package` result variables (e.g., `_FOUND`) "
+      "to follow a certain pattern.")
+  endif ()
+
 # now that we collected all arguments, process them
 
   if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
@@ -239,10 +289,12 @@
   string(TOLOWER ${_NAME} _NAME_LOWER)
 
   if(FPHSA_FOUND_VAR)
-    if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$"  OR  FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
+    set(_FOUND_VAR_UPPER ${_NAME_UPPER}_FOUND)
+    set(_FOUND_VAR_MIXED ${_NAME}_FOUND)
+    if(FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_MIXED  OR  FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_UPPER)
       set(_FOUND_VAR ${FPHSA_FOUND_VAR})
     else()
-      message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
+      message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_FOUND_VAR_MIXED}\" and \"${_FOUND_VAR_UPPER}\" are valid names.")
     endif()
   else()
     set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
diff --git a/Modules/FindTCL.cmake b/Modules/FindTCL.cmake
index be47c39..960265f 100644
--- a/Modules/FindTCL.cmake
+++ b/Modules/FindTCL.cmake
@@ -224,12 +224,14 @@
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCL DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH)
+set(FPHSA_NAME_MISMATCHED 1)
 set(TCLTK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
 set(TCLTK_FIND_QUIETLY  ${TCL_FIND_QUIETLY})
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCLTK DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH TK_LIBRARY TK_INCLUDE_PATH)
 set(TK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
 set(TK_FIND_QUIETLY  ${TCL_FIND_QUIETLY})
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(TK DEFAULT_MSG TK_LIBRARY TK_INCLUDE_PATH)
+unset(FPHSA_NAME_MISMATCHED)
 
 mark_as_advanced(
   TCL_INCLUDE_PATH
diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake
index 0e1429d..04687b9 100644
--- a/Modules/InstallRequiredSystemLibraries.cmake
+++ b/Modules/InstallRequiredSystemLibraries.cmake
@@ -288,9 +288,16 @@
         "${MSVC_CRT_DIR}/msvcp${v}.dll"
         )
       if(NOT vs VERSION_LESS 14)
-        if(EXISTS "${MSVC_CRT_DIR}/vcruntime${v}_1.dll")
-          list(APPEND __install__libs "${MSVC_CRT_DIR}/vcruntime${v}_1.dll")
-        endif()
+        foreach(crt
+            "${MSVC_CRT_DIR}/msvcp${v}_1.dll"
+            "${MSVC_CRT_DIR}/msvcp${v}_2.dll"
+            "${MSVC_CRT_DIR}/msvcp${v}_codecvt_ids.dll"
+            "${MSVC_CRT_DIR}/vcruntime${v}_1.dll"
+            )
+          if(EXISTS "${crt}")
+            list(APPEND __install__libs "${crt}")
+          endif()
+        endforeach()
         list(APPEND __install__libs
             "${MSVC_CRT_DIR}/vcruntime${v}.dll"
             "${MSVC_CRT_DIR}/concrt${v}.dll"
@@ -309,9 +316,16 @@
         "${MSVC_CRT_DIR}/msvcp${v}d.dll"
         )
       if(NOT vs VERSION_LESS 14)
-        if(EXISTS "${MSVC_CRT_DIR}/vcruntime${v}_1d.dll")
-          list(APPEND __install__libs "${MSVC_CRT_DIR}/vcruntime${v}_1d.dll")
-        endif()
+        foreach(crt
+            "${MSVC_CRT_DIR}/msvcp${v}_1d.dll"
+            "${MSVC_CRT_DIR}/msvcp${v}_2d.dll"
+            "${MSVC_CRT_DIR}/msvcp${v}d_codecvt_ids.dll"
+            "${MSVC_CRT_DIR}/vcruntime${v}_1d.dll"
+            )
+          if(EXISTS "${crt}")
+            list(APPEND __install__libs "${crt}")
+          endif()
+        endforeach()
         list(APPEND __install__libs
             "${MSVC_CRT_DIR}/vcruntime${v}d.dll"
             "${MSVC_CRT_DIR}/concrt${v}d.dll"
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index 02864c6..c17cf6d 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -24,7 +24,7 @@
   set(CMAKE_DEPFILE_FLAGS_${lang} "-MD -MT <OBJECT> -MF <DEPFILE>")
 
   set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
-  set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a" ".lib")
+  set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".a" ".lib")
   set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1)
   set (CMAKE_LINK_DEF_FILE_FLAG "-Xlinker /DEF:")
 
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index 235d9ce..38a8cf4 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -25,7 +25,7 @@
 
 if(MINGW)
   set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
-  set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a" ".lib")
+  set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".a" ".lib")
   set(CMAKE_C_STANDARD_LIBRARIES_INIT "-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32")
   set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
 endif()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 721e823..103129a 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 16)
-set(CMake_VERSION_PATCH 20200117)
+set(CMake_VERSION_PATCH 20200124)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index a595007..34f815f 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -8,7 +8,6 @@
 
 #include <cmext/algorithm>
 
-#include "cmAlgorithms.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
 #include "cmGeneratorExpression.h"
@@ -30,9 +29,6 @@
       cmExpandedList(cge->Evaluate(lg, config));
     for (std::string& it : result) {
       cmSystemTools::ConvertToUnixSlashes(it);
-      if (cmContains(it, '/') && !cmSystemTools::FileIsFullPath(it)) {
-        it = cmStrCat(lg->GetMakefile()->GetCurrentBinaryDirectory(), '/', it);
-      }
       if (cmSystemTools::FileIsFullPath(it)) {
         it = cmSystemTools::CollapseFullPath(
           it, lg->GetMakefile()->GetHomeOutputDirectory());
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index d1775a7..79110ab 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -25,6 +25,7 @@
 #include "cm_static_string_view.hxx"
 #include "cm_sys_stat.h"
 
+#include "cmAlgorithms.h"
 #include "cmArgumentParser.h"
 #include "cmCryptoHash.h"
 #include "cmExecutionStatus.h"
@@ -2674,9 +2675,20 @@
     cmSystemTools::SetFatalErrorOccured();
     return false;
   }
-  argIt = keywordsMissingValues.begin();
-  if (argIt != keywordsMissingValues.end()) {
-    status.SetError(cmStrCat("Keyword missing value: ", *argIt));
+
+  const std::vector<std::string> LIST_ARGS = { "DIRECTORIES",
+                                               "EXECUTABLES",
+                                               "LIBRARIES",
+                                               "MODULES",
+                                               "POST_EXCLUDE_REGEXES",
+                                               "POST_INCLUDE_REGEXES",
+                                               "PRE_EXCLUDE_REGEXES",
+                                               "PRE_INCLUDE_REGEXES" };
+  auto kwbegin = keywordsMissingValues.cbegin();
+  auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
+  if (kwend != kwbegin) {
+    status.SetError(cmStrCat("Keywords missing values:\n  ",
+                             cmJoin(cmMakeRange(kwbegin, kwend), "\n  ")));
     cmSystemTools::SetFatalErrorOccured();
     return false;
   }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 4158c53..792cd4d 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -2713,6 +2713,17 @@
   if (i == this->NameMap.end() || i->first != name) {
     // Check if we know how to generate this file.
     cmSourcesWithOutput sources = this->Makefile->GetSourcesWithOutput(name);
+    // If we failed to find a target or source and we have a relative path, it
+    // might be a valid source if made relative to the current binary
+    // directory.
+    if (!sources.Target && !sources.Source &&
+        !cmSystemTools::FileIsFullPath(name)) {
+      auto fullname =
+        cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', name);
+      fullname = cmSystemTools::CollapseFullPath(
+        fullname, this->Makefile->GetHomeOutputDirectory());
+      sources = this->Makefile->GetSourcesWithOutput(fullname);
+    }
     i = this->NameMap.emplace_hint(i, name, sources);
   }
   if (cmTarget* t = i->second.Target) {
@@ -3396,8 +3407,15 @@
       { "OBJCXX", ".objcxx.hxx" }
     };
 
-    filename = cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(),
-                        ".dir/cmake_pch", languageToExtension.at(language));
+    filename =
+      cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(), ".dir");
+
+    if (this->GetGlobalGenerator()->IsMultiConfig()) {
+      filename = cmStrCat(filename, "/", config);
+    }
+
+    filename =
+      cmStrCat(filename, "/cmake_pch", languageToExtension.at(language));
 
     const std::string filename_tmp = cmStrCat(filename, ".tmp");
     if (!pchReuseFrom) {
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index b3eb8e4..38ff3ae 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -7,6 +7,7 @@
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
+#include <functional>
 #include <initializer_list>
 #include <iterator>
 #include <sstream>
@@ -3120,6 +3121,16 @@
   return this->FilenameTargetDepends[sf];
 }
 
+const std::string& cmGlobalGenerator::GetRealPath(const std::string& dir)
+{
+  auto i = this->RealPaths.lower_bound(dir);
+  if (i == this->RealPaths.end() ||
+      this->RealPaths.key_comp()(dir, i->first)) {
+    i = this->RealPaths.emplace_hint(i, dir, cmSystemTools::GetRealPath(dir));
+  }
+  return i->second;
+}
+
 void cmGlobalGenerator::ProcessEvaluationFiles()
 {
   std::vector<std::string> generatedFiles;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index b427992..f6ed10f 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -415,6 +415,8 @@
 
   virtual bool IsXcode() const { return false; }
 
+  virtual bool IsVisualStudio() const { return false; }
+
   /** Return true if we know the exact location of object files.
       If false, store the reason in the given string.
       This is meaningful only after EnableLanguage has been called.  */
@@ -486,6 +488,8 @@
     configs.emplace_back("$<CONFIG>");
   }
 
+  std::string const& GetRealPath(std::string const& dir);
+
 protected:
   // for a project collect all its targets by following depend
   // information, and also collect all the targets
@@ -678,6 +682,8 @@
   mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
     FilenameTargetDepends;
 
+  std::map<std::string, std::string> RealPaths;
+
 #if !defined(CMAKE_BOOTSTRAP)
   // Pool of file locks
   cmFileLockPool FileLockPool;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 0487ad1..308644e 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -293,7 +293,7 @@
     if (config.empty()) {
       this->WriteBuild(*this->GetCommonFileStream(), build);
     } else {
-      this->WriteBuild(*this->GetConfigFileStream(config), build);
+      this->WriteBuild(*this->GetImplFileStream(config), build);
     }
   }
 
@@ -324,7 +324,7 @@
     cmNinjaBuild build("COPY_OSX_CONTENT");
     build.Outputs.push_back(std::move(output));
     build.ExplicitDeps.push_back(std::move(input));
-    this->WriteBuild(*this->GetConfigFileStream(config), build);
+    this->WriteBuild(*this->GetImplFileStream(config), build);
   }
 }
 
@@ -518,6 +518,7 @@
   if (cmSystemTools::GetErrorOccuredFlag()) {
     this->RulesFileStream->setstate(std::ios::failbit);
     for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+      this->GetImplFileStream(config)->setstate(std::ios::failbit);
       this->GetConfigFileStream(config)->setstate(std::ios::failbit);
     }
     this->GetCommonFileStream()->setstate(std::ios::failbit);
@@ -527,15 +528,13 @@
   this->CloseRulesFileStream();
   this->CloseBuildFileStreams();
 
-  if (!this->WriteDefaultBuildFile()) {
-    return;
-  }
-
-  auto run_ninja_tool = [this](char const* tool) {
+  auto run_ninja_tool = [this](std::vector<char const*> const& args) {
     std::vector<std::string> command;
     command.push_back(this->NinjaCommand);
     command.emplace_back("-t");
-    command.emplace_back(tool);
+    for (auto const& arg : args) {
+      command.emplace_back(arg);
+    }
     std::string error;
     if (!cmSystemTools::RunSingleCommand(command, nullptr, &error, nullptr,
                                          nullptr,
@@ -550,14 +549,35 @@
     }
   };
 
-  if (this->NinjaSupportsCleanDeadTool) {
-    run_ninja_tool("cleandead");
+  // The `cleandead` tool needs to know about all outputs in the build we just
+  // wrote out. Ninja-Multi doesn't have a single `build.ninja` we can use that
+  // is the union of all generated configurations, so we can't run it reliably
+  // in that case.
+  if (this->NinjaSupportsCleanDeadTool && !this->IsMultiConfig()) {
+    run_ninja_tool({ "cleandead" });
   }
-  if (this->NinjaSupportsUnconditionalRecompactTool) {
-    run_ninja_tool("recompact");
+  // The `recompact` tool loads the manifest. As above, we don't have a single
+  // `build.ninja` to load for this in Ninja-Multi. This may be relaxed in the
+  // future pending further investigation into how Ninja works upstream
+  // (ninja#1721).
+  if (this->NinjaSupportsUnconditionalRecompactTool &&
+      !this->IsMultiConfig()) {
+    run_ninja_tool({ "recompact" });
   }
   if (this->NinjaSupportsRestatTool) {
-    run_ninja_tool("restat");
+    // XXX(ninja): We only list `build.ninja` entry files here because CMake
+    // *always* rewrites these files on a reconfigure. If CMake ever gets
+    // smarter about this, all CMake-time created/edited files listed as
+    // outputs for the reconfigure build statement will need to be listed here.
+    cmNinjaDeps outputs;
+    this->AddRebuildManifestOutputs(outputs);
+    std::vector<const char*> args;
+    args.reserve(outputs.size() + 1);
+    args.push_back("restat");
+    for (auto const& output : outputs) {
+      args.push_back(output.c_str());
+    }
+    run_ninja_tool(args);
   }
 }
 
@@ -1150,14 +1170,11 @@
       newAliasGlobal.first->second.GeneratorTarget != target) {
     newAliasGlobal.first->second.GeneratorTarget = nullptr;
   }
-  if (config != "all") {
-    std::pair<TargetAliasMap::iterator, bool> newAliasConfig =
-      this->Configs[config].TargetAliases.insert(
-        std::make_pair(outputPath, ta));
-    if (newAliasConfig.second &&
-        newAliasConfig.first->second.GeneratorTarget != target) {
-      newAliasConfig.first->second.GeneratorTarget = nullptr;
-    }
+  std::pair<TargetAliasMap::iterator, bool> newAliasConfig =
+    this->Configs[config].TargetAliases.insert(std::make_pair(outputPath, ta));
+  if (newAliasConfig.second &&
+      newAliasConfig.first->second.GeneratorTarget != target) {
+    newAliasConfig.first->second.GeneratorTarget = nullptr;
   }
 }
 
@@ -1194,7 +1211,7 @@
     }
     this->WriteBuild(this->EnableCrossConfigBuild()
                        ? os
-                       : *this->GetConfigFileStream(ta.second.Config),
+                       : *this->GetImplFileStream(ta.second.Config),
                      build);
   }
 
@@ -1219,6 +1236,37 @@
         this->WriteBuild(*this->GetConfigFileStream(config), build);
       }
     }
+
+    auto const* defaultConfig = this->GetDefaultBuildAlias();
+    if (defaultConfig) {
+      std::string config = defaultConfig;
+      for (auto const& ta : this->Configs[config].TargetAliases) {
+        // Don't write ambiguous aliases.
+        if (!ta.second.GeneratorTarget) {
+          continue;
+        }
+
+        // Don't write alias if there is a already a custom command with
+        // matching output
+        if (this->HasCustomCommandOutput(ta.first)) {
+          continue;
+        }
+
+        build.Outputs.front() = ta.first;
+        build.ExplicitDeps.clear();
+        if (config == "all") {
+          for (auto const& config2 :
+               this->Makefiles.front()->GetGeneratorConfigs()) {
+            this->AppendTargetOutputs(ta.second.GeneratorTarget,
+                                      build.ExplicitDeps, config2);
+          }
+        } else {
+          this->AppendTargetOutputs(ta.second.GeneratorTarget,
+                                    build.ExplicitDeps, config);
+        }
+        this->WriteBuild(*this->GetDefaultFileStream(), build);
+      }
+    }
   }
 }
 
@@ -1262,10 +1310,9 @@
         }
       }
       // Write target
-      this->WriteBuild(this->EnableCrossConfigBuild()
-                         ? os
-                         : *this->GetConfigFileStream(config),
-                       build);
+      this->WriteBuild(
+        this->EnableCrossConfigBuild() ? os : *this->GetImplFileStream(config),
+        build);
     }
 
     // Add shortcut target
@@ -1277,6 +1324,16 @@
           this->ConvertToNinjaPath(currentBinaryDir + "/all");
         this->WriteBuild(*this->GetConfigFileStream(config), build);
       }
+
+      auto const* defaultConfig = this->GetDefaultBuildAlias();
+      if (defaultConfig) {
+        std::string config = defaultConfig;
+        build.ExplicitDeps = { this->BuildAlias(
+          this->ConvertToNinjaPath(currentBinaryDir + "/all"), config) };
+        build.Outputs.front() =
+          this->ConvertToNinjaPath(currentBinaryDir + "/all");
+        this->WriteBuild(*this->GetDefaultFileStream(), build);
+      }
     }
 
     // Add target for all configs
@@ -1428,6 +1485,10 @@
   for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
     this->WriteTargetDefault(*this->GetConfigFileStream(config));
   }
+
+  if (this->GetDefaultBuildType()) {
+    this->WriteTargetDefault(*this->GetDefaultFileStream());
+  }
 }
 
 void cmGlobalNinjaGenerator::WriteTargetDefault(std::ostream& os)
@@ -1720,9 +1781,10 @@
         }
         if (this->IsMultiConfig()) {
           build.Variables["FILE_ARG"] = cmStrCat(
-            "-f ", cmGlobalNinjaMultiGenerator::GetNinjaFilename(fileConfig));
+            "-f ",
+            cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig));
         }
-        this->WriteBuild(*this->GetConfigFileStream(fileConfig), build);
+        this->WriteBuild(*this->GetImplFileStream(fileConfig), build);
       }
     }
 
@@ -1740,8 +1802,9 @@
 
       for (auto const& fileConfig : configs) {
         build.Variables["FILE_ARG"] = cmStrCat(
-          "-f ", cmGlobalNinjaMultiGenerator::GetNinjaFilename(fileConfig));
-        this->WriteBuild(*this->GetConfigFileStream(fileConfig), build);
+          "-f ",
+          cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig));
+        this->WriteBuild(*this->GetImplFileStream(fileConfig), build);
       }
     }
   }
@@ -1757,6 +1820,14 @@
         this->NinjaOutputPath(this->GetCleanTargetName()), config);
       this->WriteBuild(*this->GetConfigFileStream(config), build);
     }
+
+    auto const* defaultConfig = this->GetDefaultBuildAlias();
+    if (defaultConfig) {
+      std::string config = defaultConfig;
+      build.ExplicitDeps.front() = this->BuildAlias(
+        this->NinjaOutputPath(this->GetCleanTargetName()), config);
+      this->WriteBuild(*this->GetDefaultFileStream(), build);
+    }
   }
 
   // Write byproducts
@@ -2297,7 +2368,8 @@
   }
 }
 
-const char* cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE = "common.ninja";
+const char* cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE =
+  "CMakeFiles/common.ninja";
 const char* cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION = ".ninja";
 
 cmGlobalNinjaMultiGenerator::cmGlobalNinjaMultiGenerator(cmake* cm)
@@ -2328,21 +2400,45 @@
     return false;
   }
 
+  auto const* defaultConfig = this->GetDefaultBuildType();
+  if (defaultConfig) {
+    if (!this->OpenFileStream(this->DefaultFileStream, NINJA_BUILD_FILE)) {
+      return false;
+    }
+    *this->DefaultFileStream
+      << "# This file is a convenience file generated by\n"
+      << "# CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE.\n\n"
+      << "include " << GetNinjaImplFilename(defaultConfig) << "\n\n";
+  }
+
   // Write a comment about this file.
   *this->CommonFileStream
     << "# This file contains build statements common to all "
        "configurations.\n\n";
 
   for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+    // Open impl file.
+    if (!this->OpenFileStream(this->ImplFileStreams[config],
+                              GetNinjaImplFilename(config))) {
+      return false;
+    }
+
+    // Write a comment about this file.
+    *this->ImplFileStreams[config]
+      << "# This file contains build statements specific to the \"" << config
+      << "\"\n# configuration.\n\n";
+
+    // Open config file.
     if (!this->OpenFileStream(this->ConfigFileStreams[config],
-                              GetNinjaFilename(config))) {
+                              GetNinjaConfigFilename(config))) {
       return false;
     }
 
     // Write a comment about this file.
     *this->ConfigFileStreams[config]
-      << "# This file contains build statements specific to the \"" << config
-      << "\"\n# configuration.\n\n";
+      << "# This file contains aliases specific to the \"" << config
+      << "\"\n# configuration.\n\n"
+      << "include " << GetNinjaImplFilename(config) << "\n\n";
   }
 
   return true;
@@ -2356,7 +2452,17 @@
     cmSystemTools::Error("Common file stream was not open.");
   }
 
+  if (this->DefaultFileStream) {
+    this->DefaultFileStream.reset();
+  } // No error if it wasn't open
+
   for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+    if (this->ImplFileStreams[config]) {
+      this->ImplFileStreams[config].reset();
+    } else {
+      cmSystemTools::Error(
+        cmStrCat("Impl file stream for \"", config, "\" was not open."));
+    }
     if (this->ConfigFileStreams[config]) {
       this->ConfigFileStreams[config].reset();
     } else {
@@ -2370,10 +2476,17 @@
   GeneratedMakeCommand& command, const std::string& config) const
 {
   command.Add("-f");
-  command.Add(GetNinjaFilename(config));
+  command.Add(GetNinjaConfigFilename(config));
 }
 
-std::string cmGlobalNinjaMultiGenerator::GetNinjaFilename(
+std::string cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(
+  const std::string& config)
+{
+  return cmStrCat("CMakeFiles/impl-", config,
+                  cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION);
+}
+
+std::string cmGlobalNinjaMultiGenerator::GetNinjaConfigFilename(
   const std::string& config)
 {
   return cmStrCat("build-", config,
@@ -2384,7 +2497,8 @@
   cmNinjaDeps& outputs) const
 {
   for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
-    outputs.push_back(this->NinjaOutputPath(GetNinjaFilename(config)));
+    outputs.push_back(this->NinjaOutputPath(GetNinjaImplFilename(config)));
+    outputs.push_back(this->NinjaOutputPath(GetNinjaConfigFilename(config)));
   }
   if (this->Makefiles.front()->GetDefinition(
         "CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE")) {
@@ -2402,20 +2516,21 @@
   }
 }
 
-bool cmGlobalNinjaMultiGenerator::WriteDefaultBuildFile()
+const char* cmGlobalNinjaMultiGenerator::GetDefaultBuildType() const
 {
-  auto const* defaultConfig = this->Makefiles.front()->GetDefinition(
+  return this->Makefiles.front()->GetDefinition(
     "CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE");
-  if (defaultConfig) {
-    std::unique_ptr<cmGeneratedFileStream> defaultStream;
-    if (!this->OpenFileStream(defaultStream, NINJA_BUILD_FILE)) {
-      return false;
+}
+
+const char* cmGlobalNinjaMultiGenerator::GetDefaultBuildAlias() const
+{
+  if (this->EnableCrossConfigBuild()) {
+    auto const* alias = this->Makefiles.front()->GetDefinition(
+      "CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS");
+    if (alias) {
+      return alias;
     }
-    *defaultStream << "# This file is a convenience file generated by\n"
-                   << "# CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE.\n\n"
-                   << "include " << this->GetNinjaFilename(defaultConfig)
-                   << "\n";
   }
 
-  return true;
+  return this->GetDefaultBuildType();
 }
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 3545f1e..b61999f 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -208,12 +208,23 @@
   }
   const char* GetCleanTargetName() const override { return "clean"; }
 
+  virtual cmGeneratedFileStream* GetImplFileStream(
+    const std::string& /*config*/) const
+  {
+    return this->BuildFileStream.get();
+  }
+
   virtual cmGeneratedFileStream* GetConfigFileStream(
     const std::string& /*config*/) const
   {
     return this->BuildFileStream.get();
   }
 
+  virtual cmGeneratedFileStream* GetDefaultFileStream() const
+  {
+    return this->BuildFileStream.get();
+  }
+
   virtual cmGeneratedFileStream* GetCommonFileStream() const
   {
     return this->BuildFileStream.get();
@@ -397,6 +408,10 @@
 
   bool EnableCrossConfigBuild() const;
 
+  virtual const char* GetDefaultBuildType() const { return nullptr; }
+
+  virtual const char* GetDefaultBuildAlias() const { return nullptr; }
+
 protected:
   void Generate() override;
 
@@ -404,7 +419,6 @@
 
   virtual bool OpenBuildFileStreams();
   virtual void CloseBuildFileStreams();
-  virtual bool WriteDefaultBuildFile() { return true; }
 
   bool OpenFileStream(std::unique_ptr<cmGeneratedFileStream>& stream,
                       const std::string& name);
@@ -573,12 +587,23 @@
   std::string ExpandCFGIntDir(const std::string& str,
                               const std::string& config) const override;
 
+  cmGeneratedFileStream* GetImplFileStream(
+    const std::string& config) const override
+  {
+    return this->ImplFileStreams.at(config).get();
+  }
+
   cmGeneratedFileStream* GetConfigFileStream(
     const std::string& config) const override
   {
     return this->ConfigFileStreams.at(config).get();
   }
 
+  cmGeneratedFileStream* GetDefaultFileStream() const override
+  {
+    return this->DefaultFileStream.get();
+  }
+
   cmGeneratedFileStream* GetCommonFileStream() const override
   {
     return this->CommonFileStream.get();
@@ -587,13 +612,16 @@
   void AppendNinjaFileArgument(GeneratedMakeCommand& command,
                                const std::string& config) const override;
 
-  static std::string GetNinjaFilename(const std::string& config);
+  static std::string GetNinjaImplFilename(const std::string& config);
+  static std::string GetNinjaConfigFilename(const std::string& config);
 
   void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const override;
 
   void GetQtAutoGenConfigs(std::vector<std::string>& configs) const override;
 
-  bool WriteDefaultBuildFile() override;
+  const char* GetDefaultBuildType() const override;
+
+  const char* GetDefaultBuildAlias() const override;
 
 protected:
   bool OpenBuildFileStreams() override;
@@ -601,8 +629,11 @@
 
 private:
   std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>
+    ImplFileStreams;
+  std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>
     ConfigFileStreams;
   std::unique_ptr<cmGeneratedFileStream> CommonFileStream;
+  std::unique_ptr<cmGeneratedFileStream> DefaultFileStream;
 };
 
 #endif // ! cmGlobalNinjaGenerator_h
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 0591758..90c9ef0 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -892,6 +892,9 @@
 
   // Keep track of targets already listed.
   std::set<std::string> emittedTargets;
+  std::set<std::string> utility_targets;
+  std::set<std::string> globals_targets;
+  std::set<std::string> project_targets;
 
   // for each local generator
   for (const auto& localGen : this->LocalGenerators) {
@@ -907,18 +910,30 @@
             (type == cmStateEnums::STATIC_LIBRARY) ||
             (type == cmStateEnums::SHARED_LIBRARY) ||
             (type == cmStateEnums::MODULE_LIBRARY) ||
-            (type == cmStateEnums::OBJECT_LIBRARY) ||
-            (type == cmStateEnums::GLOBAL_TARGET) ||
-            (type == cmStateEnums::UTILITY)) {
-          std::string const& name = target->GetName();
-          if (emittedTargets.insert(name).second) {
-            path = cmStrCat("... ", name);
-            lg->AppendEcho(commands, path);
-          }
+            (type == cmStateEnums::OBJECT_LIBRARY)) {
+          project_targets.insert(target->GetName());
+        } else if (type == cmStateEnums::GLOBAL_TARGET) {
+          globals_targets.insert(target->GetName());
+        } else if (type == cmStateEnums::UTILITY) {
+          utility_targets.insert(target->GetName());
         }
       }
     }
   }
+
+  for (std::string const& name : globals_targets) {
+    path = cmStrCat("... ", name);
+    lg->AppendEcho(commands, path);
+  }
+  for (std::string const& name : utility_targets) {
+    path = cmStrCat("... ", name);
+    lg->AppendEcho(commands, path);
+  }
+  for (std::string const& name : project_targets) {
+    path = cmStrCat("... ", name);
+    lg->AppendEcho(commands, path);
+  }
+
   for (std::string const& o : lg->GetLocalHelp()) {
     path = cmStrCat("... ", o);
     lg->AppendEcho(commands, path);
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 4f2007f..29a5c2c 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -150,6 +150,8 @@
   bool Open(const std::string& bindir, const std::string& projectName,
             bool dryRun) override;
 
+  bool IsVisualStudio() const override { return true; }
+
 protected:
   cmGlobalVisualStudioGenerator(cmake* cm,
                                 std::string const& platformInGeneratorName);
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 54b85cd..c67358f 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -93,13 +93,12 @@
   cmInstallGenerator::MessageLevel message =
     cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
   target.SetHaveInstallRule(true);
-  const char* component = namelink ? args.GetNamelinkComponent().c_str()
-                                   : args.GetComponent().c_str();
+  const std::string& component =
+    namelink ? args.GetNamelinkComponent() : args.GetComponent();
   auto g = cm::make_unique<cmInstallTargetGenerator>(
-    target.GetName(), destination.c_str(), impLib,
-    args.GetPermissions().c_str(), args.GetConfigurations(), component,
-    message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt,
-    backtrace);
+    target.GetName(), destination, impLib, args.GetPermissions(),
+    args.GetConfigurations(), component, message, args.GetExcludeFromAll(),
+    args.GetOptional() || forceOpt, backtrace);
   target.AddInstallGenerator(g.get());
   return g;
 }
@@ -122,9 +121,9 @@
   cmInstallGenerator::MessageLevel message =
     cmInstallGenerator::SelectMessageLevel(mf);
   return cm::make_unique<cmInstallFilesGenerator>(
-    absFiles, destination.c_str(), programs, args.GetPermissions().c_str(),
-    args.GetConfigurations(), args.GetComponent().c_str(), message,
-    args.GetExcludeFromAll(), args.GetRename().c_str(), args.GetOptional());
+    absFiles, destination, programs, args.GetPermissions(),
+    args.GetConfigurations(), args.GetComponent(), message,
+    args.GetExcludeFromAll(), args.GetRename(), args.GetOptional());
 }
 
 std::unique_ptr<cmInstallFilesGenerator> CreateInstallFilesGenerator(
@@ -197,14 +196,14 @@
         return false;
       }
       helper.Makefile->AddInstallGenerator(
-        cm::make_unique<cmInstallScriptGenerator>(
-          script.c_str(), false, component.c_str(), exclude_from_all));
+        cm::make_unique<cmInstallScriptGenerator>(script, false, component,
+                                                  exclude_from_all));
     } else if (doing_code) {
       doing_code = false;
       std::string const& code = arg;
       helper.Makefile->AddInstallGenerator(
-        cm::make_unique<cmInstallScriptGenerator>(
-          code.c_str(), true, component.c_str(), exclude_from_all));
+        cm::make_unique<cmInstallScriptGenerator>(code, true, component,
+                                                  exclude_from_all));
     }
   }
 
@@ -943,7 +942,7 @@
   bool exclude_from_all = false;
   bool message_never = false;
   std::vector<std::string> dirs;
-  const char* destination = nullptr;
+  const std::string* destination = nullptr;
   std::string permissions_file;
   std::string permissions_dir;
   std::vector<std::string> configurations;
@@ -1102,7 +1101,7 @@
     } else if (doing == DoingConfigurations) {
       configurations.push_back(args[i]);
     } else if (doing == DoingDestination) {
-      destination = args[i].c_str();
+      destination = &args[i];
       doing = DoingNone;
     } else if (doing == DoingType) {
       if (allowedTypes.count(args[i]) == 0) {
@@ -1188,7 +1187,7 @@
       return false;
     }
     destinationStr = helper.GetDestinationForType(nullptr, type);
-    destination = destinationStr.c_str();
+    destination = &destinationStr;
   } else if (!type.empty()) {
     status.SetError(cmStrCat(args[0],
                              " given both TYPE and DESTINATION "
@@ -1202,9 +1201,8 @@
   // Create the directory install generator.
   helper.Makefile->AddInstallGenerator(
     cm::make_unique<cmInstallDirectoryGenerator>(
-      dirs, destination, permissions_file.c_str(), permissions_dir.c_str(),
-      configurations, component.c_str(), message, exclude_from_all,
-      literal_args.c_str(), optional));
+      dirs, *destination, permissions_file, permissions_dir, configurations,
+      component, message, exclude_from_all, literal_args, optional));
 
   // Tell the global generator about any installation component names
   // specified.
@@ -1294,10 +1292,9 @@
   // Create the export install generator.
   helper.Makefile->AddInstallGenerator(
     cm::make_unique<cmInstallExportGenerator>(
-      &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
-      ica.GetConfigurations(), ica.GetComponent().c_str(), message,
-      ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld,
-      true));
+      &exportSet, ica.GetDestination(), ica.GetPermissions(),
+      ica.GetConfigurations(), ica.GetComponent(), message,
+      ica.GetExcludeFromAll(), fname, name_space, exportOld, true));
 
   return true;
 #else
@@ -1408,10 +1405,9 @@
   // Create the export install generator.
   helper.Makefile->AddInstallGenerator(
     cm::make_unique<cmInstallExportGenerator>(
-      &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
-      ica.GetConfigurations(), ica.GetComponent().c_str(), message,
-      ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld,
-      false));
+      &exportSet, ica.GetDestination(), ica.GetPermissions(),
+      ica.GetConfigurations(), ica.GetComponent(), message,
+      ica.GetExcludeFromAll(), fname, name_space, exportOld, false));
 
   return true;
 }
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index 259c7f7..175e7cf 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -2,6 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmInstallDirectoryGenerator.h"
 
+#include <utility>
+
 #include "cmGeneratorExpression.h"
 #include "cmInstallType.h"
 #include "cmLocalGenerator.h"
@@ -10,18 +12,18 @@
 #include "cmSystemTools.h"
 
 cmInstallDirectoryGenerator::cmInstallDirectoryGenerator(
-  std::vector<std::string> const& dirs, const char* dest,
-  const char* file_permissions, const char* dir_permissions,
-  std::vector<std::string> const& configurations, const char* component,
-  MessageLevel message, bool exclude_from_all, const char* literal_args,
+  std::vector<std::string> const& dirs, std::string const& dest,
+  std::string file_permissions, std::string dir_permissions,
+  std::vector<std::string> const& configurations, std::string const& component,
+  MessageLevel message, bool exclude_from_all, std::string literal_args,
   bool optional)
   : cmInstallGenerator(dest, configurations, component, message,
                        exclude_from_all)
   , LocalGenerator(nullptr)
   , Directories(dirs)
-  , FilePermissions(file_permissions)
-  , DirPermissions(dir_permissions)
-  , LiteralArguments(literal_args)
+  , FilePermissions(std::move(file_permissions))
+  , DirPermissions(std::move(dir_permissions))
+  , LiteralArguments(std::move(literal_args))
   , Optional(optional)
 {
   // We need per-config actions if destination have generator expressions.
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index 84c0694..bec89df 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -21,12 +21,13 @@
 {
 public:
   cmInstallDirectoryGenerator(std::vector<std::string> const& dirs,
-                              const char* dest, const char* file_permissions,
-                              const char* dir_permissions,
+                              std::string const& dest,
+                              std::string file_permissions,
+                              std::string dir_permissions,
                               std::vector<std::string> const& configurations,
-                              const char* component, MessageLevel message,
-                              bool exclude_from_all, const char* literal_args,
-                              bool optional = false);
+                              std::string const& component,
+                              MessageLevel message, bool exclude_from_all,
+                              std::string literal_args, bool optional = false);
   ~cmInstallDirectoryGenerator() override;
 
   bool Compute(cmLocalGenerator* lg) override;
@@ -41,11 +42,11 @@
                                Indent indent,
                                std::vector<std::string> const& dirs);
   cmLocalGenerator* LocalGenerator;
-  std::vector<std::string> Directories;
-  std::string FilePermissions;
-  std::string DirPermissions;
-  std::string LiteralArguments;
-  bool Optional;
+  std::vector<std::string> const Directories;
+  std::string const FilePermissions;
+  std::string const DirPermissions;
+  std::string const LiteralArguments;
+  bool const Optional;
 };
 
 #endif
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index cba68be..2c53a28 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -18,16 +18,16 @@
 #include "cmSystemTools.h"
 
 cmInstallExportGenerator::cmInstallExportGenerator(
-  cmExportSet* exportSet, const char* destination,
-  const char* file_permissions, std::vector<std::string> const& configurations,
-  const char* component, MessageLevel message, bool exclude_from_all,
-  const char* filename, const char* name_space, bool exportOld, bool android)
+  cmExportSet* exportSet, std::string const& destination,
+  std::string file_permissions, std::vector<std::string> const& configurations,
+  std::string const& component, MessageLevel message, bool exclude_from_all,
+  std::string filename, std::string name_space, bool exportOld, bool android)
   : cmInstallGenerator(destination, configurations, component, message,
                        exclude_from_all)
   , ExportSet(exportSet)
-  , FilePermissions(file_permissions)
-  , FileName(filename)
-  , Namespace(name_space)
+  , FilePermissions(std::move(file_permissions))
+  , FileName(std::move(filename))
+  , Namespace(std::move(name_space))
   , ExportOld(exportOld)
   , LocalGenerator(nullptr)
 {
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index f44127e..cf28b35 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -23,12 +23,12 @@
 class cmInstallExportGenerator : public cmInstallGenerator
 {
 public:
-  cmInstallExportGenerator(cmExportSet* exportSet, const char* dest,
-                           const char* file_permissions,
+  cmInstallExportGenerator(cmExportSet* exportSet, std::string const& dest,
+                           std::string file_permissions,
                            const std::vector<std::string>& configurations,
-                           const char* component, MessageLevel message,
-                           bool exclude_from_all, const char* filename,
-                           const char* name_space, bool exportOld,
+                           std::string const& component, MessageLevel message,
+                           bool exclude_from_all, std::string filename,
+                           std::string name_space, bool exportOld,
                            bool android);
   ~cmInstallExportGenerator() override;
 
@@ -52,11 +52,11 @@
   void ComputeTempDir();
   size_t GetMaxConfigLength() const;
 
-  cmExportSet* ExportSet;
-  std::string FilePermissions;
-  std::string FileName;
-  std::string Namespace;
-  bool ExportOld;
+  cmExportSet* const ExportSet;
+  std::string const FilePermissions;
+  std::string const FileName;
+  std::string const Namespace;
+  bool const ExportOld;
   cmLocalGenerator* LocalGenerator;
 
   std::string TempDir;
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index bfc7359..3c59f01 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -115,8 +115,8 @@
   }
 
   // Use a file install generator.
-  const char* no_permissions = "";
-  const char* no_rename = "";
+  const std::string no_permissions;
+  const std::string no_rename;
   bool no_exclude_from_all = false;
   std::string no_component =
     makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
@@ -124,8 +124,8 @@
   cmInstallGenerator::MessageLevel message =
     cmInstallGenerator::SelectMessageLevel(&makefile);
   makefile.AddInstallGenerator(cm::make_unique<cmInstallFilesGenerator>(
-    files, destination.c_str(), false, no_permissions, no_configurations,
-    no_component.c_str(), message, no_exclude_from_all, no_rename));
+    files, destination, false, no_permissions, no_configurations, no_component,
+    message, no_exclude_from_all, no_rename));
 }
 
 /**
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index f5b69a5..ad2f84e 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -2,6 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmInstallFilesGenerator.h"
 
+#include <utility>
+
 #include "cmGeneratorExpression.h"
 #include "cmInstallType.h"
 #include "cmStringAlgorithms.h"
@@ -9,16 +11,17 @@
 class cmLocalGenerator;
 
 cmInstallFilesGenerator::cmInstallFilesGenerator(
-  std::vector<std::string> const& files, const char* dest, bool programs,
-  const char* file_permissions, std::vector<std::string> const& configurations,
-  const char* component, MessageLevel message, bool exclude_from_all,
-  const char* rename, bool optional)
+  std::vector<std::string> const& files, std::string const& dest,
+  bool programs, std::string file_permissions,
+  std::vector<std::string> const& configurations, std::string const& component,
+  MessageLevel message, bool exclude_from_all, std::string rename,
+  bool optional)
   : cmInstallGenerator(dest, configurations, component, message,
                        exclude_from_all)
   , LocalGenerator(nullptr)
   , Files(files)
-  , FilePermissions(file_permissions)
-  , Rename(rename)
+  , FilePermissions(std::move(file_permissions))
+  , Rename(std::move(rename))
   , Programs(programs)
   , Optional(optional)
 {
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index a680037..8266603 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -21,11 +21,11 @@
 {
 public:
   cmInstallFilesGenerator(std::vector<std::string> const& files,
-                          const char* dest, bool programs,
-                          const char* file_permissions,
+                          std::string const& dest, bool programs,
+                          std::string file_permissions,
                           std::vector<std::string> const& configurations,
-                          const char* component, MessageLevel message,
-                          bool exclude_from_all, const char* rename,
+                          std::string const& component, MessageLevel message,
+                          bool exclude_from_all, std::string rename,
                           bool optional = false);
   ~cmInstallFilesGenerator() override;
 
@@ -42,11 +42,11 @@
                            std::vector<std::string> const& files);
 
   cmLocalGenerator* LocalGenerator;
-  std::vector<std::string> Files;
-  std::string FilePermissions;
-  std::string Rename;
-  bool Programs;
-  bool Optional;
+  std::vector<std::string> const Files;
+  std::string const FilePermissions;
+  std::string const Rename;
+  bool const Programs;
+  bool const Optional;
 };
 
 #endif
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index ec17361..0665895 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -3,16 +3,17 @@
 #include "cmInstallGenerator.h"
 
 #include <ostream>
+#include <utility>
 
 #include "cmMakefile.h"
 #include "cmSystemTools.h"
 
 cmInstallGenerator::cmInstallGenerator(
-  const char* destination, std::vector<std::string> const& configurations,
-  const char* component, MessageLevel message, bool exclude_from_all)
+  std::string destination, std::vector<std::string> const& configurations,
+  std::string component, MessageLevel message, bool exclude_from_all)
   : cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations)
-  , Destination(destination ? destination : "")
-  , Component(component ? component : "")
+  , Destination(std::move(destination))
+  , Component(std::move(component))
   , Message(message)
   , ExcludeFromAll(exclude_from_all)
 {
@@ -139,8 +140,8 @@
   os << ")\n";
 }
 
-std::string cmInstallGenerator::CreateComponentTest(const char* component,
-                                                    bool exclude_from_all)
+std::string cmInstallGenerator::CreateComponentTest(
+  const std::string& component, bool exclude_from_all)
 {
   std::string result = R"("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "x)";
   result += component;
@@ -158,7 +159,7 @@
 
   // Begin this block of installation.
   std::string component_test =
-    this->CreateComponentTest(this->Component.c_str(), this->ExcludeFromAll);
+    this->CreateComponentTest(this->Component, this->ExcludeFromAll);
   os << indent << "if(" << component_test << ")\n";
 
   // Generate the script possibly with per-configuration code.
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index 024027d..d786d24 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -30,9 +30,9 @@
     MessageNever
   };
 
-  cmInstallGenerator(const char* destination,
+  cmInstallGenerator(std::string destination,
                      std::vector<std::string> const& configurations,
-                     const char* component, MessageLevel message,
+                     std::string component, MessageLevel message,
                      bool exclude_from_all);
   ~cmInstallGenerator() override;
 
@@ -65,14 +65,14 @@
 protected:
   void GenerateScript(std::ostream& os) override;
 
-  std::string CreateComponentTest(const char* component,
+  std::string CreateComponentTest(const std::string& component,
                                   bool exclude_from_all);
 
   // Information shared by most generator types.
-  std::string Destination;
-  std::string Component;
-  MessageLevel Message;
-  bool ExcludeFromAll;
+  std::string const Destination;
+  std::string const Component;
+  MessageLevel const Message;
+  bool const ExcludeFromAll;
 };
 
 #endif
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index 2fd9bad..be07fd4 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -89,8 +89,8 @@
   }
 
   // Use a file install generator.
-  const char* no_permissions = "";
-  const char* no_rename = "";
+  const std::string no_permissions;
+  const std::string no_rename;
   bool no_exclude_from_all = false;
   std::string no_component =
     makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
@@ -98,8 +98,8 @@
   cmInstallGenerator::MessageLevel message =
     cmInstallGenerator::SelectMessageLevel(&makefile);
   makefile.AddInstallGenerator(cm::make_unique<cmInstallFilesGenerator>(
-    files, destination.c_str(), true, no_permissions, no_configurations,
-    no_component.c_str(), message, no_exclude_from_all, no_rename));
+    files, destination, true, no_permissions, no_configurations, no_component,
+    message, no_exclude_from_all, no_rename));
 }
 
 /**
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index ea29455..7cdf3b4 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -3,6 +3,7 @@
 #include "cmInstallScriptGenerator.h"
 
 #include <ostream>
+#include <utility>
 #include <vector>
 
 #include "cmGeneratorExpression.h"
@@ -11,13 +12,12 @@
 #include "cmPolicies.h"
 #include "cmScriptGenerator.h"
 
-cmInstallScriptGenerator::cmInstallScriptGenerator(const char* script,
-                                                   bool code,
-                                                   const char* component,
-                                                   bool exclude_from_all)
-  : cmInstallGenerator(nullptr, std::vector<std::string>(), component,
+cmInstallScriptGenerator::cmInstallScriptGenerator(
+  std::string script, bool code, std::string const& component,
+  bool exclude_from_all)
+  : cmInstallGenerator("", std::vector<std::string>(), component,
                        MessageDefault, exclude_from_all)
-  , Script(script)
+  , Script(std::move(script))
   , Code(code)
   , AllowGenex(false)
 {
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
index 7efa321..0a9c4ba 100644
--- a/Source/cmInstallScriptGenerator.h
+++ b/Source/cmInstallScriptGenerator.h
@@ -19,8 +19,9 @@
 class cmInstallScriptGenerator : public cmInstallGenerator
 {
 public:
-  cmInstallScriptGenerator(const char* script, bool code,
-                           const char* component, bool exclude_from_all);
+  cmInstallScriptGenerator(std::string script, bool code,
+                           std::string const& component,
+                           bool exclude_from_all);
   ~cmInstallScriptGenerator() override;
 
   bool Compute(cmLocalGenerator* lg) override;
@@ -32,8 +33,8 @@
   void AddScriptInstallRule(std::ostream& os, Indent indent,
                             std::string const& script);
 
-  std::string Script;
-  bool Code;
+  std::string const Script;
+  bool const Code;
   cmLocalGenerator* LocalGenerator;
   bool AllowGenex;
 };
diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx
index 5405b7c..12bc92b 100644
--- a/Source/cmInstallSubdirectoryGenerator.cxx
+++ b/Source/cmInstallSubdirectoryGenerator.cxx
@@ -4,6 +4,7 @@
 
 #include <memory>
 #include <sstream>
+#include <utility>
 #include <vector>
 
 #include "cmLocalGenerator.h"
@@ -13,11 +14,11 @@
 #include "cmSystemTools.h"
 
 cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator(
-  cmMakefile* makefile, const char* binaryDirectory, bool excludeFromAll)
-  : cmInstallGenerator(nullptr, std::vector<std::string>(), nullptr,
-                       MessageDefault, excludeFromAll)
+  cmMakefile* makefile, std::string binaryDirectory, bool excludeFromAll)
+  : cmInstallGenerator("", std::vector<std::string>(), "", MessageDefault,
+                       excludeFromAll)
   , Makefile(makefile)
-  , BinaryDirectory(binaryDirectory)
+  , BinaryDirectory(std::move(binaryDirectory))
 {
 }
 
diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h
index b99bdd5..f9cd0f1 100644
--- a/Source/cmInstallSubdirectoryGenerator.h
+++ b/Source/cmInstallSubdirectoryGenerator.h
@@ -20,7 +20,7 @@
 {
 public:
   cmInstallSubdirectoryGenerator(cmMakefile* makefile,
-                                 const char* binaryDirectory,
+                                 std::string binaryDirectory,
                                  bool excludeFromAll);
   ~cmInstallSubdirectoryGenerator() override;
 
@@ -33,8 +33,8 @@
 protected:
   void GenerateScript(std::ostream& os) override;
 
-  cmMakefile* Makefile;
-  std::string BinaryDirectory;
+  cmMakefile* const Makefile;
+  std::string const BinaryDirectory;
   cmLocalGenerator* LocalGenerator;
 };
 
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 69c9b7e..e05daa8 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -25,15 +25,15 @@
 #include "cmake.h"
 
 cmInstallTargetGenerator::cmInstallTargetGenerator(
-  std::string targetName, const char* dest, bool implib,
-  const char* file_permissions, std::vector<std::string> const& configurations,
-  const char* component, MessageLevel message, bool exclude_from_all,
+  std::string targetName, std::string const& dest, bool implib,
+  std::string file_permissions, std::vector<std::string> const& configurations,
+  std::string const& component, MessageLevel message, bool exclude_from_all,
   bool optional, cmListFileBacktrace backtrace)
   : cmInstallGenerator(dest, configurations, component, message,
                        exclude_from_all)
   , TargetName(std::move(targetName))
   , Target(nullptr)
-  , FilePermissions(file_permissions)
+  , FilePermissions(std::move(file_permissions))
   , ImportLibrary(implib)
   , Optional(optional)
   , Backtrace(std::move(backtrace))
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 8730454..e21001f 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -23,11 +23,11 @@
 {
 public:
   cmInstallTargetGenerator(
-    std::string targetName, const char* dest, bool implib,
-    const char* file_permissions,
-    std::vector<std::string> const& configurations, const char* component,
-    MessageLevel message, bool exclude_from_all, bool optional,
-    cmListFileBacktrace backtrace = cmListFileBacktrace());
+    std::string targetName, std::string const& dest, bool implib,
+    std::string file_permissions,
+    std::vector<std::string> const& configurations,
+    std::string const& component, MessageLevel message, bool exclude_from_all,
+    bool optional, cmListFileBacktrace backtrace = cmListFileBacktrace());
   ~cmInstallTargetGenerator() override;
 
   /** Select the policy for installing shared library linkable name
@@ -106,13 +106,13 @@
                                const std::string& toDestDirPath);
   void IssueCMP0095Warning(const std::string& unescapedRpath);
 
-  std::string TargetName;
+  std::string const TargetName;
   cmGeneratorTarget* Target;
-  std::string FilePermissions;
+  std::string const FilePermissions;
   NamelinkModeType NamelinkMode;
-  bool ImportLibrary;
-  bool Optional;
-  cmListFileBacktrace Backtrace;
+  bool const ImportLibrary;
+  bool const Optional;
+  cmListFileBacktrace const Backtrace;
 };
 
 #endif
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 18f82dd..d1a3454 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1171,7 +1171,7 @@
     }
 
     for (std::string const& i : impDirVec) {
-      if (implicitSet.insert(cmSystemTools::GetRealPath(i)).second) {
+      if (implicitSet.insert(this->GlobalGenerator->GetRealPath(i)).second) {
         implicitDirs.emplace_back(i);
       }
     }
@@ -1182,7 +1182,7 @@
                       &lang](std::string const& dir) {
     return (
       // Do not exclude directories that are not in an excluded set.
-      ((!cmContains(implicitSet, cmSystemTools::GetRealPath(dir))) &&
+      ((!cmContains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) &&
        (!cmContains(implicitExclude, dir)))
       // Do not exclude entries of the CPATH environment variable even though
       // they are implicitly searched by the compiler.  They are meant to be
@@ -2003,8 +2003,16 @@
 
   // Treat the name as relative to the source directory in which it
   // was given.
-  dep = cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentSource(), '/',
-                 inName);
+  dep = cmStrCat(this->GetCurrentSourceDirectory(), '/', inName);
+
+  // If the in-source path does not exist, assume it instead lives in the
+  // binary directory.
+  if (!cmSystemTools::FileExists(dep)) {
+    dep = cmStrCat(this->GetCurrentBinaryDirectory(), '/', inName);
+  }
+
+  dep = cmSystemTools::CollapseFullPath(dep, this->GetBinaryDirectory());
+
   return true;
 }
 
@@ -2413,163 +2421,170 @@
 
 void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
 {
-  // FIXME: Handle all configurations in multi-config generators.
-  std::string config;
-  if (!this->GetGlobalGenerator()->IsMultiConfig()) {
-    config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+  std::vector<std::string> configsList;
+  std::string configDefault = this->Makefile->GetConfigurations(configsList);
+  if (configsList.empty()) {
+    configsList.push_back(configDefault);
   }
-  const std::string buildType = cmSystemTools::UpperCase(config);
 
-  // FIXME: Refactor collection of sources to not evaluate object libraries.
-  std::vector<cmSourceFile*> sources;
-  target->GetSourceFiles(sources, buildType);
+  for (std::string const& config : configsList) {
+    const std::string buildType = cmSystemTools::UpperCase(config);
 
-  for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) {
-    auto langSources =
-      std::count_if(sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
-        return lang == sf->GetLanguage() &&
-          !sf->GetProperty("SKIP_PRECOMPILE_HEADERS");
-      });
-    if (langSources == 0) {
-      continue;
-    }
+    // FIXME: Refactor collection of sources to not evaluate object libraries.
+    std::vector<cmSourceFile*> sources;
+    target->GetSourceFiles(sources, buildType);
 
-    const std::string pchSource = target->GetPchSource(config, lang);
-    const std::string pchHeader = target->GetPchHeader(config, lang);
-
-    if (pchSource.empty() || pchHeader.empty()) {
-      continue;
-    }
-
-    const std::string pchExtension =
-      this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
-
-    if (pchExtension.empty()) {
-      continue;
-    }
-
-    const char* pchReuseFrom =
-      target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
-
-    auto pch_sf = this->Makefile->GetOrCreateSource(
-      pchSource, false, cmSourceFileLocationKind::Known);
-
-    if (!this->GetGlobalGenerator()->IsXcode()) {
-      if (!pchReuseFrom) {
-        target->AddSource(pchSource, true);
+    for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) {
+      auto langSources = std::count_if(
+        sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
+          return lang == sf->GetLanguage() &&
+            !sf->GetProperty("SKIP_PRECOMPILE_HEADERS");
+        });
+      if (langSources == 0) {
+        continue;
       }
 
-      const std::string pchFile = target->GetPchFile(config, lang);
+      const std::string pchSource = target->GetPchSource(config, lang);
+      const std::string pchHeader = target->GetPchHeader(config, lang);
 
-      // Exclude the pch files from linking
-      if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+      if (pchSource.empty() || pchHeader.empty()) {
+        continue;
+      }
+
+      const std::string pchExtension =
+        this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
+
+      if (pchExtension.empty()) {
+        continue;
+      }
+
+      const char* pchReuseFrom =
+        target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+
+      auto pch_sf = this->Makefile->GetOrCreateSource(
+        pchSource, false, cmSourceFileLocationKind::Known);
+
+      if (!this->GetGlobalGenerator()->IsXcode()) {
         if (!pchReuseFrom) {
-          pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
-        } else {
-          auto reuseTarget =
-            this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
-
-          if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
-
-            const std::string pdb_prefix =
-              this->GetGlobalGenerator()->IsMultiConfig()
-              ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
-              : "";
-
-            const std::string target_compile_pdb_dir = cmStrCat(
-              target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
-              target->GetName(), ".dir/");
-
-            const std::string copy_script =
-              cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
-            cmGeneratedFileStream file(copy_script);
-
-            file << "# CMake generated file\n";
-            for (auto extension : { ".pdb", ".idb" }) {
-              const std::string from_file = cmStrCat(
-                reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
-                "/", pchReuseFrom, ".dir/${PDB_PREFIX}", pchReuseFrom,
-                extension);
-
-              const std::string to_dir = cmStrCat(
-                target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
-                target->GetName(), ".dir/${PDB_PREFIX}");
-
-              const std::string to_file =
-                cmStrCat(to_dir, pchReuseFrom, extension);
-
-              std::string dest_file = to_file;
-
-              const std::string prefix = target->GetSafeProperty("PREFIX");
-              if (!prefix.empty()) {
-                dest_file = cmStrCat(to_dir, prefix, pchReuseFrom, extension);
-              }
-
-              file << "if (EXISTS \"" << from_file << "\" AND \"" << from_file
-                   << "\" IS_NEWER_THAN \"" << dest_file << "\")\n";
-              file << "  file(COPY \"" << from_file << "\""
-                   << " DESTINATION \"" << to_dir << "\")\n";
-              if (!prefix.empty()) {
-                file << "  file(REMOVE \"" << dest_file << "\")\n";
-                file << "  file(RENAME \"" << to_file << "\" \"" << dest_file
-                     << "\")\n";
-              }
-              file << "endif()\n";
-            }
-
-            cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
-              { cmSystemTools::GetCMakeCommand(),
-                cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P", copy_script });
-
-            const std::string no_main_dependency;
-            const std::vector<std::string> no_deps;
-            const char* no_message = "";
-            const char* no_current_dir = nullptr;
-            std::vector<std::string> no_byproducts;
-
-            std::vector<std::string> outputs;
-            outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
-                                       pchReuseFrom, ".pdb"));
-
-            if (this->GetGlobalGenerator()->IsMultiConfig()) {
-              this->AddCustomCommandToTarget(
-                target->GetName(), outputs, no_deps, commandLines,
-                cmCustomCommandType::PRE_BUILD, no_message, no_current_dir);
-            } else {
-              cmImplicitDependsList no_implicit_depends;
-              cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
-                outputs, no_byproducts, no_deps, no_main_dependency,
-                no_implicit_depends, commandLines, no_message, no_current_dir);
-
-              if (copy_rule) {
-                target->AddSource(copy_rule->ResolveFullPath());
-              }
-            }
-
-            target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
-                                        target_compile_pdb_dir);
-          }
-
-          std::string pchSourceObj =
-            reuseTarget->GetPchFileObject(config, lang);
-
-          // Link to the pch object file
-          target->Target->AppendProperty(
-            "LINK_FLAGS",
-            cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL)),
-            true);
+          target->AddSource(pchSource, true);
         }
-      } else {
-        pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
-      }
 
-      // Add pchHeader to source files, which will
-      // be grouped as "Precompile Header File"
-      auto pchHeader_sf = this->Makefile->GetOrCreateSource(
-        pchHeader, false, cmSourceFileLocationKind::Known);
-      std::string err;
-      pchHeader_sf->ResolveFullPath(&err);
-      target->AddSource(pchHeader);
+        const std::string pchFile = target->GetPchFile(config, lang);
+
+        // Exclude the pch files from linking
+        if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+          if (!pchReuseFrom) {
+            pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
+          } else {
+            auto reuseTarget =
+              this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
+
+            if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
+
+              const std::string pdb_prefix =
+                this->GetGlobalGenerator()->IsMultiConfig()
+                ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
+                : "";
+
+              const std::string target_compile_pdb_dir = cmStrCat(
+                target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+                target->GetName(), ".dir/");
+
+              const std::string copy_script =
+                cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
+              cmGeneratedFileStream file(copy_script);
+
+              file << "# CMake generated file\n";
+              for (auto extension : { ".pdb", ".idb" }) {
+                const std::string from_file =
+                  cmStrCat(reuseTarget->GetLocalGenerator()
+                             ->GetCurrentBinaryDirectory(),
+                           "/", pchReuseFrom, ".dir/${PDB_PREFIX}",
+                           pchReuseFrom, extension);
+
+                const std::string to_dir = cmStrCat(
+                  target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+                  "/", target->GetName(), ".dir/${PDB_PREFIX}");
+
+                const std::string to_file =
+                  cmStrCat(to_dir, pchReuseFrom, extension);
+
+                std::string dest_file = to_file;
+
+                const std::string prefix = target->GetSafeProperty("PREFIX");
+                if (!prefix.empty()) {
+                  dest_file =
+                    cmStrCat(to_dir, prefix, pchReuseFrom, extension);
+                }
+
+                file << "if (EXISTS \"" << from_file << "\" AND \""
+                     << from_file << "\" IS_NEWER_THAN \"" << dest_file
+                     << "\")\n";
+                file << "  file(COPY \"" << from_file << "\""
+                     << " DESTINATION \"" << to_dir << "\")\n";
+                if (!prefix.empty()) {
+                  file << "  file(REMOVE \"" << dest_file << "\")\n";
+                  file << "  file(RENAME \"" << to_file << "\" \"" << dest_file
+                       << "\")\n";
+                }
+                file << "endif()\n";
+              }
+
+              cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+                { cmSystemTools::GetCMakeCommand(),
+                  cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P", copy_script });
+
+              const std::string no_main_dependency;
+              const std::vector<std::string> no_deps;
+              const char* no_message = "";
+              const char* no_current_dir = nullptr;
+              std::vector<std::string> no_byproducts;
+
+              std::vector<std::string> outputs;
+              outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
+                                         pchReuseFrom, ".pdb"));
+
+              if (this->GetGlobalGenerator()->IsVisualStudio()) {
+                this->AddCustomCommandToTarget(
+                  target->GetName(), outputs, no_deps, commandLines,
+                  cmCustomCommandType::PRE_BUILD, no_message, no_current_dir);
+              } else {
+                cmImplicitDependsList no_implicit_depends;
+                cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
+                  outputs, no_byproducts, no_deps, no_main_dependency,
+                  no_implicit_depends, commandLines, no_message,
+                  no_current_dir);
+
+                if (copy_rule) {
+                  target->AddSource(copy_rule->ResolveFullPath());
+                }
+              }
+
+              target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+                                          target_compile_pdb_dir);
+            }
+
+            std::string pchSourceObj =
+              reuseTarget->GetPchFileObject(config, lang);
+
+            // Link to the pch object file
+            target->Target->AppendProperty(
+              "LINK_FLAGS",
+              cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL)),
+              true);
+          }
+        } else {
+          pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
+        }
+
+        // Add pchHeader to source files, which will
+        // be grouped as "Precompile Header File"
+        auto pchHeader_sf = this->Makefile->GetOrCreateSource(
+          pchHeader, false, cmSourceFileLocationKind::Known);
+        std::string err;
+        pchHeader_sf->ResolveFullPath(&err);
+        target->AddSource(pchHeader);
+      }
     }
   }
 }
@@ -2989,7 +3004,7 @@
 {
 public:
   cmInstallTargetGeneratorLocal(cmLocalGenerator* lg, std::string const& t,
-                                const char* dest, bool implib)
+                                std::string const& dest, bool implib)
     : cmInstallTargetGenerator(
         t, dest, implib, "", std::vector<std::string>(), "Unspecified",
         cmInstallGenerator::SelectMessageLevel(lg->GetMakefile()), false,
@@ -3013,7 +3028,7 @@
 
     // Include the user-specified pre-install script for this target.
     if (const char* preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
-      cmInstallScriptGenerator g(preinstall, false, nullptr, false);
+      cmInstallScriptGenerator g(preinstall, false, "", false);
       g.Generate(os, config, configurationTypes);
     }
 
@@ -3034,8 +3049,8 @@
         case cmStateEnums::STATIC_LIBRARY:
         case cmStateEnums::MODULE_LIBRARY: {
           // Use a target install generator.
-          cmInstallTargetGeneratorLocal g(this, l->GetName(),
-                                          destination.c_str(), false);
+          cmInstallTargetGeneratorLocal g(this, l->GetName(), destination,
+                                          false);
           g.Generate(os, config, configurationTypes);
         } break;
         case cmStateEnums::SHARED_LIBRARY: {
@@ -3043,19 +3058,19 @@
           // Special code to handle DLL.  Install the import library
           // to the normal destination and the DLL to the runtime
           // destination.
-          cmInstallTargetGeneratorLocal g1(this, l->GetName(),
-                                           destination.c_str(), true);
+          cmInstallTargetGeneratorLocal g1(this, l->GetName(), destination,
+                                           true);
           g1.Generate(os, config, configurationTypes);
           // We also skip over the leading slash given by the user.
           destination = l->Target->GetRuntimeInstallPath().substr(1);
           cmSystemTools::ConvertToUnixSlashes(destination);
-          cmInstallTargetGeneratorLocal g2(this, l->GetName(),
-                                           destination.c_str(), false);
+          cmInstallTargetGeneratorLocal g2(this, l->GetName(), destination,
+                                           false);
           g2.Generate(os, config, configurationTypes);
 #else
           // Use a target install generator.
-          cmInstallTargetGeneratorLocal g(this, l->GetName(),
-                                          destination.c_str(), false);
+          cmInstallTargetGeneratorLocal g(this, l->GetName(), destination,
+                                          false);
           g.Generate(os, config, configurationTypes);
 #endif
         } break;
@@ -3066,7 +3081,7 @@
 
     // Include the user-specified post-install script for this target.
     if (const char* postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
-      cmInstallScriptGenerator g(postinstall, false, nullptr, false);
+      cmInstallScriptGenerator g(postinstall, false, "", false);
       g.Generate(os, config, configurationTypes);
     }
   }
@@ -3276,7 +3291,8 @@
   // CMakeFiles/<target>.dir/CMakeFiles/<target>.dir/generated_source_file.obj
   const char* unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE");
   const char* pchExtension = source.GetProperty("PCH_EXTENSION");
-  if (unitySourceFile || pchExtension) {
+  const bool isPchObject = objectName.find("cmake_pch") != std::string::npos;
+  if (unitySourceFile || pchExtension || isPchObject) {
     if (pchExtension) {
       customOutputExtension = pchExtension;
     }
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 6967097..be1dd0d 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -64,7 +64,7 @@
 
   if (this->GetGlobalGenerator()->IsMultiConfig()) {
     for (auto const& config : this->GetConfigNames()) {
-      this->WriteProcessedMakefile(this->GetConfigFileStream(config));
+      this->WriteProcessedMakefile(this->GetImplFileStream(config));
     }
   }
   this->WriteProcessedMakefile(this->GetCommonFileStream());
@@ -154,10 +154,10 @@
 
 // Private methods.
 
-cmGeneratedFileStream& cmLocalNinjaGenerator::GetConfigFileStream(
+cmGeneratedFileStream& cmLocalNinjaGenerator::GetImplFileStream(
   const std::string& config) const
 {
-  return *this->GetGlobalNinjaGenerator()->GetConfigFileStream(config);
+  return *this->GetGlobalNinjaGenerator()->GetImplFileStream(config);
 }
 
 cmGeneratedFileStream& cmLocalNinjaGenerator::GetCommonFileStream() const
@@ -186,7 +186,7 @@
 
   if (this->GetGlobalGenerator()->IsMultiConfig()) {
     for (auto const& config : this->GetConfigNames()) {
-      auto& stream = this->GetConfigFileStream(config);
+      auto& stream = this->GetImplFileStream(config);
       this->WriteProjectHeader(stream);
       this->WriteNinjaRequiredVersion(stream);
       this->WriteNinjaConfigurationVariable(stream, config);
@@ -560,7 +560,7 @@
     build.Outputs = std::move(ninjaOutputs);
     build.ExplicitDeps = std::move(ninjaDeps);
     build.OrderOnlyDeps = orderOnlyDeps;
-    gg->WriteBuild(this->GetConfigFileStream(config), build);
+    gg->WriteBuild(this->GetImplFileStream(config), build);
   } else {
     std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
     // Hash full path to make unique.
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 0445879..ef160e7 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -86,7 +86,7 @@
     bool forceFullPaths = false) override;
 
 private:
-  cmGeneratedFileStream& GetConfigFileStream(const std::string& config) const;
+  cmGeneratedFileStream& GetImplFileStream(const std::string& config) const;
   cmGeneratedFileStream& GetCommonFileStream() const;
   cmGeneratedFileStream& GetRulesFileStream() const;
 
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 55a9a72..1a6b7b2 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -146,7 +146,7 @@
   // out of date.
   std::string stampName =
     cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles");
-  cmSystemTools::MakeDirectory(stampName.c_str());
+  cmSystemTools::MakeDirectory(stampName);
   stampName += "/generate.stamp";
   cmsys::ofstream stamp(stampName.c_str());
   stamp << "# CMake generation timestamp file for this directory.\n";
@@ -257,12 +257,11 @@
                               "--check-stamp-file", stampName });
   std::string comment = cmStrCat("Building Custom Rule ", makefileIn);
   const char* no_working_directory = nullptr;
-  std::string fullpathStampName =
-    cmSystemTools::CollapseFullPath(stampName.c_str());
+  std::string fullpathStampName = cmSystemTools::CollapseFullPath(stampName);
   this->AddCustomCommandToOutput(fullpathStampName, listFiles, makefileIn,
                                  commandLines, comment.c_str(),
                                  no_working_directory, true, false);
-  if (cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str())) {
+  if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
     // Finalize the source file path now since we're adding this after
     // the generator validated all project-named sources.
     file->ResolveFullPath();
@@ -279,7 +278,7 @@
 {
   fout << "\t<Configurations>\n";
   for (std::string const& config : configs) {
-    this->WriteConfiguration(fout, config.c_str(), libName, target);
+    this->WriteConfiguration(fout, config, libName, target);
   }
   fout << "\t</Configurations>\n";
 }
@@ -580,7 +579,7 @@
       this->Stream << this->LG->EscapeForXML("\n");
     }
     std::string script = this->LG->ConstructScript(ccg);
-    this->Stream << this->LG->EscapeForXML(script.c_str());
+    this->Stream << this->LG->EscapeForXML(script);
   }
 
 private:
@@ -733,13 +732,13 @@
       : target->GetDirectory(configName);
     /* clang-format off */
     fout << "\t\t\tOutputDirectory=\""
-         << this->ConvertToXMLOutputPathSingle(outDir.c_str()) << "\"\n";
+         << this->ConvertToXMLOutputPathSingle(outDir) << "\"\n";
     /* clang-format on */
   }
 
   /* clang-format off */
   fout << "\t\t\tIntermediateDirectory=\""
-       << this->ConvertToXMLOutputPath(intermediateDir.c_str())
+       << this->ConvertToXMLOutputPath(intermediateDir)
        << "\"\n"
        << "\t\t\tConfigurationType=\"" << configType << "\"\n"
        << "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"
@@ -788,8 +787,7 @@
     } else {
       modDir = ".";
     }
-    fout << "\t\t\t\tModulePath=\""
-         << this->ConvertToXMLOutputPath(modDir.c_str())
+    fout << "\t\t\t\tModulePath=\"" << this->ConvertToXMLOutputPath(modDir)
          << "\\$(ConfigurationName)\"\n";
   }
   targetOptions.OutputAdditionalIncludeDirectories(
@@ -802,7 +800,7 @@
     std::string pdb = target->GetCompilePDBPath(configName);
     if (!pdb.empty()) {
       fout << "\t\t\t\tProgramDataBaseFileName=\""
-           << this->ConvertToXMLOutputPathSingle(pdb.c_str()) << "\"\n";
+           << this->ConvertToXMLOutputPathSingle(pdb) << "\"\n";
     }
   }
   fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
@@ -879,7 +877,7 @@
       fout << "\n\t\t\t\tAdditionalManifestFiles=\"";
       for (cmSourceFile const* manifest : manifest_srcs) {
         std::string m = manifest->GetFullPath();
-        fout << this->ConvertToXMLOutputPath(m.c_str()) << ";";
+        fout << this->ConvertToXMLOutputPath(m) << ";";
       }
       fout << "\"";
     }
@@ -946,7 +944,7 @@
   }
   std::string configTypeUpper = cmSystemTools::UpperCase(configName);
   std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper);
-  targetLinkFlags = target->GetProperty(linkFlagsConfig.c_str());
+  targetLinkFlags = target->GetProperty(linkFlagsConfig);
   if (targetLinkFlags) {
     extraLinkOptions += " ";
     extraLinkOptions += targetLinkFlags;
@@ -985,7 +983,7 @@
       fout << "\t\t\t<Tool\n"
            << "\t\t\t\tName=\"" << tool << "\"\n";
       fout << "\t\t\t\tOutputFile=\""
-           << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
+           << this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";
       break;
     }
     case cmStateEnums::STATIC_LIBRARY: {
@@ -1015,7 +1013,7 @@
         fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
       }
       fout << "\t\t\t\tOutputFile=\""
-           << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
+           << this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";
       break;
     }
     case cmStateEnums::SHARED_LIBRARY:
@@ -1057,7 +1055,7 @@
       temp =
         cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
       fout << "\t\t\t\tOutputFile=\""
-           << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+           << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
       this->WriteTargetVersionAttribute(fout, target);
       linkOptions.OutputFlagMap(fout, 4);
       fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
@@ -1066,7 +1064,7 @@
       temp =
         cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
       fout << "\t\t\t\tProgramDatabaseFile=\""
-           << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+           << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
       if (targetOptions.IsDebug()) {
         fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
       }
@@ -1078,7 +1076,7 @@
         }
       }
       std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
-      const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
+      const char* stackVal = this->Makefile->GetDefinition(stackVar);
       if (stackVal) {
         fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n";
       }
@@ -1086,7 +1084,7 @@
         target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact),
         '/', targetNames.ImportLibrary);
       fout << "\t\t\t\tImportLibrary=\""
-           << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"";
+           << this->ConvertToXMLOutputPathSingle(temp) << "\"";
       if (this->FortranProject) {
         fout << "\n\t\t\t\tLinkDLL=\"true\"";
       }
@@ -1132,14 +1130,14 @@
       temp =
         cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
       fout << "\t\t\t\tOutputFile=\""
-           << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+           << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
       this->WriteTargetVersionAttribute(fout, target);
       linkOptions.OutputFlagMap(fout, 4);
       fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
       this->OutputLibraryDirectories(fout, cli.GetDirectories());
       fout << "\"\n";
       std::string path = this->ConvertToXMLOutputPathSingle(
-        target->GetPDBDirectory(configName).c_str());
+        target->GetPDBDirectory(configName));
       fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/"
            << targetNames.PDB << "\"\n";
       if (targetOptions.IsDebug()) {
@@ -1167,7 +1165,7 @@
              << "\"\n";
       }
       std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
-      const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
+      const char* stackVal = this->Makefile->GetDefinition(stackVar);
       if (stackVal) {
         fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
       }
@@ -1175,7 +1173,7 @@
         target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact),
         '/', targetNames.ImportLibrary);
       fout << "\t\t\t\tImportLibrary=\""
-           << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
+           << this->ConvertToXMLOutputPathSingle(temp) << "\"/>\n";
       break;
     }
     case cmStateEnums::UTILITY:
@@ -1256,8 +1254,8 @@
   for (auto const& lib : libs) {
     if (lib.IsPath) {
       std::string rel =
-        lg->MaybeConvertToRelativePath(currentBinDir, lib.Value.c_str());
-      fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
+        lg->MaybeConvertToRelativePath(currentBinDir, lib.Value);
+      fout << lg->ConvertToXMLOutputPath(rel) << " ";
     } else if (!lib.Target ||
                lib.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
       fout << lib.Value << " ";
@@ -1282,7 +1280,7 @@
     if (!obj->GetObjectLibrary().empty()) {
       std::string const& objFile = obj->GetFullPath();
       std::string rel = lg->MaybeConvertToRelativePath(currentBinDir, objFile);
-      fout << sep << lg->ConvertToXMLOutputPath(rel.c_str());
+      fout << sep << lg->ConvertToXMLOutputPath(rel);
       sep = " ";
     }
   }
@@ -1303,9 +1301,8 @@
     }
 
     // Switch to a relative path specification if it is shorter.
-    if (cmSystemTools::FileIsFullPath(dir.c_str())) {
-      std::string rel =
-        this->MaybeConvertToRelativePath(currentBinDir, dir.c_str());
+    if (cmSystemTools::FileIsFullPath(dir)) {
+      std::string rel = this->MaybeConvertToRelativePath(currentBinDir, dir);
       if (rel.size() < dir.size()) {
         dir = rel;
       }
@@ -1314,9 +1311,8 @@
     // First search a configuration-specific subdirectory and then the
     // original directory.
     fout << comma
-         << this->ConvertToXMLOutputPath(
-              (dir + "/$(ConfigurationName)").c_str())
-         << "," << this->ConvertToXMLOutputPath(dir.c_str());
+         << this->ConvertToXMLOutputPath(dir + "/$(ConfigurationName)") << ","
+         << this->ConvertToXMLOutputPath(dir);
     comma = ",";
   }
 }
@@ -1518,13 +1514,13 @@
       for (std::vector<std::string>::iterator j = depends.begin();
            j != depends.end(); ++j) {
         fc.AdditionalDeps += sep;
-        fc.AdditionalDeps += lg->ConvertToXMLOutputPath(j->c_str());
+        fc.AdditionalDeps += lg->ConvertToXMLOutputPath(*j);
         sep = ";";
         needfc = true;
       }
     }
 
-    const std::string& linkLanguage = gt->GetLinkerLanguage(config.c_str());
+    const std::string& linkLanguage = gt->GetLinkerLanguage(config);
     // If HEADER_FILE_ONLY is set, we must suppress this generation in
     // the project file
     fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
@@ -1629,7 +1625,7 @@
       FCInfo fcinfo(this, target, acs, configs);
 
       fout << "\t\t\t<File\n";
-      std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
+      std::string d = this->ConvertToXMLOutputPathSingle(source);
       // Tell MS-Dev what the source is.  If the compiler knows how to
       // build it, then it will.
       fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
@@ -1759,21 +1755,21 @@
       fout << "\t\t\t\t\t<Tool\n"
            << "\t\t\t\t\tName=\"" << compileTool << "\"\n"
            << "\t\t\t\t\tAdditionalOptions=\""
-           << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
+           << this->EscapeForXML(fc.CompileFlags) << "\"/>\n";
     }
 
     std::string comment = this->ConstructComment(ccg);
     std::string script = this->ConstructScript(ccg);
     if (this->FortranProject) {
-      cmSystemTools::ReplaceString(script, "$(Configuration)", config.c_str());
+      cmSystemTools::ReplaceString(script, "$(Configuration)", config);
     }
     /* clang-format off */
     fout << "\t\t\t\t\t<Tool\n"
          << "\t\t\t\t\tName=\"" << customTool << "\"\n"
          << "\t\t\t\t\tDescription=\""
-         << this->EscapeForXML(comment.c_str()) << "\"\n"
+         << this->EscapeForXML(comment) << "\"\n"
          << "\t\t\t\t\tCommandLine=\""
-         << this->EscapeForXML(script.c_str()) << "\"\n"
+         << this->EscapeForXML(script) << "\"\n"
          << "\t\t\t\t\tAdditionalDependencies=\"";
     /* clang-format on */
     if (ccg.GetDepends().empty()) {
@@ -1789,8 +1785,8 @@
       for (std::string const& d : ccg.GetDepends()) {
         // Get the real name of the dependency in case it is a CMake target.
         std::string dep;
-        if (this->GetRealDependency(d.c_str(), config.c_str(), dep)) {
-          fout << this->ConvertToXMLOutputPath(dep.c_str()) << ";";
+        if (this->GetRealDependency(d, config, dep)) {
+          fout << this->ConvertToXMLOutputPath(dep) << ";";
         }
       }
     }
@@ -1802,7 +1798,7 @@
       // Write a rule for the output generated by this command.
       const char* sep = "";
       for (std::string const& output : ccg.GetOutputs()) {
-        fout << sep << this->ConvertToXMLOutputPathSingle(output.c_str());
+        fout << sep << this->ConvertToXMLOutputPathSingle(output);
         sep = ";";
       }
     }
@@ -1948,7 +1944,7 @@
   this->WriteProjectSCC(fout, target);
   /* clang-format off */
   fout<< "\tKeyword=\"" << keyword << "\">\n"
-       << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\">\n"
+       << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n"
        << "\t<Platforms>\n"
        << "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
        << "\t</Platforms>\n";
@@ -1983,7 +1979,7 @@
     keyword = "Win32Proj";
   }
   fout << "\tName=\"" << projLabel << "\"\n";
-  fout << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\"\n";
+  fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
   this->WriteProjectSCC(fout, target);
   if (const char* targetFrameworkVersion =
         target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION")) {
@@ -2037,7 +2033,7 @@
 }
 
 std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPath(
-  const char* path)
+  const std::string& path)
 {
   std::string ret =
     this->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
@@ -2049,7 +2045,7 @@
 }
 
 std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPathSingle(
-  const char* path)
+  const std::string& path)
 {
   std::string ret =
     this->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
@@ -2130,8 +2126,7 @@
   std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE");
   // save the GUID in the cache
   this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry(
-    guidStoreName.c_str(), parser.GUID.c_str(), "Stored GUID",
-    cmStateEnums::INTERNAL);
+    guidStoreName, parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL);
 }
 
 std::string cmLocalVisualStudio7Generator::GetTargetDirectory(
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 22a5f9a..745766c 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -101,8 +101,8 @@
   void WriteConfiguration(std::ostream& fout, const std::string& configName,
                           const std::string& libName, cmGeneratorTarget* tgt);
   std::string EscapeForXML(const std::string& s);
-  std::string ConvertToXMLOutputPath(const char* path);
-  std::string ConvertToXMLOutputPathSingle(const char* path);
+  std::string ConvertToXMLOutputPath(const std::string& path);
+  std::string ConvertToXMLOutputPathSingle(const std::string& path);
   void OutputTargetRules(std::ostream& fout, const std::string& configName,
                          cmGeneratorTarget* target,
                          const std::string& libName);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index dc741d3..59995be 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -340,6 +340,9 @@
       for (std::string const& arg : args) {
         val["args"].append(arg);
       }
+      val["time"] = cmSystemTools::GetTime();
+      val["frame"] =
+        static_cast<std::uint64_t>(this->ExecutionStatusStack.size());
       msg << Json::writeString(builder, val);
 #endif
       break;
@@ -1748,7 +1751,7 @@
   }
 
   this->AddInstallGenerator(cm::make_unique<cmInstallSubdirectoryGenerator>(
-    subMf, binPath.c_str(), excludeFromAll));
+    subMf, binPath, excludeFromAll));
 }
 
 const std::string& cmMakefile::GetCurrentSourceDirectory() const
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 77b6bc2..714d01e 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -4,10 +4,10 @@
 
 #include <cassert>
 #include <cstdio>
-#include <memory>
 #include <sstream>
 #include <utility>
 
+#include <cm/memory>
 #include <cmext/algorithm>
 
 #include "cmComputeLinkInformation.h"
@@ -38,12 +38,7 @@
 
 cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
   : cmCommonTargetGenerator(target)
-  , OSXBundleGenerator(nullptr)
-  , MacOSXContentGenerator(nullptr)
 {
-  this->BuildFileStream = nullptr;
-  this->InfoFileStream = nullptr;
-  this->FlagFileStream = nullptr;
   this->CustomCommandDriver = OnBuild;
   this->LocalGenerator =
     static_cast<cmLocalUnixMakefileGenerator3*>(target->GetLocalGenerator());
@@ -55,31 +50,28 @@
         cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) {
     this->NoRuleMessages = cmIsOff(ruleStatus);
   }
-  MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
+  MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this);
 }
 
-cmMakefileTargetGenerator::~cmMakefileTargetGenerator()
-{
-  delete MacOSXContentGenerator;
-}
+cmMakefileTargetGenerator::~cmMakefileTargetGenerator() = default;
 
-cmMakefileTargetGenerator* cmMakefileTargetGenerator::New(
+std::unique_ptr<cmMakefileTargetGenerator> cmMakefileTargetGenerator::New(
   cmGeneratorTarget* tgt)
 {
-  cmMakefileTargetGenerator* result = nullptr;
+  std::unique_ptr<cmMakefileTargetGenerator> result;
 
   switch (tgt->GetType()) {
     case cmStateEnums::EXECUTABLE:
-      result = new cmMakefileExecutableTargetGenerator(tgt);
+      result = cm::make_unique<cmMakefileExecutableTargetGenerator>(tgt);
       break;
     case cmStateEnums::STATIC_LIBRARY:
     case cmStateEnums::SHARED_LIBRARY:
     case cmStateEnums::MODULE_LIBRARY:
     case cmStateEnums::OBJECT_LIBRARY:
-      result = new cmMakefileLibraryTargetGenerator(tgt);
+      result = cm::make_unique<cmMakefileLibraryTargetGenerator>(tgt);
       break;
     case cmStateEnums::UTILITY:
-      result = new cmMakefileUtilityTargetGenerator(tgt);
+      result = cm::make_unique<cmMakefileUtilityTargetGenerator>(tgt);
       break;
     default:
       return result;
@@ -139,9 +131,9 @@
 
   // Open the rule file.  This should be copy-if-different because the
   // rules may depend on this file itself.
-  this->BuildFileStream =
-    new cmGeneratedFileStream(this->BuildFileNameFull, false,
-                              this->GlobalGenerator->GetMakefileEncoding());
+  this->BuildFileStream = cm::make_unique<cmGeneratedFileStream>(
+    this->BuildFileNameFull, false,
+    this->GlobalGenerator->GetMakefileEncoding());
   if (!this->BuildFileStream) {
     return;
   }
@@ -247,11 +239,11 @@
   this->GeneratorTarget->GetHeaderSources(headerSources,
                                           this->GetConfigName());
   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
-    headerSources, this->MacOSXContentGenerator, this->GetConfigName());
+    headerSources, this->MacOSXContentGenerator.get(), this->GetConfigName());
   std::vector<cmSourceFile const*> extraSources;
   this->GeneratorTarget->GetExtraSources(extraSources, this->GetConfigName());
   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
-    extraSources, this->MacOSXContentGenerator, this->GetConfigName());
+    extraSources, this->MacOSXContentGenerator.get(), this->GetConfigName());
   const char* pchExtension =
     this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
   std::vector<cmSourceFile const*> externalObjects;
@@ -316,9 +308,9 @@
   // rules may depend on this file itself.
   this->FlagFileNameFull =
     cmStrCat(this->TargetBuildDirectoryFull, "/flags.make");
-  this->FlagFileStream =
-    new cmGeneratedFileStream(this->FlagFileNameFull, false,
-                              this->GlobalGenerator->GetMakefileEncoding());
+  this->FlagFileStream = cm::make_unique<cmGeneratedFileStream>(
+    this->FlagFileNameFull, false,
+    this->GlobalGenerator->GetMakefileEncoding());
   if (!this->FlagFileStream) {
     return;
   }
@@ -1057,7 +1049,8 @@
   this->InfoFileNameFull = cmStrCat(dir, "/DependInfo.cmake");
   this->InfoFileNameFull =
     this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull);
-  this->InfoFileStream = new cmGeneratedFileStream(this->InfoFileNameFull);
+  this->InfoFileStream =
+    cm::make_unique<cmGeneratedFileStream>(this->InfoFileNameFull);
   if (!this->InfoFileStream) {
     return;
   }
@@ -1524,9 +1517,9 @@
 
 void cmMakefileTargetGenerator::CloseFileStreams()
 {
-  delete this->BuildFileStream;
-  delete this->InfoFileStream;
-  delete this->FlagFileStream;
+  this->BuildFileStream.reset();
+  this->InfoFileStream.reset();
+  this->FlagFileStream.reset();
 }
 
 void cmMakefileTargetGenerator::CreateLinkScript(
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index fd62933..ec6b314 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -34,10 +34,15 @@
 public:
   // constructor to set the ivars
   cmMakefileTargetGenerator(cmGeneratorTarget* target);
+  cmMakefileTargetGenerator(const cmMakefileTargetGenerator&) = delete;
   ~cmMakefileTargetGenerator() override;
 
+  cmMakefileTargetGenerator& operator=(const cmMakefileTargetGenerator&) =
+    delete;
+
   // construct using this factory call
-  static cmMakefileTargetGenerator* New(cmGeneratorTarget* tgt);
+  static std::unique_ptr<cmMakefileTargetGenerator> New(
+    cmGeneratorTarget* tgt);
 
   /* the main entry point for this class. Writes the Makefiles associated
      with this target */
@@ -195,11 +200,11 @@
   std::string TargetBuildDirectoryFull;
 
   // the stream for the build file
-  cmGeneratedFileStream* BuildFileStream;
+  std::unique_ptr<cmGeneratedFileStream> BuildFileStream;
 
   // the stream for the flag file
   std::string FlagFileNameFull;
-  cmGeneratedFileStream* FlagFileStream;
+  std::unique_ptr<cmGeneratedFileStream> FlagFileStream;
   class StringList : public std::vector<std::string>
   {
   };
@@ -207,7 +212,7 @@
 
   // the stream for the info file
   std::string InfoFileNameFull;
-  cmGeneratedFileStream* InfoFileStream;
+  std::unique_ptr<cmGeneratedFileStream> InfoFileStream;
 
   // files to clean
   std::set<std::string> CleanFiles;
@@ -236,7 +241,7 @@
   // macOS content info.
   std::set<std::string> MacContentFolders;
   std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator;
-  MacOSXContentGeneratorType* MacOSXContentGenerator;
+  std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
 };
 
 #endif
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index ca46e14..45043fa 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -4,8 +4,11 @@
 
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPolicies.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
 
@@ -28,14 +31,63 @@
     }
     i = 1;
   }
+
+  cmMakefile& mf = status.GetMakefile();
+  cmState* state = mf.GetState();
+
   for (; i < args.size(); ++i) {
     std::string const& variable = args[i];
-    cmState* state = status.GetMakefile().GetState();
-    if (!state->GetCacheEntryValue(variable)) {
-      status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
-        variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
-      overwrite = true;
+
+    bool issueMessage = false;
+    bool oldBehavior = false;
+    bool ignoreVariable = false;
+    switch (mf.GetPolicyStatus(cmPolicies::CMP0102)) {
+      case cmPolicies::WARN:
+        if (mf.PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0102")) {
+          if (!state->GetCacheEntryValue(variable)) {
+            issueMessage = true;
+          }
+        }
+        CM_FALLTHROUGH;
+      case cmPolicies::OLD:
+        oldBehavior = true;
+        break;
+      case cmPolicies::NEW:
+      case cmPolicies::REQUIRED_IF_USED:
+      case cmPolicies::REQUIRED_ALWAYS:
+        if (!state->GetCacheEntryValue(variable)) {
+          ignoreVariable = true;
+        }
+        break;
     }
+
+    // First see if we should issue a message about CMP0102
+    if (issueMessage) {
+      std::string err = cmStrCat(
+        "Policy CMP0102 is not set: The variable named \"", variable,
+        "\" is not in the cache. This results in an empty cache entry which "
+        "is no longer created when policy CMP0102 is set to NEW. Run \"cmake "
+        "--help-policy CMP0102\" for policy details. Use the cmake_policy "
+        "command to set the policy and suppress this warning.");
+      mf.IssueMessage(MessageType::AUTHOR_WARNING, err);
+    }
+
+    // If it's not in the cache and we're using the new behavior, nothing to
+    // see here.
+    if (ignoreVariable) {
+      continue;
+    }
+
+    // Check if we want the old behavior of making a dummy cache entry.
+    if (oldBehavior) {
+      if (!state->GetCacheEntryValue(variable)) {
+        status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
+          variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
+        overwrite = true;
+      }
+    }
+
+    // We need a cache entry to do this.
     if (!state->GetCacheEntryValue(variable)) {
       cmSystemTools::Error("This should never happen...");
       return false;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index f853ac5..a871a92 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -811,9 +811,9 @@
   }
 
   // Write comments.
-  cmGlobalNinjaGenerator::WriteDivider(this->GetConfigFileStream(fileConfig));
+  cmGlobalNinjaGenerator::WriteDivider(this->GetImplFileStream(fileConfig));
   const cmStateEnums::TargetType targetType = gt->GetType();
-  this->GetConfigFileStream(fileConfig)
+  this->GetImplFileStream(fileConfig)
     << "# Link build statements for " << cmState::GetTargetTypeName(targetType)
     << " target " << this->GetTargetName() << "\n\n";
 
@@ -1183,7 +1183,7 @@
 
   // Write the build statement for this target.
   bool usedResponseFile = false;
-  globalGen->WriteBuild(this->GetConfigFileStream(fileConfig), linkBuild,
+  globalGen->WriteBuild(this->GetImplFileStream(fileConfig), linkBuild,
                         commandLineLengthLimit, &usedResponseFile);
   this->WriteLinkRule(usedResponseFile, config);
 
@@ -1197,7 +1197,7 @@
       }
       build.ExplicitDeps.push_back(targetOutputReal);
       build.Variables = std::move(symlinkVars);
-      globalGen->WriteBuild(this->GetConfigFileStream(fileConfig), build);
+      globalGen->WriteBuild(this->GetImplFileStream(fileConfig), build);
     } else {
       cmNinjaBuild build("CMAKE_SYMLINK_LIBRARY");
       build.Comment = "Create library symlink " + targetOutput;
@@ -1223,7 +1223,7 @@
       build.ExplicitDeps.push_back(targetOutputReal);
       build.Variables = std::move(symlinkVars);
 
-      globalGen->WriteBuild(this->GetConfigFileStream(fileConfig), build);
+      globalGen->WriteBuild(this->GetImplFileStream(fileConfig), build);
     }
   }
 
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 5a8c144..455d809 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -68,10 +68,10 @@
 
 cmNinjaTargetGenerator::~cmNinjaTargetGenerator() = default;
 
-cmGeneratedFileStream& cmNinjaTargetGenerator::GetConfigFileStream(
+cmGeneratedFileStream& cmNinjaTargetGenerator::GetImplFileStream(
   const std::string& config) const
 {
-  return *this->GetGlobalGenerator()->GetConfigFileStream(config);
+  return *this->GetGlobalGenerator()->GetImplFileStream(config);
 }
 
 cmGeneratedFileStream& cmNinjaTargetGenerator::GetCommonFileStream() const
@@ -815,8 +815,8 @@
   bool firstForConfig)
 {
   // Write comments.
-  cmGlobalNinjaGenerator::WriteDivider(this->GetConfigFileStream(fileConfig));
-  this->GetConfigFileStream(fileConfig)
+  cmGlobalNinjaGenerator::WriteDivider(this->GetImplFileStream(fileConfig));
+  this->GetImplFileStream(fileConfig)
     << "# Object build statements for "
     << cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
     << " target " << this->GetTargetName() << "\n\n";
@@ -901,8 +901,8 @@
       orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir));
     }
 
-    this->GetGlobalGenerator()->WriteBuild(
-      this->GetConfigFileStream(fileConfig), build);
+    this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+                                           build);
   }
 
   {
@@ -935,11 +935,11 @@
       this->GeneratorTarget, build.OrderOnlyDeps, config, fileConfig,
       DependOnTargetArtifact);
 
-    this->GetGlobalGenerator()->WriteBuild(
-      this->GetConfigFileStream(fileConfig), build);
+    this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+                                           build);
   }
 
-  this->GetConfigFileStream(fileConfig) << "\n";
+  this->GetImplFileStream(fileConfig) << "\n";
 
   if (!this->Configs[config].SwiftOutputMap.empty()) {
     std::string const mapFilePath =
@@ -1177,8 +1177,8 @@
     this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
                                ppBuild.Variables);
 
-    this->GetGlobalGenerator()->WriteBuild(
-      this->GetConfigFileStream(fileConfig), ppBuild, commandLineLengthLimit);
+    this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+                                           ppBuild, commandLineLengthLimit);
   }
   if (needDyndep) {
     std::string const dyndep = this->GetDyndepFilePath(language, config);
@@ -1210,8 +1210,8 @@
   if (language == "Swift") {
     this->EmitSwiftDependencyInfo(source, config);
   } else {
-    this->GetGlobalGenerator()->WriteBuild(
-      this->GetConfigFileStream(fileConfig), objBuild, commandLineLengthLimit);
+    this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+                                           objBuild, commandLineLengthLimit);
   }
 
   if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
@@ -1221,8 +1221,8 @@
     std::transform(build.Outputs.begin(), build.Outputs.end(),
                    build.Outputs.begin(), MapToNinjaPath());
     build.ExplicitDeps = objBuild.Outputs;
-    this->GetGlobalGenerator()->WriteBuild(
-      this->GetConfigFileStream(fileConfig), build);
+    this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+                                           build);
   }
 }
 
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 22dd7b8..bca12b1 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -47,7 +47,7 @@
 protected:
   bool SetMsvcTargetPdbVariable(cmNinjaVars&, const std::string& config) const;
 
-  cmGeneratedFileStream& GetConfigFileStream(const std::string& config) const;
+  cmGeneratedFileStream& GetImplFileStream(const std::string& config) const;
   cmGeneratedFileStream& GetCommonFileStream() const;
   cmGeneratedFileStream& GetRulesFileStream() const;
 
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 0cddb12..a42d65d 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -164,6 +164,6 @@
     cmNinjaBuild phonyAlias("phony");
     gg->AppendTargetOutputs(genTarget, phonyAlias.Outputs, "");
     phonyAlias.ExplicitDeps = phonyBuild.Outputs;
-    gg->WriteBuild(this->GetConfigFileStream(config), phonyAlias);
+    gg->WriteBuild(this->GetImplFileStream(config), phonyAlias);
   }
 }
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index eef41c0..1366ff0 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -302,7 +302,10 @@
          17, 0, cmPolicies::WARN)                                             \
   SELECT(POLICY, CMP0101,                                                     \
          "target_compile_options honors BEFORE keyword in all scopes.", 3,    \
-         17, 0, cmPolicies::WARN)
+         17, 0, cmPolicies::WARN)                                             \
+  SELECT(POLICY, CMP0102,                                                     \
+         "mark_as_advanced() does nothing if a cache entry does not exist.",  \
+         3, 17, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 2edff25..ebb522b 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1219,7 +1219,10 @@
     // Register info file as generated by CMake
     this->Makefile->AddCMakeOutputFile(qrc.InfoFile);
     // Register file at target
-    this->AddGeneratedSource(qrc.OutputFile, this->Rcc);
+    {
+      cmSourceFile* sf = this->AddGeneratedSource(qrc.OutputFile, this->Rcc);
+      sf->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "On");
+    }
 
     std::vector<std::string> ccOutput;
     ccOutput.push_back(qrc.OutputFile);
@@ -1514,27 +1517,30 @@
   return true;
 }
 
-void cmQtAutoGenInitializer::RegisterGeneratedSource(
+cmSourceFile* cmQtAutoGenInitializer::RegisterGeneratedSource(
   std::string const& filename)
 {
   cmSourceFile* gFile = this->Makefile->GetOrCreateSource(filename, true);
   gFile->SetProperty("GENERATED", "1");
   gFile->SetProperty("SKIP_AUTOGEN", "1");
+  return gFile;
 }
 
-bool cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename,
-                                                GenVarsT const& genVars,
-                                                bool prepend)
+cmSourceFile* cmQtAutoGenInitializer::AddGeneratedSource(
+  std::string const& filename, GenVarsT const& genVars, bool prepend)
 {
   // Register source at makefile
-  this->RegisterGeneratedSource(filename);
+  cmSourceFile* gFile = this->RegisterGeneratedSource(filename);
   // Add source file to target
   this->GenTarget->AddSource(filename, prepend);
+
   // Add source file to source group
-  return this->AddToSourceGroup(filename, genVars.GenNameUpper);
+  this->AddToSourceGroup(filename, genVars.GenNameUpper);
+
+  return gFile;
 }
 
-bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
+void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
                                               cm::string_view genNameUpper)
 {
   cmSourceGroup* sourceGroup = nullptr;
@@ -1565,14 +1571,12 @@
           cmStrCat(genNameUpper, " error in ", property,
                    ": Could not find or create the source group ",
                    cmQtAutoGen::Quoted(groupName)));
-        return false;
       }
     }
   }
   if (sourceGroup != nullptr) {
     sourceGroup->AddGroupFile(fileName);
   }
-  return true;
 }
 
 void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 847e4e5..8cedf14 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -129,10 +129,11 @@
   bool SetupWriteAutogenInfo();
   bool SetupWriteRccInfo();
 
-  void RegisterGeneratedSource(std::string const& filename);
-  bool AddGeneratedSource(std::string const& filename, GenVarsT const& genVars,
-                          bool prepend = false);
-  bool AddToSourceGroup(std::string const& fileName,
+  cmSourceFile* RegisterGeneratedSource(std::string const& filename);
+  cmSourceFile* AddGeneratedSource(std::string const& filename,
+                                   GenVarsT const& genVars,
+                                   bool prepend = false);
+  void AddToSourceGroup(std::string const& fileName,
                         cm::string_view genNameUpper);
   void AddCleanFile(std::string const& fileName);
 
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
index c8bb1ab..7d676c9 100644
--- a/Source/cmScriptGenerator.h
+++ b/Source/cmScriptGenerator.h
@@ -71,7 +71,7 @@
 
   std::string CreateConfigTest(const std::string& config);
   std::string CreateConfigTest(std::vector<std::string> const& configs);
-  std::string CreateComponentTest(const char* component);
+  std::string CreateComponentTest(const std::string& component);
 
   // Information shared by most generator types.
   std::string RuntimeConfigVariable;
diff --git a/Tests/CMakeTests/FileDownloadTest.cmake.in b/Tests/CMakeTests/FileDownloadTest.cmake.in
index 5bd3803..76c0000 100644
--- a/Tests/CMakeTests/FileDownloadTest.cmake.in
+++ b/Tests/CMakeTests/FileDownloadTest.cmake.in
@@ -138,9 +138,9 @@
 
 message(STATUS "FileDownload:11")
 file(DOWNLOAD
-  badhostname.png
+  badhostname.invalid
   ${dir}/file11.png
-  TIMEOUT ${timeout}
+  TIMEOUT 30
   STATUS status
   )
 message(STATUS "${status}")
diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt
index 70e8476..196fea3 100644
--- a/Tests/CustomCommand/CMakeLists.txt
+++ b/Tests/CustomCommand/CMakeLists.txt
@@ -535,6 +535,7 @@
 add_custom_target(command_expand_lists ALL DEPENDS "${gen_file}")
 set_property(TARGET command_expand_lists PROPERTY CMPARGS "${cmp_args}")
 
+# This also tests that `./` is squeezed out of the resulting path.
 set(depends_path "./depended_upon_path.txt")
 
 add_custom_command(
@@ -549,3 +550,19 @@
 )
 
 add_custom_target(depends_on_path ALL DEPENDS "depends_on_path.txt")
+
+add_custom_command(
+  OUTPUT "depends_on_in_source_path.txt"
+  COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/main.cxx" depends_on_in_source_path.txt
+  DEPENDS main.cxx
+)
+
+add_custom_target(depends_on_in_source_path ALL DEPENDS "depends_on_in_source_path.txt")
+
+add_custom_command(
+  OUTPUT "depends_on_in_rel_source_path.txt"
+  COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/main.cxx" depends_on_in_rel_source_path.txt
+  DEPENDS ./main.cxx
+)
+
+add_custom_target(depends_on_in_rel_source_path ALL DEPENDS "depends_on_in_rel_source_path.txt")
diff --git a/Tests/RunCMake/CMP0102/CMP0102-Common.cmake b/Tests/RunCMake/CMP0102/CMP0102-Common.cmake
new file mode 100644
index 0000000..61fdad6
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-Common.cmake
@@ -0,0 +1,2 @@
+
+mark_as_advanced(CMP0102_TEST_VARIABLE)
diff --git a/Tests/RunCMake/CMP0102/CMP0102-NEW.cmake b/Tests/RunCMake/CMP0102/CMP0102-NEW.cmake
new file mode 100644
index 0000000..bdf769f
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-NEW.cmake
@@ -0,0 +1,13 @@
+
+cmake_policy(SET CMP0102 NEW)
+
+include (CMP0102-Common.cmake)
+get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
+  PROPERTY TYPE SET)
+if (is_type_set)
+  get_property(type CACHE CMP0102_TEST_VARIABLE
+    PROPERTY TYPE)
+  message(FATAL_ERROR
+    "There is a cache entry for an undefined variable after "
+    "`mark_as_advanced`.")
+endif ()
diff --git a/Tests/RunCMake/CMP0102/CMP0102-OLD.cmake b/Tests/RunCMake/CMP0102/CMP0102-OLD.cmake
new file mode 100644
index 0000000..5c20dd3
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-OLD.cmake
@@ -0,0 +1,18 @@
+
+cmake_policy(SET CMP0102 OLD)
+
+include (CMP0102-Common.cmake)
+get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
+  PROPERTY TYPE SET)
+if (NOT is_type_set)
+  message(FATAL_ERROR
+    "There is a cache entry for an undefined variable after "
+    "`mark_as_advanced`.")
+endif ()
+get_property(type CACHE CMP0102_TEST_VARIABLE
+  PROPERTY TYPE)
+if (NOT type STREQUAL "UNINITIALIZED")
+  message(FATAL_ERROR
+    "The cache type for CMP0102_TEST_VARIABLE is not "
+    "UNINITIALIZED")
+endif ()
diff --git a/Tests/RunCMake/CMP0102/CMP0102-WARN-Default.cmake b/Tests/RunCMake/CMP0102/CMP0102-WARN-Default.cmake
new file mode 100644
index 0000000..d6ebe4d
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-WARN-Default.cmake
@@ -0,0 +1,16 @@
+
+include (CMP0102-Common.cmake)
+get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
+  PROPERTY TYPE SET)
+if (NOT is_type_set)
+  message(FATAL_ERROR
+    "There is a cache entry for an undefined variable after "
+    "`mark_as_advanced`.")
+endif ()
+get_property(type CACHE CMP0102_TEST_VARIABLE
+  PROPERTY TYPE)
+if (NOT type STREQUAL "UNINITIALIZED")
+  message(FATAL_ERROR
+    "The cache type for CMP0102_TEST_VARIABLE is not "
+    "UNINITIALIZED")
+endif ()
diff --git a/Tests/RunCMake/CMP0102/CMP0102-WARN-stderr.txt b/Tests/RunCMake/CMP0102/CMP0102-WARN-stderr.txt
new file mode 100644
index 0000000..bb56ec2
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-WARN-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0102-Common.cmake:2 \(mark_as_advanced\):
+  Policy CMP0102 is not set: The variable named "CMP0102_TEST_VARIABLE" is
+  not in the cache.  This results in an empty cache entry which is no longer
+  created when policy CMP0102 is set to NEW.  Run "cmake --help-policy
+  CMP0102" for policy details.  Use the cmake_policy command to set the
+  policy and suppress this warning.
+Call Stack \(most recent call first\):
+  CMP0102-WARN.cmake:4 \(include\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0102/CMP0102-WARN.cmake b/Tests/RunCMake/CMP0102/CMP0102-WARN.cmake
new file mode 100644
index 0000000..e9a45f1
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-WARN.cmake
@@ -0,0 +1,18 @@
+
+set(CMAKE_POLICY_WARNING_CMP0102 1)
+
+include (CMP0102-Common.cmake)
+get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
+  PROPERTY TYPE SET)
+if (NOT is_type_set)
+  message(FATAL_ERROR
+    "There is a cache entry for an undefined variable after "
+    "`mark_as_advanced`.")
+endif ()
+get_property(type CACHE CMP0102_TEST_VARIABLE
+  PROPERTY TYPE)
+if (NOT type STREQUAL "UNINITIALIZED")
+  message(FATAL_ERROR
+    "The cache type for CMP0102_TEST_VARIABLE is not "
+    "UNINITIALIZED")
+endif ()
diff --git a/Tests/RunCMake/CMP0102/CMakeLists.txt b/Tests/RunCMake/CMP0102/CMakeLists.txt
new file mode 100644
index 0000000..ef2163c
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/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/CMP0102/RunCMakeTest.cmake b/Tests/RunCMake/CMP0102/RunCMakeTest.cmake
new file mode 100644
index 0000000..9b5df74
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(CMP0102-OLD)
+run_cmake(CMP0102-NEW)
+run_cmake(CMP0102-WARN)
+run_cmake(CMP0102-WARN-Default)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index d302fe3..cd6e9ae 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -115,6 +115,7 @@
 endif()
 add_RunCMake_test(CMP0069)
 add_RunCMake_test(CMP0081)
+add_RunCMake_test(CMP0102)
 
 # The test for Policy 65 requires the use of the
 # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
diff --git a/Tests/RunCMake/CommandLine/trace-json-v1-check.py b/Tests/RunCMake/CommandLine/trace-json-v1-check.py
index 14febaf..e617b76 100755
--- a/Tests/RunCMake/CommandLine/trace-json-v1-check.py
+++ b/Tests/RunCMake/CommandLine/trace-json-v1-check.py
@@ -46,6 +46,7 @@
     {
         'args': msg_args,
         'cmd': 'message',
+        'frame': 3 if expand else 2
     },
 ]
 
@@ -59,14 +60,17 @@
 
     for i in fp.readlines():
         line = json.loads(i)
-        assert sorted(line.keys()) == ['args', 'cmd', 'file', 'line']
+        assert sorted(line.keys()) == ['args', 'cmd', 'file', 'frame', 'line', 'time']
         assert isinstance(line['args'], list)
         assert isinstance(line['cmd'], unicode)
         assert isinstance(line['file'], unicode)
+        assert isinstance(line['frame'], int)
         assert isinstance(line['line'], int)
+        assert isinstance(line['time'], float)
 
         for j in required_traces:
-            if j['cmd'] == line['cmd'] and j['args'] == line['args']:
-                j['found'] = True
+            # Compare the subset of required keys with line
+            if {k: line[k] for k in j} == j:
+                required_traces.remove(j)
 
-assert all([x.get('found', False) == True for x in required_traces])
+assert not required_traces
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatch.cmake b/Tests/RunCMake/FPHSA/FindNameMismatch.cmake
new file mode 100644
index 0000000..540aa67
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatch.cmake
@@ -0,0 +1,4 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NAMEMISMATCH REQUIRED_VARS "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatchOld.cmake b/Tests/RunCMake/FPHSA/FindNameMismatchOld.cmake
new file mode 100644
index 0000000..d155ea7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatchOld.cmake
@@ -0,0 +1,4 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NAMEMISMATCH "old signature" "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatchSuppressed.cmake b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressed.cmake
new file mode 100644
index 0000000..042a59a
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressed.cmake
@@ -0,0 +1,6 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+set(FPHSA_NAME_MISMATCHED 1)
+find_package_handle_standard_args(NAMEMISMATCH "old signature" "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+unset(FPHSA_NAME_MISMATCHED)
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedArg.cmake b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedArg.cmake
new file mode 100644
index 0000000..6a0e964
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedArg.cmake
@@ -0,0 +1,4 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NAMEMISMATCH NAME_MISMATCHED REQUIRED_VARS "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedCompat.cmake b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedCompat.cmake
new file mode 100644
index 0000000..791cfee
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedCompat.cmake
@@ -0,0 +1,6 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+set(FPHSA_NAME_MISMATCHED 1)
+find_package_handle_standard_args(NAMEMISMATCH REQUIRED_VARS "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+unset(FPHSA_NAME_MISMATCHED)
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt b/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
new file mode 100644
index 0000000..722b50b
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
@@ -0,0 +1,23 @@
+CMake Warning \(dev\) at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\):
+  The package name passed to `find_package_handle_standard_args`
+  \(NAMEMISMATCH\) does not match the name of the calling package
+  \(NameMismatch\).  This can lead to problems in calling code that expects
+  `find_package` result variables \(e.g., `_FOUND`\) to follow a certain
+  pattern.
+Call Stack \(most recent call first\):
+  FindNameMismatch.cmake:3 \(find_package_handle_standard_args\)
+  NameMismatch.cmake:3 \(find_package\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\):
+  The package name passed to `find_package_handle_standard_args`
+  \(NAMEMISMATCH\) does not match the name of the calling package
+  \(NameMismatchOld\).  This can lead to problems in calling code that expects
+  `find_package` result variables \(e.g., `_FOUND`\) to follow a certain
+  pattern.
+Call Stack \(most recent call first\):
+  FindNameMismatchOld.cmake:3 \(find_package_handle_standard_args\)
+  NameMismatch.cmake:4 \(find_package\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/FPHSA/NameMismatch.cmake b/Tests/RunCMake/FPHSA/NameMismatch.cmake
new file mode 100644
index 0000000..9ca3cc6
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/NameMismatch.cmake
@@ -0,0 +1,7 @@
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
+
+find_package(NameMismatch REQUIRED)
+find_package(NameMismatchOld REQUIRED)
+find_package(NameMismatchSuppressed REQUIRED)
+find_package(NameMismatchSuppressedCompat REQUIRED)
+find_package(NameMismatchSuppressedArg REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
index f3e6c3e..286915d 100644
--- a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
@@ -1,6 +1,7 @@
 include(RunCMake)
 
 run_cmake(BadFoundVar)
+run_cmake(NameMismatch)
 
 # The pseudo module will "find" a package with the given version. Check if the
 # version selection code in FPHSA works correctly.
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index f3208ed..7d32b27 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -103,6 +103,18 @@
 execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
 file(TOUCH "${RunCMake_TEST_BINARY_DIR}/empty.cmake")
 run_ninja(Simple reconfigure-noconfig build.ninja simpleexe)
+run_ninja(Simple default-build-file-clean build.ninja clean)
+run_ninja(Simple default-build-file-clean-minsizerel build.ninja clean:MinSizeRel)
+run_ninja(Simple default-build-file-all build.ninja all)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAlias-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE=Release;-DCMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS=all;-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
+run_cmake_configure(SimpleDefaultBuildAlias)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_ninja(SimpleDefaultBuildAlias target build.ninja simpleexe)
+run_ninja(SimpleDefaultBuildAlias all build.ninja all)
+run_ninja(SimpleDefaultBuildAlias clean build.ninja clean)
 
 set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleNoCross-build)
 run_cmake_configure(SimpleNoCross)
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-all-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-all-ninja-check.cmake
new file mode 100644
index 0000000..4e6e654
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-all-ninja-check.cmake
@@ -0,0 +1,49 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${GENERATED_FILES}
+
+    ${TARGET_FILE_simpleexe_Debug}
+    ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+    ${TARGET_FILE_simpleshared_Debug}
+    ${TARGET_LINKER_FILE_simpleshared_Debug}
+    ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+    ${TARGET_FILE_simplestatic_Debug}
+    ${TARGET_LINKER_FILE_simplestatic_Debug}
+    ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+    ${TARGET_FILE_simpleexe_Release}
+    ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+    ${TARGET_FILE_simpleshared_Release}
+    ${TARGET_LINKER_FILE_simpleshared_Release}
+    ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+    ${TARGET_FILE_simplestatic_Release}
+    ${TARGET_LINKER_FILE_simplestatic_Release}
+    ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+    ${TARGET_FILE_simpleexe_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+    ${TARGET_FILE_simpleshared_RelWithDebInfo}
+    ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+    ${TARGET_FILE_simplestatic_RelWithDebInfo}
+    ${TARGET_LINKER_FILE_simplestatic_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+
+    ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+  EXCLUDE
+    ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+  )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-minsizerel-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-minsizerel-ninja-check.cmake
new file mode 100644
index 0000000..c09ae65
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-minsizerel-ninja-check.cmake
@@ -0,0 +1,41 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${GENERATED_FILES}
+
+    ${TARGET_FILE_simpleexe_Debug}
+    ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+    ${TARGET_FILE_simpleshared_Debug}
+    ${TARGET_LINKER_FILE_simpleshared_Debug}
+    ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+    ${TARGET_FILE_simplestatic_Debug}
+    ${TARGET_LINKER_FILE_simplestatic_Debug}
+    ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+    ${TARGET_FILE_simpleexe_Release}
+    ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+    ${TARGET_FILE_simpleshared_Release}
+    ${TARGET_LINKER_FILE_simpleshared_Release}
+    ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+    ${TARGET_FILE_simplestatic_Release}
+    ${TARGET_LINKER_FILE_simplestatic_Release}
+    ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+  EXCLUDE
+    ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+    ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+  )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-ninja-check.cmake
new file mode 100644
index 0000000..43213dd
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-ninja-check.cmake
@@ -0,0 +1,49 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${GENERATED_FILES}
+
+    ${TARGET_FILE_simpleexe_Debug}
+    ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+    ${TARGET_FILE_simpleshared_Debug}
+    ${TARGET_LINKER_FILE_simpleshared_Debug}
+    ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+    ${TARGET_FILE_simplestatic_Debug}
+    ${TARGET_LINKER_FILE_simplestatic_Debug}
+    ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+    ${TARGET_FILE_simpleexe_Release}
+    ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+    ${TARGET_FILE_simpleshared_Release}
+    ${TARGET_LINKER_FILE_simpleshared_Release}
+    ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+    ${TARGET_FILE_simplestatic_Release}
+    ${TARGET_LINKER_FILE_simplestatic_Release}
+    ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+    ${TARGET_FILE_simpleexe_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+    ${TARGET_FILE_simpleshared_MinSizeRel}
+    ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+    ${TARGET_FILE_simplestatic_MinSizeRel}
+    ${TARGET_LINKER_FILE_simplestatic_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+    ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+  EXCLUDE
+    ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+  )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-all-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-all-ninja-check.cmake
new file mode 100644
index 0000000..c171e3d
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-all-ninja-check.cmake
@@ -0,0 +1,56 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${GENERATED_FILES}
+
+    ${TARGET_FILE_simpleexe_Debug}
+    ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+    ${TARGET_FILE_simpleshared_Debug}
+    ${TARGET_LINKER_FILE_simpleshared_Debug}
+    ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+    ${TARGET_FILE_simplestatic_Debug}
+    ${TARGET_LINKER_FILE_simplestatic_Debug}
+    ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+    ${TARGET_FILE_simpleexe_Release}
+    ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+    ${TARGET_FILE_simpleshared_Release}
+    ${TARGET_LINKER_FILE_simpleshared_Release}
+    ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+    ${TARGET_FILE_simplestatic_Release}
+    ${TARGET_LINKER_FILE_simplestatic_Release}
+    ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+    ${TARGET_FILE_simpleexe_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+    ${TARGET_FILE_simpleshared_MinSizeRel}
+    ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+    ${TARGET_FILE_simplestatic_MinSizeRel}
+    ${TARGET_LINKER_FILE_simplestatic_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+    ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+    ${TARGET_FILE_simpleexe_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+    ${TARGET_FILE_simpleshared_RelWithDebInfo}
+    ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+    ${TARGET_FILE_simplestatic_RelWithDebInfo}
+    ${TARGET_LINKER_FILE_simplestatic_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+
+    ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+  )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-clean-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-clean-ninja-check.cmake
new file mode 100644
index 0000000..0f919df
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-clean-ninja-check.cmake
@@ -0,0 +1,25 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${GENERATED_FILES}
+
+  EXCLUDE
+    ${TARGET_OBJECT_FILES_simpleexe_Debug}
+    ${TARGET_OBJECT_FILES_simpleshared_Debug}
+    ${TARGET_OBJECT_FILES_simplestatic_Debug}
+    ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+    ${TARGET_OBJECT_FILES_simpleexe_Release}
+    ${TARGET_OBJECT_FILES_simpleshared_Release}
+    ${TARGET_OBJECT_FILES_simplestatic_Release}
+    ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+    ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+    ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+  )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-target-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-target-ninja-check.cmake
new file mode 100644
index 0000000..de4505c
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-target-ninja-check.cmake
@@ -0,0 +1,49 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${GENERATED_FILES}
+
+    ${TARGET_FILE_simpleexe_Debug}
+    ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+    ${TARGET_FILE_simpleshared_Debug}
+    ${TARGET_LINKER_FILE_simpleshared_Debug}
+    ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+    ${TARGET_FILE_simpleexe_Release}
+    ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+    ${TARGET_FILE_simpleshared_Release}
+    ${TARGET_LINKER_FILE_simpleshared_Release}
+    ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+    ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+    ${TARGET_FILE_simpleexe_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+    ${TARGET_FILE_simpleshared_MinSizeRel}
+    ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+    ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+    ${TARGET_FILE_simpleexe_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+    ${TARGET_FILE_simpleshared_RelWithDebInfo}
+    ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+    ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+  EXCLUDE
+    ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+    ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+    ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+    ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+  )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias.cmake
new file mode 100644
index 0000000..2a5b708
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/Simple.cmake")
diff --git a/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake b/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
index 494bcf7..cc719be 100644
--- a/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
@@ -1,4 +1,7 @@
 set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/cmake_pch.h")
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/Debug/cmake_pch.h")
+endif()
 set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
 
 if (NOT EXISTS ${foo_pch_header})
diff --git a/Tests/RunCMake/PrecompileHeaders/PchDebugGenex-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchDebugGenex-check.cmake
new file mode 100644
index 0000000..cb94ee5
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchDebugGenex-check.cmake
@@ -0,0 +1,17 @@
+if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  return()
+endif()
+
+set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/Debug/cmake_pch.h")
+
+if (NOT EXISTS ${foo_pch_header})
+  set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} does not exist")
+  return()
+endif()
+
+file(STRINGS ${foo_pch_header} foo_pch_header_strings)
+
+if (NOT foo_pch_header_strings MATCHES ";#include \"[^\"]*PrecompileHeaders/include/foo.h\";#include <stdio.h>(;|$)")
+  set(RunCMake_TEST_FAILED "Generated foo pch header\n  ${foo_pch_header}\nhas bad content:\n  ${foo_pch_header_strings}")
+  return()
+endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/PchDebugGenex.cmake b/Tests/RunCMake/PrecompileHeaders/PchDebugGenex.cmake
new file mode 100644
index 0000000..854689f
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchDebugGenex.cmake
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.15)
+project(PchDebugGenex C)
+
+add_library(foo foo.c)
+target_include_directories(foo PUBLIC include)
+target_precompile_headers(foo PUBLIC
+  "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/include/foo.h>"
+  <stdio.h>
+)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
index 4e62b81..28c6ba4 100644
--- a/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
@@ -1,5 +1,9 @@
 set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/cmake_pch.h")
 set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/Debug/cmake_pch.h")
+  set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/Debug/cmake_pch.h")
+endif()
 
 if (NOT EXISTS ${foo_pch_header})
   set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} does not exist")
diff --git a/Tests/RunCMake/PrecompileHeaders/PchMultilanguage-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchMultilanguage-check.cmake
index cc01ecb..1696037 100644
--- a/Tests/RunCMake/PrecompileHeaders/PchMultilanguage-check.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/PchMultilanguage-check.cmake
@@ -1,5 +1,9 @@
 set(foobar_pch_h_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
 set(foobar_pch_hxx_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.hxx")
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(foobar_pch_h_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/Debug/cmake_pch.h")
+  set(foobar_pch_hxx_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/Debug/cmake_pch.hxx")
+endif()
 
 if (NOT EXISTS ${foobar_pch_h_header})
   set(RunCMake_TEST_FAILED "Generated foobar C pch header ${foobar_pch_h_header} does not exist")
diff --git a/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake
index 9018664..f1504a7 100644
--- a/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake
@@ -1,4 +1,7 @@
 set(main_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/main.dir/cmake_pch.hxx")
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(main_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/main.dir/Debug/cmake_pch.hxx")
+endif()
 
 file(STRINGS ${main_pch_header} main_pch_header_strings)
 string(REGEX MATCH "#pragma warning\\(push, 0\\).*#include.*pch.h.*#pragma warning\\(pop\\)" matched_code ${main_pch_header_strings})
diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
index 8d2f4f9..f587c7d 100644
--- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
@@ -13,6 +13,7 @@
 endfunction()
 
 run_cmake(DisabledPch)
+run_cmake(PchDebugGenex)
 run_test(PchInterface)
 run_cmake(PchPrologueEpilogue)
 run_test(SkipPrecompileHeaders)
diff --git a/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake b/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
index 91cea0e..9c214f1 100644
--- a/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
@@ -1,4 +1,4 @@
-set(pch_header "CMakeFiles/tgt.dir/cmake_pch.hxx")
+set(pch_header "CMakeFiles/tgt.dir/Debug/cmake_pch.hxx")
 set(pch_source [=[CMakeFiles\\tgt.dir\\cmake_pch.cxx]=])
 
 if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${pch_header}")
diff --git a/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake b/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake
index aa3eafc..4e85db6 100644
--- a/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake
@@ -1,4 +1,4 @@
-set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.hxx")
+set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Debug/cmake_pch.hxx")
 
 if(NOT EXISTS "${pch_header}")
   set(RunCMake_TEST_FAILED "Generated PCH header ${pch_header} does not exist.")
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2-stderr.txt
index 94f0f46..50fa81f 100644
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2-stderr.txt
+++ b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2-stderr.txt
@@ -13,6 +13,11 @@
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
 
 CMake Error at file-GET_RUNTIME_DEPENDENCIES-badargs2\.cmake:[0-9]+ \(file\):
-  file Keyword missing value: BUNDLE_EXECUTABLE
+  file Keywords missing values:
+
+    RESOLVED_DEPENDENCIES_VAR
+    UNRESOLVED_DEPENDENCIES_VAR
+    CONFLICTING_DEPENDENCIES_PREFIX
+    BUNDLE_EXECUTABLE
 Call Stack \(most recent call first\):
   CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2.cmake b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2.cmake
index 138ab95..ac6af85 100644
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2.cmake
+++ b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2.cmake
@@ -1,2 +1,15 @@
-file(GET_RUNTIME_DEPENDENCIES BUNDLE_EXECUTABLE)
+file(GET_RUNTIME_DEPENDENCIES
+  RESOLVED_DEPENDENCIES_VAR
+  UNRESOLVED_DEPENDENCIES_VAR
+  CONFLICTING_DEPENDENCIES_PREFIX
+  BUNDLE_EXECUTABLE
+  EXECUTABLES
+  LIBRARIES
+  MODULES
+  DIRECTORIES
+  PRE_INCLUDE_REGEXES
+  PRE_EXCLUDE_REGEXES
+  POST_INCLUDE_REGEXES
+  POST_EXCLUDE_REGEXES
+  )
 message(FATAL_ERROR "This message should not be displayed")
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index 60c8316..26a9aa9 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -281,7 +281,6 @@
   ENDIF(USE_BZIP2_DLL)
 ENDIF(BZIP2_FOUND)
 MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR)
-MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARIES)
 
 
 #
diff --git a/Utilities/std/cm/type_traits b/Utilities/std/cm/type_traits
index 4dfe17b..e32c2c6 100644
--- a/Utilities/std/cm/type_traits
+++ b/Utilities/std/cm/type_traits
@@ -33,6 +33,8 @@
 using std::invoke_result;
 using std::invoke_result_t;
 
+using std::void_t;
+
 #else
 
 // Helper classes
@@ -46,6 +48,14 @@
 template <class F, typename... ArgTypes>
 using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;
 
+template <typename... ArgTypes>
+struct make_void
+{
+  typedef void type;
+};
+template <typename... ArgTypes>
+using void_t = typename make_void<ArgTypes...>::type;
+
 #endif
 
 } // namespace cm
diff --git a/Utilities/std/cmext/memory b/Utilities/std/cmext/memory
index 540a3de..50e79df 100644
--- a/Utilities/std/cmext/memory
+++ b/Utilities/std/cmext/memory
@@ -6,6 +6,8 @@
 #ifndef cmext_memory
 #define cmext_memory
 
+#include <typeinfo>
+
 #include <cm/type_traits>
 
 namespace cm {
@@ -24,7 +26,13 @@
             int> = 0>
 T& dynamic_reference_cast(O& item)
 {
-  return *(dynamic_cast<T*>(item.get()));
+  auto p = dynamic_cast<T*>(item.get());
+
+  if (p == nullptr) {
+    throw std::bad_cast();
+  }
+
+  return *p;
 }
 
 } // namespace cm
diff --git a/Utilities/std/cmext/type_traits b/Utilities/std/cmext/type_traits
new file mode 100644
index 0000000..da6550d
--- /dev/null
+++ b/Utilities/std/cmext/type_traits
@@ -0,0 +1,68 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmext_type_traits
+#define cmext_type_traits
+
+#include <cm/type_traits>
+
+namespace cm {
+
+// type traits for managed pointer types
+template <typename>
+struct is_unique_ptr : std::false_type
+{
+};
+template <typename T>
+struct is_unique_ptr<std::unique_ptr<T>> : std::true_type
+{
+};
+
+// type traits for containers
+template <typename, typename = void_t<>>
+struct is_container : std::false_type
+{
+};
+template <typename T>
+struct is_container<
+  T,
+  cm::void_t<typename T::value_type, typename T::size_type,
+             typename T::difference_type, typename T::iterator>>
+  : std::true_type
+{
+};
+
+template <typename, typename = void_t<>>
+struct is_associative_container : std::false_type
+{
+};
+template <typename T>
+struct is_associative_container<
+  T, cm::void_t<typename T::key_type, typename T::key_compare>>
+  : cm::is_container<T>
+{
+};
+
+template <typename, typename = void_t<>>
+struct is_unordered_associative_container : std::false_type
+{
+};
+template <typename T>
+struct is_unordered_associative_container<
+  T,
+  cm::void_t<typename T::key_type, typename T::hasher, typename T::key_equal,
+             typename T::local_iterator>> : cm::is_container<T>
+{
+};
+
+template <typename T>
+using is_sequence_container =
+  cm::bool_constant<cm::is_container<T>::value &&
+                    !cm::is_associative_container<T>::value &&
+                    !cm::is_unordered_associative_container<T>::value>;
+
+} // namespace cm
+
+#endif