diff options
-rw-r--r-- | Help/manual/cmake.1.rst | 13 | ||||
-rw-r--r-- | Help/release/dev/cmake-e-tar-zstd-support.rst | 7 | ||||
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/cmArchiveWrite.cxx | 7 | ||||
-rw-r--r-- | Source/cmArchiveWrite.h | 3 | ||||
-rw-r--r-- | Source/cmCTest.cxx | 4 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 187 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.h | 18 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 153 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 128 | ||||
-rw-r--r-- | Source/cmNinjaTypes.h | 21 | ||||
-rw-r--r-- | Source/cmSystemTools.cxx | 15 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 7 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 17 | ||||
-rw-r--r-- | Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake | 1 | ||||
-rw-r--r-- | Tests/RunCMake/CommandLineTar/pax-zstd.cmake | 10 |
16 files changed, 282 insertions, 311 deletions
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 97c65e7..107c2cb 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -552,20 +552,23 @@ Available commands are: Compress the resulting archive with bzip2. ``J`` Compress the resulting archive with XZ. - ``--`` - Stop interpreting options and treat all remaining arguments - as file names even if they start in ``-``. + ``--zstd`` + Compress the resulting archive with Zstandard. ``--files-from=<file>`` Read file names from the given file, one per line. Blank lines are ignored. Lines may not start in ``-`` except for ``--add-file=<name>`` to add files whose names start in ``-``. - ``--mtime=<date>`` - Specify modification time recorded in tarball entries. ``--format=<format>`` Specify the format of the archive to be created. Supported formats are: ``7zip``, ``gnutar``, ``pax``, ``paxr`` (restricted pax, default), and ``zip``. + ``--mtime=<date>`` + Specify modification time recorded in tarball entries. + ``--`` + Stop interpreting options and treat all remaining arguments + as file names, even if they start with ``-``. + ``time <command> [<args>...]`` Run command and display elapsed time. diff --git a/Help/release/dev/cmake-e-tar-zstd-support.rst b/Help/release/dev/cmake-e-tar-zstd-support.rst new file mode 100644 index 0000000..e3488b5 --- /dev/null +++ b/Help/release/dev/cmake-e-tar-zstd-support.rst @@ -0,0 +1,7 @@ +Help/release/dev/cmake-e-tar-zstd-support +----------------------------------------- + +* The :manual:`cmake(1)` ``-E tar`` tool now support Zstandard compression + algorithm with ``--zstd`` option. Zstandard was designed to give + a compression ratio comparable to that of the DEFLATE (zip) algorithm, + but faster, especially for decompression. diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 06fac72..63f1dce 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 14) -set(CMake_VERSION_PATCH 20190529) +set(CMake_VERSION_PATCH 20190530) #set(CMake_VERSION_RC 1) diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index 177ba02..359d57a 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -137,6 +137,13 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, return; } break; + case CompressZstd: + if (archive_write_add_filter_zstd(this->Archive) != ARCHIVE_OK) { + this->Error = "archive_write_add_filter_zstd: "; + this->Error += cm_archive_error_string(this->Archive); + return; + } + break; } #if !defined(_WIN32) || defined(__CYGWIN__) if (archive_read_disk_set_standard_lookup(this->Disk) != ARCHIVE_OK) { diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h index 1f23dae..9ea88d3 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -49,7 +49,8 @@ public: CompressGZip, CompressBZip2, CompressLZMA, - CompressXZ + CompressXZ, + CompressZstd }; /** Construct with output stream to which to write archive. */ diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 071ff56..d1226c3 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -1611,8 +1611,8 @@ std::string cmCTest::Base64GzipEncodeFile(std::string const& file) std::vector<std::string> files; files.push_back(file); - if (!cmSystemTools::CreateTar(tarFile.c_str(), files, - cmSystemTools::TarCompressGZip, false)) { + if (!cmSystemTools::CreateTar(tarFile, files, cmSystemTools::TarCompressGZip, + false)) { cmCTestLog(this, ERROR_MESSAGE, "Error creating tar while " "encoding file: " diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 61dea80..3fce29e 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -238,14 +238,11 @@ void cmGlobalNinjaGenerator::WritePhonyBuild( void cmGlobalNinjaGenerator::AddCustomCommandRule() { - this->AddRule("CUSTOM_COMMAND", "$COMMAND", "$DESC", - "Rule for running custom commands.", - /*depfile*/ "", - /*deptype*/ "", - /*rspfile*/ "", - /*rspcontent*/ "", - /*restat*/ "", // bound on each build statement as needed - /*generator*/ false); + cmNinjaRule rule("CUSTOM_COMMAND"); + rule.Command = "$COMMAND"; + rule.Description = "$DESC"; + rule.Comment = "Rule for running custom commands."; + this->AddRule(rule); } void cmGlobalNinjaGenerator::WriteCustomCommandBuild( @@ -293,15 +290,11 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( void cmGlobalNinjaGenerator::AddMacOSXContentRule() { - this->AddRule("COPY_OSX_CONTENT", CMakeCmd() + " -E copy $in $out", - "Copying OS X Content $out", - "Rule for copying OS X bundle content file.", - /*depfile*/ "", - /*deptype*/ "", - /*rspfile*/ "", - /*rspcontent*/ "", - /*restat*/ "", - /*generator*/ false); + cmNinjaRule rule("COPY_OSX_CONTENT"); + rule.Command = CMakeCmd() + " -E copy $in $out"; + rule.Description = "Copying OS X Content $out"; + rule.Comment = "Rule for copying OS X bundle content file."; + this->AddRule(rule); } void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input, @@ -320,40 +313,36 @@ void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input, cmNinjaDeps(), cmNinjaVars()); } -void cmGlobalNinjaGenerator::WriteRule( - std::ostream& os, const std::string& name, const std::string& command, - const std::string& description, const std::string& comment, - const std::string& depfile, const std::string& deptype, - const std::string& rspfile, const std::string& rspcontent, - const std::string& restat, bool generator) +void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, + cmNinjaRule const& rule) { // -- Parameter checks // Make sure the rule has a name. - if (name.empty()) { + if (rule.Name.empty()) { cmSystemTools::Error("No name given for WriteRule! called with comment: " + - comment); + rule.Comment); return; } // Make sure a command is given. - if (command.empty()) { + if (rule.Command.empty()) { cmSystemTools::Error( - "No command given for WriteRule! called with comment: " + comment); + "No command given for WriteRule! called with comment: " + rule.Comment); return; } // Make sure response file content is given - if (!rspfile.empty() && rspcontent.empty()) { + if (!rule.RspFile.empty() && rule.RspContent.empty()) { cmSystemTools::Error("rspfile but no rspfile_content given for WriteRule! " "called with comment: " + - comment); + rule.Comment); return; } // -- Write rule // Write rule intro - cmGlobalNinjaGenerator::WriteComment(os, comment); - os << "rule " << name << '\n'; + cmGlobalNinjaGenerator::WriteComment(os, rule.Comment); + os << "rule " << rule.Name << '\n'; // Write rule key/value pairs auto writeKV = [&os](const char* key, std::string const& value) { @@ -363,16 +352,16 @@ void cmGlobalNinjaGenerator::WriteRule( } }; - writeKV("depfile", depfile); - writeKV("deps", deptype); - writeKV("command", command); - writeKV("description", description); - if (!rspfile.empty()) { - writeKV("rspfile", rspfile); - writeKV("rspfile_content", rspcontent); + writeKV("depfile", rule.DepFile); + writeKV("deps", rule.DepType); + writeKV("command", rule.Command); + writeKV("description", rule.Description); + if (!rule.RspFile.empty()) { + writeKV("rspfile", rule.RspFile); + writeKV("rspfile_content", rule.RspContent); } - writeKV("restat", restat); - if (generator) { + writeKV("restat", rule.Restat); + if (rule.Generator) { writeKV("generator", "1"); } @@ -697,23 +686,16 @@ cmGlobalNinjaGenerator::GenerateBuildCommand( // Non-virtual public methods. -void cmGlobalNinjaGenerator::AddRule( - const std::string& name, const std::string& command, - const std::string& description, const std::string& comment, - const std::string& depfile, const std::string& deptype, - const std::string& rspfile, const std::string& rspcontent, - const std::string& restat, bool generator) +void cmGlobalNinjaGenerator::AddRule(cmNinjaRule const& rule) { // Do not add the same rule twice. - if (!this->Rules.insert(name).second) { + if (!this->Rules.insert(rule.Name).second) { return; } // Store command length - this->RuleCmdLength[name] = static_cast<int>(command.size()); + this->RuleCmdLength[rule.Name] = static_cast<int>(rule.Command.size()); // Write rule - cmGlobalNinjaGenerator::WriteRule(*this->RulesFileStream, name, command, - description, comment, depfile, deptype, - rspfile, rspcontent, restat, generator); + cmGlobalNinjaGenerator::WriteRule(*this->RulesFileStream, rule); } bool cmGlobalNinjaGenerator::HasRule(const std::string& name) @@ -1329,21 +1311,18 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) cmLocalGenerator* lg = this->LocalGenerators[0]; { - std::string cmd = CMakeCmd(); - cmd += " -S"; - cmd += lg->ConvertToOutputFormat(lg->GetSourceDirectory(), - cmOutputConverter::SHELL); - cmd += " -B"; - cmd += lg->ConvertToOutputFormat(lg->GetBinaryDirectory(), - cmOutputConverter::SHELL); - WriteRule(*this->RulesFileStream, "RERUN_CMAKE", cmd, - "Re-running CMake...", "Rule for re-running cmake.", - /*depfile=*/"", - /*deptype=*/"", - /*rspfile=*/"", - /*rspcontent*/ "", - /*restat=*/"", - /*generator=*/true); + cmNinjaRule rule("RERUN_CMAKE"); + rule.Command = CMakeCmd(); + rule.Command += " -S"; + rule.Command += lg->ConvertToOutputFormat(lg->GetSourceDirectory(), + cmOutputConverter::SHELL); + rule.Command += " -B"; + rule.Command += lg->ConvertToOutputFormat(lg->GetBinaryDirectory(), + cmOutputConverter::SHELL); + rule.Description = "Re-running CMake..."; + rule.Comment = "Rule for re-running cmake."; + rule.Generator = true; + WriteRule(*this->RulesFileStream, rule); } cmNinjaDeps implicitDeps; @@ -1365,20 +1344,15 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) cmake* cm = this->GetCMakeInstance(); if (this->SupportsManifestRestat() && cm->DoWriteGlobVerifyTarget()) { { - std::string cmd = CMakeCmd(); - cmd += " -P "; - cmd += lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(), - cmOutputConverter::SHELL); - - WriteRule(*this->RulesFileStream, "VERIFY_GLOBS", cmd, - "Re-checking globbed directories...", - "Rule for re-checking globbed directories.", - /*depfile=*/"", - /*deptype=*/"", - /*rspfile=*/"", - /*rspcontent*/ "", - /*restat=*/"", - /*generator=*/true); + cmNinjaRule rule("VERIFY_GLOBS"); + rule.Command = CMakeCmd(); + rule.Command += " -P "; + rule.Command += lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(), + cmOutputConverter::SHELL); + rule.Description = "Re-checking globbed directories..."; + rule.Comment = "Rule for re-checking globbed directories."; + rule.Generator = true; + this->WriteRule(*this->RulesFileStream, rule); } std::string verifyForce = cm->GetGlobVerifyScript() + "_force"; @@ -1514,19 +1488,14 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) // Write rule { - std::string cmd = CMakeCmd(); - cmd += " -P "; - cmd += lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel), - cmOutputConverter::SHELL); - WriteRule(*this->RulesFileStream, "CLEAN_ADDITIONAL", cmd, - "Cleaning additional files...", - "Rule for cleaning additional files.", - /*depfile=*/"", - /*deptype=*/"", - /*rspfile=*/"", - /*rspcontent*/ "", - /*restat=*/"", - /*generator=*/false); + cmNinjaRule rule("CLEAN_ADDITIONAL"); + rule.Command = CMakeCmd(); + rule.Command += " -P "; + rule.Command += lgr->ConvertToOutputFormat( + this->NinjaOutputPath(cleanScriptRel), cmOutputConverter::SHELL); + rule.Description = "Cleaning additional files..."; + rule.Comment = "Rule for cleaning additional files."; + WriteRule(*this->RulesFileStream, rule); } // Write build @@ -1553,15 +1522,13 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) // -- Default clean target // Write rule - WriteRule(*this->RulesFileStream, "CLEAN", NinjaCmd() + " -t clean", - "Cleaning all built files...", - "Rule for cleaning all built files.", - /*depfile=*/"", - /*deptype=*/"", - /*rspfile=*/"", - /*rspcontent*/ "", - /*restat=*/"", - /*generator=*/false); + { + cmNinjaRule rule("CLEAN"); + rule.Command = NinjaCmd() + " -t clean"; + rule.Description = "Cleaning all built files..."; + rule.Comment = "Rule for cleaning all built files."; + WriteRule(*this->RulesFileStream, rule); + } // Write build { @@ -1584,15 +1551,13 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) { - WriteRule(*this->RulesFileStream, "HELP", NinjaCmd() + " -t targets", - "All primary targets available:", - "Rule for printing all primary targets available.", - /*depfile=*/"", - /*deptype=*/"", - /*rspfile=*/"", - /*rspcontent*/ "", - /*restat=*/"", - /*generator=*/false); + { + cmNinjaRule rule("HELP"); + rule.Command = NinjaCmd() + " -t targets"; + rule.Description = "All primary targets available:"; + rule.Comment = "Rule for printing all primary targets available."; + WriteRule(*this->RulesFileStream, rule); + } WriteBuild(os, "Print all primary targets available.", "HELP", /*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("help")), /*implicitOuts=*/cmNinjaDeps(), diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 47685c2..dcc358b 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -138,18 +138,10 @@ public: const std::string& output); /** - * Write a rule statement named @a name to @a os with the @a comment, - * the mandatory @a command, the @a depfile and the @a description. - * It also writes the variables bound to this rule statement. + * Write a rule statement to @a os. * @warning no escaping of any kind is done here. */ - static void WriteRule(std::ostream& os, const std::string& name, - const std::string& command, - const std::string& description, - const std::string& comment, const std::string& depfile, - const std::string& deptype, const std::string& rspfile, - const std::string& rspcontent, - const std::string& restat, bool generator); + static void WriteRule(std::ostream& os, cmNinjaRule const& rule); /** * Write a variable named @a name to @a os with value @a value and an @@ -273,11 +265,7 @@ public: * Call WriteRule() behind the scene but perform some check before like: * - Do not add twice the same rule. */ - void AddRule(const std::string& name, const std::string& command, - const std::string& description, const std::string& comment, - const std::string& depfile, const std::string& deptype, - const std::string& rspfile, const std::string& rspcontent, - const std::string& restat, bool generator); + void AddRule(cmNinjaRule const& rule); bool HasRule(const std::string& name); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 77af45e..6e9e112 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -162,13 +162,8 @@ struct cmNinjaRemoveNoOpCommands void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile) { - cmStateEnums::TargetType targetType = this->GetGeneratorTarget()->GetType(); - std::string ruleName = this->LanguageLinkerDeviceRule(); - // Select whether to use a response file for objects. - std::string rspfile; - std::string rspcontent; - - if (!this->GetGlobalGenerator()->HasRule(ruleName)) { + cmNinjaRule rule(this->LanguageLinkerDeviceRule()); + if (!this->GetGlobalGenerator()->HasRule(rule.Name)) { cmRulePlaceholderExpander::RuleVariables vars; vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str(); vars.CMTargetType = @@ -192,16 +187,16 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile) } else { responseFlag = "@"; } - rspfile = "$RSP_FILE"; - responseFlag += rspfile; + rule.RspFile = "$RSP_FILE"; + responseFlag += rule.RspFile; // build response file content if (this->GetGlobalGenerator()->IsGCCOnWindows()) { - rspcontent = "$in"; + rule.RspContent = "$in"; } else { - rspcontent = "$in_newline"; + rule.RspContent = "$in_newline"; } - rspcontent += " $LINK_LIBRARIES"; + rule.RspContent += " $LINK_LIBRARIES"; vars.Objects = responseFlag.c_str(); vars.LinkLibraries = ""; } @@ -220,7 +215,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile) vars.Manifests = "$MANIFESTS"; std::string langFlags; - if (targetType != cmStateEnums::EXECUTABLE) { + if (this->GetGeneratorTarget()->GetType() != cmStateEnums::EXECUTABLE) { langFlags += "$LANGUAGE_COMPILE_FLAGS $ARCH_FLAGS"; vars.LanguageCompileFlags = langFlags.c_str(); } @@ -247,39 +242,35 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile) // If there is no ranlib the command will be ":". Skip it. cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands()); - std::string linkCmd = - this->GetLocalGenerator()->BuildCommandLine(linkCmds); + rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds); // Write the linker rule with response file if needed. - std::ostringstream comment; - comment << "Rule for linking " << this->TargetLinkLanguage << " " - << this->GetVisibleTypeName() << "."; - std::ostringstream description; - description << "Linking " << this->TargetLinkLanguage << " " - << this->GetVisibleTypeName() << " $TARGET_FILE"; - this->GetGlobalGenerator()->AddRule(ruleName, linkCmd, description.str(), - comment.str(), - /*depfile*/ "", - /*deptype*/ "", rspfile, rspcontent, - /*restat*/ "$RESTAT", - /*generator*/ false); + rule.Comment = "Rule for linking "; + rule.Comment += this->TargetLinkLanguage; + rule.Comment += " "; + rule.Comment += this->GetVisibleTypeName(); + rule.Comment += "."; + rule.Description = "Linking "; + rule.Description += this->TargetLinkLanguage; + rule.Description += " "; + rule.Description += this->GetVisibleTypeName(); + rule.Description += " $TARGET_FILE"; + rule.Restat = "$RESTAT"; + + this->GetGlobalGenerator()->AddRule(rule); } } void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) { cmStateEnums::TargetType targetType = this->GetGeneratorTarget()->GetType(); - std::string ruleName = this->LanguageLinkerRule(); - // Select whether to use a response file for objects. - std::string rspfile; - std::string rspcontent; - - if (!this->GetGlobalGenerator()->HasRule(ruleName)) { + std::string linkRuleName = this->LanguageLinkerRule(); + if (!this->GetGlobalGenerator()->HasRule(linkRuleName)) { + cmNinjaRule rule(std::move(linkRuleName)); cmRulePlaceholderExpander::RuleVariables vars; vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str(); - vars.CMTargetType = - cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()); + vars.CMTargetType = cmState::GetTargetTypeName(targetType); vars.Language = this->TargetLinkLanguage.c_str(); @@ -311,16 +302,16 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) } else { responseFlag = "@"; } - rspfile = "$RSP_FILE"; - responseFlag += rspfile; + rule.RspFile = "$RSP_FILE"; + responseFlag += rule.RspFile; // build response file content if (this->GetGlobalGenerator()->IsGCCOnWindows()) { - rspcontent = "$in"; + rule.RspContent = "$in"; } else { - rspcontent = "$in_newline"; + rule.RspContent = "$in_newline"; } - rspcontent += " $LINK_PATH $LINK_LIBRARIES"; + rule.RspContent += " $LINK_PATH $LINK_LIBRARIES"; if (this->TargetLinkLanguage == "Swift") { vars.SwiftSources = responseFlag.c_str(); } else { @@ -389,22 +380,21 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) linkCmds.insert(linkCmds.begin(), "$PRE_LINK"); linkCmds.emplace_back("$POST_BUILD"); - std::string linkCmd = - this->GetLocalGenerator()->BuildCommandLine(linkCmds); + rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds); // Write the linker rule with response file if needed. - std::ostringstream comment; - comment << "Rule for linking " << this->TargetLinkLanguage << " " - << this->GetVisibleTypeName() << "."; - std::ostringstream description; - description << "Linking " << this->TargetLinkLanguage << " " - << this->GetVisibleTypeName() << " $TARGET_FILE"; - this->GetGlobalGenerator()->AddRule(ruleName, linkCmd, description.str(), - comment.str(), - /*depfile*/ "", - /*deptype*/ "", rspfile, rspcontent, - /*restat*/ "$RESTAT", - /*generator*/ false); + rule.Comment = "Rule for linking "; + rule.Comment += this->TargetLinkLanguage; + rule.Comment += " "; + rule.Comment += this->GetVisibleTypeName(); + rule.Comment += "."; + rule.Description = "Linking "; + rule.Description += this->TargetLinkLanguage; + rule.Description += " "; + rule.Description += this->GetVisibleTypeName(); + rule.Description += " $TARGET_FILE"; + rule.Restat = "$RESTAT"; + this->GetGlobalGenerator()->AddRule(rule); } if (this->TargetNames.Output != this->TargetNames.Real && @@ -413,41 +403,28 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) this->GetLocalGenerator()->ConvertToOutputFormat( cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL); if (targetType == cmStateEnums::EXECUTABLE) { - std::vector<std::string> commandLines; - commandLines.push_back(cmakeCommand + - " -E cmake_symlink_executable $in $out"); - commandLines.emplace_back("$POST_BUILD"); - - this->GetGlobalGenerator()->AddRule( - "CMAKE_SYMLINK_EXECUTABLE", - this->GetLocalGenerator()->BuildCommandLine(commandLines), - "Creating executable symlink $out", - "Rule for creating " - "executable symlink.", - /*depfile*/ "", - /*deptype*/ "", - /*rspfile*/ "", - /*rspcontent*/ "", - /*restat*/ "", - /*generator*/ false); + cmNinjaRule rule("CMAKE_SYMLINK_EXECUTABLE"); + { + std::vector<std::string> cmd; + cmd.push_back(cmakeCommand + " -E cmake_symlink_executable $in $out"); + cmd.emplace_back("$POST_BUILD"); + rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd); + } + rule.Description = "Creating executable symlink $out"; + rule.Comment = "Rule for creating executable symlink."; + this->GetGlobalGenerator()->AddRule(rule); } else { - std::vector<std::string> commandLines; - commandLines.push_back(cmakeCommand + - " -E cmake_symlink_library $in $SONAME $out"); - commandLines.emplace_back("$POST_BUILD"); - - this->GetGlobalGenerator()->AddRule( - "CMAKE_SYMLINK_LIBRARY", - this->GetLocalGenerator()->BuildCommandLine(commandLines), - "Creating library symlink $out", - "Rule for creating " - "library symlink.", - /*depfile*/ "", - /*deptype*/ "", - /*rspfile*/ "", - /*rspcontent*/ "", - /*restat*/ "", - /*generator*/ false); + cmNinjaRule rule("CMAKE_SYMLINK_LIBRARY"); + { + std::vector<std::string> cmd; + cmd.push_back(cmakeCommand + + " -E cmake_symlink_library $in $SONAME $out"); + cmd.emplace_back("$POST_BUILD"); + rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd); + } + rule.Description = "Creating library symlink $out"; + rule.Comment = "Rule for creating library symlink."; + this->GetGlobalGenerator()->AddRule(rule); } } } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 9652a51..5b8ed90 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -495,9 +495,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); if (explicitPP) { + cmNinjaRule rule(this->LanguagePreprocessRule(lang)); // Explicit preprocessing always uses a depfile. - std::string const ppDeptype; // no deps= for multiple outputs - std::string const ppDepfile = "$DEP_FILE"; + rule.DepType = ""; // no deps= for multiple outputs + rule.DepFile = "$DEP_FILE"; cmRulePlaceholderExpander::RuleVariables ppVars; ppVars.CMTargetName = vars.CMTargetName; @@ -505,7 +506,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) ppVars.Language = vars.Language; ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE ppVars.PreprocessedSource = "$out"; - ppVars.DependencyFile = ppDepfile.c_str(); + ppVars.DependencyFile = rule.DepFile.c_str(); // Preprocessing uses the original source, // compilation uses preprocessed output. @@ -524,17 +525,15 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) ppVars.Includes = vars.Includes; // If using a response file, move defines, includes, and flags into it. - std::string ppRspFile; - std::string ppRspContent; if (!responseFlag.empty()) { - ppRspFile = "$RSP_FILE"; - ppRspContent = " "; - ppRspContent += ppVars.Defines; - ppRspContent += " "; - ppRspContent += ppVars.Includes; - ppRspContent += " "; - ppRspContent += ppFlags; - ppFlags = responseFlag + ppRspFile; + rule.RspFile = "$RSP_FILE"; + rule.RspContent = " "; + rule.RspContent += ppVars.Defines; + rule.RspContent += " "; + rule.RspContent += ppVars.Includes; + rule.RspContent += " "; + rule.RspContent += ppFlags; + ppFlags = responseFlag + rule.RspFile; ppVars.Defines = ""; ppVars.Includes = ""; } @@ -570,31 +569,25 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) } ppCmds.emplace_back(std::move(ccmd)); } - std::string const ppCmdLine = - this->GetLocalGenerator()->BuildCommandLine(ppCmds); + rule.Command = this->GetLocalGenerator()->BuildCommandLine(ppCmds); // Write the rule for preprocessing file of the given language. - std::string ppComment = "Rule for preprocessing "; - ppComment += lang; - ppComment += " files."; - std::string ppDesc = "Building "; - ppDesc += lang; - ppDesc += " preprocessed $out"; - this->GetGlobalGenerator()->AddRule( - this->LanguagePreprocessRule(lang), ppCmdLine, ppDesc, ppComment, - ppDepfile, ppDeptype, ppRspFile, ppRspContent, - /*restat*/ "", - /*generator*/ false); + rule.Comment = "Rule for preprocessing "; + rule.Comment += lang; + rule.Comment += " files."; + rule.Description = "Building "; + rule.Description += lang; + rule.Description += " preprocessed $out"; + this->GetGlobalGenerator()->AddRule(rule); } if (needDyndep) { // Write the rule for ninja dyndep file generation. - + cmNinjaRule rule(this->LanguageDyndepRule(lang)); // Command line length is almost always limited -> use response file for // dyndep rules - std::string ddRspFile = "$out.rsp"; - std::string ddRspContent = "$in"; - std::string ddCmdLine; + rule.RspFile = "$out.rsp"; + rule.RspContent = "$in"; // Run CMake dependency scanner on the source file (using the preprocessed // source if that was performed). @@ -608,53 +601,49 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) ccmd += lang; ccmd += " --dd=$out "; ccmd += "@"; - ccmd += ddRspFile; + ccmd += rule.RspFile; ddCmds.emplace_back(std::move(ccmd)); } - ddCmdLine = this->GetLocalGenerator()->BuildCommandLine(ddCmds); + rule.Command = this->GetLocalGenerator()->BuildCommandLine(ddCmds); } - std::string ddComment = "Rule to generate ninja dyndep files for "; - ddComment += lang; - ddComment += "."; - std::string ddDesc = "Generating "; - ddDesc += lang; - ddDesc += " dyndep file $out"; - this->GetGlobalGenerator()->AddRule(this->LanguageDyndepRule(lang), - ddCmdLine, ddDesc, ddComment, - /*depfile*/ "", - /*deps*/ "", ddRspFile, ddRspContent, - /*restat*/ "", - /*generator*/ false); + rule.Comment = "Rule to generate ninja dyndep files for "; + rule.Comment += lang; + rule.Comment += "."; + rule.Description = "Generating "; + rule.Description += lang; + rule.Description += " dyndep file $out"; + this->GetGlobalGenerator()->AddRule(rule); } + cmNinjaRule rule(this->LanguageCompilerRule(lang)); // If using a response file, move defines, includes, and flags into it. - std::string rspfile; - std::string rspcontent; if (!responseFlag.empty()) { - rspfile = "$RSP_FILE"; - rspcontent = - std::string(" ") + vars.Defines + " " + vars.Includes + " " + flags; - flags = responseFlag + rspfile; + rule.RspFile = "$RSP_FILE"; + rule.RspContent = " "; + rule.RspContent += vars.Defines; + rule.RspContent += " "; + rule.RspContent += vars.Includes; + rule.RspContent += " "; + rule.RspContent += flags; + flags = responseFlag + rule.RspFile; vars.Defines = ""; vars.Includes = ""; } // Tell ninja dependency format so all deps can be loaded into a database - std::string deptype; - std::string depfile; std::string cldeps; if (explicitPP) { // The explicit preprocessing step will handle dependency scanning. } else if (this->NeedDepTypeMSVC(lang)) { - deptype = "msvc"; - depfile.clear(); + rule.DepType = "msvc"; + rule.DepFile.clear(); flags += " /showIncludes"; } else if (mf->IsOn("CMAKE_NINJA_CMCLDEPS_" + lang)) { // For the MS resource compiler we need cmcldeps, but skip dependencies // for source-file try_compile cases because they are always fresh. if (!mf->GetIsSourceFileTryCompile()) { - deptype = "gcc"; - depfile = "$DEP_FILE"; + rule.DepType = "gcc"; + rule.DepFile = "$DEP_FILE"; const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER") ? mf->GetSafeDefinition("CMAKE_C_COMPILER") : mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); @@ -665,8 +654,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) cldeps += "\" \"" + cl + "\" "; } } else { - deptype = "gcc"; - depfile = "$DEP_FILE"; + rule.DepType = "gcc"; + rule.DepFile = "$DEP_FILE"; const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang; std::string depfileFlags = mf->GetSafeDefinition(flagsName); if (!depfileFlags.empty()) { @@ -679,7 +668,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) } vars.Flags = flags.c_str(); - vars.DependencyFile = depfile.c_str(); + vars.DependencyFile = rule.DepFile.c_str(); // Rule for compiling object file. std::vector<std::string> compileCmds; @@ -784,21 +773,16 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) vars); } - std::string cmdLine = - this->GetLocalGenerator()->BuildCommandLine(compileCmds); + rule.Command = this->GetLocalGenerator()->BuildCommandLine(compileCmds); // Write the rule for compiling file of the given language. - std::string comment = "Rule for compiling "; - comment += lang; - comment += " files."; - std::string description = "Building "; - description += lang; - description += " object $out"; - this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(lang), - cmdLine, description, comment, depfile, - deptype, rspfile, rspcontent, - /*restat*/ "", - /*generator*/ false); + rule.Comment = "Rule for compiling "; + rule.Comment += lang; + rule.Comment += " files."; + rule.Description = "Building "; + rule.Description += lang; + rule.Description += " object $out"; + this->GetGlobalGenerator()->AddRule(rule); } void cmNinjaTargetGenerator::WriteObjectBuildStatements() diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h index 9e962f1..78f3917 100644 --- a/Source/cmNinjaTypes.h +++ b/Source/cmNinjaTypes.h @@ -8,6 +8,7 @@ #include <map> #include <set> #include <string> +#include <utility> #include <vector> enum cmNinjaTargetDepends @@ -20,4 +21,24 @@ typedef std::vector<std::string> cmNinjaDeps; typedef std::set<std::string> cmNinjaOuts; typedef std::map<std::string, std::string> cmNinjaVars; +class cmNinjaRule +{ +public: + cmNinjaRule(std::string name) + : Name(std::move(name)) + { + } + + std::string Name; + std::string Command; + std::string Description; + std::string Comment; + std::string DepFile; + std::string DepType; + std::string RspFile; + std::string RspContent; + std::string Restat; + bool Generator = false; +}; + #endif // ! cmNinjaTypes_h diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 2453aea..1501481 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1529,7 +1529,7 @@ bool cmSystemTools::IsPathToFramework(const std::string& path) cmHasLiteralSuffix(path, ".framework")); } -bool cmSystemTools::CreateTar(const char* outFileName, +bool cmSystemTools::CreateTar(const std::string& outFileName, const std::vector<std::string>& files, cmTarCompression compressType, bool verbose, std::string const& mtime, @@ -1537,7 +1537,7 @@ bool cmSystemTools::CreateTar(const char* outFileName, { #if defined(CMAKE_BUILD_WITH_CMAKE) std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); - cmsys::ofstream fout(outFileName, std::ios::out | std::ios::binary); + cmsys::ofstream fout(outFileName.c_str(), std::ios::out | std::ios::binary); if (!fout) { std::string e = "Cannot open output file \""; e += outFileName; @@ -1557,6 +1557,9 @@ bool cmSystemTools::CreateTar(const char* outFileName, case TarCompressXZ: compress = cmArchiveWrite::CompressXZ; break; + case TarCompressZstd: + compress = cmArchiveWrite::CompressZstd; + break; case TarCompressNone: compress = cmArchiveWrite::CompressNone; break; @@ -1757,7 +1760,7 @@ bool copy_data(struct archive* ar, struct archive* aw) # endif } -bool extract_tar(const char* outFileName, +bool extract_tar(const std::string& outFileName, const std::vector<std::string>& files, bool verbose, bool extract) { @@ -1783,7 +1786,7 @@ bool extract_tar(const char* outFileName, } } - int r = cm_archive_read_open_file(a, outFileName, 10240); + int r = cm_archive_read_open_file(a, outFileName.c_str(), 10240); if (r) { ArchiveError("Problem with archive_read_open_file(): ", a); archive_write_free(ext); @@ -1878,7 +1881,7 @@ bool extract_tar(const char* outFileName, } #endif -bool cmSystemTools::ExtractTar(const char* outFileName, +bool cmSystemTools::ExtractTar(const std::string& outFileName, const std::vector<std::string>& files, bool verbose) { @@ -1892,7 +1895,7 @@ bool cmSystemTools::ExtractTar(const char* outFileName, #endif } -bool cmSystemTools::ListTar(const char* outFileName, +bool cmSystemTools::ListTar(const std::string& outFileName, const std::vector<std::string>& files, bool verbose) { diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 09a4d13..016c266 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -447,17 +447,18 @@ public: TarCompressGZip, TarCompressBZip2, TarCompressXZ, + TarCompressZstd, TarCompressNone }; - static bool ListTar(const char* outFileName, + static bool ListTar(const std::string& outFileName, const std::vector<std::string>& files, bool verbose); - static bool CreateTar(const char* outFileName, + static bool CreateTar(const std::string& outFileName, const std::vector<std::string>& files, cmTarCompression compressType, bool verbose, std::string const& mtime = std::string(), std::string const& format = std::string()); - static bool ExtractTar(const char* inFileName, + static bool ExtractTar(const std::string& inFileName, const std::vector<std::string>& files, bool verbose); // This should be called first thing in main // it will keep child processes from inheriting the diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 4ddfddd..f4ef45c 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1043,11 +1043,17 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) std::vector<std::string> files; std::string mtime; std::string format; + cmSystemTools::cmTarCompression compress = + cmSystemTools::TarCompressNone; + int nCompress = 0; bool doing_options = true; for (auto const& arg : cmMakeRange(args).advance(4)) { if (doing_options && cmHasLiteralPrefix(arg, "--")) { if (arg == "--") { doing_options = false; + } else if (arg == "--zstd") { + compress = cmSystemTools::TarCompressZstd; + ++nCompress; } else if (cmHasLiteralPrefix(arg, "--mtime=")) { mtime = arg.substr(8); } else if (cmHasLiteralPrefix(arg, "--files-from=")) { @@ -1075,10 +1081,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) } } cmSystemTools::cmTarAction action = cmSystemTools::TarActionNone; - cmSystemTools::cmTarCompression compress = - cmSystemTools::TarCompressNone; bool verbose = false; - int nCompress = 0; for (auto flag : flags) { switch (flag) { @@ -1127,7 +1130,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 1; } if (action == cmSystemTools::TarActionList) { - if (!cmSystemTools::ListTar(outFile.c_str(), files, verbose)) { + if (!cmSystemTools::ListTar(outFile, files, verbose)) { cmSystemTools::Error("Problem listing tar: " + outFile); return 1; } @@ -1136,13 +1139,13 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) cmSystemTools::Message("tar: No files or directories specified", "Warning"); } - if (!cmSystemTools::CreateTar(outFile.c_str(), files, compress, - verbose, mtime, format)) { + if (!cmSystemTools::CreateTar(outFile, files, compress, verbose, mtime, + format)) { cmSystemTools::Error("Problem creating tar: " + outFile); return 1; } } else if (action == cmSystemTools::TarActionExtract) { - if (!cmSystemTools::ExtractTar(outFile.c_str(), files, verbose)) { + if (!cmSystemTools::ExtractTar(outFile, files, verbose)) { cmSystemTools::Error("Problem extracting tar: " + outFile); return 1; } diff --git a/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake index 4d1b396..a64af95 100644 --- a/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake @@ -27,6 +27,7 @@ run_cmake(gnutar) run_cmake(gnutar-gz) run_cmake(pax) run_cmake(pax-xz) +run_cmake(pax-zstd) run_cmake(paxr) run_cmake(paxr-bz2) run_cmake(zip) diff --git a/Tests/RunCMake/CommandLineTar/pax-zstd.cmake b/Tests/RunCMake/CommandLineTar/pax-zstd.cmake new file mode 100644 index 0000000..c2a304d --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/pax-zstd.cmake @@ -0,0 +1,10 @@ +set(OUTPUT_NAME "test.tar.zstd") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=pax --zstd) + +set(DECOMPRESSION_FLAGS xvf) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("28b52ffd0058" LIMIT 6 HEX) |