From 0bca70968a733c4a6b96dcb409ef89d7d0d6f471 Mon Sep 17 00:00:00 2001 From: AJIOB Date: Mon, 22 Dec 2025 12:58:14 +0300 Subject: [PATCH] CPack: support archive compression level Fixes: #18117 --- Help/cpack_gen/archive.rst | 18 ++++++++++++++++++ Help/cpack_gen/deb.rst | 12 ++++++------ .../dev/cpack-archive-compression-level.rst | 9 +++++++++ Modules/CPack.cmake | 18 ++++++++++++++++++ Modules/Internal/CPack/CPackDeb.cmake | 3 +++ Source/CPack/cmCPackArchiveGenerator.cxx | 17 ++++++++++++++++- Source/CPack/cmCPackArchiveGenerator.h | 1 + .../packaging_COMPONENT_default.cmake | 1 + .../7Z_LZMA2/packaging_COMPONENT_default.cmake | 1 + .../7Z_PPMD/packaging_COMPONENT_default.cmake | 1 + .../7Z_ZSTD/packaging_COMPONENT_default.cmake | 1 + .../TGZ/packaging_COMPONENT_default.cmake | 1 + .../TXZ/packaging_COMPONENT_default.cmake | 1 + .../packaging_COMPONENT_default.cmake | 1 + .../packaging_COMPONENT_default.cmake | 1 + 15 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 Help/release/dev/cpack-archive-compression-level.rst diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst index 61ecc04151..21e67cec3e 100644 --- a/Help/cpack_gen/archive.rst +++ b/Help/cpack_gen/archive.rst @@ -199,3 +199,21 @@ CPack generators which are essentially archives at their core. These include: Official CMake binaries available on ``cmake.org`` now ship with a ``liblzma`` that supports parallel compression. Older versions did not. + +.. variable:: CPACK_ARCHIVE_COMPRESSION_LEVEL + + .. versionadded:: 4.3 + + The compression level to use when compressing the archive. + + :Default: value of :variable:`CPACK_COMPRESSION_LEVEL` + + The compression level should be between ``0`` and ``9``. + + The compression level of the Zstandard-based algorithm can be set + between ``0`` and ``19``, except for the ``ZIP_ZSTD`` mode. + + The value ``0`` is used to specify the default compression level. + It is selected automatically by the archive library backend and + not directly set by CMake itself. The default compression level + may vary between archive formats, platforms, etc. diff --git a/Help/cpack_gen/deb.rst b/Help/cpack_gen/deb.rst index 41ca64aed1..d738804984 100644 --- a/Help/cpack_gen/deb.rst +++ b/Help/cpack_gen/deb.rst @@ -313,7 +313,7 @@ List of CPack DEB generator specific variables: The compression level used for creating the Debian package. :Mandatory: No - :Default: Automatically determined by the compression tool. + :Default: value of :variable:`CPACK_COMPRESSION_LEVEL` This variable allows fine-tuning of the compression ratio and speed for the Debian package archive. It controls the numeric compression level passed to @@ -323,11 +323,11 @@ List of CPack DEB generator specific variables: The valid range and interpretation depend on the selected compression type: - - ``gzip`` – level 1–9 (default 6) - - ``bzip2`` – level 1–9 (default 9) - - ``xz`` – level 1–9 (default 6) - - ``lzma`` – level 1–9 (default 6) - - ``zstd`` – level 1–19 (default 3) + - ``gzip`` – level 1–9 + - ``bzip2`` – level 1–9 + - ``xz`` – level 1–9 + - ``lzma`` – level 1–9 + - ``zstd`` – level 1–19 Example usage: diff --git a/Help/release/dev/cpack-archive-compression-level.rst b/Help/release/dev/cpack-archive-compression-level.rst new file mode 100644 index 0000000000..b8748d7cec --- /dev/null +++ b/Help/release/dev/cpack-archive-compression-level.rst @@ -0,0 +1,9 @@ +cpack-archive-compression-level +------------------------------- + +* :module:`CPack` gained the :variable:`CPACK_COMPRESSION_LEVEL` + variable to control the compression level used for creating + packages, that supports compression. +* The :cpack_gen:`CPack Archive Generator` gained a new variable + :variable:`CPACK_ARCHIVE_COMPRESSION_LEVEL` to control the + compression level used when creating archive packages. diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 9d039599df..6bae6cfa45 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -338,6 +338,24 @@ installers. The most commonly-used variables are: Other compression methods ignore this value and use only one thread. +.. variable:: CPACK_COMPRESSION_LEVEL + + .. versionadded:: 4.3 + + Select the compression level to use when it's applicable, + such as compressing the installer package. + + Some compression methods used by CPack generators such as Debian or Archive + may take advantage of different compression levels. The accepted values + are in the range ``0`` to ``9``. If you select the ``zstd`` compression method, + you can select the compression level between ``0`` and ``19``, except the ``zip`` + archive format. + + By default ``CPACK_COMPRESSION_LEVEL`` is set to ``0``, which selects the default + compression level. It is selected automatically by the archive library backend and + not directly set by CMake itself. The default compression level + may vary between archive formats, platforms, etc. + Variables for Source Package Generators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake index 12ab6aecb8..046adc2e6b 100644 --- a/Modules/Internal/CPack/CPackDeb.cmake +++ b/Modules/Internal/CPack/CPackDeb.cmake @@ -810,6 +810,9 @@ function(cpack_deb_prepare_package_vars) if(NOT DEFINED CPACK_DEBIAN_COMPRESSION_LEVEL) set(CPACK_DEBIAN_COMPRESSION_LEVEL "0") + if(DEFINED CPACK_COMPRESSION_LEVEL) + set(CPACK_DEBIAN_COMPRESSION_LEVEL "${CPACK_COMPRESSION_LEVEL}") + endif() endif() # Print out some debug information if we were asked for that diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index bee86a8ed4..8ee56374b1 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -392,7 +392,8 @@ int cmCPackArchiveGenerator::addOneComponentToArchive( << (filename) << ">." << std::endl); \ return 0; \ } \ - cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat, 0, \ + cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat, \ + this->GetCompressionLevel(), \ this->GetThreadCount()); \ if (this->UID >= 0 && this->GID >= 0) { \ archive.SetUIDAndGID(this->UID, this->GID); \ @@ -595,3 +596,17 @@ int cmCPackArchiveGenerator::GetThreadCount() const return threads; } + +int cmCPackArchiveGenerator::GetCompressionLevel() const +{ + int level = 0; + + // CPACK_ARCHIVE_COMPRESSION_LEVEL overrides CPACK_COMPRESSION_LEVEL + if (cmValue v = this->GetOptionIfSet("CPACK_ARCHIVE_COMPRESSION_LEVEL")) { + level = std::stoi(*v); + } else if (cmValue v2 = this->GetOptionIfSet("CPACK_COMPRESSION_LEVEL")) { + level = std::stoi(*v2); + } + + return level; +} diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 5088ae0310..22c8bba1ee 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -105,6 +105,7 @@ private: } int GetThreadCount() const; + int GetCompressionLevel() const; private: cmArchiveWrite::Compress Compress; diff --git a/Tests/RunCMake/CPack/7Z_DEFLATE/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/7Z_DEFLATE/packaging_COMPONENT_default.cmake index 81a5035a3d..69e1528538 100644 --- a/Tests/RunCMake/CPack/7Z_DEFLATE/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/7Z_DEFLATE/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_COMPRESSION_LEVEL 7) diff --git a/Tests/RunCMake/CPack/7Z_LZMA2/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/7Z_LZMA2/packaging_COMPONENT_default.cmake index 81a5035a3d..c05e9aac9f 100644 --- a/Tests/RunCMake/CPack/7Z_LZMA2/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/7Z_LZMA2/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_ARCHIVE_COMPRESSION_LEVEL 9) diff --git a/Tests/RunCMake/CPack/7Z_PPMD/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/7Z_PPMD/packaging_COMPONENT_default.cmake index 81a5035a3d..f28a89c342 100644 --- a/Tests/RunCMake/CPack/7Z_PPMD/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/7Z_PPMD/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_COMPRESSION_LEVEL 2) diff --git a/Tests/RunCMake/CPack/7Z_ZSTD/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/7Z_ZSTD/packaging_COMPONENT_default.cmake index 81a5035a3d..b2e3a667e1 100644 --- a/Tests/RunCMake/CPack/7Z_ZSTD/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/7Z_ZSTD/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_ARCHIVE_COMPRESSION_LEVEL 19) diff --git a/Tests/RunCMake/CPack/TGZ/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/TGZ/packaging_COMPONENT_default.cmake index 81a5035a3d..b835889bed 100644 --- a/Tests/RunCMake/CPack/TGZ/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/TGZ/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_COMPRESSION_LEVEL 1) diff --git a/Tests/RunCMake/CPack/TXZ/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/TXZ/packaging_COMPONENT_default.cmake index 81a5035a3d..2a5727999c 100644 --- a/Tests/RunCMake/CPack/TXZ/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/TXZ/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_ARCHIVE_COMPRESSION_LEVEL 4) diff --git a/Tests/RunCMake/CPack/ZIP_DEFLATE/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/ZIP_DEFLATE/packaging_COMPONENT_default.cmake index 81a5035a3d..2a5727999c 100644 --- a/Tests/RunCMake/CPack/ZIP_DEFLATE/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/ZIP_DEFLATE/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_ARCHIVE_COMPRESSION_LEVEL 4) diff --git a/Tests/RunCMake/CPack/ZIP_LZMA2/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/ZIP_LZMA2/packaging_COMPONENT_default.cmake index 81a5035a3d..f75d0d800a 100644 --- a/Tests/RunCMake/CPack/ZIP_LZMA2/packaging_COMPONENT_default.cmake +++ b/Tests/RunCMake/CPack/ZIP_LZMA2/packaging_COMPONENT_default.cmake @@ -1 +1,2 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON") +set(CPACK_ARCHIVE_COMPRESSION_LEVEL 8)