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)