cmake/Source/CPack/cmCPackArchiveGenerator.cxx

506 lines
18 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2010-06-23 01:18:35 +03:00
#include "cmCPackArchiveGenerator.h"
2020-02-01 23:06:01 +01:00
#include <cstring>
#include <map>
#include <ostream>
2024-04-14 22:45:38 +02:00
#include <unordered_map>
#include <unordered_set>
2020-02-01 23:06:01 +01:00
#include <utility>
#include <vector>
2016-10-30 18:24:19 +01:00
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
2016-07-09 11:21:54 +02:00
#include "cmCPackLog.h"
#include "cmGeneratedFileStream.h"
2020-02-01 23:06:01 +01:00
#include "cmStringAlgorithms.h"
2016-07-09 11:21:54 +02:00
#include "cmSystemTools.h"
2021-11-20 13:41:27 +01:00
#include "cmValue.h"
2017-07-20 19:35:53 +02:00
#include "cmWorkingDirectory.h"
2010-06-23 01:18:35 +03:00
2024-04-14 22:45:38 +02:00
enum class DeduplicateStatus
{
Skip,
Add,
Error
};
/**
* @class cmCPackArchiveGenerator::Deduplicator
* @brief A utility class for deduplicating files, folders, and symlinks.
*
* This class is responsible for identifying duplicate files, folders, and
* symlinks when generating an archive. It keeps track of the paths that have
* been processed and helps in deciding whether a new path should be added,
* skipped, or flagged as an error.
*/
class cmCPackArchiveGenerator::Deduplicator
{
private:
/**
* @brief Compares a file with already processed files.
*
* @param path The path of the file to compare.
* @param localTopLevel The top-level directory for the file.
* @return DeduplicateStatus indicating whether to add, skip, or flag an
* error for the file.
*/
DeduplicateStatus CompareFile(const std::string& path,
const std::string& localTopLevel)
{
auto fileItr = this->Files.find(path);
if (fileItr != this->Files.end()) {
return cmSystemTools::FilesDiffer(path, fileItr->second)
? DeduplicateStatus::Error
: DeduplicateStatus::Skip;
}
this->Files[path] = cmStrCat(localTopLevel, "/", path);
return DeduplicateStatus::Add;
}
/**
* @brief Compares a folder with already processed folders.
*
* @param path The path of the folder to compare.
* @return DeduplicateStatus indicating whether to add or skip the folder.
*/
DeduplicateStatus CompareFolder(const std::string& path)
{
if (this->Folders.find(path) != this->Folders.end()) {
return DeduplicateStatus::Skip;
}
this->Folders.emplace(path);
return DeduplicateStatus::Add;
}
/**
* @brief Compares a symlink with already processed symlinks.
*
* @param path The path of the symlink to compare.
* @return DeduplicateStatus indicating whether to add, skip, or flag an
* error for the symlink.
*/
DeduplicateStatus CompareSymlink(const std::string& path)
{
auto symlinkItr = this->Symlink.find(path);
std::string symlinkValue;
auto status = cmSystemTools::ReadSymlink(path, symlinkValue);
if (!status.IsSuccess()) {
return DeduplicateStatus::Error;
}
if (symlinkItr != this->Symlink.end()) {
return symlinkValue == symlinkItr->second ? DeduplicateStatus::Skip
: DeduplicateStatus::Error;
}
this->Symlink[path] = symlinkValue;
return DeduplicateStatus::Add;
}
public:
/**
* @brief Determines the deduplication status of a given path.
*
* This method identifies whether the given path is a file, folder, or
* symlink and then delegates to the appropriate comparison method.
*
* @param path The path to check for deduplication.
* @param localTopLevel The top-level directory for the path.
* @return DeduplicateStatus indicating the action to take for the given
* path.
*/
DeduplicateStatus IsDeduplicate(const std::string& path,
const std::string& localTopLevel)
{
DeduplicateStatus status;
if (cmSystemTools::FileIsDirectory(path)) {
status = this->CompareFolder(path);
} else if (cmSystemTools::FileIsSymlink(path)) {
status = this->CompareSymlink(path);
} else {
status = this->CompareFile(path, localTopLevel);
}
return status;
}
private:
std::unordered_map<std::string, std::string> Symlink;
std::unordered_set<std::string> Folders;
std::unordered_map<std::string, std::string> Files;
};
2020-02-01 23:06:01 +01:00
cmCPackGenerator* cmCPackArchiveGenerator::Create7ZGenerator()
{
return new cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "7zip",
".7z");
}
cmCPackGenerator* cmCPackArchiveGenerator::CreateTBZ2Generator()
{
return new cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr",
".tar.bz2");
}
cmCPackGenerator* cmCPackArchiveGenerator::CreateTGZGenerator()
{
return new cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr",
".tar.gz");
}
cmCPackGenerator* cmCPackArchiveGenerator::CreateTXZGenerator()
{
return new cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr",
".tar.xz");
}
cmCPackGenerator* cmCPackArchiveGenerator::CreateTZGenerator()
{
return new cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, "paxr",
".tar.Z");
}
cmCPackGenerator* cmCPackArchiveGenerator::CreateTZSTGenerator()
{
return new cmCPackArchiveGenerator(cmArchiveWrite::CompressZstd, "paxr",
".tar.zst");
}
cmCPackGenerator* cmCPackArchiveGenerator::CreateZIPGenerator()
{
return new cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "zip",
".zip");
}
2010-06-23 01:18:35 +03:00
2020-02-01 23:06:01 +01:00
cmCPackArchiveGenerator::cmCPackArchiveGenerator(
cmArchiveWrite::Compress compress, std::string format, std::string extension)
: Compress(compress)
, ArchiveFormat(std::move(format))
, OutputExtension(std::move(extension))
2010-06-23 01:18:35 +03:00
{
}
2019-11-11 23:01:05 +01:00
cmCPackArchiveGenerator::~cmCPackArchiveGenerator() = default;
2010-06-23 01:18:35 +03:00
2017-07-20 19:35:53 +02:00
std::string cmCPackArchiveGenerator::GetArchiveComponentFileName(
const std::string& component, bool isGroupName)
{
std::string componentUpper(cmSystemTools::UpperCase(component));
std::string packageFileName;
if (this->IsSet("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME")) {
packageFileName +=
2021-11-20 13:41:27 +01:00
*this->GetOption("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME");
2017-07-20 19:35:53 +02:00
} else if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) {
2021-09-14 00:13:48 +02:00
packageFileName += this->GetComponentPackageFileName(
2023-05-23 16:38:00 +02:00
*this->GetOption("CPACK_ARCHIVE_FILE_NAME"), component, isGroupName);
2017-07-20 19:35:53 +02:00
} else {
2021-09-14 00:13:48 +02:00
packageFileName += this->GetComponentPackageFileName(
2023-05-23 16:38:00 +02:00
*this->GetOption("CPACK_PACKAGE_FILE_NAME"), component, isGroupName);
2017-07-20 19:35:53 +02:00
}
packageFileName += this->GetOutputExtension();
return packageFileName;
}
2010-11-13 01:00:53 +02:00
int cmCPackArchiveGenerator::InitializeInternal()
2010-06-23 01:18:35 +03:00
{
2010-11-13 01:00:53 +02:00
this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
2022-11-16 20:14:03 +01:00
cmValue newExtensionValue = this->GetOption("CPACK_ARCHIVE_FILE_EXTENSION");
if (!newExtensionValue.IsEmpty()) {
std::string newExtension = *newExtensionValue;
if (!cmHasLiteralPrefix(newExtension, ".")) {
newExtension = cmStrCat('.', newExtension);
}
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Using user-provided file extension "
<< newExtension << " instead of the default "
<< this->OutputExtension << std::endl);
this->OutputExtension = std::move(newExtension);
}
2010-11-13 01:00:53 +02:00
return this->Superclass::InitializeInternal();
}
2018-08-09 18:06:22 +02:00
2016-07-09 11:21:54 +02:00
int cmCPackArchiveGenerator::addOneComponentToArchive(
2024-04-14 22:45:38 +02:00
cmArchiveWrite& archive, cmCPackComponent* component,
Deduplicator* deduplicator)
2010-06-23 01:18:35 +03:00
{
2016-07-09 11:21:54 +02:00
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
" - packaging component: " << component->Name << std::endl);
2010-11-13 01:00:53 +02:00
// Add the files of this component to the archive
std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
2016-07-09 11:21:54 +02:00
localToplevel += "/" + component->Name;
2010-11-13 01:00:53 +02:00
// Change to local toplevel
2017-07-20 19:35:53 +02:00
cmWorkingDirectory workdir(localToplevel);
2018-08-09 18:06:22 +02:00
if (workdir.Failed()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Failed to change working directory to "
<< localToplevel << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl);
return 0;
}
2012-04-19 19:04:21 +03:00
std::string filePrefix;
2016-07-09 11:21:54 +02:00
if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) {
2020-02-01 23:06:01 +01:00
filePrefix = cmStrCat(this->GetOption("CPACK_PACKAGE_FILE_NAME"), '/');
2016-07-09 11:21:54 +02:00
}
2021-11-20 13:41:27 +01:00
cmValue installPrefix = this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
if (installPrefix && installPrefix->size() > 1 &&
(*installPrefix)[0] == '/') {
2015-08-17 11:37:30 +02:00
// add to file prefix and remove the leading '/'
2021-11-20 13:41:27 +01:00
filePrefix += installPrefix->substr(1);
2015-08-17 11:37:30 +02:00
filePrefix += "/";
2016-07-09 11:21:54 +02:00
}
2018-01-26 17:06:56 +01:00
for (std::string const& file : component->Files) {
std::string rp = filePrefix + file;
2024-04-14 22:45:38 +02:00
DeduplicateStatus status = DeduplicateStatus::Add;
if (deduplicator != nullptr) {
status = deduplicator->IsDeduplicate(rp, localToplevel);
}
if (deduplicator == nullptr || status == DeduplicateStatus::Add) {
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file: " << rp << std::endl);
archive.Add(rp, 0, nullptr, false);
} else if (status == DeduplicateStatus::Error) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"ERROR The data in files with the "
"same filename is different.");
return 0;
} else {
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Passing file: " << rp << std::endl);
}
2016-07-09 11:21:54 +02:00
if (!archive) {
2018-08-09 18:06:22 +02:00
cmCPackLogger(cmCPackLog::LOG_ERROR,
"ERROR while packaging files: " << archive.GetError()
<< std::endl);
2010-11-13 01:00:53 +02:00
return 0;
2010-06-23 01:18:35 +03:00
}
2016-07-09 11:21:54 +02:00
}
2010-11-13 01:00:53 +02:00
return 1;
2010-06-23 01:18:35 +03:00
}
2010-11-13 01:00:53 +02:00
/*
* The macro will open/create a file 'filename'
* an declare and open the associated
* cmArchiveWrite 'archive' object.
*/
2016-07-09 11:21:54 +02:00
#define DECLARE_AND_OPEN_ARCHIVE(filename, archive) \
cmGeneratedFileStream gf; \
2018-10-28 12:09:07 +01:00
gf.Open((filename), false, true); \
2016-07-09 11:21:54 +02:00
if (!GenerateHeader(&gf)) { \
cmCPackLogger(cmCPackLog::LOG_ERROR, \
2018-10-28 12:09:07 +01:00
"Problem to generate Header for archive <" \
2016-10-30 18:24:19 +01:00
<< (filename) << ">." << std::endl); \
2016-07-09 11:21:54 +02:00
return 0; \
} \
2021-09-14 00:13:48 +02:00
cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat, 0, \
this->GetThreadCount()); \
2019-11-11 23:01:05 +01:00
do { \
2020-08-30 11:54:41 +02:00
if (!archive.Open()) { \
cmCPackLogger(cmCPackLog::LOG_ERROR, \
"Problem to open archive <" \
<< (filename) << ">, ERROR = " << (archive).GetError() \
<< std::endl); \
return 0; \
} \
2019-11-11 23:01:05 +01:00
if (!(archive)) { \
cmCPackLogger(cmCPackLog::LOG_ERROR, \
"Problem to create archive <" \
<< (filename) << ">, ERROR = " << (archive).GetError() \
<< std::endl); \
return 0; \
} \
} while (false)
2010-06-23 01:18:35 +03:00
2011-01-16 11:35:12 +01:00
int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
2010-06-23 01:18:35 +03:00
{
2021-09-14 00:13:48 +02:00
this->packageFileNames.clear();
2010-11-13 01:00:53 +02:00
// The default behavior is to have one package by component group
// unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
2016-07-09 11:21:54 +02:00
if (!ignoreGroup) {
2018-01-26 17:06:56 +01:00
for (auto const& compG : this->ComponentGroups) {
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging component group: " << compG.first << std::endl);
2010-11-13 01:00:53 +02:00
// Begin the archive for this group
2021-09-14 00:13:48 +02:00
std::string packageFileName = std::string(this->toplevel) + "/" +
2018-01-26 17:06:56 +01:00
this->GetArchiveComponentFileName(compG.first, true);
2017-07-20 19:35:53 +02:00
2024-04-14 22:45:38 +02:00
Deduplicator deduplicator;
2010-11-13 01:00:53 +02:00
// open a block in order to automatically close archive
// at the end of the block
{
2016-07-09 11:21:54 +02:00
DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
2010-11-13 01:00:53 +02:00
// now iterate over the component of this group
2018-01-26 17:06:56 +01:00
for (cmCPackComponent* comp : (compG.second).Components) {
2010-11-13 01:00:53 +02:00
// Add the files of this component to the archive
2024-04-14 22:45:38 +02:00
this->addOneComponentToArchive(archive, comp, &deduplicator);
2016-07-09 11:21:54 +02:00
}
2010-11-13 01:00:53 +02:00
}
// add the generated package to package file names list
2021-09-14 00:13:48 +02:00
this->packageFileNames.push_back(std::move(packageFileName));
2016-07-09 11:21:54 +02:00
}
2011-06-19 15:41:06 +03:00
// Handle Orphan components (components not belonging to any groups)
2018-01-26 17:06:56 +01:00
for (auto& comp : this->Components) {
2011-06-19 15:41:06 +03:00
// Does the component belong to a group?
2018-01-26 17:06:56 +01:00
if (comp.second.Group == nullptr) {
2016-07-09 11:21:54 +02:00
cmCPackLogger(
2018-08-09 18:06:22 +02:00
cmCPackLog::LOG_VERBOSE,
"Component <"
2018-01-26 17:06:56 +01:00
<< comp.second.Name
2016-07-09 11:21:54 +02:00
<< "> does not belong to any group, package it separately."
<< std::endl);
2011-06-19 15:41:06 +03:00
std::string localToplevel(
2016-07-09 11:21:54 +02:00
this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
2021-09-14 00:13:48 +02:00
std::string packageFileName = std::string(this->toplevel);
2011-06-19 15:41:06 +03:00
2018-01-26 17:06:56 +01:00
localToplevel += "/" + comp.first;
2017-07-20 19:35:53 +02:00
packageFileName +=
2018-01-26 17:06:56 +01:00
"/" + this->GetArchiveComponentFileName(comp.first, false);
2017-07-20 19:35:53 +02:00
2011-06-19 15:41:06 +03:00
{
2016-07-09 11:21:54 +02:00
DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
2011-06-19 15:41:06 +03:00
// Add the files of this component to the archive
2024-04-14 22:45:38 +02:00
this->addOneComponentToArchive(archive, &(comp.second), nullptr);
2011-06-19 15:41:06 +03:00
}
// add the generated package to package file names list
2021-09-14 00:13:48 +02:00
this->packageFileNames.push_back(std::move(packageFileName));
2011-06-19 15:41:06 +03:00
}
2010-06-23 01:18:35 +03:00
}
2016-07-09 11:21:54 +02:00
}
2010-11-13 01:00:53 +02:00
// CPACK_COMPONENTS_IGNORE_GROUPS is set
// We build 1 package per component
2016-07-09 11:21:54 +02:00
else {
2018-01-26 17:06:56 +01:00
for (auto& comp : this->Components) {
2010-11-13 01:00:53 +02:00
std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
2021-09-14 00:13:48 +02:00
std::string packageFileName = std::string(this->toplevel);
2010-11-13 01:00:53 +02:00
2018-01-26 17:06:56 +01:00
localToplevel += "/" + comp.first;
2017-07-20 19:35:53 +02:00
packageFileName +=
2018-01-26 17:06:56 +01:00
"/" + this->GetArchiveComponentFileName(comp.first, false);
2017-07-20 19:35:53 +02:00
2010-11-13 01:00:53 +02:00
{
2016-07-09 11:21:54 +02:00
DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
2010-11-13 01:00:53 +02:00
// Add the files of this component to the archive
2024-04-14 22:45:38 +02:00
this->addOneComponentToArchive(archive, &(comp.second), nullptr);
2010-11-13 01:00:53 +02:00
}
// add the generated package to package file names list
2021-09-14 00:13:48 +02:00
this->packageFileNames.push_back(std::move(packageFileName));
2010-06-23 01:18:35 +03:00
}
2016-07-09 11:21:54 +02:00
}
2010-11-13 01:00:53 +02:00
return 1;
2010-06-23 01:18:35 +03:00
}
2011-06-19 15:41:06 +03:00
int cmCPackArchiveGenerator::PackageComponentsAllInOne()
2010-06-23 01:18:35 +03:00
{
2010-11-13 01:00:53 +02:00
// reset the package file names
2021-09-14 00:13:48 +02:00
this->packageFileNames.clear();
this->packageFileNames.emplace_back(this->toplevel);
this->packageFileNames[0] += "/";
2017-07-20 19:35:53 +02:00
if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) {
2021-11-20 13:41:27 +01:00
this->packageFileNames[0] += *this->GetOption("CPACK_ARCHIVE_FILE_NAME");
2017-07-20 19:35:53 +02:00
} else {
2021-11-20 13:41:27 +01:00
this->packageFileNames[0] += *this->GetOption("CPACK_PACKAGE_FILE_NAME");
2017-07-20 19:35:53 +02:00
}
2021-09-14 00:13:48 +02:00
this->packageFileNames[0] += this->GetOutputExtension();
2017-07-20 19:35:53 +02:00
2010-11-13 01:00:53 +02:00
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging all groups in one package..."
"(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE is set)"
2016-07-09 11:21:54 +02:00
<< std::endl);
DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);
2010-11-13 01:00:53 +02:00
2024-04-14 22:45:38 +02:00
Deduplicator deduplicator;
2011-06-19 15:41:06 +03:00
// The ALL COMPONENTS in ONE package case
2018-01-26 17:06:56 +01:00
for (auto& comp : this->Components) {
2011-06-19 15:41:06 +03:00
// Add the files of this component to the archive
2024-04-14 22:45:38 +02:00
this->addOneComponentToArchive(archive, &(comp.second), &deduplicator);
2016-07-09 11:21:54 +02:00
}
2011-06-19 15:41:06 +03:00
2010-11-13 01:00:53 +02:00
// archive goes out of scope so it will finalized and closed.
return 1;
2010-06-23 01:18:35 +03:00
}
2010-11-13 01:00:53 +02:00
int cmCPackArchiveGenerator::PackageFiles()
2010-06-23 01:18:35 +03:00
{
2021-09-14 00:13:48 +02:00
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Toplevel: " << this->toplevel << std::endl);
2010-06-23 01:18:35 +03:00
2021-09-14 00:13:48 +02:00
if (this->WantsComponentInstallation()) {
2011-01-16 11:35:12 +01:00
// CASE 1 : COMPONENT ALL-IN-ONE package
2011-06-19 15:41:06 +03:00
// If ALL COMPONENTS in ONE package has been requested
2011-01-16 11:35:12 +01:00
// then the package file is unique and should be open here.
2021-09-14 00:13:48 +02:00
if (this->componentPackageMethod == ONE_PACKAGE) {
return this->PackageComponentsAllInOne();
2016-07-09 11:21:54 +02:00
}
2011-01-16 11:35:12 +01:00
// CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
// There will be 1 package for each component group
// however one may require to ignore component group and
// in this case you'll get 1 package for each component.
2021-09-14 00:13:48 +02:00
return this->PackageComponents(this->componentPackageMethod ==
ONE_PACKAGE_PER_COMPONENT);
2010-11-13 01:00:53 +02:00
}
// CASE 3 : NON COMPONENT package.
2016-07-09 11:21:54 +02:00
DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);
2021-09-14 00:13:48 +02:00
cmWorkingDirectory workdir(this->toplevel);
2018-08-09 18:06:22 +02:00
if (workdir.Failed()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Failed to change working directory to "
2021-09-14 00:13:48 +02:00
<< this->toplevel << " : "
2018-08-09 18:06:22 +02:00
<< std::strerror(workdir.GetLastResult()) << std::endl);
return 0;
}
2021-09-14 00:13:48 +02:00
for (std::string const& file : this->files) {
2010-06-23 01:18:35 +03:00
// Get the relative path to the file
2021-09-14 00:13:48 +02:00
std::string rp = cmSystemTools::RelativePath(this->toplevel, file);
2018-01-26 17:06:56 +01:00
archive.Add(rp, 0, nullptr, false);
2016-07-09 11:21:54 +02:00
if (!archive) {
2018-08-09 18:06:22 +02:00
cmCPackLogger(cmCPackLog::LOG_ERROR,
2018-10-28 12:09:07 +01:00
"Problem while adding file <"
2021-09-14 00:13:48 +02:00
<< file << "> to archive <" << this->packageFileNames[0]
2018-10-28 12:09:07 +01:00
<< ">, ERROR = " << archive.GetError() << std::endl);
2010-11-13 01:00:53 +02:00
return 0;
2010-06-23 01:18:35 +03:00
}
2016-07-09 11:21:54 +02:00
}
2010-11-13 01:00:53 +02:00
// The destructor of cmArchiveWrite will close and finish the write
2010-06-23 01:18:35 +03:00
return 1;
}
2016-10-30 18:24:19 +01:00
int cmCPackArchiveGenerator::GenerateHeader(std::ostream* /*unused*/)
2010-06-23 01:18:35 +03:00
{
return 1;
}
2010-11-13 01:00:53 +02:00
2016-07-09 11:21:54 +02:00
bool cmCPackArchiveGenerator::SupportsComponentInstallation() const
{
2011-01-16 11:35:12 +01:00
// The Component installation support should only
// be activated if explicitly requested by the user
// (for backward compatibility reason)
2021-09-14 00:13:48 +02:00
return this->IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL");
2010-11-13 01:00:53 +02:00
}
2020-08-30 11:54:41 +02:00
2021-09-14 00:13:48 +02:00
int cmCPackArchiveGenerator::GetThreadCount() const
2020-08-30 11:54:41 +02:00
{
2021-09-14 00:13:48 +02:00
int threads = 1;
2020-08-30 11:54:41 +02:00
2021-09-14 00:13:48 +02:00
// CPACK_ARCHIVE_THREADS overrides CPACK_THREADS
if (this->IsSet("CPACK_ARCHIVE_THREADS")) {
2023-05-23 16:38:00 +02:00
threads = std::stoi(*this->GetOption("CPACK_ARCHIVE_THREADS"));
2021-09-14 00:13:48 +02:00
} else if (this->IsSet("CPACK_THREADS")) {
2023-05-23 16:38:00 +02:00
threads = std::stoi(*this->GetOption("CPACK_THREADS"));
2020-08-30 11:54:41 +02:00
}
2021-09-14 00:13:48 +02:00
return threads;
2020-08-30 11:54:41 +02:00
}