From a6de8ec51b5afdef747e0dfd8f5d67e2b92429c0 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 8 Jun 2021 16:25:50 -0400 Subject: cmTransformDepfile: Make directory for transformed depfile automatically --- Source/cmLocalNinjaGenerator.cxx | 2 -- Source/cmTransformDepfile.cxx | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 81425991c4..7f7b1e7d73 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -698,8 +698,6 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: - cmSystemTools::MakeDirectory( - cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles/d")); depfile = ccg.GetInternalDepfile(); break; } diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx index 0df9550b82..039b19de3a 100644 --- a/Source/cmTransformDepfile.cxx +++ b/Source/cmTransformDepfile.cxx @@ -93,6 +93,7 @@ bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg, content = *std::move(result); } + cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(outfile)); cmsys::ofstream fout(outfile.c_str()); if (!fout) { return false; -- cgit v1.2.1 From 7291f312545d4a22339a4f9763ea61e16507c8a3 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 8 Jun 2021 17:58:33 -0400 Subject: cmTransformDepfile: Add support for MSBuild AdditionalInputs format --- Source/cmCustomCommandGenerator.cxx | 6 ++++++ Source/cmTransformDepfile.cxx | 31 +++++++++++++++++++++++++++++++ Source/cmTransformDepfile.h | 3 ++- Source/cmcmd.cxx | 2 ++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 10a6491f93..5a2683bb8b 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -230,6 +230,9 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( case cmDepfileFormat::MakeDepfile: argv.emplace_back("makedepfile"); break; + case cmDepfileFormat::MSBuildAdditionalInputs: + argv.emplace_back("MSBuildAdditionalInputs"); + break; } argv.push_back(this->LG->GetSourceDirectory()); argv.push_back(this->LG->GetCurrentSourceDirectory()); @@ -437,6 +440,9 @@ std::string cmCustomCommandGenerator::GetInternalDepfileName( case cmDepfileFormat::MakeDepfile: extension = ".d"; break; + case cmDepfileFormat::MSBuildAdditionalInputs: + extension = ".AdditionalInputs"; + break; } return cmStrCat(this->LG->GetBinaryDirectory(), "/CMakeFiles/d/", hash.HashString(depfile), extension); diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx index 039b19de3a..4032596b85 100644 --- a/Source/cmTransformDepfile.cxx +++ b/Source/cmTransformDepfile.cxx @@ -2,7 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTransformDepfile.h" +#include #include +#include #include #include #include @@ -78,6 +80,32 @@ void WriteDepfile(cmDepfileFormat format, cmsys::ofstream& fout, } } } + +void WriteMSBuildAdditionalInputs(cmsys::ofstream& fout, + cmLocalGenerator const& lg, + cmGccDepfileContent const& content) +{ + if (content.empty()) { + return; + } + + // Write a UTF-8 BOM so MSBuild knows the encoding when reading the file. + static const char utf8bom[] = { char(0xEF), char(0xBB), char(0xBF) }; + fout.write(utf8bom, sizeof(utf8bom)); + + // Write the format expected by MSBuild CustomBuild AdditionalInputs. + const char* sep = ""; + for (std::string path : content.front().paths) { + if (!cmSystemTools::FileIsFullPath(path)) { + path = + cmSystemTools::CollapseFullPath(path, lg.GetCurrentBinaryDirectory()); + } + std::replace(path.begin(), path.end(), '/', '\\'); + fout << sep << path; + sep = ";"; + } + fout << "\n"; +} } bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg, @@ -103,6 +131,9 @@ bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg, case cmDepfileFormat::MakeDepfile: WriteDepfile(format, fout, lg, content); break; + case cmDepfileFormat::MSBuildAdditionalInputs: + WriteMSBuildAdditionalInputs(fout, lg, content); + break; } return true; } diff --git a/Source/cmTransformDepfile.h b/Source/cmTransformDepfile.h index ce7cd66fe2..379e8bc882 100644 --- a/Source/cmTransformDepfile.h +++ b/Source/cmTransformDepfile.h @@ -7,7 +7,8 @@ enum class cmDepfileFormat { GccDepfile, - MakeDepfile + MakeDepfile, + MSBuildAdditionalInputs, }; class cmLocalGenerator; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 84ac1891f5..1f4c0b8052 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1531,6 +1531,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector const& args, format = cmDepfileFormat::GccDepfile; } else if (args[3] == "makedepfile") { format = cmDepfileFormat::MakeDepfile; + } else if (args[3] == "MSBuildAdditionalInputs") { + format = cmDepfileFormat::MSBuildAdditionalInputs; } else { return 1; } -- cgit v1.2.1 From 794ad78abb8da517e59e25ea38f5c1edced1cf46 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 8 Jun 2021 12:43:47 -0400 Subject: Help: Generalize release note filename for add_custom_command DEPFILE Rename the note added by commit d67cc4882d (Xcode: Add support of DEPFILE for add_custom_command, 2021-04-15) to be more general. --- Help/release/dev/Xcode-add_custom_command-DEPFILE.rst | 5 ----- Help/release/dev/add_custom_command-DEPFILE.rst | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 Help/release/dev/Xcode-add_custom_command-DEPFILE.rst create mode 100644 Help/release/dev/add_custom_command-DEPFILE.rst diff --git a/Help/release/dev/Xcode-add_custom_command-DEPFILE.rst b/Help/release/dev/Xcode-add_custom_command-DEPFILE.rst deleted file mode 100644 index 4c4d48c769..0000000000 --- a/Help/release/dev/Xcode-add_custom_command-DEPFILE.rst +++ /dev/null @@ -1,5 +0,0 @@ -Xcode-add_custom_command-DEPFILE --------------------------------- - -* The :command:`add_custom_command` command gained ``DEPFILE`` support on - :generator:`Xcode` generator. diff --git a/Help/release/dev/add_custom_command-DEPFILE.rst b/Help/release/dev/add_custom_command-DEPFILE.rst new file mode 100644 index 0000000000..6361a66446 --- /dev/null +++ b/Help/release/dev/add_custom_command-DEPFILE.rst @@ -0,0 +1,5 @@ +add_custom_command-DEPFILE +-------------------------- + +* The :command:`add_custom_command` command gained ``DEPFILE`` support on + the :generator:`Xcode` generator. -- cgit v1.2.1 From 526e2ef71c5b797818bbf232e21d0152a3938197 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 8 Jun 2021 12:45:20 -0400 Subject: VS: Add support for add_custom_command DEPFILE Transform the depfile into MSBuild `AdditionalInputs` content. Add MSBuild Targets to update `AdditionalInputs` and the `.tlog` files for future builds without actually modifying the `.vcxproj` file. Fixes: #20286 --- Help/command/add_custom_command.rst | 8 +++-- Help/release/dev/add_custom_command-DEPFILE.rst | 3 +- Source/cmGlobalVisualStudio11Generator.h | 7 ++++ Source/cmVisualStudio10TargetGenerator.cxx | 32 ++++++++++++++--- Source/cmVisualStudio10TargetGenerator.h | 8 +++-- Templates/MSBuild/CustomBuildDepFile.targets | 48 +++++++++++++++++++++++++ Tests/RunCMake/BuildDepends/RunCMakeTest.cmake | 3 +- 7 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 Templates/MSBuild/CustomBuildDepFile.targets diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index a053e59f79..d881a66b5c 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -282,17 +282,19 @@ The options are: :generator:`Xcode` or :ref:`Makefile ` is an error. .. versionadded:: 3.20 - Added the support of :ref:`Makefile Generators`. + Added support for :ref:`Makefile Generators`. .. versionadded:: 3.21 - Added the support of :generator:`Xcode` generator and + Added support for :ref:`Visual Studio Generators` with VS 2012 and above, + for the :generator:`Xcode` generator, and for :manual:`generator expressions `. If the ``DEPFILE`` argument is relative, it should be relative to :variable:`CMAKE_CURRENT_BINARY_DIR`, and any relative paths inside the ``DEPFILE`` should also be relative to :variable:`CMAKE_CURRENT_BINARY_DIR` (see policy :policy:`CMP0116`. This policy is always ``NEW`` for - :ref:`Makefile ` and :generator:`Xcode` generators). + :ref:`Makefile Generators`, :ref:`Visual Studio Generators`, + and the :generator:`Xcode` generator). .. note:: diff --git a/Help/release/dev/add_custom_command-DEPFILE.rst b/Help/release/dev/add_custom_command-DEPFILE.rst index 6361a66446..893c374e70 100644 --- a/Help/release/dev/add_custom_command-DEPFILE.rst +++ b/Help/release/dev/add_custom_command-DEPFILE.rst @@ -2,4 +2,5 @@ add_custom_command-DEPFILE -------------------------- * The :command:`add_custom_command` command gained ``DEPFILE`` support on - the :generator:`Xcode` generator. + the :generator:`Xcode` generator, and on :ref:`Visual Studio Generators` + for VS 2012 and above. diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h index 6e409cfa9e..b11905ec14 100644 --- a/Source/cmGlobalVisualStudio11Generator.h +++ b/Source/cmGlobalVisualStudio11Generator.h @@ -24,6 +24,13 @@ public: bool MatchesGeneratorName(const std::string& name) const override; + bool SupportsCustomCommandDepfile() const override { return true; } + + cm::optional DepfileFormat() const override + { + return cmDepfileFormat::MSBuildAdditionalInputs; + } + protected: cmGlobalVisualStudio11Generator(cmake* cm, const std::string& name, std::string const& platformInGeneratorName); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 98d56df32a..b79c6fda14 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -768,6 +768,11 @@ void cmVisualStudio10TargetGenerator::Generate() Elem(e1, "Import").Attribute("Project", nasmTargets); } } + if (this->ProjectType == vcxproj && this->HaveCustomCommandDepfile) { + std::string depfileTargets = + GetCMakeFilePath("Templates/MSBuild/CustomBuildDepFile.targets"); + Elem(e0, "Import").Attribute("Project", depfileTargets); + } if (this->ProjectType == csproj) { for (std::string const& c : this->Configurations) { Elem e1(e0, "PropertyGroup"); @@ -1460,7 +1465,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( e2.SetHasElements(); } for (std::string const& c : this->Configurations) { - cmCustomCommandGenerator ccg(command, c, lg); + cmCustomCommandGenerator ccg(command, c, lg, true); std::string comment = lg->ConstructComment(ccg); comment = cmVS10EscapeComment(comment); std::string script = lg->ConstructScript(ccg); @@ -1524,10 +1529,10 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( std::string name = "CustomCommand_" + c + "_" + cmSystemTools::ComputeStringMD5(sourcePath); this->WriteCustomRuleCSharp(e0, c, name, script, additional_inputs.str(), - outputs.str(), comment); + outputs.str(), comment, ccg); } else { this->WriteCustomRuleCpp(*spe2, c, script, additional_inputs.str(), - outputs.str(), comment, symbolic); + outputs.str(), comment, ccg, symbolic); } } } @@ -1535,7 +1540,8 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( Elem& e2, std::string const& config, std::string const& script, std::string const& additional_inputs, std::string const& outputs, - std::string const& comment, bool symbolic) + std::string const& comment, cmCustomCommandGenerator const& ccg, + bool symbolic) { const std::string cond = this->CalcCondition(config); e2.WritePlatformConfigTag("Message", cond, comment); @@ -1554,13 +1560,29 @@ void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( // outputs is marked SYMBOLIC and not expected to be created. e2.WritePlatformConfigTag("VerifyInputsAndOutputsExist", cond, "false"); } + + std::string depfile = ccg.GetFullDepfile(); + if (!depfile.empty()) { + this->HaveCustomCommandDepfile = true; + std::string internal_depfile = ccg.GetInternalDepfile(); + ConvertToWindowsSlash(internal_depfile); + e2.WritePlatformConfigTag("DepFileAdditionalInputsFile", cond, + internal_depfile); + } } void cmVisualStudio10TargetGenerator::WriteCustomRuleCSharp( Elem& e0, std::string const& config, std::string const& name, std::string const& script, std::string const& inputs, - std::string const& outputs, std::string const& comment) + std::string const& outputs, std::string const& comment, + cmCustomCommandGenerator const& ccg) { + if (!ccg.GetFullDepfile().empty()) { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("CSharp target \"", this->GeneratorTarget->GetName(), + "\" does not support add_custom_command DEPFILE.")); + } this->CSharpCustomCommandNames.insert(name); Elem e1(e0, "Target"); e1.Attribute("Condition", this->CalcCondition(config)); diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 35dbba8121..55c5444f1a 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -16,6 +16,7 @@ class cmComputeLinkInformation; class cmCustomCommand; +class cmCustomCommandGenerator; class cmGeneratedFileStream; class cmGlobalVisualStudio10Generator; class cmLocalVisualStudio10Generator; @@ -143,13 +144,15 @@ private: std::string const& script, std::string const& additional_inputs, std::string const& outputs, - std::string const& comment, bool symbolic); + std::string const& comment, + cmCustomCommandGenerator const& ccg, bool symbolic); void WriteCustomRuleCSharp(Elem& e0, std::string const& config, std::string const& commandName, std::string const& script, std::string const& inputs, std::string const& outputs, - std::string const& comment); + std::string const& comment, + cmCustomCommandGenerator const& ccg); void WriteCustomCommands(Elem& e0); void WriteCustomCommand(Elem& e0, cmSourceFile const* sf); void WriteGroups(); @@ -216,6 +219,7 @@ private: bool Managed; bool NsightTegra; bool Android; + bool HaveCustomCommandDepfile = false; unsigned int NsightTegraVersion[4]; bool TargetCompileAsWinRT; std::set IPOEnabledConfigurations; diff --git a/Templates/MSBuild/CustomBuildDepFile.targets b/Templates/MSBuild/CustomBuildDepFile.targets new file mode 100644 index 0000000000..2387ab5392 --- /dev/null +++ b/Templates/MSBuild/CustomBuildDepFile.targets @@ -0,0 +1,48 @@ + + + + + + + + %(CustomBuild.AdditionalInputs) + + + + $([System.IO.File]::ReadAllText('%(CustomBuild.DepFileAdditionalInputsFile)').TrimEnd()) + + + + %(CustomBuild.DepFileAdditionalInputs) + %(CustomBuild.AdditionalInputs);%(CustomBuild.DepFileAdditionalInputs) + + + + + + + + + + + $([System.IO.File]::ReadAllText('%(CustomBuild.DepFileAdditionalInputsFile)').TrimEnd()) + + + + ^%(CustomBuild.Identity) + + + %(ReadTLog)$([System.String]::Copy('%(CustomBuild.CMakeAdditionalInputs)').Trim(';').Replace(';', ' ')) + + + %(ReadTLog)$([System.String]::Copy('%(CustomBuild.DepFileAdditionalInputs)').Trim(';').Replace(';', ' ')) + + + + + @(CustomBuild->'%(ReadTLog)','') + + + + + diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake index 0a8058049b..f8c20c2ea1 100644 --- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake +++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake @@ -172,7 +172,8 @@ if (RunCMake_GENERATOR MATCHES "Makefiles") run_cmake(CustomCommandDependencies-BadArgs) endif() -if(RunCMake_GENERATOR MATCHES "Make|Ninja|Xcode") +if(RunCMake_GENERATOR MATCHES "Make|Ninja|Visual Studio|Xcode" AND + NOT RunCMake_GENERATOR MATCHES "Visual Studio (9|10)( |$)") unset(run_BuildDepends_skip_step_3) run_BuildDepends(CustomCommandDepfile) set(run_BuildDepends_skip_step_3 1) -- cgit v1.2.1