Merge branch 'release-3.18'
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
index 9ec9e8f..476a1c6 100644
--- a/CTestConfig.cmake
+++ b/CTestConfig.cmake
@@ -6,7 +6,9 @@
 set(CTEST_PROJECT_NAME "CMake")
 set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
 
-set(CTEST_DROP_METHOD "http")
+if(NOT CTEST_DROP_METHOD STREQUAL "https")
+  set(CTEST_DROP_METHOD "http")
+endif()
 set(CTEST_DROP_SITE "open.cdash.org")
 set(CTEST_DROP_LOCATION "/submit.php?project=CMake")
 set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Help/cpack_gen/external.rst b/Help/cpack_gen/external.rst
index 406f6be..7ef1071 100644
--- a/Help/cpack_gen/external.rst
+++ b/Help/cpack_gen/external.rst
@@ -281,3 +281,10 @@
   It is invoked after (optional) staging took place and may
   run an external packaging tool. The script has access to
   the variables defined by the CPack config file.
+
+.. variable:: CPACK_EXTERNAL_BUILT_PACKAGES
+
+  The ``CPACK_EXTERNAL_PACKAGE_SCRIPT`` script may set this list variable to the
+  full paths of generated package files.  CPack copy these files from the stage
+  directory back to the top build directory and possibly produce checksum files
+  if the :variable:`CPACK_PACKAGE_CHECKSUM` is set.
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index a1c1a6f..9b6774b 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -299,3 +299,28 @@
   before staging or merging.
 
 .. _`CMake Discourse Forum Development Category`: https://discourse.cmake.org/c/development
+
+Initial Post-Release Development
+--------------------------------
+
+Deprecate policies more than 8 release series old by updating the
+policy range check in ``cmMakefile::SetPolicy``.
+Commit with a message such as::
+
+  Add deprecation warnings for policies CMP#### and below
+
+  The OLD behaviors of all policies are deprecated, but only by
+  documentation.  Add an explicit deprecation diagnostic for policies
+  introduced in CMake $OLDVER and below to encourage projects to port
+  away from setting policies to OLD.
+
+Update the ``cmake_policy`` version range generated by ``install(EXPORT)``
+in ``cmExportFileGenerator::GeneratePolicyHeaderCode`` to end at the
+previous release.  We use one release back since we now know all the
+policies added for that version.  Commit with a message such as::
+
+  export: Increase maximum policy version in exported files to $prev
+
+  The files generatd by `install(EXPORT)` and `export()` commands
+  are known to work with policies as of CMake $prev, so enable them
+  in sufficiently new CMake versions.
diff --git a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
index c911625..a47d5e0 100644
--- a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
@@ -57,7 +57,11 @@
 set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
 
 # install rules
-install(TARGETS MathFunctions tutorial_compiler_flags
+set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs}
         DESTINATION lib
         EXPORT MathFunctionsTargets)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
index e0c0621..0bfe20c 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
@@ -47,5 +47,9 @@
 target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
 
 # install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs} DESTINATION lib)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
index 32f5e08..0d287ca 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
@@ -51,5 +51,9 @@
 target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
 
 # install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs} DESTINATION lib)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
index 720ee64..ea3861c 100644
--- a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
@@ -53,7 +53,11 @@
 target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
 
 # install rules
-install(TARGETS MathFunctions tutorial_compiler_flags
+set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs}
         DESTINATION lib
         EXPORT MathFunctionsTargets)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index 6e26de9..e7ea290 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -675,9 +675,9 @@
 
 Now that we have made MathFunctions always be used, we will need to update
 the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to
-create a SqrtLibrary that will conditionally be built when ``USE_MYMATH`` is
-enabled. Now, since this is a tutorial, we are going to explicitly require
-that SqrtLibrary is built statically.
+create a SqrtLibrary that will conditionally be built and installed when
+``USE_MYMATH`` is enabled. Now, since this is a tutorial, we are going to
+explicitly require that SqrtLibrary is built statically.
 
 The end result is that ``MathFunctions/CMakeLists.txt`` should look like:
 
@@ -703,7 +703,7 @@
 .. literalinclude:: Step10/MathFunctions/MathFunctions.h
   :language: c++
 
-At this point, if you build everything, you will notice that linking fails
+At this point, if you build everything, you may notice that linking fails
 as we are combining a static library without position independent code with a
 library that has position independent code. The solution to this is to
 explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index e98038a..3ceb1df 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,14 @@
 .. toctree::
    :maxdepth: 1
 
+   CMP0109: find_program() requires permission to execute but not to read. </policy/CMP0109>
+
+Policies Introduced by CMake 3.18
+=================================
+
+.. toctree::
+   :maxdepth: 1
+
    CMP0108: A target cannot link to itself through an alias. </policy/CMP0108>
    CMP0107: An ALIAS target cannot overwrite another target. </policy/CMP0107>
    CMP0106: The Documentation module is removed. </policy/CMP0106>
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 9becfc6..e4c662e 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -566,7 +566,8 @@
 
 ``compare_files [--ignore-eol] <file1> <file2>``
   Check if ``<file1>`` is same as ``<file2>``. If files are the same,
-  then returns ``0``, if not it returns ``1``.  The ``--ignore-eol`` option
+  then returns ``0``, if not it returns ``1``.  In case of invalid
+  arguments, it retruns 2. The ``--ignore-eol`` option
   implies line-wise comparison and ignores LF/CRLF differences.
 
 ``copy <file>... <destination>``
diff --git a/Help/policy/CMP0109.rst b/Help/policy/CMP0109.rst
new file mode 100644
index 0000000..7542c8f
--- /dev/null
+++ b/Help/policy/CMP0109.rst
@@ -0,0 +1,22 @@
+CMP0109
+-------
+
+:command:`find_program` requires permission to execute but not to read.
+
+In CMake 3.18 and below, the :command:`find_program` command on UNIX
+would find files that are readable without requiring execute permission,
+and would not find files that are executable without read permission.
+In CMake 3.19 and above, ``find_program`` now prefers to require execute
+permission but not read permission.  This policy provides compatibility
+with projects that have not been updated to expect the new behavior.
+
+The ``OLD`` behavior for this policy is for ``find_program`` to require
+read permission but not execute permission.
+The ``NEW`` behavior for this policy is for ``find_program`` to require
+execute permission but not read permission.
+
+This policy was introduced in CMake version 3.19.  CMake version |release|
+warns when the policy is not set and uses ``OLD`` behavior.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+  Developers should add similar notes for each topic branch
+  making a noteworthy change.  Each document should be named
+  and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/CPACK_EXTERNAL_BUILT_PACKAGES.rst b/Help/release/dev/CPACK_EXTERNAL_BUILT_PACKAGES.rst
new file mode 100644
index 0000000..af446d2
--- /dev/null
+++ b/Help/release/dev/CPACK_EXTERNAL_BUILT_PACKAGES.rst
@@ -0,0 +1,4 @@
+CPACK_EXTERNAL_BUILT_PACKAGES
+-----------------------------
+
+* :cpack_gen:`CPack External Generator` learned the :variable:`CPACK_EXTERNAL_BUILT_PACKAGES` variable.
diff --git a/Help/release/dev/FindSDL-update.rst b/Help/release/dev/FindSDL-update.rst
new file mode 100644
index 0000000..a85d2b9
--- /dev/null
+++ b/Help/release/dev/FindSDL-update.rst
@@ -0,0 +1,11 @@
+FindSDL-update
+--------------
+
+* The :module:`FindSDL` module now provides:
+
+  * imported target ``SDL::SDL``,
+
+  * result variables ``SDL_LIBRARIES`` and ``SDL_INCLUDE_DIRS``,
+
+  * version variables ``SDL_VERSION``, ``SDL_VERSION_MAJOR``
+    ``SDL_VERSION_MINOR``, and ``SDL_VERSION_PATCH``.
diff --git a/Help/release/dev/cpack-pre-and-post-build-scripts.rst b/Help/release/dev/cpack-pre-and-post-build-scripts.rst
new file mode 100644
index 0000000..bf7958b
--- /dev/null
+++ b/Help/release/dev/cpack-pre-and-post-build-scripts.rst
@@ -0,0 +1,5 @@
+cpack-pre-and-post-build-scripts
+--------------------------------
+
+* CPack learned the :variable:`CPACK_PRE_BUILD_SCRIPTS`, :variable:`CPACK_POST_BUILD_SCRIPTS`,
+  and :variable:`CPACK_PACKAGE_FILES` variables.
diff --git a/Help/release/dev/deprecate-policy-old.rst b/Help/release/dev/deprecate-policy-old.rst
new file mode 100644
index 0000000..f92aea7
--- /dev/null
+++ b/Help/release/dev/deprecate-policy-old.rst
@@ -0,0 +1,8 @@
+deprecate-policy-old
+--------------------
+
+* An explicit deprecation diagnostic was added for policy ``CMP0071``
+  (``CMP0071`` and below were already deprecated).
+  The :manual:`cmake-policies(7)` manual explains that the OLD behaviors
+  of all policies are deprecated and that projects should port to the
+  NEW behaviors.
diff --git a/Help/release/dev/find_program-exe-no-read.rst b/Help/release/dev/find_program-exe-no-read.rst
new file mode 100644
index 0000000..161b5db
--- /dev/null
+++ b/Help/release/dev/find_program-exe-no-read.rst
@@ -0,0 +1,5 @@
+find_program-exe-no-read
+------------------------
+
+* The :command:`find_program` command now requires permission to execute
+  but not to read the file found.  See policy :policy:`CMP0109`.
diff --git a/Help/release/dev/remove-cmake-gui-qt4.rst b/Help/release/dev/remove-cmake-gui-qt4.rst
new file mode 100644
index 0000000..2b29b75
--- /dev/null
+++ b/Help/release/dev/remove-cmake-gui-qt4.rst
@@ -0,0 +1,5 @@
+remove-cmake-gui-qt4
+--------------------
+
+* :manual:`cmake-gui(1)` now requires Qt5. Support for compiling with Qt4 has
+  been removed.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 4578b3a..cdc3e8b 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@
   This file should include the adjacent "dev.txt" file
   in development versions but not in release versions.
 
+.. include:: dev.txt
+
 Releases
 ========
 
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 6234b9d..553b966 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -386,6 +386,21 @@
   select the CPack generator(s) to be used when building the ``package``
   target or when running :manual:`cpack <cpack(1)>` without the ``-G`` option.
 
+.. variable:: CPACK_PRE_BUILD_SCRIPTS
+
+  List of CMake scripts to execute after CPack has installed the files to
+  be packed into a staging directory and before producing the result
+  packages.
+
+.. variable:: CPACK_POST_BUILD_SCRIPTS
+
+  List of CMake scripts to execute after CPack has produced the result
+  packages and before copying them back to a build directory.
+
+.. variable:: CPACK_PACKAGE_FILES
+
+  List of resulting package files passed to the ``CPACK_POST_BUILD_SCRIPTS``.
+
 #]=======================================================================]
 
 # Define this var in order to avoid (or warn) concerning multiple inclusion
diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake
index 2794f52..26a4bbd 100644
--- a/Modules/Compiler/AppleClang-C.cmake
+++ b/Modules/Compiler/AppleClang-C.cmake
@@ -1,6 +1,8 @@
 include(Compiler/Clang)
 __compiler_clang(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
index 15edc21..611c674 100644
--- a/Modules/Compiler/AppleClang-CXX.cmake
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -1,6 +1,8 @@
 include(Compiler/Clang)
 __compiler_clang(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
   set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
 endif()
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake
index 7c4a263..fb6ffa7 100644
--- a/Modules/Compiler/Clang-C.cmake
+++ b/Modules/Compiler/Clang-C.cmake
@@ -8,6 +8,8 @@
 
 if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
   set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
+elseif("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
 endif()
 
 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 789e991..311d2b0 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -2,7 +2,9 @@
 __compiler_clang(CXX)
 __compiler_clang_cxx_standards(CXX)
 
+
 if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+  set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
   set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
 endif()
 
diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake
index ca286b3..8105a77 100644
--- a/Modules/Compiler/GNU-C.cmake
+++ b/Modules/Compiler/GNU-C.cmake
@@ -1,6 +1,8 @@
 include(Compiler/GNU)
 __compiler_gnu(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index fcaaeab..59ec056 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -1,6 +1,8 @@
 include(Compiler/GNU)
 __compiler_gnu(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if (WIN32)
   if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
     set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fno-keep-inline-dllexport")
diff --git a/Modules/Compiler/Intel-C.cmake b/Modules/Compiler/Intel-C.cmake
index ec3bfd8..322f63d 100644
--- a/Modules/Compiler/Intel-C.cmake
+++ b/Modules/Compiler/Intel-C.cmake
@@ -28,6 +28,8 @@
 
 else()
 
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
   if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0.0)
     set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11")
     set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake
index 1ed1b08..47d5672 100644
--- a/Modules/Compiler/Intel-CXX.cmake
+++ b/Modules/Compiler/Intel-CXX.cmake
@@ -37,6 +37,8 @@
 
 else()
 
+  set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
   if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0.0)
     set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17")
     set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
diff --git a/Modules/Compiler/XL-C.cmake b/Modules/Compiler/XL-C.cmake
index 2077bda..78c44d5 100644
--- a/Modules/Compiler/XL-C.cmake
+++ b/Modules/Compiler/XL-C.cmake
@@ -6,6 +6,8 @@
 # -qthreaded = Ensures that all optimizations will be thread-safe
 string(APPEND CMAKE_C_FLAGS_INIT " -qthreaded")
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -qsourcetype=c)
+
 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-qlanglvl=stdc89")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-qlanglvl=extc89")
diff --git a/Modules/Compiler/XL-CXX.cmake b/Modules/Compiler/XL-CXX.cmake
index 41e3e11..3b911f3 100644
--- a/Modules/Compiler/XL-CXX.cmake
+++ b/Modules/Compiler/XL-CXX.cmake
@@ -6,6 +6,8 @@
 # -qthreaded = Ensures that all optimizations will be thread-safe
 string(APPEND CMAKE_CXX_FLAGS_INIT " -qthreaded")
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -+)
+
 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1)
   if(CMAKE_SYSTEM MATCHES "Linux")
     set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
@@ -32,6 +34,3 @@
 endif ()
 
 __compiler_check_default_language_standard(CXX 10.1 98)
-
-set(CMAKE_CXX_COMPILE_OBJECT
-  "<CMAKE_CXX_COMPILER> -+ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
diff --git a/Modules/Compiler/XLClang-C.cmake b/Modules/Compiler/XLClang-C.cmake
index 54c18a6..1668a4d 100644
--- a/Modules/Compiler/XLClang-C.cmake
+++ b/Modules/Compiler/XLClang-C.cmake
@@ -1,6 +1,8 @@
 include(Compiler/XLClang)
 __compiler_xlclang(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION  "-std=c89")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu89")
diff --git a/Modules/Compiler/XLClang-CXX.cmake b/Modules/Compiler/XLClang-CXX.cmake
index 9ea3d7c..02638c7 100644
--- a/Modules/Compiler/XLClang-CXX.cmake
+++ b/Modules/Compiler/XLClang-CXX.cmake
@@ -1,6 +1,8 @@
 include(Compiler/XLClang)
 __compiler_xlclang(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1)
   set(CMAKE_CXX98_STANDARD_COMPILE_OPTION  "")
   set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index 4c569b3..c5d791e 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -483,7 +483,9 @@
       endif()
       set(BLAS_mkl_LIB_PATH_SUFFIXES
           "compiler/lib" "compiler/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
+          "compiler/lib/${BLAS_mkl_ARCH_NAME}"
           "mkl/lib" "mkl/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
+          "mkl/lib/${BLAS_mkl_ARCH_NAME}"
           "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}")
 
       foreach(IT ${BLAS_SEARCH_LIBS})
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 13981d3..82dbcb9 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -1270,10 +1270,8 @@
   set(_Boost_UNIT_TEST_FRAMEWORK_HEADERS "boost/test/framework.hpp")
   set(_Boost_WAVE_HEADERS                "boost/wave.hpp")
   set(_Boost_WSERIALIZATION_HEADERS      "boost/archive/text_wiarchive.hpp")
-  if(WIN32)
-    set(_Boost_BZIP2_HEADERS             "boost/iostreams/filter/bzip2.hpp")
-    set(_Boost_ZLIB_HEADERS              "boost/iostreams/filter/zlib.hpp")
-  endif()
+  set(_Boost_BZIP2_HEADERS               "boost/iostreams/filter/bzip2.hpp")
+  set(_Boost_ZLIB_HEADERS                "boost/iostreams/filter/zlib.hpp")
 
   string(TOUPPER ${component} uppercomponent)
   set(${_hdrs} ${_Boost_${uppercomponent}_HEADERS} PARENT_SCOPE)
diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake
index ba56078..cde3a4d 100644
--- a/Modules/FindCurses.cmake
+++ b/Modules/FindCurses.cmake
@@ -156,7 +156,9 @@
 
   CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
     cbreak "" CURSES_NCURSES_HAS_CBREAK)
-  if(NOT CURSES_NCURSES_HAS_CBREAK)
+  CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
+    nodelay "" CURSES_NCURSES_HAS_NODELAY)
+  if(NOT CURSES_NCURSES_HAS_CBREAK OR NOT CURSES_NCURSES_HAS_NODELAY)
     find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" HINTS "${_cursesLibDir}")
     find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" )
 
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index 60a313d..7a1c252 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -125,8 +125,6 @@
   Set ``true`` to skip trying to find ``hdf5-config.cmake``.
 #]=======================================================================]
 
-# This module is maintained by Will Dicharry <wdicharry@stellarscience.com>.
-
 include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
@@ -347,6 +345,7 @@
   # wrapper exists, but not the compiler.  E.g. Miniconda / Anaconda Python
   execute_process(
     COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file}
+    WORKING_DIRECTORY ${scratch_dir}
     RESULT_VARIABLE return_value
     )
   if(return_value)
@@ -355,6 +354,7 @@
   else()
     execute_process(
       COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file}
+      WORKING_DIRECTORY ${scratch_dir}
       OUTPUT_VARIABLE output
       ERROR_VARIABLE output
       RESULT_VARIABLE return_value
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index e275946..a18cec4 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -289,7 +289,9 @@
         endif()
         set(LAPACK_mkl_LIB_PATH_SUFFIXES
             "compiler/lib" "compiler/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
+            "compiler/lib/${LAPACK_mkl_ARCH_NAME}"
             "mkl/lib" "mkl/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
+            "mkl/lib/${LAPACK_mkl_ARCH_NAME}"
             "lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}")
 
         # First try empty lapack libs
diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake
index 8d793a9..59eddbb 100644
--- a/Modules/FindSDL.cmake
+++ b/Modules/FindSDL.cmake
@@ -5,24 +5,54 @@
 FindSDL
 -------
 
-Locate SDL library
-
-This module defines
-
-::
-
-  SDL_LIBRARY, the name of the library to link against
-  SDL_FOUND, if false, do not try to link to SDL
-  SDL_INCLUDE_DIR, where to find SDL.h
-  SDL_VERSION_STRING, human-readable string containing the version of SDL
+Locate the SDL library
 
 
+Imported targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :prop_tgt:`IMPORTED` target:
+
+``SDL::SDL``
+  The SDL library, if found
+
+Result variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project:
+
+``SDL_INCLUDE_DIRS``
+  where to find SDL.h
+``SDL_LIBRARIES``
+  the name of the library to link against
+``SDL_FOUND``
+  if false, do not try to link to SDL
+``SDL_VERSION``
+  the human-readable string containing the version of SDL if found
+``SDL_VERSION_MAJOR``
+  SDL major version
+``SDL_VERSION_MINOR``
+  SDL minor version
+``SDL_VERSION_PATCH``
+  SDL patch version
+
+Cache variables
+^^^^^^^^^^^^^^^
+
+These variables may optionally be set to help this module find the correct files:
+
+``SDL_INCLUDE_DIR``
+  where to find SDL.h
+``SDL_LIBRARY``
+  the name of the library to link against
+
+
+Variables for locating SDL
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 This module responds to the flag:
 
-::
-
-  SDL_BUILDING_LIBRARY
+``SDL_BUILDING_LIBRARY``
     If this is defined, then no SDL_main will be linked in because
     only applications need main().
     Otherwise, it is assumed you are building an application and this
@@ -30,6 +60,15 @@
     as part of the returned SDL_LIBRARY variable.
 
 
+Obsolete variables
+^^^^^^^^^^^^^^^^^^
+
+These variables are obsolete and provided for backwards compatibility:
+
+``SDL_VERSION_STRING``
+  the human-readable string containing the version of SDL if found.
+  Identical to SDL_VERSION
+
 
 Don't forget to include SDLmain.h and SDLmain.m your project for the
 OS X framework based version.  (Other versions link to -lSDLmain which
@@ -52,15 +91,6 @@
 $SDLDIR is an environment variable that would correspond to the
 ./configure --prefix=$SDLDIR used in building SDL.  l.e.galup 9-20-02
 
-Modified by Eric Wing.  Added code to assist with automated building
-by using environmental variables and providing a more
-controlled/consistent search behavior.  Added new modifications to
-recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
-Also corrected the header search path to follow "proper" SDL
-guidelines.  Added a search for SDLmain which is needed by some
-platforms.  Added a search for threads which is needed by some
-platforms.  Added needed compile switches for MinGW.
-
 On OSX, this will prefer the Framework version (if found) over others.
 People will have to manually change the cache values of SDL_LIBRARY to
 override this selection or set the CMake environment
@@ -174,13 +204,11 @@
   string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MAJOR "${SDL_VERSION_MAJOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MINOR "${SDL_VERSION_MINOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_VERSION_PATCH "${SDL_VERSION_PATCH_LINE}")
-  set(SDL_VERSION_STRING ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH})
   unset(SDL_VERSION_MAJOR_LINE)
   unset(SDL_VERSION_MINOR_LINE)
   unset(SDL_VERSION_PATCH_LINE)
-  unset(SDL_VERSION_MAJOR)
-  unset(SDL_VERSION_MINOR)
-  unset(SDL_VERSION_PATCH)
+  set(SDL_VERSION ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH})
+  set(SDL_VERSION_STRING ${SDL_VERSION})
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
@@ -188,3 +216,14 @@
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL
                                   REQUIRED_VARS SDL_LIBRARY SDL_INCLUDE_DIR
                                   VERSION_VAR SDL_VERSION_STRING)
+
+if(SDL_FOUND)
+  set(SDL_LIBRARIES ${SDL_LIBRARY})
+  set(SDL_INCLUDE_DIRS ${SDL_INCLUDE_DIR})
+  if(NOT TARGET SDL::SDL)
+    add_library(SDL::SDL INTERFACE IMPORTED)
+    set_target_properties(SDL::SDL PROPERTIES
+      INTERFACE_INCLUDE_DIRECTORIES "${SDL_INCLUDE_DIR}"
+      INTERFACE_LINK_LIBRARIES "${SDL_LIBRARY}")
+  endif()
+endif()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 04d083b..f3c7db0 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,8 +1,8 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 18)
-set(CMake_VERSION_PATCH 0)
-set(CMake_VERSION_RC 2)
+set(CMake_VERSION_PATCH 20200623)
+#set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
 # Start with the full version number used in tags.  It has no dev info.
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 11e1aec..53be4fe 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -75,6 +75,12 @@
     if (cmSystemTools::GetErrorOccuredFlag() || !res) {
       return 0;
     }
+
+    const char* builtPackagesStr =
+      this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
+    if (builtPackagesStr) {
+      cmExpandList(builtPackagesStr, this->packageFileNames, false);
+    }
   }
 
   return 1;
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 288dc58..7990504 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -264,6 +264,23 @@
     return 0;
   }
 
+  // Run pre-build actions
+  const char* preBuildScripts = this->GetOption("CPACK_PRE_BUILD_SCRIPTS");
+  if (preBuildScripts) {
+    const auto scripts = cmExpandedList(preBuildScripts, false);
+    for (const auto& script : scripts) {
+      cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                    "Executing pre-build script: " << script << std::endl);
+
+      if (!this->MakefileMap->ReadListFile(script)) {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "The pre-build script not found: " << script
+                                                         << std::endl);
+        return 0;
+      }
+    }
+  }
+
   if (setDestDir) {
     cmSystemTools::PutEnv("DESTDIR=");
   }
@@ -333,7 +350,8 @@
     if (installDirectoriesVector.size() % 2 != 0) {
       cmCPackLogger(
         cmCPackLog::LOG_ERROR,
-        "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> and "
+        "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> "
+        "and "
         "<subdirectory>. The <subdirectory> can be '.' to be installed in "
         "the toplevel directory of installation."
           << std::endl);
@@ -475,10 +493,10 @@
                     "- Install script: " << installScript << std::endl);
 
       if (setDestDir) {
-        // For DESTDIR based packaging, use the *project* CMAKE_INSTALL_PREFIX
-        // underneath the tempInstallDirectory. The value of the project's
-        // CMAKE_INSTALL_PREFIX is sent in here as the value of the
-        // CPACK_INSTALL_PREFIX variable.
+        // For DESTDIR based packaging, use the *project*
+        // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The
+        // value of the project's CMAKE_INSTALL_PREFIX is sent in here as the
+        // value of the CPACK_INSTALL_PREFIX variable.
 
         std::string dir;
         if (this->GetOption("CPACK_INSTALL_PREFIX")) {
@@ -1076,6 +1094,25 @@
       return 0;
     }
   }
+  // Run post-build actions
+  const char* postBuildScripts = this->GetOption("CPACK_POST_BUILD_SCRIPTS");
+  if (postBuildScripts) {
+    this->MakefileMap->AddDefinition("CPACK_PACKAGE_FILES",
+                                     cmJoin(this->packageFileNames, ";"));
+
+    const auto scripts = cmExpandedList(postBuildScripts, false);
+    for (const auto& script : scripts) {
+      cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                    "Executing post-build script: " << script << std::endl);
+
+      if (!this->MakefileMap->ReadListFile(script)) {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "The post-build script not found: " << script
+                                                          << std::endl);
+        return 0;
+      }
+    }
+  }
 
   /* Prepare checksum algorithm*/
   const char* algo = this->GetOption("CPACK_PACKAGE_CHECKSUM");
@@ -1378,7 +1415,8 @@
           << std::endl);
   }
 
-  // if user specified packaging method, override the default packaging method
+  // if user specified packaging method, override the default packaging
+  // method
   if (method != UNKNOWN_COMPONENT_PACKAGE_METHOD) {
     componentPackageMethod = method;
   }
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 9a26db5..85e256b 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -2,11 +2,15 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 
 #include <csignal>
+#include <cstdio>
+#include <cstdlib>
 #include <cstring>
 #include <iostream>
 #include <string>
 #include <vector>
 
+#include <unistd.h>
+
 #include "cmsys/Encoding.hxx"
 
 #include "cmCursesColor.h"
@@ -54,7 +58,12 @@
 {
   if (cmCursesForm::CurrentForm) {
     endwin();
-    initscr();            /* Initialization */
+    if (initscr() == nullptr) {
+      static const char errmsg[] = "Error: ncurses initialization failed\n";
+      auto r = write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
+      static_cast<void>(r);
+      exit(1);
+    }
     noecho();             /* Echo off */
     cbreak();             /* nl- or cr not needed */
     keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
@@ -124,7 +133,10 @@
     cmCursesForm::DebugStart();
   }
 
-  initscr();            /* Initialization */
+  if (initscr() == nullptr) {
+    fprintf(stderr, "Error: ncurses initialization failed\n");
+    exit(1);
+  }
   noecho();             /* Echo off */
   cbreak();             /* nl- or cr not needed */
   keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 98dd0e2..e6d6b17 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -3,111 +3,79 @@
 
 project(QtDialog)
 CMake_OPTIONAL_COMPONENT(cmake-gui)
-find_package(Qt5Widgets QUIET)
-if (Qt5Widgets_FOUND)
-  include_directories(${Qt5Widgets_INCLUDE_DIRS})
-  add_definitions(${Qt5Widgets_DEFINITONS})
-  macro(qt4_wrap_ui)
-    qt5_wrap_ui(${ARGN})
-  endmacro()
-  macro(qt4_wrap_cpp)
-    qt5_wrap_cpp(${ARGN})
-  endmacro()
-  macro(qt4_add_resources)
-    qt5_add_resources(${ARGN})
-  endmacro()
+find_package(Qt5Widgets REQUIRED)
 
-  set(CMake_QT_LIBRARIES ${Qt5Widgets_LIBRARIES})
-  set(QT_QTMAIN_LIBRARY ${Qt5Core_QTMAIN_LIBRARIES})
+set(CMake_QT_EXTRA_LIBRARIES)
 
-  # Try to find the package WinExtras for the task bar progress
-  if(WIN32)
-    find_package(Qt5WinExtras QUIET)
-    if (Qt5WinExtras_FOUND)
-      include_directories(${Qt5WinExtras_INCLUDE_DIRS})
-      add_definitions(-DQT_WINEXTRAS)
-      list(APPEND CMake_QT_LIBRARIES ${Qt5WinExtras_LIBRARIES})
-    endif()
+# Try to find the package WinExtras for the task bar progress
+if(WIN32)
+  find_package(Qt5WinExtras QUIET)
+  if (Qt5WinExtras_FOUND)
+    add_definitions(-DQT_WINEXTRAS)
+    list(APPEND CMake_QT_EXTRA_LIBRARIES Qt5::WinExtras)
   endif()
+endif()
 
-  # Remove this when the minimum version of Qt is 4.6.
-  add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
 
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
+if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
+  list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
+  set_property(SOURCE CMakeSetup.cxx
+    PROPERTY COMPILE_DEFINITIONS USE_QXcbIntegrationPlugin)
+endif()
 
-  if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
-    list(APPEND CMake_QT_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
-    set_property(SOURCE CMakeSetup.cxx
-      PROPERTY COMPILE_DEFINITIONS USE_QXcbIntegrationPlugin)
-  endif()
+if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
+  list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES})
+  set_property(SOURCE CMakeSetup.cxx
+    PROPERTY COMPILE_DEFINITIONS USE_QWindowsIntegrationPlugin)
+endif()
 
-  if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
-    list(APPEND CMake_QT_LIBRARIES ${CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES})
-    set_property(SOURCE CMakeSetup.cxx
-      PROPERTY COMPILE_DEFINITIONS USE_QWindowsIntegrationPlugin)
-  endif()
-
-  # We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
-  # FIXME: This should be part of Qt5 CMake scripts, but unfortunately
-  # Qt5 support is missing there.
-  if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
-    macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
-      get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
-      if(EXISTS "${_qt_plugin_path}")
-        get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
-        get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
-        get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
-        if(APPLE)
-          set(_qt_plugin_dir "PlugIns")
-        elseif(WIN32)
-          set(_qt_plugin_dir "plugins")
-        endif()
-        set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
-        install(FILES "${_qt_plugin_path}"
-          DESTINATION "${_qt_plugin_dest}"
-          ${COMPONENT})
-        set(${_qt_plugins_var}
-          "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
-      else()
-        message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
+# We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
+# FIXME: This should be part of Qt5 CMake scripts, but unfortunately
+# Qt5 support is missing there.
+if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
+  macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
+    get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+    if(EXISTS "${_qt_plugin_path}")
+      get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
+      get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
+      get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
+      if(APPLE)
+        set(_qt_plugin_dir "PlugIns")
+      elseif(WIN32)
+        set(_qt_plugin_dir "plugins")
       endif()
-    endmacro()
-    if(APPLE)
-      install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
-      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
-      install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+      set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
+      install(FILES "${_qt_plugin_path}"
+        DESTINATION "${_qt_plugin_dest}"
         ${COMPONENT})
-    elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
-      install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
-      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
-      install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        DESTINATION bin
-        ${COMPONENT})
+      set(${_qt_plugins_var}
+        "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
+    else()
+      message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
     endif()
+  endmacro()
+  if(APPLE)
+    install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
+    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
+    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+      ${COMPONENT})
+  elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
+    install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
+    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
+    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      DESTINATION bin
+      ${COMPONENT})
   endif()
+endif()
 
-  if(TARGET Qt5::Core)
-    get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
-    get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
-    if(APPLE)
-      get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
-    endif()
-  endif()
-else()
-  set(QT_MIN_VERSION "4.4.0")
-  find_package(Qt4 REQUIRED)
-  if(NOT QT4_FOUND)
-    message(SEND_ERROR "Failed to find Qt 4.4 or greater.")
-    return()
-  endif()
-
-  include(${QT_USE_FILE})
-
-  set(CMake_QT_LIBRARIES ${QT_LIBRARIES})
-
+get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
+get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
+if(APPLE)
+  get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
 endif()
 
 set(SRCS
@@ -116,6 +84,7 @@
   CMakeSetup.cxx
   CMakeSetupDialog.cxx
   CMakeSetupDialog.h
+  Compilers.h
   FirstConfigure.cxx
   FirstConfigure.h
   QCMake.cxx
@@ -129,7 +98,7 @@
   WarningMessagesDialog.cxx
   WarningMessagesDialog.h
   )
-QT4_WRAP_UI(UI_SRCS
+qt5_wrap_ui(UI_SRCS
   CMakeSetupDialog.ui
   Compilers.ui
   CrossCompiler.ui
@@ -137,7 +106,7 @@
   RegexExplorer.ui
   WarningMessagesDialog.ui
   )
-QT4_WRAP_CPP(MOC_SRCS
+qt5_wrap_cpp(MOC_SRCS
   AddCacheEntry.h
   Compilers.h
   CMakeSetupDialog.h
@@ -148,14 +117,24 @@
   RegexExplorer.h
   WarningMessagesDialog.h
   )
-QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
+qt5_add_resources(RC_SRCS CMakeSetup.qrc)
 
-set(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS})
+if (FALSE) # CMake's bootstrap binary does not support automoc
+  set(CMAKE_AUTOMOC 1)
+  set(CMAKE_AUTORCC 1)
+  set(CMAKE_AUTOUIC 1)
+else ()
+  list(APPEND SRCS
+    ${UI_SRCS}
+    ${MOC_SRCS}
+    ${RC_SRCS})
+endif ()
+
 if(WIN32)
-  set(SRCS ${SRCS} CMakeSetup.rc)
+  list(APPEND SRCS CMakeSetup.rc)
 endif()
 if(APPLE)
-  set(SRCS ${SRCS} CMakeSetup.icns)
+  list(APPEND SRCS CMakeSetup.icns)
   set(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns)
   set_source_files_properties(CMakeSetup.icns PROPERTIES
     MACOSX_PACKAGE_LOCATION Resources)
@@ -172,7 +151,7 @@
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS} ${MANIFEST_FILE})
-target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${CMake_QT_LIBRARIES})
+target_link_libraries(cmake-gui CMakeLib Qt5::Core Qt5::Widgets ${CMake_QT_EXTRA_LIBRARIES})
 
 if(WIN32)
   target_sources(cmake-gui PRIVATE $<TARGET_OBJECTS:CMakeVersion>)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 9d928b2..7ef5a72 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -115,14 +115,6 @@
   QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8");
   QTextCodec::setCodecForLocale(utf8_codec);
 
-#if QT_VERSION < 0x050000
-  // clean out standard Qt paths for plugins, which we don't use anyway
-  // when creating Mac bundles, it potentially causes problems
-  foreach (QString p, QApplication::libraryPaths()) {
-    QApplication::removeLibraryPath(p);
-  }
-#endif
-
   // tell the cmake library where cmake is
   QDir cmExecDir(QApplication::applicationDirPath());
 #if defined(Q_OS_MAC)
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 776af81..f0b967b 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -340,10 +340,10 @@
 
 bool QCMake::interruptCallback()
 {
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
-  return this->InterruptFlag;
-#else
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
   return this->InterruptFlag.load();
+#else
+  return this->InterruptFlag.loadRelaxed();
 #endif
 }
 
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 541d3e9..928494b 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -155,11 +155,7 @@
 
 void QCMakeCacheView::setShowAdvanced(bool s)
 {
-#if QT_VERSION >= 040300
-  // new 4.3 API that needs to be called.  what about an older Qt?
   this->SearchFilter->invalidate();
-#endif
-
   this->AdvancedFilter->setShowAdvanced(s);
 }
 
@@ -209,9 +205,7 @@
 
 void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
 {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
   this->beginResetModel();
-#endif
 
   QSet<QCMakeProperty> newProps;
   QSet<QCMakeProperty> newProps2;
@@ -334,11 +328,7 @@
   }
 
   this->blockSignals(b);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
   this->endResetModel();
-#else
-  this->reset();
-#endif
 }
 
 QCMakeCacheModel::ViewType QCMakeCacheModel::viewType() const
@@ -348,9 +338,7 @@
 
 void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
 {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
   this->beginResetModel();
-#endif
 
   this->View = t;
 
@@ -367,11 +355,7 @@
   this->setProperties(oldProps);
   this->setProperties(props);
   this->blockSignals(b);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
   this->endResetModel();
-#else
-  this->reset();
-#endif
 }
 
 void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1,
@@ -497,8 +481,7 @@
       // go to the next in the tree
       while (!idxs.isEmpty() &&
              (
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) &&                                \
-  QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
+#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
                (idxs.last().row() + 1) >= rowCount(idxs.last().parent()) ||
 #endif
                !idxs.last().sibling(idxs.last().row() + 1, 0).isValid())) {
@@ -658,20 +641,6 @@
   return success;
 }
 
-// Issue 205903 fixed in Qt 4.5.0.
-// Can remove this function and FileDialogFlag when minimum Qt version is 4.5
-bool QCMakeCacheModelDelegate::eventFilter(QObject* object, QEvent* evt)
-{
-  // workaround for what looks like a bug in Qt on macOS
-  // where it doesn't create a QWidget wrapper for the native file dialog
-  // so the Qt library ends up assuming the focus was lost to something else
-
-  if (evt->type() == QEvent::FocusOut && this->FileDialogFlag) {
-    return false;
-  }
-  return QItemDelegate::eventFilter(object, evt);
-}
-
 void QCMakeCacheModelDelegate::setModelData(QWidget* editor,
                                             QAbstractItemModel* model,
                                             const QModelIndex& index) const
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
index bea1965..a252708 100644
--- a/Source/QtDialog/QCMakeCacheView.h
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -144,7 +144,6 @@
   bool editorEvent(QEvent* event, QAbstractItemModel* model,
                    const QStyleOptionViewItem& option,
                    const QModelIndex& index);
-  bool eventFilter(QObject* object, QEvent* event);
   void setModelData(QWidget* editor, QAbstractItemModel* model,
                     const QModelIndex& index) const;
   QSize sizeHint(const QStyleOptionViewItem& option,
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
index 332a770..d16ea58 100644
--- a/Source/QtDialog/QCMakeWidgets.cxx
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -4,9 +4,9 @@
 
 #include <utility>
 
-#include <QDirModel>
 #include <QFileDialog>
 #include <QFileInfo>
+#include <QFileSystemModel>
 #include <QResizeEvent>
 #include <QToolButton>
 
@@ -88,20 +88,20 @@
   }
 }
 
-// use same QDirModel for all completers
-static QDirModel* fileDirModel()
+// use same QFileSystemModel for all completers
+static QFileSystemModel* fileDirModel()
 {
-  static QDirModel* m = nullptr;
+  static QFileSystemModel* m = nullptr;
   if (!m) {
-    m = new QDirModel();
+    m = new QFileSystemModel();
   }
   return m;
 }
-static QDirModel* pathDirModel()
+static QFileSystemModel* pathDirModel()
 {
-  static QDirModel* m = nullptr;
+  static QFileSystemModel* m = nullptr;
   if (!m) {
-    m = new QDirModel();
+    m = new QFileSystemModel();
     m->setFilter(QDir::AllDirs | QDir::Drives | QDir::NoDotAndDotDot);
   }
   return m;
@@ -110,7 +110,7 @@
 QCMakeFileCompleter::QCMakeFileCompleter(QObject* o, bool dirs)
   : QCompleter(o)
 {
-  QDirModel* m = dirs ? pathDirModel() : fileDirModel();
+  QFileSystemModel* m = dirs ? pathDirModel() : fileDirModel();
   this->setModel(m);
 }
 
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index d6f7500e..53d4cb4 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -55,7 +55,7 @@
         auto ext = cm::string_view(file).substr(dotpos + 1);
         // Process only source files
         auto cm = mf.GetCMakeInstance();
-        if (dotpos > 0 && cm->IsSourceExtension(ext)) {
+        if (dotpos > 0 && cm->IsACLikeSourceExtension(ext)) {
           std::string fullname = cmStrCat(templateDirectory, '/', file);
           // add the file as a class file so
           // depends can be done
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 8550d04..7fbe90e 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -25,77 +25,205 @@
 #include "cmVersion.h"
 #include "cmake.h"
 
-static std::string const kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN =
-  "CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN";
-static std::string const kCMAKE_C_COMPILER_TARGET = "CMAKE_C_COMPILER_TARGET";
-static std::string const kCMAKE_C_LINK_NO_PIE_SUPPORTED =
-  "CMAKE_C_LINK_NO_PIE_SUPPORTED";
-static std::string const kCMAKE_C_LINK_PIE_SUPPORTED =
-  "CMAKE_C_LINK_PIE_SUPPORTED";
-static std::string const kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN =
-  "CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN";
-static std::string const kCMAKE_CXX_COMPILER_TARGET =
-  "CMAKE_CXX_COMPILER_TARGET";
-static std::string const kCMAKE_CXX_LINK_NO_PIE_SUPPORTED =
-  "CMAKE_CXX_LINK_NO_PIE_SUPPORTED";
-static std::string const kCMAKE_CXX_LINK_PIE_SUPPORTED =
-  "CMAKE_CXX_LINK_PIE_SUPPORTED";
-static std::string const kCMAKE_CUDA_ARCHITECTURES =
-  "CMAKE_CUDA_ARCHITECTURES";
-static std::string const kCMAKE_CUDA_COMPILER_TARGET =
-  "CMAKE_CUDA_COMPILER_TARGET";
-static std::string const kCMAKE_CUDA_RUNTIME_LIBRARY =
-  "CMAKE_CUDA_RUNTIME_LIBRARY";
-static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
-static std::string const kCMAKE_LINK_SEARCH_END_STATIC =
+namespace {
+class LanguageStandardState
+{
+public:
+  LanguageStandardState(std::string&& lang)
+    : IsEnabled(false)
+    , DidStandard(false)
+    , DidStandardRequired(false)
+    , DidExtensions(false)
+    , StandardFlag(lang + "_STANDARD")
+    , RequiredFlag(lang + "_STANDARD_REQUIRED")
+    , ExtensionFlag(lang + "_EXTENSIONS")
+  {
+  }
+
+  void Enabled(bool isEnabled) { this->IsEnabled = isEnabled; }
+
+  bool UpdateIfMatches(std::vector<std::string> const& argv, size_t& index)
+  {
+    bool updated = false;
+    if (argv[index] == this->StandardFlag) {
+      this->DidStandard = true;
+      this->StandardValue = argv[++index];
+      updated = true;
+    } else if (argv[index] == this->RequiredFlag) {
+      this->DidStandardRequired = true;
+      this->RequiredValue = argv[++index];
+      updated = true;
+    } else if (argv[index] == this->ExtensionFlag) {
+      this->DidExtensions = true;
+      this->ExtensionValue = argv[++index];
+      updated = true;
+    }
+    return updated;
+  }
+
+  bool Validate(cmMakefile* const makefile) const
+  {
+    if (this->DidStandard) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(this->StandardFlag,
+                 " allowed only in source file signature."));
+      return false;
+    }
+    if (this->DidStandardRequired) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(this->RequiredFlag,
+                 " allowed only in source file signature."));
+      return false;
+    }
+    if (this->DidExtensions) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(this->ExtensionFlag,
+                 " allowed only in source file signature."));
+      return false;
+    }
+
+    return true;
+  }
+
+  bool DidNone() const
+  {
+    return !this->DidStandard && !this->DidStandardRequired &&
+      !this->DidExtensions;
+  }
+
+  void LoadUnsetPropertyValues(cmMakefile* const makefile, bool honorStandard,
+                               bool warnCMP0067,
+                               std::vector<std::string>& warnCMP0067Variables)
+  {
+    if (!this->IsEnabled) {
+      return;
+    }
+
+    auto lookupStdVar = [&](std::string const& var) -> std::string {
+      std::string value = makefile->GetSafeDefinition(var);
+      if (warnCMP0067 && !value.empty()) {
+        value.clear();
+        warnCMP0067Variables.push_back(var);
+      }
+      return value;
+    };
+
+    if (honorStandard || warnCMP0067) {
+      if (!this->DidStandard) {
+        this->StandardValue =
+          lookupStdVar(cmStrCat("CMAKE_", this->StandardFlag));
+      }
+      if (!this->DidStandardRequired) {
+        this->RequiredValue =
+          lookupStdVar(cmStrCat("CMAKE_", this->RequiredFlag));
+      }
+      if (!this->DidExtensions) {
+        this->ExtensionValue =
+          lookupStdVar(cmStrCat("CMAKE_", this->ExtensionFlag));
+      }
+    }
+  }
+
+  void WriteProperties(FILE* fout, std::string const& targetName) const
+  {
+    if (!this->IsEnabled) {
+      return;
+    }
+
+    auto writeProp = [&](std::string const& prop, std::string const& value) {
+      fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n",
+              targetName.c_str(),
+              cmOutputConverter::EscapeForCMake(prop).c_str(),
+              cmOutputConverter::EscapeForCMake(value).c_str());
+    };
+
+    if (!this->StandardValue.empty()) {
+      writeProp(this->StandardFlag, this->StandardValue);
+    }
+    if (!this->RequiredValue.empty()) {
+      writeProp(this->RequiredFlag, this->RequiredValue);
+    }
+    if (!this->ExtensionValue.empty()) {
+      writeProp(this->ExtensionFlag, this->ExtensionValue);
+    }
+  }
+
+private:
+  bool IsEnabled;
+  bool DidStandard;
+  bool DidStandardRequired;
+  bool DidExtensions;
+
+  std::string StandardFlag;
+  std::string RequiredFlag;
+  std::string ExtensionFlag;
+
+  std::string StandardValue;
+  std::string RequiredValue;
+  std::string ExtensionValue;
+};
+
+constexpr size_t lang_property_start = 0;
+constexpr size_t lang_property_size = 4;
+constexpr size_t pie_property_start = 4;
+constexpr size_t pie_property_size = 2;
+#define SETUP_LANGUAGE(name, lang)                                            \
+  static const std::string name[lang_property_size + pie_property_size + 1] = \
+    { "CMAKE_" #lang "_COMPILER_EXTERNAL_TOOLCHAIN",                          \
+      "CMAKE_" #lang "_COMPILER_TARGET",                                      \
+      "CMAKE_" #lang "_LINK_NO_PIE_SUPPORTED",                                \
+      "CMAKE_" #lang "_PIE_SUPPORTED", "" }
+
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(c_properties, C);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(cxx_properties, CXX);
+
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(cuda_properties, CUDA);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(fortran_properties, Fortran);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(objc_properties, OBJC);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(objcxx_properties, OBJCXX);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(swift_properties, Swift);
+#undef SETUP_LANGUAGE
+
+std::string const kCMAKE_CUDA_ARCHITECTURES = "CMAKE_CUDA_ARCHITECTURES";
+std::string const kCMAKE_CUDA_RUNTIME_LIBRARY = "CMAKE_CUDA_RUNTIME_LIBRARY";
+std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
+std::string const kCMAKE_LINK_SEARCH_END_STATIC =
   "CMAKE_LINK_SEARCH_END_STATIC";
-static std::string const kCMAKE_LINK_SEARCH_START_STATIC =
+std::string const kCMAKE_LINK_SEARCH_START_STATIC =
   "CMAKE_LINK_SEARCH_START_STATIC";
-static std::string const kCMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT =
+std::string const kCMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT =
   "CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT";
-static std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
-static std::string const kCMAKE_OSX_DEPLOYMENT_TARGET =
-  "CMAKE_OSX_DEPLOYMENT_TARGET";
-static std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
-static std::string const kCMAKE_APPLE_ARCH_SYSROOTS =
-  "CMAKE_APPLE_ARCH_SYSROOTS";
-static std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
+std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
+std::string const kCMAKE_OSX_DEPLOYMENT_TARGET = "CMAKE_OSX_DEPLOYMENT_TARGET";
+std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
+std::string const kCMAKE_APPLE_ARCH_SYSROOTS = "CMAKE_APPLE_ARCH_SYSROOTS";
+std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
   "CMAKE_POSITION_INDEPENDENT_CODE";
-static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
-static std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
-static std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
-static std::string const kCMAKE_Swift_COMPILER_TARGET =
-  "CMAKE_Swift_COMPILER_TARGET";
-static std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
+std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
+std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
+std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
+std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
   "CMAKE_TRY_COMPILE_OSX_ARCHITECTURES";
-static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
+std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
   "CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
-static std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
+std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
 
 /* GHS Multi platform variables */
-static std::set<std::string> ghs_platform_vars{
+std::set<std::string> const ghs_platform_vars{
   "GHS_TARGET_PLATFORM", "GHS_PRIMARY_TARGET", "GHS_TOOLSET_ROOT",
   "GHS_OS_ROOT",         "GHS_OS_DIR",         "GHS_BSP_NAME",
   "GHS_OS_DIR_OPTION"
 };
-
-static void writeProperty(FILE* fout, std::string const& targetName,
-                          std::string const& prop, std::string const& value)
-{
-  fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n", targetName.c_str(),
-          cmOutputConverter::EscapeForCMake(prop).c_str(),
-          cmOutputConverter::EscapeForCMake(value).c_str());
-}
-
-std::string cmCoreTryCompile::LookupStdVar(std::string const& var,
-                                           bool warnCMP0067)
-{
-  std::string value = this->Makefile->GetSafeDefinition(var);
-  if (warnCMP0067 && !value.empty()) {
-    value.clear();
-    this->WarnCMP0067.push_back(var);
-  }
-  return value;
 }
 
 int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
@@ -137,21 +265,11 @@
   std::string outputVariable;
   std::string copyFile;
   std::string copyFileError;
-  std::string cStandard;
-  std::string objcStandard;
-  std::string cxxStandard;
-  std::string objcxxStandard;
-  std::string cudaStandard;
-  std::string cStandardRequired;
-  std::string cxxStandardRequired;
-  std::string objcStandardRequired;
-  std::string objcxxStandardRequired;
-  std::string cudaStandardRequired;
-  std::string cExtensions;
-  std::string cxxExtensions;
-  std::string objcExtensions;
-  std::string objcxxExtensions;
-  std::string cudaExtensions;
+  LanguageStandardState cState("C");
+  LanguageStandardState cudaState("CUDA");
+  LanguageStandardState cxxState("CXX");
+  LanguageStandardState objcState("OBJC");
+  LanguageStandardState objcxxState("OBJCXX");
   std::vector<std::string> targets;
   std::vector<std::string> linkOptions;
   std::string libsToLink = " ";
@@ -160,21 +278,6 @@
   bool didOutputVariable = false;
   bool didCopyFile = false;
   bool didCopyFileError = false;
-  bool didCStandard = false;
-  bool didCxxStandard = false;
-  bool didObjCStandard = false;
-  bool didObjCxxStandard = false;
-  bool didCudaStandard = false;
-  bool didCStandardRequired = false;
-  bool didCxxStandardRequired = false;
-  bool didObjCStandardRequired = false;
-  bool didObjCxxStandardRequired = false;
-  bool didCudaStandardRequired = false;
-  bool didCExtensions = false;
-  bool didCxxExtensions = false;
-  bool didObjCExtensions = false;
-  bool didObjCxxExtensions = false;
-  bool didCudaExtensions = false;
   bool useSources = argv[2] == "SOURCES";
   std::vector<std::string> sources;
 
@@ -188,21 +291,6 @@
     DoingOutputVariable,
     DoingCopyFile,
     DoingCopyFileError,
-    DoingCStandard,
-    DoingCxxStandard,
-    DoingObjCStandard,
-    DoingObjCxxStandard,
-    DoingCudaStandard,
-    DoingCStandardRequired,
-    DoingCxxStandardRequired,
-    DoingObjCStandardRequired,
-    DoingObjCxxStandardRequired,
-    DoingCudaStandardRequired,
-    DoingCExtensions,
-    DoingCxxExtensions,
-    DoingObjCExtensions,
-    DoingObjCxxExtensions,
-    DoingCudaExtensions,
     DoingSources,
     DoingCMakeInternal
   };
@@ -226,51 +314,12 @@
     } else if (argv[i] == "COPY_FILE_ERROR") {
       doing = DoingCopyFileError;
       didCopyFileError = true;
-    } else if (argv[i] == "C_STANDARD") {
-      doing = DoingCStandard;
-      didCStandard = true;
-    } else if (argv[i] == "CXX_STANDARD") {
-      doing = DoingCxxStandard;
-      didCxxStandard = true;
-    } else if (argv[i] == "OBJC_STANDARD") {
-      doing = DoingObjCStandard;
-      didObjCStandard = true;
-    } else if (argv[i] == "OBJCXX_STANDARD") {
-      doing = DoingObjCxxStandard;
-      didObjCxxStandard = true;
-    } else if (argv[i] == "CUDA_STANDARD") {
-      doing = DoingCudaStandard;
-      didCudaStandard = true;
-    } else if (argv[i] == "C_STANDARD_REQUIRED") {
-      doing = DoingCStandardRequired;
-      didCStandardRequired = true;
-    } else if (argv[i] == "CXX_STANDARD_REQUIRED") {
-      doing = DoingCxxStandardRequired;
-      didCxxStandardRequired = true;
-    } else if (argv[i] == "OBJC_STANDARD_REQUIRED") {
-      doing = DoingObjCStandardRequired;
-      didObjCStandardRequired = true;
-    } else if (argv[i] == "OBJCXX_STANDARD_REQUIRED") {
-      doing = DoingObjCxxStandardRequired;
-      didObjCxxStandardRequired = true;
-    } else if (argv[i] == "CUDA_STANDARD_REQUIRED") {
-      doing = DoingCudaStandardRequired;
-      didCudaStandardRequired = true;
-    } else if (argv[i] == "C_EXTENSIONS") {
-      doing = DoingCExtensions;
-      didCExtensions = true;
-    } else if (argv[i] == "CXX_EXTENSIONS") {
-      doing = DoingCxxExtensions;
-      didCxxExtensions = true;
-    } else if (argv[i] == "OBJC_EXTENSIONS") {
-      doing = DoingObjCExtensions;
-      didObjCExtensions = true;
-    } else if (argv[i] == "OBJCXX_EXTENSIONS") {
-      doing = DoingObjCxxExtensions;
-      didObjCxxExtensions = true;
-    } else if (argv[i] == "CUDA_EXTENSIONS") {
-      doing = DoingCudaExtensions;
-      didCudaExtensions = true;
+    } else if (cState.UpdateIfMatches(argv, i) ||
+               cxxState.UpdateIfMatches(argv, i) ||
+               cudaState.UpdateIfMatches(argv, i) ||
+               objcState.UpdateIfMatches(argv, i) ||
+               objcxxState.UpdateIfMatches(argv, i)) {
+      continue;
     } else if (argv[i] == "__CMAKE_INTERNAL") {
       doing = DoingCMakeInternal;
     } else if (doing == DoingCMakeFlags) {
@@ -315,51 +364,6 @@
     } else if (doing == DoingCopyFileError) {
       copyFileError = argv[i];
       doing = DoingNone;
-    } else if (doing == DoingCStandard) {
-      cStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCxxStandard) {
-      cxxStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCStandard) {
-      objcStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCxxStandard) {
-      objcxxStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCudaStandard) {
-      cudaStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCStandardRequired) {
-      cStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCxxStandardRequired) {
-      cxxStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCStandardRequired) {
-      objcStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCxxStandardRequired) {
-      objcxxStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCudaStandardRequired) {
-      cudaStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCExtensions) {
-      cExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCxxExtensions) {
-      cxxExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCExtensions) {
-      objcExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCxxExtensions) {
-      objcxxExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCudaExtensions) {
-      cudaExtensions = argv[i];
-      doing = DoingNone;
     } else if (doing == DoingSources) {
       sources.push_back(argv[i]);
     } else if (doing == DoingCMakeInternal) {
@@ -411,59 +415,22 @@
     return -1;
   }
 
-  if (didCStandard && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "C_STANDARD allowed only in source file signature.");
-    return -1;
-  }
-  if (didCxxStandard && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CXX_STANDARD allowed only in source file signature.");
-    return -1;
-  }
-  if (didCudaStandard && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CUDA_STANDARD allowed only in source file signature.");
-    return -1;
-  }
-  if (didCStandardRequired && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "C_STANDARD_REQUIRED allowed only in source file signature.");
-    return -1;
-  }
-  if (didCxxStandardRequired && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CXX_STANDARD_REQUIRED allowed only in source file signature.");
-    return -1;
-  }
-  if (didCudaStandardRequired && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CUDA_STANDARD_REQUIRED allowed only in source file signature.");
-    return -1;
-  }
-  if (didCExtensions && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "C_EXTENSIONS allowed only in source file signature.");
-    return -1;
-  }
-  if (didCxxExtensions && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CXX_EXTENSIONS allowed only in source file signature.");
-    return -1;
-  }
-  if (didCudaExtensions && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CUDA_EXTENSIONS allowed only in source file signature.");
-    return -1;
+  if (!this->SrcFileSignature) {
+    if (!cState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!cudaState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!cxxState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!objcState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!objcxxState.Validate(this->Makefile)) {
+      return -1;
+    }
   }
 
   // compute the binary dir when TRY_COMPILE is called with a src file
@@ -721,12 +688,23 @@
     // Forward a set of variables to the inner project cache.
     {
       std::set<std::string> vars;
-      vars.insert(kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN);
-      vars.insert(kCMAKE_C_COMPILER_TARGET);
-      vars.insert(kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN);
-      vars.insert(kCMAKE_CXX_COMPILER_TARGET);
+      vars.insert(&c_properties[lang_property_start],
+                  &c_properties[lang_property_start + lang_property_size]);
+      vars.insert(&cxx_properties[lang_property_start],
+                  &cxx_properties[lang_property_start + lang_property_size]);
+      vars.insert(&cuda_properties[lang_property_start],
+                  &cuda_properties[lang_property_start + lang_property_size]);
+      vars.insert(
+        &fortran_properties[lang_property_start],
+        &fortran_properties[lang_property_start + lang_property_size]);
+      vars.insert(&objc_properties[lang_property_start],
+                  &objc_properties[lang_property_start + lang_property_size]);
+      vars.insert(
+        &objcxx_properties[lang_property_start],
+        &objcxx_properties[lang_property_start + lang_property_size]);
+      vars.insert(&swift_properties[lang_property_start],
+                  &swift_properties[lang_property_start + lang_property_size]);
       vars.insert(kCMAKE_CUDA_ARCHITECTURES);
-      vars.insert(kCMAKE_CUDA_COMPILER_TARGET);
       vars.insert(kCMAKE_CUDA_RUNTIME_LIBRARY);
       vars.insert(kCMAKE_ENABLE_EXPORTS);
       vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
@@ -739,7 +717,6 @@
       vars.insert(kCMAKE_SYSROOT);
       vars.insert(kCMAKE_SYSROOT_COMPILE);
       vars.insert(kCMAKE_SYSROOT_LINK);
-      vars.insert(kCMAKE_Swift_COMPILER_TARGET);
       vars.insert(kCMAKE_WARN_DEPRECATED);
       vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
 
@@ -753,10 +730,22 @@
           cmPolicies::NEW) {
         // To ensure full support of PIE, propagate cache variables
         // driving the link options
-        vars.insert(kCMAKE_C_LINK_PIE_SUPPORTED);
-        vars.insert(kCMAKE_C_LINK_NO_PIE_SUPPORTED);
-        vars.insert(kCMAKE_CXX_LINK_PIE_SUPPORTED);
-        vars.insert(kCMAKE_CXX_LINK_NO_PIE_SUPPORTED);
+        vars.insert(&c_properties[pie_property_start],
+                    &c_properties[pie_property_start + pie_property_size]);
+        vars.insert(&cxx_properties[pie_property_start],
+                    &cxx_properties[pie_property_start + pie_property_size]);
+        vars.insert(&cuda_properties[pie_property_start],
+                    &cuda_properties[pie_property_start + pie_property_size]);
+        vars.insert(
+          &fortran_properties[pie_property_start],
+          &fortran_properties[pie_property_start + pie_property_size]);
+        vars.insert(&objc_properties[pie_property_start],
+                    &objc_properties[pie_property_start + pie_property_size]);
+        vars.insert(
+          &objcxx_properties[pie_property_start],
+          &objcxx_properties[pie_property_start + pie_property_size]);
+        vars.insert(&swift_properties[pie_property_start],
+                    &swift_properties[pie_property_start + pie_property_size]);
       }
 
       /* for the TRY_COMPILEs we want to be able to specify the architecture.
@@ -819,21 +808,17 @@
     }
     fprintf(fout, ")\n");
 
-    bool const testC = testLangs.find("C") != testLangs.end();
-    bool const testObjC = testLangs.find("OBJC") != testLangs.end();
-    bool const testCxx = testLangs.find("CXX") != testLangs.end();
-    bool const testObjCxx = testLangs.find("OBJCXX") != testLangs.end();
-    bool const testCuda = testLangs.find("CUDA") != testLangs.end();
+    cState.Enabled(testLangs.find("C") != testLangs.end());
+    cxxState.Enabled(testLangs.find("CXX") != testLangs.end());
+    cudaState.Enabled(testLangs.find("CUDA") != testLangs.end());
+    objcState.Enabled(testLangs.find("OBJC") != testLangs.end());
+    objcxxState.Enabled(testLangs.find("OBJCXX") != testLangs.end());
 
     bool warnCMP0067 = false;
     bool honorStandard = true;
 
-    if (!didCStandard && !didCxxStandard && !didObjCStandard &&
-        !didObjCxxStandard && !didCudaStandard && !didCStandardRequired &&
-        !didCxxStandardRequired && !didObjCStandardRequired &&
-        !didObjCxxStandardRequired && !didCudaStandardRequired &&
-        !didCExtensions && !didCxxExtensions && !didObjCExtensions &&
-        !didObjCxxExtensions && !didCudaExtensions) {
+    if (cState.DidNone() && cxxState.DidNone() && objcState.DidNone() &&
+        objcxxState.DidNone() && cudaState.DidNone()) {
       switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
         case cmPolicies::WARN:
           warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
@@ -855,46 +840,20 @@
       }
     }
 
-    if (honorStandard || warnCMP0067) {
+    std::vector<std::string> warnCMP0067Variables;
 
-      auto testLanguage =
-        [&](bool testLang, bool didLangStandard, bool didLangStandardRequired,
-            bool didLangExtensions, std::string& langStandard,
-            std::string& langStandardRequired, std::string& langExtensions,
-            const std::string& lang) {
-          if (testLang) {
-            if (!didLangStandard) {
-              langStandard = this->LookupStdVar(
-                cmStrCat("CMAKE_", lang, "_STANDARD"), warnCMP0067);
-            }
-            if (!didLangStandardRequired) {
-              langStandardRequired = this->LookupStdVar(
-                cmStrCat("CMAKE_", lang, "_STANDARD_REQUIRED"), warnCMP0067);
-            }
-            if (!didLangExtensions) {
-              langExtensions = this->LookupStdVar(
-                cmStrCat("CMAKE_", lang, "_EXTENSIONS"), warnCMP0067);
-            }
-          }
-        };
+    cState.LoadUnsetPropertyValues(this->Makefile, honorStandard, warnCMP0067,
+                                   warnCMP0067Variables);
+    cxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                     warnCMP0067, warnCMP0067Variables);
+    cudaState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                      warnCMP0067, warnCMP0067Variables);
+    objcState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                      warnCMP0067, warnCMP0067Variables);
+    objcxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                        warnCMP0067, warnCMP0067Variables);
 
-      testLanguage(testC, didCStandard, didCStandardRequired, didCExtensions,
-                   cStandard, cStandardRequired, cExtensions, "C");
-      testLanguage(testObjC, didObjCStandard, didObjCStandardRequired,
-                   didObjCExtensions, objcStandard, objcStandardRequired,
-                   objcExtensions, "OBJC");
-      testLanguage(testCxx, didCxxStandard, didCxxStandardRequired,
-                   didCxxExtensions, cxxStandard, cxxStandardRequired,
-                   cxxExtensions, "CXX");
-      testLanguage(testObjCxx, didObjCxxStandard, didObjCxxStandardRequired,
-                   didObjCxxExtensions, objcxxStandard, objcxxStandardRequired,
-                   objcxxExtensions, "OBJCXX");
-      testLanguage(testCuda, didCudaStandard, didCudaStandardRequired,
-                   didCudaExtensions, cudaStandard, cudaStandardRequired,
-                   cudaExtensions, "CUDA");
-    }
-
-    if (!this->WarnCMP0067.empty()) {
+    if (!warnCMP0067Variables.empty()) {
       std::ostringstream w;
       /* clang-format off */
       w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0067) << "\n"
@@ -902,43 +861,17 @@
         "is not honoring language standard variables in the test project:\n"
         ;
       /* clang-format on */
-      for (std::string const& vi : this->WarnCMP0067) {
+      for (std::string const& vi : warnCMP0067Variables) {
         w << "  " << vi << "\n";
       }
       this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
     }
 
-    auto writeLanguageProperties = [&](bool testLang,
-                                       const std::string& langStandard,
-                                       const std::string& langStandardRequired,
-                                       const std::string& langExtensions,
-                                       const std::string& lang) {
-      if (testLang) {
-        if (!langStandard.empty()) {
-          writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD"),
-                        langStandard);
-        }
-        if (!langStandardRequired.empty()) {
-          writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD_REQUIRED"),
-                        langStandardRequired);
-        }
-        if (!langExtensions.empty()) {
-          writeProperty(fout, targetName, cmStrCat(lang, "_EXTENSIONS"),
-                        langExtensions);
-        }
-      }
-    };
-
-    writeLanguageProperties(testC, cStandard, cStandardRequired, cExtensions,
-                            "C");
-    writeLanguageProperties(testObjC, objcStandard, objcStandardRequired,
-                            objcExtensions, "OBJC");
-    writeLanguageProperties(testCxx, cxxStandard, cxxStandardRequired,
-                            cxxExtensions, "CXX");
-    writeLanguageProperties(testObjCxx, objcxxStandard, objcxxStandardRequired,
-                            objcxxExtensions, "OBJCXX");
-    writeLanguageProperties(testCuda, cudaStandard, cudaStandardRequired,
-                            cudaExtensions, "CUDA");
+    cState.WriteProperties(fout, targetName);
+    cxxState.WriteProperties(fout, targetName);
+    cudaState.WriteProperties(fout, targetName);
+    objcState.WriteProperties(fout, targetName);
+    objcxxState.WriteProperties(fout, targetName);
 
     if (!linkOptions.empty()) {
       std::vector<std::string> options;
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index ae714a6..916572a 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -47,10 +47,6 @@
   std::string OutputFile;
   std::string FindErrorMessage;
   bool SrcFileSignature = false;
-
-private:
-  std::vector<std::string> WarnCMP0067;
-  std::string LookupStdVar(std::string const& var, bool warnCMP0067);
 };
 
 #endif
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 32b0ca9..652c041 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -370,7 +370,7 @@
             std::string lang = s->GetOrDetermineLanguage();
             if (lang == "C" || lang == "CXX" || lang == "CUDA") {
               std::string const& srcext = s->GetExtension();
-              isCFile = cm->IsSourceExtension(srcext);
+              isCFile = cm->IsACLikeSourceExtension(srcext);
             }
 
             std::string const& fullPath = s->ResolveFullPath();
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index bf7555d..95cfb0a 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -227,8 +227,7 @@
           cmSystemTools::LowerCase(s->GetExtension());
         // check whether it is a source or a include file
         // then put it accordingly into one of the two containers
-        if (cm->IsSourceExtension(extLower) || cm->IsCudaExtension(extLower) ||
-            cm->IsFortranExtension(extLower)) {
+        if (cm->IsAKnownSourceExtension(extLower)) {
           cFiles[fullPath] = s;
         } else {
           otherFiles.insert(fullPath);
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 613a943..3e265a0 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -349,6 +349,13 @@
   if (language.empty()) {
     language = "C";
   }
+
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (source->GetProperty("LANGUAGE")) {
+    lg->AppendFeatureOptions(flags, language, "EXPLICIT_LANGUAGE");
+  }
+
   std::string const& config =
     lg->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
 
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 4b88bea..77728ec 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -4,6 +4,7 @@
 
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmPolicies.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -19,6 +20,7 @@
   cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base)
     : DebugSearches("find_program", base)
     , Makefile(makefile)
+    , PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
   {
 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
     // Consider platform-specific extensions.
@@ -48,6 +50,8 @@
   cmFindBaseDebugState DebugSearches;
   cmMakefile* Makefile;
 
+  cmPolicies::PolicyStatus PolicyCMP0109;
+
   void AddName(std::string const& name) { this->Names.push_back(name); }
   void SetName(std::string const& name)
   {
@@ -85,7 +89,7 @@
       this->TestNameExt = cmStrCat(name, ext);
       this->TestPath =
         cmSystemTools::CollapseFullPath(this->TestNameExt, path);
-      bool exists = cmSystemTools::FileExists(this->TestPath, true);
+      bool exists = this->FileIsExecutable(this->TestPath);
       exists ? this->DebugSearches.FoundAt(this->TestPath)
              : this->DebugSearches.FailedAt(this->TestPath);
       if (exists) {
@@ -95,6 +99,48 @@
     }
     return false;
   }
+  bool FileIsExecutable(std::string const& file) const
+  {
+    switch (this->PolicyCMP0109) {
+      case cmPolicies::OLD:
+        return cmSystemTools::FileExists(file, true);
+      case cmPolicies::NEW:
+      case cmPolicies::REQUIRED_ALWAYS:
+      case cmPolicies::REQUIRED_IF_USED:
+        return cmSystemTools::FileIsExecutable(file);
+      default:
+        break;
+    }
+    bool const isExeOld = cmSystemTools::FileExists(file, true);
+    bool const isExeNew = cmSystemTools::FileIsExecutable(file);
+    if (isExeNew == isExeOld) {
+      return isExeNew;
+    }
+    if (isExeNew) {
+      this->Makefile->IssueMessage(
+        MessageType::AUTHOR_WARNING,
+        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+                 "\n"
+                 "The file\n"
+                 "  ",
+                 file,
+                 "\n"
+                 "is executable but not readable.  "
+                 "CMake is ignoring it for compatibility."));
+    } else {
+      this->Makefile->IssueMessage(
+        MessageType::AUTHOR_WARNING,
+        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+                 "\n"
+                 "The file\n"
+                 "  ",
+                 file,
+                 "\n"
+                 "is readable but not executable.  "
+                 "CMake is using it for compatibility."));
+    }
+    return isExeOld;
+  }
 };
 
 cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
@@ -266,14 +312,13 @@
 
   if (executableURL != nullptr) {
     const int MAX_OSX_PATH_SIZE = 1024;
-    char buffer[MAX_OSX_PATH_SIZE];
+    UInt8 buffer[MAX_OSX_PATH_SIZE];
 
-    // Convert the CFString to a C string
-    CFStringGetCString(CFURLGetString(executableURL), buffer,
-                       MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8);
-
-    // And finally to a c++ string
-    executable = bundlePath + "/Contents/MacOS/" + std::string(buffer);
+    if (CFURLGetFileSystemRepresentation(executableURL, false, buffer,
+                                         MAX_OSX_PATH_SIZE)) {
+      executable = bundlePath + "/Contents/MacOS/" +
+        std::string(reinterpret_cast<char*>(buffer));
+    }
     // Only release CFURLRef if it's not null
     CFRelease(executableURL);
   }
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index e4fb67e..3e0c21c 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1708,7 +1708,7 @@
       std::string error;
       std::string lang;
       if (!context->LG->GetMakefile()->CompileFeatureKnown(
-            context->HeadTarget->Target, p, lang, &error)) {
+            context->HeadTarget->Target->GetName(), p, lang, &error)) {
         reportError(context, content->GetOriginalExpression(), error);
         return std::string();
       }
@@ -1742,9 +1742,9 @@
           continue;
         }
         if (!context->LG->GetMakefile()->HaveStandardAvailable(
-              target->Target, lit.first, it)) {
+              target, lit.first, context->Config, it)) {
           if (evalLL) {
-            cmProp l = target->GetProperty(lit.first + "_STANDARD");
+            cmProp l = target->GetLanguageStandard(lit.first, context->Config);
             if (!l) {
               l = standardDefault;
             }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index f2011ee..1f66a9f 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -947,6 +947,45 @@
   return it != this->ExplicitObjectName.end();
 }
 
+cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang,
+                                              std::string const& config) const
+{
+  std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
+  auto langStandardIter = this->LanguageStandardMap.find(key);
+  if (langStandardIter != this->LanguageStandardMap.end()) {
+    return &langStandardIter->second;
+  }
+
+  return this->Target->GetProperty(cmStrCat(lang, "_STANDARD"));
+}
+
+cmProp cmGeneratorTarget::GetLanguageStandardProperty(std::string const& lang,
+                                                      const char* suffix) const
+{
+  cmProp propertyValue = this->Target->GetProperty(cmStrCat(lang, suffix));
+  if (propertyValue == nullptr) {
+    // Check if we should use the value set by another language.
+    if (lang == "OBJC") {
+      propertyValue = this->GetLanguageStandardProperty("C", suffix);
+    } else if (lang == "OBJCXX" || lang == "CUDA") {
+      propertyValue = this->GetLanguageStandardProperty("CXX", suffix);
+    }
+  }
+  return propertyValue;
+}
+
+cmProp cmGeneratorTarget::GetLanguageExtensions(std::string const& lang) const
+{
+  return this->GetLanguageStandardProperty(lang, "_EXTENSIONS");
+}
+
+bool cmGeneratorTarget::GetLanguageStandardRequired(
+  std::string const& lang) const
+{
+  cmProp p = this->GetLanguageStandardProperty(lang, "_STANDARD_REQUIRED");
+  return p && cmIsOn(*p);
+}
+
 void cmGeneratorTarget::GetModuleDefinitionSources(
   std::vector<cmSourceFile const*>& data, const std::string& config) const
 {
@@ -4408,12 +4447,68 @@
 
 bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const
 {
+  // Compute the language standard based on the compile features.
   std::vector<BT<std::string>> features = this->GetCompileFeatures(config);
   for (BT<std::string> const& f : features) {
-    if (!this->Makefile->AddRequiredTargetFeature(this->Target, f.Value)) {
+    std::string lang;
+    if (!this->Makefile->CompileFeatureKnown(this->Target->GetName(), f.Value,
+                                             lang, nullptr)) {
       return false;
     }
+
+    std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
+    cmProp currentLanguageStandard = this->GetLanguageStandard(lang, config);
+
+    std::string newRequiredStandard;
+    if (!this->Makefile->GetNewRequiredStandard(
+          this->Target->GetName(), f.Value, currentLanguageStandard,
+          newRequiredStandard)) {
+      return false;
+    }
+
+    if (!newRequiredStandard.empty()) {
+      this->LanguageStandardMap[key] = newRequiredStandard;
+    }
   }
+
+  return true;
+}
+
+bool cmGeneratorTarget::ComputeCompileFeatures(
+  std::string const& config, std::set<LanguagePair> const& languagePairs) const
+{
+  for (const auto& language : languagePairs) {
+    cmProp generatorTargetLanguageStandard =
+      this->GetLanguageStandard(language.first, config);
+    if (!generatorTargetLanguageStandard) {
+      // If the standard isn't explicitly set we copy it over from the
+      // specified paired language.
+      std::string key =
+        cmStrCat(cmSystemTools::UpperCase(config), '-', language.first);
+      cmProp standardToCopy =
+        this->GetLanguageStandard(language.second, config);
+      if (standardToCopy != nullptr) {
+        this->LanguageStandardMap[key] = *standardToCopy;
+        generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
+      } else {
+        cmProp defaultStandard = this->Makefile->GetDef(
+          cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT"));
+        if (defaultStandard != nullptr) {
+          this->LanguageStandardMap[key] = *defaultStandard;
+          generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
+        }
+      }
+
+      // Custom updates for the CUDA standard.
+      if (generatorTargetLanguageStandard != nullptr &&
+          language.first == "CUDA") {
+        if (*generatorTargetLanguageStandard == "98") {
+          this->LanguageStandardMap[key] = "03";
+        }
+      }
+    }
+  }
+
   return true;
 }
 
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 3aedbf5..a71e64c 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -148,6 +148,13 @@
   bool HasExplicitObjectName(cmSourceFile const* file) const;
   void AddExplicitObjectName(cmSourceFile const* sf);
 
+  cmProp GetLanguageStandard(std::string const& lang,
+                             std::string const& config) const;
+
+  cmProp GetLanguageExtensions(std::string const& lang) const;
+
+  bool GetLanguageStandardRequired(std::string const& lang) const;
+
   void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&,
                                   const std::string& config) const;
   void GetExternalObjects(std::vector<cmSourceFile const*>&,
@@ -515,6 +522,11 @@
 
   bool ComputeCompileFeatures(std::string const& config) const;
 
+  using LanguagePair = std::pair<std::string, std::string>;
+  bool ComputeCompileFeatures(
+    std::string const& config,
+    std::set<LanguagePair> const& languagePairs) const;
+
   /**
    * Trace through the source files in this target and add al source files
    * that they depend on, used by all generators
@@ -1038,6 +1050,11 @@
   bool GetRPATH(const std::string& config, const std::string& prop,
                 std::string& rpath) const;
 
+  mutable std::map<std::string, std::string> LanguageStandardMap;
+
+  cmProp GetLanguageStandardProperty(std::string const& lang,
+                                     const char* suffix) const;
+
 public:
   const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
     const std::string& config) const;
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 811421a..38bffbf 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -14,6 +14,7 @@
 {
   if (args.size() < 3) {
     status.SetError("called with incorrect number of arguments");
+    cmSystemTools::SetFatalErrorOccured();
     return false;
   }
 
@@ -114,6 +115,7 @@
   } else {
     std::string err = "unknown component " + args[2];
     status.SetError(err);
+    cmSystemTools::SetFatalErrorOccured();
     return false;
   }
 
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 4dc4092..4b4ffda 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1442,12 +1442,10 @@
     localGen->AddHelperCommands();
   }
 
-  // Finalize the set of compile features for each target.
-  // FIXME: This turns into calls to cmMakefile::AddRequiredTargetFeature
-  // which actually modifies the <lang>_STANDARD target property
-  // on the original cmTarget instance.  It accumulates features
-  // across all configurations.  Some refactoring is needed to
-  // compute a per-config resulta purely during generation.
+  // Perform up-front computation in order to handle errors (such as unknown
+  // features) at this point. While processing the compile features we also
+  // calculate and cache the language standard required by the compile
+  // features.
   for (const auto& localGen : this->LocalGenerators) {
     if (!localGen->ComputeTargetCompileFeatures()) {
       return false;
@@ -1988,8 +1986,9 @@
   std::string makeCommandStr;
   output += "\nRun Build Command(s):";
 
-  for (auto command = makeCommand.begin(); command != makeCommand.end();
-       ++command) {
+  retVal = 0;
+  for (auto command = makeCommand.begin();
+       command != makeCommand.end() && retVal == 0; ++command) {
     makeCommandStr = command->Printable();
     if (command != makeCommand.end()) {
       makeCommandStr += " && ";
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index a5ce5d1..bb422eb 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -819,6 +819,14 @@
     default:
       break;
   }
+
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (sf->GetProperty("LANGUAGE")) {
+    this->CurrentLocalGenerator->AppendFeatureOptions(flags, lang,
+                                                      "EXPLICIT_LANGUAGE");
+  }
+
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
   if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
     lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
@@ -1144,23 +1152,24 @@
   }
 
   // organize the sources
-  std::vector<cmSourceFile*> classes;
-  if (!gtgt->GetConfigCommonSourceFiles(classes)) {
+  std::vector<cmSourceFile*> commonSourceFiles;
+  if (!gtgt->GetConfigCommonSourceFiles(commonSourceFiles)) {
     return false;
   }
 
   // Add CMakeLists.txt file for user convenience.
-  this->AddXCodeProjBuildRule(gtgt, classes);
+  this->AddXCodeProjBuildRule(gtgt, commonSourceFiles);
 
   // Add the Info.plist we are about to generate for an App Bundle.
   if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
     std::string plist = this->ComputeInfoPListLocation(gtgt);
     cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
       plist, true, cmSourceFileLocationKind::Known);
-    classes.push_back(sf);
+    commonSourceFiles.push_back(sf);
   }
 
-  std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
+  std::sort(commonSourceFiles.begin(), commonSourceFiles.end(),
+            cmSourceFilePathCompare());
 
   gtgt->ComputeObjectMapping();
 
@@ -1168,7 +1177,7 @@
   std::vector<cmXCodeObject*> headerFiles;
   std::vector<cmXCodeObject*> resourceFiles;
   std::vector<cmXCodeObject*> sourceFiles;
-  for (auto sourceFile : classes) {
+  for (auto sourceFile : commonSourceFiles) {
     cmXCodeObject* xsf = this->CreateXCodeSourceFile(
       this->CurrentLocalGenerator, sourceFile, gtgt);
     cmXCodeObject* fr = xsf->GetObject("fileRef");
@@ -1267,7 +1276,7 @@
     using mapOfVectorOfSourceFiles =
       std::map<std::string, std::vector<cmSourceFile*>>;
     mapOfVectorOfSourceFiles bundleFiles;
-    for (auto sourceFile : classes) {
+    for (auto sourceFile : commonSourceFiles) {
       cmGeneratorTarget::SourceFileFlags tsFlags =
         gtgt->GetTargetSourceFileFlags(sourceFile);
       if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent) {
@@ -1315,7 +1324,7 @@
     using mapOfVectorOfSourceFiles =
       std::map<std::string, std::vector<cmSourceFile*>>;
     mapOfVectorOfSourceFiles bundleFiles;
-    for (auto sourceFile : classes) {
+    for (auto sourceFile : commonSourceFiles) {
       cmGeneratorTarget::SourceFileFlags tsFlags =
         gtgt->GetTargetSourceFileFlags(sourceFile);
       if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeDeepResource) {
@@ -1345,22 +1354,20 @@
     }
   }
 
-  // create framework build phase
+  // always create framework build phase
   cmXCodeObject* frameworkBuildPhase = nullptr;
-  if (!externalObjFiles.empty()) {
-    frameworkBuildPhase =
-      this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
-    frameworkBuildPhase->SetComment("Frameworks");
-    frameworkBuildPhase->AddAttribute("buildActionMask",
-                                      this->CreateString("2147483647"));
-    buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
-    frameworkBuildPhase->AddAttribute("files", buildFiles);
-    for (auto& externalObjFile : externalObjFiles) {
-      buildFiles->AddObject(externalObjFile);
-    }
-    frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
-                                      this->CreateString("0"));
+  frameworkBuildPhase =
+    this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
+  frameworkBuildPhase->SetComment("Frameworks");
+  frameworkBuildPhase->AddAttribute("buildActionMask",
+                                    this->CreateString("2147483647"));
+  buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+  frameworkBuildPhase->AddAttribute("files", buildFiles);
+  for (auto& externalObjFile : externalObjFiles) {
+    buildFiles->AddObject(externalObjFile);
   }
+  frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+                                    this->CreateString("0"));
 
   // create list of build phases and create the Xcode target
   cmXCodeObject* buildPhases = this->CreateObject(cmXCodeObject::OBJECT_LIST);
@@ -2760,6 +2767,156 @@
     }
   }
 
+  // Separate libraries into ones that can be linked using "Link Binary With
+  // Libraries" build phase and the ones that can't. Only targets that build
+  // Apple bundles (.app, .framework, .bundle) can use this feature and only
+  // targets that represent actual libraries (static or dynamic, local or
+  // imported) not objects and not executables will be used. These are
+  // limitations imposed by CMake use-cases - otherwise a lot of things break.
+  // The rest will be linked using linker flags (OTHER_LDFLAGS setting in Xcode
+  // project).
+  std::map<std::string, std::vector<cmComputeLinkInformation::Item const*>>
+    configItemMap;
+  auto addToLinkerArguments =
+    [&configItemMap](const std::string& configName,
+                     cmComputeLinkInformation::Item const* libItemPtr) {
+      auto& linkVector = configItemMap[configName];
+      if (std::find_if(linkVector.begin(), linkVector.end(),
+                       [libItemPtr](cmComputeLinkInformation::Item const* p) {
+                         return p == libItemPtr;
+                       }) == linkVector.end()) {
+        linkVector.push_back(libItemPtr);
+      }
+    };
+  std::vector<cmComputeLinkInformation::Item const*> linkPhaseTargetVector;
+  std::map<std::string, std::vector<std::string>> targetConfigMap;
+  using ConfigItemPair =
+    std::pair<std::string, cmComputeLinkInformation::Item const*>;
+  std::map<std::string, std::vector<ConfigItemPair>> targetItemMap;
+  std::map<std::string, std::vector<std::string>> targetProductNameMap;
+  for (auto const& configName : this->CurrentConfigurationTypes) {
+    cmComputeLinkInformation* cli = gt->GetLinkInformation(configName);
+    if (!cli) {
+      continue;
+    }
+    for (auto const& libItem : cli->GetItems()) {
+      // TODO: Drop this check once we have option to add outside libraries to
+      // Xcode project
+      auto* libTarget = FindXCodeTarget(libItem.Target);
+      if (gt->IsBundleOnApple() &&
+          (gt->GetType() == cmStateEnums::EXECUTABLE ||
+           gt->GetType() == cmStateEnums::SHARED_LIBRARY ||
+           gt->GetType() == cmStateEnums::MODULE_LIBRARY ||
+           gt->GetType() == cmStateEnums::UNKNOWN_LIBRARY) &&
+          (libTarget && libItem.Target &&
+           (libItem.Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
+            libItem.Target->GetType() == cmStateEnums::SHARED_LIBRARY ||
+            libItem.Target->GetType() == cmStateEnums::MODULE_LIBRARY))) {
+        // Add unique configuration name to target-config map for later
+        // checks
+        std::string libName = libItem.Target->GetName();
+        auto& configVector = targetConfigMap[libName];
+        if (std::find(configVector.begin(), configVector.end(), configName) ==
+            configVector.end()) {
+          configVector.push_back(configName);
+        }
+        // Add a pair of config and item to target-item map
+        auto& itemVector = targetItemMap[libName];
+        itemVector.emplace_back(ConfigItemPair(configName, &libItem));
+        // Add product file-name to a lib-product map
+        auto productName = cmSystemTools::GetFilenameName(libItem.Value.Value);
+        auto& productVector = targetProductNameMap[libName];
+        if (std::find(productVector.begin(), productVector.end(),
+                      productName) == productVector.end()) {
+          productVector.push_back(productName);
+        }
+      } else {
+        // Add this library item to a regular linker flag list
+        addToLinkerArguments(configName, &libItem);
+      }
+    }
+  }
+
+  // Go through target library map and separate libraries that are linked
+  // in all configurations and produce only single product, from the rest.
+  // Only these will be linked through "Link Binary With Libraries" build
+  // phase.
+  for (auto const& targetLibConfigs : targetConfigMap) {
+    // Add this library to "Link Binary With Libraries" build phase if it's
+    // linked in all configurations and it has only one product name
+    auto& itemVector = targetItemMap[targetLibConfigs.first];
+    auto& productVector = targetProductNameMap[targetLibConfigs.first];
+    if (targetLibConfigs.second == this->CurrentConfigurationTypes &&
+        productVector.size() == 1) {
+      // Add this library to "Link Binary With Libraries" list
+      linkPhaseTargetVector.push_back(itemVector[0].second);
+    } else {
+      for (auto const& libItem : targetItemMap[targetLibConfigs.first]) {
+        // Add this library item to a regular linker flag list
+        addToLinkerArguments(libItem.first, libItem.second);
+      }
+    }
+  }
+
+  // Add libraries to "Link Binary With Libraries" build phase and collect
+  // their search paths. Xcode does not support per-configuration linking
+  // in this build phase so we don't have to do this for each configuration
+  // separately.
+  std::vector<std::string> linkSearchPaths;
+  for (auto const& libItem : linkPhaseTargetVector) {
+    // Add target output directory as a library search path
+    std::string linkDir = cmSystemTools::GetParentDirectory(
+      libItem->Target->GetLocationForBuild());
+    if (std::find(linkSearchPaths.begin(), linkSearchPaths.end(), linkDir) ==
+        linkSearchPaths.end()) {
+      linkSearchPaths.push_back(linkDir);
+    }
+    // Add target dependency
+    auto const& libName = *libItem;
+    if (!libName.Target->IsImported()) {
+      for (auto const& configName : this->CurrentConfigurationTypes) {
+        target->AddDependTarget(configName, libName.Target->GetName());
+      }
+    }
+    // Get the library target
+    auto* libTarget = FindXCodeTarget(libItem->Target);
+    if (!libTarget) {
+      continue;
+    }
+    // Add the target output file as a build reference for other targets
+    // to link against
+    auto* fileRefObject = libTarget->GetObject("productReference");
+    if (!fileRefObject) {
+      continue;
+    }
+    cmXCodeObject* buildFile;
+    auto it = FileRefToBuildFileMap.find(fileRefObject);
+    if (it == FileRefToBuildFileMap.end()) {
+      buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
+      buildFile->AddAttribute("fileRef", fileRefObject);
+      FileRefToBuildFileMap[fileRefObject] = buildFile;
+    } else {
+      buildFile = it->second;
+    }
+    // Add this reference to current target
+    auto* buildPhases = target->GetObject("buildPhases");
+    if (!buildPhases) {
+      continue;
+    }
+    auto* frameworkBuildPhase =
+      buildPhases->GetObject(cmXCodeObject::PBXFrameworksBuildPhase);
+    if (!frameworkBuildPhase) {
+      continue;
+    }
+    auto* buildFiles = frameworkBuildPhase->GetObject("files");
+    if (!buildFiles) {
+      continue;
+    }
+    if (!buildFiles->HasObject(buildFile)) {
+      buildFiles->AddObject(buildFile);
+    }
+  }
+
   // Loop over configuration types and set per-configuration info.
   for (auto const& configName : this->CurrentConfigurationTypes) {
     {
@@ -2787,21 +2944,20 @@
     }
 
     // Compute the link library and directory information.
-    cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
-    if (!pcli) {
+    cmComputeLinkInformation* cli = gt->GetLinkInformation(configName);
+    if (!cli) {
       continue;
     }
-    cmComputeLinkInformation& cli = *pcli;
 
     // Add dependencies directly on library files.
-    for (auto const& libDep : cli.GetDepends()) {
+    for (auto const& libDep : cli->GetDepends()) {
       target->AddDependLibrary(configName, libDep);
     }
 
     // add the library search paths
     {
       std::string linkDirs;
-      for (auto const& libDir : cli.GetDirectories()) {
+      for (auto const& libDir : cli->GetDirectories()) {
         if (!libDir.empty() && libDir != "/usr/lib") {
           // Now add the same one but append
           // $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) to it:
@@ -2812,15 +2968,22 @@
           linkDirs += this->XCodeEscapePath(libDir);
         }
       }
+      // Add previously collected paths where to look for libraries
+      // that were added to "Link Binary With Libraries"
+      for (auto& linkDir : linkSearchPaths) {
+        linkDirs += " ";
+        linkDirs += this->XCodeEscapePath(linkDir);
+      }
       this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
                                         linkDirs.c_str(), configName);
     }
 
-    // now add the link libraries
+    // now add the left-over link libraries
     {
       std::string linkLibs;
       const char* sep = "";
-      for (auto const& libName : cli.GetItems()) {
+      for (auto const& libItem : configItemMap[configName]) {
+        auto const& libName = *libItem;
         linkLibs += sep;
         sep = " ";
         if (libName.IsPath) {
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index e380f1c..0fc6558 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -28,7 +28,7 @@
 /** \class cmGlobalXCodeGenerator
  * \brief Write a Unix makefiles.
  *
- * cmGlobalXCodeGenerator manages UNIX build process for a tree
+ * cmGlobalXCodeGenerator manages Xcode build process for a tree
  */
 class cmGlobalXCodeGenerator : public cmGlobalGenerator
 {
@@ -295,6 +295,7 @@
   std::map<std::string, cmXCodeObject*> TargetGroup;
   std::map<std::string, cmXCodeObject*> FileRefs;
   std::map<cmGeneratorTarget const*, cmXCodeObject*> XCodeObjectMap;
+  std::map<cmXCodeObject*, cmXCodeObject*> FileRefToBuildFileMap;
   std::vector<std::string> Architectures;
   std::string ObjectDirArchDefault;
   std::string ObjectDirArch;
diff --git a/Source/cmLinkItemGraphVisitor.cxx b/Source/cmLinkItemGraphVisitor.cxx
index acc23c8..b13def8 100644
--- a/Source/cmLinkItemGraphVisitor.cxx
+++ b/Source/cmLinkItemGraphVisitor.cxx
@@ -24,10 +24,6 @@
 void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
                                         cmLinkItem const& rootItem)
 {
-  if (this->LinkVisited(item, rootItem)) {
-    return;
-  }
-
   if (item.Target == nullptr) {
     return;
   }
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 3b3f110..95caa30 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -803,39 +803,8 @@
     // Now that C/C++ _STANDARD values have been computed
     // set the values to ObjC/ObjCXX _STANDARD variables
     if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-      auto copyStandardToObjLang = [&](LanguagePair const& lang) -> bool {
-        if (!target->GetProperty(cmStrCat(lang.first, "_STANDARD"))) {
-          cmProp standard =
-            target->GetProperty(cmStrCat(lang.second, "_STANDARD"));
-          if (!standard) {
-            standard = this->Makefile->GetDef(
-              cmStrCat("CMAKE_", lang.second, "_STANDARD_DEFAULT"));
-          }
-          target->Target->SetProperty(cmStrCat(lang.first, "_STANDARD"),
-                                      standard ? standard->c_str() : nullptr);
-          return true;
-        }
-        return false;
-      };
-      auto copyPropertyToObjLang = [&](LanguagePair const& lang,
-                                       const char* property) {
-        if (!target->GetProperty(cmStrCat(lang.first, property)) &&
-            target->GetProperty(cmStrCat(lang.second, property))) {
-          cmProp p = target->GetProperty(cmStrCat(lang.second, property));
-          target->Target->SetProperty(cmStrCat(lang.first, property),
-                                      p ? p->c_str() : nullptr);
-        }
-      };
-      for (auto const& lang : pairedLanguages) {
-        if (copyStandardToObjLang(lang)) {
-          copyPropertyToObjLang(lang, "_STANDARD_REQUIRED");
-          copyPropertyToObjLang(lang, "_EXTENSIONS");
-        }
-      }
-      if (cmProp standard = target->GetProperty("CUDA_STANDARD")) {
-        if (*standard == "98") {
-          target->Target->SetProperty("CUDA_STANDARD", "03");
-        }
+      for (std::string const& c : configNames) {
+        target->ComputeCompileFeatures(c, inferredEnabledLanguages);
       }
     }
   }
@@ -1026,7 +995,7 @@
   }
 
   for (auto const& it : target->GetMaxLanguageStandards()) {
-    cmProp standard = target->GetProperty(it.first + "_STANDARD");
+    cmProp standard = target->GetLanguageStandard(it.first, config);
     if (!standard) {
       continue;
     }
@@ -1050,7 +1019,7 @@
   }
 
   std::string compReqFlag;
-  this->AddCompilerRequirementFlag(compReqFlag, target, lang);
+  this->AddCompilerRequirementFlag(compReqFlag, target, lang, config);
   if (!compReqFlag.empty()) {
     flags.emplace_back(std::move(compReqFlag));
   }
@@ -2046,7 +2015,7 @@
     // when linking in order to use the matching standard library.
     // FIXME: If CMake gains an abstraction for standard library
     // selection, this will have to be reconciled with it.
-    this->AddCompilerRequirementFlag(flags, target, lang);
+    this->AddCompilerRequirementFlag(flags, target, lang, config);
   }
 
   this->AddLanguageFlags(flags, target, lang, config);
@@ -2189,7 +2158,8 @@
 }
 
 void cmLocalGenerator::AddCompilerRequirementFlag(
-  std::string& flags, cmGeneratorTarget const* target, const std::string& lang)
+  std::string& flags, cmGeneratorTarget const* target, const std::string& lang,
+  const std::string& config)
 {
   if (lang.empty()) {
     return;
@@ -2200,15 +2170,13 @@
     // This compiler has no notion of language standard levels.
     return;
   }
-  std::string extProp = lang + "_EXTENSIONS";
   bool ext = true;
-  if (cmProp extPropValue = target->GetProperty(extProp)) {
+  if (cmProp extPropValue = target->GetLanguageExtensions(lang)) {
     if (cmIsOff(*extPropValue)) {
       ext = false;
     }
   }
-  std::string stdProp = lang + "_STANDARD";
-  cmProp standardProp = target->GetProperty(stdProp);
+  cmProp standardProp = target->GetLanguageStandard(lang, config);
   if (!standardProp) {
     if (ext) {
       // No language standard is specified and extensions are not disabled.
@@ -2228,7 +2196,7 @@
 
   std::string const type = ext ? "EXTENSION" : "STANDARD";
 
-  if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED")) {
+  if (target->GetLanguageStandardRequired(lang)) {
     std::string option_flag =
       "CMAKE_" + lang + *standardProp + "_" + type + "_COMPILE_OPTION";
 
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index f2d9145..f4781d6 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -123,7 +123,8 @@
                               const std::string& config);
   void AddCompilerRequirementFlag(std::string& flags,
                                   cmGeneratorTarget const* target,
-                                  const std::string& lang);
+                                  const std::string& lang,
+                                  const std::string& config);
   //! Append flags to a string.
   virtual void AppendFlags(std::string& flags,
                            const std::string& newFlags) const;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index c78b751..1f1c06a 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -39,6 +39,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionEvaluationFile.h"
+#include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
 #include "cmInstallGenerator.h" // IWYU pragma: keep
 #include "cmInstallSubdirectoryGenerator.h"
@@ -4027,6 +4028,8 @@
 
   if (copyonly) {
     if (!cmSystemTools::CopyFileIfDifferent(sinfile, soutfile)) {
+      this->IssueMessage(MessageType::FATAL_ERROR,
+                         cmSystemTools::GetLastSystemError());
       return 0;
     }
   } else {
@@ -4077,9 +4080,15 @@
     fin.close();
     fout.close();
     if (!cmSystemTools::CopyFileIfDifferent(tempOutputFile, soutfile)) {
+      this->IssueMessage(MessageType::FATAL_ERROR,
+                         cmSystemTools::GetLastSystemError());
       res = 0;
     } else {
-      cmSystemTools::SetPermissions(soutfile, perm);
+      if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+        this->IssueMessage(MessageType::FATAL_ERROR,
+                           cmSystemTools::GetLastSystemError());
+        res = 0;
+      }
     }
     cmSystemTools::RemoveFile(tempOutputFile);
   }
@@ -4554,7 +4563,7 @@
 
   // Deprecate old policies, especially those that require a lot
   // of code to maintain the old behavior.
-  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0071 &&
+  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0072 &&
       !(this->GetCMakeInstance()->GetIsInTryCompile() &&
         (
           // Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4673,7 +4682,33 @@
   }
 
   std::string lang;
-  if (!this->CompileFeatureKnown(target, feature, lang, error)) {
+  if (!this->CheckCompileFeaturesAvailable(target->GetName(), feature, lang,
+                                           error)) {
+    return false;
+  }
+
+  target->AppendProperty("COMPILE_FEATURES", feature);
+
+  // FIXME: Add a policy to avoid updating the <LANG>_STANDARD target
+  // property due to COMPILE_FEATURES.  The language standard selection
+  // should be done purely at generate time based on whatever the project
+  // code put in these properties explicitly.  That is mostly true now,
+  // but for compatibility we need to continue updating the property here.
+  if (lang == "C" || lang == "OBJC") {
+    return this->AddRequiredTargetCFeature(target, feature, lang, error);
+  }
+  if (lang == "CUDA") {
+    return this->AddRequiredTargetCudaFeature(target, feature, lang, error);
+  }
+  return this->AddRequiredTargetCxxFeature(target, feature, lang, error);
+}
+
+bool cmMakefile::CheckCompileFeaturesAvailable(const std::string& targetName,
+                                               const std::string& feature,
+                                               std::string& lang,
+                                               std::string* error) const
+{
+  if (!this->CompileFeatureKnown(targetName, feature, lang, error)) {
     return false;
   }
 
@@ -4699,18 +4734,10 @@
     return false;
   }
 
-  target->AppendProperty("COMPILE_FEATURES", feature);
-
-  if (lang == "C" || lang == "OBJC") {
-    return this->AddRequiredTargetCFeature(target, feature, lang, error);
-  }
-  if (lang == "CUDA") {
-    return this->AddRequiredTargetCudaFeature(target, feature, lang, error);
-  }
-  return this->AddRequiredTargetCxxFeature(target, feature, lang, error);
+  return true;
 }
 
-bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
+bool cmMakefile::CompileFeatureKnown(const std::string& targetName,
                                      const std::string& feature,
                                      std::string& lang,
                                      std::string* error) const
@@ -4747,7 +4774,7 @@
   e << " unknown feature \"" << feature
     << "\" for "
        "target \""
-    << target->GetName() << "\".";
+    << targetName << "\".";
   if (error) {
     *error = e.str();
   } else {
@@ -4802,22 +4829,50 @@
   return featuresKnown;
 }
 
-bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
+bool cmMakefile::GetNewRequiredStandard(const std::string& targetName,
+                                        const std::string& feature,
+                                        cmProp currentLangStandardValue,
+                                        std::string& newRequiredStandard,
+                                        std::string* error) const
+{
+  std::string lang;
+  if (!this->CheckCompileFeaturesAvailable(targetName, feature, lang, error)) {
+    return false;
+  }
+
+  if (lang == "C" || lang == "OBJC") {
+    return this->GetNewRequiredCStandard(targetName, feature, lang,
+                                         currentLangStandardValue,
+                                         newRequiredStandard, error);
+  }
+  if (lang == "CUDA") {
+    return this->GetNewRequiredCudaStandard(targetName, feature, lang,
+                                            currentLangStandardValue,
+                                            newRequiredStandard, error);
+  }
+  return this->GetNewRequiredCxxStandard(targetName, feature, lang,
+                                         currentLangStandardValue,
+                                         newRequiredStandard, error);
+}
+
+bool cmMakefile::HaveStandardAvailable(cmGeneratorTarget const* target,
                                        std::string const& lang,
+                                       std::string const& config,
                                        const std::string& feature) const
 {
   if (lang == "C" || lang == "OBJC") {
-    return this->HaveCStandardAvailable(target, feature, lang);
+    return this->HaveCStandardAvailable(target, lang, config, feature);
   }
   if (lang == "CUDA") {
-    return this->HaveCudaStandardAvailable(target, feature, lang);
+    return this->HaveCudaStandardAvailable(target, lang, config, feature);
   }
-  return this->HaveCxxStandardAvailable(target, feature, lang);
+  return this->HaveCxxStandardAvailable(target, lang, config, feature);
 }
 
-bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
-                                        const std::string& feature,
-                                        std::string const& lang) const
+bool cmMakefile::HaveCStandardAvailable(cmGeneratorTarget const* target,
+                                        std::string const& lang,
+                                        std::string const& config,
+                                        const std::string& feature) const
 {
   cmProp defaultCStandard =
     this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -4846,7 +4901,7 @@
 
   this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
 
-  cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
+  cmProp existingCStandard = target->GetLanguageStandard(lang, config);
   if (!existingCStandard) {
     existingCStandard = defaultCStandard;
   }
@@ -4909,9 +4964,10 @@
     cm::cend(CXX_STANDARDS);
 }
 
-bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
-                                          const std::string& feature,
-                                          std::string const& lang) const
+bool cmMakefile::HaveCxxStandardAvailable(cmGeneratorTarget const* target,
+                                          std::string const& lang,
+                                          std::string const& config,
+                                          const std::string& feature) const
 {
   cmProp defaultCxxStandard =
     this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -4941,8 +4997,7 @@
   this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
                                needCxx17, needCxx20);
 
-  cmProp existingCxxStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
+  cmProp existingCxxStandard = target->GetLanguageStandard(lang, config);
   if (!existingCxxStandard) {
     existingCxxStandard = defaultCxxStandard;
   }
@@ -5009,6 +5064,29 @@
                                              std::string const& lang,
                                              std::string* error) const
 {
+  std::string newRequiredStandard;
+  if (this->GetNewRequiredCxxStandard(
+        target->GetName(), feature, lang,
+        target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
+        error)) {
+    if (!newRequiredStandard.empty()) {
+      target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard);
+    }
+    return true;
+  }
+
+  return false;
+}
+
+bool cmMakefile::GetNewRequiredCxxStandard(const std::string& targetName,
+                                           const std::string& feature,
+                                           std::string const& lang,
+                                           cmProp currentLangStandardValue,
+                                           std::string& newRequiredStandard,
+                                           std::string* error) const
+{
+  newRequiredStandard.clear();
+
   bool needCxx98 = false;
   bool needCxx11 = false;
   bool needCxx14 = false;
@@ -5018,8 +5096,7 @@
   this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
                                needCxx17, needCxx20);
 
-  cmProp existingCxxStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
+  cmProp existingCxxStandard = currentLangStandardValue;
   if (existingCxxStandard == nullptr) {
     cmProp defaultCxxStandard =
       this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -5034,7 +5111,7 @@
                    cmStrCmp(*existingCxxStandard));
     if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
       const std::string e = cmStrCat(
-        "The ", lang, "_STANDARD property on target \"", target->GetName(),
+        "The ", lang, "_STANDARD property on target \"", targetName,
         "\" contained an invalid value: \"", *existingCxxStandard, "\".");
       if (error) {
         *error = e;
@@ -5060,16 +5137,17 @@
     // Ensure the C++ language level is high enough to support
     // the needed C++ features.
     if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
-      target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel);
+      newRequiredStandard = *needCxxLevel;
     }
   }
 
   return true;
 }
 
-bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
-                                           const std::string& feature,
-                                           std::string const& lang) const
+bool cmMakefile::HaveCudaStandardAvailable(cmGeneratorTarget const* target,
+                                           std::string const& lang,
+                                           std::string const& config,
+                                           const std::string& feature) const
 {
   cmProp defaultCudaStandard =
     this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -5100,8 +5178,7 @@
   this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
                                 needCuda14, needCuda17, needCuda20);
 
-  cmProp existingCudaStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
+  cmProp existingCudaStandard = target->GetLanguageStandard(lang, config);
   if (!existingCudaStandard) {
     existingCudaStandard = defaultCudaStandard;
   }
@@ -5168,6 +5245,28 @@
                                               std::string const& lang,
                                               std::string* error) const
 {
+  std::string newRequiredStandard;
+  if (this->GetNewRequiredCudaStandard(
+        target->GetName(), feature, lang,
+        target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
+        error)) {
+    if (!newRequiredStandard.empty()) {
+      target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard);
+    }
+    return true;
+  }
+  return false;
+}
+
+bool cmMakefile::GetNewRequiredCudaStandard(const std::string& targetName,
+                                            const std::string& feature,
+                                            std::string const& lang,
+                                            cmProp currentLangStandardValue,
+                                            std::string& newRequiredStandard,
+                                            std::string* error) const
+{
+  newRequiredStandard.clear();
+
   bool needCuda03 = false;
   bool needCuda11 = false;
   bool needCuda14 = false;
@@ -5177,8 +5276,7 @@
   this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
                                 needCuda14, needCuda17, needCuda20);
 
-  cmProp existingCudaStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
+  cmProp existingCudaStandard = currentLangStandardValue;
   if (existingCudaStandard == nullptr) {
     cmProp defaultCudaStandard =
       this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -5193,7 +5291,7 @@
                    cmStrCmp(*existingCudaStandard));
     if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
       const std::string e = cmStrCat(
-        "The ", lang, "_STANDARD property on target \"", target->GetName(),
+        "The ", lang, "_STANDARD property on target \"", targetName,
         "\" contained an invalid value: \"", *existingCudaStandard, "\".");
       if (error) {
         *error = e;
@@ -5219,7 +5317,7 @@
     // Ensure the CUDA language level is high enough to support
     // the needed CUDA features.
     if (!existingCudaLevel || existingCudaLevel < needCudaLevel) {
-      target->SetProperty("CUDA_STANDARD", *needCudaLevel);
+      newRequiredStandard = *needCudaLevel;
     }
   }
 
@@ -5252,13 +5350,36 @@
                                            std::string const& lang,
                                            std::string* error) const
 {
+  std::string newRequiredStandard;
+  if (this->GetNewRequiredCStandard(
+        target->GetName(), feature, lang,
+        target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
+        error)) {
+    if (!newRequiredStandard.empty()) {
+      target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard);
+    }
+    return true;
+  }
+
+  return false;
+}
+
+bool cmMakefile::GetNewRequiredCStandard(const std::string& targetName,
+                                         const std::string& feature,
+                                         std::string const& lang,
+                                         cmProp currentLangStandardValue,
+                                         std::string& newRequiredStandard,
+                                         std::string* error) const
+{
+  newRequiredStandard.clear();
+
   bool needC90 = false;
   bool needC99 = false;
   bool needC11 = false;
 
   this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
 
-  cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
+  cmProp existingCStandard = currentLangStandardValue;
   if (existingCStandard == nullptr) {
     cmProp defaultCStandard =
       this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -5270,7 +5391,7 @@
     if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
                      cmStrCmp(*existingCStandard)) == cm::cend(C_STANDARDS)) {
       const std::string e = cmStrCat(
-        "The ", lang, "_STANDARD property on target \"", target->GetName(),
+        "The ", lang, "_STANDARD property on target \"", targetName,
         "\" contained an invalid value: \"", *existingCStandard, "\".");
       if (error) {
         *error = e;
@@ -5307,11 +5428,11 @@
   }
 
   if (setC11) {
-    target->SetProperty(cmStrCat(lang, "_STANDARD"), "11");
+    newRequiredStandard = "11";
   } else if (setC99) {
-    target->SetProperty(cmStrCat(lang, "_STANDARD"), "99");
+    newRequiredStandard = "99";
   } else if (setC90) {
-    target->SetProperty(cmStrCat(lang, "_STANDARD"), "90");
+    newRequiredStandard = "90";
   }
   return true;
 }
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 45d7109..332554e 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -47,6 +47,7 @@
 class cmExportBuildFileGenerator;
 class cmFunctionBlocker;
 class cmGeneratorExpressionEvaluationFile;
+class cmGeneratorTarget;
 class cmGlobalGenerator;
 class cmImplicitDependsList;
 class cmInstallGenerator;
@@ -928,13 +929,22 @@
   bool AddRequiredTargetFeature(cmTarget* target, const std::string& feature,
                                 std::string* error = nullptr) const;
 
-  bool CompileFeatureKnown(cmTarget const* target, const std::string& feature,
-                           std::string& lang, std::string* error) const;
+  bool CompileFeatureKnown(const std::string& targetName,
+                           const std::string& feature, std::string& lang,
+                           std::string* error) const;
 
   const char* CompileFeaturesAvailable(const std::string& lang,
                                        std::string* error) const;
 
-  bool HaveStandardAvailable(cmTarget const* target, std::string const& lang,
+  bool GetNewRequiredStandard(const std::string& targetName,
+                              const std::string& feature,
+                              cmProp currentLangStandardValue,
+                              std::string& newRequiredStandard,
+                              std::string* error = nullptr) const;
+
+  bool HaveStandardAvailable(cmGeneratorTarget const* target,
+                             std::string const& lang,
+                             std::string const& config,
                              const std::string& feature) const;
 
   bool IsLaterStandard(std::string const& lang, std::string const& lhs,
@@ -1174,6 +1184,11 @@
                                     std::string const& lang,
                                     std::string* error = nullptr) const;
 
+  bool CheckCompileFeaturesAvailable(const std::string& targetName,
+                                     const std::string& feature,
+                                     std::string& lang,
+                                     std::string* error) const;
+
   void CheckNeededCLanguage(const std::string& feature,
                             std::string const& lang, bool& needC90,
                             bool& needC99, bool& needC11) const;
@@ -1186,15 +1201,37 @@
                                bool& needCuda11, bool& needCuda14,
                                bool& needCuda17, bool& needCuda20) const;
 
-  bool HaveCStandardAvailable(cmTarget const* target,
-                              const std::string& feature,
-                              std::string const& lang) const;
-  bool HaveCxxStandardAvailable(cmTarget const* target,
-                                const std::string& feature,
-                                std::string const& lang) const;
-  bool HaveCudaStandardAvailable(cmTarget const* target,
+  bool GetNewRequiredCStandard(const std::string& targetName,
+                               const std::string& feature,
+                               std::string const& lang,
+                               cmProp currentLangStandardValue,
+                               std::string& newRequiredStandard,
+                               std::string* error = nullptr) const;
+  bool GetNewRequiredCxxStandard(const std::string& targetName,
                                  const std::string& feature,
-                                 std::string const& lang) const;
+                                 std::string const& lang,
+                                 cmProp currentLangStandardValue,
+                                 std::string& newRequiredStandard,
+                                 std::string* error = nullptr) const;
+  bool GetNewRequiredCudaStandard(const std::string& targetName,
+                                  const std::string& feature,
+                                  std::string const& lang,
+                                  cmProp currentLangStandardValue,
+                                  std::string& newRequiredStandard,
+                                  std::string* error = nullptr) const;
+
+  bool HaveCStandardAvailable(cmGeneratorTarget const* target,
+                              std::string const& lang,
+                              std::string const& config,
+                              const std::string& feature) const;
+  bool HaveCxxStandardAvailable(cmGeneratorTarget const* target,
+                                std::string const& lang,
+                                std::string const& config,
+                                const std::string& feature) const;
+  bool HaveCudaStandardAvailable(cmGeneratorTarget const* target,
+                                 std::string const& lang,
+                                 std::string const& config,
+                                 const std::string& feature) const;
 
   void CheckForUnusedVariables() const;
 
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 8396fa3..6887569 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -532,6 +532,13 @@
   // Build the set of compiler flags.
   std::string flags;
 
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (source.GetProperty("LANGUAGE")) {
+    this->LocalGenerator->AppendFeatureOptions(flags, lang,
+                                               "EXPLICIT_LANGUAGE");
+  }
+
   // Add language-specific flags.
   std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
   this->LocalGenerator->AppendFlags(flags, langFlags);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index d406c99..0c7591a 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -188,7 +188,16 @@
     }
   }
 
-  std::string flags = this->GetFlags(language, config, filterArch);
+  std::string flags;
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (source->GetProperty("LANGUAGE")) {
+    this->LocalGenerator->AppendFeatureOptions(flags, language,
+                                               "EXPLICIT_LANGUAGE");
+    flags += " ";
+  }
+
+  flags += this->GetFlags(language, config, filterArch);
 
   // Add Fortran format flags.
   if (language == "Fortran") {
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a82f421..49dadc7 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -320,7 +320,10 @@
   SELECT(POLICY, CMP0107, "An ALIAS target cannot overwrite another target.", \
          3, 18, 0, cmPolicies::WARN)                                          \
   SELECT(POLICY, CMP0108, "A target cannot link to itself through an alias.", \
-         3, 18, 0, cmPolicies::WARN)
+         3, 18, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0109,                                                     \
+         "find_program() requires permission to execute but not to read.", 3, \
+         19, 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 511a018..e733a3e 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -789,9 +789,9 @@
 
       // Register files that will be scanned by moc or uic
       if (this->MocOrUicEnabled()) {
-        if (cm->IsHeaderExtension(extLower)) {
+        if (cm->IsAHeaderExtension(extLower)) {
           addMUHeader(makeMUFile(sf, fullPath, true), extLower);
-        } else if (cm->IsSourceExtension(extLower)) {
+        } else if (cm->IsACLikeSourceExtension(extLower)) {
           addMUSource(makeMUFile(sf, fullPath, true));
         }
       }
@@ -895,14 +895,14 @@
       std::string const& extLower =
         cmSystemTools::LowerCase(sf->GetExtension());
 
-      if (cm->IsHeaderExtension(extLower)) {
+      if (cm->IsAHeaderExtension(extLower)) {
         if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
           auto muf = makeMUFile(sf.get(), fullPath, false);
           if (muf->SkipMoc || muf->SkipUic) {
             addMUHeader(std::move(muf), extLower);
           }
         }
-      } else if (cm->IsSourceExtension(extLower)) {
+      } else if (cm->IsACLikeSourceExtension(extLower)) {
         if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
           auto muf = makeMUFile(sf.get(), fullPath, false);
           if (muf->SkipMoc || muf->SkipUic) {
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index f525439..781ddbc 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSourceFile.h"
 
-#include <array>
 #include <utility>
 
 #include "cmGlobalGenerator.h"
@@ -130,13 +129,11 @@
   // Location path
   std::string const& lPath = this->Location.GetFullPath();
   // List of extension lists
-  std::array<std::vector<std::string> const*, 2> const extsLists = {
-    { &makefile->GetCMakeInstance()->GetSourceExtensions(),
-      &makefile->GetCMakeInstance()->GetHeaderExtensions() }
-  };
+  std::vector<std::string> exts =
+    makefile->GetCMakeInstance()->GetAllExtensions();
 
   // Tries to find the file in a given directory
-  auto findInDir = [this, &extsLists, &lPath](std::string const& dir) -> bool {
+  auto findInDir = [this, &exts, &lPath](std::string const& dir) -> bool {
     // Compute full path
     std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir);
     // Try full path
@@ -145,14 +142,12 @@
       return true;
     }
     // Try full path with extension
-    for (auto& exts : extsLists) {
-      for (std::string const& ext : *exts) {
-        if (!ext.empty()) {
-          std::string extPath = cmStrCat(fullPath, '.', ext);
-          if (cmSystemTools::FileExists(extPath)) {
-            this->FullPath = extPath;
-            return true;
-          }
+    for (std::string const& ext : exts) {
+      if (!ext.empty()) {
+        std::string extPath = cmStrCat(fullPath, '.', ext);
+        if (cmSystemTools::FileExists(extPath)) {
+          this->FullPath = extPath;
+          return true;
         }
       }
     }
@@ -175,11 +170,9 @@
   // Compose error
   std::string err =
     cmStrCat("Cannot find source file:\n  ", lPath, "\nTried extensions");
-  for (auto exts : extsLists) {
-    for (std::string const& ext : *exts) {
-      err += " .";
-      err += ext;
-    }
+  for (std::string const& ext : exts) {
+    err += " .";
+    err += ext;
   }
   if (error != nullptr) {
     *error = std::move(err);
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index e852c05..222bafa 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -101,7 +101,7 @@
   cmMakefile const* mf = this->Makefile;
   auto cm = mf->GetCMakeInstance();
   if (!gg->GetLanguageFromExtension(ext.c_str()).empty() ||
-      cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext)) {
+      cm->IsAKnownExtension(ext)) {
     // This is a known extension.  Use the given filename with extension.
     this->Name = cmSystemTools::GetFilenameName(name);
     this->AmbiguousExtension = false;
@@ -157,7 +157,7 @@
   auto ext = cm::string_view(this->Name).substr(loc.Name.size() + 1);
   cmMakefile const* mf = this->Makefile;
   auto cm = mf->GetCMakeInstance();
-  return cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext);
+  return cm->IsAKnownExtension(ext);
 }
 
 bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 162e807..27ecb4d 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -64,10 +64,6 @@
 #  include "cmVariableWatch.h"
 #endif
 
-#if !defined(CMAKE_BOOTSTRAP)
-#  define CMAKE_USE_ECLIPSE
-#endif
-
 #if defined(__MINGW32__) && defined(CMAKE_BOOTSTRAP)
 #  define CMAKE_BOOT_MINGW
 #endif
@@ -101,16 +97,13 @@
 #if !defined(CMAKE_BOOTSTRAP)
 #  include "cmGlobalNinjaGenerator.h"
 #endif
-#include "cmExtraCodeLiteGenerator.h"
 
-#if !defined(CMAKE_BOOT_MINGW)
+#if !defined(CMAKE_BOOTSTRAP)
 #  include "cmExtraCodeBlocksGenerator.h"
-#endif
-#include "cmExtraKateGenerator.h"
-#include "cmExtraSublimeTextGenerator.h"
-
-#ifdef CMAKE_USE_ECLIPSE
+#  include "cmExtraCodeLiteGenerator.h"
 #  include "cmExtraEclipseCDT4Generator.h"
+#  include "cmExtraKateGenerator.h"
+#  include "cmExtraSublimeTextGenerator.h"
 #endif
 
 #if defined(__linux__) || defined(_WIN32)
@@ -201,7 +194,7 @@
     };
 
     // The "c" extension MUST precede the "C" extension.
-    setupExts(this->SourceFileExtensions,
+    setupExts(this->CLikeSourceFileExtensions,
               { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" });
     setupExts(this->HeaderFileExtensions,
               { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" });
@@ -1137,13 +1130,9 @@
 #if !defined(CMAKE_BOOTSTRAP)
   this->ExtraGenerators.push_back(cmExtraCodeBlocksGenerator::GetFactory());
   this->ExtraGenerators.push_back(cmExtraCodeLiteGenerator::GetFactory());
-  this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
-  this->ExtraGenerators.push_back(cmExtraKateGenerator::GetFactory());
-
-#  ifdef CMAKE_USE_ECLIPSE
   this->ExtraGenerators.push_back(cmExtraEclipseCDT4Generator::GetFactory());
-#  endif
-
+  this->ExtraGenerators.push_back(cmExtraKateGenerator::GetFactory());
+  this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
 #endif
 }
 
@@ -1970,6 +1959,17 @@
                                  backtrace);
 }
 
+std::vector<std::string> cmake::GetAllExtensions() const
+{
+  std::vector<std::string> allExt = this->CLikeSourceFileExtensions.ordered;
+  allExt.insert(allExt.end(), this->HeaderFileExtensions.ordered.begin(),
+                this->HeaderFileExtensions.ordered.end());
+  // cuda extensions are also in SourceFileExtensions so we ignore it here
+  allExt.insert(allExt.end(), this->FortranFileExtensions.ordered.begin(),
+                this->FortranFileExtensions.ordered.end());
+  return allExt;
+}
+
 std::string cmake::StripExtension(const std::string& file) const
 {
   auto dotpos = file.rfind('.');
@@ -1979,7 +1979,7 @@
 #else
     auto ext = cm::string_view(file).substr(dotpos + 1);
 #endif
-    if (this->IsSourceExtension(ext) || this->IsHeaderExtension(ext)) {
+    if (this->IsAKnownExtension(ext)) {
       return file.substr(0, dotpos);
     }
   }
diff --git a/Source/cmake.h b/Source/cmake.h
index 086ec87..c5d608f 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -264,46 +264,35 @@
     this->GeneratorToolsetSet = true;
   }
 
-  const std::vector<std::string>& GetSourceExtensions() const
+  bool IsAKnownSourceExtension(cm::string_view ext) const
   {
-    return this->SourceFileExtensions.ordered;
+    return this->CLikeSourceFileExtensions.Test(ext) ||
+      this->CudaFileExtensions.Test(ext) ||
+      this->FortranFileExtensions.Test(ext);
   }
 
-  bool IsSourceExtension(cm::string_view ext) const
+  bool IsACLikeSourceExtension(cm::string_view ext) const
   {
-    return this->SourceFileExtensions.Test(ext);
+    return this->CLikeSourceFileExtensions.Test(ext);
   }
 
+  bool IsAKnownExtension(cm::string_view ext) const
+  {
+    return this->IsAKnownSourceExtension(ext) || this->IsAHeaderExtension(ext);
+  }
+
+  std::vector<std::string> GetAllExtensions() const;
+
   const std::vector<std::string>& GetHeaderExtensions() const
   {
     return this->HeaderFileExtensions.ordered;
   }
 
-  bool IsHeaderExtension(cm::string_view ext) const
+  bool IsAHeaderExtension(cm::string_view ext) const
   {
     return this->HeaderFileExtensions.Test(ext);
   }
 
-  const std::vector<std::string>& GetCudaExtensions() const
-  {
-    return this->CudaFileExtensions.ordered;
-  }
-
-  bool IsCudaExtension(cm::string_view ext) const
-  {
-    return this->CudaFileExtensions.Test(ext);
-  }
-
-  const std::vector<std::string>& GetFortranExtensions() const
-  {
-    return this->FortranFileExtensions.ordered;
-  }
-
-  bool IsFortranExtension(cm::string_view ext) const
-  {
-    return this->FortranFileExtensions.Test(ext);
-  }
-
   // Strips the extension (if present and known) from a filename
   std::string StripExtension(const std::string& file) const;
 
@@ -628,7 +617,7 @@
   std::string CheckStampList;
   std::string VSSolutionFile;
   std::string EnvironmentGenerator;
-  FileExtensions SourceFileExtensions;
+  FileExtensions CLikeSourceFileExtensions;
   FileExtensions HeaderFileExtensions;
   FileExtensions CudaFileExtensions;
   FileExtensions FortranFileExtensions;
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index de76d73..6882fdd 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -582,12 +582,10 @@
         filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
       } else {
         ::CMakeCommandUsage(args[0].c_str());
-        return 1;
+        return 2;
       }
 
       if (filesDiffer) {
-        std::cerr << "Files \"" << args[args.size() - 2] << "\" to \""
-                  << args[args.size() - 1] << "\" are different.\n";
         return 1;
       }
       return 0;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index db6dbf3..1c88cd5 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -697,38 +697,28 @@
   # build the "Simple" test with the ExtraGenerators, if available
   # This doesn't test whether the generated project files work (unfortunately),
   # mainly it tests that cmake doesn't crash when generating these project files.
-  if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles" OR ${CMAKE_GENERATOR} MATCHES "Ninja")
-
-    # check which generators we have
-    execute_process(COMMAND ${CMAKE_CMAKE_COMMAND} --help
-      OUTPUT_VARIABLE cmakeOutput ERROR_VARIABLE cmakeOutput)
-
-    set(extraGenerators
-      "CodeBlocks"
-      "CodeLite"
-      "Eclipse CDT4"
-      "Kate"
-      "Sublime Text 2")
-
-    foreach(extraGenerator ${extraGenerators})
-      if ("${cmakeOutput}" MATCHES "${extraGenerator} - ${CMAKE_GENERATOR}")
-        set(extraGeneratorTestName "Simple_${extraGenerator}Generator")
-        string(REPLACE " " "" extraGeneratorTestName ${extraGeneratorTestName})
-
-        add_test(${extraGeneratorTestName} ${CMAKE_CTEST_COMMAND}
-          --build-and-test
-          "${CMake_SOURCE_DIR}/Tests/Simple"
-          "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}"
-          --build-two-config
-          --build-generator "${extraGenerator} - ${CMAKE_GENERATOR}"
-          --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
-          --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
-          --build-project Simple
-          --test-command Simple)
-        list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}")
-      endif ()
-    endforeach(extraGenerator)
-
+  if(CMAKE_GENERATOR MATCHES "^(Unix Makefiles|Ninja)$"
+      AND NOT "${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
+    foreach(extraGenerator
+        "CodeBlocks"
+        "CodeLite"
+        "Eclipse CDT4"
+        "Kate"
+        "Sublime Text 2"
+        )
+      string(REPLACE " " "" extraGeneratorTestName "Simple_${extraGenerator}Generator")
+      add_test(${extraGeneratorTestName} ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/Simple"
+        "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}"
+        --build-two-config
+        --build-generator "${extraGenerator} - ${CMAKE_GENERATOR}"
+        --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+        --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+        --build-project Simple
+        --test-command Simple)
+      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}")
+    endforeach()
   endif()
 
   # test for correct sub-project generation
@@ -1451,6 +1441,7 @@
             Patch
             PostgreSQL
             Protobuf
+            SDL
             SQLite3
             TIFF
             Vulkan
diff --git a/Tests/FindSDL/CMakeLists.txt b/Tests/FindSDL/CMakeLists.txt
new file mode 100644
index 0000000..e786204
--- /dev/null
+++ b/Tests/FindSDL/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindSDL.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindSDL/Test"
+  "${CMake_BINARY_DIR}/Tests/FindSDL/Test"
+  ${build_generator_args}
+  --build-project TestFindSDL
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindSDL/Test/CMakeLists.txt b/Tests/FindSDL/Test/CMakeLists.txt
new file mode 100644
index 0000000..61d4f4b
--- /dev/null
+++ b/Tests/FindSDL/Test/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindSDL C)
+include(CTest)
+
+find_package(SDL)
+
+add_definitions(
+  -DCMAKE_EXPECTED_SDL_VERSION_MAJOR=${SDL_VERSION_MAJOR}
+  -DCMAKE_EXPECTED_SDL_VERSION_MINOR=${SDL_VERSION_MINOR}
+  -DCMAKE_EXPECTED_SDL_VERSION_PATCH=${SDL_VERSION_PATCH})
+
+add_executable(test_sdl_tgt main.c)
+target_link_libraries(test_sdl_tgt SDL::SDL)
+add_test(NAME test_sdl_tgt COMMAND test_sdl_tgt)
+
+add_executable(test_sdl_var main.c)
+target_include_directories(test_sdl_var PRIVATE ${SDL_INCLUDE_DIRS})
+target_link_libraries(test_sdl_var PRIVATE ${SDL_LIBRARIES})
+add_test(NAME test_sdl_var COMMAND test_sdl_var)
diff --git a/Tests/FindSDL/Test/main.c b/Tests/FindSDL/Test/main.c
new file mode 100644
index 0000000..057289c
--- /dev/null
+++ b/Tests/FindSDL/Test/main.c
@@ -0,0 +1,18 @@
+#include <SDL.h>
+
+int main()
+{
+  // Test 1 requires headers only.
+  SDL_version compiled;
+  SDL_VERSION(&compiled);
+  if (compiled.major != CMAKE_EXPECTED_SDL_VERSION_MAJOR ||
+      compiled.minor != CMAKE_EXPECTED_SDL_VERSION_MINOR ||
+      compiled.patch != CMAKE_EXPECTED_SDL_VERSION_PATCH)
+    return 1;
+
+  // Test 2 requires to link to the library.
+  if (SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)
+    return 2;
+
+  return 0;
+}
diff --git a/Tests/RunCMake/Android/RunCMakeTest.cmake b/Tests/RunCMake/Android/RunCMakeTest.cmake
index 45798ce..234525a 100644
--- a/Tests/RunCMake/Android/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Android/RunCMakeTest.cmake
@@ -18,7 +18,19 @@
   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
   run_cmake(${case})
-  run_cmake_command(${case}-build ${CMAKE_COMMAND} --build .)
+  set(configs ".")
+  if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(configs Release Debug)
+  endif()
+  foreach(config IN LISTS configs)
+    set(build_suffix)
+    set(config_arg)
+    if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+      set(build_suffix "-${config}")
+      set(config_arg --config "${config}")
+    endif()
+    run_cmake_command(${case}-build${build_suffix} ${CMAKE_COMMAND} --build . ${config_arg})
+  endforeach()
 endfunction()
 
 set(RunCMake_TEST_OPTIONS
@@ -166,14 +178,25 @@
   # Test all combinations.
   foreach(vers IN LISTS _versions)
     foreach(stl IN LISTS stl_types)
-      foreach(config Release Debug)
+      set(configs Release Debug)
+      set(foreach_list "${configs}")
+      if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+        set(foreach_list ".")
+      endif()
+      foreach(config IN LISTS foreach_list)
         # Test this combination for all available abis.
-        message(STATUS "ndk='${ndk}' vers='${vers}' stl='${stl}' config='${config}'")
+        set(config_status " config='${config}'")
+        set(build_type_arg "-DCMAKE_BUILD_TYPE=${config}")
+        if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+          set(config_status)
+          string(REPLACE ";" "\\\\;" build_type_arg "-DCMAKE_CONFIGURATION_TYPES=${configs}")
+        endif()
+        message(STATUS "ndk='${ndk}' vers='${vers}' stl='${stl}'${config_status}")
         set(RunCMake_TEST_OPTIONS
           -DCMAKE_ANDROID_NDK=${ndk}
           -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=${vers}
           -DCMAKE_ANDROID_STL_TYPE=${stl}
-          -DCMAKE_BUILD_TYPE=${config}
+          "${build_type_arg}"
           )
         foreach(abi IN LISTS abi_names)
           # Skip ABIs not supported by this compiler.
diff --git a/Tests/RunCMake/Android/common.cmake b/Tests/RunCMake/Android/common.cmake
index d96ab86..32412aa 100644
--- a/Tests/RunCMake/Android/common.cmake
+++ b/Tests/RunCMake/Android/common.cmake
@@ -96,7 +96,7 @@
 add_executable(android_cxx android.cxx)
 add_library(android_cxx_lib SHARED android_lib.cxx)
 
-set(objdump "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}objdump")
+set(objdump "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}objdump${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}")
 if(NOT EXISTS "${objdump}")
   message(FATAL_ERROR "Expected tool missing:\n  ${objdump}")
 endif()
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 064b4dc..831f430 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -46,3 +46,4 @@
   "MONOLITHIC;COMPONENT"
 )
 run_cpack_test(PROJECT_META "RPM.PROJECT_META;DEB.PROJECT_META" false "MONOLITHIC;COMPONENT")
+run_cpack_test_package_target(PRE_POST_SCRIPTS "ZIP" false "MONOLITHIC;COMPONENT")
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake
index 6f7c4c2..3db8014 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake
@@ -29,3 +29,11 @@
 expect_file(${CPACK_TEMPORARY_DIRECTORY}/f4/share/cpack-test/f4.txt)
 
 message(STATUS "This status message is expected to be visible")
+
+set(
+    CPACK_EXTERNAL_BUILT_PACKAGES
+    ${CPACK_TEMPORARY_DIRECTORY}/f1/share/cpack-test/f1.txt
+    ${CPACK_TEMPORARY_DIRECTORY}/f2/share/cpack-test/f2.txt
+    ${CPACK_TEMPORARY_DIRECTORY}/f3/share/cpack-test/f3.txt
+    ${CPACK_TEMPORARY_DIRECTORY}/f4/share/cpack-test/f4.txt
+  )
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt b/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt
index 37d635f..587b2e8 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt
@@ -1 +1,11 @@
 -- This status message is expected to be visible
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/external-0\.1\.1-.*\.json generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/external-0\.1\.1-.*\.json\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f1\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f1\.txt\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f2\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f2\.txt\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f3\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f3\.txt\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f4\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f4\.txt\.sha1 generated\.
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake
index bc9766b..d4781ba 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake
@@ -17,6 +17,7 @@
 elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "stage_and_package")
   set(CPACK_EXTERNAL_ENABLE_STAGING 1)
   set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/create_package.cmake")
+  set(CPACK_PACKAGE_CHECKSUM SHA1)
 endif()
 
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/f1.txt" test1)
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ExpectedFiles.cmake
new file mode 100644
index 0000000..63a36a3
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ExpectedFiles.cmake
@@ -0,0 +1,19 @@
+set(SATU "/satu;/satu/CMakeLists.txt")
+set(DUA "/dua;/dua/CMakeLists.txt")
+
+if(GENERATOR_TYPE STREQUAL ZIP)
+    set(_ext "zip")
+elseif(GENERATOR_TYPE STREQUAL TGZ)
+    set(_ext "tar.gz")
+endif()
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+    set(EXPECTED_FILES_COUNT "2")
+    set(EXPECTED_FILE_1 "*-satu.${_ext}")
+    set(EXPECTED_FILE_CONTENT_1_LIST ${SATU})
+    set(EXPECTED_FILE_2 "*-dua.${_ext}")
+    set(EXPECTED_FILE_CONTENT_2_LIST ${DUA})
+else()
+    set(EXPECTED_FILES_COUNT "1")
+    set(EXPECTED_FILE_CONTENT_1_LIST ${SATU} ${DUA})
+endif()
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_COMPONENT-stdout.txt b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_COMPONENT-stdout.txt
new file mode 100644
index 0000000..319d0da
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_COMPONENT-stdout.txt
@@ -0,0 +1,4 @@
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre\.cmake and generator ZIP
+.*
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post\.cmake and generator ZIP
+-- Built packages: .*/_CPack_Packages/.*/pre_post_scripts-.*-dua.zip;.*/_CPack_Packages/.*/pre_post_scripts-.*-satu.zip
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_MONOLITHIC-stdout.txt b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_MONOLITHIC-stdout.txt
new file mode 100644
index 0000000..632c4d1
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_MONOLITHIC-stdout.txt
@@ -0,0 +1,4 @@
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre\.cmake and generator ZIP
+.*
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post\.cmake and generator ZIP
+-- Built packages: .*/_CPack_Packages/.*/pre_post_scripts-0\.1\.1-.*\.zip
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post.cmake
new file mode 100644
index 0000000..cf0b149
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post.cmake
@@ -0,0 +1,2 @@
+message(STATUS "The message from ${CMAKE_CURRENT_LIST_FILE} and generator ${CPACK_GENERATOR}")
+message(STATUS "Built packages: ${CPACK_PACKAGE_FILES}")
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre.cmake
new file mode 100644
index 0000000..b04aa6b
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre.cmake
@@ -0,0 +1 @@
+message(STATUS "The message from ${CMAKE_CURRENT_LIST_FILE} and generator ${CPACK_GENERATOR}")
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/test.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/test.cmake
new file mode 100644
index 0000000..f1b6d5f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/test.cmake
@@ -0,0 +1,9 @@
+install(FILES CMakeLists.txt DESTINATION satu COMPONENT satu)
+install(FILES CMakeLists.txt DESTINATION dua COMPONENT dua)
+
+set(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/pre.cmake")
+set(CPACK_POST_BUILD_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/post.cmake")
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+  set(CPACK_COMPONENTS_ALL satu dua)
+endif()
diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-result.txt b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
index d2a2831..cf2c087 100644
--- a/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
+++ b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
@@ -5,3 +5,4 @@
 add_custom_target(CustomTarget ALL DEPENDS output.txt)
 add_custom_target(CustomTarget2 ALL DEPENDS output.txt)
 add_custom_target(CustomTarget3 ALL DEPENDS output.txt)
+add_custom_target(CustomTargetFail COMMAND DoesNotExist)
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-different-eol-stderr.txt b/Tests/RunCMake/CommandLine/E_compare_files-different-eol-stderr.txt
deleted file mode 100644
index 4729ccb..0000000
--- a/Tests/RunCMake/CommandLine/E_compare_files-different-eol-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^Files ".*/compare_files/lf" to ".*/compare_files/crlf" are different.$
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-ignore-eol-nonexistent-stderr.txt b/Tests/RunCMake/CommandLine/E_compare_files-ignore-eol-nonexistent-stderr.txt
deleted file mode 100644
index 8a9ca81..0000000
--- a/Tests/RunCMake/CommandLine/E_compare_files-ignore-eol-nonexistent-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^Files "nonexistent_a" to "nonexistent_b" are different.$
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-result.txt b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-result.txt
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-result.txt
@@ -0,0 +1 @@
+2
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-stderr.txt b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 973391d..f291f15 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -22,6 +22,7 @@
 run_cmake_command(E_compare_files-ignore-eol-same ${CMAKE_COMMAND} -E compare_files --ignore-eol ${RunCMake_SOURCE_DIR}/compare_files/lf ${RunCMake_SOURCE_DIR}/compare_files/crlf)
 run_cmake_command(E_compare_files-ignore-eol-empty ${CMAKE_COMMAND} -E compare_files --ignore-eol ${RunCMake_SOURCE_DIR}/compare_files/empty1 ${RunCMake_SOURCE_DIR}/compare_files/empty2)
 run_cmake_command(E_compare_files-ignore-eol-nonexistent ${CMAKE_COMMAND} -E compare_files --ignore-eol nonexistent_a nonexistent_b)
+run_cmake_command(E_compare_files-invalid-arguments ${CMAKE_COMMAND} -E compare_files file1.txt file2.txt file3.txt)
 run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append)
 run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename)
 run_cmake_command(E_server-arg ${CMAKE_COMMAND} -E server --extra-arg)
@@ -134,6 +135,8 @@
     ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget)
   run_cmake_command(BuildDir--build-multiple-targets ${CMAKE_COMMAND} -E chdir ..
     ${CMAKE_COMMAND} --build BuildDir-build -t CustomTarget2 --target CustomTarget3)
+  run_cmake_command(BuildDir--build-multiple-targets-fail ${CMAKE_COMMAND} -E chdir ..
+    ${CMAKE_COMMAND} --build BuildDir-build -t CustomTargetFail --target CustomTarget3)
   run_cmake_command(BuildDir--build-multiple-targets-jobs ${CMAKE_COMMAND} -E chdir ..
     ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget CustomTarget2 -j2 --target CustomTarget3)
   run_cmake_command(BuildDir--build-multiple-targets-with-clean-first ${CMAKE_COMMAND} -E chdir ..
diff --git a/Tests/RunCMake/FindOpenGL/CMP0072-OLD-stderr.txt b/Tests/RunCMake/FindOpenGL/CMP0072-OLD-stderr.txt
new file mode 100644
index 0000000..68d23d4
--- /dev/null
+++ b/Tests/RunCMake/FindOpenGL/CMP0072-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0072-OLD.cmake:1 \(cmake_policy\):
+  The OLD behavior for policy CMP0072 will be removed from a future version
+  of CMake.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
index 10cd2bc..4ce6b5c 100644
--- a/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
+++ b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
@@ -9,6 +9,7 @@
 #   - All library depend on a common INTERFACE library holding compiler flags
 #   - We have a custom target to generate a man page
 #   - Someone has added an UNKNOWN, IMPORTED crypto mining library!
+#   - We have a circular dependency between two libraries
 
 add_subdirectory(test_project/third_party_project)
 
@@ -23,6 +24,13 @@
 
 target_link_libraries(CoreLibrary PRIVATE SeriousLoggingLibrary)
 
+add_library(SystemLibrary STATIC test_project/system_library.c)
+
+# Create a circular dependency.
+# See https://gitlab.kitware.com/cmake/cmake/issues/20720
+target_link_libraries(CoreLibrary PRIVATE SystemLibrary)
+target_link_libraries(SystemLibrary PRIVATE CoreLibrary)
+
 add_library(GraphicLibraryObjects OBJECT test_project/graphic_library.c)
 
 add_library(GraphicLibrary SHARED)
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
index 8b0365a..31d88df 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
@@ -28,25 +28,28 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GenerateManPage", shape = box ];
-    "node1" -> "node5"  // ConsoleApplication -> GenerateManPage
-    "node6" [ label = "GraphicApplication", shape = egg ];
-    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node8" [ label = "\"-lm\"", shape = septagon ];
-    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GenerateManPage", shape = box ];
+    "node1" -> "node6"  // ConsoleApplication -> GenerateManPage
+    "node7" [ label = "GraphicApplication", shape = egg ];
+    "node7" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node8" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node9" [ label = "\"-lm\"", shape = septagon ];
+    "node8" -> "node9" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node8" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node8" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node10" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node8" -> "node10" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node7" -> "node8" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node11" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node12" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node12" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node12" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
index 1bbf25a..26f2f64 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
index 1bbf25a..26f2f64 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
index 558a470..7f2e01c 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
@@ -27,18 +27,21 @@
     "node1" -> "node0"  // CoreLibrary -> CompilerFlags
     "node2" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node1" -> "node2" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
-    "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" [ label = "\"-lm\"", shape = septagon ];
-    "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node4" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node3" [ label = "SystemLibrary", shape = octagon ];
+    "node3" -> "node1" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node1" -> "node3" [ style = dotted ] // CoreLibrary -> SystemLibrary
+    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" [ label = "\"-lm\"", shape = septagon ];
+    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node5" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node5" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node8" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node9" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
index 660af37..db675a8 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
@@ -28,19 +28,22 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "GraphicApplication", shape = egg ];
-    "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node7" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "GraphicApplication", shape = egg ];
+    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
index 5af7fec..234ee39 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
@@ -28,8 +28,11 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "\"-lm\"", shape = septagon ];
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "\"-lm\"", shape = septagon ];
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
index 94ec41c..6dea88c 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
@@ -24,20 +24,23 @@
 }
     "node0" [ label = "ConsoleApplication", shape = egg ];
     "node1" [ label = "CoreLibrary", shape = octagon ];
+    "node2" [ label = "SystemLibrary", shape = octagon ];
+    "node2" -> "node1" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node1" -> "node2" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node0" -> "node1" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node2" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node0" -> "node2" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node3" [ label = "GraphicApplication", shape = egg ];
-    "node3" -> "node1" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" [ label = "\"-lm\"", shape = septagon ];
-    "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node3" -> "node4" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node0" -> "node3" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node4" [ label = "GraphicApplication", shape = egg ];
+    "node4" -> "node1" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" [ label = "\"-lm\"", shape = septagon ];
+    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node5" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node8" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node9" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
index 65b7a71..df3d10a 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
@@ -28,17 +28,20 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
index 8116bc9..8f832a8 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
@@ -28,21 +28,24 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
index 1bbf25a..26f2f64 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
index 439d1f7..e127daa 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
@@ -28,17 +28,20 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "\"-lm\"", shape = septagon ];
-    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "\"-lm\"", shape = septagon ];
+    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
index 1be6550..4f242bb 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
@@ -28,21 +28,24 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "GraphicApplication", shape = egg ];
-    "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node6" [ label = "\"-lm\"", shape = septagon ];
-    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node5" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "GraphicApplication", shape = egg ];
+    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node7" [ label = "\"-lm\"", shape = septagon ];
+    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
index 1cfbe0f..c664af8 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
index 9653c33..5579306 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
index 82d96d0..3bf20ec 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
@@ -28,23 +28,26 @@
     "point2" -> "point0"  // CoreLibrary -> CompilerFlags
     "point3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "point2" -> "point3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "point4" [ label = "SystemLibrary", shape = octagon ];
+    "point4" -> "point2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "point2" -> "point4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "point1" -> "point2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "point4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "point1" -> "point4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "point5" [ label = "GraphicApplication", shape = egg ];
-    "point5" -> "point2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "point6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "point7" [ label = "\"-lm\"", shape = septagon ];
-    "point6" -> "point7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "point6" -> "point0"  // GraphicLibrary -> CompilerFlags
-    "point6" -> "point2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "point8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "point6" -> "point8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "point5" -> "point6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "point9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "point9" -> "point0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "point9" -> "point2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "point10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "point10" -> "point0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "point10" -> "point2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "point5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "point1" -> "point5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "point6" [ label = "GraphicApplication", shape = egg ];
+    "point6" -> "point2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "point7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "point8" [ label = "\"-lm\"", shape = septagon ];
+    "point7" -> "point8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "point7" -> "point0"  // GraphicLibrary -> CompilerFlags
+    "point7" -> "point2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "point9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "point7" -> "point9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "point6" -> "point7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "point10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "point10" -> "point0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "point10" -> "point2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "point11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "point11" -> "point0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "point11" -> "point2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/test_project/system_library.c b/Tests/RunCMake/Graphviz/test_project/system_library.c
new file mode 100644
index 0000000..5d67079
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/system_library.c
@@ -0,0 +1,3 @@
+void initialize_system()
+{
+}
diff --git a/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt b/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
index 411cd7c..5c7882d 100644
--- a/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
@@ -3,7 +3,7 @@
 
     missing.c
 
-  Tried extensions( \.[A-Za-z+]+|
- )*
+  Tried extensions \.c \.C .*
+.*
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt b/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt
new file mode 100644
index 0000000..331d465
--- /dev/null
+++ b/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt
@@ -0,0 +1 @@
+-- FakeApp_EXECUTABLE='.*/Tests/RunCMake/find_program/BundleSpaceInName-build/Fake app.app/Contents/MacOS/Fake app'
diff --git a/Tests/RunCMake/find_program/BundleSpaceInName.cmake b/Tests/RunCMake/find_program/BundleSpaceInName.cmake
new file mode 100644
index 0000000..9152d5b
--- /dev/null
+++ b/Tests/RunCMake/find_program/BundleSpaceInName.cmake
@@ -0,0 +1,8 @@
+set(fakeApp "${CMAKE_CURRENT_BINARY_DIR}/Fake app.app/Contents/MacOS/Fake app")
+file(WRITE "${fakeApp}" "#!/bin/sh\n")
+execute_process(COMMAND chmod a+rx "${fakeApp}")
+
+find_program(FakeApp_EXECUTABLE NAMES "Fake app" NO_DEFAULT_PATH
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+)
+message(STATUS "FakeApp_EXECUTABLE='${FakeApp_EXECUTABLE}'")
diff --git a/Tests/RunCMake/find_program/CMP0109-Common.cmake b/Tests/RunCMake/find_program/CMP0109-Common.cmake
new file mode 100644
index 0000000..525413a
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-Common.cmake
@@ -0,0 +1,7 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead" "#!/bin/sh\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ReadNoExe" "#ReadNoExe")
+execute_process(COMMAND chmod -r+x "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead")
+find_program(ExeNoRead_EXECUTABLE NAMES ExeNoRead NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
+message(STATUS "ExeNoRead_EXECUTABLE='${ExeNoRead_EXECUTABLE}'")
+find_program(ReadNoExe_EXECUTABLE NAMES ReadNoExe NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
+message(STATUS "ReadNoExe_EXECUTABLE='${ReadNoExe_EXECUTABLE}'")
diff --git a/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt b/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt
new file mode 100644
index 0000000..2744463
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-NEW-build/ExeNoRead'
+-- ReadNoExe_EXECUTABLE='ReadNoExe_EXECUTABLE-NOTFOUND'
diff --git a/Tests/RunCMake/find_program/CMP0109-NEW.cmake b/Tests/RunCMake/find_program/CMP0109-NEW.cmake
new file mode 100644
index 0000000..b4a4033
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0109 NEW)
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt b/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt
new file mode 100644
index 0000000..1a0e2a8
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
+-- ReadNoExe_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-OLD-build/ReadNoExe'
diff --git a/Tests/RunCMake/find_program/CMP0109-OLD.cmake b/Tests/RunCMake/find_program/CMP0109-OLD.cmake
new file mode 100644
index 0000000..8260161
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0109 OLD)
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt b/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt
new file mode 100644
index 0000000..202fc6d
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt
@@ -0,0 +1,29 @@
+^CMake Warning \(dev\) at CMP0109-Common.cmake:4 \(find_program\):
+  Policy CMP0109 is not set: find_program\(\) requires permission to execute
+  but not to read.  Run "cmake --help-policy CMP0109" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  The file
+
+    .*/Tests/RunCMake/find_program/CMP0109-WARN-build/ExeNoRead
+
+  is executable but not readable.  CMake is ignoring it for compatibility.
+Call Stack \(most recent call first\):
+  CMP0109-WARN.cmake:1 \(include\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0109-Common.cmake:6 \(find_program\):
+  Policy CMP0109 is not set: find_program\(\) requires permission to execute
+  but not to read.  Run "cmake --help-policy CMP0109" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  The file
+
+    .*/Tests/RunCMake/find_program/CMP0109-WARN-build/ReadNoExe
+
+  is readable but not executable.  CMake is using it for compatibility.
+Call Stack \(most recent call first\):
+  CMP0109-WARN.cmake:1 \(include\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt b/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt
new file mode 100644
index 0000000..baf560f
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
+-- ReadNoExe_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-WARN-build/ReadNoExe'
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN.cmake b/Tests/RunCMake/find_program/CMP0109-WARN.cmake
new file mode 100644
index 0000000..a3d59af
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN.cmake
@@ -0,0 +1 @@
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/ExeNoRead-stdout.txt b/Tests/RunCMake/find_program/ExeNoRead-stdout.txt
deleted file mode 100644
index f231178..0000000
--- a/Tests/RunCMake/find_program/ExeNoRead-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
--- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
diff --git a/Tests/RunCMake/find_program/ExeNoRead.cmake b/Tests/RunCMake/find_program/ExeNoRead.cmake
deleted file mode 100644
index 7e22dc5..0000000
--- a/Tests/RunCMake/find_program/ExeNoRead.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead" "#!/bin/sh\n")
-execute_process(COMMAND chmod -r+x "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead")
-find_program(ExeNoRead_EXECUTABLE NAMES ExeNoRead NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
-message(STATUS "ExeNoRead_EXECUTABLE='${ExeNoRead_EXECUTABLE}'")
diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake
index 2bb777b..3e23920 100644
--- a/Tests/RunCMake/find_program/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake
@@ -17,6 +17,12 @@
     OUTPUT_STRIP_TRAILING_WHITESPACE)
 
   if(NOT "${uid}" STREQUAL "0")
-    run_cmake(ExeNoRead)
+    run_cmake(CMP0109-WARN)
+    run_cmake(CMP0109-OLD)
+    run_cmake(CMP0109-NEW)
   endif()
 endif()
+
+if(APPLE)
+  run_cmake(BundleSpaceInName)
+endif()
diff --git a/Tests/RunCMake/get_filename_component/IncorrectArguments-result.txt b/Tests/RunCMake/get_filename_component/IncorrectArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_filename_component/IncorrectArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_filename_component/IncorrectArguments-stderr.txt b/Tests/RunCMake/get_filename_component/IncorrectArguments-stderr.txt
new file mode 100644
index 0000000..af08afa
--- /dev/null
+++ b/Tests/RunCMake/get_filename_component/IncorrectArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at IncorrectArguments.cmake:1 \(get_filename_component\):
+  get_filename_component called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/get_filename_component/IncorrectArguments.cmake b/Tests/RunCMake/get_filename_component/IncorrectArguments.cmake
new file mode 100644
index 0000000..e329e29
--- /dev/null
+++ b/Tests/RunCMake/get_filename_component/IncorrectArguments.cmake
@@ -0,0 +1,2 @@
+get_filename_component(var)
+message("The error is fatal, so this should not print")
diff --git a/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake b/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake
index 156fc8f..a7820a0 100644
--- a/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake
+++ b/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake
@@ -1,4 +1,5 @@
 include(RunCMake)
 
+run_cmake(IncorrectArguments)
 run_cmake(KnownComponents)
 run_cmake(UnknownComponent)
diff --git a/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt b/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt
index b146e5b..f86a688 100644
--- a/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt
+++ b/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at UnknownComponent.cmake:1 \(get_filename_component\):
+^CMake Error at UnknownComponent.cmake:1 \(get_filename_component\):
   get_filename_component unknown component BOGUS
 Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/get_filename_component/UnknownComponent.cmake b/Tests/RunCMake/get_filename_component/UnknownComponent.cmake
index 06abc51..19521ba 100644
--- a/Tests/RunCMake/get_filename_component/UnknownComponent.cmake
+++ b/Tests/RunCMake/get_filename_component/UnknownComponent.cmake
@@ -1 +1,2 @@
 get_filename_component(var "/path/to/filename.ext.in" BOGUS)
+message("The error is fatal, so this should not print")
diff --git a/Tests/RunCMake/interface_library/global-interface-stderr.txt b/Tests/RunCMake/interface_library/global-interface-stderr.txt
index 23b45d9..38585eb 100644
--- a/Tests/RunCMake/interface_library/global-interface-stderr.txt
+++ b/Tests/RunCMake/interface_library/global-interface-stderr.txt
@@ -3,7 +3,7 @@
 
     GLOBAL
 
-  Tried extensions( \.[A-Za-z+]+|
- )*
+  Tried extensions \.c \.C .*
+.*
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/SetLang/CMakeLists.txt b/Tests/SetLang/CMakeLists.txt
index f24e5cb..af90f11 100644
--- a/Tests/SetLang/CMakeLists.txt
+++ b/Tests/SetLang/CMakeLists.txt
@@ -8,3 +8,10 @@
 set_source_files_properties(foo.c bar.c PROPERTIES LANGUAGE CXX)
 target_link_libraries(SetLang foo)
 set_target_properties(SetLang PROPERTIES LINKER_LANGUAGE CXX)
+
+if((CMAKE_C_COMPILER_ID MATCHES "(GNU|Clang|MSVC|Borland|Embarcadero|Intel|TI|XL)"))
+  add_library(zoom zoom.zzz)
+  set_source_files_properties(zoom.zzz PROPERTIES LANGUAGE CXX)
+  target_link_libraries(SetLang zoom)
+  target_compile_definitions(SetLang PRIVATE WITH_ZOOM)
+endif()
diff --git a/Tests/SetLang/bar.c b/Tests/SetLang/bar.c
index b934356..515e8c2 100644
--- a/Tests/SetLang/bar.c
+++ b/Tests/SetLang/bar.c
@@ -1,10 +1,22 @@
 #include <stdio.h>
 
 int foo();
+
+#ifdef WITH_ZOOM
+int zoom();
+#endif
+
 class A
 {
 public:
-  A() { this->i = foo(); }
+  A()
+  {
+    this->i = foo();
+#ifdef WITH_ZOOM
+    i += zoom();
+    i -= zoom();
+#endif
+  }
   int i;
 };
 
diff --git a/Tests/SetLang/zoom.zzz b/Tests/SetLang/zoom.zzz
new file mode 100644
index 0000000..a0c8899
--- /dev/null
+++ b/Tests/SetLang/zoom.zzz
@@ -0,0 +1,7 @@
+int zoom()
+{
+  int r = 10;
+  r++;
+  int ret = r + 10;
+  return ret;
+}
diff --git a/Utilities/Sphinx/CTestConfig.cmake b/Utilities/Sphinx/CTestConfig.cmake
index 9607e38..e5f4260 100644
--- a/Utilities/Sphinx/CTestConfig.cmake
+++ b/Utilities/Sphinx/CTestConfig.cmake
@@ -6,7 +6,9 @@
 set(CTEST_PROJECT_NAME "CMake")
 set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
 
-set(CTEST_DROP_METHOD "http")
+if(NOT CTEST_DROP_METHOD STREQUAL "https")
+  set(CTEST_DROP_METHOD "http")
+endif()
 set(CTEST_DROP_SITE "open.cdash.org")
 set(CTEST_DROP_LOCATION "/submit.php?project=CMake")
 set(CTEST_DROP_SITE_CDASH TRUE)