Merge topic 'findlapack-quiet'

c156704ff0 FindLAPACK: Use find_package_handle_standard_args

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5110
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 52536bb..f3df631 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -118,8 +118,35 @@
 and then it is used as an argument to :command:`target_link_libraries`
 like any other target.
 
-An interface library has no source files itself and is not included
-as a target in the generated buildsystem.
+An interface library created with the above signature has no source files
+itself and is not included as a target in the generated buildsystem.
+
+Since CMake 3.19, an interface library target may be created with
+source files:
+
+.. code-block:: cmake
+
+  add_library(<name> INTERFACE [<source>...] [EXCLUDE_FROM_ALL])
+
+Source files may be listed directly in the ``add_library`` call or added
+later by calls to :command:`target_sources` with the ``PRIVATE`` or
+``PUBLIC`` keywords.
+
+If an interface library has source files (i.e. the :prop_tgt:`SOURCES`
+target property is set), it will appear in the generated buildsystem
+as a build target much like a target defined by the
+:command:`add_custom_target` command.  It does not compile any sources,
+but does contain build rules for custom commands created by the
+:command:`add_custom_command` command.
+
+.. note::
+  In most command signatures where the ``INTERFACE`` keyword appears,
+  the items listed after it only become part of that target's usage
+  requirements and are not part of the target's own settings.  However,
+  in this signature of ``add_library``, the ``INTERFACE`` keyword refers
+  to the library type only.  Sources listed after it in the ``add_library``
+  call are ``PRIVATE`` to the interface library and do not appear in its
+  :prop_tgt:`INTERFACE_SOURCES` target property.
 
 Imported Libraries
 ^^^^^^^^^^^^^^^^^^
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index d8142a2..cd27316 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -922,8 +922,8 @@
 Interface Libraries
 -------------------
 
-An ``INTERFACE`` target has no :prop_tgt:`LOCATION` and is mutable, but is
-otherwise similar to an :prop_tgt:`IMPORTED` target.
+An ``INTERFACE`` library target does not compile sources and does not
+produce a library artifact on disk, so it has no :prop_tgt:`LOCATION`.
 
 It may specify usage requirements such as
 :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`,
@@ -937,11 +937,22 @@
 :command:`target_sources`, and :command:`target_link_libraries` commands
 may be used with ``INTERFACE`` libraries.
 
+Since CMake 3.19, an ``INTERFACE`` library target may optionally contain
+source files.  An interface library that contains source files will be
+included as a build target in the generated buildsystem.  It does not
+compile sources, but may contain custom commands to generate other sources.
+Additionally, IDEs will show the source files as part of the target for
+interactive reading and editing.
+
 A primary use-case for ``INTERFACE`` libraries is header-only libraries.
 
 .. code-block:: cmake
 
-  add_library(Eigen INTERFACE)
+  add_library(Eigen INTERFACE
+    src/eigen.h
+    src/vector.h
+    src/matrix.h
+    )
   target_include_directories(Eigen INTERFACE
     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
     $<INSTALL_INTERFACE:include/Eigen>
@@ -975,25 +986,17 @@
 targets, and the complexity of compiler-specific flags is encapsulated in an
 ``INTERFACE`` library target.
 
-The properties permitted to be set on or read from an ``INTERFACE`` library
-are:
-
-* Properties matching ``INTERFACE_*``
-* Built-in properties matching ``COMPATIBLE_INTERFACE_*``
-* ``EXPORT_NAME``
-* ``EXPORT_PROPERTIES``
-* ``IMPORTED``
-* ``MANUALLY_ADDED_DEPENDENCIES``
-* ``NAME``
-* Properties matching ``IMPORTED_LIBNAME_*``
-* Properties matching ``MAP_IMPORTED_CONFIG_*``
-
 ``INTERFACE`` libraries may be installed and exported.  Any content they refer
 to must be installed separately:
 
 .. code-block:: cmake
 
-  add_library(Eigen INTERFACE)
+  set(Eigen_headers
+    src/eigen.h
+    src/vector.h
+    src/matrix.h
+    )
+  add_library(Eigen INTERFACE ${Eigen_headers})
   target_include_directories(Eigen INTERFACE
     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
     $<INSTALL_INTERFACE:include/Eigen>
@@ -1003,9 +1006,6 @@
   install(EXPORT eigenExport NAMESPACE Upstream::
     DESTINATION lib/cmake/Eigen
   )
-  install(FILES
-      ${CMAKE_CURRENT_SOURCE_DIR}/src/eigen.h
-      ${CMAKE_CURRENT_SOURCE_DIR}/src/vector.h
-      ${CMAKE_CURRENT_SOURCE_DIR}/src/matrix.h
+  install(FILES ${Eigen_headers}
     DESTINATION include/Eigen
   )
diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst
index 34edc56..6876e1c 100644
--- a/Help/manual/cmake-file-api.7.rst
+++ b/Help/manual/cmake-file-api.7.rst
@@ -650,7 +650,8 @@
 ``type``
   A string specifying the type of the target.  The value is one of
   ``EXECUTABLE``, ``STATIC_LIBRARY``, ``SHARED_LIBRARY``,
-  ``MODULE_LIBRARY``, ``OBJECT_LIBRARY``, or ``UTILITY``.
+  ``MODULE_LIBRARY``, ``OBJECT_LIBRARY``, ``INTERFACE_LIBRARY``,
+  or ``UTILITY``.
 
 ``backtrace``
   Optional member that is present when a CMake language backtrace to
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 4ce8365..d780a65 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -158,6 +158,7 @@
    /variable/CMAKE_AUTOMOC_RELAXED_MODE
    /variable/CMAKE_BACKWARDS_COMPATIBILITY
    /variable/CMAKE_BUILD_TYPE
+   /variable/CMAKE_CLANG_VFS_OVERLAY
    /variable/CMAKE_CODEBLOCKS_COMPILER_ID
    /variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES
    /variable/CMAKE_CODELITE_USE_TARGETS
diff --git a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
index 4f85c16..836d953 100644
--- a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
+++ b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
@@ -15,7 +15,7 @@
 relative include path in that case.
 
 :prop_tgt:`AUTOMOC_PATH_PREFIX` is initialized from the variable
-:variable:`CMAKE_AUTOMOC_PATH_PREFIX`, which is ``ON`` by default.
+:variable:`CMAKE_AUTOMOC_PATH_PREFIX`, which is ``OFF`` by default.
 
 See the :manual:`cmake-qt(7)` manual for more information on using CMake
 with Qt.
@@ -26,8 +26,7 @@
 For reproducible builds it is recommended to keep headers that are ``moc``
 compiled in one of the target
 :command:`include directories <target_include_directories>` and set
-:prop_tgt:`AUTOMOC_PATH_PREFIX` to ``ON`` (which is the default).  This ensures
-that:
+:prop_tgt:`AUTOMOC_PATH_PREFIX` to ``ON``.  This ensures that:
 
 - ``moc`` output files are identical on different build setups,
 - ``moc`` output files will compile correctly when the source and/or
diff --git a/Help/prop_tgt/EXPORT_PROPERTIES.rst b/Help/prop_tgt/EXPORT_PROPERTIES.rst
index 34c054f..2d54f8b 100644
--- a/Help/prop_tgt/EXPORT_PROPERTIES.rst
+++ b/Help/prop_tgt/EXPORT_PROPERTIES.rst
@@ -14,3 +14,11 @@
 they are reserved for internal CMake use.
 
 Properties containing generator expressions are also not allowed.
+
+.. note::
+
+  Since CMake 3.19, :ref:`Interface Libraries` may have arbitrary
+  target properties.  If a project exports an interface library
+  with custom properties, the resulting package may not work with
+  dependents configured by older versions of CMake that reject the
+  custom properties.
diff --git a/Help/release/3.18.rst b/Help/release/3.18.rst
index ba80d2b..93694f6 100644
--- a/Help/release/3.18.rst
+++ b/Help/release/3.18.rst
@@ -339,3 +339,11 @@
   that were using manual quoting or escaping to work around the prior
   limitation.  This fix has been reverted in 3.18.1, but may be
   re-introduced in future versions of CMake with a policy for compatibility.
+
+3.18.2
+------
+
+* The default value of :variable:`CMAKE_AUTOMOC_PATH_PREFIX` was changed to
+  ``OFF`` because this feature can break existing projects that have
+  identically named header files in different include directories.
+  This restores compatibility with behavior of CMake 3.15 and below.
diff --git a/Help/release/dev/build-interface-targets.rst b/Help/release/dev/build-interface-targets.rst
new file mode 100644
index 0000000..37bded4
--- /dev/null
+++ b/Help/release/dev/build-interface-targets.rst
@@ -0,0 +1,6 @@
+build-interface-targets
+-----------------------
+
+* :ref:`Interface Libraries` may now have source files added via
+  :command:`add_library` or :command:`target_sources`.  Those
+  with sources will be generated as part of the build system.
diff --git a/Help/release/dev/clang-cl-vfs.rst b/Help/release/dev/clang-cl-vfs.rst
new file mode 100644
index 0000000..40b19ef
--- /dev/null
+++ b/Help/release/dev/clang-cl-vfs.rst
@@ -0,0 +1,6 @@
+clang-cl-vfs
+------------
+
+* A :variable:`CMAKE_CLANG_VFS_OVERLAY` variable was added to tell
+  Clang to use a VFS overlay to support the Windows SDK when
+  cross-compiling from hosts with case-sensitive filesystems.
diff --git a/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst b/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
index 07a6cc8..42f48b4 100644
--- a/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
+++ b/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
@@ -10,4 +10,4 @@
 property on all the targets.  See that target property for additional
 information.
 
-The default value is ``ON``.
+The default value is ``OFF``.
diff --git a/Help/variable/CMAKE_CLANG_VFS_OVERLAY.rst b/Help/variable/CMAKE_CLANG_VFS_OVERLAY.rst
new file mode 100644
index 0000000..56ac328
--- /dev/null
+++ b/Help/variable/CMAKE_CLANG_VFS_OVERLAY.rst
@@ -0,0 +1,9 @@
+CMAKE_CLANG_VFS_OVERLAY
+-----------------------
+
+.. versionadded:: 3.19
+
+When cross compiling for windows with clang-cl, this variable can be an
+absolute path pointing to a clang virtual file system yaml file, which
+will enable clang-cl to resolve windows header names on a case sensitive
+file system.
diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
index 000fba1..6f665a6 100644
--- a/Modules/CMakeGenericSystem.cmake
+++ b/Modules/CMakeGenericSystem.cmake
@@ -26,7 +26,9 @@
 
 set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON)
 set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON)
-set(CMAKE_AUTOMOC_PATH_PREFIX ON)
+if(NOT DEFINED CMAKE_AUTOMOC_PATH_PREFIX)
+  set(CMAKE_AUTOMOC_PATH_PREFIX OFF)
+endif()
 set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE" "Q_NAMESPACE_EXPORT")
 
 # basically all general purpose OSs support shared libs
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index 7a1c252..7c9664d 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -206,7 +206,6 @@
     set(test_file ${scratch_directory}/cmake_hdf5_test.c)
     file(WRITE ${test_file}
       "#include <hdf5.h>\n"
-      "#include <hdf5_hl.h>\n"
       "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n"
       "#ifdef H5_HAVE_PARALLEL\n"
       "const char* info_parallel = \"INFO\" \":\" \"PARALLEL\";\n"
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index e1271d4..110e7f9 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -412,8 +412,15 @@
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "GLU")
+  # FindGLU include()'s this module. It's an old pattern, but rather than
+  # trying to suppress this from outside the module (which is then sensitive to
+  # the contents, detect the case in this module and suppress it explicitly.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGL REQUIRED_VARS ${_OpenGL_REQUIRED_VARS}
                                   HANDLE_COMPONENTS)
+unset(FPHSA_NAME_MISMATCHED)
 unset(_OpenGL_REQUIRED_VARS)
 
 # OpenGL:: targets
diff --git a/Modules/FindPerl.cmake b/Modules/FindPerl.cmake
index fd120bf..c14e059 100644
--- a/Modules/FindPerl.cmake
+++ b/Modules/FindPerl.cmake
@@ -73,8 +73,15 @@
 set(PERL ${PERL_EXECUTABLE})
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "PerlLibs")
+  # FindPerlLibs include()'s this module. It's an old pattern, but rather than
+  # trying to suppress this from outside the module (which is then sensitive to
+  # the contents, detect the case in this module and suppress it explicitly.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(Perl
                                   REQUIRED_VARS PERL_EXECUTABLE
                                   VERSION_VAR PERL_VERSION_STRING)
+unset(FPHSA_NAME_MISMATCHED)
 
 mark_as_advanced(PERL_EXECUTABLE)
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 1be0625..9b65f39 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -5,17 +5,13 @@
 # This file is a "template" file used by various FindPython modules.
 #
 
-cmake_policy (GET CMP0094 _${_PYTHON_PREFIX}_LOOKUP_POLICY)
-
-cmake_policy (VERSION 3.7)
-
-if (_${_PYTHON_PREFIX}_LOOKUP_POLICY)
-  cmake_policy (SET CMP0094 ${_${_PYTHON_PREFIX}_LOOKUP_POLICY})
-endif()
-
 #
 # Initial configuration
 #
+
+# IN_LIST operator
+cmake_policy (SET CMP0057 NEW)
+
 if (NOT DEFINED _PYTHON_PREFIX)
   message (FATAL_ERROR "FindPython: INTERNAL ERROR")
 endif()
@@ -1097,6 +1093,7 @@
 unset (${_PYTHON_PREFIX}_SOABI)
 
 # Define lookup strategy
+cmake_policy (GET CMP0094 _${_PYTHON_PREFIX}_LOOKUP_POLICY)
 if (_${_PYTHON_PREFIX}_LOOKUP_POLICY STREQUAL "NEW")
   set (_${_PYTHON_PREFIX}_FIND_STRATEGY "LOCATION")
 else()
diff --git a/Modules/FindQt3.cmake b/Modules/FindQt3.cmake
index 563ed46..b5bc8b1 100644
--- a/Modules/FindQt3.cmake
+++ b/Modules/FindQt3.cmake
@@ -201,9 +201,16 @@
 
 # if the include a library are found then we have it
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "Qt")
+  # FindQt include()'s this module. It's an old pattern, but rather than trying
+  # to suppress this from outside the module (which is then sensitive to the
+  # contents, detect the case in this module and suppress it explicitly.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt3
                                   REQUIRED_VARS QT_QT_LIBRARY QT_INCLUDE_DIR QT_MOC_EXECUTABLE
                                   VERSION_VAR QT_VERSION_STRING)
+unset(FPHSA_NAME_MISMATCHED)
 set(QT_FOUND ${QT3_FOUND} )
 
 if(QT_FOUND)
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index 29b1ef8..ec0f453 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -1318,10 +1318,18 @@
       endif()
     endif()
 else()
+  if (CMAKE_FIND_PACKAGE_NAME STREQUAL "Qt")
+    # FindQt include()'s this module. It's an old pattern, but rather than
+    # trying to suppress this from outside the module (which is then sensitive
+    # to the contents, detect the case in this module and suppress it
+    # explicitly.
+    set(FPHSA_NAME_MISMATCHED 1)
+  endif ()
   FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt4 FOUND_VAR Qt4_FOUND
     REQUIRED_VARS ${_QT4_FOUND_REQUIRED_VARS}
     VERSION_VAR QTVERSION
     )
+  unset(FPHSA_NAME_MISMATCHED)
 endif()
 
 #######################################
diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake
index 1bdee60..3b8122e 100644
--- a/Modules/FindRuby.cmake
+++ b/Modules/FindRuby.cmake
@@ -50,7 +50,7 @@
 
 Also:
 
-``Ruby_INCLUDE_PATH``
+``RUBY_INCLUDE_PATH``
   same as Ruby_INCLUDE_DIRS, only provided for compatibility reasons, don't use it
 
 Hints
@@ -493,7 +493,6 @@
     Ruby_VERSION_MAJOR
     Ruby_VERSION_MINOR
     Ruby_VERSION_PATCH
-    Ruby_INCLUDE_PATH
 
     Ruby_ARCH_DIR
     Ruby_ARCH
diff --git a/Modules/FindTCL.cmake b/Modules/FindTCL.cmake
index 960265f..9b771dc 100644
--- a/Modules/FindTCL.cmake
+++ b/Modules/FindTCL.cmake
@@ -223,6 +223,12 @@
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "TclStub")
+  # FindTclStub include()'s this module. It's an old pattern, but rather than
+  # trying to suppress this from outside the module (which is then sensitive to
+  # the contents, detect the case in this module and suppress it explicitly.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCL DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH)
 set(FPHSA_NAME_MISMATCHED 1)
 set(TCLTK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
diff --git a/Modules/FindTclsh.cmake b/Modules/FindTclsh.cmake
index f306d5b..594d0ec 100644
--- a/Modules/FindTclsh.cmake
+++ b/Modules/FindTclsh.cmake
@@ -85,8 +85,17 @@
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "TCL" OR
+    CMAKE_FIND_PACKAGE_NAME STREQUAL "TclStub")
+  # FindTCL include()'s this module. It's an old pattern, but rather than
+  # trying to suppress this from outside the module (which is then sensitive to
+  # the contents, detect the case in this module and suppress it explicitly.
+  # Transitively, FindTclStub includes FindTCL.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(Tclsh
                                   REQUIRED_VARS TCL_TCLSH
                                   VERSION_VAR TCLSH_VERSION_STRING)
+unset(FPHSA_NAME_MISMATCHED)
 
 mark_as_advanced(TCL_TCLSH)
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index 958a22e..778da9b 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -413,9 +413,17 @@
   endif ()
 
   include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+  if (CMAKE_FIND_PACKAGE_NAME STREQUAL "FLTK")
+    # FindFLTK include()'s this module. It's an old pattern, but rather than
+    # trying to suppress this from outside the module (which is then sensitive
+    # to the contents, detect the case in this module and suppress it
+    # explicitly.
+    set(FPHSA_NAME_MISMATCHED 1)
+  endif ()
   find_package_handle_standard_args(X11
     REQUIRED_VARS X11_X11_INCLUDE_PATH X11_X11_LIB
     HANDLE_COMPONENTS)
+  unset(FPHSA_NAME_MISMATCHED)
 
   if(X11_FOUND)
     include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index dff8166..05dff9d 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -142,7 +142,7 @@
       endif()
       if(DEFINED CMAKE_RC_PREPROCESSOR)
         set(CMAKE_DEPFILE_FLAGS_RC "-clang:-MD -clang:-MF -clang:<DEPFILE>")
-        set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E <SOURCE> -- <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp")
+        set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp")
         if(CMAKE_GENERATOR STREQUAL "Ninja")
           set(CMAKE_NINJA_CMCLDEPS_RC 0)
           set(CMAKE_NINJA_DEP_TYPE_RC gcc)
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index e272da9..173ef40 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -333,6 +333,14 @@
   set(CMAKE_LINK_PCH ON)
   if (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang")
     set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
+
+    # macOS paths usually start with /Users/*. Unfortunately, clang-cl interprets
+    # paths starting with /U as macro undefines, so we need to put a -- before the
+    # input file path to force it to be treated as a path.
+    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_COMPILE_OBJECT "${CMAKE_${lang}_COMPILE_OBJECT}")
+    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "${CMAKE_${lang}_COMPILE_OBJECT}")
+    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "${CMAKE_${lang}_COMPILE_OBJECT}")
+
   elseif(MSVC_VERSION GREATER_EQUAL 1913)
     # At least MSVC toolet 14.13 from VS 2017 15.6
     set(CMAKE_PCH_PROLOGUE "#pragma system_header")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index b6b868e..c82a659 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 18)
-set(CMake_VERSION_PATCH 20200807)
+set(CMake_VERSION_PATCH 20200811)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 3e5d764..f262fac 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -2,8 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmAddLibraryCommand.h"
 
-#include <cmext/algorithm>
-
 #include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmGlobalGenerator.h"
@@ -111,20 +109,10 @@
           "INTERFACE library specified with conflicting ALIAS type.");
         return false;
       }
-      if (excludeFromAll) {
-        status.SetError(
-          "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
-        return false;
-      }
       ++s;
       type = cmStateEnums::INTERFACE_LIBRARY;
       haveSpecifiedType = true;
     } else if (*s == "EXCLUDE_FROM_ALL") {
-      if (type == cmStateEnums::INTERFACE_LIBRARY) {
-        status.SetError(
-          "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
-        return false;
-      }
       ++s;
       excludeFromAll = true;
     } else if (*s == "IMPORTED") {
@@ -143,10 +131,6 @@
   }
 
   if (type == cmStateEnums::INTERFACE_LIBRARY) {
-    if (s != args.end()) {
-      status.SetError("INTERFACE library requires no source arguments.");
-      return false;
-    }
     if (importGlobal && !importTarget) {
       status.SetError(
         "INTERFACE library specified as GLOBAL, but not as IMPORTED.");
@@ -302,8 +286,6 @@
     }
   }
 
-  std::vector<std::string> srclists;
-
   if (type == cmStateEnums::INTERFACE_LIBRARY) {
     if (!cmGeneratorExpression::IsValidTargetName(libName) ||
         libName.find("::") != std::string::npos) {
@@ -311,14 +293,10 @@
         cmStrCat("Invalid name for INTERFACE library target: ", libName));
       return false;
     }
-
-    mf.AddLibrary(libName, type, srclists, excludeFromAll);
-    return true;
   }
 
-  cm::append(srclists, s, args.end());
-
-  mf.AddLibrary(libName, type, srclists, excludeFromAll);
+  std::vector<std::string> srcs(s, args.end());
+  mf.AddLibrary(libName, type, srcs, excludeFromAll);
 
   return true;
 }
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index e9af208..55fb115 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -625,7 +625,7 @@
 
   for (cmGeneratorTarget* gt : targetList) {
     if (gt->GetType() == cmStateEnums::GLOBAL_TARGET ||
-        gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+        !gt->IsInBuildSystem()) {
       continue;
     }
 
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 345f0ba..2768547 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -14,10 +14,11 @@
 #endif
 
 cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
+  : OriginalLocale(getloc())
 {
 #ifndef CMAKE_BOOTSTRAP
   if (encoding != codecvt::None) {
-    imbue(std::locale(getloc(), new codecvt(encoding)));
+    imbue(std::locale(OriginalLocale, new codecvt(encoding)));
   }
 #else
   static_cast<void>(encoding);
@@ -228,3 +229,14 @@
 {
   this->TempExt = ext;
 }
+
+void cmGeneratedFileStream::WriteRaw(std::string const& data)
+{
+#ifndef CMAKE_BOOTSTRAP
+  std::locale activeLocale = this->imbue(this->OriginalLocale);
+  this->write(data.data(), data.size());
+  this->imbue(activeLocale);
+#else
+  this->write(data.data(), data.size());
+#endif
+}
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index 3dee142..f6da86e 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -147,6 +147,16 @@
    * This does not work if the file was opened by the constructor.
    */
   void SetTempExt(std::string const& ext);
+
+  /**
+   * Writes the given string directly to the file without changing the
+   * encoding.
+   */
+  void WriteRaw(std::string const& data);
+
+private:
+  // The original locale of the stream (performs no encoding conversion).
+  std::locale OriginalLocale;
 };
 
 #endif
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 41cff01..889ad7c 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -380,11 +380,6 @@
 
 cmProp cmGeneratorTarget::GetProperty(const std::string& prop) const
 {
-  if (!cmTargetPropertyComputer::PassesWhitelist(
-        this->GetType(), prop, this->Makefile->GetMessenger(),
-        this->GetBacktrace())) {
-    return nullptr;
-  }
   if (cmProp result = cmTargetPropertyComputer::GetProperty(
         this, prop, this->Makefile->GetMessenger(), this->GetBacktrace())) {
     return result;
@@ -1104,6 +1099,10 @@
     case cmStateEnums::GLOBAL_TARGET:
       return true;
     case cmStateEnums::INTERFACE_LIBRARY:
+      // An INTERFACE library is in the build system if it has SOURCES.
+      if (!this->SourceEntries.empty()) {
+        return true;
+      }
     case cmStateEnums::UNKNOWN_LIBRARY:
       break;
   }
@@ -1548,7 +1547,6 @@
   std::string const& config) const
 {
   std::vector<BT<std::string>> files;
-  assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
 
   if (!this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
     // At configure-time, this method can be called as part of getting the
@@ -1740,9 +1738,11 @@
     std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
     if (sf->GetCustomCommand()) {
       kind = SourceKindCustomCommand;
-      // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
-      // NOLINTNEXTLINE(bugprone-branch-clone)
-    } else if (this->Target->GetType() == cmStateEnums::UTILITY) {
+    } else if (this->Target->GetType() == cmStateEnums::UTILITY ||
+               this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY
+               // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+               // NOLINTNEXTLINE(bugprone-branch-clone)
+    ) {
       kind = SourceKindExtra;
     } else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) {
       kind = SourceKindUnityBatched;
@@ -3124,6 +3124,9 @@
 void cmGeneratorTarget::GetAppleArchs(const std::string& config,
                                       std::vector<std::string>& archVec) const
 {
+  if (!this->Makefile->IsOn("APPLE")) {
+    return;
+  }
   cmProp archs = nullptr;
   if (!config.empty()) {
     std::string defVarName =
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index cba7704..cdfd8c8 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -17,7 +17,6 @@
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
-#include "cmTargetPropertyComputer.h"
 #include "cmTest.h"
 #include "cmake.h"
 
@@ -364,12 +363,9 @@
     cmProp prop_cstr = nullptr;
     cmListFileBacktrace bt = status.GetMakefile().GetBacktrace();
     cmMessenger* messenger = status.GetMakefile().GetMessenger();
-    if (cmTargetPropertyComputer::PassesWhitelist(
-          target->GetType(), propertyName, messenger, bt)) {
-      prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
-      if (!prop_cstr) {
-        prop_cstr = target->GetProperty(propertyName);
-      }
+    prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
+    if (!prop_cstr) {
+      prop_cstr = target->GetProperty(propertyName);
     }
     return StoreResult(infoType, status.GetMakefile(), variable,
                        prop_cstr ? prop_cstr->c_str() : nullptr);
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index 8a304be..78a17d2 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -12,7 +12,6 @@
 #include "cmPolicies.h"
 #include "cmProperty.h"
 #include "cmTarget.h"
-#include "cmTargetPropertyComputer.h"
 
 class cmMessenger;
 
@@ -46,12 +45,9 @@
       cmProp prop_cstr = nullptr;
       cmListFileBacktrace bt = mf.GetBacktrace();
       cmMessenger* messenger = mf.GetMessenger();
-      if (cmTargetPropertyComputer::PassesWhitelist(tgt->GetType(), args[2],
-                                                    messenger, bt)) {
-        prop_cstr = tgt->GetComputedProperty(args[2], messenger, bt);
-        if (!prop_cstr) {
-          prop_cstr = tgt->GetProperty(args[2]);
-        }
+      prop_cstr = tgt->GetComputedProperty(args[2], messenger, bt);
+      if (!prop_cstr) {
+        prop_cstr = tgt->GetProperty(args[2]);
       }
       if (prop_cstr) {
         prop = *prop_cstr;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 2ef202d..f0fa1f4 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1093,6 +1093,7 @@
     }
     // FALLTHROUGH
     case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::UTILITY: {
       std::string path =
         cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
@@ -1105,7 +1106,6 @@
       break;
     }
 
-    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::UNKNOWN_LIBRARY:
       break;
   }
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index ebc90b6..37a77fa 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -387,12 +387,8 @@
       cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(lGenerator);
     // for all of out targets
     for (const auto& tgt : lg.GetGeneratorTargets()) {
-      if ((tgt->GetType() == cmStateEnums::EXECUTABLE) ||
-          (tgt->GetType() == cmStateEnums::STATIC_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::SHARED_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::MODULE_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::UTILITY)) {
+      if (tgt->IsInBuildSystem() &&
+          tgt->GetType() != cmStateEnums::GLOBAL_TARGET) {
         std::string tname = cmStrCat(lg.GetRelativeTargetDirectory(tgt.get()),
                                      "/DependInfo.cmake");
         cmSystemTools::ConvertToUnixSlashes(tname);
@@ -635,17 +631,12 @@
     for (const auto& gtarget : lg.GetGeneratorTargets()) {
       // Don't emit the same rule twice (e.g. two targets with the same
       // simple name)
-      int type = gtarget->GetType();
       std::string name = gtarget->GetName();
       if (!name.empty() && emitted.insert(name).second &&
           // Handle user targets here.  Global targets are handled in
           // the local generator on a per-directory basis.
-          ((type == cmStateEnums::EXECUTABLE) ||
-           (type == cmStateEnums::STATIC_LIBRARY) ||
-           (type == cmStateEnums::SHARED_LIBRARY) ||
-           (type == cmStateEnums::MODULE_LIBRARY) ||
-           (type == cmStateEnums::OBJECT_LIBRARY) ||
-           (type == cmStateEnums::UTILITY))) {
+          (gtarget->IsInBuildSystem() &&
+           gtarget->GetType() != cmStateEnums::GLOBAL_TARGET)) {
         // Add a rule to build the target by name.
         lg.WriteDivider(ruleFileStream);
         ruleFileStream << "# Target rules for targets named " << name
@@ -709,15 +700,10 @@
 
   // for each target Generate the rule files for each target.
   for (const auto& gtarget : lg.GetGeneratorTargets()) {
-    int type = gtarget->GetType();
     std::string name = gtarget->GetName();
     if (!name.empty() &&
-        ((type == cmStateEnums::EXECUTABLE) ||
-         (type == cmStateEnums::STATIC_LIBRARY) ||
-         (type == cmStateEnums::SHARED_LIBRARY) ||
-         (type == cmStateEnums::MODULE_LIBRARY) ||
-         (type == cmStateEnums::OBJECT_LIBRARY) ||
-         (type == cmStateEnums::UTILITY))) {
+        (gtarget->IsInBuildSystem() &&
+         gtarget->GetType() != cmStateEnums::GLOBAL_TARGET)) {
       std::string makefileName;
       // Add a rule to build the target by name.
       localName = lg.GetRelativeTargetDirectory(gtarget.get());
@@ -985,7 +971,9 @@
             (type == cmStateEnums::STATIC_LIBRARY) ||
             (type == cmStateEnums::SHARED_LIBRARY) ||
             (type == cmStateEnums::MODULE_LIBRARY) ||
-            (type == cmStateEnums::OBJECT_LIBRARY)) {
+            (type == cmStateEnums::OBJECT_LIBRARY) ||
+            (type == cmStateEnums::INTERFACE_LIBRARY &&
+             target->IsInBuildSystem())) {
           project_targets.insert(target->GetName());
         } else if (type == cmStateEnums::GLOBAL_TARGET) {
           globals_targets.insert(target->GetName());
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 574e0f5..793f6f7 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1204,6 +1204,7 @@
   }
 
   if (gtgt->GetType() == cmStateEnums::UTILITY ||
+      gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
       gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) {
     cmXCodeObject* t = this->CreateUtilityTarget(gtgt);
     if (!t) {
@@ -2536,7 +2537,7 @@
   this->XCodeObjectMap[gtgt] = target;
 
   // Add source files without build rules for editing convenience.
-  if (gtgt->GetType() == cmStateEnums::UTILITY &&
+  if (gtgt->GetType() != cmStateEnums::GLOBAL_TARGET &&
       gtgt->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
     std::vector<cmSourceFile*> sources;
     if (!gtgt->GetConfigCommonSourceFiles(sources)) {
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 7e35fe7..2380cce 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1938,6 +1938,9 @@
   this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"),
                                config);
 
+  std::string const& compiler = this->Makefile->GetSafeDefinition(
+    cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
+
   if (lang == "Swift") {
     if (cmProp v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
       if (cmSystemTools::VersionCompare(
@@ -1951,9 +1954,6 @@
     target->AddCUDAArchitectureFlags(flags);
     target->AddCUDAToolkitFlags(flags);
 
-    std::string const& compiler =
-      this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
-
     if (compiler == "Clang") {
       bool separable = target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION");
 
@@ -1965,7 +1965,24 @@
       }
     }
   }
-
+  // Add VFS Overlay for Clang compiliers
+  if (compiler == "Clang") {
+    if (const char* vfsOverlay =
+          this->Makefile->GetDefinition("CMAKE_CLANG_VFS_OVERLAY")) {
+      std::string const& compilerSimulateId =
+        this->Makefile->GetSafeDefinition(
+          cmStrCat("CMAKE_", lang, "_SIMULATE_ID"));
+      if (compilerSimulateId == "MSVC") {
+        this->AppendCompileOptions(
+          flags,
+          std::vector<std::string>{ "-Xclang", "-ivfsoverlay", "-Xclang",
+                                    vfsOverlay });
+      } else {
+        this->AppendCompileOptions(
+          flags, std::vector<std::string>{ "-ivfsoverlay", vfsOverlay });
+      }
+    }
+  }
   // Add MSVC runtime library flags.  This is activated by the presence
   // of a default selection whether or not it is overridden by a property.
   cmProp msvcRuntimeLibraryDefault =
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index ef34953..eb841d9 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -84,8 +84,26 @@
     if (!showIncludesPrefix.empty()) {
       cmGlobalNinjaGenerator::WriteComment(this->GetRulesFileStream(),
                                            "localized /showIncludes string");
-      this->GetRulesFileStream()
-        << "msvc_deps_prefix = " << showIncludesPrefix << "\n\n";
+      this->GetRulesFileStream() << "msvc_deps_prefix = ";
+#ifdef WIN32
+      // Ninja uses the ANSI Windows APIs, so strings in the rules file
+      // typically need to be ANSI encoded. However, in this case the compiler
+      // is being invoked using the UTF-8 codepage so the /showIncludes prefix
+      // will be UTF-8 encoded on stdout. Ninja can't successfully compare this
+      // UTF-8 encoded prefix to the ANSI encoded msvc_deps_prefix if it
+      // contains any non-ASCII characters and dependency checking will fail.
+      // As a workaround, leave the msvc_deps_prefix UTF-8 encoded even though
+      // the rest of the file is ANSI encoded.
+      if (GetConsoleOutputCP() == CP_UTF8 && GetACP() != CP_UTF8) {
+        this->GetRulesFileStream().WriteRaw(showIncludesPrefix);
+      } else {
+        this->GetRulesFileStream() << showIncludesPrefix;
+      }
+#else
+      // It's safe to use the standard encoding on other platforms.
+      this->GetRulesFileStream() << showIncludesPrefix;
+#endif
+      this->GetRulesFileStream() << "\n\n";
     }
   }
 
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index fec6a9d..50ffe8d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -629,9 +629,10 @@
       break;
     case cmStateEnums::UTILITY:
     case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::INTERFACE_LIBRARY:
       configType = "10";
       CM_FALLTHROUGH;
-    default:
+    case cmStateEnums::UNKNOWN_LIBRARY:
       targetBuilds = false;
       break;
   }
@@ -1638,7 +1639,8 @@
     std::string source = sf->GetFullPath();
 
     if (source != libName || target->GetType() == cmStateEnums::UTILITY ||
-        target->GetType() == cmStateEnums::GLOBAL_TARGET) {
+        target->GetType() == cmStateEnums::GLOBAL_TARGET ||
+        target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       // Look up the source kind and configs.
       std::map<cmSourceFile const*, size_t>::const_iterator map_it =
         sources.Index.find(sf);
@@ -1937,6 +1939,7 @@
   const char* keyword = p ? p->c_str() : "Console Application";
   const char* projectType = 0;
   switch (target->GetType()) {
+    case cmStateEnums::OBJECT_LIBRARY:
     case cmStateEnums::STATIC_LIBRARY:
       projectType = "typeStaticLibrary";
       if (keyword) {
@@ -1958,7 +1961,8 @@
       break;
     case cmStateEnums::UTILITY:
     case cmStateEnums::GLOBAL_TARGET:
-    default:
+    case cmStateEnums::INTERFACE_LIBRARY:
+    case cmStateEnums::UNKNOWN_LIBRARY:
       break;
   }
   if (projectType) {
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 5e1f070..5cfe5f1 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -20,8 +20,10 @@
 #include <cmext/algorithm>
 #include <cmext/string_view>
 
-#include <cm3p/json/value.h>
-#include <cm3p/json/writer.h>
+#ifndef CMAKE_BOOTSTRAP
+#  include <cm3p/json/value.h>
+#  include <cm3p/json/writer.h>
+#endif
 
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 13c2fe9..fae1d76 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -71,6 +71,7 @@
     case cmStateEnums::OBJECT_LIBRARY:
       result = cm::make_unique<cmMakefileLibraryTargetGenerator>(tgt);
       break;
+    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::UTILITY:
       result = cm::make_unique<cmMakefileUtilityTargetGenerator>(tgt);
       break;
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 048dbb6..57f526e 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -51,6 +51,7 @@
       return cm::make_unique<cmNinjaNormalTargetGenerator>(target);
 
     case cmStateEnums::UTILITY:
+    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::GLOBAL_TARGET:
       return cm::make_unique<cmNinjaUtilityTargetGenerator>(target);
 
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 0e5dfef..51b4e9e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -401,12 +401,10 @@
 #endif
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-    initProp("FOLDER");
+  initProp("FOLDER");
 
-    if (this->GetGlobalGenerator()->IsXcode()) {
-      initProp("XCODE_GENERATE_SCHEME");
-    }
+  if (this->GetGlobalGenerator()->IsXcode()) {
+    initProp("XCODE_GENERATE_SCHEME");
   }
 
   // Setup per-configuration property default values.
@@ -521,24 +519,21 @@
     initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-
-    // check for "CMAKE_VS_GLOBALS" variable and set up target properties
-    // if any
-    const char* globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
-    if (globals) {
-      const std::string genName = mf->GetGlobalGenerator()->GetName();
-      if (cmHasLiteralPrefix(genName, "Visual Studio")) {
-        std::vector<std::string> props = cmExpandedList(globals);
-        const std::string vsGlobal = "VS_GLOBAL_";
-        for (const std::string& i : props) {
-          // split NAME=VALUE
-          const std::string::size_type assignment = i.find('=');
-          if (assignment != std::string::npos) {
-            const std::string propName = vsGlobal + i.substr(0, assignment);
-            const std::string propValue = i.substr(assignment + 1);
-            initPropValue(propName, propValue.c_str());
-          }
+  // check for "CMAKE_VS_GLOBALS" variable and set up target properties
+  // if any
+  const char* globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
+  if (globals) {
+    const std::string genName = mf->GetGlobalGenerator()->GetName();
+    if (cmHasLiteralPrefix(genName, "Visual Studio")) {
+      std::vector<std::string> props = cmExpandedList(globals);
+      const std::string vsGlobal = "VS_GLOBAL_";
+      for (const std::string& i : props) {
+        // split NAME=VALUE
+        const std::string::size_type assignment = i.find('=');
+        if (assignment != std::string::npos) {
+          const std::string propName = vsGlobal + i.substr(0, assignment);
+          const std::string propValue = i.substr(assignment + 1);
+          initPropValue(propName, propValue.c_str());
         }
       }
     }
@@ -1144,11 +1139,6 @@
 
 void cmTarget::SetProperty(const std::string& prop, const char* value)
 {
-  if (!cmTargetPropertyComputer::PassesWhitelist(
-        this->GetType(), prop, impl->Makefile->GetMessenger(),
-        impl->Makefile->GetBacktrace())) {
-    return;
-  }
 #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
   MAKE_STATIC_PROP(C_STANDARD);
   MAKE_STATIC_PROP(CXX_STANDARD);
@@ -1355,11 +1345,6 @@
 void cmTarget::AppendProperty(const std::string& prop,
                               const std::string& value, bool asString)
 {
-  if (!cmTargetPropertyComputer::PassesWhitelist(
-        this->GetType(), prop, impl->Makefile->GetMessenger(),
-        impl->Makefile->GetBacktrace())) {
-    return;
-  }
   if (prop == "NAME") {
     impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                  "NAME property is read-only\n");
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index e714720..9e30136 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -123,7 +123,7 @@
   }
   if (!content.empty()) {
     if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
-        scope != "INTERFACE") {
+        scope != "INTERFACE" && this->Property != "SOURCES") {
       this->SetError("may only set INTERFACE properties on INTERFACE targets");
       return false;
     }
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index f37995c..b9c9365 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -3,15 +3,12 @@
 
 #include "cmTargetPropertyComputer.h"
 
-#include <cctype>
 #include <sstream>
-#include <unordered_set>
 
 #include "cmMessageType.h"
 #include "cmMessenger.h"
 #include "cmPolicies.h"
 #include "cmStateSnapshot.h"
-#include "cmStringAlgorithms.h"
 
 bool cmTargetPropertyComputer::HandleLocationPropertyPolicy(
   std::string const& tgtName, cmMessenger* messenger,
@@ -44,69 +41,3 @@
 
   return messageType != MessageType::FATAL_ERROR;
 }
-
-bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
-  const std::string& prop)
-{
-  if (cmHasLiteralPrefix(prop, "INTERFACE_")) {
-    return true;
-  }
-  if (cmHasLiteralPrefix(prop, "_")) {
-    return true;
-  }
-  if (std::islower(prop[0])) {
-    return true;
-  }
-  static std::unordered_set<std::string> const builtIns{
-    "COMPATIBLE_INTERFACE_BOOL",
-    "COMPATIBLE_INTERFACE_NUMBER_MAX",
-    "COMPATIBLE_INTERFACE_NUMBER_MIN",
-    "COMPATIBLE_INTERFACE_STRING",
-    "DEPRECATION",
-    "EXPORT_NAME",
-    "EXPORT_PROPERTIES",
-    "IMPORTED",
-    "IMPORTED_GLOBAL",
-    "MANUALLY_ADDED_DEPENDENCIES",
-    "NAME",
-    "PRIVATE_HEADER",
-    "PUBLIC_HEADER",
-    "TYPE"
-  };
-
-  if (builtIns.count(prop)) {
-    return true;
-  }
-
-  if (prop == "IMPORTED_CONFIGURATIONS" || prop == "IMPORTED_LIBNAME" ||
-      cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME_") ||
-      cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) {
-    return true;
-  }
-
-  // This property should not be allowed but was incorrectly added in
-  // CMake 3.8.  We can't remove it from the whitelist without breaking
-  // projects that try to set it.  One day we could warn about this, but
-  // for now silently accept it.
-  if (prop == "NO_SYSTEM_FROM_IMPORTED") {
-    return true;
-  }
-
-  return false;
-}
-
-bool cmTargetPropertyComputer::PassesWhitelist(
-  cmStateEnums::TargetType tgtType, std::string const& prop,
-  cmMessenger* messenger, cmListFileBacktrace const& context)
-{
-  if (tgtType == cmStateEnums::INTERFACE_LIBRARY &&
-      !WhiteListedInterfaceProperty(prop)) {
-    std::ostringstream e;
-    e << "INTERFACE_LIBRARY targets may only have whitelisted properties.  "
-         "The property \""
-      << prop << "\" is not allowed.";
-    messenger->IssueMessage(MessageType::FATAL_ERROR, e.str(), context);
-    return false;
-  }
-  return true;
-}
diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h
index f87b7c2..bafa43b 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -35,12 +35,6 @@
     return nullptr;
   }
 
-  static bool WhiteListedInterfaceProperty(const std::string& prop);
-
-  static bool PassesWhitelist(cmStateEnums::TargetType tgtType,
-                              std::string const& prop, cmMessenger* messenger,
-                              cmListFileBacktrace const& context);
-
 private:
   static bool HandleLocationPropertyPolicy(std::string const& tgtName,
                                            cmMessenger* messenger,
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 6369c1f..db9dc53 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -315,8 +315,7 @@
 void cmVisualStudio10TargetGenerator::Generate()
 {
   // do not generate external ms projects
-  if (this->GeneratorTarget->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-      this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
+  if (this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
     return;
   }
   const std::string ProjectFileExtension =
@@ -437,7 +436,7 @@
       e1.Element("ProjectGuid", "{" + this->GUID + "}");
 
       if ((this->MSTools || this->Android) &&
-          this->GeneratorTarget->GetType() <= cmStateEnums::GLOBAL_TARGET) {
+          this->GeneratorTarget->IsInBuildSystem()) {
         this->WriteApplicationTypeSettings(e1);
         this->VerifyNecessaryFiles();
       }
@@ -605,11 +604,11 @@
             }
             break;
           case cmStateEnums::UTILITY:
+          case cmStateEnums::INTERFACE_LIBRARY:
           case cmStateEnums::GLOBAL_TARGET:
             outputType = "Utility";
             break;
           case cmStateEnums::UNKNOWN_LIBRARY:
-          case cmStateEnums::INTERFACE_LIBRARY:
             break;
         }
         e1.Element("OutputType", outputType);
@@ -1157,6 +1156,7 @@
             }
             break;
           case cmStateEnums::UTILITY:
+          case cmStateEnums::INTERFACE_LIBRARY:
           case cmStateEnums::GLOBAL_TARGET:
             if (this->NsightTegra) {
               // Tegra-Android platform does not understand "Utility".
@@ -1166,7 +1166,6 @@
             }
             break;
           case cmStateEnums::UNKNOWN_LIBRARY:
-          case cmStateEnums::INTERFACE_LIBRARY:
             break;
         }
       }
@@ -2152,7 +2151,7 @@
 
 void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
 {
-  if (this->GeneratorTarget->GetType() > cmStateEnums::UTILITY) {
+  if (this->GeneratorTarget->GetType() == cmStateEnums::GLOBAL_TARGET) {
     return;
   }
 
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index dcb96f8..f630a7e 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -93,9 +93,13 @@
 #if defined(CMAKE_USE_WMAKE)
 #  include "cmGlobalWatcomWMakeGenerator.h"
 #endif
-#include "cmGlobalUnixMakefileGenerator3.h"
 #if !defined(CMAKE_BOOTSTRAP)
 #  include "cmGlobalNinjaGenerator.h"
+#  include "cmGlobalUnixMakefileGenerator3.h"
+#elif defined(CMAKE_BOOTSTRAP_MAKEFILES)
+#  include "cmGlobalUnixMakefileGenerator3.h"
+#elif defined(CMAKE_BOOTSTRAP_NINJA)
+#  include "cmGlobalNinjaGenerator.h"
 #endif
 
 #if !defined(CMAKE_BOOTSTRAP)
@@ -1750,6 +1754,9 @@
     gen = cm::make_unique<cmGlobalNMakeMakefileGenerator>(this);
   }
   return std::unique_ptr<cmGlobalGenerator>(std::move(gen));
+#elif defined(CMAKE_BOOTSTRAP_NINJA)
+  return std::unique_ptr<cmGlobalGenerator>(
+    cm::make_unique<cmGlobalNinjaGenerator>(this));
 #else
   return std::unique_ptr<cmGlobalGenerator>(
     cm::make_unique<cmGlobalUnixMakefileGenerator3>(this));
@@ -2026,13 +2033,17 @@
   this->Generators.push_back(cmGlobalMSYSMakefileGenerator::NewFactory());
   this->Generators.push_back(cmGlobalMinGWMakefileGenerator::NewFactory());
 #endif
-  this->Generators.push_back(cmGlobalUnixMakefileGenerator3::NewFactory());
 #if !defined(CMAKE_BOOTSTRAP)
 #  if defined(__linux__) || defined(_WIN32)
   this->Generators.push_back(cmGlobalGhsMultiGenerator::NewFactory());
 #  endif
+  this->Generators.push_back(cmGlobalUnixMakefileGenerator3::NewFactory());
   this->Generators.push_back(cmGlobalNinjaGenerator::NewFactory());
   this->Generators.push_back(cmGlobalNinjaMultiGenerator::NewFactory());
+#elif defined(CMAKE_BOOTSTRAP_NINJA)
+  this->Generators.push_back(cmGlobalNinjaGenerator::NewFactory());
+#elif defined(CMAKE_BOOTSTRAP_MAKEFILES)
+  this->Generators.push_back(cmGlobalUnixMakefileGenerator3::NewFactory());
 #endif
 #if defined(CMAKE_USE_WMAKE)
   this->Generators.push_back(cmGlobalWatcomWMakeGenerator::NewFactory());
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 1a5fea1..15d2fd1 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1161,7 +1161,7 @@
       return cmcmd::ExecuteLinkScript(args);
     }
 
-#ifndef CMAKE_BOOTSTRAP
+#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_NINJA)
     // Internal CMake ninja dependency scanning support.
     if (args[1] == "cmake_ninja_depends") {
       return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end());
@@ -1772,7 +1772,7 @@
   //   args[2] == source_file_path
   //   args[3] == intermediate_file
   //   args[4..n] == preprocess+args
-  //   args[n+1] == --
+  //   args[n+1] == ++
   //   args[n+2...] == llvm-rc+args
   if (args.size() < 3) {
     std::cerr << "Invalid cmake_llvm_rc arguments";
@@ -1784,7 +1784,11 @@
   std::vector<std::string> resource_compile;
   std::vector<std::string>* pArgTgt = &preprocess;
   for (std::string const& arg : cmMakeRange(args).advance(4)) {
-    if (arg == "--") {
+    // We use ++ as seperator between the preprocessing step definition and the
+    // rc compilation step becase we need to prepend a -- to seperate the
+    // source file properly from other options when using clang-cl for
+    // preprocessing.
+    if (arg == "++") {
       pArgTgt = &resource_compile;
     } else {
       if (arg.find("SOURCE_DIR") != std::string::npos) {
diff --git a/Tests/BootstrapTest.cmake b/Tests/BootstrapTest.cmake
index 07a65bf..137de78 100644
--- a/Tests/BootstrapTest.cmake
+++ b/Tests/BootstrapTest.cmake
@@ -1,12 +1,15 @@
 file(MAKE_DIRECTORY "${bin_dir}")
 include(ProcessorCount)
 ProcessorCount(nproc)
+if(generator MATCHES "Ninja")
+  set(ninja_arg --generator=Ninja)
+endif()
 if(NOT nproc EQUAL 0)
   set(parallel_arg --parallel=${nproc})
 endif()
-message(STATUS "running bootstrap: ${bootstrap} ${parallel_arg}")
+message(STATUS "running bootstrap: ${bootstrap} ${ninja_arg} ${parallel_arg}")
 execute_process(
-  COMMAND ${bootstrap} ${parallel_arg}
+  COMMAND ${bootstrap} ${ninja_arg} ${parallel_arg}
   WORKING_DIRECTORY "${bin_dir}"
   RESULT_VARIABLE result
   )
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 4a774dd..e4e09fa 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -3240,6 +3240,7 @@
       COMMAND ${CMAKE_CMAKE_COMMAND}
         -D "bootstrap=${bootstrap}"
         -D "bin_dir=${CMake_BINARY_DIR}/Tests/BootstrapTest"
+        -D "generator=${CMAKE_GENERATOR}"
         -P ${CMAKE_CURRENT_SOURCE_DIR}/BootstrapTest.cmake
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BootstrapTest")
diff --git a/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt
index 43b7217..ba2164b 100644
--- a/Tests/ExportImport/Export/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Export/Interface/CMakeLists.txt
@@ -1,11 +1,26 @@
-
-add_library(headeronly INTERFACE)
+set(headeronly_headers headeronly/headeronly.h)
+add_library(headeronly INTERFACE ${headeronly_headers})
 set_property(TARGET headeronly PROPERTY INTERFACE_INCLUDE_DIRECTORIES
   "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/headeronly>"
   "$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/headeronly>"
 )
 set_property(TARGET headeronly PROPERTY INTERFACE_COMPILE_DEFINITIONS "HEADERONLY_DEFINE")
 
+add_custom_command(OUTPUT headergen/headergen.h
+  COMMAND ${CMAKE_COMMAND} -E copy
+    ${CMAKE_CURRENT_SOURCE_DIR}/headergen.h.in
+    ${CMAKE_CURRENT_BINARY_DIR}/headergen/headergen.h
+  DEPENDS
+    ${CMAKE_CURRENT_SOURCE_DIR}/headergen.h.in
+  VERBATIM)
+
+add_library(headergen INTERFACE headergen/headergen.h)
+set_property(TARGET headergen PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+  "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/headergen>"
+)
+set_property(TARGET headergen PROPERTY PUBLIC_HEADER
+  ${CMAKE_CURRENT_BINARY_DIR}/headergen/headergen.h)
+
 add_library(pch_iface INTERFACE)
 target_precompile_headers(pch_iface INTERFACE
   "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/pch/pch.h>"
@@ -54,6 +69,11 @@
                 pch_iface cmakeonly
   EXPORT expInterface
 )
+install(TARGETS headergen
+  EXPORT expInterface
+  PUBLIC_HEADER DESTINATION include/headergen
+  INCLUDES DESTINATION include/headergen
+)
 install(TARGETS sharedlib
   EXPORT expInterface
   RUNTIME DESTINATION bin
@@ -63,7 +83,7 @@
   BUNDLE DESTINATION Applications
 )
 install(FILES
-  headeronly/headeronly.h
+  ${headeronly_headers}
   DESTINATION include/headeronly
 )
 install(FILES
diff --git a/Tests/ExportImport/Export/Interface/headergen.h.in b/Tests/ExportImport/Export/Interface/headergen.h.in
new file mode 100644
index 0000000..bda2b81
--- /dev/null
+++ b/Tests/ExportImport/Export/Interface/headergen.h.in
@@ -0,0 +1 @@
+#define HEADERGEN_H
diff --git a/Tests/ExportImport/Import/Interface/CMakeLists.txt b/Tests/ExportImport/Import/Interface/CMakeLists.txt
index ef666b1..202c23e 100644
--- a/Tests/ExportImport/Import/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Import/Interface/CMakeLists.txt
@@ -12,6 +12,9 @@
 add_executable(headeronlytest_bld headeronlytest.cpp)
 target_link_libraries(headeronlytest_bld bld::headeronly)
 
+add_executable(headergentest_bld headergentest.cpp)
+target_link_libraries(headergentest_bld bld::headergen)
+
 set_property(TARGET bld::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
 
 add_executable(interfacetest_bld interfacetest.cpp)
@@ -93,6 +96,9 @@
 add_executable(headeronlytest_exp headeronlytest.cpp)
 target_link_libraries(headeronlytest_exp exp::headeronly)
 
+add_executable(headergentest_exp headergentest.cpp)
+target_link_libraries(headergentest_exp exp::headergen)
+
 set_property(TARGET exp::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
 
 add_executable(interfacetest_exp interfacetest.cpp)
diff --git a/Tests/ExportImport/Import/Interface/headergentest.cpp b/Tests/ExportImport/Import/Interface/headergentest.cpp
new file mode 100644
index 0000000..88ff7f1
--- /dev/null
+++ b/Tests/ExportImport/Import/Interface/headergentest.cpp
@@ -0,0 +1,11 @@
+
+#include "headergen.h"
+
+#ifndef HEADERGEN_H
+#  error Expected HEADERGEN_H
+#endif
+
+int main()
+{
+  return 0;
+}
diff --git a/Tests/FindPython/FindPythonScript.cmake b/Tests/FindPython/FindPythonScript.cmake
index bc7e0d1..808496e 100644
--- a/Tests/FindPython/FindPythonScript.cmake
+++ b/Tests/FindPython/FindPythonScript.cmake
@@ -1,4 +1,4 @@
-
+cmake_minimum_required(VERSION 3.12)
 if (PYTHON_MUST_NOT_BE_FOUND)
   find_package(${PYTHON_PACKAGE_NAME} QUIET)
   if (${PYTHON_PACKAGE_NAME}_FOUND)
diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt
index 311ca2a..ec0a604 100644
--- a/Tests/InterfaceLibrary/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/CMakeLists.txt
@@ -44,6 +44,7 @@
 target_link_libraries(InterfaceLibrary
   iface_nodepends
   headeriface
+  iface_genheader
   subiface
   intermediate
 
diff --git a/Tests/InterfaceLibrary/definetestexe.cpp b/Tests/InterfaceLibrary/definetestexe.cpp
index 9156426..6c53840 100644
--- a/Tests/InterfaceLibrary/definetestexe.cpp
+++ b/Tests/InterfaceLibrary/definetestexe.cpp
@@ -15,6 +15,12 @@
 #  error Expected IFACE_HEADER_BUILDDIR
 #endif
 
+#include "iface_genheader.h"
+
+#ifndef IFACE_GENHEADER
+#  error Expected IFACE_GENHEADER
+#endif
+
 extern int obj();
 extern int sub();
 extern int item();
diff --git a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
index 826a9ed..ae030d7 100644
--- a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
@@ -11,3 +11,12 @@
   VERBATIM
   )
 add_dependencies(headeriface headeriface_gen)
+
+add_custom_command(OUTPUT iface_genheader.h
+  COMMAND ${CMAKE_COMMAND} -E copy
+    ${CMAKE_CURRENT_SOURCE_DIR}/iface_genheader.h.in
+    ${CMAKE_CURRENT_BINARY_DIR}/iface_genheader.h
+  DEPENDS
+    ${CMAKE_CURRENT_SOURCE_DIR}/iface_genheader.h.in
+  VERBATIM)
+add_library(iface_genheader INTERFACE iface_genheader.h)
diff --git a/Tests/InterfaceLibrary/headerdir/iface_genheader.h.in b/Tests/InterfaceLibrary/headerdir/iface_genheader.h.in
new file mode 100644
index 0000000..0a21b62
--- /dev/null
+++ b/Tests/InterfaceLibrary/headerdir/iface_genheader.h.in
@@ -0,0 +1 @@
+#define IFACE_GENHEADER
diff --git a/Tests/QtAutogen/MocIncludeSymlink/CMakeLists.txt b/Tests/QtAutogen/MocIncludeSymlink/CMakeLists.txt
index 1627b39..8b11b46 100644
--- a/Tests/QtAutogen/MocIncludeSymlink/CMakeLists.txt
+++ b/Tests/QtAutogen/MocIncludeSymlink/CMakeLists.txt
@@ -61,6 +61,7 @@
     "${sourceDir}"
     MocInclude
     CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+                "-DCMAKE_AUTOMOC_PATH_PREFIX=ON"
                 "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}"
                 "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
     OUTPUT_VARIABLE output
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index b20e683..2a5d5d3 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -779,15 +779,15 @@
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
   run_cmake_command(llvm_rc_no_args ${CMAKE_COMMAND} -E cmake_llvm_rc)
   run_cmake_command(llvm_rc_no_-- ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test")
-  run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp -- ${CMAKE_COMMAND} -E echo "This is a test")
-  run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -P FailedProgram.cmake -- ${CMAKE_COMMAND} -E echo "This is a test")
-  run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -P FailedProgram.cmake )
+  run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ++ ${CMAKE_COMMAND} -E echo "This is a test")
+  run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -P FailedProgram.cmake ++ ${CMAKE_COMMAND} -E echo "This is a test")
+  run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${CMAKE_COMMAND} -P FailedProgram.cmake )
   if(EXISTS ${RunCMake_TEST_BINARY_DIR}/test.tmp)
       message(SEND_ERROR "${test} - FAILED:\n"
         "test.tmp was not deleted")
   endif()
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir")
-  run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -E copy test.tmp SOURCE_DIR/llvmrc.result )
+  run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${CMAKE_COMMAND} -E copy test.tmp SOURCE_DIR/llvmrc.result )
   if(EXISTS ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/test.tmp)
       message(SEND_ERROR "${test} - FAILED:\n"
         "test.tmp was not deleted")
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index b567bf1..c66757f 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -522,6 +522,7 @@
         read_codemodel_json_data("directories/custom.json"),
         read_codemodel_json_data("directories/cxx.json"),
         read_codemodel_json_data("directories/imported.json"),
+        read_codemodel_json_data("directories/interface.json"),
         read_codemodel_json_data("directories/object.json"),
         read_codemodel_json_data("directories/dir.json"),
         read_codemodel_json_data("directories/dir_dir.json"),
@@ -594,6 +595,10 @@
         read_codemodel_json_data("targets/link_imported_object_exe.json"),
         read_codemodel_json_data("targets/link_imported_interface_exe.json"),
 
+        read_codemodel_json_data("targets/all_build_interface.json"),
+        read_codemodel_json_data("targets/zero_check_interface.json"),
+        read_codemodel_json_data("targets/iface_srcs.json"),
+
         read_codemodel_json_data("targets/all_build_custom.json"),
         read_codemodel_json_data("targets/zero_check_custom.json"),
         read_codemodel_json_data("targets/custom_tgt.json"),
@@ -722,6 +727,7 @@
         read_codemodel_json_data("projects/alias.json"),
         read_codemodel_json_data("projects/object.json"),
         read_codemodel_json_data("projects/imported.json"),
+        read_codemodel_json_data("projects/interface.json"),
         read_codemodel_json_data("projects/custom.json"),
         read_codemodel_json_data("projects/external.json"),
     ]
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json
new file mode 100644
index 0000000..b10d496
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json
@@ -0,0 +1,14 @@
+{
+    "source": "^interface$",
+    "build": "^interface$",
+    "parentSource": "^\\.$",
+    "childSources": null,
+    "targetIds": [
+        "^ALL_BUILD::@25b7fa8ea00134654b85$",
+        "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+        "^iface_srcs::@25b7fa8ea00134654b85$"
+    ],
+    "projectName": "Interface",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
index c144953..736d1f5 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
@@ -7,6 +7,7 @@
         "^custom$",
         "^cxx$",
         "^imported$",
+        "^interface$",
         "^object$",
         "^.*/Tests/RunCMake/FileAPIExternalSource$",
         "^dir$"
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
index f3aac63..4d0cdc0 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
@@ -6,6 +6,7 @@
         "Custom",
         "Cxx",
         "Imported",
+        "Interface",
         "Object",
         "External"
     ],
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/interface.json
new file mode 100644
index 0000000..2a22767
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/interface.json
@@ -0,0 +1,13 @@
+{
+    "name": "Interface",
+    "parentName": "codemodel-v2",
+    "childNames": null,
+    "directorySources": [
+        "^interface$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@25b7fa8ea00134654b85$",
+        "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+        "^iface_srcs::@25b7fa8ea00134654b85$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json
new file mode 100644
index 0000000..fa2a6e5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json
@@ -0,0 +1,79 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@25b7fa8ea00134654b85$",
+    "directorySource": "^interface$",
+    "projectName": "Interface",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^interface$",
+    "source": "^interface$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        },
+        {
+            "id": "^iface_srcs::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
index 59bd750..d023f99 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
@@ -176,6 +176,10 @@
             "backtrace": null
         },
         {
+            "id": "^iface_srcs::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        },
+        {
             "id": "^custom_exe::@c11385ffed57b860da63$",
             "backtrace": null
         },
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
index e7ab55b..c9e652b 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
@@ -119,7 +119,7 @@
                 "backtrace": [
                     {
                         "file": "^codemodel-v2\\.cmake$",
-                        "line": 37,
+                        "line": 38,
                         "command": "install",
                         "hasParent": true
                     },
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json
new file mode 100644
index 0000000..97d7ccd
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json
@@ -0,0 +1,67 @@
+{
+    "name": "iface_srcs",
+    "id": "^iface_srcs::@25b7fa8ea00134654b85$",
+    "directorySource": "^interface$",
+    "projectName": "Interface",
+    "type": "INTERFACE_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": 3,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^interface$",
+    "source": "^interface$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json
new file mode 100644
index 0000000..fdd4b2a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+    "directorySource": "^interface$",
+    "projectName": "Interface",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^interface$",
+    "source": "^interface$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
index c98a84c..2405954 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake
+++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
@@ -18,6 +18,7 @@
 add_subdirectory(alias)
 add_subdirectory(object)
 add_subdirectory(imported)
+add_subdirectory(interface)
 add_subdirectory(custom)
 add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../FileAPIExternalSource" "${CMAKE_CURRENT_BINARY_DIR}/../FileAPIExternalBuild")
 add_subdirectory(dir)
diff --git a/Tests/RunCMake/FileAPI/interface/CMakeLists.txt b/Tests/RunCMake/FileAPI/interface/CMakeLists.txt
new file mode 100644
index 0000000..97948c5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/interface/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(Interface)
+add_library(iface_none INTERFACE)
+add_library(iface_srcs INTERFACE ../empty.c)
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
index dc77915..4e6eef6 100644
--- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -1,5 +1,10 @@
 include(RunCMake)
 
+# Isolate test cases from caller's environment.
+set(ENV{CMAKE_PREFIX_PATH} "")
+set(ENV{CMAKE_APPBUNDLE_PATH} "")
+set(ENV{CMAKE_FRAMEWORK_PATH} "")
+
 run_cmake(PkgConfigDoesNotExist)
 
 run_cmake(FindPkgConfig_NO_PKGCONFIG_PATH)
diff --git a/Tests/RunCMake/InterfaceLibrary/ConfigSources.cmake b/Tests/RunCMake/InterfaceLibrary/ConfigSources.cmake
new file mode 100644
index 0000000..631a845
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ConfigSources.cmake
@@ -0,0 +1,2 @@
+# Test an interface library added to the build system by a per-config source.
+add_library(iface INTERFACE $<$<CONFIG:NotAConfig>:${CMAKE_CURRENT_SOURCE_DIR}/iface.c>)
diff --git a/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-result.txt b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-stdout.txt b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-stdout.txt
new file mode 100644
index 0000000..aac9172
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-stdout.txt
@@ -0,0 +1 @@
+iface2|Invalid project
diff --git a/Tests/RunCMake/InterfaceLibrary/EmptySources.cmake b/Tests/RunCMake/InterfaceLibrary/EmptySources.cmake
new file mode 100644
index 0000000..f452394
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/EmptySources.cmake
@@ -0,0 +1,8 @@
+# Test an interface library added to the build system by empty SOURCES.
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY SOURCES "")
+
+# ...but not added by unset SOURCES.
+add_library(iface2 INTERFACE)
+set_property(TARGET iface2 PROPERTY SOURCES "")
+set_property(TARGET iface2 PROPERTY SOURCES)
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build1-check.cmake b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build1-check.cmake
new file mode 100644
index 0000000..6500e48
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build1-check.cmake
@@ -0,0 +1,4 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/iface.txt")
+  set(RunCMake_TEST_FAILED "iface target built as part of 'all'")
+  return()
+endif()
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build2-check.cmake b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build2-check.cmake
new file mode 100644
index 0000000..0977c24
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build2-check.cmake
@@ -0,0 +1,4 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/iface.txt")
+  set(RunCMake_TEST_FAILED "iface target not built")
+  return()
+endif()
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-result.txt b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-stdout.txt b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-stdout.txt
new file mode 100644
index 0000000..aac9172
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-stdout.txt
@@ -0,0 +1 @@
+iface2|Invalid project
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll.cmake b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll.cmake
new file mode 100644
index 0000000..714161d
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll.cmake
@@ -0,0 +1,7 @@
+# Test an interface library with a custom command, but excluded from all.
+add_custom_command(OUTPUT iface.txt COMMAND ${CMAKE_COMMAND} -E touch iface.txt)
+add_library(iface INTERFACE EXCLUDE_FROM_ALL iface.txt)
+
+# Test that EXCLUDE_FROM_ALL is allowed even if the interface library has
+# no sources, and does not cause it to appear in the build system.
+add_library(iface2 INTERFACE EXCLUDE_FROM_ALL)
diff --git a/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-result.txt b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-stdout.txt b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-stdout.txt
new file mode 100644
index 0000000..aac9172
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-stdout.txt
@@ -0,0 +1 @@
+iface2|Invalid project
diff --git a/Tests/RunCMake/InterfaceLibrary/PublicSources.cmake b/Tests/RunCMake/InterfaceLibrary/PublicSources.cmake
new file mode 100644
index 0000000..24785bb
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/PublicSources.cmake
@@ -0,0 +1,20 @@
+cmake_policy(SET CMP0076 NEW)
+enable_language(C)
+
+# Test that an interface library can have PUBLIC sources.
+# This causes the target to appear in the build system
+# *and* causes consumers to use the source.
+add_library(iface INTERFACE)
+target_sources(iface
+  PUBLIC iface.c
+  # Private sources do not compile here or propagate.
+  PRIVATE iface_broken.c
+  )
+
+# Test that an intermediate interface library does not get the
+# sources and does not appear in the build system.
+add_library(iface2 INTERFACE)
+target_link_libraries(iface2 INTERFACE iface)
+
+add_executable(use_iface use_iface.c)
+target_link_libraries(use_iface PRIVATE iface2)
diff --git a/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake b/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake
index 5a6af1d..834b3c8 100644
--- a/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake
+++ b/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake
@@ -3,7 +3,6 @@
 run_cmake(invalid_name)
 run_cmake(target_commands)
 run_cmake(no_shared_libs)
-run_cmake(whitelist)
 run_cmake(invalid_signature)
 run_cmake(global-interface)
 run_cmake(genex_link)
@@ -11,3 +10,27 @@
 run_cmake(IMPORTED_LIBNAME-bad-value)
 run_cmake(IMPORTED_LIBNAME-non-iface)
 run_cmake(IMPORTED_LIBNAME-non-imported)
+
+function(run_WithSources CASE)
+  if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
+  run_cmake(${CASE})
+  set(RunCMake_TEST_NO_CLEAN 1)
+  foreach(build IN LISTS ARGN)
+    if(build MATCHES "^([^:]+)$")
+      run_cmake_command(${CASE}-${CMAKE_MATCH_1} ${CMAKE_COMMAND} --build . --config Debug)
+    elseif(build MATCHES "^([^:]+):([^:,]+)(,merge)?$")
+      if(CMAKE_MATCH_3 STREQUAL ",merge")
+        set(RunCMake_TEST_OUTPUT_MERGE 1)
+      endif()
+      run_cmake_command(${CASE}-${CMAKE_MATCH_1} ${CMAKE_COMMAND} --build . --config Debug --target ${CMAKE_MATCH_2})
+    endif()
+  endforeach()
+endfunction()
+
+run_WithSources(ConfigSources "build1:iface")
+run_WithSources(EmptySources "build1:iface" "build2:iface2,merge")
+run_WithSources(ExcludeFromAll "build1" "build2:iface" "build3:iface2,merge")
+run_WithSources(PublicSources "build1" "build2:iface" "build3:iface2,merge")
diff --git a/Tests/RunCMake/InterfaceLibrary/iface.c b/Tests/RunCMake/InterfaceLibrary/iface.c
new file mode 100644
index 0000000..c7e7372
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/iface.c
@@ -0,0 +1,4 @@
+int iface(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/InterfaceLibrary/iface_broken.c b/Tests/RunCMake/InterfaceLibrary/iface_broken.c
new file mode 100644
index 0000000..4ff7f31
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/iface_broken.c
@@ -0,0 +1 @@
+#error This file should not compile
diff --git a/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt b/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
index 6374b33..763f9f8 100644
--- a/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
+++ b/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
@@ -1,8 +1,3 @@
-CMake Error at invalid_signature.cmake:2 \(add_library\):
-  add_library INTERFACE library requires no source arguments.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
 CMake Error at invalid_signature.cmake:3 \(add_library\):
   add_library INTERFACE library specified with conflicting/multiple types.
 Call Stack \(most recent call first\):
@@ -73,16 +68,6 @@
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
 +
-CMake Error at invalid_signature.cmake:17 \(add_library\):
-  add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:18 \(add_library\):
-  add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
 CMake Error at invalid_signature.cmake:20 \(add_library\):
   add_library GLOBAL option may only be used with IMPORTED libraries.
 Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake b/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
index 4e53534..2a575b5 100644
--- a/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
+++ b/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
@@ -1,5 +1,5 @@
 
-add_library(iface1 INTERFACE empty.cpp)
+
 add_library(iface3 STATIC INTERFACE)
 add_library(iface4 STATIC INTERFACE empty.cpp)
 add_library(iface5 SHARED INTERFACE)
@@ -14,7 +14,7 @@
 add_library(iface14 INTERFACE ALIAS)
 add_library(iface15 ALIAS INTERFACE)
 add_library(iface16 INTERFACE INTERFACE)
-add_library(iface17 INTERFACE EXCLUDE_FROM_ALL)
-add_library(iface18 EXCLUDE_FROM_ALL INTERFACE)
+
+
 # add_library(iface19 GLOBAL INTERFACE) Tested separately
 add_library(iface20 INTERFACE GLOBAL)
diff --git a/Tests/RunCMake/InterfaceLibrary/use_iface.c b/Tests/RunCMake/InterfaceLibrary/use_iface.c
new file mode 100644
index 0000000..66293e4
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/use_iface.c
@@ -0,0 +1,6 @@
+extern int iface(void);
+
+int main(void)
+{
+  return iface();
+}
diff --git a/Tests/RunCMake/InterfaceLibrary/whitelist-result.txt b/Tests/RunCMake/InterfaceLibrary/whitelist-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/InterfaceLibrary/whitelist-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/InterfaceLibrary/whitelist-stderr.txt b/Tests/RunCMake/InterfaceLibrary/whitelist-stderr.txt
deleted file mode 100644
index 577c0cc..0000000
--- a/Tests/RunCMake/InterfaceLibrary/whitelist-stderr.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-CMake Error at whitelist.cmake:4 \(set_property\):
-  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
-  property "OUTPUT_NAME" is not allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-
-
-CMake Error at whitelist.cmake:5 \(set_property\):
-  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
-  property "OUTPUT_NAME" is not allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-
-
-CMake Error at whitelist.cmake:6 \(get_target_property\):
-  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
-  property "OUTPUT_NAME" is not allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/InterfaceLibrary/whitelist.cmake b/Tests/RunCMake/InterfaceLibrary/whitelist.cmake
deleted file mode 100644
index 0db6375..0000000
--- a/Tests/RunCMake/InterfaceLibrary/whitelist.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-
-add_library(iface INTERFACE)
-
-set_property(TARGET iface PROPERTY OUTPUT_NAME output)
-set_property(TARGET iface APPEND PROPERTY OUTPUT_NAME append)
-get_target_property(outname iface OUTPUT_NAME)
-
-# Properties starting with `_` are allowed.
-set_property(TARGET iface PROPERTY "_custom_property" output)
-set_property(TARGET iface APPEND PROPERTY "_custom_property" append)
-get_target_property(outname iface "_custom_property")
-
-# Properties starting with a lowercase letter are allowed.
-set_property(TARGET iface PROPERTY "custom_property" output)
-set_property(TARGET iface APPEND PROPERTY "custom_property" append)
-get_target_property(outname iface "custom_property")
-
-# PUBLIC_HEADER / PRIVATE_HEADER properties are allowed
-set_property(TARGET iface PROPERTY PUBLIC_HEADER foo.h)
-set_property(TARGET iface APPEND PROPERTY PUBLIC_HEADER bar.h)
-get_target_property(outname iface PUBLIC_HEADER)
-
-set_property(TARGET iface PROPERTY PRIVATE_HEADER foo.h)
-set_property(TARGET iface APPEND PROPERTY PRIVATE_HEADER bar.h)
-get_target_property(outname iface PRIVATE_HEADER)
diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake
index 6b2721c..32aafca 100644
--- a/Tests/RunCMake/Make/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Make/RunCMakeTest.cmake
@@ -27,12 +27,15 @@
   run_cmake_command(VerboseBuild-build ${CMAKE_COMMAND} --build . -v --clean-first)
   unset(RunCMake-stdout-file)
   set(_backup_lang "$ENV{LANG}")
+  set(_backup_lc_Messages "$ENV{LC_MESSAGES}")
   if(MAKE_IS_GNU)
     set(RunCMake-stdout-file VerboseBuild-nowork-gnu-stdout.txt)
     set(ENV{LANG} "C")
+    set(ENV{LC_MESSAGES} "C")
   endif()
   run_cmake_command(VerboseBuild-nowork ${CMAKE_COMMAND} --build . --verbose)
   set(ENV{LANG} "${_backup_lang}")
+  set(ENV{LC_MESSAGES} "${_backup_lc_messages}")
 endfunction()
 run_VerboseBuild()
 
diff --git a/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake b/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake
new file mode 100644
index 0000000..bcdc101
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake
@@ -0,0 +1,25 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/iface.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+  return()
+endif()
+
+set(found_iface_h 0)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+  if(line MATCHES "<([A-Za-z0-9_]+) +Include=.*iface\\.h")
+    set(rule "${CMAKE_MATCH_1}")
+    if(NOT rule STREQUAL "None")
+      set(RunCMake_TEST_FAILED "iface.h referenced as ${rule} instead of None in\n  ${vcProjectFile}")
+      return()
+    endif()
+    if(found_iface_h)
+      set(RunCMake_TEST_FAILED "iface.h referenced multiple times in\n  ${vcProjectFile}")
+      return()
+    endif()
+    set(found_iface_h 1)
+  endif()
+endforeach()
+if(NOT found_iface_h)
+  set(RunCMake_TEST_FAILED "iface.h not referenced in\n  ${vcProjectFile}")
+endif()
diff --git a/Tests/RunCMake/VS10Project/InterfaceLibSources.cmake b/Tests/RunCMake/VS10Project/InterfaceLibSources.cmake
new file mode 100644
index 0000000..3672be1
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/InterfaceLibSources.cmake
@@ -0,0 +1 @@
+add_library(iface INTERFACE iface.h)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 93ef603..e9f251a 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -6,6 +6,7 @@
 run_cmake(VsCsharpSourceGroup)
 run_cmake(VsCSharpCompilerOpts)
 run_cmake(ExplicitCMakeLists)
+run_cmake(InterfaceLibSources)
 run_cmake(RuntimeLibrary)
 run_cmake(SourceGroupCMakeLists)
 run_cmake(SourceGroupTreeCMakeLists)
diff --git a/Tests/RunCMake/VS10Project/iface.h b/Tests/RunCMake/VS10Project/iface.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/iface.h
diff --git a/Tests/RunCMake/XcodeProject/InterfaceLibSources-check.cmake b/Tests/RunCMake/XcodeProject/InterfaceLibSources-check.cmake
new file mode 100644
index 0000000..613951a
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/InterfaceLibSources-check.cmake
@@ -0,0 +1,16 @@
+set(xcProjectFile "${RunCMake_TEST_BINARY_DIR}/InterfaceLibSources.xcodeproj/project.pbxproj")
+if(NOT EXISTS "${xcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${xcProjectFile} does not exist.")
+  return()
+endif()
+
+set(found_iface_h 0)
+file(STRINGS "${xcProjectFile}" lines)
+foreach(line IN LISTS lines)
+  if(line MATCHES "PBXFileReference.*explicitFileType.*sourcecode\\.c\\.h.*iface\\.h")
+    set(found_iface_h 1)
+  endif()
+endforeach()
+if(NOT found_iface_h)
+  set(RunCMake_TEST_FAILED "iface.h not referenced in\n  ${xcProjectFile}")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/InterfaceLibSources.cmake b/Tests/RunCMake/XcodeProject/InterfaceLibSources.cmake
new file mode 100644
index 0000000..3672be1
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/InterfaceLibSources.cmake
@@ -0,0 +1 @@
+add_library(iface INTERFACE iface.h)
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index 342dbbc..cd6fd06 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -2,6 +2,7 @@
 
 run_cmake(ExplicitCMakeLists)
 run_cmake(ImplicitCMakeLists)
+run_cmake(InterfaceLibSources)
 
 run_cmake(XcodeFileType)
 run_cmake(XcodeAttributeLocation)
diff --git a/Tests/RunCMake/XcodeProject/iface.h b/Tests/RunCMake/XcodeProject/iface.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/iface.h
diff --git a/bootstrap b/bootstrap
index 2ef0fbb..eabe06b 100755
--- a/bootstrap
+++ b/bootstrap
@@ -236,6 +236,7 @@
 CMAKE_KNOWN_C_COMPILERS="cc gcc clang xlc icc tcc"
 CMAKE_KNOWN_CXX_COMPILERS="aCC xlC CC g++ clang++ c++ icc como "
 CMAKE_KNOWN_MAKE_PROCESSORS="gmake make"
+CMAKE_KNOWN_NINJA_PROCESSORS="ninja-build ninja"
 
 CMAKE_PROBLEMATIC_FILES="\
   CMakeCache.txt \
@@ -309,8 +310,6 @@
   cmCustomCommandLines \
   cmDefinePropertyCommand \
   cmDefinitions \
-  cmDepends \
-  cmDependsC \
   cmDocumentationFormatter \
   cmEnableLanguageCommand \
   cmEnableTestingCommand \
@@ -361,7 +360,6 @@
   cmGetTestPropertyCommand \
   cmGlobalCommonGenerator \
   cmGlobalGenerator \
-  cmGlobalUnixMakefileGenerator3 \
   cmGlobVerificationManager \
   cmHexFileConverter \
   cmIfCommand \
@@ -392,15 +390,10 @@
   cmListFileCache \
   cmLocalCommonGenerator \
   cmLocalGenerator \
-  cmLocalUnixMakefileGenerator3 \
   cmMSVC60LinkLineComputer \
   cmMacroCommand \
   cmMakeDirectoryCommand \
   cmMakefile \
-  cmMakefileExecutableTargetGenerator \
-  cmMakefileLibraryTargetGenerator \
-  cmMakefileTargetGenerator \
-  cmMakefileUtilityTargetGenerator \
   cmMarkAsAdvancedCommand \
   cmMathCommand \
   cmMessageCommand \
@@ -607,6 +600,8 @@
   --verbose               display more information
   --parallel=n            bootstrap cmake in parallel, where n is
                           number of nodes [1]
+  --generator=<generator> generator to use (MSYS Makefiles, Unix Makefiles,
+                          or Ninja)
   --enable-ccache         Enable ccache when building cmake
   --init=FILE             load FILE as script to populate cache
   --system-libs           use all system-installed third-party libraries
@@ -637,6 +632,8 @@
   --no-system-libuv       use cmake-provided libuv library (default)
 
   --bootstrap-system-libuv use system-installed libuv library for bootstrap
+  --bootstrap-system-jsoncpp use system-installed jsoncpp library for bootstrap
+  --bootstrap-system-librhash use system-installed librhash library for bootstrap
 
   --qt-gui                build the Qt-based GUI (requires Qt >= 4.2)
   --no-qt-gui             do not build the Qt-based GUI (default)
@@ -689,16 +686,23 @@
   exit ${res}
 }
 
+cmake_generate_file_tmp ()
+{
+  OUTFILE="$1"
+  TMPFILE="$2"
+  if "${_diff}" "$TMPFILE" "$OUTFILE" > /dev/null 2> /dev/null ; then
+    rm -f "$TMPFILE"
+  else
+    mv -f "$TMPFILE" "$OUTFILE"
+  fi
+}
+
 cmake_generate_file ()
 {
   OUTFILE="$1"
   CONTENT="$2"
   echo "$CONTENT" > "$OUTFILE.tmp"
-  if "${_diff}" "$OUTFILE.tmp" "$OUTFILE" > /dev/null 2> /dev/null ; then
-    rm -f "$OUTFILE.tmp"
-  else
-    mv -f "$OUTFILE.tmp" "$OUTFILE"
-  fi
+  cmake_generate_file_tmp "$OUTFILE" "$OUTFILE.tmp"
 }
 
 # Replace KWSYS_NAMESPACE with cmsys
@@ -760,8 +764,18 @@
   echo "$*" >> ${FILE}
 }
 
-# Escape spaces in strings
-cmake_escape ()
+# Escape spaces in strings for artifacts
+cmake_escape_artifact ()
+{
+  if test "${cmake_bootstrap_generator}" = "Ninja"; then
+    echo $1 | sed "s/ /$ /g"
+  else
+    echo $1 | sed "s/ /\\\\ /g"
+  fi
+}
+
+# Escape spaces in strings for shell
+cmake_escape_shell ()
 {
   echo $1 | sed "s/ /\\\\ /g"
 }
@@ -861,11 +875,14 @@
 cmake_ccache_enabled=
 cmake_prefix_dir="${cmake_default_prefix}"
 bootstrap_system_libuv=
+bootstrap_system_jsoncpp=
+bootstrap_system_librhash=
 while test $# != 0; do
   case "$1" in
   --prefix=*) dir=`cmake_arg "$1"`
               cmake_prefix_dir=`cmake_fix_slashes "$dir"` ;;
   --parallel=*) cmake_parallel_make=`cmake_arg "$1"` ;;
+  --generator=*) cmake_bootstrap_generator=`cmake_arg "$1"` ;;
   --bindir=*) cmake_bin_dir=`cmake_arg "$1"` ;;
   --datadir=*) cmake_data_dir=`cmake_arg "$1"` ;;
   --docdir=*) cmake_doc_dir=`cmake_arg "$1"` ;;
@@ -881,6 +898,8 @@
     lib=`cmake_arg "$1" "--no-system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
   --bootstrap-system-libuv) bootstrap_system_libuv="1" ;;
+  --bootstrap-system-jsoncpp) bootstrap_system_jsoncpp="1" ;;
+  --bootstrap-system-librhash) bootstrap_system_librhash="1" ;;
   --qt-gui) cmake_bootstrap_qt_gui="1" ;;
   --no-qt-gui) cmake_bootstrap_qt_gui="0" ;;
   --qt-qmake=*) cmake_bootstrap_qt_qmake=`cmake_arg "$1"` ;;
@@ -905,6 +924,13 @@
   shift
 done
 
+# Make sure the generator is valid
+if test "${cmake_bootstrap_generator}" != "MSYS Makefiles" -a \
+    "${cmake_bootstrap_generator}" != "Unix Makefiles" -a \
+    "${cmake_bootstrap_generator}" != "Ninja"; then
+  cmake_error 10 "Invalid generator: ${cmake_bootstrap_generator}"
+fi
+
 # If verbose, display some information about bootstrap
 if test -n "${cmake_verbose}"; then
   echo "---------------------------------------------"
@@ -912,6 +938,7 @@
   echo "Binary directory: ${cmake_binary_dir}"
   echo "Prefix directory: ${cmake_prefix_dir}"
   echo "System:           ${cmake_system}"
+  echo "Generator:        ${cmake_bootstrap_generator}"
   if test "x${cmake_parallel_make}" != "x"; then
     echo "Doing parallel make: ${cmake_parallel_make}"
   fi
@@ -980,6 +1007,58 @@
 cmake_cxx_flags=${CXXFLAGS}
 cmake_ld_flags=${LDFLAGS}
 
+# Add generator-specific files
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES} \
+    cmCryptoHash \
+    cmFortranParserImpl \
+    cmGlobalNinjaGenerator \
+    cmLocalNinjaGenerator \
+    cmNinjaLinkLineComputer \
+    cmNinjaLinkLineDeviceComputer \
+    cmNinjaNormalTargetGenerator \
+    cmNinjaTargetGenerator \
+    cmNinjaUtilityTargetGenerator \
+    "
+
+  LexerParser_CXX_SOURCES="${LexerParser_CXX_SOURCES} \
+    cmFortranLexer \
+    cmFortranParser \
+    "
+
+  JSONCPP_CXX_SOURCES="\
+    src/lib_json/json_reader.cpp \
+    src/lib_json/json_value.cpp \
+    src/lib_json/json_writer.cpp \
+    "
+
+  LIBRHASH_C_SOURCES="\
+    librhash/algorithms.c \
+    librhash/byte_order.c \
+    librhash/hex.c \
+    librhash/md5.c \
+    librhash/rhash.c \
+    librhash/sha1.c \
+    librhash/sha256.c \
+    librhash/sha3.c \
+    librhash/sha512.c \
+    "
+else
+  CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES} \
+    cmDepends \
+    cmDependsC \
+    cmGlobalUnixMakefileGenerator3 \
+    cmLocalUnixMakefileGenerator3 \
+    cmMakefileExecutableTargetGenerator \
+    cmMakefileLibraryTargetGenerator \
+    cmMakefileTargetGenerator \
+    cmMakefileUtilityTargetGenerator \
+    "
+
+  JSONCPP_CXX_SOURCES=
+  LIBRHASH_C_SOURCES=
+fi
+
 # Add Cygwin-specific flags
 if ${cmake_system_cygwin}; then
   cmake_ld_flags="${LDFLAGS} -Wl,--enable-auto-import"
@@ -1288,6 +1367,8 @@
 # If MAKE is set, use that for make processor, otherwise use list of known make
 if test -n "${MAKE}"; then
   cmake_make_processors="${MAKE}"
+elif test "${cmake_bootstrap_generator}" = "Ninja"; then
+  cmake_make_processors="${CMAKE_KNOWN_NINJA_PROCESSORS}"
 else
   cmake_make_processors="${CMAKE_KNOWN_MAKE_PROCESSORS}"
 fi
@@ -1296,10 +1377,18 @@
 rm -rf "${cmake_bootstrap_dir}/${TMPFILE}"
 mkdir "${cmake_bootstrap_dir}/${TMPFILE}"
 cd "${cmake_bootstrap_dir}/${TMPFILE}"
-echo '
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  echo '
+rule cc
+  command = "'"${cmake_c_compiler}"'" '"${cmake_ld_flags} ${cmake_c_flags}"' -o $out $in
+build test: cc test.c
+'>"build.ninja"
+else
+  echo '
 test: test.c
 	"'"${cmake_c_compiler}"'" '"${cmake_ld_flags} ${cmake_c_flags}"' -o test test.c
 '>"Makefile"
+fi
 echo '
 #include <stdio.h>
 int main(){ printf("1%c", (char)0x0a); return 0; }
@@ -1326,15 +1415,20 @@
 fi
 cd "${cmake_bootstrap_dir}"
 
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  mf_str=Ninja
+else
+  mf_str=Makefile
+fi
 if test -z "${cmake_make_processor}"; then
-  cmake_error 8 "Cannot find appropriate Makefile processor on this system.
+  cmake_error 8 "Cannot find appropriate ${mf_str} processor on this system.
 Please specify one using environment variable MAKE."
 fi
 rm -rf "${cmake_bootstrap_dir}/${TMPFILE}"
-echo "Makefile processor on this system is: ${cmake_make_processor}"
+echo "${mf_str} processor on this system is: ${cmake_make_processor}"
 if test "x${cmake_full_make_flags}" != "x${cmake_make_flags}"; then
   echo "---------------------------------------------"
-  echo "Makefile processor ${cmake_make_processor} does not support parallel build"
+  echo "${mf_str} processor ${cmake_make_processor} does not support parallel build"
   echo "---------------------------------------------"
 fi
 
@@ -1431,6 +1525,10 @@
  * ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}
  * libuv Sources:
  * ${LIBUV_C_SOURCES}
+ * jsoncpp Sources:
+ * ${JSONCPP_CXX_SOURCES}
+ * librhash Sources:
+ * ${LIBRHASH_C_SOURCES}
  */
 "
 
@@ -1458,6 +1556,12 @@
 cmake_report cmConfigure.h${_tmp} "#define CMAKE_DATA_DIR \"/bootstrap-not-insalled\""
 cmake_report cmConfigure.h${_tmp} "#define CM_FALLTHROUGH"
 
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP_NINJA"
+else
+  cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP_MAKEFILES"
+fi
+
 if ${cmake_system_mingw}; then
   cmake_report cmConfigure.h${_tmp} "#if defined(_WIN32) && !defined(NOMINMAX)"
   cmake_report cmConfigure.h${_tmp} "#  define NOMINMAX"
@@ -1474,6 +1578,7 @@
 done
 
 # Prepare KWSYS
+cmsys_header_files="cmsys/Configure.h cmsys/Configure.hxx"
 cmake_kwsys_config_replace_string \
   "${cmake_source_dir}/Source/kwsys/Configure.hxx.in" \
   "${cmake_bootstrap_dir}/cmsys/Configure.hxx" \
@@ -1486,14 +1591,33 @@
 for a in ${KWSYS_FILES}; do
   cmake_replace_string "${cmake_source_dir}/Source/kwsys/${a}.in" \
      "${cmake_bootstrap_dir}/cmsys/${a}" KWSYS_NAMESPACE cmsys
+  cmsys_header_files="${cmsys_header_files} cmsys/${a}"
 done
 
-cmake_generate_file "${cmake_bootstrap_dir}/cmThirdParty.h" ""
+echo "#ifndef cmThirdParty_h" > "${cmake_bootstrap_dir}/cmThirdParty.h.tmp"
+echo "#define cmThirdParty_h" >> "${cmake_bootstrap_dir}/cmThirdParty.h.tmp"
+if test "x${bootstrap_system_libuv}" != "x"; then
+  echo "#define CMAKE_USE_SYSTEM_LIBUV" >> "${cmake_bootstrap_dir}/cmThirdParty.h.tmp"
+fi
+if test "x${bootstrap_system_jsoncpp}" != "x"; then
+  echo "#define CMAKE_USE_SYSTEM_JSONCPP" >> "${cmake_bootstrap_dir}/cmThirdParty.h.tmp"
+fi
+if test "x${bootstrap_system_librhash}" != "x"; then
+  echo "#define CMAKE_USE_SYSTEM_LIBRHASH" >> "${cmake_bootstrap_dir}/cmThirdParty.h.tmp"
+fi
+echo "#endif" >> "${cmake_bootstrap_dir}/cmThirdParty.h.tmp"
+cmake_generate_file_tmp "${cmake_bootstrap_dir}/cmThirdParty.h" "${cmake_bootstrap_dir}/cmThirdParty.h.tmp"
 
 # Generate Makefile
-dep="cmConfigure.h cmsys/*.hxx cmsys/*.h `cmake_escape \"${cmake_source_dir}\"`/Source/*.hxx `cmake_escape \"${cmake_source_dir}\"`/Source/*.h"
+dep="cmConfigure.h ${cmsys_header_files}"
+for h in "${cmake_source_dir}"/Source/*.hxx; do
+  dep="${dep} `cmake_escape_artifact \"${h}\"`"
+done
+for h in "${cmake_source_dir}"/Source/*.h; do
+  dep="${dep} `cmake_escape_artifact \"${h}\"`"
+done
 for h in ${CMAKE_STD_CXX_HEADERS}; do
-  dep="${dep} `cmake_escape \"${cmake_source_dir}\"`/Utilities/std/cm/${h}"
+  dep="${dep} `cmake_escape_artifact \"${cmake_source_dir}\"`/Utilities/std/cm/${h}"
 done
 objs=""
 for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${CMAKE_STD_CXX_SOURCES} ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do
@@ -1504,6 +1628,18 @@
     objs="${objs} uv-`cmake_obj ${a}`"
   done
 fi
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  if test "x${bootstrap_system_jsoncpp}" = "x"; then
+    for a in ${JSONCPP_CXX_SOURCES}; do
+      objs="${objs} jsoncpp-`cmake_obj ${a}`"
+    done
+  fi
+  if test "x${bootstrap_system_librhash}" = "x"; then
+    for a in ${LIBRHASH_C_SOURCES}; do
+      objs="${objs} rhash-`cmake_obj ${a}`"
+    done
+  fi
+fi
 
 libs=""
 
@@ -1542,19 +1678,44 @@
   esac
 fi
 if test "x${bootstrap_system_libuv}" = "x"; then
-  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/include"`"
+  uv_c_flags="${uv_c_flags} `cmake_escape_shell "-I${cmake_source_dir}/Utilities/cmlibuv/include"`"
   if ${cmake_system_mingw}; then
-    uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/win"`"
+    uv_c_flags="${uv_c_flags} `cmake_escape_shell "-I${cmake_source_dir}/Utilities/cmlibuv/src/win"`"
   else
-    uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/unix"`"
+    uv_c_flags="${uv_c_flags} `cmake_escape_shell "-I${cmake_source_dir}/Utilities/cmlibuv/src/unix"`"
   fi
-  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src"`"
+  uv_c_flags="${uv_c_flags} `cmake_escape_shell "-I${cmake_source_dir}/Utilities/cmlibuv/src"`"
 else
   if test `which pkg-config`; then
-    uv_c_flags="${uv_c_flags} `pkg-config --cflags libuv`"
+    use_uv_flags="`pkg-config --cflags libuv`"
+    cmake_c_flags="${cmake_c_flags} ${use_uv_flags}"
+    cmake_cxx_flags="${cmake_cxx_flags} ${use_uv_flags}"
   fi
   libs="${libs} -luv"
 fi
+
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  jsoncpp_cxx_flags=
+  if test "x${bootstrap_system_jsoncpp}" = "x"; then
+    jsoncpp_cxx_flags="${jsoncpp_cxx_flags} `cmake_escape_shell "-I${cmake_source_dir}/Utilities/cmjsoncpp/include"`"
+  else
+    if test `which pkg-config`; then
+      use_jsoncpp_flags="`pkg-config --cflags jsoncpp`"
+      cmake_cxx_flags="${cmake_cxx_flags} ${use_jsoncpp_flags}"
+    fi
+    libs="${libs} -ljsoncpp"
+  fi
+
+  if test "x${bootstrap_system_librhash}" != "x"; then
+    if test `which pkg-config`; then
+      use_librhash_flags="`pkg-config --cflags librhash`"
+      cmake_c_flags="${cmake_c_flags} ${use_librhash_flags}"
+      cmake_cxx_flags="${cmake_cxx_flags} ${use_librhash_flags}"
+    fi
+    libs="${libs} -lrhash"
+  fi
+fi
+
 if test "x${cmake_ansi_cxx_flags}" != "x"; then
   cmake_cxx_flags="${cmake_ansi_cxx_flags} ${cmake_cxx_flags}"
 fi
@@ -1567,6 +1728,31 @@
   cmake_cxx_flags="${cmake_cxx_flags} "
 fi
 
+write_source_rule() {
+  lang="$1"
+  obj="$2"
+  src="$3"
+  src_flags="$4"
+
+  if test "${lang}" = "c"; then
+    ninja_rule=cc
+    compiler="${cmake_c_compiler}"
+    flags="${cmake_c_flags}"
+  elif test "${lang}" = "cxx"; then
+    ninja_rule=cxx
+    compiler="${cmake_cxx_compiler}"
+    flags="${cmake_cxx_flags}"
+  fi
+
+  if test "${cmake_bootstrap_generator}" = "Ninja"; then
+    echo "build ${obj} : ${ninja_rule} ${src} | ${dep}" >> "${cmake_bootstrap_dir}/build.ninja"
+    echo "  srcflags = ${src_flags}" >> "${cmake_bootstrap_dir}/build.ninja"
+  else
+    echo "${obj} : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+    echo "	${compiler} ${flags} ${src_flags} -c ${src} -o ${obj}" >> "${cmake_bootstrap_dir}/Makefile"
+  fi
+}
+
 cmake_c_flags_String="-DKWSYS_STRING_C"
 if ${cmake_system_mingw}; then
   cmake_c_flags_EncodingC="-DKWSYS_ENCODING_DEFAULT_CODEPAGE=CP_ACP"
@@ -1582,71 +1768,102 @@
 "
 cmake_c_flags="${cmake_c_flags} \
   -DCMAKE_BOOTSTRAP \
-  -I`cmake_escape \"${cmake_bootstrap_dir}\"` \
-  -I`cmake_escape \"${cmake_source_dir}/Source\"` \
-  -I`cmake_escape \"${cmake_source_dir}/Source/LexerParser\"` \
-  -I`cmake_escape \"${cmake_source_dir}/Utilities\"`"
+  -I`cmake_escape_shell \"${cmake_bootstrap_dir}\"` \
+  -I`cmake_escape_shell \"${cmake_source_dir}/Source\"` \
+  -I`cmake_escape_shell \"${cmake_source_dir}/Source/LexerParser\"` \
+  -I`cmake_escape_shell \"${cmake_source_dir}/Utilities\"`"
 cmake_cxx_flags="${cmake_cxx_flags} \
   -DCMAKE_BOOTSTRAP \
   ${cmake_have_cxx_features} \
-  -I`cmake_escape \"${cmake_bootstrap_dir}\"` \
-  -I`cmake_escape \"${cmake_source_dir}/Source\"` \
-  -I`cmake_escape \"${cmake_source_dir}/Source/LexerParser\"` \
-  -I`cmake_escape \"${cmake_source_dir}/Utilities/std\"` \
-  -I`cmake_escape \"${cmake_source_dir}/Utilities\"`"
-echo "cmake: ${objs}" > "${cmake_bootstrap_dir}/Makefile"
-echo "	${cmake_cxx_compiler} ${cmake_ld_flags} ${cmake_cxx_flags} ${objs} ${libs} -o cmake" >> "${cmake_bootstrap_dir}/Makefile"
+  -I`cmake_escape_shell \"${cmake_bootstrap_dir}\"` \
+  -I`cmake_escape_shell \"${cmake_source_dir}/Source\"` \
+  -I`cmake_escape_shell \"${cmake_source_dir}/Source/LexerParser\"` \
+  -I`cmake_escape_shell \"${cmake_source_dir}/Utilities/std\"` \
+  -I`cmake_escape_shell \"${cmake_source_dir}/Utilities\"`"
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  echo "cc = ${cmake_c_compiler}" > "${cmake_bootstrap_dir}/build.ninja"
+  echo "cxx = ${cmake_cxx_compiler}" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "cflags = ${cmake_c_flags}" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "cxxflags = ${cmake_cxx_flags}" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "ldflags = ${cmake_ld_flags}" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "rule cc" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "  command = \$cc \$cflags \$srcflags -c \$in -o \$out" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "rule cxx" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "  command = \$cxx \$cxxflags \$srcflags -c \$in -o \$out" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "rule link" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "  command = \$cxx \$ldflags \$cxxflags \$in \$libs -o \$out" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "build cmake: link ${objs}" >> "${cmake_bootstrap_dir}/build.ninja"
+  echo "  libs = ${libs}" >> "${cmake_bootstrap_dir}/build.ninja"
+else
+  echo "cmake: ${objs}" > "${cmake_bootstrap_dir}/Makefile"
+  echo "	${cmake_cxx_compiler} ${cmake_ld_flags} ${cmake_cxx_flags} ${objs} ${libs} -o cmake" >> "${cmake_bootstrap_dir}/Makefile"
+fi
 for a in ${CMAKE_CXX_SOURCES}; do
-  src=`cmake_escape "${cmake_source_dir}/Source/${a}.cxx"`
+  src=`cmake_escape_artifact "${cmake_source_dir}/Source/${a}.cxx"`
   src_flags=`eval echo \\${cmake_cxx_flags_\${a}}`
-  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "	${cmake_cxx_compiler} ${cmake_cxx_flags} ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+  write_source_rule "cxx" "${a}.o" "${src}" "${src_flags}"
 done
 for a in ${CMAKE_C_SOURCES}; do
-  src=`cmake_escape "${cmake_source_dir}/Source/${a}.c"`
-  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "	${cmake_c_compiler} ${cmake_c_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+  src=`cmake_escape_artifact "${cmake_source_dir}/Source/${a}.c"`
+  write_source_rule "c" "${a}.o" "${src}" ""
 done
 for a in ${CMAKE_STD_CXX_SOURCES}; do
-  src=`cmake_escape "${cmake_source_dir}/Utilities/std/cm/bits/${a}.cxx"`
+  src=`cmake_escape_artifact "${cmake_source_dir}/Utilities/std/cm/bits/${a}.cxx"`
   src_flags=`eval echo \\${cmake_cxx_flags_\${a}}`
-  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "	${cmake_cxx_compiler} ${cmake_cxx_flags} ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+  write_source_rule "cxx" "${a}.o" "${src}" "${src_flags}"
 done
 for a in ${LexerParser_CXX_SOURCES}; do
-  src=`cmake_escape "${cmake_source_dir}/Source/LexerParser/${a}.cxx"`
+  src=`cmake_escape_artifact "${cmake_source_dir}/Source/LexerParser/${a}.cxx"`
   src_flags=`eval echo \\${cmake_cxx_flags_\${a}}`
-  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "	${cmake_cxx_compiler} ${cmake_cxx_flags} ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+  write_source_rule "cxx" "${a}.o" "${src}" "${src_flags}"
 done
 for a in ${LexerParser_C_SOURCES}; do
-  src=`cmake_escape "${cmake_source_dir}/Source/LexerParser/${a}.c"`
-  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "	${cmake_c_compiler} ${cmake_c_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+  src=`cmake_escape_artifact "${cmake_source_dir}/Source/LexerParser/${a}.c"`
+  write_source_rule "c" "${a}.o" "${src}" ""
 done
 for a in ${KWSYS_C_SOURCES}; do
-  src=`cmake_escape "${cmake_source_dir}/Source/kwsys/${a}.c"`
-  src_flags=`eval echo \\${cmake_c_flags_\${a}}`
-  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "	${cmake_c_compiler} ${cmake_c_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+  src=`cmake_escape_artifact "${cmake_source_dir}/Source/kwsys/${a}.c"`
+  src_flags="`eval echo \\${cmake_c_flags_\${a}}` -DKWSYS_NAMESPACE=cmsys"
+  write_source_rule "c" "${a}.o" "${src}" "${src_flags}"
 done
 for a in ${KWSYS_CXX_SOURCES}; do
-  src=`cmake_escape "${cmake_source_dir}/Source/kwsys/${a}.cxx"`
-  src_flags=`eval echo \\${cmake_cxx_flags_\${a}}`
-  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "	${cmake_cxx_compiler} ${cmake_cxx_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+  src=`cmake_escape_artifact "${cmake_source_dir}/Source/kwsys/${a}.cxx"`
+  src_flags="`eval echo \\${cmake_cxx_flags_\${a}}` -DKWSYS_NAMESPACE=cmsys"
+  write_source_rule "cxx" "${a}.o" "${src}" "${src_flags}"
 done
 if test "x${bootstrap_system_libuv}" = "x"; then
   for a in ${LIBUV_C_SOURCES}; do
-    src=`cmake_escape "${cmake_source_dir}/Utilities/cmlibuv/${a}"`
-    echo "uv-`cmake_obj ${a}` : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-    echo "	${cmake_c_compiler} ${cmake_c_flags} ${uv_c_flags} -c ${src} -o uv-`cmake_obj ${a}`" >> "${cmake_bootstrap_dir}/Makefile"
+    src=`cmake_escape_artifact "${cmake_source_dir}/Utilities/cmlibuv/${a}"`
+    write_source_rule "c" "uv-`cmake_obj ${a}`" "${src}" "${uv_c_flags}"
   done
 fi
-echo '
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  if test "x${bootstrap_system_jsoncpp}" = "x"; then
+    for a in ${JSONCPP_CXX_SOURCES}; do
+      src=`cmake_escape_artifact "${cmake_source_dir}/Utilities/cmjsoncpp/${a}"`
+      write_source_rule "cxx" "jsoncpp-`cmake_obj ${a}`" "${src}" "${jsoncpp_cxx_flags}"
+    done
+  fi
+  if test "x${bootstrap_system_librhash}" = "x"; then
+    for a in ${LIBRHASH_C_SOURCES}; do
+      src=`cmake_escape_artifact "${cmake_source_dir}/Utilities/cmlibrhash/${a}"`
+      write_source_rule "c" "rhash-`cmake_obj ${a}`" "${src}" ""
+    done
+  fi
+fi
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  echo "
+rule rebuild_cache
+  command = cd \"${cmake_binary_dir}\" && \"${cmake_source_dir}/bootstrap\" --generator=\"${cmake_bootstrap_generator}\"
+  generator = 1
+build build.ninja : rebuild_cache
+" >> "${cmake_bootstrap_dir}/build.ninja"
+else
+  echo "
 rebuild_cache:
-	cd "${cmake_binary_dir}" && "${cmake_source_dir}/bootstrap"
-' >> "${cmake_bootstrap_dir}/Makefile"
+	cd \"${cmake_binary_dir}\" && \"${cmake_source_dir}/bootstrap\" --generator=\"${cmake_bootstrap_generator}\"
+" >> "${cmake_bootstrap_dir}/Makefile"
+fi
 
 # Write our default settings to Bootstrap${_cmk}/InitialCacheFlags.cmake.
 echo '
@@ -1715,10 +1932,15 @@
 echo "---------------------------------------------"
 
 # Run make to build bootstrap cmake
-if test "x${cmake_parallel_make}" != "x"; then
-  ${cmake_make_processor} ${cmake_make_flags}
+if test "${cmake_bootstrap_generator}" = "Ninja"; then
+  ninja_v=-v
 else
-  ${cmake_make_processor}
+  ninja_v=
+fi
+if test "x${cmake_parallel_make}" != "x"; then
+  ${cmake_make_processor} ${cmake_make_flags} ${ninja_v}
+else
+  ${cmake_make_processor} ${ninja_v}
 fi
 RES=$?
 if test "${RES}" -ne "0"; then