summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorAsit Dhal <dhal.asitk@gmail.com>2020-09-17 17:29:31 (GMT)
committerBrad King <brad.king@kitware.com>2020-09-21 17:08:11 (GMT)
commit195d14e7818244789638fffd2087b8b2d0952622 (patch)
tree7e46f8f1f6dfbb60dc73bb600e1190369bc00bc0 /Source
parent4fc07cd369cd46fbd859f140eda971d00ac52704 (diff)
downloadCMake-195d14e7818244789638fffd2087b8b2d0952622.zip
CMake-195d14e7818244789638fffd2087b8b2d0952622.tar.gz
CMake-195d14e7818244789638fffd2087b8b2d0952622.tar.bz2
file(ARCHIVE_CREATE): Add option to control compression level
Fixes: #21125
Diffstat (limited to 'Source')
-rw-r--r--Source/cmArchiveWrite.cxx37
-rw-r--r--Source/cmArchiveWrite.h2
-rw-r--r--Source/cmFileCommand.cxx52
-rw-r--r--Source/cmSystemTools.cxx5
-rw-r--r--Source/cmSystemTools.h3
5 files changed, 83 insertions, 16 deletions
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index addfbff..356089b 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -81,7 +81,7 @@ struct cmArchiveWrite::Callback
};
cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
- std::string const& format)
+ std::string const& format, int compressionLevel)
: Stream(os)
, Archive(archive_write_new())
, Disk(archive_read_disk_new())
@@ -151,6 +151,41 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
}
break;
}
+
+ if (compressionLevel != 0) {
+ std::string compressionLevelStr = std::to_string(compressionLevel);
+ std::string archiveFilterName;
+ switch (c) {
+ case CompressNone:
+ case CompressCompress:
+ break;
+ case CompressGZip:
+ archiveFilterName = "gzip";
+ break;
+ case CompressBZip2:
+ archiveFilterName = "bzip2";
+ break;
+ case CompressLZMA:
+ archiveFilterName = "lzma";
+ break;
+ case CompressXZ:
+ archiveFilterName = "xz";
+ break;
+ case CompressZstd:
+ archiveFilterName = "zstd";
+ break;
+ }
+ if (!archiveFilterName.empty()) {
+ if (archive_write_set_filter_option(
+ this->Archive, archiveFilterName.c_str(), "compression-level",
+ compressionLevelStr.c_str()) != ARCHIVE_OK) {
+ this->Error = cmStrCat("archive_write_set_filter_option: ",
+ cm_archive_error_string(this->Archive));
+ return;
+ }
+ }
+ }
+
#if !defined(_WIN32) || defined(__CYGWIN__)
if (archive_read_disk_set_standard_lookup(this->Disk) != ARCHIVE_OK) {
this->Error = cmStrCat("archive_read_disk_set_standard_lookup: ",
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index fff4556..0d33758 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -54,7 +54,7 @@ public:
/** Construct with output stream to which to write archive. */
cmArchiveWrite(std::ostream& os, Compress c = CompressNone,
- std::string const& format = "paxr");
+ std::string const& format = "paxr", int compressionLevel = 0);
~cmArchiveWrite();
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 84639a7..be91846 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -3023,18 +3023,21 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
std::string Output;
std::string Format;
std::string Compression;
+ std::string CompressionLevel;
std::string MTime;
bool Verbose = false;
std::vector<std::string> Paths;
};
- static auto const parser = cmArgumentParser<Arguments>{}
- .Bind("OUTPUT"_s, &Arguments::Output)
- .Bind("FORMAT"_s, &Arguments::Format)
- .Bind("COMPRESSION"_s, &Arguments::Compression)
- .Bind("MTIME"_s, &Arguments::MTime)
- .Bind("VERBOSE"_s, &Arguments::Verbose)
- .Bind("PATHS"_s, &Arguments::Paths);
+ static auto const parser =
+ cmArgumentParser<Arguments>{}
+ .Bind("OUTPUT"_s, &Arguments::Output)
+ .Bind("FORMAT"_s, &Arguments::Format)
+ .Bind("COMPRESSION"_s, &Arguments::Compression)
+ .Bind("COMPRESSION_LEVEL"_s, &Arguments::CompressionLevel)
+ .Bind("MTIME"_s, &Arguments::MTime)
+ .Bind("VERBOSE"_s, &Arguments::Verbose)
+ .Bind("PATHS"_s, &Arguments::Paths);
std::vector<std::string> unrecognizedArguments;
std::vector<std::string> keywordsMissingValues;
@@ -3048,9 +3051,9 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
return false;
}
- const std::vector<std::string> LIST_ARGS = { "OUTPUT", "FORMAT",
- "COMPRESSION", "MTIME",
- "PATHS" };
+ const std::vector<std::string> LIST_ARGS = {
+ "OUTPUT", "FORMAT", "COMPRESSION", "COMPRESSION_LEVEL", "MTIME", "PATHS"
+ };
auto kwbegin = keywordsMissingValues.cbegin();
auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
if (kwend != kwbegin) {
@@ -3099,6 +3102,33 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
return false;
}
+ int compressionLevel = 0;
+ if (!parsedArgs.CompressionLevel.empty()) {
+ if (parsedArgs.CompressionLevel.size() != 1 &&
+ !std::isdigit(parsedArgs.CompressionLevel[0])) {
+ status.SetError(cmStrCat("compression level ",
+ parsedArgs.CompressionLevel,
+ " should be in range 0 to 9"));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ compressionLevel = std::stoi(parsedArgs.CompressionLevel);
+ if (compressionLevel < 0 || compressionLevel > 9) {
+ status.SetError(cmStrCat("compression level ",
+ parsedArgs.CompressionLevel,
+ " should be in range 0 to 9"));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ if (compress == cmSystemTools::TarCompressNone) {
+ status.SetError(cmStrCat("compression level is not supported for "
+ "compression \"None\"",
+ parsedArgs.Compression));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ }
+
if (parsedArgs.Paths.empty()) {
status.SetError("ARCHIVE_CREATE requires a non-empty list of PATHS");
cmSystemTools::SetFatalErrorOccured();
@@ -3107,7 +3137,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
if (!cmSystemTools::CreateTar(parsedArgs.Output, parsedArgs.Paths, compress,
parsedArgs.Verbose, parsedArgs.MTime,
- parsedArgs.Format)) {
+ parsedArgs.Format, compressionLevel)) {
status.SetError(cmStrCat("failed to compress: ", parsedArgs.Output));
cmSystemTools::SetFatalErrorOccured();
return false;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 87176d6..fbf4ceb 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1442,7 +1442,7 @@ bool cmSystemTools::CreateTar(const std::string& outFileName,
const std::vector<std::string>& files,
cmTarCompression compressType, bool verbose,
std::string const& mtime,
- std::string const& format)
+ std::string const& format, int compressionLevel)
{
#if !defined(CMAKE_BOOTSTRAP)
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
@@ -1472,7 +1472,8 @@ bool cmSystemTools::CreateTar(const std::string& outFileName,
break;
}
- cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format);
+ cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format,
+ compressionLevel);
a.Open();
a.SetMTime(mtime);
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 1362af8..d571b96 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -362,7 +362,8 @@ public:
const std::vector<std::string>& files,
cmTarCompression compressType, bool verbose,
std::string const& mtime = std::string(),
- std::string const& format = std::string());
+ std::string const& format = std::string(),
+ int compressionLevel = 0);
static bool ExtractTar(const std::string& inFileName,
const std::vector<std::string>& files, bool verbose);
// This should be called first thing in main