cli tar: implement LZMA support

Fixes: #27433
This commit is contained in:
AJIOB
2025-12-01 08:40:46 +03:00
parent 3cd055ec6d
commit 5b87a5d53e
14 changed files with 190 additions and 10 deletions

View File

@@ -938,7 +938,23 @@ Archiving
The ``7zip`` and ``zip`` archive formats already imply a specific type of
compression. The other formats use no compression by default, but can be
directed to do so with the ``COMPRESSION`` option. Valid values for
``<compression>`` are ``None``, ``BZip2``, ``GZip``, ``XZ``, and ``Zstd``.
``<compression>`` are:
* ``None``
* ``BZip2``
* ``GZip``
* ``LZMA``
.. versionadded:: 4.3
* ``LZMA2``
.. versionadded:: 4.3
This is an alias for ``XZ``.
* ``XZ``
* ``Zstd``
.. note::
With ``FORMAT`` set to ``raw``, only one file will be compressed

View File

@@ -1468,6 +1468,12 @@ Available commands are:
Compress the resulting archive with Zstandard.
.. option:: --lzma
.. versionadded:: 4.3
Compress the resulting archive with LZMA algorithm.
.. option:: --files-from=<file>
.. versionadded:: 3.1

View File

@@ -0,0 +1,12 @@
cli-tar-lzma
------------
* The :manual:`cmake(1)` ``-E tar`` tool supports support ``LZMA`` compression
via ``--lzma`` option.
* The :command:`file(ARCHIVE_CREATE)` command's ``COMPRESSION`` option,
supports ``LZMA`` and ``LZMA2`` compression. The ``LZMA2`` compression is
an alias for ``XZ``.
* The :module:`CTestCoverageCollectGCOV` supports ``LZMA`` and ``LZMA2`` compression.
The ``LZMA2`` compression is an alias for ``XZ``.
* The :module:`CTestCoverageCollectGCOV` supports ``LZMA`` and ``ZSTD`` compression
file extensions for ``FROM_EXT`` compression mode.

View File

@@ -65,14 +65,53 @@ This module provides the following command:
Specify a compression algorithm for the
``TARBALL`` data file. Using this option reduces the size of the data file
before it is submitted to CDash. ``<compression>`` must be one of ``GZIP``,
``BZIP2``, ``XZ``, ``ZSTD``, ``FROM_EXT``, or an expression that CMake
evaluates as ``FALSE``. The default value is ``BZIP2``.
before it is submitted to CDash.
``<compression>`` should be one of the following:
* ``GZIP``
* ``BZIP2``
* ``LZMA``
.. versionadded:: 4.3
* ``LZMA2``
.. versionadded:: 4.3
This is an alias for ``XZ``.
* ``XZ``
* ``ZSTD``
* ``FROM_EXT``
* An expression that CMake evaluates as ``FALSE``
The default value is ``BZIP2``.
If ``FROM_EXT`` is specified, the resulting file will be compressed based on
the file extension of the ``<tar-file>`` (i.e. ``.tar.gz`` will use ``GZIP``
compression). File extensions that will produce compressed output include
``.tar.gz``, ``.tgz``, ``.tar.bzip2``, ``.tbz``, ``.tar.xz``, and ``.txz``.
compression). File extensions that will produce compressed output include:
* ``.tar.gz``
* ``.tgz``
* ``.tar.bzip2``
* ``.tbz``
* ``.tar.xz``
* ``.txz``
* ``.tar.lzma``
.. versionadded:: 4.3
* ``.tlzma``
.. versionadded:: 4.3
* ``.tar.zst``
.. versionadded:: 4.3
* ``.tzst``
.. versionadded:: 4.3
``SOURCE <source-dir>``
Specify the top-level source directory for the build.
@@ -152,12 +191,12 @@ function(ctest_coverage_collect_gcov)
else()
set(gcov_command "${GCOV_GCOV_COMMAND}")
endif()
set(supported_compressions "GZIP" "BZIP2" "LZMA" "LZMA2" "XZ" "ZSTD" "FROM_EXT")
if(NOT DEFINED GCOV_TARBALL_COMPRESSION)
set(GCOV_TARBALL_COMPRESSION "BZIP2")
elseif( GCOV_TARBALL_COMPRESSION AND
NOT GCOV_TARBALL_COMPRESSION MATCHES "^(GZIP|BZIP2|XZ|ZSTD|FROM_EXT)$")
message(FATAL_ERROR "TARBALL_COMPRESSION must be one of OFF, GZIP, "
"BZIP2, XZ, ZSTD, or FROM_EXT for ctest_coverage_collect_gcov")
NOT GCOV_TARBALL_COMPRESSION IN_LIST supported_compressions)
message(FATAL_ERROR "TARBALL_COMPRESSION must be OFF or one of ${supported_compressions} for ctest_coverage_collect_gcov")
endif()
# run gcov on each gcda file in the binary tree
set(gcda_files)
@@ -341,6 +380,7 @@ ${uncovered_files_for_tar}
# Prepare tar command line arguments
set(tar_opts "")
set(zstd_tar_opt "")
# Select data compression mode
if( GCOV_TARBALL_COMPRESSION STREQUAL "FROM_EXT")
if( GCOV_TARBALL MATCHES [[\.(tgz|tar.gz)$]] )
@@ -349,15 +389,21 @@ ${uncovered_files_for_tar}
string(APPEND tar_opts "J")
elseif( GCOV_TARBALL MATCHES [[\.(tbz|tar.bz)$]] )
string(APPEND tar_opts "j")
elseif( GCOV_TARBALL MATCHES [[\.(tlzma|tar.lzma)$]] )
set(zstd_tar_opt "--lzma")
elseif( GCOV_TARBALL MATCHES [[\.(tzst|tar.zst)$]] )
set(zstd_tar_opt "--zstd")
endif()
elseif(GCOV_TARBALL_COMPRESSION STREQUAL "GZIP")
string(APPEND tar_opts "z")
elseif(GCOV_TARBALL_COMPRESSION STREQUAL "XZ")
elseif((GCOV_TARBALL_COMPRESSION STREQUAL "XZ") OR (GCOV_TARBALL_COMPRESSION STREQUAL "LZMA2"))
string(APPEND tar_opts "J")
elseif(GCOV_TARBALL_COMPRESSION STREQUAL "BZIP2")
string(APPEND tar_opts "j")
elseif(GCOV_TARBALL_COMPRESSION STREQUAL "ZSTD")
set(zstd_tar_opt "--zstd")
elseif(GCOV_TARBALL_COMPRESSION STREQUAL "LZMA")
set(zstd_tar_opt "--lzma")
endif()
# Verbosity options
if(NOT GCOV_QUIET AND NOT tar_opts MATCHES v)

View File

@@ -3723,6 +3723,8 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
compressionTypeMap = { { "None", cmSystemTools::TarCompressNone },
{ "BZip2", cmSystemTools::TarCompressBZip2 },
{ "GZip", cmSystemTools::TarCompressGZip },
{ "LZMA", cmSystemTools::TarCompressLZMA },
{ "LZMA2", cmSystemTools::TarCompressXZ },
{ "XZ", cmSystemTools::TarCompressXZ },
{ "Zstd", cmSystemTools::TarCompressZstd } };

View File

@@ -2408,6 +2408,9 @@ bool cmSystemTools::CreateTar(std::string const& outFileName,
case TarCompressZstd:
compress = cmArchiveWrite::CompressZstd;
break;
case TarCompressLZMA:
compress = cmArchiveWrite::CompressLZMA;
break;
case TarCompressNone:
compress = cmArchiveWrite::CompressNone;
break;

View File

@@ -547,6 +547,7 @@ public:
{
TarCompressGZip,
TarCompressBZip2,
TarCompressLZMA,
TarCompressXZ,
TarCompressZstd,
TarCompressNone

View File

@@ -1595,6 +1595,9 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
} else if (arg == "--zstd") {
compress = cmSystemTools::TarCompressZstd;
++nCompress;
} else if (arg == "--lzma") {
compress = cmSystemTools::TarCompressLZMA;
++nCompress;
} else if (cmHasLiteralPrefix(arg, "--mtime=")) {
mtime = arg.substr(8);
} else if (cmHasLiteralPrefix(arg, "--files-from=")) {

View File

@@ -197,3 +197,65 @@ if("${out}" STREQUAL "${expected_out}")
else()
message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
endif()
#------------------------------------------------------------------------------#
# Test 6: with optional argument: TARBALL_COMPRESSION "LZMA"
#------------------------------------------------------------------------------#
set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.lzma)
ctest_coverage_collect_gcov(
TARBALL "${tar_file}"
TARBALL_COMPRESSION "LZMA"
SOURCE "${CTEST_SOURCE_DIRECTORY}"
BUILD "${CTEST_BINARY_DIRECTORY}"
GCOV_COMMAND "${CMAKE_COMMAND}"
GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
execute_process(COMMAND
${CMAKE_COMMAND} -E tar tf ${tar_file}
OUTPUT_VARIABLE out
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REPLACE "\n" ";" out "${out}")
to_relative_paths(out "${out}")
list(SORT out)
if("${out}" STREQUAL "${expected_out}")
message("PASSED with correct output: ${out}")
else()
message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
endif()
#------------------------------------------------------------------------------#
# Test 7: with optional argument: TARBALL_COMPRESSION "LZMA2"
#------------------------------------------------------------------------------#
set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov-lzma2.txz)
ctest_coverage_collect_gcov(
TARBALL "${tar_file}"
TARBALL_COMPRESSION "LZMA2"
SOURCE "${CTEST_SOURCE_DIRECTORY}"
BUILD "${CTEST_BINARY_DIRECTORY}"
GCOV_COMMAND "${CMAKE_COMMAND}"
GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
execute_process(COMMAND
${CMAKE_COMMAND} -E tar tf ${tar_file}
OUTPUT_VARIABLE out
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REPLACE "\n" ";" out "${out}")
to_relative_paths(out "${out}")
list(SORT out)
if("${out}" STREQUAL "${expected_out}")
message("PASSED with correct output: ${out}")
else()
message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
endif()

View File

@@ -26,6 +26,7 @@ run_cmake(7zip)
run_cmake(gnutar)
run_cmake(gnutar-gz)
run_cmake(pax)
run_cmake(pax-lzma)
run_cmake(pax-xz)
run_cmake(pax-zstd)
run_cmake(paxr)

View File

@@ -0,0 +1,10 @@
set(OUTPUT_NAME "test.tar.xz")
set(COMPRESSION_FLAGS cvf)
set(COMPRESSION_OPTIONS --format=pax --lzma)
set(DECOMPRESSION_FLAGS xvf)
include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
check_magic("5d00008000" LIMIT 5 HEX)

View File

@@ -4,6 +4,8 @@ run_cmake(7zip)
run_cmake(gnutar)
run_cmake(gnutar-gz)
run_cmake(pax)
run_cmake(pax-lzma)
run_cmake(pax-lzma2)
run_cmake(pax-xz)
run_cmake(pax-zstd)
run_cmake(paxr)

View File

@@ -0,0 +1,8 @@
set(OUTPUT_NAME "test.tar.lzma")
set(ARCHIVE_FORMAT pax)
set(COMPRESSION_TYPE LZMA)
include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
check_magic("5d00008000" LIMIT 5 HEX)

View File

@@ -0,0 +1,8 @@
set(OUTPUT_NAME "test.tar.xz")
set(ARCHIVE_FORMAT pax)
set(COMPRESSION_TYPE LZMA2)
include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
check_magic("fd377a585a00" LIMIT 6 HEX)