1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

CPack: Add support for multiple checksums per package

Closes: #27174
This commit is contained in:
Sergiu Deitsch
2025-08-29 23:30:30 +02:00
committed by Brad King
parent 00185a62cf
commit bc1c295b95
7 changed files with 84 additions and 15 deletions

View File

@@ -0,0 +1,4 @@
cpack-several-checksums
-----------------------
* :variable:`CPACK_PACKAGE_CHECKSUM` now supports multiple values.

View File

@@ -204,8 +204,8 @@ installers. The most commonly-used variables are:
.. versionadded:: 3.7
An algorithm that will be used to generate an additional file with the
checksum of the package. The output file name will be:
One or multiple algorithms that will be used to generate additional files with
the checksum of the package. The output file names will be:
.. code-block:: cmake
@@ -214,6 +214,9 @@ installers. The most commonly-used variables are:
Supported algorithms are those listed by the
:ref:`string(\<HASH\>) <Supported Hash Algorithms>` command.
.. versionchanged:: 4.2
The variable accepts a list of algorithms.
.. variable:: CPACK_PROJECT_CONFIG_FILE
CPack-time project CPack configuration file. This file is included at cpack

View File

@@ -3,6 +3,7 @@
#include "cmCPackGenerator.h"
#include <algorithm>
#include <iterator>
#include <memory>
#include <utility>
@@ -174,14 +175,42 @@ int cmCPackGenerator::PrepareNames()
return 0;
}
// Check algorithm for calculating the checksum of the package.
cmValue algoSignature = this->GetOption("CPACK_PACKAGE_CHECKSUM");
if (algoSignature) {
if (!cmCryptoHash::New(*algoSignature)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Cannot recognize algorithm: " << algoSignature
<< std::endl);
return 0;
// Check algorithms for calculating the checksum of the package.
cmValue algoSignatures = this->GetOption("CPACK_PACKAGE_CHECKSUM");
if (cmNonempty(algoSignatures)) {
cmList algoList{ algoSignatures };
// Workout unique algorithms and duplicates for diagnostic purposes
algoList.sort();
// Store a copy since std::unique modifies the sequence
cmList const sortedAlgoList = algoList;
auto const newEnd = std::unique(algoList.begin(), algoList.end());
if (newEnd != algoList.end()) {
cmList duplicatesAlgoList;
std::set_difference(sortedAlgoList.begin(), sortedAlgoList.end(),
algoList.begin(), newEnd,
std::back_inserter(duplicatesAlgoList));
// Make sure to output duplicates a single time even if these appear more
// than two times. Exploit the already sorted sequence to determine the
// unique elements.
duplicatesAlgoList.erase(
std::unique(duplicatesAlgoList.begin(), duplicatesAlgoList.end()),
duplicatesAlgoList.end());
cmCPackLogger(cmCPackLog::LOG_WARNING,
"Algorithm specified multiple times: "
<< duplicatesAlgoList.join(", ") << std::endl);
}
algoList.erase(newEnd, algoList.end());
for (std::string const& algo : algoList) {
if (!cmCryptoHash::New(algo)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Cannot recognize algorithm: " << algo << std::endl);
return 0;
}
}
}
@@ -1200,8 +1229,22 @@ int cmCPackGenerator::DoPackage()
}
/* Prepare checksum algorithm*/
cmValue algo = this->GetOption("CPACK_PACKAGE_CHECKSUM");
std::unique_ptr<cmCryptoHash> crypto = cmCryptoHash::New(*algo);
cmValue algoSignatures = this->GetOption("CPACK_PACKAGE_CHECKSUM");
std::vector<std::unique_ptr<cmCryptoHash>> crypto;
if (cmNonempty(algoSignatures)) {
cmList algoList{ algoSignatures };
// Keep unique algorithms since generating the same checksum multiple times
// is not meaningful.
algoList.remove_duplicates();
crypto.reserve(algoList.size());
for (std::string const& algo : algoList) {
if (std::unique_ptr<cmCryptoHash> hash = cmCryptoHash::New(algo)) {
crypto.push_back(std::move(hash));
}
}
}
/*
* Copy the generated packages to final destination
@@ -1218,9 +1261,9 @@ int cmCPackGenerator::DoPackage()
if (!this->CopyPackageFile(pkgFileName, filename)) {
return 0;
}
/* Generate checksum file */
if (crypto) {
if (!this->GenerateChecksumFile(*crypto, filename)) {
/* Generate checksum files */
for (std::unique_ptr<cmCryptoHash> const& hash : crypto) {
if (!this->GenerateChecksumFile(*hash, filename)) {
return 0;
}
}

View File

@@ -41,6 +41,7 @@ run_cpack_test_package_target(MINIMAL "RPM.MINIMAL;DEB.MINIMAL;7Z;TBZ2;TGZ;TXZ;T
run_cpack_test_package_target(THREADED_ALL "TXZ;DEB" false "MONOLITHIC;COMPONENT")
run_cpack_test_package_target(THREADED "TXZ;DEB" false "MONOLITHIC;COMPONENT")
run_cpack_test_subtests(PACKAGE_CHECKSUM "invalid;MD5;SHA1;SHA224;SHA256;SHA384;SHA512" "TGZ" false "MONOLITHIC")
run_cpack_test(PACKAGE_CHECKSUM_MULTIPLE "TGZ" false "MONOLITHIC")
run_cpack_test(PARTIALLY_RELOCATABLE_WARNING "RPM.PARTIALLY_RELOCATABLE_WARNING" false "COMPONENT")
run_cpack_test(PER_COMPONENT_FIELDS "RPM.PER_COMPONENT_FIELDS;DEB.PER_COMPONENT_FIELDS" false "COMPONENT")
run_cpack_test_subtests(SINGLE_DEBUGINFO "no_main_component" "RPM.SINGLE_DEBUGINFO" true "CUSTOM")

View File

@@ -0,0 +1,2 @@
set(EXPECTED_FILES_COUNT "1")
set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")

View File

@@ -0,0 +1,14 @@
set(hash_algos MD5 SHA1 SHA224 SHA256 SHA384 SHA512)
file(GLOB PACKAGE RELATIVE "${bin_dir}" "*.tar.gz")
foreach(algo IN LISTS hash_algos)
string(TOLOWER ${algo} CHECKSUM_EXTENSION)
file(STRINGS ${PACKAGE}.${CHECKSUM_EXTENSION} CHSUM_VALUE)
file(${algo} ${PACKAGE} expected_value)
set(expected_value "${expected_value} ${PACKAGE}")
if(NOT expected_value STREQUAL CHSUM_VALUE)
message(FATAL_ERROR "Generated checksum is not valid! Expected [${expected_value}] Got [${CHSUM_VALUE}]")
endif()
endforeach()

View File

@@ -0,0 +1,2 @@
install(FILES CMakeLists.txt DESTINATION foo)
set(CPACK_PACKAGE_CHECKSUM MD5 SHA1 SHA224 SHA256 SHA384 SHA512)