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 The ``7zip`` and ``zip`` archive formats already imply a specific type of
compression. The other formats use no compression by default, but can be compression. The other formats use no compression by default, but can be
directed to do so with the ``COMPRESSION`` option. Valid values for 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:: .. note::
With ``FORMAT`` set to ``raw``, only one file will be compressed 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. Compress the resulting archive with Zstandard.
.. option:: --lzma
.. versionadded:: 4.3
Compress the resulting archive with LZMA algorithm.
.. option:: --files-from=<file> .. option:: --files-from=<file>
.. versionadded:: 3.1 .. 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 Specify a compression algorithm for the
``TARBALL`` data file. Using this option reduces the size of the data file ``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``, before it is submitted to CDash.
``BZIP2``, ``XZ``, ``ZSTD``, ``FROM_EXT``, or an expression that CMake ``<compression>`` should be one of the following:
evaluates as ``FALSE``. The default value is ``BZIP2``.
* ``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 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`` the file extension of the ``<tar-file>`` (i.e. ``.tar.gz`` will use ``GZIP``
compression). File extensions that will produce compressed output include compression). File extensions that will produce compressed output include:
``.tar.gz``, ``.tgz``, ``.tar.bzip2``, ``.tbz``, ``.tar.xz``, and ``.txz``.
* ``.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>`` ``SOURCE <source-dir>``
Specify the top-level source directory for the build. Specify the top-level source directory for the build.
@@ -152,12 +191,12 @@ function(ctest_coverage_collect_gcov)
else() else()
set(gcov_command "${GCOV_GCOV_COMMAND}") set(gcov_command "${GCOV_GCOV_COMMAND}")
endif() endif()
set(supported_compressions "GZIP" "BZIP2" "LZMA" "LZMA2" "XZ" "ZSTD" "FROM_EXT")
if(NOT DEFINED GCOV_TARBALL_COMPRESSION) if(NOT DEFINED GCOV_TARBALL_COMPRESSION)
set(GCOV_TARBALL_COMPRESSION "BZIP2") set(GCOV_TARBALL_COMPRESSION "BZIP2")
elseif( GCOV_TARBALL_COMPRESSION AND elseif( GCOV_TARBALL_COMPRESSION AND
NOT GCOV_TARBALL_COMPRESSION MATCHES "^(GZIP|BZIP2|XZ|ZSTD|FROM_EXT)$") NOT GCOV_TARBALL_COMPRESSION IN_LIST supported_compressions)
message(FATAL_ERROR "TARBALL_COMPRESSION must be one of OFF, GZIP, " message(FATAL_ERROR "TARBALL_COMPRESSION must be OFF or one of ${supported_compressions} for ctest_coverage_collect_gcov")
"BZIP2, XZ, ZSTD, or FROM_EXT for ctest_coverage_collect_gcov")
endif() endif()
# run gcov on each gcda file in the binary tree # run gcov on each gcda file in the binary tree
set(gcda_files) set(gcda_files)
@@ -341,6 +380,7 @@ ${uncovered_files_for_tar}
# Prepare tar command line arguments # Prepare tar command line arguments
set(tar_opts "") set(tar_opts "")
set(zstd_tar_opt "")
# Select data compression mode # Select data compression mode
if( GCOV_TARBALL_COMPRESSION STREQUAL "FROM_EXT") if( GCOV_TARBALL_COMPRESSION STREQUAL "FROM_EXT")
if( GCOV_TARBALL MATCHES [[\.(tgz|tar.gz)$]] ) if( GCOV_TARBALL MATCHES [[\.(tgz|tar.gz)$]] )
@@ -349,15 +389,21 @@ ${uncovered_files_for_tar}
string(APPEND tar_opts "J") string(APPEND tar_opts "J")
elseif( GCOV_TARBALL MATCHES [[\.(tbz|tar.bz)$]] ) elseif( GCOV_TARBALL MATCHES [[\.(tbz|tar.bz)$]] )
string(APPEND tar_opts "j") 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() endif()
elseif(GCOV_TARBALL_COMPRESSION STREQUAL "GZIP") elseif(GCOV_TARBALL_COMPRESSION STREQUAL "GZIP")
string(APPEND tar_opts "z") 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") string(APPEND tar_opts "J")
elseif(GCOV_TARBALL_COMPRESSION STREQUAL "BZIP2") elseif(GCOV_TARBALL_COMPRESSION STREQUAL "BZIP2")
string(APPEND tar_opts "j") string(APPEND tar_opts "j")
elseif(GCOV_TARBALL_COMPRESSION STREQUAL "ZSTD") elseif(GCOV_TARBALL_COMPRESSION STREQUAL "ZSTD")
set(zstd_tar_opt "--zstd") set(zstd_tar_opt "--zstd")
elseif(GCOV_TARBALL_COMPRESSION STREQUAL "LZMA")
set(zstd_tar_opt "--lzma")
endif() endif()
# Verbosity options # Verbosity options
if(NOT GCOV_QUIET AND NOT tar_opts MATCHES v) 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 }, compressionTypeMap = { { "None", cmSystemTools::TarCompressNone },
{ "BZip2", cmSystemTools::TarCompressBZip2 }, { "BZip2", cmSystemTools::TarCompressBZip2 },
{ "GZip", cmSystemTools::TarCompressGZip }, { "GZip", cmSystemTools::TarCompressGZip },
{ "LZMA", cmSystemTools::TarCompressLZMA },
{ "LZMA2", cmSystemTools::TarCompressXZ },
{ "XZ", cmSystemTools::TarCompressXZ }, { "XZ", cmSystemTools::TarCompressXZ },
{ "Zstd", cmSystemTools::TarCompressZstd } }; { "Zstd", cmSystemTools::TarCompressZstd } };

View File

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

View File

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

View File

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

View File

@@ -197,3 +197,65 @@ if("${out}" STREQUAL "${expected_out}")
else() else()
message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}") message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
endif() 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)
run_cmake(gnutar-gz) run_cmake(gnutar-gz)
run_cmake(pax) run_cmake(pax)
run_cmake(pax-lzma)
run_cmake(pax-xz) run_cmake(pax-xz)
run_cmake(pax-zstd) run_cmake(pax-zstd)
run_cmake(paxr) 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)
run_cmake(gnutar-gz) run_cmake(gnutar-gz)
run_cmake(pax) run_cmake(pax)
run_cmake(pax-lzma)
run_cmake(pax-lzma2)
run_cmake(pax-xz) run_cmake(pax-xz)
run_cmake(pax-zstd) run_cmake(pax-zstd)
run_cmake(paxr) 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)