diff options
Diffstat (limited to 'Source/cmCustomCommandGenerator.cxx')
-rw-r--r-- | Source/cmCustomCommandGenerator.cxx | 114 |
1 files changed, 100 insertions, 14 deletions
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 60504ba..08a0574 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -6,18 +6,22 @@ #include <memory> #include <utility> +#include <cm/optional> #include <cmext/algorithm> +#include "cmCryptoHash.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" +#include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmProperty.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmTransformDepfile.h" namespace { void AppendPaths(const std::vector<std::string>& inputs, @@ -31,8 +35,7 @@ void AppendPaths(const std::vector<std::string>& inputs, for (std::string& it : result) { cmSystemTools::ConvertToUnixSlashes(it); if (cmSystemTools::FileIsFullPath(it)) { - it = cmSystemTools::CollapseFullPath( - it, lg->GetMakefile()->GetHomeOutputDirectory()); + it = cmSystemTools::CollapseFullPath(it); } } cm::append(output, result); @@ -42,8 +45,9 @@ void AppendPaths(const std::vector<std::string>& inputs, cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config, - cmLocalGenerator* lg) - : CC(cc) + cmLocalGenerator* lg, + bool transformDepfile) + : CC(&cc) , Config(std::move(config)) , LG(lg) , OldStyle(cc.GetEscapeOldStyle()) @@ -52,34 +56,76 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, { cmGeneratorExpression ge(cc.GetBacktrace()); - const cmCustomCommandLines& cmdlines = this->CC.GetCommandLines(); + const cmCustomCommandLines& cmdlines = this->CC->GetCommandLines(); for (cmCustomCommandLine const& cmdline : cmdlines) { cmCustomCommandLine argv; for (std::string const& clarg : cmdline) { std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(clarg); std::string parsed_arg = cge->Evaluate(this->LG, this->Config); - if (this->CC.GetCommandExpandLists()) { + for (cmGeneratorTarget* gt : cge->GetTargets()) { + this->Utilities.emplace(BT<std::pair<std::string, bool>>( + { gt->GetName(), true }, cge->GetBacktrace())); + } + if (this->CC->GetCommandExpandLists()) { cm::append(argv, cmExpandedList(parsed_arg)); } else { argv.push_back(std::move(parsed_arg)); } } - // Later code assumes at least one entry exists, but expanding - // lists on an empty command may have left this empty. - // FIXME: Should we define behavior for removing empty commands? - if (argv.empty()) { + if (!argv.empty()) { + // If the command references an executable target by name, + // collect the target to add a target-level dependency on it. + cmGeneratorTarget* gt = this->LG->FindGeneratorTargetToUse(argv.front()); + if (gt && gt->GetType() == cmStateEnums::EXECUTABLE) { + this->Utilities.emplace(BT<std::pair<std::string, bool>>( + { gt->GetName(), true }, cc.GetBacktrace())); + } + } else { + // Later code assumes at least one entry exists, but expanding + // lists on an empty command may have left this empty. + // FIXME: Should we define behavior for removing empty commands? argv.emplace_back(); } this->CommandLines.push_back(std::move(argv)); } + if (transformDepfile && !this->CommandLines.empty() && + !cc.GetDepfile().empty() && + this->LG->GetGlobalGenerator()->DepfileFormat()) { + cmCustomCommandLine argv; + argv.push_back(cmSystemTools::GetCMakeCommand()); + argv.emplace_back("-E"); + argv.emplace_back("cmake_transform_depfile"); + switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) { + case cmDepfileFormat::GccDepfile: + argv.emplace_back("gccdepfile"); + break; + case cmDepfileFormat::VsTlog: + argv.emplace_back("vstlog"); + break; + } + if (this->LG->GetCurrentBinaryDirectory() == + this->LG->GetBinaryDirectory()) { + argv.emplace_back("./"); + } else { + argv.push_back(cmStrCat(this->LG->MaybeConvertToRelativePath( + this->LG->GetBinaryDirectory(), + this->LG->GetCurrentBinaryDirectory()), + '/')); + } + argv.push_back(this->GetFullDepfile()); + argv.push_back(this->GetInternalDepfile()); + + this->CommandLines.push_back(std::move(argv)); + } + AppendPaths(cc.GetByproducts(), ge, this->LG, this->Config, this->Byproducts); AppendPaths(cc.GetDepends(), ge, this->LG, this->Config, this->Depends); - const std::string& workingdirectory = this->CC.GetWorkingDirectory(); + const std::string& workingdirectory = this->CC->GetWorkingDirectory(); if (!workingdirectory.empty()) { std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(workingdirectory); @@ -97,7 +143,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const { - return static_cast<unsigned int>(this->CC.GetCommandLines().size()); + return static_cast<unsigned int>(this->CommandLines.size()); } void cmCustomCommandGenerator::FillEmulatorsWithArguments() @@ -234,9 +280,43 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c, } } +std::string cmCustomCommandGenerator::GetFullDepfile() const +{ + std::string depfile = this->CC->GetDepfile(); + if (depfile.empty()) { + return ""; + } + + if (!cmSystemTools::FileIsFullPath(depfile)) { + depfile = cmStrCat(this->LG->GetCurrentBinaryDirectory(), '/', depfile); + } + return cmSystemTools::CollapseFullPath(depfile); +} + +std::string cmCustomCommandGenerator::GetInternalDepfile() const +{ + std::string depfile = this->GetFullDepfile(); + if (depfile.empty()) { + return ""; + } + + cmCryptoHash hash(cmCryptoHash::AlgoSHA256); + std::string extension; + switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) { + case cmDepfileFormat::GccDepfile: + extension = ".d"; + break; + case cmDepfileFormat::VsTlog: + extension = ".tlog"; + break; + } + return cmStrCat(this->LG->GetBinaryDirectory(), "/CMakeFiles/d/", + hash.HashString(depfile), extension); +} + const char* cmCustomCommandGenerator::GetComment() const { - return this->CC.GetComment(); + return this->CC->GetComment(); } std::string cmCustomCommandGenerator::GetWorkingDirectory() const @@ -246,7 +326,7 @@ std::string cmCustomCommandGenerator::GetWorkingDirectory() const std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const { - return this->CC.GetOutputs(); + return this->CC->GetOutputs(); } std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const @@ -258,3 +338,9 @@ std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const { return this->Depends; } + +std::set<BT<std::pair<std::string, bool>>> const& +cmCustomCommandGenerator::GetUtilities() const +{ + return this->Utilities; +} |