From fcedf8e5528d711f1e4b765809da018d5adb2abd Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 30 May 2019 13:47:26 -0400 Subject: VS: Isolate custom command input/output generation scopes --- Source/cmVisualStudio10TargetGenerator.cxx | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 7736e59..3f0d41d 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1354,22 +1354,26 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( std::string script = lg->ConstructScript(ccg); // input files for custom command std::stringstream inputs; - inputs << source->GetFullPath(); - for (std::string const& d : ccg.GetDepends()) { - std::string dep; - if (lg->GetRealDependency(d, c, dep)) { - ConvertToWindowsSlash(dep); - inputs << ";" << dep; + { + inputs << source->GetFullPath(); + for (std::string const& d : ccg.GetDepends()) { + std::string dep; + if (lg->GetRealDependency(d, c, dep)) { + ConvertToWindowsSlash(dep); + inputs << ";" << dep; + } } } // output files for custom command std::stringstream outputs; - const char* sep = ""; - for (std::string const& o : ccg.GetOutputs()) { - std::string out = o; - ConvertToWindowsSlash(out); - outputs << sep << out; - sep = ";"; + { + const char* sep = ""; + for (std::string const& o : ccg.GetOutputs()) { + std::string out = o; + ConvertToWindowsSlash(out); + outputs << sep << out; + sep = ";"; + } } if (this->ProjectType == csproj) { std::string name = "CustomCommand_" + c + "_" + -- cgit v0.12 From d03a6fc8578ac2b4191a74c8638d58b7f92ec6f1 Mon Sep 17 00:00:00 2001 From: Frans van Dorsselaer Date: Tue, 28 May 2019 15:53:13 +0200 Subject: VS: Clarify name of custom commands AdditionalInputs variable --- Source/cmVisualStudio10TargetGenerator.cxx | 16 ++++++++-------- Source/cmVisualStudio10TargetGenerator.h | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 3f0d41d..0405222 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1353,14 +1353,14 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( comment = cmVS10EscapeComment(comment); std::string script = lg->ConstructScript(ccg); // input files for custom command - std::stringstream inputs; + std::stringstream additional_inputs; { - inputs << source->GetFullPath(); + additional_inputs << source->GetFullPath(); for (std::string const& d : ccg.GetDepends()) { std::string dep; if (lg->GetRealDependency(d, c, dep)) { ConvertToWindowsSlash(dep); - inputs << ";" << dep; + additional_inputs << ";" << dep; } } } @@ -1378,25 +1378,25 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( if (this->ProjectType == csproj) { std::string name = "CustomCommand_" + c + "_" + cmSystemTools::ComputeStringMD5(sourcePath); - this->WriteCustomRuleCSharp(e0, c, name, script, inputs.str(), + this->WriteCustomRuleCSharp(e0, c, name, script, additional_inputs.str(), outputs.str(), comment); } else { - this->WriteCustomRuleCpp(*spe2, c, script, inputs.str(), outputs.str(), - comment); + this->WriteCustomRuleCpp(*spe2, c, script, additional_inputs.str(), + outputs.str(), comment); } } } void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( Elem& e2, std::string const& config, std::string const& script, - std::string const& inputs, std::string const& outputs, + std::string const& additional_inputs, std::string const& outputs, std::string const& comment) { const std::string cond = this->CalcCondition(config); e2.WritePlatformConfigTag("Message", cond, comment); e2.WritePlatformConfigTag("Command", cond, script); e2.WritePlatformConfigTag("AdditionalInputs", cond, - inputs + ";%(AdditionalInputs)"); + additional_inputs + ";%(AdditionalInputs)"); e2.WritePlatformConfigTag("Outputs", cond, outputs); if (this->LocalGenerator->GetVersion() > cmGlobalVisualStudioGenerator::VS10) { diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 5901004..68db332 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -135,7 +135,8 @@ private: void WriteCustomRule(Elem& e0, cmSourceFile const* source, cmCustomCommand const& command); void WriteCustomRuleCpp(Elem& e2, std::string const& config, - std::string const& script, std::string const& inputs, + std::string const& script, + std::string const& additional_inputs, std::string const& outputs, std::string const& comment); void WriteCustomRuleCSharp(Elem& e0, std::string const& config, -- cgit v0.12 From 42bc67bd43ca67c98dc33f8cb8e2f4ee3884697f Mon Sep 17 00:00:00 2001 From: Frans van Dorsselaer Date: Tue, 28 May 2019 15:53:13 +0200 Subject: VS: De-duplicate custom command dependencies Avoid listing the same input more than once in custom commands generated in `.vcxproj` and `.csproj` files. In the case of a `.vcxproj` file additionally avoid listing the source to which the command is attached since it is already implicitly a dependency. This is a nice cleanup and also works around a VS 2019 16.1 regression in MSBuild dependency checking. Starting with that version, MSBuild now re-builds custom commands when the list of dependencies has changed. However, its check is confused by duplicate dependencies. De-duplicating them avoids this problem. Co-Author: Brad King Fixes: #19303 --- Source/cmVisualStudio10TargetGenerator.cxx | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 0405222..f2f5e3f 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -18,6 +18,7 @@ #include #include // IWYU pragma: keep +#include static void ConvertToWindowsSlash(std::string& s); @@ -1355,14 +1356,34 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( // input files for custom command std::stringstream additional_inputs; { - additional_inputs << source->GetFullPath(); + const char* sep = ""; + if (this->ProjectType == csproj) { + // csproj files do not attach the command to a specific file + // so the primary input must be listed explicitly. + additional_inputs << source->GetFullPath(); + sep = ";"; + } + + // Avoid listing an input more than once. + std::set unique_inputs; + // The source is either implicit an input or has been added above. + unique_inputs.insert(source->GetFullPath()); + for (std::string const& d : ccg.GetDepends()) { std::string dep; if (lg->GetRealDependency(d, c, dep)) { + if (!unique_inputs.insert(dep).second) { + // already listed + continue; + } ConvertToWindowsSlash(dep); - additional_inputs << ";" << dep; + additional_inputs << sep << dep; + sep = ";"; } } + if (this->ProjectType != csproj) { + additional_inputs << sep << "%(AdditionalInputs)"; + } } // output files for custom command std::stringstream outputs; @@ -1395,8 +1416,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( const std::string cond = this->CalcCondition(config); e2.WritePlatformConfigTag("Message", cond, comment); e2.WritePlatformConfigTag("Command", cond, script); - e2.WritePlatformConfigTag("AdditionalInputs", cond, - additional_inputs + ";%(AdditionalInputs)"); + e2.WritePlatformConfigTag("AdditionalInputs", cond, additional_inputs); e2.WritePlatformConfigTag("Outputs", cond, outputs); if (this->LocalGenerator->GetVersion() > cmGlobalVisualStudioGenerator::VS10) { -- cgit v0.12