Merge branch 'release-3.28'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2823ca4..a99cf50 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-cmake_minimum_required(VERSION 3.13...3.26 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...3.27 FATAL_ERROR)
 set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake)
 set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
 
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 0255b4d9..f44a4e8 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -77,6 +77,7 @@
               [COMPILE_DEFINITIONS <defs>...]
               [LINK_OPTIONS <options>...]
               [LINK_LIBRARIES <libs>...]
+              [LINKER_LANGUAGE <lang>]
               [OUTPUT_VARIABLE <var>]
               [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
               [<LANG>_STANDARD <std>]
@@ -177,6 +178,9 @@
   If this option is specified, any ``-DLINK_LIBRARIES=...`` value
   given to the ``CMAKE_FLAGS`` option will be ignored.
 
+  .. versionadded:: 3.29
+    Alias targets to imported libraries are also supported.
+
 ``LINK_OPTIONS <options>...``
   .. versionadded:: 3.14
 
@@ -184,6 +188,14 @@
   set the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property in the generated
   project, depending on the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable.
 
+``LINKER_LANGUAGE <lang>```
+  .. versionadded:: 3.29
+
+  Specify the :prop_tgt:`LINKER_LANGUAGE` target property of the generated
+  project.  When using multiple source files with different languages, set
+  this to the language of the source file containing the program entry point,
+  e.g., ``main``.
+
 ``LOG_DESCRIPTION <text>``
   .. versionadded:: 3.26
 
diff --git a/Help/command/try_run.rst b/Help/command/try_run.rst
index 1b5087d..c466a81 100644
--- a/Help/command/try_run.rst
+++ b/Help/command/try_run.rst
@@ -67,6 +67,7 @@
           [COMPILE_DEFINITIONS <defs>...]
           [LINK_OPTIONS <options>...]
           [LINK_LIBRARIES <libs>...]
+          [LINKER_LANGUAGE <lang>]
           [COMPILE_OUTPUT_VARIABLE <var>]
           [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
           [<LANG>_STANDARD <std>]
diff --git a/Help/dev/try_compile-linker-language.rst b/Help/dev/try_compile-linker-language.rst
new file mode 100644
index 0000000..8482dee
--- /dev/null
+++ b/Help/dev/try_compile-linker-language.rst
@@ -0,0 +1,6 @@
+try_compile-linker-language
+---------------------------
+
+* The :command:`try_compile` and :command:`try_run` commands gained a
+  ``LINKER_LANGUAGE`` option to specify the :prop_tgt:`LINKER_LANGUAGE`
+  target property in the generated test project.
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index fa1d297..55054f5 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -336,6 +336,7 @@
    /prop_tgt/LINK_SEARCH_START_STATIC
    /prop_tgt/LINK_WHAT_YOU_USE
    /prop_tgt/LINKER_LANGUAGE
+   /prop_tgt/LINKER_TYPE
    /prop_tgt/LOCATION
    /prop_tgt/LOCATION_CONFIG
    /prop_tgt/MACHO_COMPATIBILITY_VERSION
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index d9df773..9320ffa 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -474,6 +474,8 @@
    /variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE_SUPPORTED
    /variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG
    /variable/CMAKE_LANG_LINKER_LAUNCHER
+   /variable/CMAKE_LANG_USING_LINKER_MODE
+   /variable/CMAKE_LANG_USING_LINKER_TYPE
    /variable/CMAKE_LANG_VISIBILITY_PRESET
    /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY
    /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG
@@ -490,6 +492,7 @@
    /variable/CMAKE_LINK_LIBRARY_USING_FEATURE_SUPPORTED
    /variable/CMAKE_LINK_WHAT_YOU_USE
    /variable/CMAKE_LINK_WHAT_YOU_USE_CHECK
+   /variable/CMAKE_LINKER_TYPE
    /variable/CMAKE_MACOSX_BUNDLE
    /variable/CMAKE_MACOSX_RPATH
    /variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG
diff --git a/Help/prop_tgt/LINKER_TYPE.rst b/Help/prop_tgt/LINKER_TYPE.rst
new file mode 100644
index 0000000..90a663d
--- /dev/null
+++ b/Help/prop_tgt/LINKER_TYPE.rst
@@ -0,0 +1,26 @@
+LINKER_TYPE
+-----------
+
+.. versionadded:: 3.29
+
+Specify which linker will be used for the link step. The property value may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+.. code-block:: cmake
+
+  add_library(lib1 SHARED ...)
+  set_property(TARGET lib1 PROPERTY LINKER_TYPE LLD)
+
+This specifies that ``lib1`` should use linker type ``LLD`` for the link step.
+The implementation details will be provided by the variable
+:variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` with ``<TYPE>`` having the value
+``LLD``.
+
+This property is not supported on :generator:`Green Hills MULTI` and
+:generator:`Visual Studio 9 2008` generators.
+
+.. note::
+  It is assumed that the linker specified is fully compatible with the standard
+  one. CMake will not do any options translation.
+
+.. include:: ../variable/LINKER_PREDEFINED_TYPES.txt
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+  Developers should add similar notes for each topic branch
+  making a noteworthy change.  Each document should be named
+  and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/Linker-user-selection.rst b/Help/release/dev/Linker-user-selection.rst
new file mode 100644
index 0000000..ed78099
--- /dev/null
+++ b/Help/release/dev/Linker-user-selection.rst
@@ -0,0 +1,6 @@
+Linker-user-selection
+---------------------
+
+* The linker tool can now be specified for a selection of compilers/platforms
+  by setting :variable:`CMAKE_LINKER_TYPE` variable or :prop_tgt:`LINKER_TYPE`
+  target property.
diff --git a/Help/release/dev/project-include-multiple.rst b/Help/release/dev/project-include-multiple.rst
new file mode 100644
index 0000000..3f7b360
--- /dev/null
+++ b/Help/release/dev/project-include-multiple.rst
@@ -0,0 +1,11 @@
+project-include-multiple
+------------------------
+
+* The :variable:`CMAKE_PROJECT_INCLUDE`,
+  :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
+  :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`, and
+  :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` variables learned
+  to support a :ref:`semicolon-separated list <CMake Language Lists>` of
+  CMake language files to be included sequentially. These variables can also
+  reference module names to be found in :variable:`CMAKE_MODULE_PATH` or
+  builtin to CMake.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index b84bdb4..ea13fdc 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@
   This file should include the adjacent "dev.txt" file
   in development versions but not in release versions.
 
+.. include:: dev.txt
+
 Releases
 ========
 
diff --git a/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst b/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst
new file mode 100644
index 0000000..c9b6779
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst
@@ -0,0 +1,15 @@
+CMAKE_<LANG>_USING_LINKER_MODE
+------------------------------
+
+.. versionadded:: 3.29
+
+This variable specify what is the type of data stored in variable
+ :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>`. There are two possible values:
+
+``FLAG``
+  :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` holds compiler flags. This is
+  the default.
+
+``TOOL``
+  :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` holds the path to the linker
+  tool.
diff --git a/Help/variable/CMAKE_LANG_USING_LINKER_TYPE.rst b/Help/variable/CMAKE_LANG_USING_LINKER_TYPE.rst
new file mode 100644
index 0000000..e4d9fa6
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_USING_LINKER_TYPE.rst
@@ -0,0 +1,30 @@
+CMAKE_<LANG>_USING_LINKER_<TYPE>
+--------------------------------
+
+.. versionadded:: 3.29
+
+This variable defines how to specify the linker for the link step for the type
+as specified by the variable :variable:`CMAKE_LINKER_TYPE` or the target
+property :prop_tgt:`LINKER_TYPE`. It can hold compiler flags for the link step
+or directly the linker tool. The type of data is given by the variable
+:variable:`CMAKE_<LANG>_USING_LINKER_MODE`.
+
+For example, to specify the ``LLVM`` linker for ``GNU`` compilers, we have:
+
+.. code-block:: cmake
+
+  set(CMAKE_C_USING_LINKER_LLD "-fuse-ld=lld")
+
+Or on ``Windows`` platform, for ``Clang`` compilers simulating ``MSVC``, we
+have:
+
+.. code-block:: cmake
+
+  set(CMAKE_C_USING_LINKER_LLD "-fuse-ld=lld-link")
+
+And for the ``MSVC`` compiler, linker is directly used, so we have:
+
+.. code-block:: cmake
+
+  set(CMAKE_C_USING_LINKER_LLD "/path/to/lld-link.exe")
+  set(CMAKE_C_USING_LINKER_MODE TOOL)
diff --git a/Help/variable/CMAKE_LINKER_TYPE.rst b/Help/variable/CMAKE_LINKER_TYPE.rst
new file mode 100644
index 0000000..17ea947
--- /dev/null
+++ b/Help/variable/CMAKE_LINKER_TYPE.rst
@@ -0,0 +1,18 @@
+CMAKE_LINKER_TYPE
+-----------------
+
+.. versionadded:: 3.29
+
+Specify which linker will be used for the link step.
+
+.. note::
+  It is assumed that the linker specified is fully compatible with the standard
+  one. CMake will not do any options translation.
+
+This variable is used to initialize the :prop_tgt:`LINKER_TYPE` target
+property when they are created by calls to :command:`add_library` or
+:command:`add_executable` commands. It is meaningful only for targets having a
+link step. If set, its value is also used by the :command:`try_compile`
+command.
+
+.. include:: LINKER_PREDEFINED_TYPES.txt
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
index 76b9d92..217604f 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
@@ -3,12 +3,17 @@
 
 .. versionadded:: 3.15
 
-A CMake language file or module to be included as the last step of all
+A CMake language file to be included as the last step of all
 :command:`project` command calls.  This is intended for injecting custom code
 into project builds without modifying their source.  See :ref:`Code Injection`
 for a more detailed discussion of files potentially included during a
 :command:`project` call.
 
+.. versionadded:: 3.29
+  This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
+  of CMake language files to be included sequentially. It can also now refer to
+  module names to be found in :variable:`CMAKE_MODULE_PATH` or builtin to CMake.
+
 See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
 :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
 :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`, and
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
index 9a8c4b5..1dc0241 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
@@ -3,12 +3,17 @@
 
 .. versionadded:: 3.15
 
-A CMake language file or module to be included as the first step of all
+A CMake language file to be included as the first step of all
 :command:`project` command calls.  This is intended for injecting custom code
 into project builds without modifying their source.  See :ref:`Code Injection`
 for a more detailed discussion of files potentially included during a
 :command:`project` call.
 
+.. versionadded:: 3.29
+  This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
+  of CMake language files to be included sequentially. It can also now refer to
+  module names to be found in :variable:`CMAKE_MODULE_PATH` or builtin to CMake.
+
 See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
 :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
 :variable:`CMAKE_PROJECT_INCLUDE`, and
diff --git a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
index 3bb5cd8..6d37c1a 100644
--- a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
+++ b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
@@ -1,12 +1,17 @@
 CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE
 ------------------------------------
 
-A CMake language file or module to be included as the last step of any
+A CMake language file to be included as the last step of any
 :command:`project` command calls that specify ``<PROJECT-NAME>`` as the project
 name.  This is intended for injecting custom code into project builds without
 modifying their source.  See :ref:`Code Injection` for a more detailed
 discussion of files potentially included during a :command:`project` call.
 
+.. versionadded:: 3.29
+  This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
+  of CMake language files to be included sequentially. It can also now refer to
+  module names to be found in :variable:`CMAKE_MODULE_PATH` or builtin to CMake.
+
 See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
 :variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
 and :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variables.
diff --git a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
index ca584c1..96ddbf6 100644
--- a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
+++ b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
@@ -3,12 +3,17 @@
 
 .. versionadded:: 3.17
 
-A CMake language file or module to be included as the first step of any
+A CMake language file to be included as the first step of any
 :command:`project` command calls that specify ``<PROJECT-NAME>`` as the project
 name.  This is intended for injecting custom code into project builds without
 modifying their source.  See :ref:`Code Injection` for a more detailed
 discussion of files potentially included during a :command:`project` call.
 
+.. versionadded:: 3.29
+  This variable can be a :ref:`semicolon-separated list <CMake Language Lists>`
+  of CMake language files to be included sequentially. It can also now refer to
+  module names to be found in :variable:`CMAKE_MODULE_PATH` or builtin to CMake.
+
 See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
 :variable:`CMAKE_PROJECT_INCLUDE`, :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
 and :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variables.
diff --git a/Help/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.rst b/Help/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.rst
index 2010b08..54f530e 100644
--- a/Help/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.rst
+++ b/Help/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.rst
@@ -12,6 +12,10 @@
 See :ref:`Code Injection` for a more detailed discussion of files potentially
 included during a :command:`project` call.
 
+.. versionadded:: 3.29
+  This variable can also now refer to module names to be found in
+  :variable:`CMAKE_MODULE_PATH` or builtin to CMake.
+
 This variable is intended for specifying files that perform one-time setup
 for the build. It provides an injection point for things like configuring
 package managers, adding logic the user shares between projects (e.g. defining
diff --git a/Help/variable/LINKER_PREDEFINED_TYPES.txt b/Help/variable/LINKER_PREDEFINED_TYPES.txt
new file mode 100644
index 0000000..50dc3df
--- /dev/null
+++ b/Help/variable/LINKER_PREDEFINED_TYPES.txt
@@ -0,0 +1,57 @@
+Linker types are case-sensitive and may only contain letters, numbers and
+underscores. Linker types defined in all uppercase are reserved for CMake's own
+built-in types. The pre-defined linker types are:
+
+``DEFAULT``
+  This type corresponds to standard linking, essentially equivalent to
+  not specifying :prop_tgt:`LINKER_TYPE` target property.
+
+``SYSTEM``
+  Use the standard linker delivered by the platform or the standard toolkit
+  (for example, ``SYSTEM`` imply Microsoft linker for all ``MSVC`` compatible
+  compilers). This type is supported for the following platforms/compilers:
+
+  * Linux, for ``GNU``, ``Clang`` and ``NVIDIA`` compilers.
+  * All Apple variants for ``AppleClang``, ``Clang`` and ``GNU`` compilers.
+  * Windows, for ``MSVC``, ``GNU``, ``Clang`` and ``NVIDIA`` compilers.
+
+``LLD``
+  Use the ``LLVM`` linker. This type is supported for the following
+  platforms/compilers:
+
+  * Linux, for ``GNU``, ``Clang`` and ``NVIDIA`` compilers.
+  * All Apple variants for ``Clang`` and ``AppleClang`` compilers.
+  * Windows, for ``GNU``, ``Clang`` compilers with ``GNU`` front-end and
+    ``CLang``, ``MSVC`` and ``NVIDIA`` compilers with ``MSVC`` front-end.
+
+``BFD``
+  Use the ``GNU`` linker.  This type is supported for the following
+  platforms/compilers:
+
+  * Linux, for ``GNU``, ``Clang`` and ``NVIDIA`` compilers.
+  * Windows, for ``GNU``, ``Clang`` compilers with ``GNU`` front-end.
+
+``GOLD``
+  Supported on Linux platform for ``GNU``, ``Clang`` and ``NVIDIA`` compilers.
+
+``MOLD``
+  Use the `mold linker <https://github.com/rui314/mold>`_. This type is
+  supported on the following platforms:
+
+  * Linux platform for ``GNU``, ``Clang`` and ``NVIDIA`` compilers.
+  * All Apple variants for ``Clang`` and ``AppleClang`` compilers as an
+    alias to ``SOLD``.
+
+``SOLD``
+  Use the `sold linker <https://github.com/bluewhalesystems/sold>`_. This type
+  is only supported on Apple platforms for ``Clang`` and ``AppleClang``
+  compilers.
+
+``APPLE_CLASSIC``
+  Use the Apple linker in the classic behavior (i.e. before ``Xcode 15.0``).
+  This type is only supported on Apple platforms for ``GNU``, ``Clang`` and
+  ``AppleClang`` compilers.
+
+``MSVC``
+  Use the Microsoft linker. This type is only supported on Windows
+  platform for ``MSVC`` and ``Clang`` compiler with ``MSVC`` front-end.
diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in
index 1efd9f5..fab366a 100644
--- a/Modules/CMakeASMCompiler.cmake.in
+++ b/Modules/CMakeASMCompiler.cmake.in
@@ -5,6 +5,8 @@
 set(CMAKE_RANLIB "@CMAKE_RANLIB@")
 set(CMAKE_ASM@ASM_DIALECT@_COMPILER_RANLIB "@_CMAKE_ASM_COMPILER_RANLIB@")
 set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_LINKER_LINK "@CMAKE_LINKER_LINK@")
+set(CMAKE_LINKER_LLD "@CMAKE_LINKER_LLD@")
 set(CMAKE_MT "@CMAKE_MT@")
 set(CMAKE_TAPI "@CMAKE_TAPI@")
 set(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1)
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index 2f0b774..01185a3 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -26,6 +26,8 @@
 set(CMAKE_RANLIB "@CMAKE_RANLIB@")
 set(CMAKE_C_COMPILER_RANLIB "@CMAKE_C_COMPILER_RANLIB@")
 set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_LINKER_LINK "@CMAKE_LINKER_LINK@")
+set(CMAKE_LINKER_LLD "@CMAKE_LINKER_LLD@")
 set(CMAKE_MT "@CMAKE_MT@")
 set(CMAKE_TAPI "@CMAKE_TAPI@")
 set(CMAKE_COMPILER_IS_GNUCC @CMAKE_COMPILER_IS_GNUCC@)
diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in
index 3c28c28..3bc21fb 100644
--- a/Modules/CMakeCUDACompiler.cmake.in
+++ b/Modules/CMakeCUDACompiler.cmake.in
@@ -72,5 +72,7 @@
 @_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT@
 
 set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_LINKER_LINK "@CMAKE_LINKER_LINK@")
+set(CMAKE_LINKER_LLD "@CMAKE_LINKER_LLD@")
 set(CMAKE_AR "@CMAKE_AR@")
 set(CMAKE_MT "@CMAKE_MT@")
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 8b6f82b..fbc1540 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -27,6 +27,8 @@
 set(CMAKE_RANLIB "@CMAKE_RANLIB@")
 set(CMAKE_CXX_COMPILER_RANLIB "@CMAKE_CXX_COMPILER_RANLIB@")
 set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_LINKER_LINK "@CMAKE_LINKER_LINK@")
+set(CMAKE_LINKER_LLD "@CMAKE_LINKER_LLD@")
 set(CMAKE_MT "@CMAKE_MT@")
 set(CMAKE_TAPI "@CMAKE_TAPI@")
 set(CMAKE_COMPILER_IS_GNUCXX @CMAKE_COMPILER_IS_GNUCXX@)
diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake
index 7eb93e2..e4fa43f 100644
--- a/Modules/CMakeCompilerIdDetection.cmake
+++ b/Modules/CMakeCompilerIdDetection.cmake
@@ -42,11 +42,6 @@
 
     # Order is relevant here. For example, compilers which pretend to be
     # GCC must appear before the actual GCC.
-    if ("x${lang}" STREQUAL "xCXX")
-      list(APPEND ordered_compilers
-        Comeau
-      )
-    endif()
     list(APPEND ordered_compilers
       Intel
       IntelLLVM
diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake
index e12b175..cf270c0 100644
--- a/Modules/CMakeFindBinUtils.cmake
+++ b/Modules/CMakeFindBinUtils.cmake
@@ -60,6 +60,13 @@
 __resolve_tool_path(CMAKE_LINKER "${_CMAKE_TOOLCHAIN_LOCATION}" "Default Linker")
 __resolve_tool_path(CMAKE_MT     "${_CMAKE_TOOLCHAIN_LOCATION}" "Default Manifest Tool")
 
+macro(__resolve_linker_path __linker_type __name __search_path __doc)
+  if(NOT CMAKE_LINKER_${__linker_type})
+    set( CMAKE_LINKER_${__linker_type} "${__name}")
+  endif()
+  __resolve_tool_path(CMAKE_LINKER_${__linker_type} "${__search_path}" "${__doc}")
+endmacro()
+
 set(_CMAKE_TOOL_VARS "")
 
 # if it's the MS C/CXX compiler, search for link
@@ -93,6 +100,10 @@
 
   list(APPEND _CMAKE_TOOL_VARS LINKER MT AR)
 
+  # look-up for possible usable linker
+  __resolve_linker_path(LINK "link" "${_CMAKE_TOOLCHAIN_LOCATION}" "link Linker")
+  __resolve_linker_path(LLD "lld-link" "${_CMAKE_TOOLCHAIN_LOCATION}" "lld-link Linker")
+
 elseif("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" MATCHES "^x(Open)?Watcom$")
   set(_CMAKE_LINKER_NAMES "wlink")
   set(_CMAKE_AR_NAMES "wlib")
diff --git a/Modules/CMakeHIPCompiler.cmake.in b/Modules/CMakeHIPCompiler.cmake.in
index 6d5e62a..0c06c3b 100644
--- a/Modules/CMakeHIPCompiler.cmake.in
+++ b/Modules/CMakeHIPCompiler.cmake.in
@@ -74,5 +74,7 @@
 set(CMAKE_RANLIB "@CMAKE_RANLIB@")
 set(CMAKE_HIP_COMPILER_RANLIB "@CMAKE_HIP_COMPILER_RANLIB@")
 set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_LINKER_LINK "@CMAKE_LINKER_LINK@")
+set(CMAKE_LINKER_LLD "@CMAKE_LINKER_LLD@")
 set(CMAKE_MT "@CMAKE_MT@")
 set(CMAKE_TAPI "@CMAKE_TAPI@")
diff --git a/Modules/CMakeOBJCCompiler.cmake.in b/Modules/CMakeOBJCCompiler.cmake.in
index de73645..95e52bf 100644
--- a/Modules/CMakeOBJCCompiler.cmake.in
+++ b/Modules/CMakeOBJCCompiler.cmake.in
@@ -24,6 +24,8 @@
 set(CMAKE_RANLIB "@CMAKE_RANLIB@")
 set(CMAKE_OBJC_COMPILER_RANLIB "@CMAKE_OBJC_COMPILER_RANLIB@")
 set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_LINKER_LINK "@CMAKE_LINKER_LINK@")
+set(CMAKE_LINKER_LLD "@CMAKE_LINKER_LLD@")
 set(CMAKE_MT "@CMAKE_MT@")
 set(CMAKE_TAPI "@CMAKE_TAPI@")
 set(CMAKE_COMPILER_IS_GNUOBJC @CMAKE_COMPILER_IS_GNUOBJC@)
diff --git a/Modules/CMakeOBJCXXCompiler.cmake.in b/Modules/CMakeOBJCXXCompiler.cmake.in
index 94d24ff..87aca96 100644
--- a/Modules/CMakeOBJCXXCompiler.cmake.in
+++ b/Modules/CMakeOBJCXXCompiler.cmake.in
@@ -25,6 +25,8 @@
 set(CMAKE_RANLIB "@CMAKE_RANLIB@")
 set(CMAKE_OBJCXX_COMPILER_RANLIB "@CMAKE_OBJCXX_COMPILER_RANLIB@")
 set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_LINKER_LINK "@CMAKE_LINKER_LINK@")
+set(CMAKE_LINKER_LLD "@CMAKE_LINKER_LLD@")
 set(CMAKE_MT "@CMAKE_MT@")
 set(CMAKE_TAPI "@CMAKE_TAPI@")
 set(CMAKE_COMPILER_IS_GNUOBJCXX @CMAKE_COMPILER_IS_GNUOBJCXX@)
diff --git a/Modules/Compiler/ADSP-ASM.cmake b/Modules/Compiler/ADSP-ASM.cmake
new file mode 100644
index 0000000..9ef5142
--- /dev/null
+++ b/Modules/Compiler/ADSP-ASM.cmake
@@ -0,0 +1,6 @@
+include(Compiler/ADSP)
+__compiler_adsp(ASM)
+
+set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm)
+set(CMAKE_ASM_OUTPUT_EXTENSION ".o" )
+set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
diff --git a/Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake b/Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake
deleted file mode 100644
index 2265e5e..0000000
--- a/Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-
-set(_compiler_id_pp_test "defined(__COMO__)")
-
-set(_compiler_id_version_compute "
-  /* __COMO_VERSION__ = VRR */
-# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__COMO_VERSION__ / 100)
-# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__COMO_VERSION__ % 100)")
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index f43f48d..67b805b 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -1934,8 +1934,10 @@
   set(args)
   _ep_get_configure_command_id(${name} cfg_cmd_id)
   if(cfg_cmd_id STREQUAL "cmake")
-    # CMake project.  Select build command based on generator.
-    get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR)
+    # Adding a CMake project as an External Project.  Select command based on generator
+    get_property(cmake_generator TARGET ${name} PROPERTY _EP_CMAKE_GENERATOR)
+    # cmake_generator is the CMake generator of the ExternalProject target being added
+    # CMAKE_GENERATOR is the CMake generator of the Current Project
     if("${CMAKE_GENERATOR}" MATCHES "Make" AND
        ("${cmake_generator}" MATCHES "Make" OR NOT cmake_generator))
       # The project uses the same Makefile generator.  Use recursive make.
@@ -1948,6 +1950,11 @@
       endif()
     else()
       # Drive the project with "cmake --build".
+      if(NOT cmake_generator)
+        # If there is no CMake Generator defined on the ExternalProject,
+        # use the same Generator as the current project
+        set(cmake_generator "${CMAKE_GENERATOR}")
+      endif()
       get_target_property(cmake_command ${name} _EP_CMAKE_COMMAND)
       if(cmake_command)
         set(cmd "${cmake_command}")
@@ -1977,7 +1984,11 @@
         list(APPEND args --config ${config})
       endif()
       if(step STREQUAL "INSTALL")
-        list(APPEND args --target install)
+        if("${cmake_generator}" MATCHES "Green Hills MULTI")
+          list(APPEND args --target INSTALL)
+        else()
+          list(APPEND args --target install)
+        endif()
       endif()
       # But for "TEST" drive the project with corresponding "ctest".
       if("x${step}x" STREQUAL "xTESTx")
diff --git a/Modules/Platform/Apple-Clang.cmake b/Modules/Platform/Apple-Clang.cmake
index 57b3910..5fe4300 100644
--- a/Modules/Platform/Apple-Clang.cmake
+++ b/Modules/Platform/Apple-Clang.cmake
@@ -18,6 +18,13 @@
   set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK "-framework <LIBRARY>")
   set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK_SUPPORTED TRUE)
 
+  # linker selection
+  set(CMAKE_${lang}_USING_LINKER_SYSTEM "-fuse-ld=ld")
+  set(CMAKE_${lang}_USING_LINKER_APPLE_CLASSIC "-fuse-ld=ld" "LINKER:-ld_classic")
+  set(CMAKE_${lang}_USING_LINKER_LLD "-fuse-ld=lld")
+  set(CMAKE_${lang}_USING_LINKER_MOLD "-fuse-ld=mold")
+  set(CMAKE_${lang}_USING_LINKER_SOLD "-fuse-ld=sold")
+
   if(_CMAKE_OSX_SYSROOT_PATH MATCHES "/iPhoneOS")
     set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-miphoneos-version-min=")
   elseif(_CMAKE_OSX_SYSROOT_PATH MATCHES "/iPhoneSimulator")
diff --git a/Modules/Platform/Apple-GNU.cmake b/Modules/Platform/Apple-GNU.cmake
index 823c790..15f6a71 100644
--- a/Modules/Platform/Apple-GNU.cmake
+++ b/Modules/Platform/Apple-GNU.cmake
@@ -17,6 +17,9 @@
 
   set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK "-framework <LIBRARY>")
   set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK_SUPPORTED TRUE)
+
+  set(CMAKE_${lang}_USING_LINKER_SYSTEM "")
+  set(CMAKE_${lang}_USING_LINKER_APPLE_CLASSIC "LINKER:-ld_classic")
 endmacro()
 
 macro(cmake_gnu_set_sysroot_flag lang)
diff --git a/Modules/Platform/Linux-Clang-CUDA.cmake b/Modules/Platform/Linux-Clang-CUDA.cmake
new file mode 100644
index 0000000..4a9337e
--- /dev/null
+++ b/Modules/Platform/Linux-Clang-CUDA.cmake
@@ -0,0 +1,2 @@
+include(Platform/Linux-GNU)
+__linux_compiler_gnu(CUDA)
diff --git a/Modules/Platform/Linux-GNU.cmake b/Modules/Platform/Linux-GNU.cmake
index 6878254..b8ce521 100644
--- a/Modules/Platform/Linux-GNU.cmake
+++ b/Modules/Platform/Linux-GNU.cmake
@@ -12,4 +12,11 @@
   # We pass this for historical reasons.  Projects may have
   # executables that use dlopen but do not set ENABLE_EXPORTS.
   set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
+
+  # linker selection
+  set(CMAKE_${lang}_USING_LINKER_SYSTEM "")
+  set(CMAKE_${lang}_USING_LINKER_LLD "-fuse-ld=lld")
+  set(CMAKE_${lang}_USING_LINKER_BFD "-fuse-ld=bfd")
+  set(CMAKE_${lang}_USING_LINKER_GOLD "-fuse-ld=gold")
+  set(CMAKE_${lang}_USING_LINKER_MOLD "-fuse-ld=mold")
 endmacro()
diff --git a/Modules/Platform/Linux-NVIDIA-CUDA.cmake b/Modules/Platform/Linux-NVIDIA-CUDA.cmake
new file mode 100644
index 0000000..4b416de
--- /dev/null
+++ b/Modules/Platform/Linux-NVIDIA-CUDA.cmake
@@ -0,0 +1,7 @@
+
+# linker selection
+set(CMAKE_CUDA_USING_LINKER_SYSTEM "")
+set(CMAKE_CUDA_USING_LINKER_LLD "-fuse-ld=lld")
+set(CMAKE_CUDA_USING_LINKER_BFD "-fuse-ld=bfd")
+set(CMAKE_CUDA_USING_LINKER_GOLD "-fuse-ld=gold")
+set(CMAKE_CUDA_USING_LINKER_MOLD "-fuse-ld=mold")
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index 33d271d..a03fc9e 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -53,6 +53,12 @@
   set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
 
+  # linker selection
+  set(CMAKE_${lang}_USING_LINKER_DEFAULT "-fuse-ld=lld-link")
+  set(CMAKE_${lang}_USING_LINKER_SYSTEM "-fuse-ld=link")
+  set(CMAKE_${lang}_USING_LINKER_LLD "-fuse-ld=lld-link")
+  set(CMAKE_${lang}_USING_LINKER_MSVC "-fuse-ld=link")
+
   set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1)
   set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES 1)
   set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1)
@@ -74,10 +80,10 @@
   set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
   set(CMAKE_${lang}_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
   set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
-    "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} -Xlinker /MANIFEST:EMBED -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <OBJECTS> <LINK_LIBRARIES> <MANIFESTS>")
+    "<CMAKE_${lang}_COMPILER> -nostartfiles -nostdlib <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} -Xlinker /MANIFEST:EMBED -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <OBJECTS> <LINK_LIBRARIES> <MANIFESTS>")
   set(CMAKE_${lang}_CREATE_SHARED_MODULE ${CMAKE_${lang}_CREATE_SHARED_LIBRARY})
   set(CMAKE_${lang}_LINK_EXECUTABLE
-    "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Xlinker /MANIFEST:EMBED -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES> <MANIFESTS>")
+    "<CMAKE_${lang}_COMPILER> -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Xlinker /MANIFEST:EMBED -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES> <MANIFESTS>")
 
   set(CMAKE_${lang}_CREATE_WIN32_EXE "-Xlinker /subsystem:windows")
   set(CMAKE_${lang}_CREATE_CONSOLE_EXE "-Xlinker /subsystem:console")
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index 412af6b..ac990d5 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -112,6 +112,11 @@
     set(CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS "-Wl,-Bdynamic")
   endforeach()
 
+  # linker selection
+  set(CMAKE_${lang}_USING_LINKER_SYSTEM "")
+  set(CMAKE_${lang}_USING_LINKER_BFD "-fuse-ld=bfd")
+  set(CMAKE_${lang}_USING_LINKER_LLD "-fuse-ld=lld")
+
   # No -fPIC on Windows
   set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "")
   set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "")
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 829ab9b..1fbf0cc 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -512,6 +512,12 @@
     set(CMAKE_DEPFILE_FLAGS_${lang} "/showIncludes")
     set(CMAKE_${lang}_DEPFILE_FORMAT msvc)
   endif()
+
+  # linker selection
+  set(CMAKE_${lang}_USING_LINKER_SYSTEM "${CMAKE_LINKER_LINK}")
+  set(CMAKE_${lang}_USING_LINKER_LLD "${CMAKE_LINKER_LLD}")
+  set(CMAKE_${lang}_USING_LINKER_MSVC "${CMAKE_LINKER_LINK}")
+  set(CMAKE_${lang}_USING_LINKER_MODE TOOL)
 endmacro()
 
 macro(__windows_compiler_msvc_enable_rc flags)
diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
index 326e715..6489841 100644
--- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake
+++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
@@ -47,6 +47,12 @@
   "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICIT_DLINK_FLAGS}")
 unset(__IMPLICIT_DLINK_FLAGS)
 
+# linker selection
+set(CMAKE_CUDA_USING_LINKER_SYSTEM "${CMAKE_LINKER_LINK}")
+set(CMAKE_CUDA_USING_LINKER_LLD "${CMAKE_LINKER_LLD}")
+set(CMAKE_CUDA_USING_LINKER_MSVC "${CMAKE_LINKER_LINK}")
+set(CMAKE_CUDA_USING_LINKER_MODE TOOL)
+
 string(REPLACE "/D" "-D" _PLATFORM_DEFINES_CUDA "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_CXX}")
 
 if(CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 0e17767..0f25cc2 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,8 +1,8 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 28)
-set(CMake_VERSION_PATCH 0)
-set(CMake_VERSION_RC 2)
+set(CMake_VERSION_PATCH 20231019)
+#set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
 # Start with the full version number used in tags.  It has no dev info.
diff --git a/Source/Checks/Curses/CMakeLists.txt b/Source/Checks/Curses/CMakeLists.txt
index bc6b906..6f5f145 100644
--- a/Source/Checks/Curses/CMakeLists.txt
+++ b/Source/Checks/Curses/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.13...3.26 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...3.27 FATAL_ERROR)
 project(CheckCurses C)
 
 set(CURSES_NEED_NCURSES TRUE)
diff --git a/Source/Modules/CMakeBuildUtilities.cmake b/Source/Modules/CMakeBuildUtilities.cmake
index c891fe9..94896ab 100644
--- a/Source/Modules/CMakeBuildUtilities.cmake
+++ b/Source/Modules/CMakeBuildUtilities.cmake
@@ -287,6 +287,8 @@
   set(ENABLE_CPIO_SHARED OFF)
   set(ENABLE_CAT OFF)
   set(ENABLE_CAT_SHARED OFF)
+  set(ENABLE_UNZIP OFF)
+  set(ENABLE_UNZIP_SHARED OFF)
   set(ENABLE_XATTR OFF)
   set(ENABLE_ACL OFF)
   set(ENABLE_ICONV OFF)
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 7e19812..7f7c747 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -14,6 +14,7 @@
 
 #include "cmsys/Directory.hxx"
 #include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
 
 #include "cmArgumentParser.h"
 #include "cmConfigureLog.h"
@@ -83,6 +84,7 @@
 std::string const kCMAKE_HIP_RUNTIME_LIBRARY = "CMAKE_HIP_RUNTIME_LIBRARY";
 std::string const kCMAKE_ISPC_INSTRUCTION_SETS = "CMAKE_ISPC_INSTRUCTION_SETS";
 std::string const kCMAKE_ISPC_HEADER_SUFFIX = "CMAKE_ISPC_HEADER_SUFFIX";
+std::string const kCMAKE_LINKER_TYPE = "CMAKE_LINKER_TYPE";
 std::string const kCMAKE_LINK_SEARCH_END_STATIC =
   "CMAKE_LINK_SEARCH_END_STATIC";
 std::string const kCMAKE_LINK_SEARCH_START_STATIC =
@@ -176,6 +178,7 @@
           ArgumentParser::ExpectAtLeast{ 0 })
     .Bind("LINK_LIBRARIES"_s, &Arguments::LinkLibraries)
     .Bind("LINK_OPTIONS"_s, &Arguments::LinkOptions)
+    .Bind("LINKER_LANGUAGE"_s, &Arguments::LinkerLanguage)
     .Bind("COPY_FILE"_s, &Arguments::CopyFileTo)
     .Bind("COPY_FILE_ERROR"_s, &Arguments::CopyFileError)
     .BIND_LANG_PROPS(C)
@@ -854,8 +857,30 @@
         fclose(fout);
         return cm::nullopt;
       }
-      fprintf(fout, "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n\n",
+      fprintf(fout, "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n",
               fname.c_str());
+      // Create all relevant alias targets
+      if (arguments.LinkLibraries) {
+        const auto& aliasTargets = this->Makefile->GetAliasTargets();
+        for (std::string const& i : *arguments.LinkLibraries) {
+          auto alias = aliasTargets.find(i);
+          if (alias != aliasTargets.end()) {
+            const auto& aliasTarget =
+              this->Makefile->FindTargetToUse(alias->second);
+            // Create equivalent library/executable alias
+            if (aliasTarget->GetType() == cmStateEnums::EXECUTABLE) {
+              fprintf(fout, "add_executable(\"%s\" ALIAS \"%s\")\n", i.c_str(),
+                      alias->second.c_str());
+            } else {
+              // Other cases like UTILITY and GLOBAL_TARGET are excluded when
+              // arguments.LinkLibraries is initially parsed in this function.
+              fprintf(fout, "add_library(\"%s\" ALIAS \"%s\")\n", i.c_str(),
+                      alias->second.c_str());
+            }
+          }
+        }
+      }
+      fprintf(fout, "\n");
     }
 
     /* Set the appropriate policy information for ENABLE_EXPORTS */
@@ -1043,6 +1068,19 @@
       }
     }
 
+    if (arguments.LinkerLanguage) {
+      std::string LinkerLanguage = *arguments.LinkerLanguage;
+      if (testLangs.find(LinkerLanguage) == testLangs.end()) {
+        this->Makefile->IssueMessage(
+          MessageType::FATAL_ERROR,
+          "Linker language '" + LinkerLanguage +
+            "' must be enabled in project(LANGUAGES).");
+      }
+
+      fprintf(fout, "set_property(TARGET %s PROPERTY LINKER_LANGUAGE %s)\n",
+              targetName.c_str(), LinkerLanguage.c_str());
+    }
+
     if (arguments.LinkLibraries) {
       std::string libsToLink = " ";
       for (std::string const& i : *arguments.LinkLibraries) {
@@ -1114,6 +1152,20 @@
       vars.insert(varList.begin(), varList.end());
     }
 
+    if (this->Makefile->GetDefinition(kCMAKE_LINKER_TYPE)) {
+      // propagate various variables to support linker selection
+      vars.insert(kCMAKE_LINKER_TYPE);
+      auto defs = this->Makefile->GetDefinitions();
+      cmsys::RegularExpression linkerTypeDef{
+        "^CMAKE_[A-Za-z]+_USING_LINKER_"
+      };
+      for (auto const& def : defs) {
+        if (linkerTypeDef.find(def)) {
+          vars.insert(def);
+        }
+      }
+    }
+
     if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0083) ==
         cmPolicies::NEW) {
       // To ensure full support of PIE, propagate cache variables
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 3217a1b..6a26e88 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -91,6 +91,7 @@
     cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>>
       LinkLibraries;
     ArgumentParser::MaybeEmpty<std::vector<std::string>> LinkOptions;
+    cm::optional<std::string> LinkerLanguage;
     std::map<std::string, std::string> LangProps;
     std::string CMakeInternal;
     cm::optional<std::string> OutputVariable;
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index d0e69fb..bd87e11 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -960,13 +960,13 @@
 
   // Isolate the file policy level.
   // Support CMake versions as far back as 2.6 but also support using NEW
-  // policy settings for up to CMake 3.26 (this upper limit may be reviewed
+  // policy settings for up to CMake 3.27 (this upper limit may be reviewed
   // and increased from time to time). This reduces the opportunity for CMake
   // warnings when an older export file is later used with newer CMake
   // versions.
   /* clang-format off */
   os << "cmake_policy(PUSH)\n"
-     << "cmake_policy(VERSION 2.8.3...3.26)\n";
+     << "cmake_policy(VERSION 2.8.3...3.27)\n";
   /* clang-format on */
 }
 
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index d51dbd0..4e46df7 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -175,14 +175,15 @@
   cm::string_view property(this->Top()->Property);
 
   return property == "LINK_DIRECTORIES"_s || property == "LINK_OPTIONS"_s ||
-    property == "LINK_DEPENDS"_s || property == "LINK_LIBRARY_OVERRIDE"_s;
+    property == "LINK_DEPENDS"_s || property == "LINK_LIBRARY_OVERRIDE"_s ||
+    property == "LINKER_TYPE"_s;
 }
 
 bool cmGeneratorExpressionDAGChecker::EvaluatingLinkOptionsExpression() const
 {
   cm::string_view property(this->Top()->Property);
 
-  return property == "LINK_OPTIONS"_s;
+  return property == "LINK_OPTIONS"_s || property == "LINKER_TYPE"_s;
 }
 
 bool cmGeneratorExpressionDAGChecker::EvaluatingLinkerLauncher() const
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 2ea18bd..f7a6a4e 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -868,6 +868,31 @@
   return this->LocalGenerator->GetFeature(feature, config);
 }
 
+std::string cmGeneratorTarget::GetLinkerTypeProperty(
+  std::string const& lang, std::string const& config) const
+{
+  std::string propName{ "LINKER_TYPE" };
+  auto linkerType = this->GetProperty(propName);
+  if (!linkerType.IsEmpty()) {
+    cmGeneratorExpressionDAGChecker dagChecker(this, propName, nullptr,
+                                               nullptr);
+    auto ltype =
+      cmGeneratorExpression::Evaluate(*linkerType, this->GetLocalGenerator(),
+                                      config, this, &dagChecker, this, lang);
+    if (this->IsDeviceLink()) {
+      cmList list{ ltype };
+      const auto DL_BEGIN = "<DEVICE_LINK>"_s;
+      const auto DL_END = "</DEVICE_LINK>"_s;
+      cm::erase_if(list, [&](const std::string& item) {
+        return item == DL_BEGIN || item == DL_END;
+      });
+      return list.to_string();
+    }
+    return ltype;
+  }
+  return std::string{};
+}
+
 const char* cmGeneratorTarget::GetLinkPIEProperty(
   const std::string& config) const
 {
@@ -5515,6 +5540,50 @@
   return this->GetLinkClosure(config)->LinkerLanguage;
 }
 
+std::string cmGeneratorTarget::GetLinkerTool(const std::string& config) const
+{
+  return this->GetLinkerTool(this->GetLinkerLanguage(config), config);
+}
+
+std::string cmGeneratorTarget::GetLinkerTool(const std::string& lang,
+                                             const std::string& config) const
+{
+  auto usingLinker =
+    cmStrCat("CMAKE_", lang, "_USING_", this->IsDeviceLink() ? "DEVICE_" : "",
+             "LINKER_");
+  auto format = this->Makefile->GetDefinition(cmStrCat(usingLinker, "MODE"));
+  if (!format || format != "TOOL"_s) {
+    return this->Makefile->GetDefinition("CMAKE_LINKER");
+  }
+
+  auto linkerType = this->GetLinkerTypeProperty(lang, config);
+  if (linkerType.empty()) {
+    linkerType = "DEFAULT";
+  }
+  usingLinker = cmStrCat(usingLinker, linkerType);
+  auto linkerTool = this->Makefile->GetDefinition(usingLinker);
+
+  if (!linkerTool) {
+    if (this->GetGlobalGenerator()->IsVisualStudio() &&
+        linkerType == "DEFAULT"_s) {
+      return std::string{};
+    }
+
+    // fall-back to generic definition
+    linkerTool = this->Makefile->GetDefinition("CMAKE_LINKER");
+
+    if (linkerType != "DEFAULT"_s) {
+      this->LocalGenerator->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat("LINKER_TYPE '", linkerType,
+                 "' is unknown. Did you forgot to define '", usingLinker,
+                 "' variable?"));
+    }
+  }
+
+  return linkerTool;
+}
+
 std::string cmGeneratorTarget::GetPDBOutputName(
   const std::string& config) const
 {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index bf49914..a32c5d8 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -205,6 +205,9 @@
   cmValue GetFeature(const std::string& feature,
                      const std::string& config) const;
 
+  std::string GetLinkerTypeProperty(std::string const& lang,
+                                    std::string const& config) const;
+
   const char* GetLinkPIEProperty(const std::string& config) const;
 
   bool IsIPOEnabled(std::string const& lang, std::string const& config) const;
@@ -788,6 +791,10 @@
 
   //! Return the preferred linker language for this target
   std::string GetLinkerLanguage(const std::string& config) const;
+  //! Return the preferred linker tool for this target
+  std::string GetLinkerTool(const std::string& config) const;
+  std::string GetLinkerTool(const std::string& lang,
+                            const std::string& config) const;
 
   /** Does this target have a GNU implib to convert to MS format?  */
   bool HasImplibGNUtoMS(std::string const& config) const;
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 95e2187..940f49d 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -116,6 +116,19 @@
 
 void cmGhsMultiTargetGenerator::GenerateTarget()
 {
+  if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE &&
+      !this->GeneratorTarget
+         ->GetLinkerTypeProperty(
+           this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
+           this->ConfigName)
+         .empty()) {
+    // Green Hill MULTI does not support this feature.
+    cmSystemTools::Message(
+      cmStrCat("'LINKER_TYPE' property, specified on target '",
+               this->GeneratorTarget->GetName(),
+               "', is not supported by this generator."));
+  }
+
   // Open the target file in copy-if-different mode.
   std::string fproj =
     cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 933e754..e798d3e 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -694,7 +694,22 @@
     std::string includes =
       mf->GetSafeDefinition("CMAKE_PROJECT_TOP_LEVEL_INCLUDES");
     cmList includesList{ includes };
-    for (std::string const& setupFile : includesList) {
+    for (std::string setupFile : includesList) {
+      // Any relative path without a .cmake extension is checked for valid
+      // cmake modules. This logic should be consistent with CMake's include()
+      // command. Otherwise default to checking relative path w.r.t. source
+      // directory
+      if (!cmSystemTools::FileIsFullPath(setupFile) &&
+          !cmHasLiteralSuffix(setupFile, ".cmake")) {
+        std::string mfile = mf->GetModulesFile(cmStrCat(setupFile, ".cmake"));
+        if (mfile.empty()) {
+          cmSystemTools::Error(cmStrCat(
+            "CMAKE_PROJECT_TOP_LEVEL_INCLUDES module:\n  ", setupFile));
+          mf->GetState()->SetInTopLevelIncludes(false);
+          return;
+        }
+        setupFile = mfile;
+      }
       std::string absSetupFile = cmSystemTools::CollapseFullPath(
         setupFile, mf->GetCurrentSourceDirectory());
       if (!cmSystemTools::FileExists(absSetupFile)) {
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 5076e6c..9f6786e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2500,6 +2500,9 @@
     this->CurrentLocalGenerator->GetStaticLibraryFlags(
       extraLinkOptions, configName, llang, gtgt);
   } else {
+    this->CurrentLocalGenerator->AppendLinkerTypeFlags(extraLinkOptions, gtgt,
+                                                       configName, llang);
+
     cmValue targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
     if (targetLinkFlags) {
       this->CurrentLocalGenerator->AppendFlags(extraLinkOptions,
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index fe8d502..76e36ab 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -82,7 +82,6 @@
                                 "CMAKE_CURRENT_SOURCE_DIR",
                                 "CMAKE_CURRENT_BINARY_DIR",
                                 "CMAKE_RANLIB",
-                                "CMAKE_LINKER",
                                 "CMAKE_MT",
                                 "CMAKE_TAPI",
                                 "CMAKE_CUDA_HOST_COMPILER",
@@ -1604,6 +1603,7 @@
   }
 
   std::string extraLinkFlags;
+  this->AppendLinkerTypeFlags(extraLinkFlags, target, config, linkLanguage);
   this->AppendPositionIndependentLinkerFlags(extraLinkFlags, target, config,
                                              linkLanguage);
   this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage);
@@ -3200,6 +3200,49 @@
   }
 }
 
+void cmLocalGenerator::AppendLinkerTypeFlags(std::string& flags,
+                                             cmGeneratorTarget* target,
+                                             const std::string& config,
+                                             const std::string& linkLanguage)
+{
+  switch (target->GetType()) {
+    case cmStateEnums::EXECUTABLE:
+    case cmStateEnums::SHARED_LIBRARY:
+    case cmStateEnums::MODULE_LIBRARY:
+      break;
+    default:
+      return;
+  }
+
+  auto usingLinker =
+    cmStrCat("CMAKE_", linkLanguage, "_USING_",
+             target->IsDeviceLink() ? "DEVICE_" : "", "LINKER_");
+
+  auto format = this->Makefile->GetDefinition(cmStrCat(usingLinker, "MODE"));
+  if (format && format != "FLAG"_s) {
+    return;
+  }
+
+  auto linkerType = target->GetLinkerTypeProperty(linkLanguage, config);
+  if (linkerType.empty()) {
+    linkerType = "DEFAULT";
+  }
+  usingLinker = cmStrCat(usingLinker, linkerType);
+  auto linkerTypeFlags = this->Makefile->GetDefinition(usingLinker);
+  if (linkerTypeFlags) {
+    if (!linkerTypeFlags.IsEmpty()) {
+      auto linkerFlags = cmExpandListWithBacktrace(linkerTypeFlags);
+      target->ResolveLinkerWrapper(linkerFlags, linkLanguage);
+      this->AppendFlags(flags, linkerFlags);
+    }
+  } else if (linkerType != "DEFAULT"_s) {
+    this->IssueMessage(MessageType::FATAL_ERROR,
+                       cmStrCat("LINKER_TYPE '", linkerType,
+                                "' is unknown. Did you forgot to define '",
+                                usingLinker, "' variable?"));
+  }
+}
+
 void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
                                             cmGeneratorTarget* target,
                                             const std::string& config,
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index a920cfe..a61def9 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -177,6 +177,9 @@
   void AddPchDependencies(cmGeneratorTarget* target);
   void AddUnityBuild(cmGeneratorTarget* target);
   virtual void AddXCConfigSources(cmGeneratorTarget* /* target */) {}
+  void AppendLinkerTypeFlags(std::string& flags, cmGeneratorTarget* target,
+                             const std::string& config,
+                             const std::string& linkLanguage);
   void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
                             const std::string& config,
                             const std::string& lang);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 7b02c56..3f3779a 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -32,6 +32,7 @@
 #include "cmList.h"
 #include "cmListFileCache.h"
 #include "cmMakefile.h"
+#include "cmMessageType.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
 #include "cmSourceFile.h"
@@ -1085,6 +1086,16 @@
       cmComputeLinkInformation& cli = *pcli;
       std::string linkLanguage = cli.GetLinkLanguage();
 
+      if (!target->GetLinkerTypeProperty(linkLanguage, configName).empty()) {
+        // Visual Studio 10 or upper is required for this feature
+        this->GetCMakeInstance()->IssueMessage(
+          MessageType::FATAL_ERROR,
+          cmStrCat("'LINKER_TYPE' property, specified on target '",
+                   target->GetName(),
+                   "', is not supported by this generator."),
+          target->GetBacktrace());
+      }
+
       // Compute the variable name to lookup standard libraries for this
       // language.
       std::string standardLibsVar =
@@ -1161,6 +1172,16 @@
       cmComputeLinkInformation& cli = *pcli;
       std::string linkLanguage = cli.GetLinkLanguage();
 
+      if (!target->GetLinkerTypeProperty(linkLanguage, configName).empty()) {
+        // Visual Studio 10 or upper is required for this feature
+        this->GetCMakeInstance()->IssueMessage(
+          MessageType::FATAL_ERROR,
+          cmStrCat("'LINKER_TYPE' property, specified on target '",
+                   target->GetName(),
+                   "', is not supported by this generator."),
+          target->GetBacktrace());
+      }
+
       bool isWin32Executable = target->IsWin32Executable(configName);
 
       // Compute the variable name to lookup standard libraries for this
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 80f8a77..40d769d 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4630,12 +4630,13 @@
   }
 
   // Deprecate old policies.
-  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0120 &&
+  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0126 &&
       !(this->GetCMakeInstance()->GetIsInTryCompile() &&
         (
           // Policies set by cmCoreTryCompile::TryCompileCode.
           id == cmPolicies::CMP0065 || id == cmPolicies::CMP0083 ||
-          id == cmPolicies::CMP0091 || id == cmPolicies::CMP0104)) &&
+          id == cmPolicies::CMP0091 || id == cmPolicies::CMP0104 ||
+          id == cmPolicies::CMP0123 || id == cmPolicies::CMP0126)) &&
       (!this->IsSet("CMAKE_WARN_DEPRECATED") ||
        this->IsOn("CMAKE_WARN_DEPRECATED"))) {
     this->IssueMessage(MessageType::DEPRECATION_WARNING,
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 4a2b9e8..96a0d5c 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -344,6 +344,8 @@
     return;
   }
 
+  auto linker = this->GeneratorTarget->GetLinkerTool(this->GetConfigName());
+
   // Build list of dependencies.
   std::vector<std::string> depends;
   this->AppendLinkDepends(depends, linkLanguage);
@@ -533,6 +535,7 @@
     vars.CMTargetType =
       cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
     vars.Language = linkLanguage.c_str();
+    vars.Linker = linker.c_str();
     vars.AIXExports = aixExports.c_str();
     vars.Objects = buildObjs.c_str();
     std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index fc3caa1..0429155 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -441,6 +441,8 @@
     return;
   }
 
+  auto linker = this->GeneratorTarget->GetLinkerTool(this->GetConfigName());
+
   // Build list of dependencies.
   std::vector<std::string> depends;
   this->AppendLinkDepends(depends, linkLanguage);
@@ -766,6 +768,7 @@
     vars.CMTargetType =
       cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
     vars.Language = linkLanguage.c_str();
+    vars.Linker = linker.c_str();
     vars.AIXExports = aixExports.c_str();
     vars.Objects = buildObjs.c_str();
     std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 0c2a719..343f6b8 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -153,6 +153,8 @@
   this->LocalGenerator->AppendCompileOptions(flags, opts);
   this->LocalGenerator->SetLinkScriptShell(false);
 
+  this->LocalGenerator->AppendLinkerTypeFlags(
+    flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
   this->LocalGenerator->AppendPositionIndependentLinkerFlags(
     flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
   this->LocalGenerator->AppendDependencyInfoLinkerFlags(
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 48c30b6..5e7bb6e 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -294,6 +294,9 @@
         .c_str();
 
     vars.Language = "CUDA";
+    std::string linker =
+      this->GetGeneratorTarget()->GetLinkerTool("CUDA", config);
+    vars.Linker = linker.c_str();
 
     // build response file name
     std::string responseFlag = this->GetMakefile()->GetSafeDefinition(
@@ -400,6 +403,9 @@
   vars.Fatbinary = "$FATBIN";
   vars.RegisterFile = "$REGISTER";
   vars.LinkFlags = "$LINK_FLAGS";
+  std::string linker =
+    this->GetGeneratorTarget()->GetLinkerTool("CUDA", config);
+  vars.Linker = linker.c_str();
 
   std::string flags = this->GetFlags("CUDA", config);
   vars.Flags = flags.c_str();
@@ -441,6 +447,8 @@
     vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
     vars.CMTargetType = cmState::GetTargetTypeName(targetType).c_str();
 
+    std::string linker = this->GetGeneratorTarget()->GetLinkerTool(config);
+    vars.Linker = linker.c_str();
     std::string lang = this->TargetLinkLanguage(config);
     vars.Language = lang.c_str();
     vars.AIXExports = "$AIX_EXPORTS";
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 0bda945..a93f9c9 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1409,10 +1409,13 @@
     }
   }
 
+  this->SetMsvcTargetPdbVariable(vars, config);
+
   if (firstForConfig) {
     this->ExportObjectCompileCommand(
       language, sourceFilePath, objectDir, objectFileName, objectFileDir,
-      vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"], config);
+      vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"],
+      vars["TARGET_COMPILE_PDB"], vars["TARGET_PDB"], config);
   }
 
   objBuild.Outputs.push_back(objectFileName);
@@ -1607,8 +1610,6 @@
     }
   }
 
-  this->SetMsvcTargetPdbVariable(vars, config);
-
   objBuild.RspFile = cmStrCat(objectFileName, ".rsp");
 
   if (language == "ISPC") {
@@ -1759,10 +1760,13 @@
     vars["CLANG_TIDY_EXPORT_FIXES"] = fixesFile;
   }
 
+  this->SetMsvcTargetPdbVariable(vars, config);
+
   if (firstForConfig) {
     this->ExportObjectCompileCommand(
       language, sourceFilePath, bmiDir, bmiFileName, bmiFileDir, vars["FLAGS"],
-      vars["DEFINES"], vars["INCLUDES"], config);
+      vars["DEFINES"], vars["INCLUDES"], vars["TARGET_COMPILE_PDB"],
+      vars["TARGET_PDB"], config);
   }
 
   bmiBuild.Outputs.push_back(bmiFileName);
@@ -1833,8 +1837,6 @@
   this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
                              vars);
 
-  this->SetMsvcTargetPdbVariable(vars, config);
-
   bmiBuild.RspFile = cmStrCat(bmiFileName, ".rsp");
 
   this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
@@ -1966,6 +1968,7 @@
   std::string const& objectDir, std::string const& objectFileName,
   std::string const& objectFileDir, std::string const& flags,
   std::string const& defines, std::string const& includes,
+  std::string const& targetCompilePdb, std::string const& targetPdb,
   std::string const& outputConfig)
 {
   if (!this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS")) {
@@ -2016,6 +2019,8 @@
   compileObjectVars.Flags = fullFlags.c_str();
   compileObjectVars.Defines = defines.c_str();
   compileObjectVars.Includes = includes.c_str();
+  compileObjectVars.TargetCompilePDB = targetCompilePdb.c_str();
+  compileObjectVars.TargetPDB = targetPdb.c_str();
 
   // Rule for compiling object file.
   std::string cudaCompileMode;
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 3f56113..2131f6d 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -189,6 +189,7 @@
     std::string const& objectDir, std::string const& objectFileName,
     std::string const& objectFileDir, std::string const& flags,
     std::string const& defines, std::string const& includes,
+    std::string const& targetCompilePdb, std::string const& targetPdb,
     std::string const& outputConfig);
 
   void AdditionalCleanFiles(const std::string& config);
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 3aef299..53166c1 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -11,6 +11,7 @@
 #include "cmsys/RegularExpression.hxx"
 
 #include "cmExecutionStatus.h"
+#include "cmList.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
@@ -371,29 +372,55 @@
   if (!include) {
     return true;
   }
+  cmList includeFiles{ *include };
 
-  std::string includeFile =
-    cmSystemTools::CollapseFullPath(*include, mf.GetCurrentSourceDirectory());
-  if (!cmSystemTools::FileExists(includeFile)) {
-    status.SetError(cmStrCat("could not find requested file:\n  ", *include));
-    return false;
-  }
-  if (cmSystemTools::FileIsDirectory(includeFile)) {
-    status.SetError(cmStrCat("requested file is a directory:\n  ", *include));
-    return false;
-  }
+  bool failed = false;
+  for (auto filePath : includeFiles) {
+    // Any relative path without a .cmake extension is checked for valid cmake
+    // modules. This logic should be consistent with CMake's include() command.
+    // Otherwise default to checking relative path w.r.t. source directory
+    if (!cmSystemTools::FileIsFullPath(filePath) &&
+        !cmHasLiteralSuffix(filePath, ".cmake")) {
+      std::string mfile = mf.GetModulesFile(cmStrCat(filePath, ".cmake"));
+      if (mfile.empty()) {
+        status.SetError(
+          cmStrCat("could not find requested module:\n  ", filePath));
+        failed = true;
+        continue;
+      }
+      filePath = mfile;
+    }
+    std::string includeFile = cmSystemTools::CollapseFullPath(
+      filePath, mf.GetCurrentSourceDirectory());
+    if (!cmSystemTools::FileExists(includeFile)) {
+      status.SetError(
+        cmStrCat("could not find requested file:\n  ", filePath));
+      failed = true;
+      continue;
+    }
+    if (cmSystemTools::FileIsDirectory(includeFile)) {
+      status.SetError(
+        cmStrCat("requested file is a directory:\n  ", filePath));
+      failed = true;
+      continue;
+    }
 
-  const bool readit = mf.ReadDependentFile(*include);
-  if (readit) {
-    return true;
-  }
+    const bool readit = mf.ReadDependentFile(filePath);
+    if (readit) {
+      // If the included file ran successfully, continue to the next file
+      continue;
+    }
 
-  if (cmSystemTools::GetFatalErrorOccurred()) {
-    return true;
-  }
+    if (cmSystemTools::GetFatalErrorOccurred()) {
+      failed = true;
+      continue;
+    }
 
-  status.SetError(cmStrCat("could not load requested file:\n  ", *include));
-  return false;
+    status.SetError(cmStrCat("could not load requested file:\n  ", filePath));
+    failed = true;
+  }
+  // At this point all files were processed
+  return !failed;
 }
 
 static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name,
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 638bb42..a8c81d0 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -27,6 +27,19 @@
       return this->ReplaceValues->LinkFlags;
     }
   }
+  if (this->ReplaceValues->Linker) {
+    if (variable == "CMAKE_LINKER") {
+      auto result = this->OutputConverter->ConvertToOutputForExisting(
+        this->ReplaceValues->Linker);
+      if (this->ReplaceValues->Launcher) {
+        // Add launcher as part of expansion so that it always appears
+        // immediately before the command itself, regardless of whether the
+        // overall rule template contains other content at the front.
+        result = cmStrCat(this->ReplaceValues->Launcher, " ", result);
+      }
+      return result;
+    }
+  }
   if (this->ReplaceValues->Manifests) {
     if (variable == "MANIFESTS") {
       return this->ReplaceValues->Manifests;
@@ -325,17 +338,7 @@
   auto mapIt = this->VariableMappings.find(variable);
   if (mapIt != this->VariableMappings.end()) {
     if (variable.find("_FLAG") == std::string::npos) {
-      std::string ret =
-        this->OutputConverter->ConvertToOutputForExisting(mapIt->second);
-
-      if (this->ReplaceValues->Launcher && variable == "CMAKE_LINKER") {
-        // Add launcher as part of expansion so that it always appears
-        // immediately before the command itself, regardless of whether the
-        // overall rule template contains other content at the front.
-        ret = cmStrCat(this->ReplaceValues->Launcher, " ", ret);
-      }
-
-      return ret;
+      return this->OutputConverter->ConvertToOutputForExisting(mapIt->second);
     }
     return mapIt->second;
   }
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 5d1f199..225abd4 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -53,6 +53,7 @@
     const char* SONameFlag = nullptr;
     const char* TargetSOName = nullptr;
     const char* TargetInstallNameDir = nullptr;
+    const char* Linker = nullptr;
     const char* LinkFlags = nullptr;
     const char* Manifests = nullptr;
     const char* LanguageCompileFlags = nullptr;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index abbf29e..d93f658 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -456,6 +456,7 @@
   { "AUTORCC_EXECUTABLE"_s, IC::CanCompileSources },
 
   // Linking properties
+  { "LINKER_TYPE"_s, IC::CanCompileSources },
   { "ENABLE_EXPORTS"_s, IC::TargetWithSymbolExports },
   { "LINK_LIBRARIES_ONLY_TARGETS"_s, IC::NormalNonImportedTarget },
   { "LINK_SEARCH_START_STATIC"_s, IC::CanCompileSources },
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4860d9a..1bbd934 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2996,6 +2996,16 @@
       e1.WritePlatformConfigTag(
         "IntDir", cond, R"($(Platform)\$(Configuration)\$(ProjectName)\)");
     } else {
+      if (ttype == cmStateEnums::SHARED_LIBRARY ||
+          ttype == cmStateEnums::MODULE_LIBRARY ||
+          ttype == cmStateEnums::EXECUTABLE) {
+        auto linker = this->GeneratorTarget->GetLinkerTool(config);
+        if (!linker.empty()) {
+          ConvertToWindowsSlash(linker);
+          e1.WritePlatformConfigTag("LinkToolExe", cond, linker);
+        }
+      }
+
       std::string intermediateDir = cmStrCat(
         this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/',
         config, '/');
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index 2c5662d..2a57633 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -500,7 +500,7 @@
       OUTPUT_VARIABLE OUTPUT
       )
     if(NOT BLD_ERROR_VARIABLE)
-      message(SEND_ERROR "BLD_ERROR_VARIABLE try_compile failed, but it was expected to succeed.")
+      message(SEND_ERROR "BLD_ERROR_VARIABLE try_compile failed, but it was expected to succeed. ${OUTPUT}")
     endif()
 
     if(NOT CMAKE_CROSSCOMPILING)
@@ -518,6 +518,91 @@
       endif()
     endif()
   endif()
+
+  # Testing try_compile with ALIAS targets.
+  # These assume that previous test were successful, or at least the failures will be at the linking stage
+  # with symbol not found errors
+
+  # First make sure that if the test run without appropriate alias targets, they should error out
+  try_compile(FAILING_LIBRARY_ALIAS_ERROR_VARIABLE
+          "${CMAKE_CURRENT_BINARY_DIR}/test_failing_library_alias"
+          "${CMAKE_CURRENT_SOURCE_DIR}/test_system.cpp"
+          LINK_LIBRARIES not_existing_library
+          OUTPUT_VARIABLE OUTPUT
+          NO_CACHE
+  )
+  if(FAILING_LIBRARY_ALIAS_ERROR_VARIABLE)
+    message(SEND_ERROR "FAILING_LIBRARY_ALIAS_ERROR_VARIABLE try_compile succeeded, but it was expected to fail ${OUTPUT}.")
+  endif()
+
+  # FIXME: CMAKE_TRY_COMPILE_TARGET_TYPE=MODULE is needed to properly link and test targets linked to an executable
+#  set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+#  try_compile(FAILING_EXE_ALIAS_ERROR_VARIABLE
+#          "${CMAKE_CURRENT_BINARY_DIR}/test_failing_exe_alias"
+#          "${CMAKE_CURRENT_SOURCE_DIR}/imp_mod1.c"
+#          LINK_LIBRARIES not_existing_executable
+#          OUTPUT_VARIABLE OUTPUT
+#          NO_CACHE
+#  )
+#  unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
+#  if(FAILING_EXE_ALIAS_ERROR_VARIABLE)
+#    message(SEND_ERROR "FAILING_EXE_ALIAS_ERROR_VARIABLE try_compile succeeded, but it was expected to fail ${OUTPUT}.")
+#  endif()
+
+  # Do the actual try_compile tests for ALIAS targets
+  add_library(exp_systemlib_alias ALIAS exp_systemlib)
+  try_compile(EXP_LIBRARY_ALIAS_ERROR_VARIABLE
+          "${CMAKE_CURRENT_BINARY_DIR}/test_library_alias"
+          "${CMAKE_CURRENT_SOURCE_DIR}/test_system.cpp"
+          LINK_LIBRARIES exp_systemlib_alias
+          OUTPUT_VARIABLE OUTPUT
+          NO_CACHE
+  )
+  if(NOT EXP_LIBRARY_ALIAS_ERROR_VARIABLE)
+    message(SEND_ERROR "EXP_LIBRARY_ALIAS_ERROR_VARIABLE try_compile failed with library aliased target, but it was expected to succeed ${OUTPUT}.")
+  endif()
+
+  # FIXME: CMAKE_TRY_COMPILE_TARGET_TYPE=MODULE is needed to properly link and test targets linked to an executable
+#  set(CMAKE_TRY_COMPILE_TARGET_TYPE MODULE)
+#  add_executable(exp_exe_alias ALIAS exp_testExe2)
+#  try_compile(EXP_EXE_ALIAS_ERROR_VARIABLE
+#          "${CMAKE_CURRENT_BINARY_DIR}/test_exe_alias"
+#          "${CMAKE_CURRENT_SOURCE_DIR}/imp_mod1.c"
+#          LINK_LIBRARIES exp_exe_alias
+#          OUTPUT_VARIABLE OUTPUT
+#          NO_CACHE
+#  )
+#  unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
+#  if(NOT EXP_EXE_ALIAS_ERROR_VARIABLE)
+#    message(SEND_ERROR "EXP_EXE_ALIAS_ERROR_VARIABLE try_compile failed with executable aliased target, but it was expected to succeed ${OUTPUT}.")
+#  endif()
+
+  add_library(bld_systemlib_alias ALIAS bld_systemlib)
+  try_compile(BLD_LIBRARY_ALIAS_ERROR_VARIABLE
+          "${CMAKE_CURRENT_BINARY_DIR}/test_library_alias"
+          "${CMAKE_CURRENT_SOURCE_DIR}/test_system.cpp"
+          LINK_LIBRARIES bld_systemlib_alias
+          OUTPUT_VARIABLE OUTPUT
+          NO_CACHE
+  )
+  if(NOT BLD_LIBRARY_ALIAS_ERROR_VARIABLE)
+    message(SEND_ERROR "BLD_LIBRARY_ALIAS_ERROR_VARIABLE try_compile failed with library aliased target, but it was expected to succeed. ${OUTPUT}")
+  endif()
+
+  # FIXME: CMAKE_TRY_COMPILE_TARGET_TYPE=MODULE is needed to properly link and test targets linked to an executable
+#  set(CMAKE_TRY_COMPILE_TARGET_TYPE MODULE)
+#  add_executable(bld_exe_alias ALIAS bld_testExe2)
+#  try_compile(BLD_EXE_ALIAS_ERROR_VARIABLE
+#          "${CMAKE_CURRENT_BINARY_DIR}/test_exe_alias"
+#          "${CMAKE_CURRENT_SOURCE_DIR}/imp_mod1.c"
+#          LINK_LIBRARIES bld_exe_alias
+#          OUTPUT_VARIABLE OUTPUT
+#          NO_CACHE
+#  )
+#  unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
+#  if(NOT BLD_EXE_ALIAS_ERROR_VARIABLE)
+#    message(SEND_ERROR "BLD_EXE_ALIAS_ERROR_VARIABLE try_compile failed with executable aliased target, but it was expected to succeed. ${OUTPUT}")
+#  endif()
 endif()
 
 #---------------------------------------------------------------------------------
diff --git a/Tests/RunCMake/CMP0126/CMP0126-OLD-stderr.txt b/Tests/RunCMake/CMP0126/CMP0126-OLD-stderr.txt
new file mode 100644
index 0000000..7d2608b
--- /dev/null
+++ b/Tests/RunCMake/CMP0126/CMP0126-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0126-OLD\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0126 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMP0126/CMP0126-OLD_CL-stderr.txt b/Tests/RunCMake/CMP0126/CMP0126-OLD_CL-stderr.txt
new file mode 100644
index 0000000..1f2179c
--- /dev/null
+++ b/Tests/RunCMake/CMP0126/CMP0126-OLD_CL-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0126-OLD_CL\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0126 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 4387c5b..5a23b8b 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -583,7 +583,9 @@
 add_RunCMake_test_try_compile()
 
 add_RunCMake_test(try_run -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-                          -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
+                          -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+                          -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}
+                          -DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID})
 add_RunCMake_test(set)
 add_RunCMake_test(variable_watch)
 add_RunCMake_test(while)
@@ -737,6 +739,14 @@
   endif()
 endif()
 
+if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin|Windows)"
+    AND CMAKE_C_COMPILER_ID MATCHES "^(AppleClang|Clang|GNU|MSVC|NVIDIA)$"
+    AND NOT CMAKE_GENERATOR STREQUAL "Green Hills MULTI")
+  add_RunCMake_test(LinkerSelection -DCMake_TEST_CUDA=${CMake_TEST_CUDA}
+                                    -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+                                    -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
+endif()
+
 add_RunCMake_test(File_Archive)
 add_RunCMake_test(File_Configure)
 add_RunCMake_test(File_Generate)
diff --git a/Tests/RunCMake/LinkerSelection/AppleClassic.cmake b/Tests/RunCMake/LinkerSelection/AppleClassic.cmake
new file mode 100644
index 0000000..62a12ad
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/AppleClassic.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+set(CMAKE_LINKER_TYPE APPLE_CLASSIC)
+
+add_executable(main main.c)
+target_link_libraries(main PRIVATE m m)
diff --git a/Tests/RunCMake/LinkerSelection/CMakeLists.txt b/Tests/RunCMake/LinkerSelection/CMakeLists.txt
new file mode 100644
index 0000000..6a9ce76
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.28)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/LinkerSelection/CustomLinkerType-build-check.cmake b/Tests/RunCMake/LinkerSelection/CustomLinkerType-build-check.cmake
new file mode 100644
index 0000000..235c38e
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/CustomLinkerType-build-check.cmake
@@ -0,0 +1,2 @@
+
+include("${CMAKE_CURRENT_LIST_DIR}/LinkerType-validation.cmake")
diff --git a/Tests/RunCMake/LinkerSelection/CustomLinkerType.cmake b/Tests/RunCMake/LinkerSelection/CustomLinkerType.cmake
new file mode 100644
index 0000000..4bf98b0
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/CustomLinkerType.cmake
@@ -0,0 +1,36 @@
+
+enable_language(C)
+
+set(CMAKE_C_USING_LINKER_FOO_C "${CMAKE_C_USING_LINKER_LLD}")
+
+add_executable(main main.c)
+set_property(TARGET main PROPERTY LINKER_TYPE "$<$<LINK_LANGUAGE:C>:FOO_C>$<$<LINK_LANGUAGE:CUDA>:FOO_CUDA>")
+
+if(CMake_TEST_CUDA)
+  enable_language(CUDA)
+
+  set(CMAKE_CUDA_USING_LINKER_FOO_CUDA "${CMAKE_CUDA_USING_LINKER_LLD}")
+
+  add_executable(mainCU main.cu)
+  set_property(TARGET mainCU PROPERTY LINKER_TYPE "$<$<LINK_LANGUAGE:C>:FOO_C>$<$<LINK_LANGUAGE:CUDA>:FOO_CUDA>")
+endif()
+
+#
+# Generate file for validation
+#
+if (CMAKE_C_USING_LINKER_MODE STREQUAL "TOOL")
+  cmake_path(GET CMAKE_C_USING_LINKER_FOO_C FILENAME LINKER_TYPE_OPTION)
+else()
+  set(LINKER_TYPE_OPTION "${CMAKE_C_USING_LINKER_FOO_C}")
+endif()
+if(CMake_TEST_CUDA)
+  if (CMAKE_CUDA_USING_LINKER_MODE STREQUAL "TOOL")
+    cmake_path(GET CMAKE_CUDA_USING_LINKER_FOO_CUDA FILENAME CUDA_LINKER)
+  else()
+    set(CUDA_LINKER "${CMAKE_CUDA_USING_LINKER_FOO_CUDA}")
+  endif()
+  string(APPEND LINKER_TYPE_OPTION "|${CUDA_LINKER}")
+endif()
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER_TYPE_OPTION.cmake"
+  "set(LINKER_TYPE_OPTION \"${LINKER_TYPE_OPTION}\")\n")
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt b/Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType-stderr.txt b/Tests/RunCMake/LinkerSelection/InvalidLinkerType-stderr.txt
new file mode 100644
index 0000000..11aea7a
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/InvalidLinkerType-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  LINKER_TYPE 'FOO' is unknown.  Did you forgot to define
+  'CMAKE_C_USING_LINKER_FOO' variable\?
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType.cmake b/Tests/RunCMake/LinkerSelection/InvalidLinkerType.cmake
new file mode 100644
index 0000000..bbe398c
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/InvalidLinkerType.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+set(CMAKE_LINKER_TYPE FOO)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/LinkerSelection/LinkerType-validation.cmake b/Tests/RunCMake/LinkerSelection/LinkerType-validation.cmake
new file mode 100644
index 0000000..3f82479
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/LinkerType-validation.cmake
@@ -0,0 +1,9 @@
+
+include ("${RunCMake_TEST_BINARY_DIR}/LINKER_TYPE_OPTION.cmake")
+
+# In some environment, `=` character is escaped
+string(REPLACE "=" "\\\\?=" LINKER_TYPE_OPTION "${LINKER_TYPE_OPTION}")
+
+if (NOT actual_stdout MATCHES "${LINKER_TYPE_OPTION}")
+    set (RunCMake_TEST_FAILED "Not found expected '${LINKER_TYPE_OPTION}'.")
+endif()
diff --git a/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake b/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake
new file mode 100644
index 0000000..cae4ca4
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake
@@ -0,0 +1,44 @@
+include(RunCMake)
+
+if (RunCMake_GENERATOR MATCHES "Visual Studio 9 2008")
+  run_cmake(UnsupportedLinkerType)
+  return()
+endif()
+
+run_cmake(InvalidLinkerType)
+
+# look-up for LLVM linker
+if (WIN32)
+  set (LINKER_NAMES lld-link)
+else()
+  set(LINKER_NAMES ld.lld ld64.lld)
+endif()
+find_program(LLD_LINKER NAMES ${LINKER_NAMES})
+
+macro(run_cmake_and_build test)
+  run_cmake_with_options(${test} -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  if(CMake_TEST_CUDA)
+    string(APPEND "|${CMAKE_CUDA_USING_LINKER_LLD}")
+  endif()
+  run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config Release --verbose ${ARGN})
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+endmacro()
+
+if(LLD_LINKER)
+  block(SCOPE_FOR VARIABLES)
+    set(CMAKE_VERBOSE_MAKEFILE TRUE)
+    set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+    set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+
+    run_cmake_and_build(ValidLinkerType)
+    run_cmake_and_build(CustomLinkerType)
+  endblock()
+endif()
+
+if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "15.0")
+  run_cmake_and_build(AppleClassic)
+endif()
diff --git a/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-result.txt b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-stderr.txt b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-stderr.txt
new file mode 100644
index 0000000..6473451
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error at UnsupportedLinkerType.cmake:[0-9]+ \(add_executable\):
+  'LINKER_TYPE' property, specified on target 'main', is not supported by
+  this generator.
diff --git a/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType.cmake b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType.cmake
new file mode 100644
index 0000000..1b0703c
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/UnsupportedLinkerType.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+set(CMAKE_LINKER_TYPE LDD)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/LinkerSelection/ValidLinkerType-build-check.cmake b/Tests/RunCMake/LinkerSelection/ValidLinkerType-build-check.cmake
new file mode 100644
index 0000000..235c38e
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/ValidLinkerType-build-check.cmake
@@ -0,0 +1,2 @@
+
+include("${CMAKE_CURRENT_LIST_DIR}/LinkerType-validation.cmake")
diff --git a/Tests/RunCMake/LinkerSelection/ValidLinkerType.cmake b/Tests/RunCMake/LinkerSelection/ValidLinkerType.cmake
new file mode 100644
index 0000000..a685ac1
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/ValidLinkerType.cmake
@@ -0,0 +1,32 @@
+
+enable_language(C)
+
+set(CMAKE_LINKER_TYPE LLD)
+
+add_executable(main main.c)
+
+if(CMake_TEST_CUDA)
+  enable_language(CUDA)
+
+  add_executable(mainCU main.cu)
+endif()
+
+#
+# Generate file for validation
+#
+if (CMAKE_C_USING_LINKER_MODE STREQUAL "TOOL")
+  cmake_path(GET CMAKE_C_USING_LINKER_LLD FILENAME LINKER_TYPE_OPTION)
+else()
+  set(LINKER_TYPE_OPTION "${CMAKE_C_USING_LINKER_LLD}")
+endif()
+if(CMake_TEST_CUDA)
+  if (CMAKE_CUDA_USING_LINKER_MODE STREQUAL "TOOL")
+    cmake_path(GET CMAKE_CUDA_USING_LINKER_LLD FILENAME CUDA_LINKER)
+  else()
+    set(CUDA_LINKER "${CMAKE_CUDA_USING_LINKER_LLD}")
+  endif()
+  string(APPEND LINKER_TYPE_OPTION "|${CUDA_LINKER}")
+endif()
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER_TYPE_OPTION.cmake"
+  "set(LINKER_TYPE_OPTION \"${LINKER_TYPE_OPTION}\")\n")
diff --git a/Tests/RunCMake/LinkerSelection/main.c b/Tests/RunCMake/LinkerSelection/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/LinkerSelection/main.cu b/Tests/RunCMake/LinkerSelection/main.cu
new file mode 100644
index 0000000..766b775
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/main.cu
@@ -0,0 +1,5 @@
+
+int main()
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/ToolchainFile/CMP0126-OLD-stderr.txt b/Tests/RunCMake/ToolchainFile/CMP0126-OLD-stderr.txt
index f3c068a..efa7b32 100644
--- a/Tests/RunCMake/ToolchainFile/CMP0126-OLD-stderr.txt
+++ b/Tests/RunCMake/ToolchainFile/CMP0126-OLD-stderr.txt
@@ -1 +1,12 @@
-^try_compile CMP0126='OLD' VAR='2'
+^CMake Deprecation Warning at CMP0126-OLD\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0126 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
++
+try_compile CMP0126='OLD' VAR='2'
diff --git a/Tests/RunCMake/UseSWIG/CMP0122-NEW-check.cmake b/Tests/RunCMake/UseSWIG/CMP0122-NEW-check.cmake
index a26c278..df14d15 100644
--- a/Tests/RunCMake/UseSWIG/CMP0122-NEW-check.cmake
+++ b/Tests/RunCMake/UseSWIG/CMP0122-NEW-check.cmake
@@ -1,5 +1,5 @@
 
-cmake_policy(VERSION 3.1)
+cmake_policy(VERSION 3.5)
 
 file(STRINGS "${RunCMake_TEST_BINARY_DIR}/CMP0122-library-name.txt" prefixes)
 
diff --git a/Tests/RunCMake/UseSWIG/CMP0122-OLD-check.cmake b/Tests/RunCMake/UseSWIG/CMP0122-OLD-check.cmake
index 01657d0..6eb5c20 100644
--- a/Tests/RunCMake/UseSWIG/CMP0122-OLD-check.cmake
+++ b/Tests/RunCMake/UseSWIG/CMP0122-OLD-check.cmake
@@ -1,5 +1,5 @@
 
-cmake_policy(VERSION 3.1)
+cmake_policy(VERSION 3.5)
 
 file(STRINGS "${RunCMake_TEST_BINARY_DIR}/CMP0122-library-name.txt" prefixes)
 
diff --git a/Tests/RunCMake/UseSWIG/CMP0122-OLD-stderr.txt b/Tests/RunCMake/UseSWIG/CMP0122-OLD-stderr.txt
new file mode 100644
index 0000000..84f2ee7
--- /dev/null
+++ b/Tests/RunCMake/UseSWIG/CMP0122-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0122-OLD\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0122 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/find_file/NO_CACHE-stderr.txt b/Tests/RunCMake/find_file/NO_CACHE-stderr.txt
new file mode 100644
index 0000000..6da353b
--- /dev/null
+++ b/Tests/RunCMake/find_file/NO_CACHE-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at NO_CACHE\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0125 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_library/NO_CACHE-stderr.txt b/Tests/RunCMake/find_library/NO_CACHE-stderr.txt
new file mode 100644
index 0000000..6da353b
--- /dev/null
+++ b/Tests/RunCMake/find_library/NO_CACHE-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at NO_CACHE\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0125 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_path/NO_CACHE-stderr.txt b/Tests/RunCMake/find_path/NO_CACHE-stderr.txt
new file mode 100644
index 0000000..6da353b
--- /dev/null
+++ b/Tests/RunCMake/find_path/NO_CACHE-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at NO_CACHE\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0125 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_program/NO_CACHE-stderr.txt b/Tests/RunCMake/find_program/NO_CACHE-stderr.txt
new file mode 100644
index 0000000..6da353b
--- /dev/null
+++ b/Tests/RunCMake/find_program/NO_CACHE-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at NO_CACHE\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0125 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-OLD-stderr.txt b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-OLD-stderr.txt
new file mode 100644
index 0000000..7a49647
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at foreach-var-scope-CMP0124-OLD\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0124 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/CodeInjection-stdout.txt b/Tests/RunCMake/project/CodeInjection-stdout.txt
deleted file mode 100644
index 88ac966..0000000
--- a/Tests/RunCMake/project/CodeInjection-stdout.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE
-(-- )?Included CMAKE_TOOLCHAIN_FILE
-.*Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES first file
-(-- )?Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES second file
-(-- )?Included CMAKE_PROJECT_INCLUDE
-(-- )?Calling sub-project
-(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE
-(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE
-(-- )?Included CMAKE_PROJECT_INCLUDE
-(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_include.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_include.cmake
deleted file mode 100644
index f3f0a7e..0000000
--- a/Tests/RunCMake/project/CodeInjection/cmake_project_include.cmake
+++ /dev/null
@@ -1 +0,0 @@
-message(STATUS "Included CMAKE_PROJECT_INCLUDE")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_include_before.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_include_before.cmake
deleted file mode 100644
index 01d53c9..0000000
--- a/Tests/RunCMake/project/CodeInjection/cmake_project_include_before.cmake
+++ /dev/null
@@ -1 +0,0 @@
-message(STATUS "Included CMAKE_PROJECT_INCLUDE_BEFORE")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_includes_1.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_includes_1.cmake
new file mode 100644
index 0000000..2bc65cf
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/cmake_project_includes_1.cmake
@@ -0,0 +1 @@
+message(STATUS "Included CMAKE_PROJECT_INCLUDE first file")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_includes_2.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_includes_2.cmake
new file mode 100644
index 0000000..df7240c
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/cmake_project_includes_2.cmake
@@ -0,0 +1 @@
+message(STATUS "Included CMAKE_PROJECT_INCLUDE second file")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_includes_before_1.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_includes_before_1.cmake
new file mode 100644
index 0000000..20bea78
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/cmake_project_includes_before_1.cmake
@@ -0,0 +1 @@
+message(STATUS "Included CMAKE_PROJECT_INCLUDE_BEFORE first file")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_includes_before_2.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_includes_before_2.cmake
new file mode 100644
index 0000000..91b59d1
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/cmake_project_includes_before_2.cmake
@@ -0,0 +1 @@
+message(STATUS "Included CMAKE_PROJECT_INCLUDE_BEFORE second file")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_include.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_include.cmake
deleted file mode 100644
index d68de6a..0000000
--- a/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_include.cmake
+++ /dev/null
@@ -1 +0,0 @@
-message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_include_before.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_include_before.cmake
deleted file mode 100644
index ef3bfc0..0000000
--- a/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_include_before.cmake
+++ /dev/null
@@ -1 +0,0 @@
-message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_1.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_1.cmake
new file mode 100644
index 0000000..fe0fe4a
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_1.cmake
@@ -0,0 +1 @@
+message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE first file")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_2.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_2.cmake
new file mode 100644
index 0000000..c36fb52
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_2.cmake
@@ -0,0 +1 @@
+message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE second file")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_before_1.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_before_1.cmake
new file mode 100644
index 0000000..23ae05a
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_before_1.cmake
@@ -0,0 +1 @@
+message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE first file")
diff --git a/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_before_2.cmake b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_before_2.cmake
new file mode 100644
index 0000000..17f1d29
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/cmake_project_subproj_includes_before_2.cmake
@@ -0,0 +1 @@
+message(STATUS "Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE second file")
diff --git a/Tests/RunCMake/project/CodeInjection/initial_cache.cmake b/Tests/RunCMake/project/CodeInjection/initial_cache.cmake
deleted file mode 100644
index 6c8995b..0000000
--- a/Tests/RunCMake/project/CodeInjection/initial_cache.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-set(CMAKE_TOOLCHAIN_FILE                 "${CMAKE_CURRENT_LIST_DIR}/passthrough_toolchain_file.cmake" CACHE FILEPATH "")
-set(CMAKE_PROJECT_INCLUDE                "${CMAKE_CURRENT_LIST_DIR}/cmake_project_include.cmake" CACHE FILEPATH "")
-set(CMAKE_PROJECT_INCLUDE_BEFORE         "${CMAKE_CURRENT_LIST_DIR}/cmake_project_include_before.cmake" CACHE FILEPATH "")
-set(CMAKE_PROJECT_SubProj_INCLUDE        "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_include.cmake" CACHE FILEPATH "")
-set(CMAKE_PROJECT_SubProj_INCLUDE_BEFORE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_include_before.cmake" CACHE FILEPATH "")
-set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
-  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_1.cmake"
-  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_2.cmake"
-  CACHE STRING ""
-)
diff --git a/Tests/RunCMake/project/CodeInjection/initial_cache_1.cmake b/Tests/RunCMake/project/CodeInjection/initial_cache_1.cmake
new file mode 100644
index 0000000..43bb817
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/initial_cache_1.cmake
@@ -0,0 +1,9 @@
+set(CMAKE_TOOLCHAIN_FILE                 "${CMAKE_CURRENT_LIST_DIR}/passthrough_toolchain_file.cmake" CACHE FILEPATH "")
+set(CMAKE_PROJECT_INCLUDE                "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_1.cmake" CACHE FILEPATH "")
+set(CMAKE_PROJECT_INCLUDE_BEFORE         "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_before_1.cmake" CACHE FILEPATH "")
+set(CMAKE_PROJECT_SubProj_INCLUDE        "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_1.cmake" CACHE FILEPATH "")
+set(CMAKE_PROJECT_SubProj_INCLUDE_BEFORE "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_before_1.cmake" CACHE FILEPATH "")
+set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_1.cmake"
+  CACHE FILEPATH ""
+)
diff --git a/Tests/RunCMake/project/CodeInjection/initial_cache_2.cmake b/Tests/RunCMake/project/CodeInjection/initial_cache_2.cmake
new file mode 100644
index 0000000..09fcbfd
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/initial_cache_2.cmake
@@ -0,0 +1,27 @@
+set(CMAKE_TOOLCHAIN_FILE
+  "${CMAKE_CURRENT_LIST_DIR}/passthrough_toolchain_file.cmake" CACHE FILEPATH "")
+set(CMAKE_PROJECT_INCLUDE
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_1.cmake"
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_2.cmake"
+  CACHE STRING ""
+)
+set(CMAKE_PROJECT_INCLUDE_BEFORE
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_before_1.cmake"
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_before_2.cmake"
+  CACHE STRING ""
+)
+set(CMAKE_PROJECT_SubProj_INCLUDE
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_1.cmake"
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_2.cmake"
+  CACHE STRING ""
+)
+set(CMAKE_PROJECT_SubProj_INCLUDE_BEFORE
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_before_1.cmake"
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_before_2.cmake"
+  CACHE STRING ""
+)
+set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_1.cmake"
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_2.cmake"
+  CACHE STRING ""
+)
diff --git a/Tests/RunCMake/project/CodeInjection/initial_cache_3.cmake b/Tests/RunCMake/project/CodeInjection/initial_cache_3.cmake
new file mode 100644
index 0000000..dd299bc
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection/initial_cache_3.cmake
@@ -0,0 +1,28 @@
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}" CACHE STRING "")
+set(CMAKE_TOOLCHAIN_FILE
+  "${CMAKE_CURRENT_LIST_DIR}/passthrough_toolchain_file.cmake" CACHE FILEPATH "")
+set(CMAKE_PROJECT_INCLUDE
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_1.cmake"
+  "cmake_project_includes_2"
+  CACHE STRING ""
+)
+set(CMAKE_PROJECT_INCLUDE_BEFORE
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_includes_before_1.cmake"
+  "cmake_project_includes_before_2"
+  CACHE STRING ""
+)
+set(CMAKE_PROJECT_SubProj_INCLUDE
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_1.cmake"
+  "cmake_project_subproj_includes_2"
+  CACHE STRING ""
+)
+set(CMAKE_PROJECT_SubProj_INCLUDE_BEFORE
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_subproj_includes_before_1.cmake"
+  "cmake_project_subproj_includes_before_2"
+  CACHE STRING ""
+)
+set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
+  "${CMAKE_CURRENT_LIST_DIR}/cmake_project_top_level_includes_1.cmake"
+  "cmake_project_top_level_includes_2"
+  CACHE STRING ""
+)
diff --git a/Tests/RunCMake/project/CodeInjection1-stdout.txt b/Tests/RunCMake/project/CodeInjection1-stdout.txt
new file mode 100644
index 0000000..7a780b7
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection1-stdout.txt
@@ -0,0 +1,9 @@
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
+(-- )?Included CMAKE_TOOLCHAIN_FILE
+.*Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES first file
+(-- )?Included CMAKE_PROJECT_INCLUDE first file
+(-- )?Calling sub-project
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE first file
+(-- )?Included CMAKE_PROJECT_INCLUDE first file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE first file
diff --git a/Tests/RunCMake/project/CodeInjection.cmake b/Tests/RunCMake/project/CodeInjection1.cmake
similarity index 100%
rename from Tests/RunCMake/project/CodeInjection.cmake
rename to Tests/RunCMake/project/CodeInjection1.cmake
diff --git a/Tests/RunCMake/project/CodeInjection2-stdout.txt b/Tests/RunCMake/project/CodeInjection2-stdout.txt
new file mode 100644
index 0000000..5c18cdf
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection2-stdout.txt
@@ -0,0 +1,16 @@
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE second file
+(-- )?Included CMAKE_TOOLCHAIN_FILE
+.*Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES first file
+(-- )?Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES second file
+(-- )?Included CMAKE_PROJECT_INCLUDE first file
+(-- )?Included CMAKE_PROJECT_INCLUDE second file
+(-- )?Calling sub-project
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE second file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE first file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE second file
+(-- )?Included CMAKE_PROJECT_INCLUDE first file
+(-- )?Included CMAKE_PROJECT_INCLUDE second file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE first file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE second file
diff --git a/Tests/RunCMake/project/CodeInjection.cmake b/Tests/RunCMake/project/CodeInjection2.cmake
similarity index 100%
copy from Tests/RunCMake/project/CodeInjection.cmake
copy to Tests/RunCMake/project/CodeInjection2.cmake
diff --git a/Tests/RunCMake/project/CodeInjection3-stdout.txt b/Tests/RunCMake/project/CodeInjection3-stdout.txt
new file mode 100644
index 0000000..5c18cdf
--- /dev/null
+++ b/Tests/RunCMake/project/CodeInjection3-stdout.txt
@@ -0,0 +1,16 @@
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE second file
+(-- )?Included CMAKE_TOOLCHAIN_FILE
+.*Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES first file
+(-- )?Included CMAKE_PROJECT_TOP_LEVEL_INCLUDES second file
+(-- )?Included CMAKE_PROJECT_INCLUDE first file
+(-- )?Included CMAKE_PROJECT_INCLUDE second file
+(-- )?Calling sub-project
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE first file
+(-- )?Included CMAKE_PROJECT_INCLUDE_BEFORE second file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE first file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE_BEFORE second file
+(-- )?Included CMAKE_PROJECT_INCLUDE first file
+(-- )?Included CMAKE_PROJECT_INCLUDE second file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE first file
+(-- )?Included CMAKE_PROJECT_SubProj_INCLUDE second file
diff --git a/Tests/RunCMake/project/CodeInjection.cmake b/Tests/RunCMake/project/CodeInjection3.cmake
similarity index 100%
copy from Tests/RunCMake/project/CodeInjection.cmake
copy to Tests/RunCMake/project/CodeInjection3.cmake
diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake
index 0f3716f..16f10be 100644
--- a/Tests/RunCMake/project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/project/RunCMakeTest.cmake
@@ -5,8 +5,16 @@
 # which tests some of the individual variables one at a time.
 # Here, we are focused on testing that the variables are all injected
 # at the expected points in the expected order.
-run_cmake_with_options(CodeInjection
-  -C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache.cmake"
+run_cmake_with_options(CodeInjection1
+  -C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache_1.cmake"
+)
+# This checks that List variables are allowed.
+run_cmake_with_options(CodeInjection2
+        -C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache_2.cmake"
+)
+# This checks that module names are also allowed.
+run_cmake_with_options(CodeInjection3
+        -C "${CMAKE_CURRENT_LIST_DIR}/CodeInjection/initial_cache_3.cmake"
 )
 
 if(CMake_TEST_RESOURCES)
diff --git a/Tests/RunCMake/try_compile/LinkOptions.cmake b/Tests/RunCMake/try_compile/LinkOptions.cmake
index 7fae35c..45cbedf 100644
--- a/Tests/RunCMake/try_compile/LinkOptions.cmake
+++ b/Tests/RunCMake/try_compile/LinkOptions.cmake
@@ -1,8 +1,5 @@
-
 enable_language(C)
 
-cmake_policy(SET CMP0054 NEW)
-
 set (lib_name "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}lib${CMAKE_STATIC_LIBRARY_SUFFIX}")
 if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
   if (RunCMake_C_COMPILER_ID STREQUAL "MSVC"
diff --git a/Tests/RunCMake/try_run/LinkOptions.cmake b/Tests/RunCMake/try_run/LinkOptions.cmake
index b9a87f3..b19141c 100644
--- a/Tests/RunCMake/try_run/LinkOptions.cmake
+++ b/Tests/RunCMake/try_run/LinkOptions.cmake
@@ -1,8 +1,5 @@
-
 enable_language(C)
 
-cmake_policy(SET CMP0054 NEW)
-
 set (lib_name "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}lib${CMAKE_STATIC_LIBRARY_SUFFIX}")
 if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
   if (RunCMake_C_COMPILER_ID STREQUAL "MSVC"
diff --git a/Tests/RunCMake/try_run/LinkerLanguage.cmake b/Tests/RunCMake/try_run/LinkerLanguage.cmake
new file mode 100644
index 0000000..137e198
--- /dev/null
+++ b/Tests/RunCMake/try_run/LinkerLanguage.cmake
@@ -0,0 +1,29 @@
+enable_language(CXX)
+enable_language(Fortran)
+
+set (lib_name "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}lib${CMAKE_STATIC_LIBRARY_SUFFIX}")
+if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
+  if (CMAKE_SIZEOF_VOID_P EQUAL 4)
+    set (undef_flag -u _func)
+  else()
+    set (undef_flag -u func)
+  endif()
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+  set (undef_flag -u _func)
+else()
+  set (undef_flag -u func)
+endif()
+
+set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
+try_run(run_result compile_result
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/lib.cxx ${CMAKE_CURRENT_SOURCE_DIR}/main.f90
+  COMPILE_OUTPUT_VARIABLE compile_out
+  RUN_OUTPUT_VARIABLE run_out
+  LINKER_LANGUAGE Fortran)
+
+if(NOT compile_result)
+  message(FATAL_ERROR "try_run(... LINKER_LANGUAGE Fortran) compilation failed:\n${compile_out}")
+endif()
+if(run_result STREQUAL "FAILED_TO_RUN")
+  message(FATAL_ERROR "try_run(... LINKER_LANGUAGE Fortran) execution failed:\n${run_out}")
+endif()
diff --git a/Tests/RunCMake/try_run/RunCMakeTest.cmake b/Tests/RunCMake/try_run/RunCMakeTest.cmake
index 62e3caf..bd7cd9b 100644
--- a/Tests/RunCMake/try_run/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_run/RunCMakeTest.cmake
@@ -19,3 +19,13 @@
   run_cmake(LinkOptions)
   unset (RunCMake_TEST_OPTIONS)
 endif()
+
+if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows)$" AND
+    CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$" AND
+    CMAKE_Fortran_COMPILER_ID MATCHES "^(GNU)$")
+  set (RunCMake_TEST_OPTIONS
+    -DRunCMake_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}
+    -DRunCMake_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID})
+  run_cmake(LinkerLanguage)
+  unset (RunCMake_TEST_OPTIONS)
+endif()
diff --git a/Tests/RunCMake/try_run/lib.cxx b/Tests/RunCMake/try_run/lib.cxx
new file mode 100644
index 0000000..b01a075
--- /dev/null
+++ b/Tests/RunCMake/try_run/lib.cxx
@@ -0,0 +1,4 @@
+
+extern "C" void func()
+{
+}
diff --git a/Tests/RunCMake/try_run/main.f90 b/Tests/RunCMake/try_run/main.f90
new file mode 100644
index 0000000..29b933e
--- /dev/null
+++ b/Tests/RunCMake/try_run/main.f90
@@ -0,0 +1,12 @@
+program main
+
+implicit none
+
+interface
+subroutine func() bind(C)
+end subroutine
+end interface
+
+call func()
+
+end program
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index 12b5407..52a31eb 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@
 
 if(NOT CMake_SOURCE_DIR)
   set(CMakeDeveloperReference_STANDALONE 1)
-  cmake_minimum_required(VERSION 3.13...3.26 FATAL_ERROR)
+  cmake_minimum_required(VERSION 3.13...3.27 FATAL_ERROR)
   get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
   get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
   include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/Scripts/update-libarchive.bash b/Utilities/Scripts/update-libarchive.bash
index 5a4f11a..724303e 100755
--- a/Utilities/Scripts/update-libarchive.bash
+++ b/Utilities/Scripts/update-libarchive.bash
@@ -8,7 +8,7 @@
 readonly ownership="LibArchive Upstream <libarchive-discuss@googlegroups.com>"
 readonly subtree="Utilities/cmlibarchive"
 readonly repo="https://github.com/libarchive/libarchive.git"
-readonly tag="v3.6.2"
+readonly tag="v3.7.2"
 readonly shortlog=false
 readonly paths="
   CMakeLists.txt
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index 694ba3c..4ffcdd7 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@
 
 if(NOT CMake_SOURCE_DIR)
   set(CMakeHelp_STANDALONE 1)
-  cmake_minimum_required(VERSION 3.13...3.26 FATAL_ERROR)
+  cmake_minimum_required(VERSION 3.13...3.27 FATAL_ERROR)
   get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
   get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
   include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/cmThirdPartyChecks.cmake b/Utilities/cmThirdPartyChecks.cmake
index 8f68777..311d58e 100644
--- a/Utilities/cmThirdPartyChecks.cmake
+++ b/Utilities/cmThirdPartyChecks.cmake
@@ -43,8 +43,8 @@
   set(HAVE_CHROOT 0)
   set(HAVE_COPYFILE_H 0)
   set(HAVE_CRYPTO_H 0)
-  set(HAVE__CTIME64_S 1)
   set(HAVE_CTIME_R 0)
+  set(HAVE_CTIME_S 1)
   set(HAVE_CYGWIN_CONV_PATH 0)
   set(HAVE_DES_H 0)
   set(HAVE_DIRECT_H 1)
@@ -64,6 +64,8 @@
   set(HAVE_FCNTL_H 1)
   set(HAVE_FCNTL_O_NONBLOCK 0)
   set(HAVE_FDOPENDIR 0)
+  set(HAVE_FNMATCH 0)
+  set(HAVE_FNMATCH_H 0)
   set(HAVE_FORK 0)
   set(HAVE_FREEADDRINFO 1)
   set(HAVE_FREEIFADDRS 0)
@@ -82,6 +84,7 @@
   set(HAVE_GETGRGID_R 0)
   set(HAVE_GETGRNAM_R 0)
   set(HAVE_GETHOSTBYNAME 1)
+  set(HAVE_GETLINE 0)
   set(HAVE_GETPAGESIZE 0)
   set(HAVE_GETPEERNAME 1)
   set(HAVE_GETPID 1)
@@ -94,8 +97,8 @@
   set(HAVE_GETSOCKNAME 1)
   set(HAVE_GETVFSBYNAME 0)
   set(HAVE_GLIBC_STRERROR_R 0)
-  set(HAVE__GMTIME64_S 1)
   set(HAVE_GMTIME_R 0)
+  set(HAVE_GMTIME_S 1)
   set(HAVE_GRP_H 0)
   set(HAVE_IDN2_H 0)
   set(HAVE_IFADDRS_H 0)
@@ -126,8 +129,8 @@
   set(HAVE_LINUX_FS_H 0)
   set(HAVE_LINUX_MAGIC_H 0)
   set(HAVE_LINUX_TYPES_H 0)
-  set(HAVE__LOCALTIME64_S 1)
   set(HAVE_LOCALTIME_R 0)
+  set(HAVE_LOCALTIME_S 0)
   set(HAVE_LSTAT 0)
   set(HAVE_LUTIMES 0)
   set(HAVE_MACH_ABSOLUTE_TIME 0)
@@ -136,7 +139,7 @@
   set(HAVE_MEMORY_H 1)
   set(HAVE_MKDIR 1)
   set(HAVE_MKFIFO 0)
-  set(HAVE__MKGMTIME64 1)
+  set(HAVE__MKGMTIME 1)
   set(HAVE_MKNOD 0)
   set(HAVE_MMAP 0)
   set(HAVE_MSG_NOSIGNAL 0)
@@ -216,6 +219,7 @@
   set(HAVE_SYS_MKDEV_H 0)
   set(HAVE_SYS_MOUNT_H 0)
   set(HAVE_SYS_POLL_H 0)
+  set(HAVE_SYS_QUEUE_H 0)
   set(HAVE_SYS_RESOURCE_H 0)
   set(HAVE_SYS_RICHACL_H 0)
   set(HAVE_SYS_SELECT_H 0)
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index 027de5c..1237608 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -69,6 +69,7 @@
 SET(BSDCPIO_VERSION_STRING     "${VERSION}")
 SET(BSDTAR_VERSION_STRING      "${VERSION}")
 SET(BSDCAT_VERSION_STRING      "${VERSION}")
+SET(BSDUNZIP_VERSION_STRING    "${VERSION}")
 SET(LIBARCHIVE_VERSION_NUMBER  "${_version_number}")
 SET(LIBARCHIVE_VERSION_STRING  "${VERSION}")
 
@@ -224,6 +225,8 @@
 # Enable CTest/CDash support
 include(CTest)
 
+option(BUILD_SHARED_LIBS "Build shared libraries" ON)
+
 OPTION(ENABLE_MBEDTLS "Enable use of mbed TLS" OFF)
 OPTION(ENABLE_NETTLE "Enable use of Nettle" OFF)
 OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
@@ -248,6 +251,13 @@
 OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE)
 OPTION(ENABLE_CAT "Enable cat building" ON)
 OPTION(ENABLE_CAT_SHARED "Enable dynamic build of cat" FALSE)
+IF(WIN32 AND NOT CYGWIN)
+	SET(ENABLE_UNZIP FALSE)
+	SET(ENABLE_UNZIP_SHARED FALSE)
+ELSE()
+	OPTION(ENABLE_UNZIP "Enable unzip building" ON)
+	OPTION(ENABLE_UNZIP_SHARED "Enable dynamic build of unzip" FALSE)
+ENDIF()
 OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
 OPTION(ENABLE_ACL "Enable ACL support" ON)
 OPTION(ENABLE_ICONV "Enable iconv support" ON)
@@ -324,6 +334,7 @@
 
 IF(MINGW)
   ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO)
+  ADD_DEFINITIONS(-D__MINGW_USE_VC2005_COMPAT)
 ENDIF()
 
 #
@@ -394,7 +405,11 @@
       IF("${TRY_TYPE}" MATCHES "COMPILES")
         CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
       ELSEIF("${TRY_TYPE}" MATCHES "RUNS")
-        CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
+        IF(CMAKE_CROSSCOMPILING)
+          MESSAGE(WARNING "Cannot test run \"${VAR}\" when cross-compiling")
+        ELSE(CMAKE_CROSSCOMPILING)
+          CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
+        ENDIF(CMAKE_CROSSCOMPILING)
       ELSE("${TRY_TYPE}" MATCHES "COMPILES")
         MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE")
       ENDIF("${TRY_TYPE}" MATCHES "COMPILES")
@@ -533,15 +548,19 @@
       COMPILES
       "#include <lzma.h>\nint main() {return (int)lzma_version_number(); }"
       "WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC")
+    CHECK_C_SOURCE_COMPILES(
+      "#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
+      HAVE_LZMA_STREAM_ENCODER_MT)
     IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
       ADD_DEFINITIONS(-DLZMA_API_STATIC)
-    ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
+    ENDIF()
   ELSE()
     ADD_DEFINITIONS(-DLZMA_API_STATIC)
   ENDIF()
   CMAKE_POP_CHECK_STATE()
 ELSE(LIBLZMA_FOUND)
 # LZMA not found and will not be used.
+  SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
 ENDIF(LIBLZMA_FOUND)
 #
 # Find LZO2
@@ -590,6 +609,7 @@
   SET(HAVE_BLAKE2_H 1)
   SET(ARCHIVE_BLAKE2 FALSE)
   LIST(APPEND ADDITIONAL_LIBS ${LIBB2_LIBRARY})
+  INCLUDE_DIRECTORIES(${LIBB2_INCLUDE_DIR})
   CMAKE_PUSH_CHECK_STATE()
   SET(CMAKE_REQUIRED_LIBRARIES ${LIBB2_LIBRARY})
   SET(CMAKE_REQUIRED_INCLUDES ${LIBB2_INCLUDE_DIR})
@@ -708,6 +728,7 @@
 int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
 
 LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
+LA_CHECK_INCLUDE_FILE("fnmatch.h" HAVE_FNMATCH_H)
 LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
 LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
 LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
@@ -745,6 +766,7 @@
 LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
 LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
 LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
+LA_CHECK_INCLUDE_FILE("sys/queue.h" HAVE_SYS_QUEUE_H)
 LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H)
 LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
 LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
@@ -764,9 +786,9 @@
 LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
 LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
 IF(ENABLE_CNG)
-  LA_CHECK_INCLUDE_FILE("Bcrypt.h" HAVE_BCRYPT_H)
+  LA_CHECK_INCLUDE_FILE("bcrypt.h" HAVE_BCRYPT_H)
   IF(HAVE_BCRYPT_H)
-    LIST(APPEND ADDITIONAL_LIBS "Bcrypt")
+    LIST(APPEND ADDITIONAL_LIBS "bcrypt")
   ENDIF(HAVE_BCRYPT_H)
 ELSE(ENABLE_CNG)
   UNSET(HAVE_BCRYPT_H CACHE)
@@ -842,6 +864,10 @@
   IF(OPENSSL_FOUND)
     SET(HAVE_LIBCRYPTO 1)
     INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
+    SET(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
+    SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
+    LA_CHECK_INCLUDE_FILE("openssl/evp.h" HAVE_OPENSSL_EVP_H)
+    CHECK_FUNCTION_EXISTS(PKCS5_PBKDF2_HMAC_SHA1 HAVE_PKCS5_PBKDF2_HMAC_SHA1)
   ENDIF(OPENSSL_FOUND)
 ELSE()
   SET(OPENSSL_FOUND FALSE) # Override cached value
@@ -1379,6 +1405,7 @@
 CHECK_FUNCTION_EXISTS_GLIBC(fchown HAVE_FCHOWN)
 CHECK_FUNCTION_EXISTS_GLIBC(fcntl HAVE_FCNTL)
 CHECK_FUNCTION_EXISTS_GLIBC(fdopendir HAVE_FDOPENDIR)
+CHECK_FUNCTION_EXISTS_GLIBC(fnmatch HAVE_FNMATCH)
 CHECK_FUNCTION_EXISTS_GLIBC(fork HAVE_FORK)
 CHECK_FUNCTION_EXISTS_GLIBC(fstat HAVE_FSTAT)
 CHECK_FUNCTION_EXISTS_GLIBC(fstatat HAVE_FSTATAT)
@@ -1391,6 +1418,7 @@
 CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
 CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
 CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE)
 CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
 CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
 CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
@@ -1443,12 +1471,12 @@
 CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
 CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
 CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
-CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
 CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
 CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
-CHECK_FUNCTION_EXISTS_GLIBC(_gmtime64_s HAVE__GMTIME64_S)
-CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
-CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
+CHECK_SYMBOL_EXISTS(ctime_s "time.h" HAVE_CTIME_S)
+CHECK_SYMBOL_EXISTS(gmtime_s "time.h" HAVE_GMTIME_S)
+CHECK_SYMBOL_EXISTS(localtime_s "time.h" HAVE_LOCALTIME_S)
+CHECK_SYMBOL_EXISTS(_mkgmtime "time.h" HAVE__MKGMTIME)
 
 SET(CMAKE_REQUIRED_LIBRARIES "")
 CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH)
@@ -1491,7 +1519,6 @@
   "#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
   HAVE_READLINKAT)
 
-
 # To verify major(), we need to both include the header
 # of interest and verify that the result can be linked.
 # CHECK_FUNCTION_EXISTS doesn't accept a header argument,
@@ -1503,20 +1530,6 @@
   "#include <sys/sysmacros.h>\nint main() { return major(256); }"
   MAJOR_IN_SYSMACROS)
 
-IF(ENABLE_LZMA)
-CMAKE_PUSH_CHECK_STATE()
-SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
-SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
-
-CHECK_C_SOURCE_COMPILES(
-  "#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
-  HAVE_LZMA_STREAM_ENCODER_MT)
-
-CMAKE_POP_CHECK_STATE()
-ELSE()
-  SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
-ENDIF(ENABLE_LZMA)
-
 IF(HAVE_STRERROR_R)
   SET(HAVE_DECL_STRERROR_R 1)
 ENDIF(HAVE_STRERROR_R)
@@ -1578,7 +1591,7 @@
 #
 #
 CHECK_STRUCT_HAS_MEMBER("struct tm" tm_sec
-    "sys/types.h;sys/time.h;time.h" TIME_WITH_SYS_TIME)
+    "sys/types.h;sys/time.h;time.h" HAVE_SYS_TIME_H)
 
 CHECK_TYPE_SIZE(dev_t       DEV_T)
 IF(NOT HAVE_DEV_T)
@@ -2076,6 +2089,7 @@
 add_subdirectory(cat)
 add_subdirectory(tar)
 add_subdirectory(cpio)
+add_subdirectory(unzip)
 ENDIF()
 
 install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmlibarchive)
diff --git a/Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake b/Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake
index a916395..aa40485 100644
--- a/Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake
+++ b/Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake
@@ -7,7 +7,7 @@
 set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(MBEDTLS DEFAULT_MSG
+find_package_handle_standard_args(MbedTLS DEFAULT_MSG
     MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
 
 mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
index e44a514..493c388 100644
--- a/Utilities/cmlibarchive/build/cmake/config.h.in
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -38,6 +38,9 @@
 /* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1
 
+/* MD5 via ARCHIVE_CRYPTO_MD5_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_MBEDTLS 1
+
 /* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_MD5_NETTLE 1
 
@@ -53,6 +56,9 @@
 /* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_RMD160_NETTLE 1
 
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_MBEDTLS 1
+
 /* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */
 #cmakedefine ARCHIVE_CRYPTO_RMD160_OPENSSL 1
 
@@ -62,6 +68,9 @@
 /* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1
 
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_MBEDTLS 1
+
 /* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA1_NETTLE 1
 
@@ -83,6 +92,9 @@
 /* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1
 
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_MBEDTLS 1
+
 /* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA256_NETTLE 1
 
@@ -104,6 +116,9 @@
 /* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1
 
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_MBEDTLS 1
+
 /* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA384_NETTLE 1
 
@@ -125,6 +140,9 @@
 /* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1
 
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_MBEDTLS 1
+
 /* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA512_NETTLE 1
 
@@ -155,6 +173,9 @@
 /* Version number of bsdcat */
 #cmakedefine BSDCAT_VERSION_STRING "@BSDCAT_VERSION_STRING@"
 
+/* Version number of bsdunzip */
+#cmakedefine BSDUNZIP_VERSION_STRING "@BSDUNZIP_VERSION_STRING@"
+
 /* Define to 1 if you have the `acl_create_entry' function. */
 #cmakedefine HAVE_ACL_CREATE_ENTRY 1
 
@@ -197,7 +218,7 @@
 /* Define to 1 if you have the <attr/xattr.h> header file. */
 #cmakedefine HAVE_ATTR_XATTR_H 1
 
-/* Define to 1 if you have the <Bcrypt.h> header file. */
+/* Define to 1 if you have the <bcrypt.h> header file. */
 #cmakedefine HAVE_BCRYPT_H 1
 
 /* Define to 1 if you have the <bsdxml.h> header file. */
@@ -357,6 +378,12 @@
 /* Define to 1 if you have the `flistxattr' function. */
 #cmakedefine HAVE_FLISTXATTR 1
 
+/* Define to 1 if you have the `fnmatch' function. */
+#cmakedefine HAVE_FNMATCH 1
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#cmakedefine HAVE_FNMATCH_H 1
+
 /* Define to 1 if you have the `fork' function. */
 #cmakedefine HAVE_FORK 1
 
@@ -405,6 +432,9 @@
 /* Define to 1 if you have the `getgrnam_r' function. */
 #cmakedefine HAVE_GETGRNAM_R 1
 
+/* Define to 1 if you have the `getline' function. */
+#cmakedefine HAVE_GETLINE 1
+
 /* Define to 1 if you have the `getpid' function. */
 #cmakedefine HAVE_GETPID 1
 
@@ -611,6 +641,15 @@
 /* Define to 1 if you have the <lzo/lzoconf.h> header file. */
 #cmakedefine HAVE_LZO_LZOCONF_H 1
 
+/* Define to 1 if you have the <mbedtls/aes.h> header file. */
+#cmakedefine HAVE_MBEDTLS_AES_H 1
+
+/* Define to 1 if you have the <mbedtls/md.h> header file. */
+#cmakedefine HAVE_MBEDTLS_MD_H 1
+
+/* Define to 1 if you have the <mbedtls/pkcs5.h> header file. */
+#cmakedefine HAVE_MBEDTLS_PKCS5_H 1
+
 /* Define to 1 if you have the `mbrtowc' function. */
 #cmakedefine HAVE_MBRTOWC 1
 
@@ -662,6 +701,9 @@
 /* Define to 1 if you have the `openat' function. */
 #cmakedefine HAVE_OPENAT 1
 
+/* Define to 1 if you have the <openssl/evp.h> header file. */
+#cmakedefine HAVE_OPENSSL_EVP_H 1
+
 /* Define to 1 if you have the <paths.h> header file. */
 #cmakedefine HAVE_PATHS_H 1
 
@@ -771,6 +813,12 @@
 /* Define to 1 if you have the `strrchr' function. */
 #cmakedefine HAVE_STRRCHR 1
 
+/* Define to 1 if the system has the type `struct statfs'. */
+#cmakedefine HAVE_STRUCT_STATFS 1
+
+/* Define to 1 if `f_iosize' is a member of `struct statfs'. */
+#cmakedefine HAVE_STRUCT_STATFS_F_IOSIZE 1
+
 /* Define to 1 if `f_namemax' is a member of `struct statfs'. */
 #cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1
 
@@ -854,6 +902,9 @@
 /* Define to 1 if you have the <sys/poll.h> header file. */
 #cmakedefine HAVE_SYS_POLL_H 1
 
+/* Define to 1 if you have the <sys/queue.h> header file. */
+#cmakedefine HAVE_SYS_QUEUE_H 1
+
 /* Define to 1 if you have the <sys/richacl.h> header file. */
 #cmakedefine HAVE_SYS_RICHACL_H 1
 
@@ -993,8 +1044,8 @@
 /* Define to 1 if you have the <zstd.h> header file. */
 #cmakedefine HAVE_ZSTD_H 1
 
-/* Define to 1 if you have the `_ctime64_s' function. */
-#cmakedefine HAVE__CTIME64_S 1
+/* Define to 1 if you have the `ctime_s' function. */
+#cmakedefine HAVE_CTIME_S 1
 
 /* Define to 1 if you have the `_fseeki64' function. */
 #cmakedefine HAVE__FSEEKI64 1
@@ -1002,14 +1053,14 @@
 /* Define to 1 if you have the `_get_timezone' function. */
 #cmakedefine HAVE__GET_TIMEZONE 1
 
-/* Define to 1 if you have the `_gmtime64_s' function. */
-#cmakedefine HAVE__GMTIME64_S 1
+/* Define to 1 if you have the `gmtime_s' function. */
+#cmakedefine HAVE_GMTIME_S 1
 
-/* Define to 1 if you have the `_localtime64_s' function. */
-#cmakedefine HAVE__LOCALTIME64_S 1
+/* Define to 1 if you have the `localtime_s' function. */
+#cmakedefine HAVE_LOCALTIME_S 1
 
-/* Define to 1 if you have the `_mkgmtime64' function. */
-#cmakedefine HAVE__MKGMTIME64 1
+/* Define to 1 if you have the `_mkgmtime' function. */
+#cmakedefine HAVE__MKGMTIME 1
 
 /* Define as const if the declaration of iconv() needs const. */
 #define ICONV_CONST @ICONV_CONST@
diff --git a/Utilities/cmlibarchive/build/version b/Utilities/cmlibarchive/build/version
index 1af1bec..414ae6d 100644
--- a/Utilities/cmlibarchive/build/version
+++ b/Utilities/cmlibarchive/build/version
@@ -1 +1 @@
-3006002
+3007002
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
index e820853..ac0bd2c 100644
--- a/Utilities/cmlibarchive/libarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -252,10 +252,12 @@
 
 IF(0) # CMake does not build libarchive's full package.
 # Libarchive is a shared library
-ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
-TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
-TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
-SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
+IF(BUILD_SHARED_LIBS)
+  ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
+  TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
+  TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
+  SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
+ENDIF(BUILD_SHARED_LIBS)
 
 # archive_static is a static library
 ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
@@ -263,13 +265,19 @@
 SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
   LIBARCHIVE_STATIC)
 # On Posix systems, libarchive.so and libarchive.a can co-exist.
-IF(NOT WIN32 OR CYGWIN)
+IF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
   SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
-ENDIF(NOT WIN32 OR CYGWIN)
+ENDIF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
 
 IF(ENABLE_INSTALL)
   # How to install the libraries
-  INSTALL(TARGETS archive archive_static
+  IF(BUILD_SHARED_LIBS)
+    INSTALL(TARGETS archive
+            RUNTIME DESTINATION bin
+            LIBRARY DESTINATION lib
+            ARCHIVE DESTINATION lib)
+  ENDIF(BUILD_SHARED_LIBS)
+  INSTALL(TARGETS archive_static
           RUNTIME DESTINATION bin
           LIBRARY DESTINATION lib
           ARCHIVE DESTINATION lib)
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index 180f3e4..a89f33b 100644
--- a/Utilities/cmlibarchive/libarchive/archive.h
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -36,7 +36,7 @@
  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006002
+#define	ARCHIVE_VERSION_NUMBER 3007002
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -154,7 +154,7 @@
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.6.2"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.7.2"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest.c b/Utilities/cmlibarchive/libarchive/archive_digest.c
index 3361b19..3776831 100644
--- a/Utilities/cmlibarchive/libarchive/archive_digest.c
+++ b/Utilities/cmlibarchive/libarchive/archive_digest.c
@@ -36,6 +36,11 @@
 #error Cannot use both OpenSSL and libmd.
 #endif
 
+/* Common in other bcrypt implementations, but missing from VS2008. */
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
+#endif
+
 /*
  * Message digest functions for Windows platform.
  */
@@ -48,6 +53,26 @@
 /*
  * Initialize a Message digest.
  */
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+static int
+win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
+{
+	NTSTATUS status;
+	ctx->valid = 0;
+
+	status = BCryptOpenAlgorithmProvider(&ctx->hAlg, algo, NULL, 0);
+	if (!BCRYPT_SUCCESS(status))
+		return (ARCHIVE_FAILED);
+	status = BCryptCreateHash(ctx->hAlg, &ctx->hHash, NULL, 0, NULL, 0, 0);
+	if (!BCRYPT_SUCCESS(status)) {
+		BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
+		return (ARCHIVE_FAILED);
+	}
+
+	ctx->valid = 1;
+	return (ARCHIVE_OK);
+}
+#else
 static int
 win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
 {
@@ -70,6 +95,7 @@
 	ctx->valid = 1;
 	return (ARCHIVE_OK);
 }
+#endif
 
 /*
  * Update a Message digest.
@@ -81,23 +107,37 @@
 	if (!ctx->valid)
 		return (ARCHIVE_FAILED);
 
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	BCryptHashData(ctx->hHash,
+		      (PUCHAR)(uintptr_t)buf,
+		      (ULONG)len, 0);
+#else
 	CryptHashData(ctx->hash,
 		      (unsigned char *)(uintptr_t)buf,
 		      (DWORD)len, 0);
+#endif
 	return (ARCHIVE_OK);
 }
 
 static int
 win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
 {
+#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
 	DWORD siglen = (DWORD)bufsize;
+#endif
 
 	if (!ctx->valid)
 		return (ARCHIVE_FAILED);
 
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
+	BCryptDestroyHash(ctx->hHash);
+	BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
+#else
 	CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
 	CryptDestroyHash(ctx->hash);
 	CryptReleaseContext(ctx->cryptProv, 0);
+#endif
 	ctx->valid = 0;
 	return (ARCHIVE_OK);
 }
@@ -276,7 +316,11 @@
 static int
 __archive_md5init(archive_md5_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
+#endif
 }
 
 static int
@@ -659,7 +703,11 @@
 static int
 __archive_sha1init(archive_sha1_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
+#endif
 }
 
 static int
@@ -919,7 +967,11 @@
 static int
 __archive_sha256init(archive_sha256_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
+#endif
 }
 
 static int
@@ -1155,7 +1207,11 @@
 static int
 __archive_sha384init(archive_sha384_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
+#endif
 }
 
 static int
@@ -1415,7 +1471,11 @@
 static int
 __archive_sha512init(archive_sha512_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
+#endif
 }
 
 static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest_private.h b/Utilities/cmlibarchive/libarchive/archive_digest_private.h
index 9b3bd66..339b4ed 100644
--- a/Utilities/cmlibarchive/libarchive/archive_digest_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_digest_private.h
@@ -164,6 +164,15 @@
   defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
   defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
   defined(ARCHIVE_CRYPTO_SHA512_WIN)
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* don't use bcrypt when XP needs to be supported */
+#include <bcrypt.h>
+typedef struct {
+  int   valid;
+  BCRYPT_ALG_HANDLE  hAlg;
+  BCRYPT_HASH_HANDLE hHash;
+} Digest_CTX;
+#else
 #include <windows.h>
 #include <wincrypt.h>
 typedef struct {
@@ -172,6 +181,7 @@
   HCRYPTHASH  hash;
 } Digest_CTX;
 #endif
+#endif
 
 /* typedefs */
 #if defined(ARCHIVE_CRYPTO_MD5_LIBC)
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index 91ef0c9..0e4ccbb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -30,7 +30,7 @@
 #define	ARCHIVE_ENTRY_H_INCLUDED
 
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006002
+#define	ARCHIVE_VERSION_NUMBER 3007002
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
diff --git a/Utilities/cmlibarchive/libarchive/archive_getdate.c b/Utilities/cmlibarchive/libarchive/archive_getdate.c
index 5b0b775..fc9516e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_getdate.c
+++ b/Utilities/cmlibarchive/libarchive/archive_getdate.c
@@ -700,13 +700,9 @@
 	time_t		Julian;
 	int		i;
 	struct tm	*ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	if (Year < 69)
 		Year += 2000;
@@ -733,15 +729,10 @@
 	Julian *= DAY;
 	Julian += Timezone;
 	Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &Julian) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&Julian, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Julian;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&Julian);
 #endif
@@ -757,36 +748,21 @@
 	time_t		StartDay;
 	time_t		FutureDay;
 	struct tm	*ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
-
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&Start, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Start;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&Start);
 #endif
 	StartDay = (ltime->tm_hour + 1) % 24;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &Future) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&Future, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Future;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&Future);
 #endif
@@ -801,24 +777,15 @@
 {
 	struct tm	*tm;
 	time_t	t, now;
-#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__GMTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	t = Start - zone;
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+	tm = gmtime_s(&tmbuf, &t) ? NULL : &tmbuf;
+#elif defined(HAVE_GMTIME_R)
 	tm = gmtime_r(&t, &tmbuf);
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = t;
-	terr = _gmtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		tm = NULL;
-	else
-		tm = &tmbuf;
 #else
 	tm = gmtime(&t);
 #endif
@@ -837,25 +804,16 @@
 	struct tm	*tm;
 	time_t	Month;
 	time_t	Year;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	if (RelMonth == 0)
 		return 0;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	tm = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	tm = localtime_r(&Start, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Start;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		tm = NULL;
-	else
-		tm = &tmbuf;
 #else
 	tm = localtime(&Start);
 #endif
@@ -995,10 +953,6 @@
 	time_t		Start;
 	time_t		tod;
 	long		tzone;
-#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	/* Clear out the parsed token array. */
 	memset(tokens, 0, sizeof(tokens));
@@ -1007,36 +961,26 @@
 	gds = &_gds;
 
 	/* Look up the current time. */
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	tm = localtime_s(&local, &now) ? NULL : &local;
+#elif defined(HAVE_LOCALTIME_R)
 	tm = localtime_r(&now, &local);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = now;
-	terr = _localtime64_s(&local, &tmptime);
-	if (terr)
-		tm = NULL;
-	else
-		tm = &local;
 #else
 	memset(&local, 0, sizeof(local));
 	tm = localtime(&now);
 #endif
 	if (tm == NULL)
 		return -1;
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
+#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S)
 	local = *tm;
 #endif
 
 	/* Look up UTC if we can and use that to determine the current
 	 * timezone offset. */
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+	gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
+#elif defined(HAVE_GMTIME_R)
 	gmt_ptr = gmtime_r(&now, &gmt);
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = now;
-	terr = _gmtime64_s(&gmt, &tmptime);
-	if (terr)
-		gmt_ptr = NULL;
-	else
-		gmt_ptr = &gmt;
 #else
 	memset(&gmt, 0, sizeof(gmt));
 	gmt_ptr = gmtime(&now);
@@ -1078,15 +1022,10 @@
 	 * time components instead of the local timezone. */
 	if (gds->HaveZone && gmt_ptr != NULL) {
 		now -= gds->Timezone;
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+		gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
+#elif defined(HAVE_GMTIME_R)
 		gmt_ptr = gmtime_r(&now, &gmt);
-#elif defined(HAVE__GMTIME64_S)
-		tmptime = now;
-		terr = _gmtime64_s(&gmt, &tmptime);
-		if (terr)
-			gmt_ptr = NULL;
-		else
-			gmt_ptr = &gmt;
 #else
 		gmt_ptr = gmtime(&now);
 #endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac.c b/Utilities/cmlibarchive/libarchive/archive_hmac.c
index 012fe15..edb3bf5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_hmac.c
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac.c
@@ -231,15 +231,20 @@
 __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
 {
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
-	OSSL_PARAM params[2];
+	EVP_MAC *mac;
 
-	EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+	char sha1[] = "SHA1";
+	OSSL_PARAM params[] = {
+		OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),
+		OSSL_PARAM_END
+	};
+
+	mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
 	*ctx = EVP_MAC_CTX_new(mac);
+	EVP_MAC_free(mac);
 	if (*ctx == NULL)
 		return -1;
-	EVP_MAC_free(mac);
-	params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
-	params[1] = OSSL_PARAM_construct_end();
+
 	EVP_MAC_init(*ctx, key, key_len, params);
 #else
 	*ctx = HMAC_CTX_new();
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac_private.h b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
index 50044a0..d0fda7f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
@@ -77,6 +77,8 @@
 #include <openssl/opensslv.h>
 #include <openssl/hmac.h>
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/params.h>
+
 typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
 
 #else
diff --git a/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h b/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
index ebb0670..8ac4772 100644
--- a/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
@@ -33,7 +33,8 @@
 #include <openssl/evp.h>
 #include <openssl/opensslv.h>
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+    (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
 #include <stdlib.h> /* malloc, free */
 #include <string.h> /* memset */
 static inline EVP_MD_CTX *EVP_MD_CTX_new(void)
diff --git a/Utilities/cmlibarchive/libarchive/archive_random.c b/Utilities/cmlibarchive/libarchive/archive_random.c
index 9d1aa49..a410dc0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_random.c
+++ b/Utilities/cmlibarchive/libarchive/archive_random.c
@@ -51,16 +51,27 @@
 #include <pthread.h>
 #endif
 
-static void arc4random_buf(void *, size_t);
+static void la_arc4random_buf(void *, size_t);
 
 #endif /* HAVE_ARC4RANDOM_BUF */
 
 #include "archive.h"
 #include "archive_random_private.h"
 
-#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* don't use bcrypt when XP needs to be supported */
+#include <bcrypt.h>
+
+/* Common in other bcrypt implementations, but missing from VS2008. */
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
+#endif
+
+#elif defined(HAVE_WINCRYPT_H)
 #include <wincrypt.h>
 #endif
+#endif
 
 #ifndef O_CLOEXEC
 #define O_CLOEXEC	0
@@ -75,6 +86,20 @@
 archive_random(void *buf, size_t nbytes)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
+# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	NTSTATUS status;
+	BCRYPT_ALG_HANDLE hAlg;
+
+	status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0);
+	if (!BCRYPT_SUCCESS(status))
+		return ARCHIVE_FAILED;
+	status = BCryptGenRandom(hAlg, buf, (ULONG)nbytes, 0);
+	BCryptCloseAlgorithmProvider(hAlg, 0);
+	if (!BCRYPT_SUCCESS(status))
+		return ARCHIVE_FAILED;
+
+	return ARCHIVE_OK;
+# else
 	HCRYPTPROV hProv;
 	BOOL success;
 
@@ -92,6 +117,10 @@
 	}
 	/* TODO: Does this case really happen? */
 	return ARCHIVE_FAILED;
+# endif
+#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
+	la_arc4random_buf(buf, nbytes);
+	return ARCHIVE_OK;
 #else
 	arc4random_buf(buf, nbytes);
 	return ARCHIVE_OK;
@@ -256,7 +285,7 @@
 }
 
 static void
-arc4random_buf(void *_buf, size_t n)
+la_arc4random_buf(void *_buf, size_t n)
 {
 	uint8_t *buf = (uint8_t *)_buf;
 	_ARC4_LOCK();
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c b/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
index b4398f1..f16ca5c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
@@ -95,8 +95,13 @@
 	    "archive_read_data_into_fd");
 
 	can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
-	if (!can_lseek)
+	if (!can_lseek) {
 		nulls = calloc(1, nulls_size);
+		if (!nulls) {
+			r = ARCHIVE_FATAL;
+			goto cleanup;
+		}
+	}
 
 	while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
 	    ARCHIVE_OK) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
index c964d3f..ab5306d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
@@ -1678,6 +1678,11 @@
 	else
 		t->current_filesystem->name_max = nm;
 #endif
+	if (t->current_filesystem->name_max == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Cannot determine name_max");
+		return (ARCHIVE_FAILED);
+	}
 #endif /* USE_READDIR_R */
 	return (ARCHIVE_OK);
 }
@@ -1868,8 +1873,17 @@
 
 #if defined(USE_READDIR_R)
 	/* Set maximum filename length. */
+#if defined(HAVE_STATVFS)
+	t->current_filesystem->name_max = svfs.f_namemax;
+#else
 	t->current_filesystem->name_max = sfs.f_namelen;
 #endif
+	if (t->current_filesystem->name_max == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Cannot determine name_max");
+		return (ARCHIVE_FAILED);
+	}
+#endif
 	return (ARCHIVE_OK);
 }
 
@@ -1950,6 +1964,11 @@
 #if defined(USE_READDIR_R)
 	/* Set maximum filename length. */
 	t->current_filesystem->name_max = svfs.f_namemax;
+	if (t->current_filesystem->name_max == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Cannot determine name_max");
+		return (ARCHIVE_FAILED);
+	}
 #endif
 	return (ARCHIVE_OK);
 }
@@ -2004,6 +2023,11 @@
 	else
 		t->current_filesystem->name_max = nm;
 #  endif /* _PC_NAME_MAX */
+	if (t->current_filesystem->name_max == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Cannot determine name_max");
+		return (ARCHIVE_FAILED);
+	}
 #endif /* USE_READDIR_R */
 	return (ARCHIVE_OK);
 }
@@ -2554,7 +2578,11 @@
 #else
 		if (tree_enter_working_dir(t) != 0)
 			return NULL;
+#ifdef HAVE_LSTAT
 		if (lstat(tree_current_access_path(t), &t->lst) != 0)
+#else
+		if (la_stat(tree_current_access_path(t), &t->lst) != 0)
+#endif
 #endif
 			return NULL;
 		t->flags |= hasLstat;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
index f9d1395..f92a78a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
@@ -418,9 +418,19 @@
 	    FILE_FLAG_OPEN_REPARSE_POINT;
 	int ret;
 
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileFlags = flag;
+	h = CreateFile2(path, 0,
+	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+	    OPEN_EXISTING, &createExParams);
+#else
 	h = CreateFileW(path, 0,
 	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 	    OPEN_EXISTING, flag, NULL);
+#endif
 	if (h == INVALID_HANDLE_VALUE) {
 		la_dosmaperr(GetLastError());
 		return (-1);
@@ -1067,16 +1077,29 @@
 	if (archive_entry_filetype(entry) == AE_IFREG &&
 	    archive_entry_size(entry) > 0) {
 		DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 		if (t->async_io)
 			flags |= FILE_FLAG_OVERLAPPED;
 		if (t->direct_io)
 			flags |= FILE_FLAG_NO_BUFFERING;
 		else
 			flags |= FILE_FLAG_SEQUENTIAL_SCAN;
+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		ZeroMemory(&createExParams, sizeof(createExParams));
+		createExParams.dwSize = sizeof(createExParams);
+		createExParams.dwFileFlags = flags;
+		t->entry_fh = CreateFile2(tree_current_access_path(t),
+		    GENERIC_READ,
+		    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+		    OPEN_EXISTING, &createExParams);
+#else
 		t->entry_fh = CreateFileW(tree_current_access_path(t),
 		    GENERIC_READ,
 		    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
 		    NULL, OPEN_EXISTING, flags, NULL);
+#endif
 		if (t->entry_fh == INVALID_HANDLE_VALUE) {
 			la_dosmaperr(GetLastError());
 			archive_set_error(&a->archive, errno,
@@ -1547,6 +1570,9 @@
 {
 	HANDLE handle;
 	int r = 0;
+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 	if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
 		return (0);
@@ -1560,8 +1586,16 @@
 	if ((t->flags & needsRestoreTimes) == 0)
 		return (r);
 
+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
+	handle = CreateFile2(rt->full_path, FILE_WRITE_ATTRIBUTES,
+		    0, OPEN_EXISTING, &createExParams);
+#else
 	handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
 		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+#endif
 	if (handle == INVALID_HANDLE_VALUE) {
 		errno = EINVAL;
 		return (-1);
@@ -2046,12 +2080,24 @@
 	HANDLE h;
 	int r;
 	DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
-	
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
+
 	if (sim_lstat && tree_current_is_physical_link(t))
 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileFlags = flag;
+	h = CreateFile2(tree_current_access_path(t), 0,
+	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+	    OPEN_EXISTING, &createExParams);
+#else
 	h = CreateFileW(tree_current_access_path(t), 0,
 	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 	    OPEN_EXISTING, flag, NULL);
+#endif
 	if (h == INVALID_HANDLE_VALUE) {
 		la_dosmaperr(GetLastError());
 		t->tree_errno = errno;
@@ -2257,7 +2303,10 @@
 		} else {
 			WIN32_FIND_DATAW findData;
 			DWORD flag, desiredAccess;
-	
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
+
 			h = FindFirstFileW(path, &findData);
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
@@ -2279,9 +2328,18 @@
 			} else
 				desiredAccess = GENERIC_READ;
 
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			ZeroMemory(&createExParams, sizeof(createExParams));
+			createExParams.dwSize = sizeof(createExParams);
+			createExParams.dwFileFlags = flag;
+			h = CreateFile2(path, desiredAccess,
+			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+			    OPEN_EXISTING, &createExParams);
+#else
 			h = CreateFileW(path, desiredAccess,
 			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 			    OPEN_EXISTING, flag, NULL);
+#endif
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
 				archive_set_error(&a->archive, errno,
@@ -2342,9 +2400,19 @@
 		if (fd >= 0) {
 			h = (HANDLE)_get_osfhandle(fd);
 		} else {
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+			ZeroMemory(&createExParams, sizeof(createExParams));
+			createExParams.dwSize = sizeof(createExParams);
+			createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
+			h = CreateFile2(path, GENERIC_READ,
+			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+			    OPEN_EXISTING, &createExParams);
+#else
 			h = CreateFileW(path, GENERIC_READ,
 			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 			    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+#endif
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
 				archive_set_error(&a->archive, errno,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_file.c b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
index 101dae6..03719e8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
@@ -154,10 +154,10 @@
 #ifdef __ANDROID__
         /* fileno() isn't safe on all platforms ... see above. */
 	if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
-#elif HAVE_FSEEKO
-	if (fseeko(mine->f, skip, SEEK_CUR) != 0)
 #elif HAVE__FSEEKI64
 	if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
+#elif HAVE_FSEEKO
+	if (fseeko(mine->f, skip, SEEK_CUR) != 0)
 #else
 	if (fseek(mine->f, skip, SEEK_CUR) != 0)
 #endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
index b2db4cb..162b79d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
@@ -255,6 +255,27 @@
 Without this option, only the contents of
 the first concatenated archive would be read.
 .El
+.It Format zip
+.Bl -tag -compact -width indent
+.It Cm compat-2x
+Libarchive 2.x incorrectly encoded Unicode filenames on
+some platforms.
+This option mimics the libarchive 2.x filename handling
+so that such archives can be read correctly.
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file names.
+.It Cm ignorecrc32
+Skip the CRC32 check.
+Mostly used for testing.
+.It Cm mac-ext
+Support Mac OS metadata extension that records data in special
+files beginning with a period and underscore.
+Defaults to enabled on Mac OS, disabled on other platforms.
+Use
+.Cm !mac-ext
+to disable.
+.El
 .El
 .\"
 .Sh ERRORS
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
index a5243af..9e5f6d9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
@@ -230,7 +230,7 @@
 
 	/* Empty our output buffer. */
 	state->stream.next_out = state->out_block;
-	state->stream.avail_out = state->out_block_size;
+	state->stream.avail_out = (uint32_t)state->out_block_size;
 
 	/* Try to fill the output buffer. */
 	for (;;) {
@@ -288,7 +288,7 @@
 			return (ARCHIVE_FATAL);
 		}
 		state->stream.next_in = (char *)(uintptr_t)read_buf;
-		state->stream.avail_in = ret;
+		state->stream.avail_in = (uint32_t)ret;
 		/* There is no more data, return whatever we have. */
 		if (ret == 0) {
 			state->eof = 1;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
index 1e99542..d0fc1a8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
@@ -584,7 +584,7 @@
 		    state->out_block + prefix64k, (int)compressed_size,
 		    state->flags.block_maximum_size,
 		    state->out_block,
-		    prefix64k);
+		    (int)prefix64k);
 #else
 		uncompressed_size = LZ4_decompress_safe_withPrefix64k(
 		    read_buf + 4,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
index c66c247..802165c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
@@ -41,6 +41,7 @@
 #endif
 
 #include "archive.h"
+#include "archive_entry.h"
 #include "archive_private.h"
 #include "archive_read_private.h"
 
@@ -61,12 +62,17 @@
 #define ST_UUEND	2
 #define ST_READ_BASE64	3
 #define ST_IGNORE	4
+	mode_t		mode;
+	int		mode_set;
+	char		*name;
 };
 
 static int	uudecode_bidder_bid(struct archive_read_filter_bidder *,
 		    struct archive_read_filter *filter);
 static int	uudecode_bidder_init(struct archive_read_filter *);
 
+static int	uudecode_read_header(struct archive_read_filter *,
+		    struct archive_entry *entry);
 static ssize_t	uudecode_filter_read(struct archive_read_filter *,
 		    const void **);
 static int	uudecode_filter_close(struct archive_read_filter *);
@@ -359,6 +365,7 @@
 uudecode_reader_vtable = {
 	.read = uudecode_filter_read,
 	.close = uudecode_filter_close,
+	.read_header = uudecode_read_header
 };
 
 static int
@@ -389,6 +396,8 @@
 	uudecode->in_allocated = IN_BUFF_SIZE;
 	uudecode->out_buff = out_buff;
 	uudecode->state = ST_FIND_HEAD;
+	uudecode->mode_set = 0;
+	uudecode->name = NULL;
 	self->vtable = &uudecode_reader_vtable;
 
 	return (ARCHIVE_OK);
@@ -434,6 +443,22 @@
 	return (ARCHIVE_OK);
 }
 
+static int
+uudecode_read_header(struct archive_read_filter *self, struct archive_entry *entry)
+{
+
+	struct uudecode *uudecode;
+	uudecode = (struct uudecode *)self->data;
+
+	if (uudecode->mode_set != 0)
+		archive_entry_set_mode(entry, S_IFREG | uudecode->mode);
+
+	if (uudecode->name != NULL)
+		archive_entry_set_pathname(entry, uudecode->name);
+
+	return (ARCHIVE_OK);
+}
+
 static ssize_t
 uudecode_filter_read(struct archive_read_filter *self, const void **buff)
 {
@@ -443,7 +468,7 @@
 	ssize_t avail_in, ravail;
 	ssize_t used;
 	ssize_t total;
-	ssize_t len, llen, nl;
+	ssize_t len, llen, nl, namelen;
 
 	uudecode = (struct uudecode *)self->data;
 
@@ -551,6 +576,28 @@
 					uudecode->state = ST_READ_UU;
 				else
 					uudecode->state = ST_READ_BASE64;
+				uudecode->mode = (mode_t)(
+				    ((int)(b[l] - '0') * 64) +
+				    ((int)(b[l+1] - '0') * 8) +
+				     (int)(b[l+2] - '0'));
+				uudecode->mode_set = 1;
+				namelen = len - nl - 4 - l;
+				if (namelen > 1) {
+					if (uudecode->name != NULL)
+						free(uudecode->name);
+					uudecode->name = malloc(namelen + 1);
+			                if (uudecode->name == NULL) {
+					archive_set_error(
+					    &self->archive->archive,
+					    ENOMEM,
+					    "Can't allocate data for uudecode");
+						return (ARCHIVE_FATAL);
+					}
+					strncpy(uudecode->name,
+					    (const char *)(b + l + 4),
+					    namelen);
+					uudecode->name[namelen] = '\0';
+				}
 			}
 			break;
 		case ST_READ_UU:
@@ -683,6 +730,7 @@
 	uudecode = (struct uudecode *)self->data;
 	free(uudecode->in_buff);
 	free(uudecode->out_buff);
+	free(uudecode->name);
 	free(uudecode);
 
 	return (ARCHIVE_OK);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
index 29d4d62..8d20d7c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
@@ -115,9 +115,9 @@
 	unsigned prefix;
 
 	/* Zstd frame magic values */
-	const unsigned zstd_magic = 0xFD2FB528U;
-	const unsigned zstd_magic_skippable_start = 0x184D2A50U;
-	const unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
+	unsigned zstd_magic = 0xFD2FB528U;
+	unsigned zstd_magic_skippable_start = 0x184D2A50U;
+	unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
 
 	(void) self; /* UNUSED */
 
@@ -170,7 +170,7 @@
 zstd_bidder_init(struct archive_read_filter *self)
 {
 	struct private_data *state;
-	const size_t out_block_size = ZSTD_DStreamOutSize();
+	size_t out_block_size = ZSTD_DStreamOutSize();
 	void *out_block;
 	ZSTD_DStream *dstream;
 
@@ -211,6 +211,7 @@
 	ssize_t avail_in;
 	ZSTD_outBuffer out;
 	ZSTD_inBuffer in;
+	size_t ret;
 
 	state = (struct private_data *)self->data;
 
@@ -219,7 +220,7 @@
 	/* Try to fill the output buffer. */
 	while (out.pos < out.size && !state->eof) {
 		if (!state->in_frame) {
-			const size_t ret = ZSTD_initDStream(state->dstream);
+			ret = ZSTD_initDStream(state->dstream);
 			if (ZSTD_isError(ret)) {
 				archive_set_error(&self->archive->archive,
 				    ARCHIVE_ERRNO_MISC,
@@ -249,8 +250,7 @@
 		in.pos = 0;
 
 		{
-			const size_t ret =
-			    ZSTD_decompressStream(state->dstream, &out, &in);
+			ret = ZSTD_decompressStream(state->dstream, &out, &in);
 
 			if (ZSTD_isError(ret)) {
 				archive_set_error(&self->archive->archive,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
index a4d9dcf..0bfbf1f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
@@ -41,6 +41,9 @@
 #ifdef HAVE_ZLIB_H
 #include <cm3p/zlib.h>
 #endif
+#ifdef HAVE_ZSTD_H
+#include <cm3p/zstd.h>
+#endif
 
 #ifdef __clang_analyzer__
 #include <assert.h>
@@ -84,8 +87,11 @@
 #define _7Z_IA64	0x03030401
 #define _7Z_ARM		0x03030501
 #define _7Z_ARMTHUMB	0x03030701
+#define _7Z_ARM64	0xa
 #define _7Z_SPARC	0x03030805
 
+#define _7Z_ZSTD	0x4F71101 /* Copied from https://github.com/mcmilk/7-Zip-zstd.git */
+
 /*
  * 7-Zip header property IDs.
  */
@@ -114,6 +120,30 @@
 #define kEncodedHeader		0x17
 #define kDummy			0x19
 
+// Check that some windows file attribute constants are defined.
+// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
+#ifndef FILE_ATTRIBUTE_READONLY
+#define FILE_ATTRIBUTE_READONLY 0x00000001
+#endif
+
+#ifndef FILE_ATTRIBUTE_HIDDEN
+#define FILE_ATTRIBUTE_HIDDEN 0x00000002
+#endif
+
+#ifndef FILE_ATTRIBUTE_SYSTEM
+#define FILE_ATTRIBUTE_SYSTEM 0x00000004
+#endif
+
+#ifndef FILE_ATTRIBUTE_DIRECTORY
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#endif
+
+// This value is defined in 7zip with the comment "trick for Unix".
+//
+// 7z archives created on unix have this bit set in the high 16 bits of
+// the attr field along with the unix permissions.
+#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000
+
 struct _7z_digests {
 	unsigned char	*defineds;
 	uint32_t	*digests;
@@ -282,6 +312,11 @@
 	z_stream		 stream;
 	int			 stream_valid;
 #endif
+	/* Decoding Zstandard data. */
+#if HAVE_ZSTD_H
+	ZSTD_DStream		 *zstd_dstream;
+	int		         zstdstream_valid;
+#endif
 	/* Decoding PPMd data. */
 	int			 ppmd7_stat;
 	CPpmd7			 ppmd7_context;
@@ -401,6 +436,9 @@
 		    int);
 static void	x86_Init(struct _7zip *);
 static size_t	x86_Convert(struct _7zip *, uint8_t *, size_t);
+static void	arm_Init(struct _7zip *);
+static size_t	arm_Convert(struct _7zip *, uint8_t *, size_t);
+static size_t	arm64_Convert(struct _7zip *, uint8_t *, size_t);
 static ssize_t		Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
 
 
@@ -729,6 +767,37 @@
 		archive_entry_set_size(entry, 0);
 	}
 
+	// These attributes are supported by the windows implementation of archive_write_disk.
+	const int supported_attrs = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
+
+	if (zip_entry->attr & supported_attrs) {
+		char *fflags_text, *ptr;
+		/* allocate for "rdonly,hidden,system," */
+		fflags_text = malloc(22 * sizeof(char));
+		if (fflags_text != NULL) {
+			ptr = fflags_text; 
+			if (zip_entry->attr & FILE_ATTRIBUTE_READONLY) { 
+ 			strcpy(ptr, "rdonly,"); 
+ 			ptr = ptr + 7; 
+ 		} 
+ 		if (zip_entry->attr & FILE_ATTRIBUTE_HIDDEN) { 
+ 			strcpy(ptr, "hidden,"); 
+ 			ptr = ptr + 7; 
+ 		} 
+ 		if (zip_entry->attr & FILE_ATTRIBUTE_SYSTEM) { 
+ 			strcpy(ptr, "system,"); 
+ 			ptr = ptr + 7; 
+ 		} 
+ 		if (ptr > fflags_text) { 
+ 			/* Delete trailing comma */ 
+ 			*(ptr - 1) = '\0'; 
+ 			archive_entry_copy_fflags_text(entry, 
+				fflags_text); 
+ 		} 
+ 		free(fflags_text); 
+		}
+	}
+
 	/* If there's no body, force read_data() to return EOF immediately. */
 	if (zip->entry_bytes_remaining < 1)
 		zip->end_of_entry = 1;
@@ -1034,10 +1103,13 @@
 	case _7Z_COPY:
 	case _7Z_BZ2:
 	case _7Z_DEFLATE:
+	case _7Z_ZSTD:
 	case _7Z_PPMD:
 		if (coder2 != NULL) {
 			if (coder2->codec != _7Z_X86 &&
-			    coder2->codec != _7Z_X86_BCJ2) {
+			    coder2->codec != _7Z_X86_BCJ2 &&
+			    coder2->codec != _7Z_ARM &&
+			    coder2->codec != _7Z_ARM64) {
 				archive_set_error(&a->archive,
 				    ARCHIVE_ERRNO_MISC,
 				    "Unsupported filter %lx for %lx",
@@ -1048,6 +1120,8 @@
 			zip->bcj_state = 0;
 			if (coder2->codec == _7Z_X86)
 				x86_Init(zip);
+			else if (coder2->codec == _7Z_ARM)
+				arm_Init(zip);
 		}
 		break;
 	default:
@@ -1144,6 +1218,12 @@
 				filters[fi].id = LZMA_FILTER_ARMTHUMB;
 				fi++;
 				break;
+#ifdef LZMA_FILTER_ARM64
+			case _7Z_ARM64:
+				filters[fi].id = LZMA_FILTER_ARM64;
+				fi++;
+				break;
+#endif
 			case _7Z_SPARC:
 				filters[fi].id = LZMA_FILTER_SPARC;
 				fi++;
@@ -1229,6 +1309,22 @@
 		    "BZ2 codec is unsupported");
 		return (ARCHIVE_FAILED);
 #endif
+	case _7Z_ZSTD:
+	{
+#if defined(HAVE_ZSTD_H)
+		if (zip->zstdstream_valid) {
+			ZSTD_freeDStream(zip->zstd_dstream);
+			zip->zstdstream_valid = 0;
+		}
+		zip->zstd_dstream = ZSTD_createDStream();
+		zip->zstdstream_valid = 1;
+		break;
+#else
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			"ZSTD codec is unsupported");
+		return (ARCHIVE_FAILED);
+#endif
+	}
 	case _7Z_DEFLATE:
 #ifdef HAVE_ZLIB_H
 		if (zip->stream_valid)
@@ -1299,6 +1395,7 @@
 	case _7Z_IA64:
 	case _7Z_ARM:
 	case _7Z_ARMTHUMB:
+	case _7Z_ARM64:
 	case _7Z_SPARC:
 	case _7Z_DELTA:
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1443,9 +1540,9 @@
 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
 	case _7Z_BZ2:
 		zip->bzstream.next_in = (char *)(uintptr_t)t_next_in;
-		zip->bzstream.avail_in = t_avail_in;
+		zip->bzstream.avail_in = (uint32_t)t_avail_in;
 		zip->bzstream.next_out = (char *)(uintptr_t)t_next_out;
-		zip->bzstream.avail_out = t_avail_out;
+		zip->bzstream.avail_out = (uint32_t)t_avail_out;
 		r = BZ2_bzDecompress(&(zip->bzstream));
 		switch (r) {
 		case BZ_STREAM_END: /* Found end of stream. */
@@ -1495,6 +1592,22 @@
 		t_avail_out = zip->stream.avail_out;
 		break;
 #endif
+#ifdef HAVE_ZSTD_H
+	case _7Z_ZSTD:
+	{
+		ZSTD_inBuffer input = { t_next_in, t_avail_in, 0 }; // src, size, pos
+		ZSTD_outBuffer output = { t_next_out, t_avail_out, 0 }; // dst, size, pos
+
+		size_t const zret = ZSTD_decompressStream(zip->zstd_dstream, &output, &input);
+		if (ZSTD_isError(zret)) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Zstd decompression failed: %s", ZSTD_getErrorName(zret));
+			return ARCHIVE_FAILED;
+		}
+		t_avail_in -= input.pos;
+		t_avail_out -= output.pos;
+		break;
+	}
+#endif
 	case _7Z_PPMD:
 	{
 		uint64_t flush_bytes;
@@ -1579,16 +1692,23 @@
 	/*
 	 * Decord BCJ.
 	 */
-	if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
-		size_t l = x86_Convert(zip, buff, *outbytes);
-		zip->odd_bcj_size = *outbytes - l;
-		if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
-		    o_avail_in && ret != ARCHIVE_EOF) {
-			memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
-			    zip->odd_bcj_size);
-			*outbytes = l;
-		} else
-			zip->odd_bcj_size = 0;
+	if (zip->codec != _7Z_LZMA2) {
+		if (zip->codec2 == _7Z_X86) {
+			size_t l = x86_Convert(zip, buff, *outbytes);
+
+			zip->odd_bcj_size = *outbytes - l;
+			if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
+		    	o_avail_in && ret != ARCHIVE_EOF) {
+				memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
+			    	zip->odd_bcj_size);
+				*outbytes = l;
+			} else
+				zip->odd_bcj_size = 0;
+		} else if (zip->codec2 == _7Z_ARM) {
+			*outbytes = arm_Convert(zip, buff, *outbytes);
+		} else if (zip->codec2 == _7Z_ARM64) {
+			*outbytes = arm64_Convert(zip, buff, *outbytes);
+		}
 	}
 
 	/*
@@ -2612,6 +2732,28 @@
 			entries[i].flg |= HAS_STREAM;
 		/* The high 16 bits of attributes is a posix file mode. */
 		entries[i].mode = entries[i].attr >> 16;
+
+		if (!(entries[i].attr & FILE_ATTRIBUTE_UNIX_EXTENSION)) {
+			// Only windows permissions specified for this entry. Translate to
+			// reasonable corresponding unix permissions.
+
+			if (entries[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
+				if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
+					// Read-only directory.
+					entries[i].mode = AE_IFDIR | 0555;
+				} else {
+					// Read-write directory.
+					entries[i].mode = AE_IFDIR | 0755;
+				}
+			} else if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
+				// Readonly file.
+				entries[i].mode = AE_IFREG | 0444;
+			} else {
+				// Assume read-write file.
+				entries[i].mode = AE_IFREG | 0644;
+			}
+		}
+
 		if (entries[i].flg & HAS_STREAM) {
 			if ((size_t)sindex >= si->ss.unpack_streams)
 				return (-1);
@@ -2652,7 +2794,7 @@
 			}
 			entries[i].ssIndex = -1;
 		}
-		if (entries[i].attr & 0x01)
+		if (entries[i].attr & FILE_ATTRIBUTE_READONLY)
 			entries[i].mode &= ~0222;/* Read only. */
 
 		if ((entries[i].flg & HAS_STREAM) == 0 && indexInFolder == 0) {
@@ -3737,6 +3879,116 @@
 	return (bufferPos);
 }
 
+static void
+arm_Init(struct _7zip *zip)
+{
+	zip->bcj_ip = 8;
+}
+
+static size_t
+arm_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
+{
+	// This function was adapted from
+	// static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+	// in https://git.tukaani.org/xz-embedded.git
+
+	/*
+	 * Branch/Call/Jump (BCJ) filter decoders
+	 *
+	 * Authors: Lasse Collin <lasse.collin@tukaani.org>
+	 *          Igor Pavlov <https://7-zip.org/>
+	 *
+	 * This file has been put into the public domain.
+	 * You can do whatever you want with this file.
+	 */
+
+	size_t i;
+	uint32_t addr;
+
+	for (i = 0; i + 4 <= size; i += 4) {
+		if (buf[i + 3] == 0xEB) {
+			// Calculate the transformed addr.
+			addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
+				| ((uint32_t)buf[i + 2] << 16);
+			addr <<= 2;
+			addr -= zip->bcj_ip + (uint32_t)i;
+			addr >>= 2;
+
+			// Store the transformed addr in buf.
+			buf[i] = (uint8_t)addr;
+			buf[i + 1] = (uint8_t)(addr >> 8);
+			buf[i + 2] = (uint8_t)(addr >> 16);
+		}
+	}
+
+	zip->bcj_ip += (uint32_t)i;
+
+	return i;
+}
+
+static size_t
+arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
+{
+	// This function was adapted from
+	// static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+	// in https://git.tukaani.org/xz-embedded.git
+
+	/*
+	 * Branch/Call/Jump (BCJ) filter decoders
+	 *
+	 * Authors: Lasse Collin <lasse.collin@tukaani.org>
+	 *          Igor Pavlov <https://7-zip.org/>
+	 *
+	 * This file has been put into the public domain.
+	 * You can do whatever you want with this file.
+	 */
+
+	size_t i;
+	uint32_t instr;
+	uint32_t addr;
+
+	for (i = 0; i + 4 <= size; i += 4) {
+		instr = (uint32_t)buf[i]
+			| ((uint32_t)buf[i+1] << 8)
+			| ((uint32_t)buf[i+2] << 16)
+			| ((uint32_t)buf[i+3] << 24);
+
+		if ((instr >> 26) == 0x25) {
+			/* BL instruction */
+			addr = instr - ((zip->bcj_ip + (uint32_t)i) >> 2);
+			instr = 0x94000000 | (addr & 0x03FFFFFF);
+
+			buf[i]   = (uint8_t)instr;
+			buf[i+1] = (uint8_t)(instr >> 8);
+			buf[i+2] = (uint8_t)(instr >> 16);
+			buf[i+3] = (uint8_t)(instr >> 24);
+		} else if ((instr & 0x9F000000) == 0x90000000) {
+			/* ADRP instruction */
+			addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
+
+			/* Only convert values in the range +/-512 MiB. */
+			if ((addr + 0x020000) & 0x1C0000)
+				continue;
+
+			addr -= (zip->bcj_ip + (uint32_t)i) >> 12;
+
+			instr &= 0x9000001F;
+			instr |= (addr & 3) << 29;
+			instr |= (addr & 0x03FFFC) << 3;
+			instr |= (0U - (addr & 0x020000)) & 0xE00000;
+
+			buf[i]   = (uint8_t)instr;
+			buf[i+1] = (uint8_t)(instr >> 8);
+			buf[i+2] = (uint8_t)(instr >> 16);
+			buf[i+3] = (uint8_t)(instr >> 24);
+		}
+	}
+
+	zip->bcj_ip += (uint32_t)i;
+
+	return i;
+}
+
 /*
  * Brought from LZMA SDK.
  *
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
index 6fcfbfc..e57b8c3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
@@ -2294,10 +2294,10 @@
 		 		   (br->cache_buffer << 48) |
 				    ((uint64_t)strm->next_in[1]) << 40 |
 				    ((uint64_t)strm->next_in[0]) << 32 |
-				    ((uint32_t)strm->next_in[3]) << 24 |
-				    ((uint32_t)strm->next_in[2]) << 16 |
-				    ((uint32_t)strm->next_in[5]) << 8 |
-				     (uint32_t)strm->next_in[4];
+				    ((uint64_t)strm->next_in[3]) << 24 |
+				    ((uint64_t)strm->next_in[2]) << 16 |
+				    ((uint64_t)strm->next_in[5]) << 8 |
+				     (uint64_t)strm->next_in[4];
 				strm->next_in += 6;
 				strm->avail_in -= 6;
 				br->cache_avail += 6 * 8;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
index 6b8ae33..9adcfd3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
@@ -441,7 +441,7 @@
 
 	/* Compare name to "TRAILER!!!" to test for end-of-archive. */
 	if (namelength == 11 && strncmp((const char *)h, "TRAILER!!!",
-	    11) == 0) {
+	    10) == 0) {
 		/* TODO: Store file location of start of block. */
 		archive_clear_error(&a->archive);
 		return (ARCHIVE_EOF);
@@ -985,14 +985,14 @@
 static int64_t
 le4(const unsigned char *p)
 {
-	return ((p[0] << 16) + (((int64_t)p[1]) << 24) + (p[2] << 0) + (p[3] << 8));
+	return ((p[0] << 16) | (((int64_t)p[1]) << 24) | (p[2] << 0) | (p[3] << 8));
 }
 
 
 static int64_t
 be4(const unsigned char *p)
 {
-	return ((((int64_t)p[0]) << 24) + (p[1] << 16) + (p[2] << 8) + (p[3]));
+	return ((((int64_t)p[0]) << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
 }
 
 /*
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
index 91b9187..a6219fa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
@@ -1901,7 +1901,7 @@
 	 * NUMBER of RRIP "PX" extension.
 	 * Note: Old mkisofs did not record that FILE SERIAL NUMBER
 	 * in ISO images.
-	 * Note2: xorriso set 0 to the location of a symlink file. 
+	 * Note2: xorriso set 0 to the location of a symlink file.
 	 */
 	if (file->size == 0 && location >= 0) {
 		/* If file->size is zero, its location points wrong place,
@@ -1955,7 +1955,7 @@
 			 * made by makefs is not zero and its location is
 			 * the same as those of next regular file. That is
 			 * the same as hard like file and it causes unexpected
-			 * error. 
+			 * error.
 			 */
 			if (file->size > 0 &&
 			    (file->mode & AE_IFMT) == AE_IFLNK) {
@@ -2747,7 +2747,7 @@
 			 * If directory entries all which are descendant of
 			 * rr_moved are still remaining, expose their.
 			 */
-			if (iso9660->re_files.first != NULL && 
+			if (iso9660->re_files.first != NULL &&
 			    iso9660->rr_moved != NULL &&
 			    iso9660->rr_moved->rr_moved_has_re_only)
 				/* Expose "rr_moved" entry. */
@@ -3182,11 +3182,11 @@
 static time_t
 time_from_tm(struct tm *t)
 {
-#if HAVE_TIMEGM
+#if HAVE__MKGMTIME
+        return _mkgmtime(t);
+#elif HAVE_TIMEGM
         /* Use platform timegm() if available. */
         return (timegm(t));
-#elif HAVE__MKGMTIME64
-        return (_mkgmtime64(t));
 #else
         /* Else use direct calculation using POSIX assumptions. */
         /* First, fix up tm_yday based on the year/month/day. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
index 8b7bf66..1c64b29 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
@@ -1819,7 +1819,7 @@
 		 * remove the statement which will not be executed. */
 #undef bswap16
 #ifndef __has_builtin
-#  define __has_builtin(x) 0
+#define __has_builtin(x) 0
 #endif
 #if defined(_MSC_VER) && _MSC_VER >= 1400  /* Visual Studio */
 #  define bswap16(x) _byteswap_ushort(x)
@@ -1827,7 +1827,7 @@
 /* GCC 4.8 and later has __builtin_bswap16() */
 #  define bswap16(x) __builtin_bswap16(x)
 #elif defined(__clang__) && __has_builtin(__builtin_bswap16)
-/* All clang versions have __builtin_bswap16() */
+/* Newer clang versions have __builtin_bswap16() */
 #  define bswap16(x) __builtin_bswap16(x)
 #else
 #  define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8))
@@ -2012,10 +2012,10 @@
 				    ((uint64_t)strm->next_in[0]) << 48 |
 				    ((uint64_t)strm->next_in[1]) << 40 |
 				    ((uint64_t)strm->next_in[2]) << 32 |
-				    ((uint32_t)strm->next_in[3]) << 24 |
-				    ((uint32_t)strm->next_in[4]) << 16 |
-				    ((uint32_t)strm->next_in[5]) << 8 |
-				     (uint32_t)strm->next_in[6];
+				    ((uint64_t)strm->next_in[3]) << 24 |
+				    ((uint64_t)strm->next_in[4]) << 16 |
+				    ((uint64_t)strm->next_in[5]) << 8 |
+				     (uint64_t)strm->next_in[6];
 				strm->next_in += 7;
 				strm->avail_in -= 7;
 				br->cache_avail += 7 * 8;
@@ -2025,10 +2025,10 @@
 		 		   (br->cache_buffer << 48) |
 				    ((uint64_t)strm->next_in[0]) << 40 |
 				    ((uint64_t)strm->next_in[1]) << 32 |
-				    ((uint32_t)strm->next_in[2]) << 24 |
-				    ((uint32_t)strm->next_in[3]) << 16 |
-				    ((uint32_t)strm->next_in[4]) << 8 |
-				     (uint32_t)strm->next_in[5];
+				    ((uint64_t)strm->next_in[2]) << 24 |
+				    ((uint64_t)strm->next_in[3]) << 16 |
+				    ((uint64_t)strm->next_in[4]) << 8 |
+				     (uint64_t)strm->next_in[5];
 				strm->next_in += 6;
 				strm->avail_in -= 6;
 				br->cache_avail += 6 * 8;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
index 2bc3ba0..a5fa30e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -1280,7 +1280,13 @@
 				mtree->fd = -1;
 				st = NULL;
 			}
-		} else if (lstat(path, st) == -1) {
+		}
+#ifdef HAVE_LSTAT
+		else if (lstat(path, st) == -1)
+#else
+		else if (la_stat(path, st) == -1)
+#endif
+		{
 			st = NULL;
 		}
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
index 41d6cb2..a1c5495 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -1064,7 +1064,7 @@
 		      return (ARCHIVE_FATAL);
 	      }
 	      p = h;
-	      crc32_val = crc32(crc32_val, (const unsigned char *)p, to_read);
+	      crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned int)to_read);
 	      __archive_read_consume(a, to_read);
 	      skip -= to_read;
       }
@@ -1832,13 +1832,9 @@
   struct tm *tm;
   time_t t;
   long nsec;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
   struct tm tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-  errno_t terr;
-  __time64_t tmptime;
-#endif
 
   if (p + 2 > endp)
     return (-1);
@@ -1870,15 +1866,10 @@
         rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
         p++;
       }
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+      tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
       tm = localtime_r(&t, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-      tmptime = t;
-      terr = _localtime64_s(&tmbuf, &tmptime);
-      if (terr)
-        tm = NULL;
-      else
-        tm = &tmbuf;
 #else
       tm = localtime(&t);
 #endif
@@ -3451,7 +3442,7 @@
   prog = calloc(1, sizeof(*prog));
   if (!prog)
     return NULL;
-  prog->fingerprint = crc32(0, bytes, length) | ((uint64_t)length << 32);
+  prog->fingerprint = crc32(0, bytes, (unsigned int)length) | ((uint64_t)length << 32);
 
   if (membr_bits(&br, 1))
   {
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
index aa7b861..7f1efb8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
@@ -2475,7 +2475,7 @@
 		 * `stored_crc32` info filled in. */
 		if(rar->file.stored_crc32 > 0) {
 			rar->file.calculated_crc32 =
-				crc32(rar->file.calculated_crc32, p, to_read);
+				crc32(rar->file.calculated_crc32, p, (unsigned int)to_read);
 		}
 
 		/* Check if the file uses an optional BLAKE2sp checksum
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
index 2732996..61ab29e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
@@ -530,11 +530,11 @@
 static time_t
 time_from_tm(struct tm *t)
 {
-#if HAVE_TIMEGM
+#if HAVE__MKGMTIME
+        return _mkgmtime(t);
+#elif HAVE_TIMEGM
         /* Use platform timegm() if available. */
         return (timegm(t));
-#elif HAVE__MKGMTIME64
-        return (_mkgmtime64(t));
 #else
         /* Else use direct calculation using POSIX assumptions. */
         /* First, fix up tm_yday based on the year/month/day. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
index 330df58..efed86d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
@@ -1127,7 +1127,7 @@
 			x |= p[1] - '0';
 		else
 			return (-1);
-		
+
 		*b++ = x;
 		bsize--;
 		p += 2;
@@ -1139,11 +1139,11 @@
 static time_t
 time_from_tm(struct tm *t)
 {
-#if HAVE_TIMEGM
+#if HAVE__MKGMTIME
+        return _mkgmtime(t);
+#elif HAVE_TIMEGM
         /* Use platform timegm() if available. */
         return (timegm(t));
-#elif HAVE__MKGMTIME64
-        return (_mkgmtime64(t));
 #else
         /* Else use direct calculation using POSIX assumptions. */
         /* First, fix up tm_yday based on the year/month/day. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index e126ae3..e8b20f5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -2186,11 +2186,11 @@
 
 	/* Setup buffer boundaries. */
 	zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff;
-	zip->bzstream.avail_in = in_bytes;
+	zip->bzstream.avail_in = (uint32_t)in_bytes;
 	zip->bzstream.total_in_hi32 = 0;
 	zip->bzstream.total_in_lo32 = 0;
 	zip->bzstream.next_out = (char*) zip->uncompressed_buffer;
-	zip->bzstream.avail_out = zip->uncompressed_buffer_size;
+	zip->bzstream.avail_out = (uint32_t)zip->uncompressed_buffer_size;
 	zip->bzstream.total_out_hi32 = 0;
 	zip->bzstream.total_out_lo32 = 0;
 
@@ -2227,7 +2227,7 @@
 	to_consume = zip->bzstream.total_in_lo32;
 	__archive_read_consume(a, to_consume);
 
-	total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) +
+	total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) |
 	    zip->bzstream.total_out_lo32;
 
 	zip->entry_bytes_remaining -= to_consume;
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index 69458e1..accf526 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -1324,6 +1324,10 @@
 }
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
+# if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#  define GetOEMCP() CP_OEMCP
+# endif
+
 static unsigned
 my_atoi(const char *p)
 {
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c
index 83586b5..0680711 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.c
+++ b/Utilities/cmlibarchive/libarchive/archive_util.c
@@ -42,9 +42,20 @@
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
-#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* don't use bcrypt when XP needs to be supported */
+#include <bcrypt.h>
+
+/* Common in other bcrypt implementations, but missing from VS2008. */
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
+#endif
+
+#elif defined(HAVE_WINCRYPT_H)
 #include <wincrypt.h>
 #endif
+#endif
 #ifdef HAVE_ZLIB_H
 #include <cm3p/zlib.h>
 #endif
@@ -233,14 +244,16 @@
 		L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
 		L'u', L'v', L'w', L'x', L'y', L'z'
 	};
-	HCRYPTPROV hProv;
 	struct archive_wstring temp_name;
 	wchar_t *ws;
 	DWORD attr;
 	wchar_t *xp, *ep;
 	int fd;
-
-	hProv = (HCRYPTPROV)NULL;
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	BCRYPT_ALG_HANDLE hAlg = NULL;
+#else
+	HCRYPTPROV hProv = (HCRYPTPROV)NULL;
+#endif
 	fd = -1;
 	ws = NULL;
 
@@ -314,23 +327,42 @@
 			abort();
 	}
 
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM,
+		NULL, 0))) {
+		la_dosmaperr(GetLastError());
+		goto exit_tmpfile;
+	}
+#else
 	if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
 		CRYPT_VERIFYCONTEXT)) {
 		la_dosmaperr(GetLastError());
 		goto exit_tmpfile;
 	}
+#endif
 
 	for (;;) {
 		wchar_t *p;
 		HANDLE h;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 		/* Generate a random file name through CryptGenRandom(). */
 		p = xp;
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+		if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p,
+		    (DWORD)(ep - p)*sizeof(wchar_t), 0))) {
+			la_dosmaperr(GetLastError());
+			goto exit_tmpfile;
+		}
+#else
 		if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
 		    (BYTE*)p)) {
 			la_dosmaperr(GetLastError());
 			goto exit_tmpfile;
 		}
+#endif
 		for (; p < ep; p++)
 			*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
 
@@ -347,6 +379,17 @@
 			/* mkstemp */
 			attr = FILE_ATTRIBUTE_NORMAL;
 		}
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		ZeroMemory(&createExParams, sizeof(createExParams));
+		createExParams.dwSize = sizeof(createExParams);
+		createExParams.dwFileAttributes = attr & 0xFFFF;
+		createExParams.dwFileFlags = attr & 0xFFF00000;
+		h = CreateFile2(ws,
+		    GENERIC_READ | GENERIC_WRITE | DELETE,
+		    0,/* Not share */
+			CREATE_NEW,
+			&createExParams);
+#else
 		h = CreateFileW(ws,
 		    GENERIC_READ | GENERIC_WRITE | DELETE,
 		    0,/* Not share */
@@ -354,6 +397,7 @@
 		    CREATE_NEW,/* Create a new file only */
 		    attr,
 		    NULL);
+#endif
 		if (h == INVALID_HANDLE_VALUE) {
 			/* The same file already exists. retry with
 			 * a new filename. */
@@ -372,8 +416,13 @@
 			break;/* success! */
 	}
 exit_tmpfile:
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	if (hAlg != NULL)
+		BCryptCloseAlgorithmProvider(hAlg, 0);
+#else
 	if (hProv != (HCRYPTPROV)NULL)
 		CryptReleaseContext(hProv, 0);
+#endif
 	free(ws);
 	if (template == temp_name.s)
 		archive_wstring_free(&temp_name);
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.c b/Utilities/cmlibarchive/libarchive/archive_windows.c
index 624e270..ebc5eef 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.c
@@ -234,7 +234,11 @@
 {
 	wchar_t *wpath;
 	HANDLE handle;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
 	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
 	    hTemplateFile);
@@ -242,12 +246,25 @@
 		return (handle);
 	if (GetLastError() != ERROR_PATH_NOT_FOUND)
 		return (handle);
+#endif
 	wpath = __la_win_permissive_name(path);
 	if (wpath == NULL)
-		return (handle);
+		return INVALID_HANDLE_VALUE;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF;
+	createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000;
+	createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F00000;
+	createExParams.lpSecurityAttributes = lpSecurityAttributes;
+	createExParams.hTemplateFile = hTemplateFile;
+	handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode,
+	    dwCreationDisposition, &createExParams);
+#else /* !WINAPI_PARTITION_DESKTOP */
 	handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
 	    hTemplateFile);
+#endif /* !WINAPI_PARTITION_DESKTOP */
 	free(wpath);
 	return (handle);
 }
@@ -305,7 +322,10 @@
 		 * "Permission denied" error.
 		 */
 		attr = GetFileAttributesA(path);
-		if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
+		if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND)
+#endif
+		{
 			ws = __la_win_permissive_name(path);
 			if (ws == NULL) {
 				errno = EINVAL;
@@ -320,7 +340,7 @@
 		}
 		if (attr & FILE_ATTRIBUTE_DIRECTORY) {
 			HANDLE handle;
-
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
 			if (ws != NULL)
 				handle = CreateFileW(ws, 0, 0, NULL,
 				    OPEN_EXISTING,
@@ -333,6 +353,15 @@
 				    FILE_FLAG_BACKUP_SEMANTICS |
 				    FILE_ATTRIBUTE_READONLY,
 					NULL);
+#else /* !WINAPI_PARTITION_DESKTOP */
+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+			ZeroMemory(&createExParams, sizeof(createExParams));
+			createExParams.dwSize = sizeof(createExParams);
+			createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
+			createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
+			handle = CreateFile2(ws, 0, 0,
+				OPEN_EXISTING, &createExParams);
+#endif /* !WINAPI_PARTITION_DESKTOP */
 			free(ws);
 			if (handle == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
index 27626b5..ec3c95c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -310,6 +310,25 @@
 	return (__archive_write_filter(a->filter_first, buff, length));
 }
 
+static int
+__archive_write_filters_flush(struct archive_write *a)
+{
+	struct archive_write_filter *f;
+	int ret, ret1;
+
+	ret = ARCHIVE_OK;
+	for (f = a->filter_first; f != NULL; f = f->next_filter) {
+		if (f->flush != NULL && f->bytes_written > 0) {
+			ret1 = (f->flush)(f);
+			if (ret1 < ret)
+				ret = ret1;
+			if (ret1 < ARCHIVE_WARN)
+				f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
+		}
+	}
+	return (ret);
+}
+
 int
 __archive_write_nulls(struct archive_write *a, size_t length)
 {
@@ -740,6 +759,18 @@
 		return (ARCHIVE_FAILED);
 	}
 
+	/* Flush filters at boundary. */
+	r2 = __archive_write_filters_flush(a);
+	if (r2 == ARCHIVE_FAILED) {
+		return (ARCHIVE_FAILED);
+	}
+	if (r2 == ARCHIVE_FATAL) {
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		return (ARCHIVE_FATAL);
+	}
+	if (r2 < ret)
+		ret = r2;
+
 	/* Format and write header. */
 	r2 = ((a->format_write_header)(a, entry));
 	if (r2 == ARCHIVE_FAILED) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
index 0637e96..9c2144a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
@@ -190,7 +190,7 @@
 
 	memset(&data->stream, 0, sizeof(data->stream));
 	data->stream.next_out = data->compressed;
-	data->stream.avail_out = data->compressed_buffer_size;
+	data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
 	f->write = archive_compressor_bzip2_write;
 
 	/* Initialize compression library */
@@ -244,7 +244,7 @@
 
 	/* Compress input data to output buffer */
 	SET_NEXT_IN(data, buff);
-	data->stream.avail_in = length;
+	data->stream.avail_in = (uint32_t)length;
 	if (drive_compressor(f, data, 0))
 		return (ARCHIVE_FATAL);
 	return (ARCHIVE_OK);
@@ -313,7 +313,7 @@
 				return (ARCHIVE_FATAL);
 			}
 			data->stream.next_out = data->compressed;
-			data->stream.avail_out = data->compressed_buffer_size;
+			data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
 		}
 
 		/* If there's nothing to do, we're done. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
index d404fae..3ed269f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
@@ -352,7 +352,7 @@
 	while (length--) {
 		c = *bp++;
 		state->in_count++;
-		state->cur_fcode = (c << 16) + state->cur_code;
+		state->cur_fcode = (c << 16) | state->cur_code;
 		i = ((c << HSHIFT) ^ state->cur_code);	/* Xor hashing. */
 
 		if (state->hashtab[i] == state->cur_fcode) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
index cf19fad..6ac4503 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
@@ -518,10 +518,10 @@
 	} else {
 		/* The buffer is not compressed. The compressed size was
 		 * bigger than its uncompressed size. */
-		archive_le32enc(data->out, length | 0x80000000);
+		archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
 		data->out += 4;
 		memcpy(data->out, p, length);
-		outsize = length;
+		outsize = (uint32_t)length;
 	}
 	data->out += outsize;
 	if (data->block_checksum) {
@@ -603,10 +603,10 @@
 	} else {
 		/* The buffer is not compressed. The compressed size was
 		 * bigger than its uncompressed size. */
-		archive_le32enc(data->out, length | 0x80000000);
+		archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
 		data->out += 4;
 		memcpy(data->out, p, length);
-		outsize = length;
+		outsize = (uint32_t)length;
 	}
 	data->out += outsize;
 	if (data->block_checksum) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
index 7d36d58..3d6b3d1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
@@ -31,6 +31,9 @@
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -50,10 +53,22 @@
 
 struct private_data {
 	int		 compression_level;
-	int      threads;
+	int		 threads;
+	int		 long_distance;
 #if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+	enum {
+		running,
+		finishing,
+		resetting,
+	} state;
+	int		 frame_per_file;
+	size_t		 min_frame_size;
+	size_t		 max_frame_size;
+	size_t		 cur_frame;
+	size_t		 cur_frame_in;
+	size_t		 cur_frame_out;
+	size_t		 total_in;
 	ZSTD_CStream	*cstream;
-	int64_t		 total_in;
 	ZSTD_outBuffer	 out;
 #else
 	struct archive_write_program_data *pdata;
@@ -67,14 +82,18 @@
 #define CLEVEL_STD_MAX 19 /* without using --ultra */
 #define CLEVEL_MAX 22
 
+#define LONG_STD 27
+
 #define MINVER_NEGCLEVEL 10304
 #define MINVER_MINCLEVEL 10306
+#define MINVER_LONG 10302
 
 static int archive_compressor_zstd_options(struct archive_write_filter *,
 		    const char *, const char *);
 static int archive_compressor_zstd_open(struct archive_write_filter *);
 static int archive_compressor_zstd_write(struct archive_write_filter *,
 		    const void *, size_t);
+static int archive_compressor_zstd_flush(struct archive_write_filter *);
 static int archive_compressor_zstd_close(struct archive_write_filter *);
 static int archive_compressor_zstd_free(struct archive_write_filter *);
 #if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
@@ -103,13 +122,20 @@
 	f->data = data;
 	f->open = &archive_compressor_zstd_open;
 	f->options = &archive_compressor_zstd_options;
+	f->flush = &archive_compressor_zstd_flush;
 	f->close = &archive_compressor_zstd_close;
 	f->free = &archive_compressor_zstd_free;
 	f->code = ARCHIVE_FILTER_ZSTD;
 	f->name = "zstd";
 	data->compression_level = CLEVEL_DEFAULT;
 	data->threads = 0;
+	data->long_distance = 0;
 #if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+	data->frame_per_file = 0;
+	data->min_frame_size = 0;
+	data->max_frame_size = SIZE_MAX;
+	data->cur_frame_in = 0;
+	data->cur_frame_out = 0;
 	data->cstream = ZSTD_createCStream();
 	if (data->cstream == NULL) {
 		free(data);
@@ -147,29 +173,18 @@
 	return (ARCHIVE_OK);
 }
 
-static int string_is_numeric (const char* value)
+static int string_to_number(const char *string, intmax_t *numberp)
 {
-       size_t len = strlen(value);
-       size_t i;
+	char *end;
 
-       if (len == 0) {
-               return (ARCHIVE_WARN);
-       }
-       else if (len == 1 && !(value[0] >= '0' && value[0] <= '9')) {
-               return (ARCHIVE_WARN);
-       }
-       else if (!(value[0] >= '0' && value[0] <= '9') &&
-                value[0] != '-' && value[0] != '+') {
-               return (ARCHIVE_WARN);
-       }
-
-       for (i = 1; i < len; i++) {
-               if (!(value[i] >= '0' && value[i] <= '9')) {
-                       return (ARCHIVE_WARN);
-               }
-       }
-
-       return (ARCHIVE_OK);
+	if (string == NULL || *string == '\0')
+		return (ARCHIVE_WARN);
+	*numberp = strtoimax(string, &end, 10);
+	if (end == string || *end != '\0' || errno == EOVERFLOW) {
+		*numberp = 0;
+		return (ARCHIVE_WARN);
+	}
+	return (ARCHIVE_OK);
 }
 
 /*
@@ -182,13 +197,13 @@
 	struct private_data *data = (struct private_data *)f->data;
 
 	if (strcmp(key, "compression-level") == 0) {
-		int level = atoi(value);
+		intmax_t level;
+		if (string_to_number(value, &level) != ARCHIVE_OK) {
+			return (ARCHIVE_WARN);
+		}
 		/* If we don't have the library, hard-code the max level */
 		int minimum = CLEVEL_MIN;
 		int maximum = CLEVEL_MAX;
-		if (string_is_numeric(value) != ARCHIVE_OK) {
-			return (ARCHIVE_WARN);
-		}
 #if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
 		maximum = ZSTD_maxCLevel();
 #if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
@@ -204,21 +219,65 @@
 		if (level < minimum || level > maximum) {
 			return (ARCHIVE_WARN);
 		}
-		data->compression_level = level;
+		data->compression_level = (int)level;
 		return (ARCHIVE_OK);
 	} else if (strcmp(key, "threads") == 0) {
-		int threads = atoi(value);
-		if (string_is_numeric(value) != ARCHIVE_OK) {
+		intmax_t threads;
+		if (string_to_number(value, &threads) != ARCHIVE_OK) {
 			return (ARCHIVE_WARN);
 		}
-
-		int minimum = 0;
-
-		if (threads < minimum) {
+		if (threads < 0) {
 			return (ARCHIVE_WARN);
 		}
-
-		data->threads = threads;
+		data->threads = (int)threads;
+		return (ARCHIVE_OK);
+#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+	} else if (strcmp(key, "frame-per-file") == 0) {
+		data->frame_per_file = 1;
+		return (ARCHIVE_OK);
+	} else if (strcmp(key, "min-frame-size") == 0) {
+		intmax_t min_frame_size;
+		if (string_to_number(value, &min_frame_size) != ARCHIVE_OK) {
+			return (ARCHIVE_WARN);
+		}
+		if (min_frame_size < 0) {
+			return (ARCHIVE_WARN);
+		}
+		data->min_frame_size = min_frame_size;
+		return (ARCHIVE_OK);
+	} else if (strcmp(key, "max-frame-size") == 0) {
+		intmax_t max_frame_size;
+		if (string_to_number(value, &max_frame_size) != ARCHIVE_OK) {
+			return (ARCHIVE_WARN);
+		}
+		if (max_frame_size < 1024) {
+			return (ARCHIVE_WARN);
+		}
+		data->max_frame_size = max_frame_size;
+		return (ARCHIVE_OK);
+#endif
+	}
+	else if (strcmp(key, "long") == 0) {
+		intmax_t long_distance;
+		if (string_to_number(value, &long_distance) != ARCHIVE_OK) {
+			return (ARCHIVE_WARN);
+		}
+#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR && ZSTD_VERSION_NUMBER >= MINVER_LONG
+		ZSTD_bounds bounds = ZSTD_cParam_getBounds(ZSTD_c_windowLog);
+		if (ZSTD_isError(bounds.error)) {
+			int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
+			if (((int)long_distance) < 10 || (int)long_distance > max_distance)
+				return (ARCHIVE_WARN);
+		} else {
+			if ((int)long_distance < bounds.lowerBound || (int)long_distance > bounds.upperBound)
+				return (ARCHIVE_WARN);
+		}
+#else
+		int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
+		if (((int)long_distance) < 10 || (int)long_distance > max_distance)
+		    return (ARCHIVE_WARN);
+#endif
+		data->long_distance = (int)long_distance;
 		return (ARCHIVE_OK);
 	}
 
@@ -270,6 +329,10 @@
 
 	ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads);
 
+#if ZSTD_VERSION_NUMBER >= MINVER_LONG
+	ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance);
+#endif
+
 	return (ARCHIVE_OK);
 }
 
@@ -281,15 +344,22 @@
     size_t length)
 {
 	struct private_data *data = (struct private_data *)f->data;
-	int ret;
 
-	/* Update statistics */
-	data->total_in += length;
+	return (drive_compressor(f, data, 0, buff, length));
+}
 
-	if ((ret = drive_compressor(f, data, 0, buff, length)) != ARCHIVE_OK)
-		return (ret);
+/*
+ * Flush the compressed stream.
+ */
+static int
+archive_compressor_zstd_flush(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
 
-	return (ARCHIVE_OK);
+	if (data->frame_per_file && data->state == running &&
+	    data->cur_frame_out > data->min_frame_size)
+		data->state = finishing;
+	return (drive_compressor(f, data, 1, NULL, 0));
 }
 
 /*
@@ -300,57 +370,72 @@
 {
 	struct private_data *data = (struct private_data *)f->data;
 
-	/* Finish zstd frame */
-	return drive_compressor(f, data, 1, NULL, 0);
+	if (data->state == running)
+		data->state = finishing;
+	return (drive_compressor(f, data, 1, NULL, 0));
 }
 
 /*
  * Utility function to push input data through compressor,
  * writing full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
  */
 static int
 drive_compressor(struct archive_write_filter *f,
-    struct private_data *data, int finishing, const void *src, size_t length)
+    struct private_data *data, int flush, const void *src, size_t length)
 {
-	ZSTD_inBuffer in = (ZSTD_inBuffer) { src, length, 0 };
+	ZSTD_inBuffer in = { .src = src, .size = length, .pos = 0 };
+	size_t ipos, opos, zstdret = 0;
+	int ret;
 
 	for (;;) {
-		if (data->out.pos == data->out.size) {
-			const int ret = __archive_write_filter(f->next_filter,
-			    data->out.dst, data->out.size);
+		ipos = in.pos;
+		opos = data->out.pos;
+		switch (data->state) {
+		case running:
+			if (in.pos == in.size)
+				return (ARCHIVE_OK);
+			zstdret = ZSTD_compressStream(data->cstream,
+			    &data->out, &in);
+			if (ZSTD_isError(zstdret))
+				goto zstd_fatal;
+			break;
+		case finishing:
+			zstdret = ZSTD_endStream(data->cstream, &data->out);
+			if (ZSTD_isError(zstdret))
+				goto zstd_fatal;
+			if (zstdret == 0)
+				data->state = resetting;
+			break;
+		case resetting:
+			ZSTD_CCtx_reset(data->cstream, ZSTD_reset_session_only);
+			data->cur_frame++;
+			data->cur_frame_in = 0;
+			data->cur_frame_out = 0;
+			data->state = running;
+			break;
+		}
+		data->total_in += in.pos - ipos;
+		data->cur_frame_in += in.pos - ipos;
+		data->cur_frame_out += data->out.pos - opos;
+		if (data->state == running &&
+		    data->cur_frame_in >= data->max_frame_size) {
+			data->state = finishing;
+		}
+		if (data->out.pos == data->out.size ||
+		    (flush && data->out.pos > 0)) {
+			ret = __archive_write_filter(f->next_filter,
+			    data->out.dst, data->out.pos);
 			if (ret != ARCHIVE_OK)
-				return (ARCHIVE_FATAL);
+				goto fatal;
 			data->out.pos = 0;
 		}
-
-		/* If there's nothing to do, we're done. */
-		if (!finishing && in.pos == in.size)
-			return (ARCHIVE_OK);
-
-		{
-			const size_t zstdret = !finishing ?
-			    ZSTD_compressStream(data->cstream, &data->out, &in)
-			    : ZSTD_endStream(data->cstream, &data->out);
-
-			if (ZSTD_isError(zstdret)) {
-				archive_set_error(f->archive,
-				    ARCHIVE_ERRNO_MISC,
-				    "Zstd compression failed: %s",
-				    ZSTD_getErrorName(zstdret));
-				return (ARCHIVE_FATAL);
-			}
-
-			/* If we're finishing, 0 means nothing left to flush */
-			if (finishing && zstdret == 0) {
-				const int ret = __archive_write_filter(f->next_filter,
-				    data->out.dst, data->out.pos);
-				return (ret);
-			}
-		}
 	}
+zstd_fatal:
+	archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+	    "Zstd compression failed: %s",
+	    ZSTD_getErrorName(zstdret));
+fatal:
+	return (ARCHIVE_FATAL);
 }
 
 #else /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
@@ -367,17 +452,9 @@
 	archive_strcpy(&as, "zstd --no-check");
 
 	if (data->compression_level < CLEVEL_STD_MIN) {
-		struct archive_string as2;
-		archive_string_init(&as2);
-		archive_string_sprintf(&as2, " --fast=%d", -data->compression_level);
-		archive_string_concat(&as, &as2);
-		archive_string_free(&as2);
+		archive_string_sprintf(&as, " --fast=%d", -data->compression_level);
 	} else {
-		struct archive_string as2;
-		archive_string_init(&as2);
-		archive_string_sprintf(&as2, " -%d", data->compression_level);
-		archive_string_concat(&as, &as2);
-		archive_string_free(&as2);
+		archive_string_sprintf(&as, " -%d", data->compression_level);
 	}
 
 	if (data->compression_level > CLEVEL_STD_MAX) {
@@ -385,11 +462,11 @@
 	}
 
 	if (data->threads != 0) {
-		struct archive_string as2;
-		archive_string_init(&as2);
-		archive_string_sprintf(&as2, " --threads=%d", data->threads);
-		archive_string_concat(&as, &as2);
-		archive_string_free(&as2);
+		archive_string_sprintf(&as, " --threads=%d", data->threads);
+	}
+
+	if (data->long_distance != 0) {
+		archive_string_sprintf(&as, " --long=%d", data->long_distance);
 	}
 
 	f->write = archive_compressor_zstd_write;
@@ -408,6 +485,14 @@
 }
 
 static int
+archive_compressor_zstd_flush(struct archive_write_filter *f)
+{
+	(void)f; /* UNUSED */
+
+	return (ARCHIVE_OK);
+}
+
+static int
 archive_compressor_zstd_close(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
index bd5180e..d676ed6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -397,6 +397,7 @@
 static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
 static ssize_t	write_data_block(struct archive_write_disk *,
 		    const char *, size_t);
+static void close_file_descriptor(struct archive_write_disk *);
 
 static int	_archive_write_disk_close(struct archive *);
 static int	_archive_write_disk_free(struct archive *);
@@ -514,7 +515,12 @@
 	 * XXX At this point, symlinks should not be hit, otherwise
 	 * XXX a race occurred.  Do we want to check explicitly for that?
 	 */
-	if (lstat(a->name, &a->st) == 0) {
+#ifdef HAVE_LSTAT
+	if (lstat(a->name, &a->st) == 0)
+#else
+	if (la_stat(a->name, &a->st) == 0)
+#endif
+	{
 		a->pst = &a->st;
 		return (ARCHIVE_OK);
 	}
@@ -1605,12 +1611,12 @@
 			    "Seek failed");
 			return (ARCHIVE_FATAL);
 		} else if (a->offset > a->fd_offset) {
-			int64_t skip = a->offset - a->fd_offset;
+			uint64_t skip = a->offset - a->fd_offset;
 			char nullblock[1024];
 
 			memset(nullblock, 0, sizeof(nullblock));
 			while (skip > 0) {
-				if (skip > (int64_t)sizeof(nullblock))
+				if (skip > sizeof(nullblock))
 					bytes_written = hfs_write_decmpfs_block(
 					    a, nullblock, sizeof(nullblock));
 				else
@@ -1725,8 +1731,10 @@
 			else
 				r = hfs_write_data_block(
 				    a, null_d, a->file_remaining_bytes);
-			if (r < 0)
+			if (r < 0) {
+				close_file_descriptor(a);
 				return ((int)r);
+			}
 		}
 #endif
 	} else {
@@ -1735,6 +1743,7 @@
 		    a->filesize == 0) {
 			archive_set_error(&a->archive, errno,
 			    "File size could not be restored");
+			close_file_descriptor(a);
 			return (ARCHIVE_FAILED);
 		}
 #endif
@@ -1744,8 +1753,10 @@
 		 * to see what happened.
 		 */
 		a->pst = NULL;
-		if ((ret = lazy_stat(a)) != ARCHIVE_OK)
-			return (ret);
+        if ((ret = lazy_stat(a)) != ARCHIVE_OK) {
+            close_file_descriptor(a);
+            return (ret);
+        }
 		/* We can use lseek()/write() to extend the file if
 		 * ftruncate didn't work or isn't available. */
 		if (a->st.st_size < a->filesize) {
@@ -1753,11 +1764,13 @@
 			if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) {
 				archive_set_error(&a->archive, errno,
 				    "Seek failed");
+				close_file_descriptor(a);
 				return (ARCHIVE_FATAL);
 			}
 			if (write(a->fd, &nul, 1) < 0) {
 				archive_set_error(&a->archive, errno,
 				    "Write to restore size failed");
+				close_file_descriptor(a);
 				return (ARCHIVE_FATAL);
 			}
 			a->pst = NULL;
@@ -2154,7 +2167,11 @@
 		 * then don't follow it.
 		 */
 		if (r != 0 || !S_ISDIR(a->mode))
+#ifdef HAVE_LSTAT
 			r = lstat(a->name, &a->st);
+#else
+			r = la_stat(a->name, &a->st);
+#endif
 		if (r != 0) {
 			archive_set_error(&a->archive, errno,
 			    "Can't stat existing object");
@@ -2550,7 +2567,12 @@
 					goto skip_fixup_entry;
 				} else
 #endif
-				if (lstat(p->name, &st) != 0 ||
+				if (
+#ifdef HAVE_LSTAT
+					lstat(p->name, &st) != 0 ||
+#else
+					la_stat(p->name, &st) != 0 ||
+#endif
 				    la_verify_filetype(st.st_mode,
 				    p->filetype) == 0) {
 					goto skip_fixup_entry;
@@ -2565,7 +2587,12 @@
 				goto skip_fixup_entry;
 			} else
 #endif
-			if (lstat(p->name, &st) != 0 ||
+			if (
+#ifdef HAVE_LSTAT
+				lstat(p->name, &st) != 0 ||
+#else
+				la_stat(p->name, &st) != 0 ||
+#endif
 			    la_verify_filetype(st.st_mode,
 			    p->filetype) == 0) {
 				goto skip_fixup_entry;
@@ -2785,8 +2812,8 @@
     !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT))
 	/* Platform doesn't have lstat, so we can't look for symlinks. */
 	(void)path; /* UNUSED */
-	(void)error_number; /* UNUSED */
-	(void)error_string; /* UNUSED */
+	(void)a_eno; /* UNUSED */
+	(void)a_estr; /* UNUSED */
 	(void)flags; /* UNUSED */
 	(void)checking_linkname; /* UNUSED */
 	return (ARCHIVE_OK);
@@ -2859,8 +2886,10 @@
 		/* Check that we haven't hit a symlink. */
 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
 		r = fstatat(chdir_fd, head, &st, AT_SYMLINK_NOFOLLOW);
-#else
+#elif defined(HAVE_LSTAT)
 		r = lstat(head, &st);
+#else
+		r = la_stat(head, &st);
 #endif
 		if (r != 0) {
 			tail[0] = c;
@@ -3558,7 +3587,9 @@
 	(void)fd; /* UNUSED */
 	(void)mode; /* UNUSED */
 	(void)name; /* UNUSED */
+	(void)atime; /* UNUSED */
 	(void)atime_nsec; /* UNUSED */
+	(void)mtime; /* UNUSED */
 	(void)mtime_nsec; /* UNUSED */
 	return (ARCHIVE_WARN);
 #endif
@@ -4391,7 +4422,12 @@
 	 */
 	archive_strncpy(&datafork, pathname, p - pathname);
 	archive_strcat(&datafork, p + 2);
-	if (lstat(datafork.s, &st) == -1 ||
+	if (
+#ifdef HAVE_LSTAT
+		lstat(datafork.s, &st) == -1 ||
+#else
+		la_stat(datafork.s, &st) == -1 ||
+#endif
 	    (st.st_mode & AE_IFMT) != AE_IFREG)
 		goto skip_appledouble;
 
@@ -4707,5 +4743,17 @@
 }
 #endif
 
+/*
+ * Close the file descriptor if one is open.
+ */
+static void close_file_descriptor(struct archive_write_disk* a)
+{
+	if (a->fd >= 0) {
+		close(a->fd);
+		a->fd = -1;
+	}
+}
+
+
 #endif /* !_WIN32 || __CYGWIN__ */
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index 88df3ce..7b9ea74 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -254,9 +254,9 @@
  * which is high-16-bits of nFileIndexHigh. */
 #define bhfi_ino(bhfi)	\
 	((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
-    + (bhfi)->nFileIndexLow)
+    | (bhfi)->nFileIndexLow)
 #define bhfi_size(bhfi)	\
-    ((((int64_t)(bhfi)->nFileSizeHigh) << 32) + (bhfi)->nFileSizeLow)
+    ((((int64_t)(bhfi)->nFileSizeHigh) << 32) | (bhfi)->nFileSizeLow)
 
 static int
 file_information(struct archive_write_disk *a, wchar_t *path,
@@ -266,6 +266,9 @@
 	int r;
 	DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
 	WIN32_FIND_DATAW	findData;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 	if (sim_lstat || mode != NULL) {
 		h = FindFirstFileW(path, &findData);
@@ -290,14 +293,27 @@
 		(findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
 
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileFlags = flag;
+	h = CreateFile2(a->name, 0, 0,
+		OPEN_EXISTING, &createExParams);
+#else
 	h = CreateFileW(a->name, 0, 0, NULL,
 	    OPEN_EXISTING, flag, NULL);
+#endif
 	if (h == INVALID_HANDLE_VALUE &&
 	    GetLastError() == ERROR_INVALID_NAME) {
 		wchar_t *full;
 		full = __la_win_permissive_name_w(path);
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		h = CreateFile2(full, 0, 0,
+			OPEN_EXISTING, &createExParams);
+#else
 		h = CreateFileW(full, 0, 0, NULL,
 		    OPEN_EXISTING, flag, NULL);
+#endif
 		free(full);
 	}
 	if (h == INVALID_HANDLE_VALUE) {
@@ -559,6 +575,7 @@
 	return (fd);
 }
 
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
 static void *
 la_GetFunctionKernel32(const char *name)
 {
@@ -574,18 +591,24 @@
 	}
 	return (void *)GetProcAddress(lib, name);
 }
+#endif
 
 static int
 la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
 {
-	static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
-	static int set;
+	static BOOL (WINAPI *f)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
 	BOOL ret;
 
+#if _WIN32_WINNT < _WIN32_WINNT_XP
+	static int set;
+/* CreateHardLinkW is available since XP and always loaded */
 	if (!set) {
 		set = 1;
 		f = la_GetFunctionKernel32("CreateHardLinkW");
 	}
+#else
+	f = CreateHardLinkW;
+#endif
 	if (!f) {
 		errno = ENOTSUP;
 		return (0);
@@ -624,7 +647,6 @@
 la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
     int linktype) {
 	static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD);
-	static int set;
 	wchar_t *ttarget, *p;
 	size_t len;
 	DWORD attrs = 0;
@@ -632,10 +654,20 @@
 	DWORD newflags = 0;
 	BOOL ret = 0;
 
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
+/* CreateSymbolicLinkW is available since Vista and always loaded */
+	static int set;
 	if (!set) {
 		set = 1;
 		f = la_GetFunctionKernel32("CreateSymbolicLinkW");
 	}
+#else
+# if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+	f = CreateSymbolicLinkW;
+# else
+	f = NULL;
+# endif
+#endif
 	if (!f)
 		return (0);
 
@@ -1185,6 +1217,8 @@
 		if (la_ftruncate(a->fh, a->filesize) == -1) {
 			archive_set_error(&a->archive, errno,
 			    "File size could not be restored");
+			CloseHandle(a->fh);
+			a->fh = INVALID_HANDLE_VALUE;
 			return (ARCHIVE_FAILED);
 		}
 	}
@@ -1656,6 +1690,9 @@
 	mode_t final_mode, mode;
 	int r;
 	DWORD attrs = 0;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 	/* We identify hard/symlinks according to the link names. */
 	/* Since link(2) and symlink(2) don't handle modes, we're done here. */
@@ -1719,8 +1756,16 @@
 			a->todo = 0;
 			a->deferred = 0;
 		} else if (r == 0 && a->filesize > 0) {
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			ZeroMemory(&createExParams, sizeof(createExParams));
+			createExParams.dwSize = sizeof(createExParams);
+			createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+			a->fh = CreateFile2(namefull, GENERIC_WRITE, 0,
+			    TRUNCATE_EXISTING, &createExParams);
+#else
 			a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
 			    TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
 			if (a->fh == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
 				r = errno;
@@ -1783,14 +1828,27 @@
 		a->tmpname = NULL;
 		fullname = a->name;
 		/* O_WRONLY | O_CREAT | O_EXCL */
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		ZeroMemory(&createExParams, sizeof(createExParams));
+		createExParams.dwSize = sizeof(createExParams);
+		createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+		a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
+		    CREATE_NEW, &createExParams);
+#else
 		a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
 		    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
 		if (a->fh == INVALID_HANDLE_VALUE &&
 		    GetLastError() == ERROR_INVALID_NAME &&
 		    fullname == a->name) {
 			fullname = __la_win_permissive_name_w(a->name);
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
+			    CREATE_NEW, &createExParams);
+#else
 			a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
 			    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
 		}
 		if (a->fh == INVALID_HANDLE_VALUE) {
 			if (GetLastError() == ERROR_ACCESS_DENIED) {
@@ -2551,14 +2609,25 @@
 		hw = NULL;
 	} else {
 		wchar_t *ws;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 		if (S_ISLNK(mode))
 			return (ARCHIVE_OK);
 		ws = __la_win_permissive_name_w(name);
 		if (ws == NULL)
 			goto settimes_failed;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		ZeroMemory(&createExParams, sizeof(createExParams));
+		createExParams.dwSize = sizeof(createExParams);
+		createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
+		hw = CreateFile2(ws, FILE_WRITE_ATTRIBUTES, 0,
+		    OPEN_EXISTING, &createExParams);
+#else
 		hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
 		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+#endif
 		free(ws);
 		if (hw == INVALID_HANDLE_VALUE)
 			goto settimes_failed;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_private.h b/Utilities/cmlibarchive/libarchive/archive_write_private.h
index 155fdd7..6522e65 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_write_private.h
@@ -53,6 +53,7 @@
 	    const char *key, const char *value);
 	int	(*open)(struct archive_write_filter *);
 	int	(*write)(struct archive_write_filter *, const void *, size_t);
+	int	(*flush)(struct archive_write_filter *);
 	int	(*close)(struct archive_write_filter *);
 	int	(*free)(struct archive_write_filter *);
 	void	 *data;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
index 87b3586..1d7249f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
@@ -91,6 +91,26 @@
 #define kAttributes		0x15
 #define kEncodedHeader		0x17
 
+// Check that some windows file attribute constants are defined.
+// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
+#ifndef FILE_ATTRIBUTE_READONLY
+#define FILE_ATTRIBUTE_READONLY 0x00000001
+#endif
+
+#ifndef FILE_ATTRIBUTE_DIRECTORY
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#endif
+
+#ifndef FILE_ATTRIBUTE_ARCHIVE
+#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
+#endif
+
+// This value is defined in 7zip with the comment "trick for Unix".
+//
+// 7z archives created on unix have this bit set in the high 16 bits of
+// the attr field along with the unix permissions.
+#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000
+
 enum la_zaction {
 	ARCHIVE_Z_FINISH,
 	ARCHIVE_Z_RUN
@@ -165,7 +185,7 @@
 	mode_t			 mode;
 	uint32_t		 crc32;
 
-	signed int		 dir:1;
+	unsigned		 dir:1;
 };
 
 struct _7zip {
@@ -1424,14 +1444,19 @@
 		 * High 16bits is unix mode.
 		 * Low 16bits is Windows attributes.
 		 */
-		uint32_t encattr, attr;
+		uint32_t encattr, attr = 0;
+
 		if (file->dir)
-			attr = 0x8010;
+			attr |= FILE_ATTRIBUTE_DIRECTORY;
 		else
-			attr = 0x8020;
+			attr |= FILE_ATTRIBUTE_ARCHIVE;
+
 		if ((file->mode & 0222) == 0)
-			attr |= 1;/* Read Only. */
+			attr |= FILE_ATTRIBUTE_READONLY;
+
+		attr |= FILE_ATTRIBUTE_UNIX_EXTENSION;
 		attr |= ((uint32_t)file->mode) << 16;
+
 		archive_le32enc(&encattr, attr);
 		r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
 		if (r < 0)
@@ -1809,11 +1834,11 @@
 	 * of ugly hackery to convert a const * pointer to
 	 * a non-const pointer. */
 	strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
-	strm->avail_in = lastrm->avail_in;
+	strm->avail_in = (uint32_t)lastrm->avail_in;
 	strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
 	strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
 	strm->next_out = (char *)lastrm->next_out;
-	strm->avail_out = lastrm->avail_out;
+	strm->avail_out = (uint32_t)lastrm->avail_out;
 	strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
 	strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
 	if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
@@ -1842,11 +1867,11 @@
 	 * of ugly hackery to convert a const * pointer to
 	 * a non-const pointer. */
 	strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
-	strm->avail_in = lastrm->avail_in;
+	strm->avail_in = (uint32_t)lastrm->avail_in;
 	strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
 	strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
 	strm->next_out = (char *)lastrm->next_out;
-	strm->avail_out = lastrm->avail_out;
+	strm->avail_out = (uint32_t)lastrm->avail_out;
 	strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
 	strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
 	r = BZ2_bzCompress(strm,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
index ebd33c5..1b03170 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
@@ -293,12 +293,12 @@
 		struct extr_rec	*current;
 	}			 extr_rec_list;
 
-	signed int		 virtual:1;
+	unsigned int		 virtual:1;
 	/* If set to one, this file type is a directory.
 	 * A convenience flag to be used as
 	 * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
 	 */
-	signed int		 dir:1;
+	unsigned int		 dir:1;
 };
 
 struct hardlink {
@@ -656,7 +656,7 @@
 #define VOLUME_IDENTIFIER_SIZE		32
 
 	/*
-	 * Usage  : !zisofs [DEFAULT] 
+	 * Usage  : !zisofs [DEFAULT]
 	 *        :    Disable to generate RRIP 'ZF' extension.
 	 *        : zisofs
 	 *        :    Make files zisofs file and generate RRIP 'ZF'
@@ -693,7 +693,7 @@
 	uint64_t		 bytes_remaining;
 	int			 need_multi_extent;
 
-	/* Temporary string buffer for Joliet extension. */ 
+	/* Temporary string buffer for Joliet extension. */
 	struct archive_string	 utf16be;
 	struct archive_string	 mbs;
 
@@ -759,9 +759,9 @@
 
 	/* Used for making zisofs. */
 	struct {
-		signed int	 detect_magic:1;
-		signed int	 making:1;
-		signed int	 allzero:1;
+		unsigned int	 detect_magic:1;
+		unsigned int	 making:1;
+		unsigned int	 allzero:1;
 		unsigned char	 magic_buffer[64];
 		int		 magic_cnt;
 
@@ -2525,12 +2525,11 @@
 static void
 get_tmfromtime(struct tm *tm, time_t *t)
 {
-#if HAVE_LOCALTIME_R
+#if HAVE_LOCALTIME_S
+	localtime_s(tm, t);
+#elif HAVE_LOCALTIME_R
 	tzset();
 	localtime_r(t, tm);
-#elif HAVE__LOCALTIME64_S
-	__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
-	_localtime64_s(tm, &tmp_t);
 #else
 	memcpy(tm, localtime(t), sizeof(*tm));
 #endif
@@ -4078,11 +4077,8 @@
 	}
 	memset(info.s, 0, info_size);
 	opt = 0;
-#if defined(HAVE__CTIME64_S)
-	{
-		__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
-		_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
-	}
+#if defined(HAVE_CTIME_S)
+	ctime_s(buf, sizeof(buf), &(iso9660->birth_time));
 #elif defined(HAVE_CTIME_R)
 	ctime_r(&(iso9660->birth_time), buf);
 #else
@@ -7811,8 +7807,8 @@
 	uint64_t	 pz_uncompressed_size;
 	size_t		 uncompressed_buffer_size;
 
-	signed int	 initialized:1;
-	signed int	 header_passed:1;
+	unsigned int	 initialized:1;
+	unsigned int	 header_passed:1;
 
 	uint32_t	 pz_offset;
 	unsigned char	*block_pointers;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
index cf1f477..1eb9a9a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
@@ -100,6 +100,7 @@
 static void		 sparse_list_clear(struct pax *);
 static int		 sparse_list_add(struct pax *, int64_t, int64_t);
 static char		*url_encode(const char *in);
+static time_t		 get_ustar_max_mtime(void);
 
 /*
  * Set output format to 'restricted pax' format.
@@ -367,10 +368,12 @@
 	struct archive_string s;
 	char *encoded_value;
 
+	if (encoded_name == NULL)
+		return;
+
 	if (pax->flags & WRITE_LIBARCHIVE_XATTR) {
 		encoded_value = base64_encode((const char *)value, value_len);
-
-		if (encoded_name != NULL && encoded_value != NULL) {
+		if (encoded_value != NULL) {
 			archive_string_init(&s);
 			archive_strcpy(&s, "LIBARCHIVE.xattr.");
 			archive_strcat(&s, encoded_name);
@@ -403,17 +406,22 @@
 
 		archive_entry_xattr_next(entry, &name, &value, &size);
 		url_encoded_name = url_encode(name);
-		if (url_encoded_name != NULL) {
+		if (url_encoded_name == NULL)
+			goto malloc_error;
+		else {
 			/* Convert narrow-character to UTF-8. */
 			r = archive_strcpy_l(&(pax->l_url_encoded_name),
 			    url_encoded_name, pax->sconv_utf8);
 			free(url_encoded_name); /* Done with this. */
 			if (r == 0)
 				encoded_name = pax->l_url_encoded_name.s;
-			else if (errno == ENOMEM) {
-				archive_set_error(&a->archive, ENOMEM,
-				    "Can't allocate memory for Linkname");
-				return (ARCHIVE_FATAL);
+			else if (r == -1)
+				goto malloc_error;
+			else {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Error encoding pax extended attribute");
+				return (ARCHIVE_FAILED);
 			}
 		}
 
@@ -422,6 +430,9 @@
 
 	}
 	return (ARCHIVE_OK);
+malloc_error:
+	archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
+	return (ARCHIVE_FATAL);
 }
 
 static int
@@ -595,6 +606,8 @@
 	need_extension = 0;
 	pax = (struct pax *)a->format_data;
 
+	const time_t ustar_max_mtime = get_ustar_max_mtime();
+
 	/* Sanity check. */
 	if (archive_entry_pathname(entry_original) == NULL) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1116,16 +1129,13 @@
 	}
 
 	/*
-	 * Technically, the mtime field in the ustar header can
-	 * support 33 bits, but many platforms use signed 32-bit time
-	 * values.  The cutoff of 0x7fffffff here is a compromise.
 	 * Yes, this check is duplicated just below; this helps to
 	 * avoid writing an mtime attribute just to handle a
 	 * high-resolution timestamp in "restricted pax" mode.
 	 */
 	if (!need_extension &&
 	    ((archive_entry_mtime(entry_main) < 0)
-		|| (archive_entry_mtime(entry_main) >= 0x7fffffff)))
+		|| (archive_entry_mtime(entry_main) >= ustar_max_mtime)))
 		need_extension = 1;
 
 	/* I use a star-compatible file flag attribute. */
@@ -1190,7 +1200,7 @@
 	if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
 	    need_extension) {
 		if (archive_entry_mtime(entry_main) < 0  ||
-		    archive_entry_mtime(entry_main) >= 0x7fffffff  ||
+		    archive_entry_mtime(entry_main) >= ustar_max_mtime  ||
 		    archive_entry_mtime_nsec(entry_main) != 0)
 			add_pax_attr_time(&(pax->pax_header), "mtime",
 			    archive_entry_mtime(entry_main),
@@ -1428,7 +1438,7 @@
 		/* Copy mtime, but clip to ustar limits. */
 		s = archive_entry_mtime(entry_main);
 		if (s < 0) { s = 0; }
-		if (s >= 0x7fffffff) { s = 0x7fffffff; }
+		if (s > ustar_max_mtime) { s = ustar_max_mtime; }
 		archive_entry_set_mtime(pax_attr_entry, s, 0);
 
 		/* Standard ustar doesn't support atime. */
@@ -1904,14 +1914,19 @@
 {
 	const char *s;
 	char *d;
-	int out_len = 0;
+	size_t out_len = 0;
 	char *out;
 
 	for (s = in; *s != '\0'; s++) {
-		if (*s < 33 || *s > 126 || *s == '%' || *s == '=')
+		if (*s < 33 || *s > 126 || *s == '%' || *s == '=') {
+			if (SIZE_MAX - out_len < 4)
+				return (NULL);
 			out_len += 3;
-		else
+		} else {
+			if (SIZE_MAX - out_len < 2)
+				return (NULL);
 			out_len++;
+		}
 	}
 
 	out = (char *)malloc(out_len + 1);
@@ -2046,3 +2061,18 @@
 	return (_sparse_list_add_block(pax, offset, length, 0));
 }
 
+static time_t
+get_ustar_max_mtime(void)
+{
+	/*
+	 * Technically, the mtime field in the ustar header can
+	 * support 33 bits. We are using all of them to keep
+	 * tar/test/test_option_C_mtree.c simple and passing after 2038.
+	 * For platforms that use signed 32-bit time values we
+	 * use the 32-bit maximum.
+	 */
+	if (sizeof(time_t) > sizeof(int32_t))
+		return (time_t)0x1ffffffff;
+	else
+		return (time_t)0x7fffffff;
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
index 46b0573..0ef003e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
@@ -329,30 +329,21 @@
 {
 /** like strftime(3) but for time_t objects */
 	struct tm *rt;
-#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
 	struct tm timeHere;
 #endif
-#if defined(HAVE__GMTIME64_S)
-	errno_t terr;
-	__time64_t tmptime;
-#endif
 	char strtime[100];
 	size_t len;
 
-#ifdef HAVE_GMTIME_R
-	if ((rt = gmtime_r(&t, &timeHere)) == NULL)
-		return;
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = t;
-	terr = _gmtime64_s(&timeHere, &tmptime);
-	if (terr)
-		rt = NULL;
-	else
-		rt = &timeHere;
+#if defined(HAVE_GMTIME_S)
+	rt = gmtime_s(&timeHere, &t) ? NULL : &timeHere;
+#elif defined(HAVE_GMTIME_R)
+	rt = gmtime_r(&t, &timeHere);
 #else
-	if ((rt = gmtime(&t)) == NULL)
-		return;
+	rt = gmtime(&t);
 #endif
+	if (!rt)
+		return;
 	/* leave the hard yacker to our role model strftime() */
 	len = strftime(strtime, sizeof(strtime)-1, fmt, rt);
 	archive_strncat(as, strtime, len);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
index 1e35375..1e82aa2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
@@ -212,8 +212,8 @@
 	struct heap_data	 data;
         struct archive_string    script;
 
-	signed int		 virtual:1;
-	signed int		 dir:1;
+	unsigned int		 virtual:1;
+	unsigned int		 dir:1;
 };
 
 struct hardlink {
@@ -906,15 +906,11 @@
 {
 	char timestr[100];
 	struct tm tm;
-#if defined(HAVE__GMTIME64_S)
-	__time64_t tmptime;
-#endif
 
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+	gmtime_s(&tm, &t);
+#elif defined(HAVE_GMTIME_R)
 	gmtime_r(&t, &tm);
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = t;
-	_gmtime64_s(&tm, &tmptime);
 #else
 	memcpy(&tm, gmtime(&t), sizeof(tm));
 #endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
index 530e1e8..d610300 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
@@ -1382,25 +1382,14 @@
 {
 	struct tm *t;
 	unsigned int dt;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t terr;
-	__time64_t tmptime;
-#endif
 
-	/* This will not preserve time when creating/extracting the archive
-	 * on two systems with different time zones. */
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	t = localtime_s(&tmbuf, &unix_time) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	t = localtime_r(&unix_time, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = unix_time;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		t = NULL;
-	else
-		t = &tmbuf;
 #else
 	t = localtime(&unix_time);
 #endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
index dd57358..f4b5081 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
@@ -257,6 +257,15 @@
 The value is interpreted as a decimal integer specifying the
 compression level. Supported values depend on the library version,
 common values are from 1 to 22.
+.It Cm long
+Enables long distance matching. The value is interpreted as a
+decimal integer specifying log2 window size in bytes. Values from
+10 to 30 for 32 bit, or 31 for 64 bit, are supported.
+.It Cm threads
+The value is interpreted as a decimal integer specifying the
+number of threads for multi-threaded zstd compression.
+If set to 0, zstd will attempt to detect and use the number
+of physical CPU cores.
 .El
 .It Format 7zip
 .Bl -tag -compact -width indent
diff --git a/Utilities/cmlibarchive/libarchive/config_freebsd.h b/Utilities/cmlibarchive/libarchive/config_freebsd.h
index 758621c..669f272 100644
--- a/Utilities/cmlibarchive/libarchive/config_freebsd.h
+++ b/Utilities/cmlibarchive/libarchive/config_freebsd.h
@@ -111,6 +111,8 @@
 #define HAVE_FCNTL 1
 #define HAVE_FCNTL_H 1
 #define HAVE_FDOPENDIR 1
+#define HAVE_FNMATCH 1
+#define HAVE_FNMATCH_H 1
 #define HAVE_FORK 1
 #define HAVE_FSEEKO 1
 #define HAVE_FSTAT 1
@@ -123,6 +125,8 @@
 #define HAVE_GETEUID 1
 #define HAVE_GETGRGID_R 1
 #define HAVE_GETGRNAM_R 1
+#define HAVE_GETLINE 1
+#define HAVE_GETOPT_OPTRESET 1
 #define HAVE_GETPID 1
 #define HAVE_GETPWNAM_R 1
 #define HAVE_GETPWUID_R 1
@@ -201,6 +205,7 @@
 #define HAVE_SYS_MOUNT_H 1
 #define HAVE_SYS_PARAM_H 1
 #define HAVE_SYS_POLL_H 1
+#define HAVE_SYS_QUEUE_H 1
 #define HAVE_SYS_SELECT_H 1
 #define HAVE_SYS_STATVFS_H 1
 #define HAVE_SYS_STAT_H 1
@@ -234,7 +239,7 @@
 #define HAVE_WMEMCPY 1
 #define HAVE_WMEMMOVE 1
 #define HAVE_ZLIB_H 1
-#define TIME_WITH_SYS_TIME 1
+#define HAVE_SYS_TIME_H 1
 
 #if __FreeBSD_version >= 800505
 #define HAVE_LIBLZMA 1
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_windows.c b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
index 0b96397..9e49c56 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
@@ -31,6 +31,7 @@
 
 #include "filter_fork.h"
 
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
 /* There are some editions of Windows ("nano server," for example) that
  * do not host user32.dll. If we want to keep running on those editions,
  * we need to delay-load WaitForInputIdle. */
@@ -224,6 +225,14 @@
 	__archive_cmdline_free(acmd);
 	return ARCHIVE_FAILED;
 }
+#else /* !WINAPI_PARTITION_DESKTOP */
+int
+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, HANDLE *out_child)
+{
+	(void)cmd; (void)child_stdin; (void) child_stdout; (void) out_child;
+	return ARCHIVE_FAILED;
+}
+#endif /* !WINAPI_PARTITION_DESKTOP */
 
 void
 __archive_check_child(int in, int out)
diff --git a/Utilities/cmlibarchive/libarchive/xxhash.c b/Utilities/cmlibarchive/libarchive/xxhash.c
index f96e9d9..beacd23 100644
--- a/Utilities/cmlibarchive/libarchive/xxhash.c
+++ b/Utilities/cmlibarchive/libarchive/xxhash.c
@@ -149,6 +149,10 @@
 
 #if GCC_VERSION >= 409
 __attribute__((__no_sanitize_undefined__))
+#else
+#  if defined(__clang__)
+__attribute__((no_sanitize("undefined")))
+#  endif
 #endif
 #if defined(_MSC_VER)
 static __inline U32 A32(const void * x)