Merge topic 'Xcode-add_custom_command-DEPFILE'

d67cc4882d Xcode: Add support of DEPFILE for add_custom_command

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !6006
This commit is contained in:
Brad King
2021-04-16 15:42:16 +00:00
committed by Kitware Robot
9 changed files with 115 additions and 27 deletions
+23 -7
View File
@@ -151,7 +151,9 @@ std::string EvaluateDepfile(std::string const& path,
cmCustomCommandGenerator::cmCustomCommandGenerator(
cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg,
bool transformDepfile, cm::optional<std::string> crossConfig)
bool transformDepfile, cm::optional<std::string> crossConfig,
std::function<std::string(const std::string&, const std::string&)>
computeInternalDepfile)
: CC(&cc)
, OutputConfig(crossConfig ? *crossConfig : config)
, CommandConfig(std::move(config))
@@ -159,7 +161,15 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
, OldStyle(cc.GetEscapeOldStyle())
, MakeVars(cc.GetEscapeAllowMakeVars())
, EmulatorsWithArguments(cc.GetCommandLines().size())
, ComputeInternalDepfile(std::move(computeInternalDepfile))
{
if (!this->ComputeInternalDepfile) {
this->ComputeInternalDepfile =
[this](const std::string& cfg, const std::string& file) -> std::string {
return this->GetInternalDepfileName(cfg, file);
};
}
cmGeneratorExpression ge(cc.GetBacktrace());
const cmCustomCommandLines& cmdlines = this->CC->GetCommandLines();
@@ -413,13 +423,9 @@ std::string cmCustomCommandGenerator::GetFullDepfile() const
return cmSystemTools::CollapseFullPath(depfile);
}
std::string cmCustomCommandGenerator::GetInternalDepfile() const
std::string cmCustomCommandGenerator::GetInternalDepfileName(
const std::string& /*config*/, const std::string& depfile)
{
std::string depfile = this->GetFullDepfile();
if (depfile.empty()) {
return "";
}
cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
std::string extension;
switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
@@ -434,6 +440,16 @@ std::string cmCustomCommandGenerator::GetInternalDepfile() const
hash.HashString(depfile), extension);
}
std::string cmCustomCommandGenerator::GetInternalDepfile() const
{
std::string depfile = this->GetFullDepfile();
if (depfile.empty()) {
return "";
}
return this->ComputeInternalDepfile(this->OutputConfig, depfile);
}
const char* cmCustomCommandGenerator::GetComment() const
{
return this->CC->GetComment();
+10 -3
View File
@@ -4,6 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <functional>
#include <set>
#include <string>
#include <utility>
@@ -19,6 +20,8 @@ class cmLocalGenerator;
class cmCustomCommandGenerator
{
std::string GetInternalDepfileName(const std::string&, const std::string&);
cmCustomCommand const* CC;
std::string OutputConfig;
std::string CommandConfig;
@@ -32,15 +35,19 @@ class cmCustomCommandGenerator
std::vector<std::string> Depends;
std::string WorkingDirectory;
std::set<BT<std::pair<std::string, bool>>> Utilities;
std::function<std::string(const std::string&, const std::string&)>
ComputeInternalDepfile;
void FillEmulatorsWithArguments();
std::vector<std::string> GetCrossCompilingEmulator(unsigned int c) const;
const char* GetArgv0Location(unsigned int c) const;
public:
cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config,
cmLocalGenerator* lg, bool transformDepfile = true,
cm::optional<std::string> crossConfig = {});
cmCustomCommandGenerator(
cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg,
bool transformDepfile = true, cm::optional<std::string> crossConfig = {},
std::function<std::string(const std::string&, const std::string&)>
computeInternalDepfile = {});
cmCustomCommandGenerator(const cmCustomCommandGenerator&) = delete;
cmCustomCommandGenerator(cmCustomCommandGenerator&&) = default;
cmCustomCommandGenerator& operator=(const cmCustomCommandGenerator&) =
+29 -4
View File
@@ -17,6 +17,7 @@
#include "cmsys/RegularExpression.hxx"
#include "cmCMakePath.h"
#include "cmComputeLinkInformation.h"
#include "cmCryptoHash.h"
#include "cmCustomCommand.h"
@@ -1864,9 +1865,20 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
std::set<std::string> allConfigInputs;
std::set<std::string> allConfigOutputs;
cmXCodeObject* buildPhase =
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase,
cmStrCat(gt->GetName(), ':', sf->GetFullPath()));
auto depfilesDirectory = cmStrCat(
gt->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/CMakeFiles/d/");
auto depfilesPrefix = cmStrCat(depfilesDirectory, buildPhase->GetId(), ".");
std::string shellScript = "set -e\n";
for (std::string const& configName : this->CurrentConfigurationTypes) {
cmCustomCommandGenerator ccg(cc, configName, this->CurrentLocalGenerator);
cmCustomCommandGenerator ccg(
cc, configName, this->CurrentLocalGenerator, true, {},
[&depfilesPrefix](const std::string& config, const std::string&)
-> std::string { return cmStrCat(depfilesPrefix, config, ".d"); });
std::vector<std::string> realDepends;
realDepends.reserve(ccg.GetDepends().size());
for (auto const& d : ccg.GetDepends()) {
@@ -1886,9 +1898,22 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
"\"; then :\n", this->ConstructScript(ccg), "fi\n");
}
cmXCodeObject* buildPhase =
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase,
cmStrCat(gt->GetName(), ':', sf->GetFullPath()));
if (!cc.GetDepfile().empty()) {
buildPhase->AddAttribute(
"dependencyFile",
this->CreateString(cmStrCat(depfilesDirectory, buildPhase->GetId(),
".$(CONFIGURATION).d")));
// to avoid spurious errors during first build, create empty dependency
// files
cmSystemTools::MakeDirectory(depfilesDirectory);
for (std::string const& configName : this->CurrentConfigurationTypes) {
auto file = cmStrCat(depfilesPrefix, configName, ".d");
if (!cmSystemTools::FileExists(file)) {
cmSystemTools::Touch(file, true);
}
}
}
buildPhase->AddAttribute("buildActionMask",
this->CreateString("2147483647"));
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+13
View File
@@ -14,6 +14,7 @@
#include <cm/string_view>
#include "cmGlobalGenerator.h"
#include "cmTransformDepfile.h"
#include "cmXCodeObject.h"
class cmCustomCommand;
@@ -111,6 +112,18 @@ public:
bool ShouldStripResourcePath(cmMakefile*) const override;
/**
* Used to determine if this generator supports DEPFILE option.
*/
bool SupportsCustomCommandDepfile() const override
{
return this->XcodeBuildSystem >= BuildSystem::Twelve;
}
virtual cm::optional<cmDepfileFormat> DepfileFormat() const override
{
return cmDepfileFormat::GccDepfile;
}
bool SetSystemName(std::string const& s, cmMakefile* mf) override;
bool SetGeneratorToolset(std::string const& ts, bool build,
cmMakefile* mf) override;
+12 -2
View File
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTransformDepfile.h"
#include <functional>
#include <string>
#include <type_traits>
#include <utility>
@@ -13,6 +14,7 @@
#include "cmGccDepfileReader.h"
#include "cmGccDepfileReaderTypes.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
@@ -38,6 +40,14 @@ void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg,
const cmGccDepfileContent& content)
{
const auto& binDir = lg.GetBinaryDirectory();
std::function<std::string(const std::string&)> formatPath =
[&lg, &binDir](const std::string& path) -> std::string {
return lg.MaybeConvertToRelativePath(binDir, path);
};
if (lg.GetGlobalGenerator()->GetName() == "Xcode") {
// full paths must be preserved for Xcode compliance
formatPath = [](const std::string& path) -> std::string { return path; };
}
for (auto const& dep : content) {
bool first = true;
@@ -46,12 +56,12 @@ void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg,
fout << " \\\n ";
}
first = false;
WriteFilenameGcc(fout, lg.MaybeConvertToRelativePath(binDir, rule));
WriteFilenameGcc(fout, formatPath(rule));
}
fout << ':';
for (auto const& path : dep.paths) {
fout << " \\\n ";
WriteFilenameGcc(fout, lg.MaybeConvertToRelativePath(binDir, path));
WriteFilenameGcc(fout, formatPath(path));
}
fout << '\n';
}