CPack: Add option to generate a checksum file next to each package file

Add variable CPACK_PACKAGE_CHECKSUM to activate it.
This commit is contained in:
Petr Orlov 2016-08-31 18:05:15 +03:00 committed by Brad King
parent 4682b42bdb
commit 1c63aa4d43
8 changed files with 76 additions and 1 deletions

View File

@ -0,0 +1,5 @@
cpack.hash_computing
--------------------
* CPack gained a new :variable:`CPACK_PACKAGE_CHECKSUM` variable to
enable generation of a checksum file for each package file.

View File

@ -116,6 +116,15 @@
# A branding image that will be displayed inside the installer (used by GUI # A branding image that will be displayed inside the installer (used by GUI
# installers). # installers).
# #
# .. variable:: CPACK_PACKAGE_CHECKSUM
#
# An algorithm that will be used to generate additional file with checksum
# of the package. Output file name will be::
#
# ${CPACK_PACKAGE_FILE_NAME}.${CPACK_PACKAGE_CHECKSUM}
#
# Current supported alogorithms: MD5|SHA1|SHA224|SHA256|SHA384|SHA512.
#
# .. variable:: CPACK_PROJECT_CONFIG_FILE # .. variable:: CPACK_PROJECT_CONFIG_FILE
# #
# CPack-time project CPack configuration file. This file included at cpack # CPack-time project CPack configuration file. This file included at cpack

View File

@ -14,6 +14,7 @@
#include "cmCPackComponentGroup.h" #include "cmCPackComponentGroup.h"
#include "cmCPackLog.h" #include "cmCPackLog.h"
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h" #include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmMakefile.h" #include "cmMakefile.h"
@ -163,6 +164,14 @@ int cmCPackGenerator::PrepareNames()
<< std::endl); << std::endl);
return 0; return 0;
} }
const char* algoSignature = this->GetOption("CPACK_PACKAGE_CHECKSUM");
if (algoSignature) {
if (cmCryptoHash::New(algoSignature).get() == CM_NULLPTR) {
cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot recognize algorithm: "
<< algoSignature << std::endl);
return 0;
}
}
this->SetOptionIfNotSet("CPACK_REMOVE_TOPLEVEL_DIRECTORY", "1"); this->SetOptionIfNotSet("CPACK_REMOVE_TOPLEVEL_DIRECTORY", "1");
@ -980,6 +989,10 @@ int cmCPackGenerator::DoPackage()
return 0; return 0;
} }
/* Prepare checksum algorithm*/
const char* algo = this->GetOption("CPACK_PACKAGE_CHECKSUM");
CM_AUTO_PTR<cmCryptoHash> crypto = cmCryptoHash::New(algo ? algo : "");
/* /*
* Copy the generated packages to final destination * Copy the generated packages to final destination
* - there may be several of them * - there may be several of them
@ -992,8 +1005,9 @@ int cmCPackGenerator::DoPackage()
/* now copy package one by one */ /* now copy package one by one */
for (it = packageFileNames.begin(); it != packageFileNames.end(); ++it) { for (it = packageFileNames.begin(); it != packageFileNames.end(); ++it) {
std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX")); std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
std::string filename(cmSystemTools::GetFilenameName(*it));
tempPackageFileName = it->c_str(); tempPackageFileName = it->c_str();
tmpPF += "/" + cmSystemTools::GetFilenameName(*it); tmpPF += "/" + filename;
const char* packageFileName = tmpPF.c_str(); const char* packageFileName = tmpPF.c_str();
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): " cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): "
<< (tempPackageFileName ? tempPackageFileName : "(NULL)") << (tempPackageFileName ? tempPackageFileName : "(NULL)")
@ -1009,6 +1023,23 @@ int cmCPackGenerator::DoPackage()
} }
cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- package: " cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- package: "
<< packageFileName << " generated." << std::endl); << packageFileName << " generated." << std::endl);
/* Generate checksum file */
if (crypto.get() != CM_NULLPTR) {
std::string hashFile(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
hashFile +=
"/" + filename.substr(0, filename.rfind(this->GetOutputExtension()));
hashFile += "." + cmSystemTools::LowerCase(algo);
cmsys::ofstream outF(hashFile.c_str());
if (!outF) {
cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create checksum file: "
<< hashFile << std::endl);
return 0;
}
outF << crypto->HashFile(packageFileName) << " " << filename << "\n";
cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- checksum file: "
<< hashFile << " generated." << std::endl);
}
} }
return 1; return 1;

View File

@ -0,0 +1,4 @@
install(FILES CMakeLists.txt DESTINATION foo)
set(CPACK_PACKAGE_NAME "package_checksum")
set(CPACK_PACKAGE_CHECKSUM ${RunCMake_SUBTEST_SUFFIX})

View File

@ -18,3 +18,4 @@ run_cpack_test(DEB_GENERATE_SHLIBS "DEB" true)
run_cpack_test(DEB_GENERATE_SHLIBS_LDCONFIG "DEB" true) run_cpack_test(DEB_GENERATE_SHLIBS_LDCONFIG "DEB" true)
run_cpack_test(DEBUGINFO "RPM" true) run_cpack_test(DEBUGINFO "RPM" true)
run_cpack_test(LONG_FILENAMES "DEB" false) run_cpack_test(LONG_FILENAMES "DEB" false)
run_cpack_test_subtests(PACKAGE_CHECKSUM "invalid;MD5;SHA1;SHA224;SHA256;SHA384;SHA512" "TGZ" false)

View File

@ -0,0 +1,9 @@
set(whitespaces_ "[\t\n\r ]*")
set(EXPECTED_FILES_COUNT "0")
if (NOT ${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid")
set(EXPECTED_FILES_COUNT "1")
set(EXPECTED_FILE_1 "package_checksum*.tar.gz")
set(EXPECTED_FILE_CONTENT_1 "^[^\n]*package_checksum*-[^\n]*/foo/\n[^\n]*package_checksum-[^\n]*/foo/CMakeLists.txt$")
endif()

View File

@ -0,0 +1,14 @@
if(NOT ${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid")
string(TOLOWER ${RunCMake_SUBTEST_SUFFIX} EXTENSION)
file(GLOB PACKAGE RELATIVE ${bin_dir} "*.tar.gz")
file(GLOB CSUMFILE RELATIVE ${bin_dir} "*.${EXTENSION}")
file(STRINGS ${CSUMFILE} CHSUM_VALUE)
file(${RunCMake_SUBTEST_SUFFIX} ${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()
else()
message(${error})
endif()

View File

@ -0,0 +1,2 @@
^CPack Error: Cannot recognize algorithm: invalid
CPack Error: Error when generating package: package_checksum$