Merge topic 'vs-sdk-dirs'

6ec3e880e7 VS: Add variables to set SDK directories in vcxproj files

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1965
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a27c662..3ee67cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -546,7 +546,7 @@
   #---------------------------------------------------------------------
   # Build libuv library.
   if(CMAKE_USE_SYSTEM_LIBUV)
-    find_package(LibUV 1.0.0)
+    find_package(LibUV 1.10.0)
     if(NOT LIBUV_FOUND)
       message(FATAL_ERROR
         "CMAKE_USE_SYSTEM_LIBUV is ON but a libuv is not found!")
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index fa2c23d..01987be 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -36,6 +36,7 @@
 #. Push a topic branch to a personal repository fork on GitLab.
 #. Create a GitLab Merge Request targeting the upstream ``master`` branch
    (even if the change is intended for merge to the ``release`` branch).
+   Check the box to allow edits from maintainers.
 
 The merge request will enter the `CMake Review Process`_ for consideration.
 
diff --git a/Help/command/list.rst b/Help/command/list.rst
index 6218a2a..e240b65 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -151,6 +151,79 @@
 
 Removes duplicated items in the list.
 
+TRANSFORM
+"""""""""
+
+::
+
+  list(TRANSFORM <list> <ACTION> [<SELECTOR>]
+                        [OUTPUT_VARIABLE <output variable>])
+
+Transforms the list by applying an action to all or, by specifying a
+``<SELECTOR>``, to the selected elements of the list, storing result in-place
+or in the specified output variable.
+
+.. note::
+
+   ``TRANSFORM`` sub-command does not change the number of elements of the
+   list. If a ``<SELECTOR>`` is specified, only some elements will be changed,
+   the other ones will remain same as before the transformation.
+
+``<ACTION>`` specify the action to apply to the elements of list.
+The actions have exactly the same semantics as sub-commands of
+:command:`string` command.
+
+The ``<ACTION>`` may be one of:
+
+``APPEND``, ``PREPEND``: Append, prepend specified value to each element of
+the list. ::
+
+  list(TRANSFORM <list> <APPEND|PREPEND> <value> ...)
+
+``TOUPPER``, ``TOLOWER``: Convert each element of the list to upper, lower
+characters. ::
+
+  list(TRANSFORM <list> <TOLOWER|TOUPPER> ...)
+
+``STRIP``: Remove leading and trailing spaces from each element of the
+list. ::
+
+  list(TRANSFORM <list> STRIP ...)
+
+``GENEX_STRIP``: Strip any
+:manual:`generator expressions <cmake-generator-expressions(7)>` from each
+element of the list. ::
+
+  list(TRANSFORM <list> GENEX_STRIP ...)
+
+``REPLACE``: Match the regular expression as many times as possible and
+substitute the replacement expression for the match for each element
+of the list
+(Same semantic as ``REGEX REPLACE`` from :command:`string` command). ::
+
+  list(TRANSFORM <list> REPLACE <regular_expression>
+                                <replace_expression> ...)
+
+``<SELECTOR>`` select which elements of the list will be transformed. Only one
+type of selector can be specified at a time.
+
+The ``<SELECTOR>`` may be one of:
+
+``AT``: Specify a list of indexes. ::
+
+  list(TRANSFORM <list> <ACTION> AT <index> [<index> ...] ...)
+
+``FOR``: Specify a range with, optionaly, an increment used to iterate over
+the range. ::
+
+  list(TRANSFORM <list> <ACTION> FOR <start> <stop> [<step>] ...)
+
+``REGEX``: Specify a regular expression. Only elements matching the regular
+expression will be transformed. ::
+
+  list(TRANSFORM <list> <ACTION> REGEX <regular_expression> ...)
+
+
 Sorting
 ^^^^^^^
 
diff --git a/Help/manual/LINKS.txt b/Help/manual/LINKS.txt
index 3993ff8..8e53c0c 100644
--- a/Help/manual/LINKS.txt
+++ b/Help/manual/LINKS.txt
@@ -5,15 +5,11 @@
 
  The primary starting point for learning about CMake.
 
-Frequently Asked Questions
- https://cmake.org/Wiki/CMake_FAQ
-
- A Wiki is provided containing answers to frequently asked questions.
-
-Online Documentation
+Online Documentation and Community Resources
  https://cmake.org/documentation
 
- Links to available documentation may be found on this web page.
+ Links to available documentation and community resources may be
+ found on this web page.
 
 Mailing List
  https://cmake.org/mailing-lists
diff --git a/Help/manual/ccmake.1.rst b/Help/manual/ccmake.1.rst
index a5fe191..cc3ceec 100644
--- a/Help/manual/ccmake.1.rst
+++ b/Help/manual/ccmake.1.rst
@@ -8,7 +8,7 @@
 
 .. parsed-literal::
 
- ccmake [<options>] (<path-to-source> | <path-to-existing-build>)
+ ccmake [<options>] {<path-to-source> | <path-to-existing-build>}
 
 Description
 ===========
diff --git a/Help/manual/cmake-gui.1.rst b/Help/manual/cmake-gui.1.rst
index 032b51f..57a9850 100644
--- a/Help/manual/cmake-gui.1.rst
+++ b/Help/manual/cmake-gui.1.rst
@@ -9,7 +9,7 @@
 .. parsed-literal::
 
  cmake-gui [<options>]
- cmake-gui [<options>] (<path-to-source> | <path-to-existing-build>)
+ cmake-gui [<options>] {<path-to-source> | <path-to-existing-build>}
 
 Description
 ===========
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 7e2255d..631f75b 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@
 .. toctree::
    :maxdepth: 1
 
+   CMP0075: Include file check macros honor CMAKE_REQUIRED_LIBRARIES. </policy/CMP0075>
    CMP0074: find_package uses PackageName_ROOT variables. </policy/CMP0074>
    CMP0073: Do not produce legacy _LIB_DEPENDS cache entries. </policy/CMP0073>
 
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index c2e6435..577d321 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -8,8 +8,8 @@
 
 .. parsed-literal::
 
- cmake [<options>] (<path-to-source> | <path-to-existing-build>)
- cmake [(-D <var>=<value>)...] -P <cmake-script-file>
+ cmake [<options>] {<path-to-source> | <path-to-existing-build>}
+ cmake [{-D <var>=<value>}...] -P <cmake-script-file>
  cmake --build <dir> [<options>...] [-- <build-tool-options>...]
  cmake --open <dir>
  cmake -E <command> [<options>...]
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 75af22e..9553d15 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -13,7 +13,7 @@
  ctest [<options>]
  ctest <path-to-source> <path-to-build> --build-generator <generator>
        [<options>...] [-- <build-options>...] [--test-command <test>]
- ctest (-D <dashboard> | -M <model> -T <action> | -S <script> | -SP <script>)
+ ctest {-D <dashboard> | -M <model> -T <action> | -S <script> | -SP <script>}
        [-- <dashboard-options>...]
 
 Description
diff --git a/Help/policy/CMP0075.rst b/Help/policy/CMP0075.rst
new file mode 100644
index 0000000..aa5c3f7
--- /dev/null
+++ b/Help/policy/CMP0075.rst
@@ -0,0 +1,26 @@
+CMP0075
+-------
+
+Include file check macros honor ``CMAKE_REQUIRED_LIBRARIES``.
+
+In CMake 3.12 and above, the
+
+* ``check_include_file`` macro in the :module:`CheckIncludeFile` module, the
+* ``check_include_file_cxx`` macro in the
+  :module:`CheckIncludeFileCXX` module, and the
+* ``check_include_files`` macro in the :module:`CheckIncludeFiles` module
+
+now prefer to link the check executable to the libraries listed in the
+``CMAKE_REQUIRED_LIBRARIES`` variable.  This policy provides compatibility
+with projects that have not been updated to expect this behavior.
+
+The ``OLD`` behavior for this policy is to ignore ``CMAKE_REQUIRED_LIBRARIES``
+in the include file check macros.  The ``NEW`` behavior of this policy is to
+honor ``CMAKE_REQUIRED_LIBRARIES`` in the include file check macros.
+
+This policy was introduced in CMake version 3.12.  CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/dev/CheckIncludeFile-required-libs.rst b/Help/release/dev/CheckIncludeFile-required-libs.rst
new file mode 100644
index 0000000..6fb5c40
--- /dev/null
+++ b/Help/release/dev/CheckIncludeFile-required-libs.rst
@@ -0,0 +1,14 @@
+CheckIncludeFile-required-libs
+------------------------------
+
+* The :module:`CheckIncludeFile` module ``check_include_file`` macro
+  learned to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable.
+  See policy :policy:`CMP0075`.
+
+* The :module:`CheckIncludeFileCXX` module ``check_include_file_cxx`` macro
+  learned to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable.
+  See policy :policy:`CMP0075`.
+
+* The :module:`CheckIncludeFiles` module ``check_include_files`` macro
+  learned to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable.
+  See policy :policy:`CMP0075`.
diff --git a/Help/release/dev/FindJPEG-imported-targets.rst b/Help/release/dev/FindJPEG-imported-targets.rst
new file mode 100644
index 0000000..32cf2f6
--- /dev/null
+++ b/Help/release/dev/FindJPEG-imported-targets.rst
@@ -0,0 +1,4 @@
+FindJPEG-imported-targets
+-------------------------
+
+* The :module:`FindJPEG` module now provides imported targets.
diff --git a/Help/release/dev/list-transform.rst b/Help/release/dev/list-transform.rst
new file mode 100644
index 0000000..4a6dacc
--- /dev/null
+++ b/Help/release/dev/list-transform.rst
@@ -0,0 +1,5 @@
+list-transform
+--------------
+
+* The :command:`list` command learned a ``TRANSFORM`` sub-command
+  to apply various string transformation to list's elements.
diff --git a/Help/variable/CMAKE_LANG_FLAGS.rst b/Help/variable/CMAKE_LANG_FLAGS.rst
index c57d92c..14b2694 100644
--- a/Help/variable/CMAKE_LANG_FLAGS.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS.rst
@@ -4,3 +4,14 @@
 Flags for all build types.
 
 ``<LANG>`` flags used regardless of the value of :variable:`CMAKE_BUILD_TYPE`.
+
+This is initialized for each language from environment variables:
+
+* ``CMAKE_C_FLAGS``:
+  Initialized by the :envvar:`CFLAGS` environment variable.
+* ``CMAKE_CXX_FLAGS``:
+  Initialized by the :envvar:`CXXFLAGS` environment variable.
+* ``CMAKE_CUDA_FLAGS``:
+  Initialized by the :envvar:`CUDAFLAGS` environment variable.
+* ``CMAKE_Fortran_FLAGS``:
+  Initialized by the :envvar:`FFLAGS` environment variable.
diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake
index 125c4e3..6b73730 100644
--- a/Modules/CMakeASMInformation.cmake
+++ b/Modules/CMakeASMInformation.cmake
@@ -29,15 +29,15 @@
 endif()
 
 if(CMAKE_SYSTEM_PROCESSOR)
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL  RESULT_VARIABLE _INCLUDED_FILE)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL  RESULT_VARIABLE _INCLUDED_FILE)
   if(NOT _INCLUDED_FILE)
-    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
   endif()
 endif()
 
-include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT} OPTIONAL  RESULT_VARIABLE _INCLUDED_FILE)
+include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT} OPTIONAL  RESULT_VARIABLE _INCLUDED_FILE)
 if(NOT _INCLUDED_FILE)
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL)
 endif()
 
 # This should be included before the _INIT variables are
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index 1e46cac..df43559 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -35,21 +35,21 @@
 # load a hardware specific file, mostly useful for embedded compilers
 if(CMAKE_SYSTEM_PROCESSOR)
   if(CMAKE_C_COMPILER_ID)
-    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
   endif()
   if (NOT _INCLUDED_FILE)
-    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
   endif ()
 endif()
 
 
 # load the system- and compiler specific files
 if(CMAKE_C_COMPILER_ID)
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C
     OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
 endif()
 if (NOT _INCLUDED_FILE)
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}
     OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
 endif ()
 
diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in
index f524e5f..9761d8c 100644
--- a/Modules/CMakeCUDACompiler.cmake.in
+++ b/Modules/CMakeCUDACompiler.cmake.in
@@ -11,6 +11,7 @@
 set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX")
 set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX")
 
+set(CMAKE_CUDA_COMPILER_LOADED 1)
 set(CMAKE_CUDA_COMPILER_ID_RUN 1)
 set(CMAKE_CUDA_SOURCE_FILE_EXTENSIONS cu)
 set(CMAKE_CUDA_LINKER_PREFERENCE 15)
diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake
index 4788cbf..479493b 100644
--- a/Modules/CMakeCUDAInformation.cmake
+++ b/Modules/CMakeCUDAInformation.cmake
@@ -17,9 +17,9 @@
 if(CMAKE_CUDA_COMPILER_ID)
   # load a hardware specific file, mostly useful for embedded compilers
   if(CMAKE_SYSTEM_PROCESSOR)
-    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CUDA_COMPILER_ID}-CUDA-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_CUDA_COMPILER_ID}-CUDA-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
   endif()
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CUDA_COMPILER_ID}-CUDA OPTIONAL)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_CUDA_COMPILER_ID}-CUDA OPTIONAL)
 endif()
 
 
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
index 9ac9560..2975874 100644
--- a/Modules/CMakeCXXInformation.cmake
+++ b/Modules/CMakeCXXInformation.cmake
@@ -36,19 +36,19 @@
 # load a hardware specific file, mostly useful for embedded compilers
 if(CMAKE_SYSTEM_PROCESSOR)
   if(CMAKE_CXX_COMPILER_ID)
-    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
   endif()
   if (NOT _INCLUDED_FILE)
-    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
   endif ()
 endif()
 
 # load the system- and compiler specific files
 if(CMAKE_CXX_COMPILER_ID)
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
 endif()
 if (NOT _INCLUDED_FILE)
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL
           RESULT_VARIABLE _INCLUDED_FILE)
 endif ()
 
diff --git a/Modules/CMakeFindPackageMode.cmake b/Modules/CMakeFindPackageMode.cmake
index 7c41d49..ec3652c 100644
--- a/Modules/CMakeFindPackageMode.cmake
+++ b/Modules/CMakeFindPackageMode.cmake
@@ -65,6 +65,8 @@
   set(CMAKE_${LANGUAGE}_OSX_DEPLOYMENT_TARGET_FLAG "")
 endif()
 
+include(CMakeSystemSpecificInitialize)
+
 # Also load the system specific file, which sets up e.g. the search paths.
 # This makes the FIND_XXX() calls work much better
 include(CMakeSystemSpecificInformation)
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake
index 5f028e4..cceac83 100644
--- a/Modules/CMakeFortranInformation.cmake
+++ b/Modules/CMakeFortranInformation.cmake
@@ -22,10 +22,10 @@
   set(CMAKE_BASE_NAME g77)
 endif()
 if(CMAKE_Fortran_COMPILER_ID)
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Fortran_COMPILER_ID}-Fortran OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Fortran_COMPILER_ID}-Fortran OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
 endif()
 if (NOT _INCLUDED_FILE)
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL
           RESULT_VARIABLE _INCLUDED_FILE)
 endif ()
 
diff --git a/Modules/CMakeLanguageInformation.cmake b/Modules/CMakeLanguageInformation.cmake
index 18c8624..674ab86 100644
--- a/Modules/CMakeLanguageInformation.cmake
+++ b/Modules/CMakeLanguageInformation.cmake
@@ -9,10 +9,10 @@
 macro(__cmake_include_compiler_wrapper lang)
   set(_INCLUDED_WRAPPER_FILE 0)
   if (CMAKE_${lang}_COMPILER_ID)
-    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${CMAKE_${lang}_COMPILER_ID}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${CMAKE_${lang}_COMPILER_ID}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE)
   endif()
   if (NOT _INCLUDED_WRAPPER_FILE)
-    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE)
   endif ()
 
   # No platform - wrapper - lang information so maybe there's just wrapper - lang information
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake
index 63d18ab..935f92d 100644
--- a/Modules/CMakeParseImplicitLinkInfo.cmake
+++ b/Modules/CMakeParseImplicitLinkInfo.cmake
@@ -142,7 +142,7 @@
   # We remove items that are not language-specific.
   set(implicit_libs "")
   foreach(lib IN LISTS implicit_libs_tmp)
-    if("x${lib}" MATCHES "^x(crt.*\\.o|gcc_eh.*|System.*|.*libclang_rt.*|msvcrt.*|libvcruntime.*|libucrt.*|libcmt.*)$")
+    if("x${lib}" MATCHES "^x(crt.*\\.o|gcc_eh.*|.*libgcc_eh.*|System.*|.*libclang_rt.*|msvcrt.*|libvcruntime.*|libucrt.*|libcmt.*)$")
       string(APPEND log "  remove lib [${lib}]\n")
     elseif(IS_ABSOLUTE "${lib}")
       get_filename_component(abs "${lib}" ABSOLUTE)
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index d9b408d..07ba6d0 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -14,9 +14,9 @@
 if(CMAKE_Swift_COMPILER_ID)
   # load a hardware specific file, mostly useful for embedded compilers
   if(CMAKE_SYSTEM_PROCESSOR)
-    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
   endif()
-  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
 endif()
 
 # for most systems a module is the same as a shared library
diff --git a/Modules/CMakeSystemSpecificInitialize.cmake b/Modules/CMakeSystemSpecificInitialize.cmake
index 6200e9c..de4d7f5 100644
--- a/Modules/CMakeSystemSpecificInitialize.cmake
+++ b/Modules/CMakeSystemSpecificInitialize.cmake
@@ -5,6 +5,19 @@
 # This file is included by cmGlobalGenerator::EnableLanguage.
 # It is included before the compiler has been determined.
 
+# The CMAKE_EFFECTIVE_SYSTEM_NAME is used to load compiler and compiler
+# wrapper configuration files. By default it equals to CMAKE_SYSTEM_NAME
+# but could be overridden in the ${CMAKE_SYSTEM_NAME}-Initialize files.
+#
+# It is useful to share the same aforementioned configuration files and
+# avoids duplicating them in case of tightly related platforms.
+#
+# An example are the platforms supported by Xcode (macOS, iOS, tvOS,
+# and watchOS). For all of those the CMAKE_EFFECTIVE_SYSTEM_NAME is
+# set to Apple which results in using
+# Platfom/Apple-AppleClang-CXX.cmake for the Apple C++ compiler.
+set(CMAKE_EFFECTIVE_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}")
+
 include(Platform/${CMAKE_SYSTEM_NAME}-Initialize OPTIONAL)
 
 set(CMAKE_SYSTEM_SPECIFIC_INITIALIZE_LOADED 1)
diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake
index e5554c4..24bc349 100644
--- a/Modules/CheckIncludeFile.cmake
+++ b/Modules/CheckIncludeFile.cmake
@@ -27,6 +27,8 @@
 #   list of macros to define (-DFOO=bar)
 # ``CMAKE_REQUIRED_INCLUDES``
 #   list of include directories
+# ``CMAKE_REQUIRED_LIBRARIES``
+#   A list of libraries to link.  See policy :policy:`CMP0075`.
 # ``CMAKE_REQUIRED_QUIET``
 #   execute quietly without messages
 #
@@ -55,14 +57,39 @@
       string(APPEND CMAKE_C_FLAGS " ${ARGV2}")
     endif()
 
+    set(_CIF_LINK_LIBRARIES "")
+    if(CMAKE_REQUIRED_LIBRARIES)
+      cmake_policy(GET CMP0075 _CIF_CMP0075
+        PARENT_SCOPE # undocumented, do not use outside of CMake
+        )
+      if("x${_CIF_CMP0075}x" STREQUAL "xNEWx")
+        set(_CIF_LINK_LIBRARIES LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+      elseif("x${_CIF_CMP0075}x" STREQUAL "xOLDx")
+      elseif(NOT _CIF_CMP0075_WARNED)
+        set(_CIF_CMP0075_WARNED 1)
+        message(AUTHOR_WARNING
+          "Policy CMP0075 is not set: Include file check macros honor CMAKE_REQUIRED_LIBRARIES.  "
+          "Run \"cmake --help-policy CMP0075\" for policy details.  "
+          "Use the cmake_policy command to set the policy and suppress this warning."
+          "\n"
+          "CMAKE_REQUIRED_LIBRARIES is set to:\n"
+          "  ${CMAKE_REQUIRED_LIBRARIES}\n"
+          "For compatibility with CMake 3.11 and below this check is ignoring it."
+          )
+      endif()
+      unset(_CIF_CMP0075)
+    endif()
+
     try_compile(${VARIABLE}
       ${CMAKE_BINARY_DIR}
       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${_CIF_LINK_LIBRARIES}
       CMAKE_FLAGS
       -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
       "${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}"
       OUTPUT_VARIABLE OUTPUT)
+    unset(_CIF_LINK_LIBRARIES)
 
     if(${ARGC} EQUAL 3)
       set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_SAVE})
diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake
index 7948bab..f13d983 100644
--- a/Modules/CheckIncludeFileCXX.cmake
+++ b/Modules/CheckIncludeFileCXX.cmake
@@ -27,6 +27,8 @@
 #   list of macros to define (-DFOO=bar)
 # ``CMAKE_REQUIRED_INCLUDES``
 #   list of include directories
+# ``CMAKE_REQUIRED_LIBRARIES``
+#   A list of libraries to link.  See policy :policy:`CMP0075`.
 # ``CMAKE_REQUIRED_QUIET``
 #   execute quietly without messages
 #
@@ -54,14 +56,39 @@
       string(APPEND CMAKE_CXX_FLAGS " ${ARGV2}")
     endif()
 
+    set(_CIF_LINK_LIBRARIES "")
+    if(CMAKE_REQUIRED_LIBRARIES)
+      cmake_policy(GET CMP0075 _CIF_CMP0075
+        PARENT_SCOPE # undocumented, do not use outside of CMake
+        )
+      if("x${_CIF_CMP0075}x" STREQUAL "xNEWx")
+        set(_CIF_LINK_LIBRARIES LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+      elseif("x${_CIF_CMP0075}x" STREQUAL "xOLDx")
+      elseif(NOT _CIF_CMP0075_WARNED)
+        set(_CIF_CMP0075_WARNED 1)
+        message(AUTHOR_WARNING
+          "Policy CMP0075 is not set: Include file check macros honor CMAKE_REQUIRED_LIBRARIES.  "
+          "Run \"cmake --help-policy CMP0075\" for policy details.  "
+          "Use the cmake_policy command to set the policy and suppress this warning."
+          "\n"
+          "CMAKE_REQUIRED_LIBRARIES is set to:\n"
+          "  ${CMAKE_REQUIRED_LIBRARIES}\n"
+          "For compatibility with CMake 3.11 and below this check is ignoring it."
+          )
+      endif()
+      unset(_CIF_CMP0075)
+    endif()
+
     try_compile(${VARIABLE}
       ${CMAKE_BINARY_DIR}
       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${_CIF_LINK_LIBRARIES}
       CMAKE_FLAGS
       -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
       "${CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS}"
       OUTPUT_VARIABLE OUTPUT)
+    unset(_CIF_LINK_LIBRARIES)
 
     if(${ARGC} EQUAL 3)
       set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_SAVE})
diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake
index 59afdab..c689f05 100644
--- a/Modules/CheckIncludeFiles.cmake
+++ b/Modules/CheckIncludeFiles.cmake
@@ -33,6 +33,8 @@
 #   list of macros to define (-DFOO=bar)
 # ``CMAKE_REQUIRED_INCLUDES``
 #   list of include directories
+# ``CMAKE_REQUIRED_LIBRARIES``
+#   A list of libraries to link.  See policy :policy:`CMP0075`.
 # ``CMAKE_REQUIRED_QUIET``
 #   execute quietly without messages
 #
@@ -95,6 +97,29 @@
       set(_description "include file ${_INCLUDE}")
     endif()
 
+    set(_CIF_LINK_LIBRARIES "")
+    if(CMAKE_REQUIRED_LIBRARIES)
+      cmake_policy(GET CMP0075 _CIF_CMP0075
+        PARENT_SCOPE # undocumented, do not use outside of CMake
+        )
+      if("x${_CIF_CMP0075}x" STREQUAL "xNEWx")
+        set(_CIF_LINK_LIBRARIES LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+      elseif("x${_CIF_CMP0075}x" STREQUAL "xOLDx")
+      elseif(NOT _CIF_CMP0075_WARNED)
+        set(_CIF_CMP0075_WARNED 1)
+        message(AUTHOR_WARNING
+          "Policy CMP0075 is not set: Include file check macros honor CMAKE_REQUIRED_LIBRARIES.  "
+          "Run \"cmake --help-policy CMP0075\" for policy details.  "
+          "Use the cmake_policy command to set the policy and suppress this warning."
+          "\n"
+          "CMAKE_REQUIRED_LIBRARIES is set to:\n"
+          "  ${CMAKE_REQUIRED_LIBRARIES}\n"
+          "For compatibility with CMake 3.11 and below this check is ignoring it."
+          )
+      endif()
+      unset(_CIF_CMP0075)
+    endif()
+
     if(NOT CMAKE_REQUIRED_QUIET)
       message(STATUS "Looking for ${_description}")
     endif()
@@ -102,10 +127,12 @@
       ${CMAKE_BINARY_DIR}
       ${src}
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${_CIF_LINK_LIBRARIES}
       CMAKE_FLAGS
       -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILES_FLAGS}
       "${CHECK_INCLUDE_FILES_INCLUDE_DIRS}"
       OUTPUT_VARIABLE OUTPUT)
+    unset(_CIF_LINK_LIBRARIES)
     if(${VARIABLE})
       if(NOT CMAKE_REQUIRED_QUIET)
         message(STATUS "Looking for ${_description} - found")
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 77866e9..e99011b 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -51,8 +51,33 @@
   endif()
 
   unset(_clang_version_std17)
+
+  __compiler_check_default_language_standard(CXX 2.1 98)
+elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
+    AND CMAKE_CXX_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
+  # This version of clang-cl and the MSVC version it simulates have
+  # support for -std: flags.
+  set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
+  set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
+  set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
+  set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "")
+  set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std:c++14")
+  set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std:c++14")
+  if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
+    set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++17")
+    set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++17")
+    set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
+    set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
+  else()
+    set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest")
+    set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest")
+  endif()
+
+  __compiler_check_default_language_standard(CXX 3.9 14)
 else()
-  # clang-cl does not know these options because it behaves like cl.exe
+  # This version of clang-cl, or the MSVC version it simulates, does not have
+  # language standards.  Set these options as empty strings so the feature
+  # test infrastructure can at least check to see if they are defined.
   set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
   set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
   set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
@@ -63,10 +88,22 @@
   set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
   set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
   set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
-endif()
 
-if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
-  __compiler_check_default_language_standard(CXX 2.1 98)
-else()
+  # There is no meaningful default for this
   set(CMAKE_CXX_STANDARD_DEFAULT "")
+
+  # There are no compiler modes so we only need to test features once.
+  # Override the default macro for this special case.  Pretend that
+  # all language standards are available so that at least compilation
+  # can be attempted.
+  macro(cmake_record_cxx_compile_features)
+    list(APPEND CMAKE_CXX_COMPILE_FEATURES
+      cxx_std_98
+      cxx_std_11
+      cxx_std_14
+      cxx_std_17
+      cxx_std_20
+      )
+    _record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
+  endmacro()
 endif()
diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake
index 29c2f22..8d0e6d6 100644
--- a/Modules/Compiler/SunPro-C.cmake
+++ b/Modules/Compiler/SunPro-C.cmake
@@ -18,6 +18,8 @@
 string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -xO3 -DNDEBUG")
 string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -g -xO2 -DNDEBUG")
 
+set(CMAKE_DEPFILE_FLAGS_C "-xMD -xMF <DEPFILE>")
+
 # Initialize C link type selection flags.  These flags are used when
 # building a shared library, shared module, or executable that links
 # to other libraries to select whether to use the static or shared
diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake
index 5cb7edc..14196b7 100644
--- a/Modules/Compiler/SunPro-CXX.cmake
+++ b/Modules/Compiler/SunPro-CXX.cmake
@@ -18,6 +18,8 @@
 string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -xO3 -DNDEBUG")
 string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -g -xO2 -DNDEBUG")
 
+set(CMAKE_DEPFILE_FLAGS_CXX "-xMD -xMF <DEPFILE>")
+
 # Initialize C link type selection flags.  These flags are used when
 # building a shared library, shared module, or executable that links
 # to other libraries to select whether to use the static or shared
diff --git a/Modules/Compiler/XL.cmake b/Modules/Compiler/XL.cmake
index e527a04..3361f8f 100644
--- a/Modules/Compiler/XL.cmake
+++ b/Modules/Compiler/XL.cmake
@@ -30,6 +30,8 @@
   set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
   set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE     "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
 
+  set(CMAKE_DEPFILE_FLAGS_${lang} "-MF <DEPFILE> -qmakedep=gcc")
+
   # CMAKE_XL_CreateExportList is part of the AIX XL compilers but not the linux ones.
   # If we found the tool, we'll use it to create exports, otherwise stick with the regular
   # create shared library compile line.
diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake
index e233714..9542f69 100644
--- a/Modules/FindJPEG.cmake
+++ b/Modules/FindJPEG.cmake
@@ -5,38 +5,127 @@
 # FindJPEG
 # --------
 #
-# Find JPEG
+# Find the JPEG library (libjpeg)
 #
-# Find the native JPEG includes and library This module defines
+# Imported targets
+# ^^^^^^^^^^^^^^^^
 #
-# ::
+# This module defines the following :prop_tgt:`IMPORTED` targets:
 #
-#   JPEG_INCLUDE_DIR, where to find jpeglib.h, etc.
-#   JPEG_LIBRARIES, the libraries needed to use JPEG.
-#   JPEG_FOUND, If false, do not try to use JPEG.
+# ``JPEG::JPEG``
+#   The JPEG library, if found.
 #
-# also defined, but not for general use are
+# Result variables
+# ^^^^^^^^^^^^^^^^
 #
-# ::
+# This module will set the following variables in your project:
 #
-#   JPEG_LIBRARY, where to find the JPEG library.
+# ``JPEG_FOUND``
+#   If false, do not try to use JPEG.
+# ``JPEG_INCLUDE_DIRS``
+#   where to find jpeglib.h, etc.
+# ``JPEG_LIBRARIES``
+#   the libraries needed to use JPEG.
+# ``JPEG_VERSION``
+#   the version of the JPEG library found
+#
+# Cache variables
+# ^^^^^^^^^^^^^^^
+#
+# The following cache variables may also be set:
+#
+# ``JPEG_INCLUDE_DIRS``
+#   where to find jpeglib.h, etc.
+# ``JPEG_LIBRARY_RELEASE``
+#   where to find the JPEG library (optimized).
+# ``JPEG_LIBRARY_DEBUG``
+#   where to find the JPEG library (debug).
+#
+# Obsolete variables
+# ^^^^^^^^^^^^^^^^^^
+#
+# ``JPEG_INCLUDE_DIR``
+#   where to find jpeglib.h, etc. (same as JPEG_INCLUDE_DIRS)
+# ``JPEG_LIBRARY``
+#   where to find the JPEG library.
 
 find_path(JPEG_INCLUDE_DIR jpeglib.h)
 
-set(JPEG_NAMES ${JPEG_NAMES} jpeg libjpeg)
-find_library(JPEG_LIBRARY NAMES ${JPEG_NAMES} )
+set(jpeg_names ${JPEG_NAMES} jpeg libjpeg)
+foreach(name ${JPEG_NAMES})
+  list(APPEND jpeg_names_debug "${name}d")
+endforeach()
+
+if(NOT JPEG_LIBRARY)
+  find_library(JPEG_LIBRARY_RELEASE NAMES ${jpeg_names})
+  find_library(JPEG_LIBRARY_DEBUG NAMES ${jpeg_names_debug})
+  include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+  select_library_configurations(JPEG)
+  mark_as_advanced(JPEG_LIBRARY_RELEASE JPEG_LIBRARY_DEBUG)
+endif()
+unset(jpeg_names)
+unset(jpeg_names_debug)
+
+if(JPEG_INCLUDE_DIR AND EXISTS "${JPEG_INCLUDE_DIR}/jpeglib.h")
+  file(STRINGS "${JPEG_INCLUDE_DIR}/jpeglib.h"
+    jpeg_lib_version REGEX "^#define[\t ]+JPEG_LIB_VERSION[\t ]+.*")
+
+  if (NOT jpeg_lib_version)
+    # libjpeg-turbo sticks JPEG_LIB_VERSION in jconfig.h
+    find_path(jconfig_dir jconfig.h)
+    if (jconfig_dir)
+      file(STRINGS "${jconfig_dir}/jconfig.h"
+        jpeg_lib_version REGEX "^#define[\t ]+JPEG_LIB_VERSION[\t ]+.*")
+    endif()
+    unset(jconfig_dir)
+  endif()
+
+  string(REGEX REPLACE "^#define[\t ]+JPEG_LIB_VERSION[\t ]+([0-9]+).*"
+    "\\1" JPEG_VERSION "${jpeg_lib_version}")
+  unset(jpeg_lib_version)
+endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(JPEG DEFAULT_MSG JPEG_LIBRARY JPEG_INCLUDE_DIR)
+find_package_handle_standard_args(JPEG
+  REQUIRED_VARS JPEG_LIBRARY JPEG_INCLUDE_DIR
+  VERSION_VAR JPEG_VERSION)
 
 if(JPEG_FOUND)
   set(JPEG_LIBRARIES ${JPEG_LIBRARY})
+  set(JPEG_INCLUDE_DIRS "${JPEG_INCLUDE_DIR}")
+
+  if(NOT TARGET JPEG::JPEG)
+    add_library(JPEG::JPEG UNKNOWN IMPORTED)
+    if(JPEG_INCLUDE_DIRS)
+      set_target_properties(JPEG::JPEG PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${JPEG_INCLUDE_DIRS}")
+    endif()
+    if(EXISTS "${JPEG_LIBRARY}")
+      set_target_properties(JPEG::JPEG PROPERTIES
+        IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+        IMPORTED_LOCATION "${JPEG_LIBRARY}")
+    endif()
+    if(EXISTS "${JPEG_LIBRARY_RELEASE}")
+      set_property(TARGET JPEG::JPEG APPEND PROPERTY
+        IMPORTED_CONFIGURATIONS RELEASE)
+      set_target_properties(JPEG::JPEG PROPERTIES
+        IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+        IMPORTED_LOCATION_RELEASE "${JPEG_LIBRARY_RELEASE}")
+    endif()
+    if(EXISTS "${JPEG_LIBRARY_DEBUG}")
+      set_property(TARGET JPEG::JPEG APPEND PROPERTY
+        IMPORTED_CONFIGURATIONS DEBUG)
+      set_target_properties(JPEG::JPEG PROPERTIES
+        IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+        IMPORTED_LOCATION_DEBUG "${JPEG_LIBRARY_DEBUG}")
+    endif()
+  endif()
 endif()
 
 # Deprecated declarations.
-set (NATIVE_JPEG_INCLUDE_PATH ${JPEG_INCLUDE_DIR} )
+set(NATIVE_JPEG_INCLUDE_PATH ${JPEG_INCLUDE_DIR})
 if(JPEG_LIBRARY)
-  get_filename_component (NATIVE_JPEG_LIB_PATH ${JPEG_LIBRARY} PATH)
+  get_filename_component(NATIVE_JPEG_LIB_PATH ${JPEG_LIBRARY} PATH)
 endif()
 
-mark_as_advanced(JPEG_LIBRARY JPEG_INCLUDE_DIR )
+mark_as_advanced(JPEG_LIBRARY JPEG_INCLUDE_DIR)
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 4bfbf03..75c4441 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -352,6 +352,9 @@
   # Ensure that no error output might be passed upwards.
   if(NOT WRAPPER_RETURN EQUAL 0)
     unset(WRAPPER_OUTPUT)
+  else()
+    # Strip leading whitespace
+    string(REGEX REPLACE "^ +" "" WRAPPER_OUTPUT "${WRAPPER_OUTPUT}")
   endif()
   set(${OUTPUT_VARIABLE} "${WRAPPER_OUTPUT}" PARENT_SCOPE)
   set(${RESULT_VARIABLE} "${WRAPPER_RETURN}" PARENT_SCOPE)
@@ -715,20 +718,20 @@
   # or shared libraries if there aren't any import libraries in use on the system.
   # Note that we do not consider CMAKE_<TYPE>_LIBRARY_PREFIX intentionally here: The linker will for a given file
   # decide how to link it based on file type, not based on a prefix like 'lib'.
-  set(_MPI_LIB_NAME_REGEX "[^\" ]+${CMAKE_STATIC_LIBRARY_SUFFIX}|\"[^\"]+${CMAKE_STATIC_LIBRARY_SUFFIX}\"")
+  set(_MPI_LIB_SUFFIX_REGEX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
   if(DEFINED CMAKE_IMPORT_LIBRARY_SUFFIX)
     if(NOT ("${CMAKE_IMPORT_LIBRARY_SUFFIX}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}"))
-      string(APPEND _MPI_LIB_NAME_REGEX "[^\" ]+${CMAKE_IMPORT_LIBRARY_SUFFIX}|\"[^\"]+${CMAKE_IMPORT_LIBRARY_SUFFIX}\"")
+      string(APPEND _MPI_SUFFIX_REGEX "|${CMAKE_IMPORT_LIBRARY_SUFFIX}")
     endif()
   else()
-    string(APPEND _MPI_LIB_NAME_REGEX "[^\" ]+${CMAKE_SHARED_LIBRARY_SUFFIX}|\"[^\"]+${CMAKE_SHARED_LIBRARY_SUFFIX}\"")
+    string(APPEND _MPI_LIB_SUFFIX_REGEX "|${CMAKE_SHARED_LIBRARY_SUFFIX}")
   endif()
+  set(_MPI_LIB_NAME_REGEX "(([^\" ]+(${_MPI_LIB_SUFFIX_REGEX}))|(\"[^\"]+(${_MPI_LIB_SUFFIX_REGEX})\"))( +|$)")
   string(REPLACE "." "\\." _MPI_LIB_NAME_REGEX "${_MPI_LIB_NAME_REGEX}")
 
-  string(REGEX MATCHALL "(^| )(${_MPI_LIB_NAME_REGEX})" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
+  string(REGEX MATCHALL "${_MPI_LIB_NAME_REGEX}" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
   foreach(_MPI_LIB_NAME IN LISTS MPI_LIBNAMES)
-    string(REGEX REPLACE "^ " "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
-    string(REPLACE "\"" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
+    string(REGEX REPLACE "^ +\"?|\"? +$" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}")
     get_filename_component(_MPI_LIB_PATH "${_MPI_LIB_NAME}" DIRECTORY)
     if(NOT "${_MPI_LIB_PATH}" STREQUAL "")
       list(APPEND MPI_LIB_FULLPATHS_WORK "${_MPI_LIB_NAME}")
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index c3d202e..7521d51 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -58,7 +58,7 @@
 find_path(OPENAL_INCLUDE_DIR al.h
   HINTS
     ENV OPENALDIR
-  PATH_SUFFIXES include/AL include/OpenAL include
+  PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL
   PATHS
   ~/Library/Frameworks
   /Library/Frameworks
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index e252ba5..329ace1 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -242,19 +242,10 @@
         endforeach()
         set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
       else()
-        # The Intel compiler on windows has no verbose mode, so we need to treat it explicitly
-        if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel" AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
-          set("${OPENMP_LIB_NAMES_VAR}" "libiomp5md" PARENT_SCOPE)
-          find_library(OpenMP_libiomp5md_LIBRARY
-            NAMES "libiomp5md"
-            HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
-            CMAKE_FIND_ROOT_PATH_BOTH
-            NO_DEFAULT_PATH
-          )
-          mark_as_advanced(OpenMP_libiomp5md_LIBRARY)
-        else()
-          set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
-        endif()
+        # We do not know how to extract implicit OpenMP libraries for this compiler.
+        # Assume that it handles them automatically, e.g. the Intel Compiler on
+        # Windows should put the dependency in its object files.
+        set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
       endif()
       break()
     elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang"
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index c358ff1..d5cd8bc 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -7,6 +7,12 @@
 #
 # Find the OpenSSL encryption library.
 #
+# Optional COMPONENTS
+# ^^^^^^^^^^^^^^^^^^^
+#
+# This module supports two optional COMPONENTS: ``Crypto`` and ``SSL``.  Both
+# components have associated imported targets, as described below.
+#
 # Imported Targets
 # ^^^^^^^^^^^^^^^^
 #
@@ -23,7 +29,8 @@
 # This module will set the following variables in your project:
 #
 # ``OPENSSL_FOUND``
-#   System has the OpenSSL library.
+#   System has the OpenSSL library. If no components are requested it only
+#   requires the crypto library.
 # ``OPENSSL_INCLUDE_DIR``
 #   The OpenSSL include directory.
 # ``OPENSSL_CRYPTO_LIBRARY``
@@ -371,28 +378,47 @@
   endif ()
 endif ()
 
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-
 set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} )
 
-if (OPENSSL_VERSION)
-  find_package_handle_standard_args(OpenSSL
-    REQUIRED_VARS
-      #OPENSSL_SSL_LIBRARY # FIXME: require based on a component request?
-      OPENSSL_CRYPTO_LIBRARY
-      OPENSSL_INCLUDE_DIR
-    VERSION_VAR
-      OPENSSL_VERSION
-    FAIL_MESSAGE
-      "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
-  )
-else ()
-  find_package_handle_standard_args(OpenSSL "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
-    #OPENSSL_SSL_LIBRARY # FIXME: require based on a component request?
+foreach(_comp IN LISTS OpenSSL_FIND_COMPONENTS)
+  if(_comp STREQUAL "Crypto")
+    if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND
+        (EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR
+        EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR
+        EXISTS "${LIB_EAY_LIBRARY_RELEASE}")
+    )
+      set(OpenSSL_${_comp}_FOUND TRUE)
+    else()
+      set(OpenSSL_${_comp}_FOUND FALSE)
+    endif()
+  elseif(_comp STREQUAL "SSL")
+    if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND
+        (EXISTS "${OPENSSL_SSL_LIBRARY}" OR
+        EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR
+        EXISTS "${SSL_EAY_LIBRARY_RELEASE}")
+    )
+      set(OpenSSL_${_comp}_FOUND TRUE)
+    else()
+      set(OpenSSL_${_comp}_FOUND FALSE)
+    endif()
+  else()
+    message(WARNING "${_comp} is not a valid OpenSSL component")
+    set(OpenSSL_${_comp}_FOUND FALSE)
+  endif()
+endforeach()
+unset(_comp)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(OpenSSL
+  REQUIRED_VARS
     OPENSSL_CRYPTO_LIBRARY
     OPENSSL_INCLUDE_DIR
-  )
-endif ()
+  VERSION_VAR
+    OPENSSL_VERSION
+  HANDLE_COMPONENTS
+  FAIL_MESSAGE
+    "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
+)
 
 mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
 
@@ -425,6 +451,7 @@
         IMPORTED_LOCATION_DEBUG "${LIB_EAY_LIBRARY_DEBUG}")
     endif()
   endif()
+
   if(NOT TARGET OpenSSL::SSL AND
       (EXISTS "${OPENSSL_SSL_LIBRARY}" OR
         EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 179b394..67bda7a 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -436,10 +436,16 @@
     string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION})
 
     # try to use pythonX.Y-config tool
+    set (_${_PYTHON_PREFIX}_CONFIG_NAMES)
+    if (DEFINED CMAKE_LIBRARY_ARCHITECTURE)
+      set (_${_PYTHON_PREFIX}_CONFIG_NAMES "${CMAKE_LIBRARY_ARCHITECTURE}-python${_${_PYTHON_PREFIX}_VERSION}-config")
+    endif()
+    list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config")
     find_program (_${_PYTHON_PREFIX}_CONFIG
-                  NAMES python${_${_PYTHON_PREFIX}_VERSION}-config
+                  NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
                   HINTS ${_${_PYTHON_PREFIX}_HINTS}
                   PATH_SUFFIXES bin)
+    unset (_${_PYTHON_PREFIX}_CONFIG_NAMES)
 
     if (NOT _${_PYTHON_PREFIX}_CONFIG)
       continue()
@@ -481,17 +487,17 @@
                     PATH_SUFFIXES lib
                     NO_SYSTEM_ENVIRONMENT_PATH
                     NO_CMAKE_SYSTEM_PATH)
-       # retrieve runtime library
-       if (${_PYTHON_PREFIX}_LIBRARY_RELEASE)
-         get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
-         _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
-                                       NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
-                                       NAMES_PER_DIR
-                                       HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS}
-                                       PATH_SUFFIXES bin
-                                       NO_SYSTEM_ENVIRONMENT_PATH
-                                       NO_CMAKE_SYSTEM_PATH)
-       endif()
+      # retrieve runtime library
+      if (${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+        get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+        _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+                                      NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+                                      NAMES_PER_DIR
+                                      HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS}
+                                      PATH_SUFFIXES bin
+                                      NO_SYSTEM_ENVIRONMENT_PATH
+                                      NO_CMAKE_SYSTEM_PATH)
+      endif()
     endif()
 
     # retrieve include directory
@@ -538,7 +544,7 @@
                           [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
                           [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
                           [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
-                    PATH_SUFFIXES lib libs
+                    PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs
                                   lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu
                                   lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m
                                   lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u
@@ -546,7 +552,7 @@
                                   lib/python${_${_PYTHON_PREFIX}_VERSION}/config)
       # retrieve runtime library
       if (${_PYTHON_PREFIX}_LIBRARY_RELEASE)
-         get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+        get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
         _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
                                       NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}
                                             python${_${_PYTHON_PREFIX}_VERSION}mu
@@ -585,7 +591,7 @@
                         PATH_SUFFIXES lib libs)
         endif()
         if (${_PYTHON_PREFIX}_LIBRARY_DEBUG)
-         get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY)
+          get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY)
           _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
                                         NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d
                                         NAMES_PER_DIR
@@ -608,6 +614,8 @@
               list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
             elseif (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
               list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
+            elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
+              list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
             else()
               # assume library is in a directory under root
               get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${${_${_PYTHON_PREFIX}_LIB}}" DIRECTORY)
diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake
index 50e9361..0fd76c0 100644
--- a/Modules/InstallRequiredSystemLibraries.cmake
+++ b/Modules/InstallRequiredSystemLibraries.cmake
@@ -460,6 +460,10 @@
         if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}d.dll")
           set(__install__libs ${__install__libs}
             "${MSVC_MFC_DIR}/mfc${v}d.dll"
+          )
+        endif()
+        if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}d.dll")
+          set(__install__libs ${__install__libs}
             "${MSVC_MFC_DIR}/mfcm${v}d.dll"
           )
         endif()
@@ -474,6 +478,10 @@
         if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}.dll")
           set(__install__libs ${__install__libs}
             "${MSVC_MFC_DIR}/mfc${v}.dll"
+          )
+        endif()
+        if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}.dll")
+          set(__install__libs ${__install__libs}
             "${MSVC_MFC_DIR}/mfcm${v}.dll"
           )
         endif()
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index add1dc1..e623902 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -261,7 +261,40 @@
   else()
     # https://developer.android.com/ndk/guides/application_mk.html
     # Default is the oldest ARM ABI.
-    set(CMAKE_ANDROID_ARCH_ABI "armeabi")
+
+    # Lookup the available ABIs among all toolchains.
+    set(_ANDROID_ABIS "")
+    file(GLOB _ANDROID_CONFIG_MKS
+      "${CMAKE_ANDROID_NDK}/build/core/toolchains/*/config.mk"
+      "${CMAKE_ANDROID_NDK}/toolchains/*/config.mk"
+      )
+    foreach(config_mk IN LISTS _ANDROID_CONFIG_MKS)
+      file(STRINGS "${config_mk}" _ANDROID_TOOL_ABIS REGEX "^TOOLCHAIN_ABIS :=")
+      string(REPLACE "TOOLCHAIN_ABIS :=" "" _ANDROID_TOOL_ABIS "${_ANDROID_TOOL_ABIS}")
+      separate_arguments(_ANDROID_TOOL_ABIS UNIX_COMMAND "${_ANDROID_TOOL_ABIS}")
+      list(APPEND _ANDROID_ABIS ${_ANDROID_TOOL_ABIS})
+      unset(_ANDROID_TOOL_ABIS)
+    endforeach()
+    unset(_ANDROID_CONFIG_MKS)
+
+    # Choose the oldest among the available arm ABIs.
+    if(_ANDROID_ABIS)
+      list(REMOVE_DUPLICATES _ANDROID_ABIS)
+      cmake_policy(PUSH)
+      cmake_policy(SET CMP0057 NEW)
+      foreach(abi armeabi armeabi-v7a arm64-v8a)
+        if("${abi}" IN_LIST _ANDROID_ABIS)
+          set(CMAKE_ANDROID_ARCH_ABI "${abi}")
+          break()
+        endif()
+      endforeach()
+      cmake_policy(POP)
+    endif()
+    unset(_ANDROID_ABIS)
+
+    if(NOT CMAKE_ANDROID_ARCH_ABI)
+      set(CMAKE_ANDROID_ARCH_ABI "armeabi")
+    endif()
   endif()
 endif()
 set(CMAKE_ANDROID_ARCH "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_ARCH}")
diff --git a/Modules/Platform/Darwin-Absoft-Fortran.cmake b/Modules/Platform/Apple-Absoft-Fortran.cmake
similarity index 100%
rename from Modules/Platform/Darwin-Absoft-Fortran.cmake
rename to Modules/Platform/Apple-Absoft-Fortran.cmake
diff --git a/Modules/Platform/Darwin-AppleClang-C.cmake b/Modules/Platform/Apple-AppleClang-C.cmake
similarity index 83%
rename from Modules/Platform/Darwin-AppleClang-C.cmake
rename to Modules/Platform/Apple-AppleClang-C.cmake
index 3216b29..f45ccf4 100644
--- a/Modules/Platform/Darwin-AppleClang-C.cmake
+++ b/Modules/Platform/Apple-AppleClang-C.cmake
@@ -1,4 +1,4 @@
-include(Platform/Darwin-Clang-C)
+include(Platform/Apple-Clang-C)
 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.2)
   set(CMAKE_C_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
 else()
diff --git a/Modules/Platform/Darwin-AppleClang-CXX.cmake b/Modules/Platform/Apple-AppleClang-CXX.cmake
similarity index 83%
rename from Modules/Platform/Darwin-AppleClang-CXX.cmake
rename to Modules/Platform/Apple-AppleClang-CXX.cmake
index 3fedf8c..1128204 100644
--- a/Modules/Platform/Darwin-AppleClang-CXX.cmake
+++ b/Modules/Platform/Apple-AppleClang-CXX.cmake
@@ -1,4 +1,4 @@
-include(Platform/Darwin-Clang-CXX)
+include(Platform/Apple-Clang-CXX)
 if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2)
   set(CMAKE_CXX_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
 else()
diff --git a/Modules/Platform/Apple-Clang-C.cmake b/Modules/Platform/Apple-Clang-C.cmake
new file mode 100644
index 0000000..4d0dc82
--- /dev/null
+++ b/Modules/Platform/Apple-Clang-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/Apple-Clang)
+__apple_compiler_clang(C)
diff --git a/Modules/Platform/Apple-Clang-CXX.cmake b/Modules/Platform/Apple-Clang-CXX.cmake
new file mode 100644
index 0000000..6c1ddc1
--- /dev/null
+++ b/Modules/Platform/Apple-Clang-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/Apple-Clang)
+__apple_compiler_clang(CXX)
diff --git a/Modules/Platform/Darwin-Clang.cmake b/Modules/Platform/Apple-Clang.cmake
similarity index 93%
rename from Modules/Platform/Darwin-Clang.cmake
rename to Modules/Platform/Apple-Clang.cmake
index f8a07ec..0681bfb 100644
--- a/Modules/Platform/Darwin-Clang.cmake
+++ b/Modules/Platform/Apple-Clang.cmake
@@ -3,12 +3,9 @@
 
 
 # This module is shared by multiple languages; use include blocker.
-if(__DARWIN_COMPILER_CLANG)
-  return()
-endif()
-set(__DARWIN_COMPILER_CLANG 1)
+include_guard()
 
-macro(__darwin_compiler_clang lang)
+macro(__apple_compiler_clang lang)
   set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
   set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
diff --git a/Modules/Platform/Apple-GNU-C.cmake b/Modules/Platform/Apple-GNU-C.cmake
new file mode 100644
index 0000000..5481c99
--- /dev/null
+++ b/Modules/Platform/Apple-GNU-C.cmake
@@ -0,0 +1,4 @@
+include(Platform/Apple-GNU)
+__apple_compiler_gnu(C)
+cmake_gnu_set_sysroot_flag(C)
+cmake_gnu_set_osx_deployment_target_flag(C)
diff --git a/Modules/Platform/Apple-GNU-CXX.cmake b/Modules/Platform/Apple-GNU-CXX.cmake
new file mode 100644
index 0000000..727f726
--- /dev/null
+++ b/Modules/Platform/Apple-GNU-CXX.cmake
@@ -0,0 +1,4 @@
+include(Platform/Apple-GNU)
+__apple_compiler_gnu(CXX)
+cmake_gnu_set_sysroot_flag(CXX)
+cmake_gnu_set_osx_deployment_target_flag(CXX)
diff --git a/Modules/Platform/Darwin-GNU-Fortran.cmake b/Modules/Platform/Apple-GNU-Fortran.cmake
similarity index 86%
rename from Modules/Platform/Darwin-GNU-Fortran.cmake
rename to Modules/Platform/Apple-GNU-Fortran.cmake
index 568d79b..2f53603 100644
--- a/Modules/Platform/Darwin-GNU-Fortran.cmake
+++ b/Modules/Platform/Apple-GNU-Fortran.cmake
@@ -1,8 +1,8 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-include(Platform/Darwin-GNU)
-__darwin_compiler_gnu(Fortran)
+include(Platform/Apple-GNU)
+__apple_compiler_gnu(Fortran)
 cmake_gnu_set_sysroot_flag(Fortran)
 cmake_gnu_set_osx_deployment_target_flag(Fortran)
 
diff --git a/Modules/Platform/Darwin-GNU.cmake b/Modules/Platform/Apple-GNU.cmake
similarity index 95%
rename from Modules/Platform/Darwin-GNU.cmake
rename to Modules/Platform/Apple-GNU.cmake
index 9f9ef01..0eb8168 100644
--- a/Modules/Platform/Darwin-GNU.cmake
+++ b/Modules/Platform/Apple-GNU.cmake
@@ -3,12 +3,9 @@
 
 
 # This module is shared by multiple languages; use include blocker.
-if(__DARWIN_COMPILER_GNU)
-  return()
-endif()
-set(__DARWIN_COMPILER_GNU 1)
+include_guard()
 
-macro(__darwin_compiler_gnu lang)
+macro(__apple_compiler_gnu lang)
   set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output
   # GNU does not have -shared on OS X
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
diff --git a/Modules/Platform/Apple-Intel-C.cmake b/Modules/Platform/Apple-Intel-C.cmake
new file mode 100644
index 0000000..95bb270
--- /dev/null
+++ b/Modules/Platform/Apple-Intel-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/Apple-Intel)
+__apple_compiler_intel(C)
diff --git a/Modules/Platform/Apple-Intel-CXX.cmake b/Modules/Platform/Apple-Intel-CXX.cmake
new file mode 100644
index 0000000..b87e512
--- /dev/null
+++ b/Modules/Platform/Apple-Intel-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/Apple-Intel)
+__apple_compiler_intel(CXX)
diff --git a/Modules/Platform/Darwin-Intel-Fortran.cmake b/Modules/Platform/Apple-Intel-Fortran.cmake
similarity index 81%
rename from Modules/Platform/Darwin-Intel-Fortran.cmake
rename to Modules/Platform/Apple-Intel-Fortran.cmake
index 2299da9..e54e237 100644
--- a/Modules/Platform/Darwin-Intel-Fortran.cmake
+++ b/Modules/Platform/Apple-Intel-Fortran.cmake
@@ -1,8 +1,8 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-include(Platform/Darwin-Intel)
-__darwin_compiler_intel(Fortran)
+include(Platform/Apple-Intel)
+__apple_compiler_intel(Fortran)
 
 set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
 set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-current_version ")
diff --git a/Modules/Platform/Darwin-Intel.cmake b/Modules/Platform/Apple-Intel.cmake
similarity index 84%
rename from Modules/Platform/Darwin-Intel.cmake
rename to Modules/Platform/Apple-Intel.cmake
index dd33cec..2d4f7e5 100644
--- a/Modules/Platform/Darwin-Intel.cmake
+++ b/Modules/Platform/Apple-Intel.cmake
@@ -3,12 +3,9 @@
 
 
 # This module is shared by multiple languages; use include blocker.
-if(__DARWIN_COMPILER_INTEL)
-  return()
-endif()
-set(__DARWIN_COMPILER_INTEL 1)
+include_guard()
 
-macro(__darwin_compiler_intel lang)
+macro(__apple_compiler_intel lang)
   set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
   set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
diff --git a/Modules/Platform/Darwin-NAG-Fortran.cmake b/Modules/Platform/Apple-NAG-Fortran.cmake
similarity index 100%
rename from Modules/Platform/Darwin-NAG-Fortran.cmake
rename to Modules/Platform/Apple-NAG-Fortran.cmake
diff --git a/Modules/Platform/Darwin-NVIDIA-CUDA.cmake b/Modules/Platform/Apple-NVIDIA-CUDA.cmake
similarity index 100%
rename from Modules/Platform/Darwin-NVIDIA-CUDA.cmake
rename to Modules/Platform/Apple-NVIDIA-CUDA.cmake
diff --git a/Modules/Platform/Apple-PGI-C.cmake b/Modules/Platform/Apple-PGI-C.cmake
new file mode 100644
index 0000000..1e11724
--- /dev/null
+++ b/Modules/Platform/Apple-PGI-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/Apple-PGI)
+__apple_compiler_pgi(C)
diff --git a/Modules/Platform/Apple-PGI-CXX.cmake b/Modules/Platform/Apple-PGI-CXX.cmake
new file mode 100644
index 0000000..aa5daf7
--- /dev/null
+++ b/Modules/Platform/Apple-PGI-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/Apple-PGI)
+__apple_compiler_pgi(CXX)
diff --git a/Modules/Platform/Apple-PGI-Fortran.cmake b/Modules/Platform/Apple-PGI-Fortran.cmake
new file mode 100644
index 0000000..1e3e4b1
--- /dev/null
+++ b/Modules/Platform/Apple-PGI-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/Apple-PGI)
+__apple_compiler_pgi(Fortran)
diff --git a/Modules/Platform/Darwin-PGI.cmake b/Modules/Platform/Apple-PGI.cmake
similarity index 80%
rename from Modules/Platform/Darwin-PGI.cmake
rename to Modules/Platform/Apple-PGI.cmake
index 04479a8..8d343b7 100644
--- a/Modules/Platform/Darwin-PGI.cmake
+++ b/Modules/Platform/Apple-PGI.cmake
@@ -2,12 +2,9 @@
 # file Copyright.txt or https://cmake.org/licensing for details.
 
 # This module is shared by multiple languages; use include blocker.
-if(__DARWIN_COMPILER_PGI)
-  return()
-endif()
-set(__DARWIN_COMPILER_PGI 1)
+include_guard()
 
-macro(__darwin_compiler_pgi lang)
+macro(__apple_compiler_pgi lang)
   set(CMAKE_${lang}_OSX_COMPATIBILITY_VERSION_FLAG "-Wl,-compatibility_version,")
   set(CMAKE_${lang}_OSX_CURRENT_VERSION_FLAG "-Wl,-current_version,")
   set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-install_name")
diff --git a/Modules/Platform/Apple-VisualAge-C.cmake b/Modules/Platform/Apple-VisualAge-C.cmake
new file mode 100644
index 0000000..7fa6032
--- /dev/null
+++ b/Modules/Platform/Apple-VisualAge-C.cmake
@@ -0,0 +1 @@
+include(Platform/Apple-XL-C)
diff --git a/Modules/Platform/Apple-VisualAge-CXX.cmake b/Modules/Platform/Apple-VisualAge-CXX.cmake
new file mode 100644
index 0000000..12dd347
--- /dev/null
+++ b/Modules/Platform/Apple-VisualAge-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Apple-XL-CXX)
diff --git a/Modules/Platform/Darwin-XL-C.cmake b/Modules/Platform/Apple-XL-C.cmake
similarity index 100%
rename from Modules/Platform/Darwin-XL-C.cmake
rename to Modules/Platform/Apple-XL-C.cmake
diff --git a/Modules/Platform/Darwin-XL-CXX.cmake b/Modules/Platform/Apple-XL-CXX.cmake
similarity index 100%
rename from Modules/Platform/Darwin-XL-CXX.cmake
rename to Modules/Platform/Apple-XL-CXX.cmake
diff --git a/Modules/Platform/Darwin-Clang-C.cmake b/Modules/Platform/Darwin-Clang-C.cmake
deleted file mode 100644
index 0a1502e..0000000
--- a/Modules/Platform/Darwin-Clang-C.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-include(Platform/Darwin-Clang)
-__darwin_compiler_clang(C)
diff --git a/Modules/Platform/Darwin-Clang-CXX.cmake b/Modules/Platform/Darwin-Clang-CXX.cmake
deleted file mode 100644
index f8e8d88..0000000
--- a/Modules/Platform/Darwin-Clang-CXX.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-include(Platform/Darwin-Clang)
-__darwin_compiler_clang(CXX)
diff --git a/Modules/Platform/Darwin-GNU-C.cmake b/Modules/Platform/Darwin-GNU-C.cmake
deleted file mode 100644
index efdfd00..0000000
--- a/Modules/Platform/Darwin-GNU-C.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-include(Platform/Darwin-GNU)
-__darwin_compiler_gnu(C)
-cmake_gnu_set_sysroot_flag(C)
-cmake_gnu_set_osx_deployment_target_flag(C)
diff --git a/Modules/Platform/Darwin-GNU-CXX.cmake b/Modules/Platform/Darwin-GNU-CXX.cmake
deleted file mode 100644
index e3c2ea7..0000000
--- a/Modules/Platform/Darwin-GNU-CXX.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-include(Platform/Darwin-GNU)
-__darwin_compiler_gnu(CXX)
-cmake_gnu_set_sysroot_flag(CXX)
-cmake_gnu_set_osx_deployment_target_flag(CXX)
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index b539e45..3db77aa 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -20,6 +20,10 @@
 set(CMAKE_OSX_ARCHITECTURES "$ENV{CMAKE_OSX_ARCHITECTURES}" CACHE STRING
   "Build architectures for OSX")
 
+# macOS, iOS, tvOS, and watchOS should lookup compilers from
+# Platform/Apple-${CMAKE_CXX_COMPILER_ID}-<LANG>
+set(CMAKE_EFFECTIVE_SYSTEM_NAME "Apple")
+
 #----------------------------------------------------------------------------
 # _CURRENT_OSX_VERSION - as a two-component string: 10.5, 10.6, ...
 #
diff --git a/Modules/Platform/Darwin-Intel-C.cmake b/Modules/Platform/Darwin-Intel-C.cmake
deleted file mode 100644
index 81c630f..0000000
--- a/Modules/Platform/Darwin-Intel-C.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-include(Platform/Darwin-Intel)
-__darwin_compiler_intel(C)
diff --git a/Modules/Platform/Darwin-Intel-CXX.cmake b/Modules/Platform/Darwin-Intel-CXX.cmake
deleted file mode 100644
index 90ae53b..0000000
--- a/Modules/Platform/Darwin-Intel-CXX.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-include(Platform/Darwin-Intel)
-__darwin_compiler_intel(CXX)
diff --git a/Modules/Platform/Darwin-PGI-C.cmake b/Modules/Platform/Darwin-PGI-C.cmake
deleted file mode 100644
index 790919b..0000000
--- a/Modules/Platform/Darwin-PGI-C.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-include(Platform/Darwin-PGI)
-__darwin_compiler_pgi(C)
diff --git a/Modules/Platform/Darwin-PGI-CXX.cmake b/Modules/Platform/Darwin-PGI-CXX.cmake
deleted file mode 100644
index ceaed71..0000000
--- a/Modules/Platform/Darwin-PGI-CXX.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-include(Platform/Darwin-PGI)
-__darwin_compiler_pgi(CXX)
diff --git a/Modules/Platform/Darwin-PGI-Fortran.cmake b/Modules/Platform/Darwin-PGI-Fortran.cmake
deleted file mode 100644
index 146807b..0000000
--- a/Modules/Platform/Darwin-PGI-Fortran.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-include(Platform/Darwin-PGI)
-__darwin_compiler_pgi(Fortran)
diff --git a/Modules/Platform/Darwin-VisualAge-C.cmake b/Modules/Platform/Darwin-VisualAge-C.cmake
deleted file mode 100644
index 859914f..0000000
--- a/Modules/Platform/Darwin-VisualAge-C.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include(Platform/Darwin-XL-C)
diff --git a/Modules/Platform/Darwin-VisualAge-CXX.cmake b/Modules/Platform/Darwin-VisualAge-CXX.cmake
deleted file mode 100644
index 46c1005..0000000
--- a/Modules/Platform/Darwin-VisualAge-CXX.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include(Platform/Darwin-XL-CXX)
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index e23b070..a007098 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -557,6 +557,7 @@
   cmSiteNameCommand.h
   cmSourceGroupCommand.cxx
   cmSourceGroupCommand.h
+  cmStringReplaceHelper.cxx
   cmStringCommand.cxx
   cmStringCommand.h
   cmSubdirCommand.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 593c139..7aadb3b 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 11)
-set(CMake_VERSION_PATCH 20180412)
+set(CMake_VERSION_PATCH 20180420)
 #set(CMake_VERSION_RC 1)
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index 7ca1cbc..adf9ef8 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -95,7 +95,11 @@
 
 bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
 {
-  if (args.size() != 3) {
+  bool parent_scope = false;
+  if (args.size() == 4 && args[3] == "PARENT_SCOPE") {
+    // Undocumented PARENT_SCOPE option for use within CMake.
+    parent_scope = true;
+  } else if (args.size() != 3) {
     this->SetError("GET must be given exactly 2 additional arguments.");
     return false;
   }
@@ -115,7 +119,8 @@
   }
 
   // Lookup the policy setting.
-  cmPolicies::PolicyStatus status = this->Makefile->GetPolicyStatus(pid);
+  cmPolicies::PolicyStatus status =
+    this->Makefile->GetPolicyStatus(pid, parent_scope);
   switch (status) {
     case cmPolicies::OLD:
       // Report that the policy is set to OLD.
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index f9eb90f..cf277d5 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1893,6 +1893,13 @@
     retVal = 1;
   }
 
+  // The OpenWatcom tools do not return an error code when a link
+  // library is not found!
+  if (this->CMakeInstance->GetState()->UseWatcomWMake() && retVal == 0 &&
+      output.find("W1008: cannot open") != std::string::npos) {
+    retVal = 1;
+  }
+
   return retVal;
 }
 
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index d562df7..599e27c 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -101,31 +101,6 @@
   return encoded;
 }
 
-static bool IsIdentChar(char c)
-{
-  return ('a' <= c && c <= 'z') ||
-    ('+' <= c && c <= '9') || // +,-./ and numbers
-    ('A' <= c && c <= 'Z') || (c == '_') || (c == '$') || (c == '\\') ||
-    (c == ' ') || (c == ':');
-}
-
-std::string cmGlobalNinjaGenerator::EncodeIdent(const std::string& ident,
-                                                std::ostream& vars)
-{
-  if (std::find_if(ident.begin(), ident.end(),
-                   [](char c) { return !IsIdentChar(c); }) != ident.end()) {
-    static unsigned VarNum = 0;
-    std::ostringstream names;
-    names << "ident" << VarNum++;
-    vars << names.str() << " = " << ident << "\n";
-    return "$" + names.str();
-  }
-  std::string result = ident;
-  cmSystemTools::ReplaceString(result, " ", "$ ");
-  cmSystemTools::ReplaceString(result, ":", "$:");
-  return result;
-}
-
 std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string& lit)
 {
   std::string result = lit;
@@ -143,7 +118,10 @@
   else
     std::replace(result.begin(), result.end(), '/', '\\');
 #endif
-  return EncodeLiteral(result);
+  result = EncodeLiteral(result);
+  cmSystemTools::ReplaceString(result, " ", "$ ");
+  cmSystemTools::ReplaceString(result, ":", "$:");
+  return result;
 }
 
 void cmGlobalNinjaGenerator::WriteBuild(
@@ -177,14 +155,14 @@
 
   // Write explicit dependencies.
   for (std::string const& explicitDep : explicitDeps) {
-    arguments += " " + EncodeIdent(EncodePath(explicitDep), os);
+    arguments += " " + EncodePath(explicitDep);
   }
 
   // Write implicit dependencies.
   if (!implicitDeps.empty()) {
     arguments += " |";
     for (std::string const& implicitDep : implicitDeps) {
-      arguments += " " + EncodeIdent(EncodePath(implicitDep), os);
+      arguments += " " + EncodePath(implicitDep);
     }
   }
 
@@ -192,7 +170,7 @@
   if (!orderOnlyDeps.empty()) {
     arguments += " ||";
     for (std::string const& orderOnlyDep : orderOnlyDeps) {
-      arguments += " " + EncodeIdent(EncodePath(orderOnlyDep), os);
+      arguments += " " + EncodePath(orderOnlyDep);
     }
   }
 
@@ -203,7 +181,7 @@
   // Write outputs files.
   build += "build";
   for (std::string const& output : outputs) {
-    build += " " + EncodeIdent(EncodePath(output), os);
+    build += " " + EncodePath(output);
     if (this->ComputingUnknownDependencies) {
       this->CombinedBuildOutputs.insert(output);
     }
@@ -211,7 +189,7 @@
   if (!implicitOuts.empty()) {
     build += " |";
     for (std::string const& implicitOut : implicitOuts) {
-      build += " " + EncodeIdent(EncodePath(implicitOut), os);
+      build += " " + EncodePath(implicitOut);
     }
   }
   build += ":";
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index a779919..bfff3d9 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -73,7 +73,6 @@
   static void WriteDivider(std::ostream& os);
 
   static std::string EncodeRuleName(std::string const& name);
-  static std::string EncodeIdent(const std::string& ident, std::ostream& vars);
   static std::string EncodeLiteral(const std::string& lit);
   std::string EncodePath(const std::string& path);
 
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index df671c2..4481bdc 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -841,6 +841,19 @@
   return buildFile;
 }
 
+void cmGlobalXCodeGenerator::AddXCodeProjBuildRule(
+  cmGeneratorTarget* target, std::vector<cmSourceFile*>& sources) const
+{
+  std::string listfile =
+    target->GetLocalGenerator()->GetCurrentSourceDirectory();
+  listfile += "/CMakeLists.txt";
+  cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(listfile);
+  if (std::find(sources.begin(), sources.end(), srcCMakeLists) ==
+      sources.end()) {
+    sources.push_back(srcCMakeLists);
+  }
+}
+
 std::string GetSourcecodeValueFromFileExtension(const std::string& _ext,
                                                 const std::string& lang,
                                                 bool& keepLastKnownFileType)
@@ -1063,10 +1076,7 @@
     }
 
     // Add CMakeLists.txt file for user convenience.
-    std::string listfile =
-      gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
-    listfile += "/CMakeLists.txt";
-    classes.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
+    this->AddXCodeProjBuildRule(gtgt, classes);
 
     std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
 
@@ -2359,10 +2369,7 @@
     }
 
     // Add CMakeLists.txt file for user convenience.
-    std::string listfile =
-      gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
-    listfile += "/CMakeLists.txt";
-    sources.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
+    this->AddXCodeProjBuildRule(gtgt, sources);
 
     for (auto sourceFile : sources) {
       if (!sourceFile->GetPropertyAsBool("GENERATED")) {
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index b45887e..7c51177 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -198,6 +198,8 @@
                                           cmGeneratorTarget* target);
   cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, cmSourceFile* sf,
                                        cmGeneratorTarget* gtgt);
+  void AddXCodeProjBuildRule(cmGeneratorTarget* target,
+                             std::vector<cmSourceFile*>& sources) const;
   bool CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>&);
   bool IsHeaderFile(cmSourceFile*);
   void AddDependTarget(cmXCodeObject* target, cmXCodeObject* dependTarget);
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 821e6d1..31bc1c0 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -5,14 +5,19 @@
 #include "cmsys/RegularExpression.hxx"
 #include <algorithm>
 #include <assert.h>
+#include <functional>
 #include <iterator>
+#include <set>
 #include <sstream>
+#include <stdexcept>
 #include <stdio.h>
 #include <stdlib.h> // required for atoi
 
 #include "cmAlgorithms.h"
+#include "cmGeneratorExpression.h"
 #include "cmMakefile.h"
 #include "cmPolicies.h"
+#include "cmStringReplaceHelper.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
 
@@ -54,6 +59,9 @@
   if (subCommand == "REMOVE_DUPLICATES") {
     return this->HandleRemoveDuplicatesCommand(args);
   }
+  if (subCommand == "TRANSFORM") {
+    return this->HandleTransformCommand(args);
+  }
   if (subCommand == "SORT") {
     return this->HandleSortCommand(args);
   }
@@ -407,6 +415,554 @@
   return true;
 }
 
+// Helpers for list(TRANSFORM <list> ...)
+namespace {
+using transform_type = std::function<std::string(const std::string&)>;
+
+class transform_error : public std::runtime_error
+{
+public:
+  transform_error(const std::string& error)
+    : std::runtime_error(error)
+  {
+  }
+};
+
+class TransformSelector
+{
+public:
+  virtual ~TransformSelector() {}
+
+  std::string Tag;
+
+  virtual bool Validate(std::size_t count = 0) = 0;
+
+  virtual bool InSelection(const std::string&) = 0;
+
+  virtual void Transform(std::vector<std::string>& list,
+                         const transform_type& transform)
+  {
+    std::transform(list.begin(), list.end(), list.begin(), transform);
+  }
+
+protected:
+  TransformSelector(std::string&& tag)
+    : Tag(std::move(tag))
+  {
+  }
+};
+class TransformNoSelector : public TransformSelector
+{
+public:
+  TransformNoSelector()
+    : TransformSelector("NO SELECTOR")
+  {
+  }
+
+  bool Validate(std::size_t) override { return true; }
+
+  bool InSelection(const std::string&) override { return true; }
+};
+class TransformSelectorRegex : public TransformSelector
+{
+public:
+  TransformSelectorRegex(const std::string& regex)
+    : TransformSelector("REGEX")
+    , Regex(regex)
+  {
+  }
+
+  bool Validate(std::size_t) override { return this->Regex.is_valid(); }
+
+  bool InSelection(const std::string& value) override
+  {
+    return this->Regex.find(value);
+  }
+
+  cmsys::RegularExpression Regex;
+};
+class TransformSelectorIndexes : public TransformSelector
+{
+public:
+  std::vector<int> Indexes;
+
+  bool InSelection(const std::string&) override { return true; }
+
+  void Transform(std::vector<std::string>& list,
+                 const transform_type& transform) override
+  {
+    this->Validate(list.size());
+
+    for (auto index : this->Indexes) {
+      list[index] = transform(list[index]);
+    }
+  }
+
+protected:
+  TransformSelectorIndexes(std::string&& tag)
+    : TransformSelector(std::move(tag))
+  {
+  }
+  TransformSelectorIndexes(std::string&& tag, std::vector<int>&& indexes)
+    : TransformSelector(std::move(tag))
+    , Indexes(indexes)
+  {
+  }
+
+  int NormalizeIndex(int index, std::size_t count)
+  {
+    if (index < 0) {
+      index = static_cast<int>(count) + index;
+    }
+    if (index < 0 || count <= static_cast<std::size_t>(index)) {
+      std::ostringstream str;
+      str << "sub-command TRANSFORM, selector " << this->Tag
+          << ", index: " << index << " out of range (-" << count << ", "
+          << count - 1 << ").";
+      throw transform_error(str.str());
+    }
+    return index;
+  }
+};
+class TransformSelectorAt : public TransformSelectorIndexes
+{
+public:
+  TransformSelectorAt(std::vector<int>&& indexes)
+    : TransformSelectorIndexes("AT", std::move(indexes))
+  {
+  }
+
+  bool Validate(std::size_t count) override
+  {
+    decltype(Indexes) indexes;
+
+    for (auto index : Indexes) {
+      indexes.push_back(this->NormalizeIndex(index, count));
+    }
+    this->Indexes = std::move(indexes);
+
+    return true;
+  }
+};
+class TransformSelectorFor : public TransformSelectorIndexes
+{
+public:
+  TransformSelectorFor(int start, int stop, int step)
+    : TransformSelectorIndexes("FOR")
+    , Start(start)
+    , Stop(stop)
+    , Step(step)
+  {
+  }
+
+  bool Validate(std::size_t count) override
+  {
+    this->Start = this->NormalizeIndex(this->Start, count);
+    this->Stop = this->NormalizeIndex(this->Stop, count);
+
+    // compute indexes
+    auto size = (this->Stop - this->Start + 1) / this->Step;
+    if ((this->Stop - this->Start + 1) % this->Step != 0) {
+      size += 1;
+    }
+
+    this->Indexes.resize(size);
+    auto start = this->Start, step = this->Step;
+    std::generate(this->Indexes.begin(), this->Indexes.end(),
+                  [&start, step]() -> int {
+                    auto r = start;
+                    start += step;
+                    return r;
+                  });
+
+    return true;
+  }
+
+private:
+  int Start, Stop, Step;
+};
+
+class TransformAction
+{
+public:
+  virtual ~TransformAction() {}
+
+  virtual std::string Transform(const std::string& input) = 0;
+};
+class TransformReplace : public TransformAction
+{
+public:
+  TransformReplace(const std::vector<std::string>& arguments,
+                   cmMakefile* makefile)
+    : ReplaceHelper(arguments[0], arguments[1], makefile)
+  {
+    makefile->ClearMatches();
+
+    if (!this->ReplaceHelper.IsRegularExpressionValid()) {
+      std::ostringstream error;
+      error
+        << "sub-command TRANSFORM, action REPLACE: Failed to compile regex \""
+        << arguments[0] << "\".";
+      throw transform_error(error.str());
+    }
+    if (!this->ReplaceHelper.IsReplaceExpressionValid()) {
+      std::ostringstream error;
+      error << "sub-command TRANSFORM, action REPLACE: "
+            << this->ReplaceHelper.GetError() << ".";
+      throw transform_error(error.str());
+    }
+  }
+
+  std::string Transform(const std::string& input) override
+  {
+    // Scan through the input for all matches.
+    std::string output;
+
+    if (!this->ReplaceHelper.Replace(input, output)) {
+      std::ostringstream error;
+      error << "sub-command TRANSFORM, action REPLACE: "
+            << this->ReplaceHelper.GetError() << ".";
+      throw transform_error(error.str());
+    }
+
+    return output;
+  }
+
+private:
+  cmStringReplaceHelper ReplaceHelper;
+};
+}
+
+bool cmListCommand::HandleTransformCommand(
+  std::vector<std::string> const& args)
+{
+  if (args.size() < 3) {
+    this->SetError(
+      "sub-command TRANSFORM requires an action to be specified.");
+    return false;
+  }
+
+  // Structure collecting all elements of the command
+  struct Command
+  {
+    Command(const std::string& listName)
+      : ListName(listName)
+      , OutputName(listName)
+    {
+    }
+
+    std::string Name;
+    std::string ListName;
+    std::vector<std::string> Arguments;
+    std::unique_ptr<TransformAction> Action;
+    std::unique_ptr<TransformSelector> Selector;
+    std::string OutputName;
+  } command(args[1]);
+
+  // Descriptor of action
+  // Arity: number of arguments required for the action
+  // Transform: lambda function implementing the action
+  struct ActionDescriptor
+  {
+    ActionDescriptor(const std::string& name)
+      : Name(name)
+    {
+    }
+    ActionDescriptor(const std::string& name, int arity,
+                     const transform_type& transform)
+      : Name(name)
+      , Arity(arity)
+      , Transform(transform)
+    {
+    }
+
+    operator const std::string&() const { return Name; }
+
+    std::string Name;
+    int Arity = 0;
+    transform_type Transform;
+  };
+
+  // Build a set of supported actions.
+  std::set<ActionDescriptor,
+           std::function<bool(const std::string&, const std::string&)>>
+  descriptors(
+    [](const std::string& x, const std::string& y) { return x < y; });
+  descriptors = { { "APPEND", 1,
+                    [&command](const std::string& s) -> std::string {
+                      if (command.Selector->InSelection(s)) {
+                        return s + command.Arguments[0];
+                      }
+
+                      return s;
+                    } },
+                  { "PREPEND", 1,
+                    [&command](const std::string& s) -> std::string {
+                      if (command.Selector->InSelection(s)) {
+                        return command.Arguments[0] + s;
+                      }
+
+                      return s;
+                    } },
+                  { "TOUPPER", 0,
+                    [&command](const std::string& s) -> std::string {
+                      if (command.Selector->InSelection(s)) {
+                        return cmSystemTools::UpperCase(s);
+                      }
+
+                      return s;
+                    } },
+                  { "TOLOWER", 0,
+                    [&command](const std::string& s) -> std::string {
+                      if (command.Selector->InSelection(s)) {
+                        return cmSystemTools::LowerCase(s);
+                      }
+
+                      return s;
+                    } },
+                  { "STRIP", 0,
+                    [&command](const std::string& s) -> std::string {
+                      if (command.Selector->InSelection(s)) {
+                        return cmSystemTools::TrimWhitespace(s);
+                      }
+
+                      return s;
+                    } },
+                  { "GENEX_STRIP", 0,
+                    [&command](const std::string& s) -> std::string {
+                      if (command.Selector->InSelection(s)) {
+                        return cmGeneratorExpression::Preprocess(
+                          s,
+                          cmGeneratorExpression::StripAllGeneratorExpressions);
+                      }
+
+                      return s;
+                    } },
+                  { "REPLACE", 2,
+                    [&command](const std::string& s) -> std::string {
+                      if (command.Selector->InSelection(s)) {
+                        return command.Action->Transform(s);
+                      }
+
+                      return s;
+                    } } };
+
+  using size_type = std::vector<std::string>::size_type;
+  size_type index = 2;
+
+  // Parse all possible function parameters
+  auto descriptor = descriptors.find(args[index]);
+
+  if (descriptor == descriptors.end()) {
+    std::ostringstream error;
+    error << " sub-command TRANSFORM, " << args[index] << " invalid action.";
+    this->SetError(error.str());
+    return false;
+  }
+
+  // Action arguments
+  index += 1;
+  if (args.size() < index + descriptor->Arity) {
+    std::ostringstream error;
+    error << "sub-command TRANSFORM, action " << descriptor->Name
+          << " expects " << descriptor->Arity << " argument(s).";
+    this->SetError(error.str());
+    return false;
+  }
+
+  command.Name = descriptor->Name;
+  index += descriptor->Arity;
+  if (descriptor->Arity > 0) {
+    command.Arguments =
+      std::vector<std::string>(args.begin() + 3, args.begin() + index);
+  }
+
+  if (command.Name == "REPLACE") {
+    try {
+      command.Action =
+        cm::make_unique<TransformReplace>(command.Arguments, this->Makefile);
+    } catch (const transform_error& e) {
+      this->SetError(e.what());
+      return false;
+    }
+  }
+
+  const std::string REGEX{ "REGEX" }, AT{ "AT" }, FOR{ "FOR" },
+    OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" };
+
+  // handle optional arguments
+  while (args.size() > index) {
+    if ((args[index] == REGEX || args[index] == AT || args[index] == FOR) &&
+        command.Selector) {
+      std::ostringstream error;
+      error << "sub-command TRANSFORM, selector already specified ("
+            << command.Selector->Tag << ").";
+      this->SetError(error.str());
+      return false;
+    }
+
+    // REGEX selector
+    if (args[index] == REGEX) {
+      if (args.size() == ++index) {
+        this->SetError("sub-command TRANSFORM, selector REGEX expects "
+                       "'regular expression' argument.");
+        return false;
+      }
+
+      command.Selector = cm::make_unique<TransformSelectorRegex>(args[index]);
+      if (!command.Selector->Validate()) {
+        std::ostringstream error;
+        error << "sub-command TRANSFORM, selector REGEX failed to compile "
+                 "regex \"";
+        error << args[index] << "\".";
+        this->SetError(error.str());
+        return false;
+      }
+
+      index += 1;
+      continue;
+    }
+
+    // AT selector
+    if (args[index] == AT) {
+      // get all specified indexes
+      std::vector<int> indexes;
+      while (args.size() > ++index) {
+        std::size_t pos;
+        int value;
+
+        try {
+          value = std::stoi(args[index], &pos);
+          if (pos != args[index].length()) {
+            // this is not a number, stop processing
+            break;
+          }
+          indexes.push_back(value);
+        } catch (const std::invalid_argument&) {
+          // this is not a number, stop processing
+          break;
+        }
+      }
+
+      if (indexes.empty()) {
+        this->SetError(
+          "sub-command TRANSFORM, selector AT expects at least one "
+          "numeric value.");
+        return false;
+      }
+
+      command.Selector =
+        cm::make_unique<TransformSelectorAt>(std::move(indexes));
+
+      continue;
+    }
+
+    // FOR selector
+    if (args[index] == FOR) {
+      if (args.size() <= ++index + 1) {
+        this->SetError("sub-command TRANSFORM, selector FOR expects, at least,"
+                       " two arguments.");
+        return false;
+      }
+
+      int start = 0, stop = 0, step = 1;
+      bool valid = true;
+      try {
+        std::size_t pos;
+
+        start = std::stoi(args[index], &pos);
+        if (pos != args[index].length()) {
+          // this is not a number
+          valid = false;
+        } else {
+          stop = std::stoi(args[++index], &pos);
+          if (pos != args[index].length()) {
+            // this is not a number
+            valid = false;
+          }
+        }
+      } catch (const std::invalid_argument&) {
+        // this is not numbers
+        valid = false;
+      }
+      if (!valid) {
+        this->SetError("sub-command TRANSFORM, selector FOR expects, "
+                       "at least, two numeric values.");
+        return false;
+      }
+      // try to read a third numeric value for step
+      if (args.size() > ++index) {
+        try {
+          std::size_t pos;
+
+          step = std::stoi(args[index], &pos);
+          if (pos != args[index].length()) {
+            // this is not a number
+            step = 1;
+          } else {
+            index += 1;
+          }
+        } catch (const std::invalid_argument&) {
+          // this is not number, ignore exception
+        }
+      }
+
+      if (step < 0) {
+        this->SetError("sub-command TRANSFORM, selector FOR expects "
+                       "non negative numeric value for <step>.");
+      }
+
+      command.Selector =
+        cm::make_unique<TransformSelectorFor>(start, stop, step);
+
+      continue;
+    }
+
+    // output variable
+    if (args[index] == OUTPUT_VARIABLE) {
+      if (args.size() == ++index) {
+        this->SetError("sub-command TRANSFORM, OUTPUT_VARIABLE "
+                       "expects variable name argument.");
+        return false;
+      }
+
+      command.OutputName = args[index++];
+      continue;
+    }
+
+    std::ostringstream error;
+    error << "sub-command TRANSFORM, '"
+          << cmJoin(cmMakeRange(args).advance(index), " ")
+          << "': unexpected argument(s).";
+    this->SetError(error.str());
+    return false;
+  }
+
+  // expand the list variable
+  std::vector<std::string> varArgsExpanded;
+  if (!this->GetList(varArgsExpanded, command.ListName)) {
+    this->Makefile->AddDefinition(command.OutputName, "");
+    return true;
+  }
+
+  if (!command.Selector) {
+    // no selector specified, apply transformation to all elements
+    command.Selector = cm::make_unique<TransformNoSelector>();
+  }
+
+  try {
+    command.Selector->Transform(varArgsExpanded, descriptor->Transform);
+  } catch (const transform_error& e) {
+    this->SetError(e.what());
+    return false;
+  }
+
+  this->Makefile->AddDefinition(command.OutputName,
+                                cmJoin(varArgsExpanded, ";").c_str());
+
+  return true;
+}
+
 bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
 {
   assert(args.size() >= 2);
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index d69d8f9..76a9856 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -41,6 +41,7 @@
   bool HandleRemoveAtCommand(std::vector<std::string> const& args);
   bool HandleRemoveItemCommand(std::vector<std::string> const& args);
   bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args);
+  bool HandleTransformCommand(std::vector<std::string> const& args);
   bool HandleSortCommand(std::vector<std::string> const& args);
   bool HandleSublistCommand(std::vector<std::string> const& args);
   bool HandleReverseCommand(std::vector<std::string> const& args);
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index c714299..b5ae939 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -251,8 +251,7 @@
   cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
   std::string const ninjaRulesFile =
     ng->NinjaOutputPath(cmGlobalNinjaGenerator::NINJA_RULES_FILE);
-  std::string const rulesFilePath =
-    ng->EncodeIdent(ng->EncodePath(ninjaRulesFile), os);
+  std::string const rulesFilePath = ng->EncodePath(ninjaRulesFile);
   cmGlobalNinjaGenerator::WriteInclude(os, rulesFilePath,
                                        "Include rules file.");
   os << "\n";
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index acb5921..fcdcdc5 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1364,7 +1364,18 @@
       for (size_t ci = 0; ci < configs.size(); ++ci) {
         acs.Configs.push_back(ci);
       }
-      sources.Sources.emplace_back(std::move(acs));
+      bool haveCMakeLists = false;
+      for (cmGeneratorTarget::AllConfigSource& si : sources.Sources) {
+        if (si.Source == sf) {
+          haveCMakeLists = true;
+          // Replace the explicit source reference with our generated one.
+          si = acs;
+          break;
+        }
+      }
+      if (!haveCMakeLists) {
+        sources.Sources.emplace_back(std::move(acs));
+      }
     }
   }
 
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 9aeeb5c..490d516 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4089,10 +4089,10 @@
   return this->DefineFlagsOrig.c_str();
 }
 
-cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(
-  cmPolicies::PolicyID id) const
+cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id,
+                                                     bool parent_scope) const
 {
-  return this->StateSnapshot.GetPolicy(id);
+  return this->StateSnapshot.GetPolicy(id, parent_scope);
 }
 
 bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var)
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index d2626cd..8589deb 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -284,7 +284,8 @@
      */
   bool SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
   bool SetPolicy(const char* id, cmPolicies::PolicyStatus status);
-  cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id) const;
+  cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id,
+                                           bool parent_scope = false) const;
   bool SetPolicyVersion(std::string const& version_min,
                         std::string const& version_max);
   void RecordPolicies(cmPolicies::PolicyMap& pm);
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a21c778..9b9ef60 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -219,7 +219,10 @@
          "Do not produce legacy _LIB_DEPENDS cache entries.", 3, 12, 0,       \
          cmPolicies::WARN)                                                    \
   SELECT(POLICY, CMP0074, "find_package uses PackageName_ROOT variables.", 3, \
-         12, 0, cmPolicies::WARN)
+         12, 0, cmPolicies::WARN)                                             \
+  SELECT(POLICY, CMP0075,                                                     \
+         "Include file check macros honor CMAKE_REQUIRED_LIBRARIES.", 3, 12,  \
+         0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 0d97c33..0229a77 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -160,8 +160,8 @@
   }
 }
 
-cmPolicies::PolicyStatus cmStateSnapshot::GetPolicy(
-  cmPolicies::PolicyID id) const
+cmPolicies::PolicyStatus cmStateSnapshot::GetPolicy(cmPolicies::PolicyID id,
+                                                    bool parent_scope) const
 {
   cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id);
 
@@ -180,6 +180,10 @@
     cmLinkedTree<cmStateDetail::PolicyStackEntry>::iterator root =
       dir->DirectoryEnd->PolicyRoot;
     for (; leaf != root; ++leaf) {
+      if (parent_scope) {
+        parent_scope = false;
+        continue;
+      }
       if (leaf->IsDefined(id)) {
         status = leaf->Get(id);
         return status;
diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h
index 94d6274..af5653b 100644
--- a/Source/cmStateSnapshot.h
+++ b/Source/cmStateSnapshot.h
@@ -43,7 +43,8 @@
   cmStateEnums::SnapshotType GetType() const;
 
   void SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
-  cmPolicies::PolicyStatus GetPolicy(cmPolicies::PolicyID id) const;
+  cmPolicies::PolicyStatus GetPolicy(cmPolicies::PolicyID id,
+                                     bool parent_scope = false) const;
   bool HasDefinedPolicyCMP0011();
   void PushPolicy(cmPolicies::PolicyMap const& entry, bool weak);
   bool PopPolicy();
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 9631912..dabec47 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -13,6 +13,7 @@
 #include "cmCryptoHash.h"
 #include "cmGeneratorExpression.h"
 #include "cmMakefile.h"
+#include "cmStringReplaceHelper.h"
 #include "cmSystemTools.h"
 #include "cmTimestamp.h"
 #include "cmUuid.h"
@@ -344,46 +345,17 @@
   std::string const& regex = args[2];
   std::string const& replace = args[3];
   std::string const& outvar = args[4];
+  cmStringReplaceHelper replaceHelper(regex, replace, this->Makefile);
 
-  // Pull apart the replace expression to find the escaped [0-9] values.
-  std::vector<RegexReplacement> replacement;
-  std::string::size_type l = 0;
-  while (l < replace.length()) {
-    std::string::size_type r = replace.find('\\', l);
-    if (r == std::string::npos) {
-      r = replace.length();
-      replacement.push_back(replace.substr(l, r - l));
-    } else {
-      if (r - l > 0) {
-        replacement.push_back(replace.substr(l, r - l));
-      }
-      if (r == (replace.length() - 1)) {
-        this->SetError("sub-command REGEX, mode REPLACE: "
-                       "replace-expression ends in a backslash.");
-        return false;
-      }
-      if ((replace[r + 1] >= '0') && (replace[r + 1] <= '9')) {
-        replacement.push_back(replace[r + 1] - '0');
-      } else if (replace[r + 1] == 'n') {
-        replacement.push_back("\n");
-      } else if (replace[r + 1] == '\\') {
-        replacement.push_back("\\");
-      } else {
-        std::string e = "sub-command REGEX, mode REPLACE: Unknown escape \"";
-        e += replace.substr(r, 2);
-        e += "\" in replace-expression.";
-        this->SetError(e);
-        return false;
-      }
-      r += 2;
-    }
-    l = r;
+  if (!replaceHelper.IsReplaceExpressionValid()) {
+    this->SetError("sub-command REGEX, mode REPLACE: " +
+                   replaceHelper.GetError() + ".");
+    return false;
   }
 
   this->Makefile->ClearMatches();
-  // Compile the regular expression.
-  cmsys::RegularExpression re;
-  if (!re.compile(regex.c_str())) {
+
+  if (!replaceHelper.IsRegularExpressionValid()) {
     std::string e =
       "sub-command REGEX, mode REPLACE failed to compile regex \"" + regex +
       "\".";
@@ -392,60 +364,16 @@
   }
 
   // Concatenate all the last arguments together.
-  std::string input = cmJoin(cmMakeRange(args).advance(5), std::string());
-
-  // Scan through the input for all matches.
+  const std::string input =
+    cmJoin(cmMakeRange(args).advance(5), std::string());
   std::string output;
-  std::string::size_type base = 0;
-  while (re.find(input.c_str() + base)) {
-    this->Makefile->ClearMatches();
-    this->Makefile->StoreMatches(re);
-    std::string::size_type l2 = re.start();
-    std::string::size_type r = re.end();
 
-    // Concatenate the part of the input that was not matched.
-    output += input.substr(base, l2);
-
-    // Make sure the match had some text.
-    if (r - l2 == 0) {
-      std::string e = "sub-command REGEX, mode REPLACE regex \"" + regex +
-        "\" matched an empty string.";
-      this->SetError(e);
-      return false;
-    }
-
-    // Concatenate the replacement for the match.
-    for (RegexReplacement const& i : replacement) {
-      if (i.number < 0) {
-        // This is just a plain-text part of the replacement.
-        output += i.value;
-      } else {
-        // Replace with part of the match.
-        int n = i.number;
-        std::string::size_type start = re.start(n);
-        std::string::size_type end = re.end(n);
-        std::string::size_type len = input.length() - base;
-        if ((start != std::string::npos) && (end != std::string::npos) &&
-            (start <= len) && (end <= len)) {
-          output += input.substr(base + start, end - start);
-        } else {
-          std::string e =
-            "sub-command REGEX, mode REPLACE: replace expression \"" +
-            replace + "\" contains an out-of-range escape for regex \"" +
-            regex + "\".";
-          this->SetError(e);
-          return false;
-        }
-      }
-    }
-
-    // Move past the match.
-    base += r;
+  if (!replaceHelper.Replace(input, output)) {
+    this->SetError("sub-command REGEX, mode REPLACE: " +
+                   replaceHelper.GetError() + ".");
+    return false;
   }
 
-  // Concatenate the text after the last match.
-  output += input.substr(base, input.length() - base);
-
   // Store the output in the provided variable.
   this->Makefile->AddDefinition(outvar, output.c_str());
   return true;
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index 569ed83..cbff73e 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -60,29 +60,6 @@
 
   bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
                 size_t varIdx);
-
-  class RegexReplacement
-  {
-  public:
-    RegexReplacement(const char* s)
-      : number(-1)
-      , value(s)
-    {
-    }
-    RegexReplacement(const std::string& s)
-      : number(-1)
-      , value(s)
-    {
-    }
-    RegexReplacement(int n)
-      : number(n)
-      , value()
-    {
-    }
-    RegexReplacement() {}
-    int number;
-    std::string value;
-  };
 };
 
 #endif
diff --git a/Source/cmStringReplaceHelper.cxx b/Source/cmStringReplaceHelper.cxx
new file mode 100644
index 0000000..69b7ced
--- /dev/null
+++ b/Source/cmStringReplaceHelper.cxx
@@ -0,0 +1,117 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include "cmStringReplaceHelper.h"
+
+#include "cmMakefile.h"
+#include <sstream>
+
+cmStringReplaceHelper::cmStringReplaceHelper(const std::string& regex,
+                                             const std::string& replace_expr,
+                                             cmMakefile* makefile)
+  : RegExString(regex)
+  , RegularExpression(regex)
+  , ReplaceExpression(replace_expr)
+  , Makefile(makefile)
+{
+  this->ParseReplaceExpression();
+}
+
+bool cmStringReplaceHelper::Replace(const std::string& input,
+                                    std::string& output)
+{
+  output.clear();
+
+  // Scan through the input for all matches.
+  std::string::size_type base = 0;
+  while (this->RegularExpression.find(input.c_str() + base)) {
+    if (this->Makefile != nullptr) {
+      this->Makefile->ClearMatches();
+      this->Makefile->StoreMatches(this->RegularExpression);
+    }
+    auto l2 = this->RegularExpression.start();
+    auto r = this->RegularExpression.end();
+
+    // Concatenate the part of the input that was not matched.
+    output += input.substr(base, l2);
+
+    // Make sure the match had some text.
+    if (r - l2 == 0) {
+      std::ostringstream error;
+      error << "regex \"" << this->RegExString << "\" matched an empty string";
+      this->ErrorString = error.str();
+      return false;
+    }
+
+    // Concatenate the replacement for the match.
+    for (const auto& replacement : this->Replacements) {
+      if (replacement.Number < 0) {
+        // This is just a plain-text part of the replacement.
+        output += replacement.Value;
+      } else {
+        // Replace with part of the match.
+        auto n = replacement.Number;
+        auto start = this->RegularExpression.start(n);
+        auto end = this->RegularExpression.end(n);
+        auto len = input.length() - base;
+        if ((start != std::string::npos) && (end != std::string::npos) &&
+            (start <= len) && (end <= len)) {
+          output += input.substr(base + start, end - start);
+        } else {
+          std::ostringstream error;
+          error << "replace expression \"" << this->ReplaceExpression
+                << "\" contains an out-of-range escape for regex \""
+                << this->RegExString << "\"";
+          this->ErrorString = error.str();
+          return false;
+        }
+      }
+    }
+
+    // Move past the match.
+    base += r;
+  }
+
+  // Concatenate the text after the last match.
+  output += input.substr(base, input.length() - base);
+
+  return true;
+}
+
+void cmStringReplaceHelper::ParseReplaceExpression()
+{
+  std::string::size_type l = 0;
+  while (l < this->ReplaceExpression.length()) {
+    auto r = this->ReplaceExpression.find('\\', l);
+    if (r == std::string::npos) {
+      r = this->ReplaceExpression.length();
+      this->Replacements.push_back(this->ReplaceExpression.substr(l, r - l));
+    } else {
+      if (r - l > 0) {
+        this->Replacements.push_back(this->ReplaceExpression.substr(l, r - l));
+      }
+      if (r == (this->ReplaceExpression.length() - 1)) {
+        this->ValidReplaceExpression = false;
+        this->ErrorString = "replace-expression ends in a backslash";
+        return;
+      }
+      if ((this->ReplaceExpression[r + 1] >= '0') &&
+          (this->ReplaceExpression[r + 1] <= '9')) {
+        this->Replacements.push_back(this->ReplaceExpression[r + 1] - '0');
+      } else if (this->ReplaceExpression[r + 1] == 'n') {
+        this->Replacements.push_back("\n");
+      } else if (this->ReplaceExpression[r + 1] == '\\') {
+        this->Replacements.push_back("\\");
+      } else {
+        this->ValidReplaceExpression = false;
+        std::ostringstream error;
+        error << "Unknown escape \"" << this->ReplaceExpression.substr(r, 2)
+              << "\" in replace-expression";
+        this->ErrorString = error.str();
+        return;
+      }
+      r += 2;
+    }
+    l = r;
+  }
+}
diff --git a/Source/cmStringReplaceHelper.h b/Source/cmStringReplaceHelper.h
new file mode 100644
index 0000000..938325a
--- /dev/null
+++ b/Source/cmStringReplaceHelper.h
@@ -0,0 +1,69 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmStringReplaceHelper_h
+#define cmStringReplaceHelper_h
+
+#include "cmsys/RegularExpression.hxx"
+
+#include <string>
+#include <vector>
+
+class cmMakefile;
+
+class cmStringReplaceHelper
+{
+public:
+  cmStringReplaceHelper(const std::string& regex,
+                        const std::string& replace_expr,
+                        cmMakefile* makefile = nullptr);
+
+  bool IsRegularExpressionValid() const
+  {
+    return this->RegularExpression.is_valid();
+  }
+  bool IsReplaceExpressionValid() const
+  {
+    return this->ValidReplaceExpression;
+  }
+
+  bool Replace(const std::string& input, std::string& output);
+
+  const std::string& GetError() { return this->ErrorString; }
+
+private:
+  class RegexReplacement
+  {
+  public:
+    RegexReplacement(const char* s)
+      : Number(-1)
+      , Value(s)
+    {
+    }
+    RegexReplacement(const std::string& s)
+      : Number(-1)
+      , Value(s)
+    {
+    }
+    RegexReplacement(int n)
+      : Number(n)
+      , Value()
+    {
+    }
+    RegexReplacement() {}
+
+    int Number;
+    std::string Value;
+  };
+
+  void ParseReplaceExpression();
+
+  std::string ErrorString;
+  std::string RegExString;
+  cmsys::RegularExpression RegularExpression;
+  bool ValidReplaceExpression = true;
+  std::string ReplaceExpression;
+  std::vector<RegexReplacement> Replacements;
+  cmMakefile* Makefile = nullptr;
+};
+
+#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 0d32b3a..b56104e 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1894,7 +1894,14 @@
   std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
     this->GeneratorTarget->GetAllConfigSources();
 
+  cmSourceFile const* srcCMakeLists =
+    this->LocalGenerator->CreateVCProjBuildRule();
+
   for (cmGeneratorTarget::AllConfigSource const& si : sources) {
+    if (si.Source == srcCMakeLists) {
+      // Skip explicit reference to CMakeLists.txt source.
+      continue;
+    }
     const char* tool = nullptr;
     switch (si.Kind) {
       case cmGeneratorTarget::SourceKindAppManifest:
@@ -2739,6 +2746,20 @@
     cudaOptions.AppendFlagString("AdditionalOptions", "-x cu");
   }
 
+  // Specify the compiler program database file if configured.
+  std::string pdb = this->GeneratorTarget->GetCompilePDBPath(configName);
+  if (!pdb.empty()) {
+    // CUDA does not have a field for this and does not honor the
+    // ProgramDataBaseFileName field in ClCompile.  Work around this
+    // limitation by creating the directory and passing the flag ourselves.
+    std::string const pdbDir = cmSystemTools::GetFilenamePath(pdb);
+    cmSystemTools::MakeDirectory(pdbDir);
+    pdb = this->ConvertPath(pdb, true);
+    ConvertToWindowsSlash(pdb);
+    std::string const clFd = "-Xcompiler=\"-Fd\\\"" + pdb + "\\\"\"";
+    cudaOptions.AppendFlagString("AdditionalOptions", clFd);
+  }
+
   // CUDA automatically passes the proper '--machine' flag to nvcc
   // for the current architecture, but does not reflect this default
   // in the user-visible IDE settings.  Set it explicitly.
@@ -3695,10 +3716,8 @@
                     "{" + this->GlobalGenerator->GetGUID(name) + "}", 3);
     this->WriteElem("Name", name, 3);
     this->WriteDotNetReferenceCustomTags(name);
-    if (csproj == this->ProjectType) {
-      if (!this->GlobalGenerator->TargetCanBeReferenced(dt)) {
-        this->WriteElem("ReferenceOutputAssembly", "false", 3);
-      }
+    if (!this->GlobalGenerator->TargetCanBeReferenced(dt)) {
+      this->WriteElem("ReferenceOutputAssembly", "false", 3);
     }
     this->WriteString("</ProjectReference>\n", 2);
   }
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 2b9d7b1..7426816 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -94,7 +94,6 @@
 #endif
 
 #ifdef __APPLE__
-#include <fenv.h>
 #include <mach/host_info.h>
 #include <mach/mach.h>
 #include <mach/mach_types.h>
@@ -114,7 +113,6 @@
 #endif
 
 #if defined(__linux) || defined(__sun) || defined(_SCO_DS)
-#include <fenv.h>
 #include <netdb.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index aad7cfc..38b4828 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1359,6 +1359,10 @@
     add_subdirectory(FindICU)
   endif()
 
+  if(CMake_TEST_FindJPEG)
+    add_subdirectory(FindJPEG)
+  endif()
+
   if(CMake_TEST_FindJsonCpp)
     add_subdirectory(FindJsonCpp)
   endif()
diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
index 443d366..a53e441 100644
--- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
+++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
@@ -86,7 +86,7 @@
 endforeach()
 
 foreach(VTEST BISON Boost CUDA DOXYGEN FLEX GIF GTK2
-        HDF5 LibArchive OPENSCENEGRAPH RUBY SWIG Protobuf)
+        HDF5 JPEG LibArchive OPENSCENEGRAPH RUBY SWIG Protobuf)
     check_version_string(${VTEST} ${VTEST}_VERSION)
 endforeach()
 
diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
index 65487bb..9157c76 100644
--- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
+++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
@@ -349,6 +349,12 @@
 set(aix_xlf90_64_dirs "/usr/lpp/xlf/lib")
 list(APPEND platforms aix_xlf90_64)
 
+# g++ dummy.c -v
+set(aix_g++_text " /prefix/libexec/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/collect2 -bpT:0x10000000 -bpD:0x20000000 -btextro /lib/crt0.o /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/crtcxa.o /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/crtdbase.o -L/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0 -L/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/../../.. /tmp//ccKROJ1f.o -lstdc++ -lm -lgcc_s /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a -lc -lgcc_s /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a")
+set(aix_g++_libs "stdc++;m;gcc_s;/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a;c;gcc_s;/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a")
+set(aix_g++_dirs "/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0;/prefix/lib")
+list(APPEND platforms aix_g++)
+
 #-----------------------------------------------------------------------------
 # HP
 
diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt
index 565baca..59f3e84 100644
--- a/Tests/CudaOnly/CMakeLists.txt
+++ b/Tests/CudaOnly/CMakeLists.txt
@@ -6,3 +6,7 @@
 ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
 ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation)
 ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs)
+
+if(MSVC)
+  ADD_TEST_MACRO(CudaOnly.PDB CudaOnlyPDB)
+endif()
diff --git a/Tests/CudaOnly/PDB/CMakeLists.txt b/Tests/CudaOnly/PDB/CMakeLists.txt
new file mode 100644
index 0000000..34e1e5c
--- /dev/null
+++ b/Tests/CudaOnly/PDB/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.11)
+project (CudaOnlyPDB CUDA)
+
+add_executable(CudaOnlyPDB main.cu)
+set_target_properties(CudaOnlyPDB PROPERTIES
+  PDB_NAME LinkPDBName
+  PDB_OUTPUT_DIRECTORY LinkPDBDir
+  COMPILE_PDB_NAME CompPDBName
+  COMPILE_PDB_OUTPUT_DIRECTORY CompPDBDir
+  )
+
+set(pdbs
+  ${CMAKE_CURRENT_BINARY_DIR}/CompPDBDir/${CMAKE_CFG_INTDIR}/CompPDBName.pdb
+  ${CMAKE_CURRENT_BINARY_DIR}/LinkPDBDir/${CMAKE_CFG_INTDIR}/LinkPDBName.pdb
+  )
+add_custom_command(TARGET CudaOnlyPDB POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -Dconfig=$<CONFIG> "-Dpdbs=${pdbs}"
+                           -P ${CMAKE_CURRENT_SOURCE_DIR}/check_pdbs.cmake
+  )
diff --git a/Tests/CudaOnly/PDB/check_pdbs.cmake b/Tests/CudaOnly/PDB/check_pdbs.cmake
new file mode 100644
index 0000000..5e01ca7
--- /dev/null
+++ b/Tests/CudaOnly/PDB/check_pdbs.cmake
@@ -0,0 +1,10 @@
+if(NOT "${config}" MATCHES "[Dd][Ee][Bb]")
+  return()
+endif()
+foreach(pdb ${pdbs})
+  if(EXISTS "${pdb}")
+    message(STATUS "PDB Exists: ${pdb}")
+  else()
+    message(SEND_ERROR "PDB MISSING:\n ${pdb}")
+  endif()
+endforeach()
diff --git a/Tests/CudaOnly/PDB/main.cu b/Tests/CudaOnly/PDB/main.cu
new file mode 100644
index 0000000..f8b643a
--- /dev/null
+++ b/Tests/CudaOnly/PDB/main.cu
@@ -0,0 +1,4 @@
+int main()
+{
+  return 0;
+}
diff --git a/Tests/FindJPEG/CMakeLists.txt b/Tests/FindJPEG/CMakeLists.txt
new file mode 100644
index 0000000..c8663c5
--- /dev/null
+++ b/Tests/FindJPEG/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindJPEG.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindJPEG/Test"
+  "${CMake_BINARY_DIR}/Tests/FindJPEG/Test"
+  ${build_generator_args}
+  --build-project TestFindJPEG
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindJPEG/Test/CMakeLists.txt b/Tests/FindJPEG/Test/CMakeLists.txt
new file mode 100644
index 0000000..a744f85
--- /dev/null
+++ b/Tests/FindJPEG/Test/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindJPEG C)
+include(CTest)
+
+find_package(JPEG)
+
+add_executable(test_jpeg_tgt main.c)
+target_link_libraries(test_jpeg_tgt JPEG::JPEG)
+add_test(NAME test_jpeg_tgt COMMAND test_jpeg_tgt)
+
+add_executable(test_jpeg_var main.c)
+target_include_directories(test_jpeg_var PRIVATE ${JPEG_INCLUDE_DIRS})
+target_link_libraries(test_jpeg_var PRIVATE ${JPEG_LIBRARIES})
+add_test(NAME test_jpeg_var COMMAND test_jpeg_var)
diff --git a/Tests/FindJPEG/Test/main.c b/Tests/FindJPEG/Test/main.c
new file mode 100644
index 0000000..c6e48f0
--- /dev/null
+++ b/Tests/FindJPEG/Test/main.c
@@ -0,0 +1,16 @@
+#include <assert.h>
+#include <stdio.h>
+
+#include <jpeglib.h>
+
+int main()
+{
+  /* Without any JPEG file to open, test that the call fails as
+     expected.  This tests that linking worked. */
+  struct jpeg_decompress_struct cinfo;
+  struct jpeg_error_mgr jerr;
+  cinfo.err = jpeg_std_error(&jerr);
+  jpeg_create_decompress(&cinfo);
+
+  return 0;
+}
diff --git a/Tests/Module/ExternalData/Data5/CMakeLists.txt b/Tests/Module/ExternalData/Data5/CMakeLists.txt
index 13c7fab..ea67f05 100644
--- a/Tests/Module/ExternalData/Data5/CMakeLists.txt
+++ b/Tests/Module/ExternalData/Data5/CMakeLists.txt
@@ -2,21 +2,21 @@
 ExternalData_Add_Test(Data5.A
   NAME Data5Check.A
   COMMAND ${CMAKE_COMMAND}
-    -D Data5=DATA{../Data.dat}
+    -D Data5=DATA{Data5.dat}
     -P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
   )
 ExternalData_Add_Target(Data5.A)
 ExternalData_Add_Test(Data5.B
   NAME Data5Check.B
   COMMAND ${CMAKE_COMMAND}
-    -D Data5=DATA{../Data.dat}
+    -D Data5=DATA{Data5.dat}
     -P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
   )
 ExternalData_Add_Target(Data5.B)
 ExternalData_Add_Test(Data5.C
   NAME Data5Check.C
   COMMAND ${CMAKE_COMMAND}
-    -D Data5=DATA{../Data.dat}
+    -D Data5=DATA{Data5.dat}
     -P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
   )
 ExternalData_Add_Target(Data5.C)
diff --git a/Tests/Module/ExternalData/Data5/Data5.dat.md5 b/Tests/Module/ExternalData/Data5/Data5.dat.md5
new file mode 100644
index 0000000..70e39bd
--- /dev/null
+++ b/Tests/Module/ExternalData/Data5/Data5.dat.md5
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/PolicyScope/CMakeLists.txt b/Tests/PolicyScope/CMakeLists.txt
index 413195a..353842b 100644
--- a/Tests/PolicyScope/CMakeLists.txt
+++ b/Tests/PolicyScope/CMakeLists.txt
@@ -52,6 +52,10 @@
     # CMP0002 should be changed when this function is invoked
     cmake_policy(GET CMP0002 cmp)
     check(CMP0002 "OLD" "${cmp}")
+
+    # The undocumented PARENT_SCOPE option sees the caller's setting.
+    cmake_policy(GET CMP0002 cmp PARENT_SCOPE)
+    check(CMP0002 "NEW" "${cmp}")
   endfunction()
 
   # Unset CMP0002
@@ -61,6 +65,10 @@
     cmake_policy(GET CMP0002 cmp)
     check(CMP0002 "" "${cmp}")
 
+    # The undocumented PARENT_SCOPE option sees the caller's setting.
+    cmake_policy(GET CMP0002 cmp PARENT_SCOPE)
+    check(CMP0002 "NEW" "${cmp}")
+
     # Setting the policy should work here and also in the caller.
     cmake_policy(SET CMP0002 OLD)
     cmake_policy(GET CMP0002 cmp)
diff --git a/Tests/RunCMake/Android/RunCMakeTest.cmake b/Tests/RunCMake/Android/RunCMakeTest.cmake
index 86a9896..2027c4f 100644
--- a/Tests/RunCMake/Android/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Android/RunCMakeTest.cmake
@@ -88,12 +88,14 @@
     -DCMAKE_ANDROID_ARM_MODE=0
     )
   run_cmake(ndk-badarm)
-  set(RunCMake_TEST_OPTIONS
-    -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
-    -DCMAKE_ANDROID_ARM_NEON=0
-    )
-  run_cmake(ndk-badneon)
+  if("armeabi" IN_LIST _abis_)
+    set(RunCMake_TEST_OPTIONS
+      -DCMAKE_SYSTEM_NAME=Android
+      -DCMAKE_ANDROID_NDK=${ndk}
+      -DCMAKE_ANDROID_ARM_NEON=0
+      )
+    run_cmake(ndk-badneon)
+  endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
     -DCMAKE_ANDROID_NDK=${ndk}
diff --git a/Tests/RunCMake/Android/ndk-badvernum-stderr.txt b/Tests/RunCMake/Android/ndk-badvernum-stderr.txt
index 25bbaf9..adacaf1 100644
--- a/Tests/RunCMake/Android/ndk-badvernum-stderr.txt
+++ b/Tests/RunCMake/Android/ndk-badvernum-stderr.txt
@@ -1,5 +1,5 @@
 ^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\):
-  Android: No toolchain for ABI 'armeabi' found in the NDK:
+  Android: No toolchain for ABI 'armeabi(-v7a)?' found in the NDK:
 
     .*
 
diff --git a/Tests/RunCMake/CheckModules/CMP0075-stderr.txt b/Tests/RunCMake/CheckModules/CMP0075-stderr.txt
new file mode 100644
index 0000000..960fe94
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CMP0075-stderr.txt
@@ -0,0 +1,50 @@
+^CMake Warning \(dev\) at [^
+]*/Modules/CheckIncludeFile.cmake:[0-9]+ \(message\):
+  Policy CMP0075 is not set: Include file check macros honor
+  CMAKE_REQUIRED_LIBRARIES.  Run "cmake --help-policy CMP0075" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
+
+  CMAKE_REQUIRED_LIBRARIES is set to:
+
+    does_not_exist
+
+  For compatibility with CMake 3.11 and below this check is ignoring it.
+Call Stack \(most recent call first\):
+  CMP0075.cmake:11 \(check_include_file\)
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at [^
+]*/Modules/CheckIncludeFileCXX.cmake:[0-9]+ \(message\):
+  Policy CMP0075 is not set: Include file check macros honor
+  CMAKE_REQUIRED_LIBRARIES.  Run "cmake --help-policy CMP0075" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
+
+  CMAKE_REQUIRED_LIBRARIES is set to:
+
+    does_not_exist
+
+  For compatibility with CMake 3.11 and below this check is ignoring it.
+Call Stack \(most recent call first\):
+  CMP0075.cmake:26 \(check_include_file_cxx\)
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at [^
+]*/Modules/CheckIncludeFiles.cmake:[0-9]+ \(message\):
+  Policy CMP0075 is not set: Include file check macros honor
+  CMAKE_REQUIRED_LIBRARIES.  Run "cmake --help-policy CMP0075" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
+
+  CMAKE_REQUIRED_LIBRARIES is set to:
+
+    does_not_exist
+
+  For compatibility with CMake 3.11 and below this check is ignoring it.
+Call Stack \(most recent call first\):
+  CMP0075.cmake:41 \(check_include_files\)
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/CheckModules/CMP0075.cmake b/Tests/RunCMake/CheckModules/CMP0075.cmake
new file mode 100644
index 0000000..4a3b720
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CMP0075.cmake
@@ -0,0 +1,124 @@
+enable_language(C)
+enable_language(CXX)
+include(CheckIncludeFile)
+include(CheckIncludeFileCXX)
+include(CheckIncludeFiles)
+
+set(CMAKE_REQUIRED_LIBRARIES does_not_exist)
+
+#============================================================================
+
+check_include_file("stddef.h" HAVE_STDDEF_H_1)
+if(NOT HAVE_STDDEF_H_1)
+  message(SEND_ERROR "HAVE_STDDEF_H_1 failed but should have passed.")
+endif()
+if(NOT _CIF_CMP0075_WARNED)
+  message(SEND_ERROR "HAVE_STDDEF_H_1 did not warn but should have")
+endif()
+check_include_file("stddef.h" HAVE_STDDEF_H_2) # second does not warn
+if(NOT HAVE_STDDEF_H_2)
+  message(SEND_ERROR "HAVE_STDDEF_H_2 failed but should have passed.")
+endif()
+unset(_CIF_CMP0075_WARNED)
+
+#----------------------------------------------------------------------------
+
+check_include_file_cxx("stddef.h" HAVE_STDDEF_H_CXX_1)
+if(NOT HAVE_STDDEF_H_CXX_1)
+  message(SEND_ERROR "HAVE_STDDEF_H_CXX_1 failed but should have passed.")
+endif()
+if(NOT _CIF_CMP0075_WARNED)
+  message(SEND_ERROR "HAVE_STDDEF_H_CXX_1 did not warn but should have")
+endif()
+check_include_file_cxx("stddef.h" HAVE_STDDEF_H_CXX_2) # second does not warn
+if(NOT HAVE_STDDEF_H_CXX_2)
+  message(SEND_ERROR "HAVE_STDDEF_H_CXX_2 failed but should have passed.")
+endif()
+unset(_CIF_CMP0075_WARNED)
+
+#----------------------------------------------------------------------------
+
+check_include_files("stddef.h;stdlib.h" HAVE_STDLIB_H_1)
+if(NOT HAVE_STDLIB_H_1)
+  message(SEND_ERROR "HAVE_STDLIB_H_1 failed but should have passed.")
+endif()
+if(NOT _CIF_CMP0075_WARNED)
+  message(SEND_ERROR "HAVE_STDLIB_H_1 did not warn but should have")
+endif()
+check_include_files("stddef.h;stdlib.h" HAVE_STDLIB_H_2) # second does not warn
+if(NOT HAVE_STDLIB_H_2)
+  message(SEND_ERROR "HAVE_STDLIB_H_2 failed but should have passed.")
+endif()
+unset(_CIF_CMP0075_WARNED)
+
+#============================================================================
+cmake_policy(SET CMP0075 OLD)
+# These should not warn.
+# These should pass the checks due to ignoring 'does_not_exist'.
+
+check_include_file("stddef.h" HAVE_STDDEF_H_3)
+if(NOT HAVE_STDDEF_H_3)
+  message(SEND_ERROR "HAVE_STDDEF_H_3 failed but should have passed.")
+endif()
+if(_CIF_CMP0075_WARNED)
+  message(SEND_ERROR "HAVE_STDDEF_H_3 warned but should not have")
+endif()
+unset(_CIF_CMP0075_WARNED)
+
+#----------------------------------------------------------------------------
+
+check_include_file_cxx("stddef.h" HAVE_STDDEF_H_CXX_3)
+if(NOT HAVE_STDDEF_H_CXX_3)
+  message(SEND_ERROR "HAVE_STDDEF_H_CXX_3 failed but should have passed.")
+endif()
+if(_CIF_CMP0075_WARNED)
+  message(SEND_ERROR "HAVE_STDDEF_H_CXX_3 warned but should not have")
+endif()
+unset(_CIF_CMP0075_WARNED)
+
+#----------------------------------------------------------------------------
+
+check_include_files("stddef.h;stdlib.h" HAVE_STDLIB_H_3)
+if(NOT HAVE_STDLIB_H_3)
+  message(SEND_ERROR "HAVE_STDLIB_H_3 failed but should have passed.")
+endif()
+if(_CIF_CMP0075_WARNED)
+  message(SEND_ERROR "HAVE_STDLIB_H_3 warned but should not have")
+endif()
+unset(_CIF_CMP0075_WARNED)
+
+#============================================================================
+cmake_policy(SET CMP0075 NEW)
+# These should not warn.
+# These should fail the checks due to requiring 'does_not_exist'.
+
+check_include_file("stddef.h" HAVE_STDDEF_H_4)
+if(HAVE_STDDEF_H_4)
+  message(SEND_ERROR "HAVE_STDDEF_H_4 passed but should have failed.")
+endif()
+if(_CIF_CMP0075_WARNED)
+  message(SEND_ERROR "HAVE_STDDEF_H_4 warned but should not have")
+endif()
+unset(_CIF_CMP0075_WARNED)
+
+#----------------------------------------------------------------------------
+
+check_include_file_cxx("stddef.h" HAVE_STDDEF_H_CXX_4)
+if(HAVE_STDDEF_H_CXX_4)
+  message(SEND_ERROR "HAVE_STDDEF_H_CXX_4 passed but should have failed.")
+endif()
+if(_CIF_CMP0075_WARNED)
+  message(SEND_ERROR "HAVE_STDDEF_H_CXX_4 warned but should not have")
+endif()
+unset(_CIF_CMP0075_WARNED)
+
+#----------------------------------------------------------------------------
+
+check_include_files("stddef.h;stdlib.h" HAVE_STDLIB_H_4)
+if(HAVE_STDLIB_H_4)
+  message(SEND_ERROR "HAVE_STDLIB_H_4 passed but should have failed.")
+endif()
+if(_CIF_CMP0075_WARNED)
+  message(SEND_ERROR "HAVE_STDLIB_H_4 warned but should not have")
+endif()
+unset(_CIF_CMP0075_WARNED)
diff --git a/Tests/RunCMake/CheckModules/RunCMakeTest.cmake b/Tests/RunCMake/CheckModules/RunCMakeTest.cmake
index c5aaa64..8a046e1 100644
--- a/Tests/RunCMake/CheckModules/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CheckModules/RunCMakeTest.cmake
@@ -1,5 +1,7 @@
 include(RunCMake)
 
+run_cmake(CMP0075)
+
 run_cmake(CheckStructHasMemberOk)
 run_cmake(CheckStructHasMemberUnknownLanguage)
 run_cmake(CheckStructHasMemberMissingLanguage)
diff --git a/Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake b/Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake
new file mode 100644
index 0000000..b671e35
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake
@@ -0,0 +1,25 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+  return()
+endif()
+
+set(foundCMakeLists 0)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+  if(line MATCHES "<([A-Za-z0-9_]+) +Include=.*CMakeLists.txt")
+    set(rule "${CMAKE_MATCH_1}")
+    if(NOT rule STREQUAL "CustomBuild")
+      set(RunCMake_TEST_FAILED "CMakeLists.txt referenced as ${rule} instead of CustomBuild")
+      return()
+    endif()
+    if(foundCMakeLists)
+      set(RunCMake_TEST_FAILED "CMakeLists.txt referenced multiple times")
+      return()
+    endif()
+    set(foundCMakeLists 1)
+  endif()
+endforeach()
+if(NOT foundCMakeLists)
+  set(RunCMake_TEST_FAILED "CMakeLists.txt not referenced")
+endif()
diff --git a/Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake b/Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake
new file mode 100644
index 0000000..c9e4456
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_CONFIGURATION_TYPES Debug)
+enable_language(CXX)
+add_executable(foo foo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 359cdfb..0d178ce 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -1,4 +1,7 @@
 include(RunCMake)
+
+run_cmake(ExplicitCMakeLists)
+
 run_cmake(VsConfigurationType)
 run_cmake(VsTargetsFileReferences)
 run_cmake(VsCustomProps)
diff --git a/Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake
new file mode 100644
index 0000000..3073e0b
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake
@@ -0,0 +1,20 @@
+set(xcProjectFile "${RunCMake_TEST_BINARY_DIR}/ExplicitCMakeLists.xcodeproj/project.pbxproj")
+if(NOT EXISTS "${xcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${xcProjectFile} does not exist.")
+  return()
+endif()
+
+set(foundCMakeLists 0)
+file(STRINGS "${xcProjectFile}" lines)
+foreach(line IN LISTS lines)
+  if(line MATCHES "PBXBuildFile.*fileRef.*CMakeLists.txt")
+    if(foundCMakeLists)
+      set(RunCMake_TEST_FAILED "CMakeLists.txt referenced multiple times")
+      return()
+    endif()
+    set(foundCMakeLists 1)
+  endif()
+endforeach()
+if(NOT foundCMakeLists)
+  set(RunCMake_TEST_FAILED "CMakeLists.txt not referenced")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake
new file mode 100644
index 0000000..678b0ea
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake
@@ -0,0 +1,2 @@
+enable_language(CXX)
+add_executable(foo foo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index 5eff6b9..1150666 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -4,6 +4,8 @@
   set(IOS_DEPLOYMENT_TARGET "-DCMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET=10")
 endif()
 
+run_cmake(ExplicitCMakeLists)
+
 run_cmake(XcodeFileType)
 run_cmake(XcodeAttributeLocation)
 run_cmake(XcodeAttributeGenex)
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
index 3913783..bdc23a4 100644
--- a/Tests/RunCMake/list/RunCMakeTest.cmake
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -43,3 +43,44 @@
 run_cmake(SUBLIST-NoVariable)
 run_cmake(SUBLIST-InvalidLength)
 run_cmake(SUBLIST)
+
+run_cmake(TRANSFORM-NoAction)
+run_cmake(TRANSFORM-InvalidAction)
+# 'action' oriented tests
+run_cmake(TRANSFORM-TOUPPER-TooManyArguments)
+run_cmake(TRANSFORM-TOLOWER-TooManyArguments)
+run_cmake(TRANSFORM-STRIP-TooManyArguments)
+run_cmake(TRANSFORM-GENEX_STRIP-TooManyArguments)
+run_cmake(TRANSFORM-APPEND-NoArguments)
+run_cmake(TRANSFORM-APPEND-TooManyArguments)
+run_cmake(TRANSFORM-PREPEND-NoArguments)
+run_cmake(TRANSFORM-PREPEND-TooManyArguments)
+run_cmake(TRANSFORM-REPLACE-NoArguments)
+run_cmake(TRANSFORM-REPLACE-NoEnoughArguments)
+run_cmake(TRANSFORM-REPLACE-TooManyArguments)
+run_cmake(TRANSFORM-REPLACE-InvalidRegex)
+run_cmake(TRANSFORM-REPLACE-InvalidReplace1)
+run_cmake(TRANSFORM-REPLACE-InvalidReplace2)
+# 'selector' oriented tests
+run_cmake(TRANSFORM-Selector-REGEX-NoArguments)
+run_cmake(TRANSFORM-Selector-REGEX-TooManyArguments)
+run_cmake(TRANSFORM-Selector-REGEX-InvalidRegex)
+run_cmake(TRANSFORM-Selector-AT-NoArguments)
+run_cmake(TRANSFORM-Selector-AT-BadArgument)
+run_cmake(TRANSFORM-Selector-AT-InvalidIndex)
+run_cmake(TRANSFORM-Selector-FOR-NoArguments)
+run_cmake(TRANSFORM-Selector-FOR-NoEnoughArguments)
+run_cmake(TRANSFORM-Selector-FOR-TooManyArguments)
+run_cmake(TRANSFORM-Selector-FOR-BadArgument)
+run_cmake(TRANSFORM-Selector-FOR-InvalidIndex)
+# 'output' oriented tests
+run_cmake(TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments)
+run_cmake(TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments)
+# Successful tests
+run_cmake(TRANSFORM-TOUPPER)
+run_cmake(TRANSFORM-TOLOWER)
+run_cmake(TRANSFORM-STRIP)
+run_cmake(TRANSFORM-GENEX_STRIP)
+run_cmake(TRANSFORM-APPEND)
+run_cmake(TRANSFORM-PREPEND)
+run_cmake(TRANSFORM-REPLACE)
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt
new file mode 100644
index 0000000..028f8d5
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-APPEND-NoArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, action APPEND expects 1 argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake
new file mode 100644
index 0000000..f161187
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist APPEND)
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..aeb646d
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-APPEND-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake
new file mode 100644
index 0000000..8430a4c
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist APPEND delta one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND.cmake b/Tests/RunCMake/list/TRANSFORM-APPEND.cmake
new file mode 100644
index 0000000..9639088
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist APPEND "_A" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_A;bravo_A;charlie_A;delta_A")
+  message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha_A;bravo_A;charlie_A;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie;delta_A")
+  message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie_A;delta")
+  message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie_A;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie_A;delta")
+  message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie_A;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie_A;delta_A")
+  message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie_A;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_A;bravo;charlie_A;delta")
+  message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha_A;bravo;charlie_A;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie;delta_A")
+  message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;bravo_A;charlie;delta_A")
+  message (FATAL_ERROR "TRANSFORM(APPEND) is \"${mylist}\", expected is \"alpha;bravo_A;charlie;delta_A\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..6071a00
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-GENEX_STRIP-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake
new file mode 100644
index 0000000..257d7fe
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist GENEX_STRIP one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake
new file mode 100644
index 0000000..8045eef
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake
@@ -0,0 +1,49 @@
+set(mylist one "$<1:two\;three>" four "$<TARGET_OBJECTS:some_target>")
+
+list(TRANSFORM mylist GENEX_STRIP OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one;;four;")
+  message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one;;four;\"")
+endif()
+
+set(mylist "one $<CONFIG>" "$<1:two\;three>-$<PLATFORM_ID>" "$<ANGLE-R>four" "$<TARGET_OBJECTS:some_target>")
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;$<ANGLE-R>four;")
+  message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;$<ANGLE-R>four;\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>")
+  message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>")
+  message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;four;")
+  message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;four;\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one ;$<1:two;three>-$<PLATFORM_ID>;four;$<TARGET_OBJECTS:some_target>")
+  message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one ;$<1:two;three>-$<PLATFORM_ID>;four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP REGEX "(D|G)>" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>")
+  message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP REGEX "(D|G)>")
+if (NOT mylist STREQUAL "one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>")
+  message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${mylist}\", expected is \"one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt b/Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt b/Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt
new file mode 100644
index 0000000..0fa45c9
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-InvalidAction.cmake:2 \(list\):
+  list sub-command TRANSFORM, BAD_ACTION invalid action.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake b/Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake
new file mode 100644
index 0000000..fb2cc30
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist BAD_ACTION)
diff --git a/Tests/RunCMake/list/TRANSFORM-NoAction-result.txt b/Tests/RunCMake/list/TRANSFORM-NoAction-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-NoAction-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt b/Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt
new file mode 100644
index 0000000..68e9e9d
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-NoAction.cmake:2 \(list\):
+  list sub-command TRANSFORM requires an action to be specified.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-NoAction.cmake b/Tests/RunCMake/list/TRANSFORM-NoAction.cmake
new file mode 100644
index 0000000..3690f14
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-NoAction.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist)
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt
new file mode 100644
index 0000000..b4f4e06
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, OUTPUT_VARIABLE expects variable name argument.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake
new file mode 100644
index 0000000..acc4094
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER OUTPUT_VARIABLE)
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..9a58346
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake
new file mode 100644
index 0000000..c4da864
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER OUTPUT_VARIABLE output one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt
new file mode 100644
index 0000000..413ce30
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-PREPEND-NoArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, action PREPEND expects 1 argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake
new file mode 100644
index 0000000..a8e4530
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist PREPEND)
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..6ff1b89
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-PREPEND-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake
new file mode 100644
index 0000000..1f904ad
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist PREPEND delta one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND.cmake b/Tests/RunCMake/list/TRANSFORM-PREPEND.cmake
new file mode 100644
index 0000000..55b8867
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist PREPEND "P_" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "P_alpha;P_bravo;P_charlie;P_delta")
+  message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"P_alpha;P_bravo;P_charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;charlie;P_delta")
+  message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;P_charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;P_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;P_charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;P_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;P_charlie;P_delta")
+  message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;P_charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "P_alpha;bravo;P_charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"P_alpha;bravo;P_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;charlie;P_delta")
+  message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;P_bravo;charlie;P_delta")
+  message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${mylist}\", expected is \"alpha;P_bravo;charlie;P_delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt
new file mode 100644
index 0000000..334c96e
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-REPLACE-InvalidRegex.cmake:2 \(list\):
+  list sub-command TRANSFORM, action REPLACE: Failed to compile regex
+  "\^\(alpha\$".
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake
new file mode 100644
index 0000000..f440c35
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^(alpha$" "zulu")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt
new file mode 100644
index 0000000..7671c83
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-REPLACE-InvalidReplace1.cmake:2 \(list\):
+  list sub-command TRANSFORM, action REPLACE: replace-expression ends in a
+  backslash.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake
new file mode 100644
index 0000000..35387f0
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$" "zulu\\")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt
new file mode 100644
index 0000000..e0aabd7
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-REPLACE-InvalidReplace2.cmake:2 \(list\):
+  list sub-command TRANSFORM, action REPLACE: Unknown escape "\\z" in
+  replace-expression.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake
new file mode 100644
index 0000000..2f1f2c7
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$" "\\zulu")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt
new file mode 100644
index 0000000..3d39e72
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-REPLACE-NoArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, action REPLACE expects 2 argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake
new file mode 100644
index 0000000..b7b1e9d
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE)
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt
new file mode 100644
index 0000000..dc80f33
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-REPLACE-NoEnoughArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, action REPLACE expects 2 argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake
new file mode 100644
index 0000000..1d418c0
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..3d4e15a
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-REPLACE-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake
new file mode 100644
index 0000000..baed0af
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$" "zulu" "one_too_many")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE.cmake
new file mode 100644
index 0000000..256b1b8
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_alpha;bravo;charlie;delta_delta")
+  message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha_alpha;bravo;charlie;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta_delta")
+  message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+e)$" "\\1_\\1" AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie_charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+e)$" "\\1_\\1" FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie_charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta_delta")
+  message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie_A;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_alpha;bravo;charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha_alpha;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta_delta")
+  message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;bravo;charlie;delta_delta")
+  message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${mylist}\", expected is \"alpha;bravo;charlie;delta_delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..534f940
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-STRIP-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake
new file mode 100644
index 0000000..c6a8213
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist STRIP one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP.cmake b/Tests/RunCMake/list/TRANSFORM-STRIP.cmake
new file mode 100644
index 0000000..366c63a
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP.cmake
@@ -0,0 +1,49 @@
+set(mylist " alpha" "bravo " " charlie " delta)
+
+list(TRANSFORM mylist STRIP OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \"alpha;bravo;charlie;delta\"")
+endif()
+
+set(mylist " alpha" "bravo " " charlie " "delta ")
+unset(output)
+list(TRANSFORM mylist STRIP AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo; charlie ;delta")
+  message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo; charlie ;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo;charlie;delta ")
+  message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo;charlie;delta \"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo;charlie;delta ")
+  message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo;charlie;delta \"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo;charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo ;charlie;delta ")
+  message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \"alpha;bravo ;charlie;delta \"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo; charlie ;delta")
+  message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo; charlie ;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP REGEX "(r|t)a")
+if (NOT mylist STREQUAL " alpha;bravo; charlie ;delta")
+  message (FATAL_ERROR "TRANSFORM(STRIP) is \"${mylist}\", expected is \" alpha;bravo; charlie ;delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt
new file mode 100644
index 0000000..cec520f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-AT-BadArgument.cmake:2 \(list\):
+  list sub-command TRANSFORM, '1x 2': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake
new file mode 100644
index 0000000..f61b86b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER AT 0 1x 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt
new file mode 100644
index 0000000..7e2898b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-AT-InvalidIndex.cmake:2 \(list\):
+  list sub-command TRANSFORM, selector AT, index: 3 out of range \(-3, 2\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake
new file mode 100644
index 0000000..d33586c
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER AT 0 3 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt
new file mode 100644
index 0000000..eaf5281
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-AT-NoArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, selector AT expects at least one numeric value.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake
new file mode 100644
index 0000000..052b79b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER AT)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt
new file mode 100644
index 0000000..a0f701f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-Selector-FOR-BadArgument.cmake:2 \(list\):
+  list sub-command TRANSFORM, selector FOR expects, at least, two numeric
+  values.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake
new file mode 100644
index 0000000..55527be
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 0 1x 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt
new file mode 100644
index 0000000..c50cc0a
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-InvalidIndex.cmake:2 \(list\):
+  list sub-command TRANSFORM, selector FOR, index: 6 out of range \(-3, 2\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake
new file mode 100644
index 0000000..6e2374e
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 0 6 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt
new file mode 100644
index 0000000..5881b67
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-NoArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, selector FOR expects, at least, two arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake
new file mode 100644
index 0000000..4902cc9
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt
new file mode 100644
index 0000000..b1081d9
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-NoEnoughArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, selector FOR expects, at least, two arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake
new file mode 100644
index 0000000..81417de
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 1)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..2221cb3
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, '3': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake
new file mode 100644
index 0000000..80917d6
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 0 1 2 3)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt
new file mode 100644
index 0000000..31ba939
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-Selector-REGEX-InvalidRegex.cmake:2 \(list\):
+  list sub-command TRANSFORM, selector REGEX failed to compile regex
+  "\^\(alpha\$".
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake
new file mode 100644
index 0000000..56e202b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER REGEX "^(alpha$")
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt
new file mode 100644
index 0000000..2784785
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-Selector-REGEX-NoArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, selector REGEX expects 'regular expression'
+  argument.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake
new file mode 100644
index 0000000..f199d0e
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER REGEX)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..db5b1ff
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-REGEX-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake
new file mode 100644
index 0000000..4aa1619
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER REGEX "^alpha$" "one_too_many")
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..90248ae
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-TOLOWER-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake
new file mode 100644
index 0000000..1758e19
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOLOWER one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake b/Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake
new file mode 100644
index 0000000..a2d7348
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake
@@ -0,0 +1,48 @@
+set(mylist ALPHA BRAVO CHARLIE DELTA)
+
+list(TRANSFORM mylist TOLOWER OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"alpha;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;CHARLIE;delta")
+  message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;charlie;DELTA")
+  message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;charlie;DELTA")
+  message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;charlie;delta")
+  message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;charlie;DELTA")
+  message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER REGEX "(R|T)A" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;CHARLIE;delta")
+  message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER REGEX "(R|T)A")
+if (NOT mylist STREQUAL "ALPHA;bravo;CHARLIE;delta")
+  message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${mylist}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..9da241b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-TOUPPER-TooManyArguments.cmake:2 \(list\):
+  list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake
new file mode 100644
index 0000000..58d6a8c
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake b/Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake
new file mode 100644
index 0000000..5b1fcb6
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist TOUPPER OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;BRAVO;CHARLIE;DELTA")
+  message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"ALPHA;BRAVO;CHARLIE;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;charlie;DELTA")
+  message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;CHARLIE;delta")
+  message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;CHARLIE;delta")
+  message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;CHARLIE;DELTA")
+  message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;CHARLIE;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;CHARLIE;delta")
+  message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;charlie;DELTA")
+  message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;BRAVO;charlie;DELTA")
+  message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${mylist}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py
index cfda2d4..90ddd36 100644
--- a/Utilities/Sphinx/cmake.py
+++ b/Utilities/Sphinx/cmake.py
@@ -144,6 +144,7 @@
 
 _cmake_index_objs = {
     'command':    _cmake_index_entry('command'),
+    'envvar':     _cmake_index_entry('envvar'),
     'generator':  _cmake_index_entry('generator'),
     'manual':     _cmake_index_entry('manual'),
     'module':     _cmake_index_entry('module'),
@@ -324,6 +325,7 @@
     label = 'CMake'
     object_types = {
         'command':    ObjType('command',    'command'),
+        'envvar':     ObjType('envvar',     'envvar'),
         'generator':  ObjType('generator',  'generator'),
         'variable':   ObjType('variable',   'variable'),
         'module':     ObjType('module',     'module'),
@@ -339,6 +341,7 @@
     }
     directives = {
         'command':    CMakeObject,
+        'envvar':     CMakeObject,
         'variable':   CMakeObject,
         # Other object types cannot be created except by the CMakeTransform
         # 'generator':  CMakeObject,
@@ -355,6 +358,7 @@
     }
     roles = {
         'command':    CMakeXRefRole(fix_parens = True, lowercase = True),
+        'envvar':     CMakeXRefRole(),
         'generator':  CMakeXRefRole(),
         'variable':   CMakeXRefRole(),
         'module':     CMakeXRefRole(),
diff --git a/Utilities/Sphinx/create_identifiers.py b/Utilities/Sphinx/create_identifiers.py
index 3fe3fcb..e638950 100755
--- a/Utilities/Sphinx/create_identifiers.py
+++ b/Utilities/Sphinx/create_identifiers.py
@@ -21,7 +21,9 @@
 for line in lines:
 
   mapping = (("command", "command"),
+             ("envvar", "envvar"),
              ("variable", "variable"),
+             ("generator", "generator"),
              ("target property", "prop_tgt"),
              ("test property", "prop_test"),
              ("source file property", "prop_sf"),
diff --git a/bootstrap b/bootstrap
index 3bcab60..6604f54 100755
--- a/bootstrap
+++ b/bootstrap
@@ -400,6 +400,7 @@
   cmState \
   cmStateDirectory \
   cmStateSnapshot \
+  cmStringReplaceHelper \
   cmStringCommand \
   cmSubdirCommand \
   cmSystemTools \
@@ -570,6 +571,8 @@
   --no-system-libarchive  use cmake-provided libarchive library (default)
   --system-librhash       use system-installed librhash library
   --no-system-librhash    use cmake-provided librhash library (default)
+  --system-libuv          use system-installed libuv library
+  --no-system-libuv       use cmake-provided libuv library (default)
 
   --qt-gui                build the Qt-based GUI (requires Qt >= 4.2)
   --no-qt-gui             do not build the Qt-based GUI (default)
@@ -804,10 +807,10 @@
   --init=*) cmake_init_file=`cmake_arg "$1"` ;;
   --system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=1" ;;
   --no-system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=0" ;;
-  --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma)
+  --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma|--system-libuv)
     lib=`cmake_arg "$1" "--system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=1" ;;
-  --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma)
+  --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma|--no-system-libuv)
     lib=`cmake_arg "$1" "--no-system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
   --qt-gui) cmake_bootstrap_qt_gui="1" ;;