diff options
author | Asit Dhal <dhal.asitk@gmail.com> | 2020-09-17 17:29:31 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-09-21 17:08:11 (GMT) |
commit | 195d14e7818244789638fffd2087b8b2d0952622 (patch) | |
tree | 7e46f8f1f6dfbb60dc73bb600e1190369bc00bc0 /Source | |
parent | 4fc07cd369cd46fbd859f140eda971d00ac52704 (diff) | |
download | CMake-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.cxx | 37 | ||||
-rw-r--r-- | Source/cmArchiveWrite.h | 2 | ||||
-rw-r--r-- | Source/cmFileCommand.cxx | 52 | ||||
-rw-r--r-- | Source/cmSystemTools.cxx | 5 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 3 |
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 |