diff --git a/CMake/patches/3.17/FindPython/Support.cmake b/CMake/patches/3.18/FindPython/Support.cmake
similarity index 88%
rename from CMake/patches/3.17/FindPython/Support.cmake
rename to CMake/patches/3.18/FindPython/Support.cmake
index 9db33a2c00bec8bd2e93d5e39179ce7504b1bc94..0879537ed8b11634fc57714b393c28c9383f55ea 100644
--- a/CMake/patches/3.17/FindPython/Support.cmake
+++ b/CMake/patches/3.18/FindPython/Support.cmake
@@ -45,9 +45,9 @@ endif()
 if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
   message (FATAL_ERROR "FindPython: INTERNAL ERROR")
 endif()
-if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3)
+if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3")
   set(_${_PYTHON_PREFIX}_VERSIONS 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
-elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2)
+elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "2")
   set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
 else()
   message (FATAL_ERROR "FindPython: INTERNAL ERROR")
@@ -127,7 +127,9 @@ macro (_PYTHON_FIND_FRAMEWORKS)
                     ~/Library/Frameworks
                     /usr/local/Frameworks
                     ${CMAKE_SYSTEM_FRAMEWORK_PATH})
-    list (REMOVE_DUPLICATES _pff_frameworks)
+    if (_pff_frameworks) # XXX(cmake-3.14)
+      list (REMOVE_DUPLICATES _pff_frameworks)
+    endif ()
     foreach (_pff_framework IN LISTS _pff_frameworks)
       if (EXISTS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
         list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
@@ -337,7 +339,9 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
         # do some clean-up
         string (REGEX MATCHALL "(-I|-iwithsysroot)[ ]*[^ ]+" _values "${_values}")
         string (REGEX REPLACE "(-I|-iwithsysroot)[ ]*" "" _values "${_values}")
-        list (REMOVE_DUPLICATES _values)
+        if (_values) # XXX(cmake-3.14)
+          list (REMOVE_DUPLICATES _values)
+        endif ()
       elseif (NAME STREQUAL "SOABI")
         # clean-up: remove prefix character and suffix
         string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
@@ -347,7 +351,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
 
   if (_${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING)
     if (NAME STREQUAL "PREFIX")
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))"
+      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))\nexcept Exception:\n   import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_config_var('base') or '', sysconfig.get_config_var('installed_base') or '']))"
                        RESULT_VARIABLE _result
                        OUTPUT_VARIABLE _values
                        ERROR_QUIET
@@ -355,19 +359,30 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
       if (_result)
         unset (_values)
       else()
-        list (REMOVE_DUPLICATES _values)
+        if (_values) # XXX(cmake-3.14)
+          list (REMOVE_DUPLICATES _values)
+        endif ()
       endif()
     elseif (NAME STREQUAL "INCLUDES")
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))"
+      if (WIN32)
+        set (_scheme "nt")
+      else()
+        set (_scheme "posix_prefix")
+      endif()
+      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))\nexcept Exception:\n   import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_path('platinclude'),sysconfig.get_path('platinclude','${_scheme}'),sysconfig.get_path('include'),sysconfig.get_path('include','${_scheme}')]))"
                        RESULT_VARIABLE _result
                        OUTPUT_VARIABLE _values
                        ERROR_QUIET
                        OUTPUT_STRIP_TRAILING_WHITESPACE)
       if (_result)
         unset (_values)
+      else()
+        if (_values) # XXX(cmake-3.14)
+          list (REMOVE_DUPLICATES _values)
+        endif ()
       endif()
     elseif (NAME STREQUAL "SOABI")
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))"
+      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))\nexcept Exception:\n   import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))"
                        RESULT_VARIABLE _result
                        OUTPUT_VARIABLE _soabi
                        ERROR_QUIET
@@ -375,14 +390,15 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
       if (_result)
         unset (_values)
       else()
-        list (GET _soabi 0 _values)
-        if (NOT _values)
-          # try to compute SOABI from EXT_SUFFIX
-          list (GET _soabi 1 _values)
-          if (_values)
-            # clean-up: remove prefix character and suffix
-            string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
+        foreach (_item IN LISTS _soabi)
+          if (_item)
+            set (_values "${_item}")
+            break()
           endif()
+        endforeach()
+        if (_values)
+          # clean-up: remove prefix character and suffix
+          string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
         endif()
       endif()
     else()
@@ -390,7 +406,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
       if (NAME STREQUAL "CONFIGDIR")
         set (config_flag "LIBPL")
       endif()
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_config_var('${config_flag}'))"
+      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(sysconfig.get_config_var('${config_flag}'))\nexcept Exception:\n   import sysconfig\n   sys.stdout.write(sysconfig.get_config_var('${config_flag}'))"
                        RESULT_VARIABLE _result
                        OUTPUT_VARIABLE _values
                        ERROR_QUIET
@@ -414,8 +430,14 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
     # do some clean-up
     string (REGEX MATCHALL "-(l|framework)[ ]*[^ ]+" _values "${_values}")
     # remove elements relative to python library itself
-    list (FILTER _values EXCLUDE REGEX "-lpython")
-    list (REMOVE_DUPLICATES _values)
+    if (_values) # XXX(cmake-3.14)
+      list (FILTER _values EXCLUDE REGEX "-lpython")
+      list (REMOVE_DUPLICATES _values)
+    endif ()
+  endif()
+
+  if (WIN32 AND NAME MATCHES "^(PREFIX|CONFIGDIR|INCLUDES)$")
+    file (TO_CMAKE_PATH "${_values}" _values)
   endif()
 
   set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE)
@@ -464,7 +486,7 @@ function (_PYTHON_GET_VERSION)
       set (${_PGV_PREFIX}VERSION_PATCH ${version_patch} PARENT_SCOPE)
 
       # compute ABI flags
-      if (version_major VERSION_GREATER 2)
+      if (version_major VERSION_GREATER "2")
         file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/pyconfig.h" config REGEX "(Py_DEBUG|WITH_PYMALLOC|Py_UNICODE_SIZE|MS_WIN32)")
         set (abi)
         if (config MATCHES "#[ ]*define[ ]+MS_WIN32")
@@ -586,7 +608,8 @@ function (_PYTHON_VALIDATE_INTERPRETER)
     endif()
   endif()
 
-  if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+  if (CMAKE_SIZEOF_VOID_P AND ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+        OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
       AND NOT CMAKE_CROSSCOMPILING)
     # In this case, interpreter must have same architecture as environment
     execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
@@ -665,6 +688,7 @@ endfunction()
 
 function (_PYTHON_VALIDATE_LIBRARY)
   if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+    unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
     return()
   endif()
 
@@ -796,6 +820,25 @@ function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT)
 endfunction()
 
 
+function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module)
+  if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+    string(TOUPPER "${module}" id)
+    set (module_found TRUE)
+
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+        AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+      set (module_found FALSE)
+    endif()
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+        AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+      set (module_found FALSE)
+    endif()
+
+    set (${_PYTHON_PREFIX}_Development.${module}_FOUND ${module_found} PARENT_SCOPE)
+  endif()
+endfunction()
+
+
 # If major version is specified, it must be the same as internal major version
 if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR
     AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
@@ -809,19 +852,46 @@ if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS)
   set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE)
 endif()
 if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
-  list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development")
-  list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+  list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development.Module")
 endif()
-foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy)
+if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+  list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development.Module" "Development.Embed")
+endif()
+if (${_PYTHON_PREFIX}_FIND_COMPONENTS) # XXX(cmake-3.14)
+  list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+endif ()
+foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development Development.Module Development.Embed NumPy)
   set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE)
 endforeach()
+if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
+  set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module TRUE)
+  set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed TRUE)
+endif()
+
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+  if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
+    list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "LIBRARY")
+  endif()
+  list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "INCLUDE_DIR")
+endif()
+if ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+  list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS "LIBRARY" "INCLUDE_DIR")
+endif()
+set (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS})
+if (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) # XXX(cmake-3.14)
+  list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+endif ()
+
 unset (_${_PYTHON_PREFIX}_FIND_VERSIONS)
 
 # Set versions to search
 ## default: search any version
 set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS})
 
-if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1)
+if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER "1")
   if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
     set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR})
   else()
@@ -837,7 +907,7 @@ endif()
 
 # Set ABIs to search
 ## default: search any ABI
-if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_LESS 3)
+if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_LESS "3")
   # ABI not supported
   unset (_${_PYTHON_PREFIX}_FIND_ABI)
   set (_${_PYTHON_PREFIX}_ABIFLAGS "")
@@ -965,17 +1035,74 @@ endif()
 
 # Compute search signature
 # This signature will be used to check validity of cached variables on new search
-set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}")
+set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${_${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}")
 if (NOT WIN32)
   string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_USE_STATIC_LIBS}:")
 endif()
 if (CMAKE_HOST_APPLE)
-  string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_FIND_FRAMEWORK}")
+  string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_FRAMEWORK}")
 endif()
 if (CMAKE_HOST_WIN32)
-  string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_FIND_REGISTRY}")
+  string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_REGISTRY}")
 endif()
 
+function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module)
+  if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+    string (TOUPPER "${module}" id)
+    set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+      list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
+    endif()
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+      list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
+    endif()
+    string (MD5 signature "${signature}")
+    if (signature STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE)
+      if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
+        set (exact EXACT)
+      endif()
+      if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+        _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} ${exact} CHECK_EXISTS)
+      endif()
+      if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+        _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} ${exact} CHECK_EXISTS)
+      endif()
+    else()
+      if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+        unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE)
+        unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
+      endif()
+      if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+        unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
+      endif()
+    endif()
+    if (("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+          AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+        OR ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+          AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR))
+      unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+      unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
+    endif()
+  endif()
+endfunction()
+
+function (_PYTHON_COMPUTE_DEVELOPMENT_SIGNATURE module)
+  string (TOUPPER "${module}" id)
+  if (${_PYTHON_PREFIX}_Development.${module}_FOUND)
+    set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+      list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
+    endif()
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+      list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
+    endif()
+    string (MD5 signature "${signature}")
+    set (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE "${signature}" CACHE INTERNAL "")
+  else()
+    unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
+  endif()
+endfunction()
+
 
 unset (_${_PYTHON_PREFIX}_REQUIRED_VARS)
 unset (_${_PYTHON_PREFIX}_CACHED_VARS)
@@ -1060,7 +1187,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
           if (_${_PYTHON_PREFIX}_EXECUTABLE)
             break()
           endif()
-          if (NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY")
+          if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY")
             break()
           endif()
         endif()
@@ -1323,7 +1450,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
 
       list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 1 ${_PYTHON_PREFIX}_VERSION_MAJOR)
       list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 2 ${_PYTHON_PREFIX}_VERSION_MINOR)
-      list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 3 ${_PYTHON_PREFIX}_VERSION_PATH)
+      list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 3 ${_PYTHON_PREFIX}_VERSION_PATCH)
 
       list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 4 _${_PYTHON_PREFIX}_ARCH)
       set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH})
@@ -1407,7 +1534,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
         endif()
 
         # retrieve various package installation directories
-        execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))"
+        execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))\nexcept Exception:\n   import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_path('stdlib'),sysconfig.get_path('platstdlib'),sysconfig.get_path('purelib'),sysconfig.get_path('platlib')]))"
                         RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
                         OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS
                         ERROR_QUIET)
@@ -1423,7 +1550,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
           unset (${_PYTHON_PREFIX}_SITEARCH)
         endif()
 
-        if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL 3)
+        if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3")
           _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)
         endif()
 
@@ -1615,7 +1742,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
   if (_${_PYTHON_PREFIX}_COMPILER AND _${_PYTHON_PREFIX}_COMPILER_USABLE)
     if (${_PYTHON_PREFIX}_Interpreter_FOUND)
       # Compiler must be compatible with interpreter
-      if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
+      if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}")
         set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE)
       endif()
     elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
@@ -1647,46 +1774,40 @@ endif()
 
 # third step, search for the development artifacts
 ## Development environment is not compatible with IronPython interpreter
-if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+      OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
     AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
+  if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
   list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_LIBRARY_RELEASE
                                               _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
                                               _${_PYTHON_PREFIX}_LIBRARY_DEBUG
-                                              _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
-                                              _${_PYTHON_PREFIX}_INCLUDE_DIR)
-  if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
-    list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES
-                                                  ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+                                              _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
   endif()
-
-  if (DEFINED _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR)
-    # compute development signature and check validity of definition
-    string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
-    if (WIN32 AND NOT DEFINED _${_PYTHON_PREFIX}_LIBRARY_DEBUG)
-      set (_${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND" CACHE INTERNAL "")
-    endif()
-    if (NOT DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR)
-      set (_${_PYTHON_PREFIX}_INCLUDE_DIR "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND" CACHE INTERNAL "")
+  if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+    list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_INCLUDE_DIR)
+  endif()
+  if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module)
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+      list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
     endif()
-    if (__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE)
-      # check version validity
-      if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
-        _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
-        _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
-      else()
-        _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
-        _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
-      endif()
-    else()
-      unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE)
-      unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
-      unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+      list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
     endif()
   endif()
-  if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
-    unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
-    unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE)
+  if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed)
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+      list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
+    endif()
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+      list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+    endif()
   endif()
+  if (_${_PYTHON_PREFIX}_REQUIRED_VARS) # XXX(cmake-3.14)
+    list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_REQUIRED_VARS)
+  endif ()
+
+  _python_check_development_signature (Module)
+  _python_check_development_signature (Embed)
 
   if (DEFINED ${_PYTHON_PREFIX}_LIBRARY
       AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_LIBRARY}")
@@ -1706,7 +1827,9 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
     if(${_PYTHON_PREFIX}_USE_STATIC_LIBS)
       set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
     else()
-      list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
+      if (CMAKE_FIND_LIBRARY_SUFFIXES) # XXX(cmake-3.14)
+        list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
+      endif ()
     endif()
   endif()
 
@@ -1909,6 +2032,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
     endif()
   endif()
 
+  if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
   if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
     if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
       # retrieve root install directory
@@ -2153,9 +2277,16 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
                                   HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
                                   PATH_SUFFIXES bin)
   endif()
+  endif()
 
+  if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+    while (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+      if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS
+          AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
   # Don't search for include dir if no library was founded
-  if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+        break()
+      endif()
+
     if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
       _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES)
 
@@ -2174,10 +2305,11 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
       endif()
       unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS)
 
+        if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
       # Use the library's install prefix as a hint
-      if (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
+          if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
         list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
-      elseif (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
+          elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE 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}_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
         list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
@@ -2187,6 +2319,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
         get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY)
         list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
       endif()
+        endif()
 
       _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
       _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION})
@@ -2242,7 +2375,9 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
     # search header file in standard locations
     find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
                NAMES Python.h)
-  endif()
+
+      break()
+    endwhile()
 
   set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
 
@@ -2255,10 +2390,18 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
     # retrieve version from header file
     _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_)
 
+      if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
     # update versioning
-    if (_${_PYTHON_PREFIX}_INC_VERSION VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION})
+    if (_${_PYTHON_PREFIX}_INC_VERSION VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION)
       set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
     endif()
+      else()
+        set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION})
+        set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR})
+        set (_${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_INC_VERSION_MINOR})
+        set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
+      endif()
+  endif()
   endif()
 
   if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND)
@@ -2270,6 +2413,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
   endif()
 
   # define public variables
+  if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
   set (${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
   _python_select_library_configurations (${_PYTHON_PREFIX})
 
@@ -2294,37 +2438,42 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
       _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS
                                 _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
   endif()
+  endif()
 
-  if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND _${_PYTHON_PREFIX}_INCLUDE_DIR)
+  if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_INCLUDE_DIR)
     if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND)
       # development environment must be compatible with interpreter/compiler
-      if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}
-          AND ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR} VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR})
-        set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+      if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}"
+          AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
+        _python_set_development_module_found (Module)
+        _python_set_development_module_found (Embed)
       endif()
     elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR
-            AND ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR} VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR})
-      set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+            AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
+        _python_set_development_module_found (Module)
+        _python_set_development_module_found (Embed)
     endif()
     if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND
         (NOT _${_PYTHON_PREFIX}_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS
           OR NOT _${_PYTHON_PREFIX}_INC_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS))
-      set (${_PYTHON_PREFIX}_Development_FOUND FALSE)
+      set (${_PYTHON_PREFIX}_Development.Module_FOUND FALSE)
+      set (${_PYTHON_PREFIX}_Development.Embed_FOUND FALSE)
     endif()
   endif()
 
-  if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL 3
+  if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+      AND ${_PYTHON_PREFIX}_Development.Module_FOUND
+      AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+    set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+  endif()
+
+  if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3"
       AND NOT DEFINED ${_PYTHON_PREFIX}_SOABI)
     _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)
   endif()
 
-  if (${_PYTHON_PREFIX}_Development_FOUND)
-    # compute and save development signature
-    string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
-    set (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}" CACHE INTERNAL "")
-  else()
-    unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE)
-  endif()
+  _python_compute_development_signature (Module)
+  _python_compute_development_signature (Embed)
 
   # Restore the original find library ordering
   if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES)
@@ -2332,9 +2481,13 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
   endif()
 
   if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
     set (${_PYTHON_PREFIX}_LIBRARY "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" CACHE FILEPATH "${_PYTHON_PREFIX} Library")
+    endif()
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
     set (${_PYTHON_PREFIX}_INCLUDE_DIR "${_${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} Include Directory")
   endif()
+  endif()
 
   _python_mark_as_internal (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
                             _${_PYTHON_PREFIX}_LIBRARY_DEBUG
@@ -2342,7 +2495,8 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
                             _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
                             _${_PYTHON_PREFIX}_INCLUDE_DIR
                             _${_PYTHON_PREFIX}_CONFIG
-                            _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE)
+                            _${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE
+                            _${_PYTHON_PREFIX}_DEVELOPMENT_EMBED_SIGNATURE)
 endif()
 
 if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND)
@@ -2356,7 +2510,7 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte
     set (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE INTERNAL "")
   elseif (DEFINED _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
     # compute numpy signature. Depends on interpreter and development signatures
-    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
+    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
     if (NOT __${_PYTHON_PREFIX}_NUMPY_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_NUMPY_SIGNATURE
         OR NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
       unset (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR CACHE)
@@ -2400,15 +2554,15 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte
       unset (${_PYTHON_PREFIX}_NumPy_VERSION)
     endif()
 
-    # final step: set NumPy founded only if Development component is founded as well
-    set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development_FOUND})
+    # final step: set NumPy founded only if Development.Module component is founded as well
+    set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND})
   else()
     set (${_PYTHON_PREFIX}_NumPy_FOUND FALSE)
   endif()
 
   if (${_PYTHON_PREFIX}_NumPy_FOUND)
     # compute and save numpy signature
-    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
+    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
     set (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}" CACHE INTERNAL "")
   else()
     unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE)
@@ -2467,8 +2621,10 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
                   PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}")
   endif()
 
-  if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
-      AND ${_PYTHON_PREFIX}_Development_FOUND)
+  if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+        AND ${_PYTHON_PREFIX}_Development.Module_FOUND)
+      OR ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+        AND ${_PYTHON_PREFIX}_Development.Embed_FOUND))
 
     macro (__PYTHON_IMPORT_LIBRARY __name)
       if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
@@ -2529,31 +2685,35 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
       endif()
     endmacro()
 
+    if (${_PYTHON_PREFIX}_Development.Embed_FOUND)
     __python_import_library (${_PYTHON_PREFIX}::Python)
+    endif()
 
-    if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
-      # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
-      # but ALIAS cannot be used because the imported library is not GLOBAL.
-      __python_import_library (${_PYTHON_PREFIX}::Module)
-    else()
-      if (NOT TARGET ${_PYTHON_PREFIX}::Module )
-        add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
-      endif()
-      set_property (TARGET ${_PYTHON_PREFIX}::Module
-                    PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
-
-      # When available, enforce shared library generation with undefined symbols
-      if (APPLE)
-        set_property (TARGET ${_PYTHON_PREFIX}::Module
-                      PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
-      endif()
-      if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
-        set_property (TARGET ${_PYTHON_PREFIX}::Module
-                      PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
-      endif()
-      if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
+    if (${_PYTHON_PREFIX}_Development.Module_FOUND)
+      if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+        # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
+        # but ALIAS cannot be used because the imported library is not GLOBAL.
+        __python_import_library (${_PYTHON_PREFIX}::Module)
+      else()
+        if (NOT TARGET ${_PYTHON_PREFIX}::Module)
+          add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
+        endif()
         set_property (TARGET ${_PYTHON_PREFIX}::Module
-                      PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
+                      PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
+
+        # When available, enforce shared library generation with undefined symbols
+        if (APPLE)
+          set_property (TARGET ${_PYTHON_PREFIX}::Module
+                        PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
+        endif()
+        if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+          set_property (TARGET ${_PYTHON_PREFIX}::Module
+                        PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
+        endif()
+        if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
+          set_property (TARGET ${_PYTHON_PREFIX}::Module
+                        PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
+        endif()
       endif()
     endif()
 
@@ -2577,6 +2737,16 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
       else()
         set (type MODULE)
       endif()
+
+      if (type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Module)
+        message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Module' is not defined.\n   Did you miss to request COMPONENT 'Development.Module'?")
+        return()
+      endif()
+      if (NOT type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Python)
+        message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Python' is not defined.\n   Did you miss to request COMPONENT 'Development.Embed'?")
+        return()
+      endif()
+
       add_library (${name} ${type} ${PYTHON_ADD_LIBRARY_UNPARSED_ARGUMENTS})
 
       get_property (type TARGET ${name} PROPERTY TYPE)
diff --git a/CMake/patches/3.17/FindPython2.cmake b/CMake/patches/3.18/FindPython2.cmake
similarity index 83%
rename from CMake/patches/3.17/FindPython2.cmake
rename to CMake/patches/3.18/FindPython2.cmake
index 10fe2118ebe5e79a9cf207db2aeb1251e00a84a6..ef3280fbb8d2c8aa1977697cfd413597ec025d1d 100644
--- a/CMake/patches/3.17/FindPython2.cmake
+++ b/CMake/patches/3.18/FindPython2.cmake
@@ -13,13 +13,24 @@ The following components are supported:
 * ``Interpreter``: search for Python 2 interpreter
 * ``Compiler``: search for Python 2 compiler. Only offered by IronPython.
 * ``Development``: search for development artifacts (include directories and
-  libraries)
+  libraries). This component includes two sub-components which can be specified
+  independently:
+
+  * ``Development.Module``: search for artifacts for Python 2 module
+    developments.
+  * ``Development.Embed``: search for artifacts for Python 2 embedding
+    developments.
+
 * ``NumPy``: search for NumPy include directories.
 
 If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
 
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
 To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
 
   find_package (Python2 COMPONENTS Interpreter Development)
 
@@ -31,10 +42,11 @@ for you.
 
 .. note::
 
-  If components ``Interpreter`` and ``Development`` are both specified, this
-  module search only for interpreter with same platform architecture as the one
-  defined by ``CMake`` configuration. This contraint does not apply if only
-  ``Interpreter`` component is specified.
+  If components ``Interpreter`` and ``Development`` (or one of its
+  sub-components) are both specified, this module search only for interpreter
+  with same platform architecture as the one defined by ``CMake``
+  configuration. This contraint does not apply if only ``Interpreter``
+  component is specified.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -46,12 +58,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
   Python 2 interpreter. Target defined if component ``Interpreter`` is found.
 ``Python2::Compiler``
   Python 2 compiler. Target defined if component ``Compiler`` is found.
-``Python2::Python``
-  Python 2 library for Python embedding. Target defined if component
-  ``Development`` is found.
 ``Python2::Module``
   Python 2 library for Python module. Target defined if component
-  ``Development`` is found.
+  ``Development.Module`` is found.
+``Python2::Python``
+  Python 2 library for Python embedding. Target defined if component
+  ``Development.Embed`` is found.
 ``Python2::NumPy``
   NumPy library for Python 2. Target defined if component ``NumPy`` is found.
 
@@ -78,22 +90,26 @@ This module will set the following variables in your project
   Standard platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``
+  or else ``sysconfig.get_path('stdlib')``.
 ``Python2_STDARCH``
   Standard platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``
+  or else ``sysconfig.get_path('platstdlib')``.
 ``Python2_SITELIB``
   Third-party platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``
+  or else ``sysconfig.get_path('purelib')``.
 ``Python2_SITEARCH``
   Third-party platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``
+  or else ``sysconfig.get_path('platlib')``.
 ``Python2_Compiler_FOUND``
   System has the Python 2 compiler.
 ``Python2_COMPILER``
@@ -103,6 +119,10 @@ This module will set the following variables in your project
     * IronPython
 ``Python2_Development_FOUND``
   System has the Python 2 development artifacts.
+``Python2_Development.Module_FOUND``
+  System has the Python 2 development artifacts for Python module.
+``Python2_Development.Embed_FOUND``
+  System has the Python 2 development artifacts for Python embedding.
 ``Python2_INCLUDE_DIRS``
   The Python 2 include directories.
 ``Python2_LIBRARIES``
@@ -140,8 +160,7 @@ Hints
 
 ``Python2_FIND_STRATEGY``
   This variable defines how lookup will be done.
-  The ``Python2_FIND_STRATEGY`` variable can be set to empty or one of the
-  following:
+  The ``Python2_FIND_STRATEGY`` variable can be set to one of the following:
 
   * ``VERSION``: Try to find the most recent version in all specified
     locations.
@@ -154,8 +173,7 @@ Hints
 ``Python2_FIND_REGISTRY``
   On Windows the ``Python2_FIND_REGISTRY`` variable determine the order
   of preference between registry and environment variables.
-  the ``Python2_FIND_REGISTRY`` variable can be set to empty or one of the
-  following:
+  the ``Python2_FIND_REGISTRY`` variable can be set to one of the following:
 
   * ``FIRST``: Try to use registry before environment variables.
     This is the default.
@@ -165,8 +183,8 @@ Hints
 ``Python2_FIND_FRAMEWORK``
   On macOS the ``Python2_FIND_FRAMEWORK`` variable determine the order of
   preference between Apple-style and unix-style package components.
-  This variable can be set to empty or take same values as
-  :variable:`CMAKE_FIND_FRAMEWORK` variable.
+  This variable can take same values as :variable:`CMAKE_FIND_FRAMEWORK`
+  variable.
 
   .. note::
 
@@ -180,16 +198,17 @@ Hints
   ``virtualenv`` or ``conda``. It is meaningful only when a virtual environment
   is active (i.e. the ``activate`` script has been evaluated). In this case, it
   takes precedence over ``Python2_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK``
-  variables.  The ``Python2_FIND_VIRTUALENV`` variable can be set to empty or
-  one of the following:
+  variables.  The ``Python2_FIND_VIRTUALENV`` variable can be set to one of the
+  following:
 
   * ``FIRST``: The virtual environment is used before any other standard
     paths to look-up for the interpreter. This is the default.
   * ``ONLY``: Only the virtual environment is used to look-up for the
     interpreter.
   * ``STANDARD``: The virtual environment is not used to look-up for the
-    interpreter. In this case, variable ``Python2_FIND_REGISTRY`` (Windows)
-    or ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
+    interpreter but environment variable ``PATH`` is always considered.
+    In this case, variable ``Python2_FIND_REGISTRY`` (Windows) or
+    ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
     ``NEVER`` to select preferably the interpreter from the virtual
     environment.
 
diff --git a/CMake/patches/3.17/FindPython3.cmake b/CMake/patches/3.18/FindPython3.cmake
similarity index 83%
rename from CMake/patches/3.17/FindPython3.cmake
rename to CMake/patches/3.18/FindPython3.cmake
index 211f982968b9995b43111fabaeb69d0ea20ae586..1373407cf167dc4743e6b40a70932cdd2d37bef7 100644
--- a/CMake/patches/3.17/FindPython3.cmake
+++ b/CMake/patches/3.18/FindPython3.cmake
@@ -13,13 +13,24 @@ The following components are supported:
 * ``Interpreter``: search for Python 3 interpreter
 * ``Compiler``: search for Python 3 compiler. Only offered by IronPython.
 * ``Development``: search for development artifacts (include directories and
-  libraries)
+  libraries). This component includes two sub-components which can be specified
+  independently:
+
+  * ``Development.Module``: search for artifacts for Python 3 module
+    developments.
+  * ``Development.Embed``: search for artifacts for Python 3 embedding
+    developments.
+
 * ``NumPy``: search for NumPy include directories.
 
 If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
 
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
 To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
 
   find_package (Python3 COMPONENTS Interpreter Development)
 
@@ -31,10 +42,11 @@ for you.
 
 .. note::
 
-  If components ``Interpreter`` and ``Development`` are both specified, this
-  module search only for interpreter with same platform architecture as the one
-  defined by ``CMake`` configuration. This contraint does not apply if only
-  ``Interpreter`` component is specified.
+  If components ``Interpreter`` and ``Development`` (or one of its
+  sub-components) are both specified, this module search only for interpreter
+  with same platform architecture as the one defined by ``CMake``
+  configuration. This contraint does not apply if only ``Interpreter``
+  component is specified.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -46,12 +58,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
   Python 3 interpreter. Target defined if component ``Interpreter`` is found.
 ``Python3::Compiler``
   Python 3 compiler. Target defined if component ``Compiler`` is found.
-``Python3::Python``
-  Python 3 library for Python embedding. Target defined if component
-  ``Development`` is found.
 ``Python3::Module``
   Python 3 library for Python module. Target defined if component
-  ``Development`` is found.
+  ``Development.Module`` is found.
+``Python3::Python``
+  Python 3 library for Python embedding. Target defined if component
+  ``Development.Embed`` is found.
 ``Python3::NumPy``
   NumPy library for Python 3. Target defined if component ``NumPy`` is found.
 
@@ -78,29 +90,35 @@ This module will set the following variables in your project
   Standard platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``
+  or else ``sysconfig.get_path('stdlib')``.
 ``Python3_STDARCH``
   Standard platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``
+  or else ``sysconfig.get_path('platstdlib')``.
 ``Python3_SITELIB``
   Third-party platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``
+  or else ``sysconfig.get_path('purelib')``.
 ``Python3_SITEARCH``
   Third-party platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``
+  or else ``sysconfig.get_path('platlib')``.
 ``Python3_SOABI``
   Extension suffix for modules.
 
   Information returned by
-  ``distutils.sysconfig.get_config_flag('SOABI')`` or computed from
-  ``distutils.sysconfig.get_config_flag('EXT_SUFFIX')`` or
-  ``python3-config --extension-suffix``.
+  ``distutils.sysconfig.get_config_var('SOABI')`` or computed from
+  ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` or
+  ``python3-config --extension-suffix``. If package ``distutils.sysconfig`` is
+  not available, ``sysconfig.get_config_var('SOABI')`` or
+  ``sysconfig.get_config_var('EXT_SUFFIX')`` are used.
 ``Python3_Compiler_FOUND``
   System has the Python 3 compiler.
 ``Python3_COMPILER``
@@ -110,6 +128,10 @@ This module will set the following variables in your project
     * IronPython
 ``Python3_Development_FOUND``
   System has the Python 3 development artifacts.
+``Python3_Development.Module_FOUND``
+  System has the Python 3 development artifacts for Python module.
+``Python3_Development.Embed_FOUND``
+  System has the Python 3 development artifacts for Python embedding.
 ``Python3_INCLUDE_DIRS``
   The Python 3 include directories.
 ``Python3_LIBRARIES``
@@ -188,8 +210,7 @@ Hints
 
 ``Python3_FIND_STRATEGY``
   This variable defines how lookup will be done.
-  The ``Python3_FIND_STRATEGY`` variable can be set to empty or one of the
-  following:
+  The ``Python3_FIND_STRATEGY`` variable can be set to one of the following:
 
   * ``VERSION``: Try to find the most recent version in all specified
     locations.
@@ -202,8 +223,7 @@ Hints
 ``Python3_FIND_REGISTRY``
   On Windows the ``Python3_FIND_REGISTRY`` variable determine the order
   of preference between registry and environment variables.
-  The ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the
-  following:
+  The ``Python3_FIND_REGISTRY`` variable can be set to one of the following:
 
   * ``FIRST``: Try to use registry before environment variables.
     This is the default.
@@ -213,8 +233,8 @@ Hints
 ``Python3_FIND_FRAMEWORK``
   On macOS the ``Python3_FIND_FRAMEWORK`` variable determine the order of
   preference between Apple-style and unix-style package components.
-  This variable can be set to empty or take same values as
-  :variable:`CMAKE_FIND_FRAMEWORK` variable.
+  This variable can take same values as :variable:`CMAKE_FIND_FRAMEWORK`
+  variable.
 
   .. note::
 
@@ -228,16 +248,17 @@ Hints
   ``virtualenv`` or ``conda``. It is meaningful only when a virtual environment
   is active (i.e. the ``activate`` script has been evaluated). In this case, it
   takes precedence over ``Python3_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK``
-  variables.  The ``Python3_FIND_VIRTUALENV`` variable can be set to empty or
-  one of the following:
+  variables.  The ``Python3_FIND_VIRTUALENV`` variable can be set to one of the
+  following:
 
   * ``FIRST``: The virtual environment is used before any other standard
     paths to look-up for the interpreter. This is the default.
   * ``ONLY``: Only the virtual environment is used to look-up for the
     interpreter.
   * ``STANDARD``: The virtual environment is not used to look-up for the
-    interpreter. In this case, variable ``Python3_FIND_REGISTRY`` (Windows)
-    or ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
+    interpreter but environment variable ``PATH`` is always considered.
+    In this case, variable ``Python3_FIND_REGISTRY`` (Windows) or
+    ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
     ``NEVER`` to select preferably the interpreter from the virtual
     environment.
 
diff --git a/CMake/vtkInstallCMakePackage.cmake b/CMake/vtkInstallCMakePackage.cmake
index 03b42ce97469a061bd731e4623528c1a70efef16..cdfdadf108b403aaf896e4518653a9189da1efff 100644
--- a/CMake/vtkInstallCMakePackage.cmake
+++ b/CMake/vtkInstallCMakePackage.cmake
@@ -110,9 +110,9 @@ set(vtk_cmake_patch_files
   patches/3.16/FindMPI/test_mpi.f90.in
   patches/3.16/FindMPI.cmake
   patches/3.16/FindPostgreSQL.cmake
-  patches/3.17/FindPython/Support.cmake
-  patches/3.17/FindPython2.cmake
-  patches/3.17/FindPython3.cmake
+  patches/3.18/FindPython/Support.cmake
+  patches/3.18/FindPython2.cmake
+  patches/3.18/FindPython3.cmake
   patches/99/FindGDAL.cmake
   patches/99/FindHDF5.cmake
   patches/99/FindJPEG.cmake
diff --git a/CMake/vtkModuleWrapPython.cmake b/CMake/vtkModuleWrapPython.cmake
index 74858d11c861db4926c72c8d9f5c3c29db2d34bc..4f9bb1ffd21a5ebee46e005de02ca3bad99c81ea 100644
--- a/CMake/vtkModuleWrapPython.cmake
+++ b/CMake/vtkModuleWrapPython.cmake
@@ -73,7 +73,7 @@ function (vtk_module_python_default_destination var)
   else ()
     if (NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR" OR
         NOT DEFINED "Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR")
-      find_package("Python${_vtk_module_python_MAJOR_VERSION}" QUIET COMPONENTS Development)
+      find_package("Python${_vtk_module_python_MAJOR_VERSION}" QUIET COMPONENTS Development.Module)
     endif ()
 
     if (Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MAJOR AND Python${_vtk_module_python_MAJOR_VERSION}_VERSION_MINOR)
diff --git a/CMake/vtkWheelPreparation.cmake b/CMake/vtkWheelPreparation.cmake
index 17f6c788839fd31591cf9556d7e99aa67c85b5f9..0bca9dbd211b7fce368be25e9b49bb4663bcf651 100644
--- a/CMake/vtkWheelPreparation.cmake
+++ b/CMake/vtkWheelPreparation.cmake
@@ -1,4 +1,11 @@
-find_package(Python3 COMPONENTS Interpreter Development)
+# Force some VTK options for wheels.
+set(VTK_PYTHON_VERSION 3)
+set(VTK_BUILD_TESTING OFF)
+set(VTK_ENABLE_WRAPPING ON)
+set(VTK_WRAP_PYTHON ON)
+set(Python3_ARTIFACTS_INTERACTIVE ON)
+
+find_package(Python3 COMPONENTS Interpreter Development.Module)
 set_property(GLOBAL PROPERTY _vtk_python_soabi "${Python3_SOABI}")
 
 execute_process(
diff --git a/CMake/vtkWrapSettings.cmake b/CMake/vtkWrapSettings.cmake
index 45cfec1ba4bc2f2640affd93b1a3067e748cef78..cc206f475c4453c668c73904a9e58dd008d694a6 100644
--- a/CMake/vtkWrapSettings.cmake
+++ b/CMake/vtkWrapSettings.cmake
@@ -11,8 +11,6 @@ set(VTK_PYTHON_VERSION 2 CACHE STRING
 set_property(CACHE VTK_PYTHON_VERSION
   PROPERTY
     STRINGS "2;3")
-cmake_dependent_option(VTK_WHEEL_BUILD "Generate a build for a Python wheel" OFF
-  "VTK_WRAP_PYTHON;VTK_PYTHON_VERSION EQUAL 3" OFF)
 
 # Force reset of hints file location in cache if it was moved
 if(VTK_WRAP_HINTS AND NOT EXISTS ${VTK_WRAP_HINTS})
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c1f2a273b43893e1f9ca3d3c88aee82b67215052..32e7ac35bab9ebfe5adebf2ee025790d3e741cc9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -44,6 +44,12 @@ if (VTK_ANDROID_BUILD)
   return()
 endif()
 
+include(vtkCMakeBackports)
+
+if (VTK_WHEEL_BUILD)
+  include(vtkWheelPreparation)
+endif ()
+
 include(vtkCompilerChecks)
 include(vtkCompilerPlatformFlags)
 include(vtkCompilerExtraFlags)
@@ -56,7 +62,6 @@ include(vtkMobileDevices)
 include(vtkWrapSettings)
 include(vtkCrossCompiling)
 include(vtkObjectFactory)
-include(vtkCMakeBackports)
 
 # Setup compiler flags for dynamic analysis
 # Should be included after vtkTesting
@@ -120,10 +125,6 @@ mark_as_advanced(VTK_ENABLE_LOGGING)
 
 include(vtkEncodeString)
 
-if (VTK_WHEEL_BUILD)
-  include(vtkWheelPreparation)
-endif ()
-
 # Set up our directory structure for output libraries and binaries
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${VTK_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${VTK_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
diff --git a/Utilities/Python/CMakeLists.txt b/Utilities/Python/CMakeLists.txt
index b39f33122dc46531fb9bc85effa935fcb25faa3c..e2f269f6ee2ebd4c7a80eaeb4be398938900e3f9 100644
--- a/Utilities/Python/CMakeLists.txt
+++ b/Utilities/Python/CMakeLists.txt
@@ -37,7 +37,8 @@ if (VTK_PYTHON_VERSION STREQUAL "2")
   vtk_module_find_package(
     PACKAGE Python2
     VERSION "${vtk_python_min_version}"
-    COMPONENTS Interpreter Development
+    COMPONENTS Interpreter Development.Module
+    OPTIONAL_COMPONENTS Development.Embed
     FORWARD_VERSION_REQ MINOR)
 elseif (VTK_PYTHON_VERSION STREQUAL "3")
   set(vtk_python_min_version "3.2")
@@ -48,14 +49,16 @@ elseif (VTK_PYTHON_VERSION STREQUAL "3")
   vtk_module_find_package(
     PACKAGE Python3
     VERSION "${vtk_python_min_version}"
-    COMPONENTS Interpreter Development
+    COMPONENTS Interpreter Development.Module
+    OPTIONAL_COMPONENTS Development.Embed
     FORWARD_VERSION_REQ MINOR)
 else ()
   message(FATAL_ERROR
     "`VTK_PYTHON_VERSION` must either be 2 or 3.")
 endif ()
 set(vtk_python_includes "${Python${VTK_PYTHON_VERSION}_INCLUDE_DIRS}")
-set(vtk_python_target "Python${VTK_PYTHON_VERSION}::Python")
+set(vtk_python_target "Python${VTK_PYTHON_VERSION}::Module")
+set(vtk_python_embed_target "Python${VTK_PYTHON_VERSION}::Python")
 set(vtk_python_version "${Python${VTK_PYTHON_VERSION}_VERSION}")
 set(vtk_python_version_pair "${Python${VTK_PYTHON_VERSION}_VERSION_MAJOR}.${Python${VTK_PYTHON_VERSION}_VERSION_MINOR}")
 
@@ -126,7 +129,7 @@ cmake_dependent_option(VTK_PYTHON_OPTIONAL_LINK
   # We shouldn't do it for static builds and we can't do it without
   # `target_link_options`. Windows also always needs to link against libpython
   # directly.
-  "NOT WIN32;BUILD_SHARED_LIBS;COMMAND target_link_options" OFF)
+  "NOT WIN32;BUILD_SHARED_LIBS;COMMAND target_link_options;TARGET \"${vtk_python_embed_target}\"" OFF)
 
 add_library(PythonUsed INTERFACE)
 add_library(VTK::PythonUsed ALIAS PythonUsed)
@@ -163,7 +166,7 @@ if (VTK_PYTHON_OPTIONAL_LINK)
   # Only when the actual Python target should be used should it be linked.
   vtk_module_link(VTK::Python
     INTERFACE
-      "$<LINK_ONLY:$<${should_use}:${vtk_python_target}>>")
+      "$<LINK_ONLY:$<${should_use}:${vtk_python_embed_target}>>")
   # Libraries need the platform flags if they are necessary and direct linking
   # is not being performed.
   vtk_module_link_options(VTK::Python
@@ -176,7 +179,7 @@ if (VTK_PYTHON_OPTIONAL_LINK)
   # flags.
   target_link_libraries(PythonUsed
     INTERFACE
-      "$<LINK_ONLY:$<${is_exe}:${vtk_python_target}>>")
+      "$<LINK_ONLY:$<${is_exe}:${vtk_python_embed_target}>>")
   target_link_options(PythonUsed
     INTERFACE
       "$<$<AND:${is_exe},${needs_flags}>:${platform_flags}>")
@@ -184,7 +187,13 @@ if (VTK_PYTHON_OPTIONAL_LINK)
     PROPERTY  "forward_link"
     VALUE     VTK::PythonUsed)
 else ()
-  vtk_module_link(VTK::Python
-    INTERFACE
-      "${vtk_python_target}")
+  if (TARGET "${vtk_python_embed_target}")
+    vtk_module_link(VTK::Python
+      INTERFACE
+        "${vtk_python_embed_target}")
+  else ()
+    vtk_module_link(VTK::Python
+      INTERFACE
+        "${vtk_python_target}")
+  endif ()
 endif ()
diff --git a/Wrapping/Python/CMakeLists.txt b/Wrapping/Python/CMakeLists.txt
index f69a1cf4ef243130783271c4ca5e6d75e4556b2a..441fccb04e1c0debac3dca1d22da724ee5e5eff3 100644
--- a/Wrapping/Python/CMakeLists.txt
+++ b/Wrapping/Python/CMakeLists.txt
@@ -21,45 +21,48 @@ if (UNIX)
     "${vtkpython_rpath_prefix}/${vtkpython_relpath}")
 endif ()
 
-add_executable(vtkpython
-  vtkpython.rc
-  vtkPythonAppInit.cxx)
-target_link_libraries(vtkpython
-  PRIVATE
-    VTK::WrappingPythonCore
-    VTK::PythonInterpreter
-    VTK::Python
-    VTK::vtkpythonmodules
-    VTK::vtksys)
-add_executable(VTK::vtkpython ALIAS vtkpython)
-if (VTK_INSTALL_PYTHON_EXES)
-  install(
-    TARGETS     vtkpython
-    EXPORT      VTKPython
-    DESTINATION "${CMAKE_INSTALL_BINDIR}")
-endif ()
-
-if (TARGET VTK::ParallelMPI)
-  add_executable(pvtkpython
+# The interpreters are not supported in wheel builds, so skip them.
+if (NOT VTK_WHEEL_BUILD)
+  add_executable(vtkpython
+    vtkpython.rc
     vtkPythonAppInit.cxx)
-  target_compile_definitions(pvtkpython
-    PRIVATE
-      VTK_COMPILED_USING_MPI)
-  target_link_libraries(pvtkpython
+  target_link_libraries(vtkpython
     PRIVATE
       VTK::WrappingPythonCore
       VTK::PythonInterpreter
-      VTK::ParallelMPI
       VTK::Python
-      VTK::mpi
-      VTK::vtkpythonmodules)
-  add_executable(VTK::pvtkpython ALIAS pvtkpython)
+      VTK::vtkpythonmodules
+      VTK::vtksys)
+  add_executable(VTK::vtkpython ALIAS vtkpython)
   if (VTK_INSTALL_PYTHON_EXES)
     install(
-      TARGETS     pvtkpython
+      TARGETS     vtkpython
       EXPORT      VTKPython
       DESTINATION "${CMAKE_INSTALL_BINDIR}")
   endif ()
+
+  if (TARGET VTK::ParallelMPI)
+    add_executable(pvtkpython
+      vtkPythonAppInit.cxx)
+    target_compile_definitions(pvtkpython
+      PRIVATE
+        VTK_COMPILED_USING_MPI)
+    target_link_libraries(pvtkpython
+      PRIVATE
+        VTK::WrappingPythonCore
+        VTK::PythonInterpreter
+        VTK::ParallelMPI
+        VTK::Python
+        VTK::mpi
+        VTK::vtkpythonmodules)
+    add_executable(VTK::pvtkpython ALIAS pvtkpython)
+    if (VTK_INSTALL_PYTHON_EXES)
+      install(
+        TARGETS     pvtkpython
+        EXPORT      VTKPython
+        DESTINATION "${CMAKE_INSTALL_BINDIR}")
+    endif ()
+  endif ()
 endif ()
 
 set(_vtk_python_imports)