1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

Merge topic 'vs-custom-depfile'

526e2ef71c VS: Add support for add_custom_command DEPFILE
794ad78abb Help: Generalize release note filename for add_custom_command DEPFILE
7291f31254 cmTransformDepfile: Add support for MSBuild AdditionalInputs format
a6de8ec51b cmTransformDepfile: Make directory for transformed depfile automatically

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !6206
This commit is contained in:
Brad King
2021-06-10 12:23:39 +00:00
committed by Kitware Robot
13 changed files with 143 additions and 19 deletions

View File

@@ -282,17 +282,19 @@ The options are:
:generator:`Xcode` or :ref:`Makefile <Makefile Generators>` 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 <cmake-generator-expressions(7)>`.
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 <Makefile Generators>` and :generator:`Xcode` generators).
:ref:`Makefile Generators`, :ref:`Visual Studio Generators`,
and the :generator:`Xcode` generator).
.. note::

View File

@@ -1,5 +0,0 @@
Xcode-add_custom_command-DEPFILE
--------------------------------
* The :command:`add_custom_command` command gained ``DEPFILE`` support on
:generator:`Xcode` generator.

View File

@@ -0,0 +1,6 @@
add_custom_command-DEPFILE
--------------------------
* The :command:`add_custom_command` command gained ``DEPFILE`` support on
the :generator:`Xcode` generator, and on :ref:`Visual Studio Generators`
for VS 2012 and above.

View File

@@ -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);

View File

@@ -24,6 +24,13 @@ public:
bool MatchesGeneratorName(const std::string& name) const override;
bool SupportsCustomCommandDepfile() const override { return true; }
cm::optional<cmDepfileFormat> DepfileFormat() const override
{
return cmDepfileFormat::MSBuildAdditionalInputs;
}
protected:
cmGlobalVisualStudio11Generator(cmake* cm, const std::string& name,
std::string const& platformInGeneratorName);

View File

@@ -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;
}

View File

@@ -2,7 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTransformDepfile.h"
#include <algorithm>
#include <functional>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
@@ -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,
@@ -93,6 +121,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;
@@ -102,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;
}

View File

@@ -7,7 +7,8 @@
enum class cmDepfileFormat
{
GccDepfile,
MakeDepfile
MakeDepfile,
MSBuildAdditionalInputs,
};
class cmLocalGenerator;

View File

@@ -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));

View File

@@ -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<std::string> IPOEnabledConfigurations;

View File

@@ -1531,6 +1531,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
format = cmDepfileFormat::GccDepfile;
} else if (args[3] == "makedepfile") {
format = cmDepfileFormat::MakeDepfile;
} else if (args[3] == "MSBuildAdditionalInputs") {
format = cmDepfileFormat::MSBuildAdditionalInputs;
} else {
return 1;
}

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Update AdditionalInputs with depfile-discovered inputs. -->
<Target Name="CMakeCustomBuildDepFileAdditionalInputs" BeforeTargets="CustomBuild" Condition="'@(CustomBuild)' != ''">
<ItemGroup>
<!-- Save original AdditionalInputs generated by CMake. -->
<CustomBuild>
<CMakeAdditionalInputs>%(CustomBuild.AdditionalInputs)</CMakeAdditionalInputs>
</CustomBuild>
<!-- Read depfile-discovered inputs. -->
<CustomBuild Condition="Exists('%(CustomBuild.DepFileAdditionalInputsFile)')">
<DepFileAdditionalInputs>$([System.IO.File]::ReadAllText('%(CustomBuild.DepFileAdditionalInputsFile)').TrimEnd())</DepFileAdditionalInputs>
</CustomBuild>
<!-- Add depfile-discovered inputs to AdditionalInputs. -->
<CustomBuild Condition="'%(CustomBuild.DepFileAdditionalInputs)' != ''">
<AdditionalInputs Condition="'%(CustomBuild.AdditionalInputs)' == ''">%(CustomBuild.DepFileAdditionalInputs)</AdditionalInputs>
<AdditionalInputs Condition="'%(CustomBuild.AdditionalInputs)' != ''">%(CustomBuild.AdditionalInputs);%(CustomBuild.DepFileAdditionalInputs)</AdditionalInputs>
</CustomBuild>
</ItemGroup>
</Target>
<!-- Update the tracking log with depfile-discovered inputs. -->
<Target Name="CMakeCustomBuildDepFileTrackingLog" AfterTargets="CustomBuild" Condition="'@(CustomBuild)' != ''">
<!-- Compute the tracking log content for each CustomBuild item individually. -->
<ItemGroup>
<!-- Read depfile-discovered inputs. -->
<CustomBuild Condition="Exists('%(CustomBuild.DepFileAdditionalInputsFile)')">
<DepFileAdditionalInputs>$([System.IO.File]::ReadAllText('%(CustomBuild.DepFileAdditionalInputsFile)').TrimEnd())</DepFileAdditionalInputs>
</CustomBuild>
<!-- Generate tracking log representation of all inputs. -->
<CustomBuild>
<ReadTLog>^%(CustomBuild.Identity)&#xD;&#xA;</ReadTLog>
</CustomBuild>
<CustomBuild Condition="'%(CustomBuild.CMakeAdditionalInputs)' != ''">
<ReadTLog>%(ReadTLog)$([System.String]::Copy('%(CustomBuild.CMakeAdditionalInputs)').Trim(';').Replace(';', '&#xD;&#xA;'))&#xD;&#xA;</ReadTLog>
</CustomBuild>
<CustomBuild Condition="'%(CustomBuild.DepFileAdditionalInputs)' != ''">
<ReadTLog>%(ReadTLog)$([System.String]::Copy('%(CustomBuild.DepFileAdditionalInputs)').Trim(';').Replace(';', '&#xD;&#xA;'))&#xD;&#xA;</ReadTLog>
</CustomBuild>
</ItemGroup>
<!-- Compute the combined tracking log for all CustomBuild items together. -->
<PropertyGroup>
<CustomBuildReadTLog>@(CustomBuild->'%(ReadTLog)','')</CustomBuildReadTLog>
</PropertyGroup>
<!-- Replace the combined tracking log on disk. -->
<WriteLinesToFile File="$(TLogLocation)CustomBuild.read.1.tlog" Overwrite="true" Lines="$(CustomBuildReadTLog.ToUpper())" />
</Target>
</Project>

View File

@@ -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)