summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-05-04 13:06:13 +0000
committerKitware Robot <kwrobot@kitware.com>2023-05-04 09:06:23 -0400
commit0d2d5a229c1cda842f0e67134637f19fc69de6c6 (patch)
treea49e9c37852a30be719018dd3572742739e81ad4 /Source
parentbf36ce2ff6122adbbfa4df2d8f731f57ca282d27 (diff)
parent375e6fdbbe398921de321216125765ba1917a325 (diff)
downloadcmake-0d2d5a229c1cda842f0e67134637f19fc69de6c6.tar.gz
Merge topic 'use-linker-depfile'
375e6fdbbe Link step: use linker dependency linker file 24a3e5cda0 cmLocalGenerator::MayBeRelativeToWorkDir: take care of all cases Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !8443
Diffstat (limited to 'Source')
-rw-r--r--Source/cmDependsCompiler.cxx24
-rw-r--r--Source/cmGccDepfileLexerHelper.cxx6
-rw-r--r--Source/cmGeneratorTarget.cxx24
-rw-r--r--Source/cmGeneratorTarget.h3
-rw-r--r--Source/cmGlobalGenerator.h2
-rw-r--r--Source/cmGlobalNinjaGenerator.h2
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h6
-rw-r--r--Source/cmLocalCommonGenerator.cxx16
-rw-r--r--Source/cmLocalCommonGenerator.h15
-rw-r--r--Source/cmLocalGenerator.cxx38
-rw-r--r--Source/cmLocalGenerator.h8
-rw-r--r--Source/cmLocalNinjaGenerator.cxx22
-rw-r--r--Source/cmLocalNinjaGenerator.h7
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx20
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h3
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx2
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx3
-rw-r--r--Source/cmMakefileTargetGenerator.cxx29
-rw-r--r--Source/cmMakefileTargetGenerator.h2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx15
-rw-r--r--Source/cmOutputConverter.h10
21 files changed, 214 insertions, 43 deletions
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx
index 0cc4946e48..c8061c36ee 100644
--- a/Source/cmDependsCompiler.cxx
+++ b/Source/cmDependsCompiler.cxx
@@ -128,7 +128,7 @@ bool cmDependsCompiler::CheckDependencies(
}
std::string line;
- if (!isValidPath) {
+ if (!isValidPath && !source.empty()) {
// insert source as first dependency
depends.push_back(source);
}
@@ -158,14 +158,16 @@ bool cmDependsCompiler::CheckDependencies(
}
// ensure source file is the first dependency
- if (depends.front() != source) {
- cm::erase(depends, source);
- if (!isValidPath) {
- depends.insert(depends.begin(), source);
+ if (!source.empty()) {
+ if (depends.front() != source) {
+ cm::erase(depends, source);
+ if (!isValidPath) {
+ depends.insert(depends.begin(), source);
+ }
+ } else if (isValidPath) {
+ // remove first dependency because it must not be filtered out
+ depends.erase(depends.begin());
}
- } else if (isValidPath) {
- // remove first dependency because it must not be filtered out
- depends.erase(depends.begin());
}
} else {
// unknown format, ignore it
@@ -174,8 +176,10 @@ bool cmDependsCompiler::CheckDependencies(
if (isValidPath) {
cm::erase_if(depends, isValidPath);
- // insert source as first dependency
- depends.insert(depends.begin(), source);
+ if (!source.empty()) {
+ // insert source as first dependency
+ depends.insert(depends.begin(), source);
+ }
}
dependencies[target] = std::move(depends);
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
index 34c88248a0..87377de401 100644
--- a/Source/cmGccDepfileLexerHelper.cxx
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGccDepfileLexerHelper.h"
+#include <algorithm>
#include <cstdio>
#include <memory>
#include <string>
@@ -113,6 +114,11 @@ void cmGccDepfileLexerHelper::addToCurrentPath(const char* s)
void cmGccDepfileLexerHelper::sanitizeContent()
{
for (auto it = this->Content.begin(); it != this->Content.end();) {
+ // remove duplicate path entries
+ std::sort(it->paths.begin(), it->paths.end());
+ auto last = std::unique(it->paths.begin(), it->paths.end());
+ it->paths.erase(last, it->paths.end());
+
// Remove empty paths and normalize windows paths
for (auto pit = it->paths.begin(); pit != it->paths.end();) {
if (pit->empty()) {
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 2eae2451bb..897619cbfa 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -8541,6 +8541,30 @@ bool cmGeneratorTarget::IsLinkable() const
this->IsExecutableWithExports());
}
+bool cmGeneratorTarget::HasLinkDependencyFile(std::string const& config) const
+{
+ if (this->GetType() != cmStateEnums::EXECUTABLE &&
+ this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::MODULE_LIBRARY) {
+ return false;
+ }
+
+ if (this->Target->GetProperty("LINK_DEPENDS_NO_SHARED").IsOn()) {
+ // Do not use the linker dependency file because it includes shared
+ // libraries as well
+ return false;
+ }
+
+ const std::string depsUseLinker{ "CMAKE_LINK_DEPENDS_USE_LINKER" };
+ auto linkLanguage = this->GetLinkerLanguage(config);
+ const std::string langDepsUseLinker{ cmStrCat("CMAKE_", linkLanguage,
+ "_LINK_DEPENDS_USE_LINKER") };
+
+ return (!this->Makefile->IsDefinitionSet(depsUseLinker) ||
+ this->Makefile->IsOn(depsUseLinker)) &&
+ this->Makefile->IsOn(langDepsUseLinker);
+}
+
bool cmGeneratorTarget::IsFrameworkOnApple() const
{
return this->Target->IsFrameworkOnApple();
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 8b44eb50a9..78945c3fa9 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -805,6 +805,9 @@ public:
/** Return whether this target may be used to link another target. */
bool IsLinkable() const;
+ /** Return whether the link step generates a dependency file. */
+ bool HasLinkDependencyFile(std::string const& config) const;
+
/** Return whether this target is a shared library Framework on
Apple. */
bool IsFrameworkOnApple() const;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index dde364886e..79fe52c193 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -546,6 +546,8 @@ public:
return cm::nullopt;
}
+ virtual bool SupportsLinkerDependencyFile() const { return false; }
+
std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
/** Generate an <output>.rule file path for a given command output. */
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index bd541685c9..bfbe57f22b 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -236,6 +236,8 @@ public:
return cmDepfileFormat::GccDepfile;
}
+ bool SupportsLinkerDependencyFile() const override { return true; }
+
virtual cmGeneratedFileStream* GetImplFileStream(
const std::string& /*config*/) const
{
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 214ba2af51..760679a051 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -99,6 +99,12 @@ public:
*/
bool SupportsCustomCommandDepfile() const override { return true; }
+ /**
+ * Utilized to determine if this generator
+ * supports linker dependency file.
+ */
+ bool SupportsLinkerDependencyFile() const override { return true; }
+
/** Get the documentation entry for this generator. */
static cmDocumentationEntry GetDocumentation();
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index eca7a9eb6e..aa953f469d 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -8,7 +8,6 @@
#include "cmGeneratorTarget.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
-#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
@@ -17,9 +16,8 @@
class cmGlobalGenerator;
cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
- cmMakefile* mf, WorkDir wd)
+ cmMakefile* mf)
: cmLocalGenerator(gg, mf)
- , WorkingDirectory(wd)
{
this->ConfigNames =
this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
@@ -29,21 +27,9 @@ cmLocalCommonGenerator::~cmLocalCommonGenerator() = default;
std::string const& cmLocalCommonGenerator::GetWorkingDirectory() const
{
- if (this->WorkingDirectory == WorkDir::TopBin) {
- return this->GetState()->GetBinaryDirectory();
- }
return this->StateSnapshot.GetDirectory().GetCurrentBinary();
}
-std::string cmLocalCommonGenerator::MaybeRelativeToWorkDir(
- std::string const& path) const
-{
- if (this->WorkingDirectory == WorkDir::TopBin) {
- return this->MaybeRelativeToTopBinDir(path);
- }
- return this->MaybeRelativeToCurBinDir(path);
-}
-
std::string cmLocalCommonGenerator::GetTargetFortranFlags(
cmGeneratorTarget const* target, std::string const& config)
{
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
index 0505c138d1..52f7a9e5e6 100644
--- a/Source/cmLocalCommonGenerator.h
+++ b/Source/cmLocalCommonGenerator.h
@@ -20,15 +20,8 @@ class cmSourceFile;
*/
class cmLocalCommonGenerator : public cmLocalGenerator
{
-protected:
- enum class WorkDir
- {
- TopBin,
- CurBin,
- };
-
public:
- cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf, WorkDir wd);
+ cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
~cmLocalCommonGenerator() override;
std::vector<std::string> const& GetConfigNames() const
@@ -36,9 +29,7 @@ public:
return this->ConfigNames;
}
- std::string const& GetWorkingDirectory() const;
-
- std::string MaybeRelativeToWorkDir(std::string const& path) const;
+ virtual std::string const& GetWorkingDirectory() const;
std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
std::string const& config) override;
@@ -48,8 +39,6 @@ public:
cmGeneratorTarget const* gt = nullptr) override;
protected:
- WorkDir WorkingDirectory;
-
std::vector<std::string> ConfigNames;
friend class cmCommonTargetGenerator;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 64f0246e90..b02fa62487 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1586,6 +1586,8 @@ void cmLocalGenerator::GetTargetFlags(
this->AppendPositionIndependentLinkerFlags(extraLinkFlags, target, config,
linkLanguage);
this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage);
+ this->AppendDependencyInfoLinkerFlags(extraLinkFlags, target, config,
+ linkLanguage);
this->AppendModuleDefinitionFlag(extraLinkFlags, target, linkLineComputer,
config);
@@ -3202,6 +3204,42 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
}
}
+void cmLocalGenerator::AppendDependencyInfoLinkerFlags(
+ std::string& flags, cmGeneratorTarget* target, const std::string& config,
+ const std::string& linkLanguage)
+{
+ if (!this->GetGlobalGenerator()->SupportsLinkerDependencyFile() ||
+ !target->HasLinkDependencyFile(config)) {
+ return;
+ }
+
+ auto depFlag = *this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", linkLanguage, "_LINKER_DEPFILE_FLAGS"));
+ if (depFlag.empty()) {
+ return;
+ }
+
+ auto depFile = this->ConvertToOutputFormat(
+ this->MaybeRelativeToWorkDir(this->GetLinkDependencyFile(target, config)),
+ cmOutputConverter::SHELL);
+ std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
+ this->CreateRulePlaceholderExpander());
+ cmRulePlaceholderExpander::RuleVariables linkDepsVariables;
+ linkDepsVariables.DependencyFile = depFile.c_str();
+ rulePlaceholderExpander->ExpandRuleVariables(this, depFlag,
+ linkDepsVariables);
+ auto depFlags = cmExpandListWithBacktrace(depFlag);
+ target->ResolveLinkerWrapper(depFlags, linkLanguage);
+
+ this->AppendFlags(flags, depFlags);
+}
+
+std::string cmLocalGenerator::GetLinkDependencyFile(
+ cmGeneratorTarget* /*target*/, const std::string& /*config*/) const
+{
+ return "link.d";
+}
+
void cmLocalGenerator::AppendModuleDefinitionFlag(
std::string& flags, cmGeneratorTarget const* target,
cmLinkLineComputer* linkLineComputer, std::string const& config)
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index bda82bce00..3ad52c4256 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -89,7 +89,7 @@ class cmLocalGenerator : public cmOutputConverter
{
public:
cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
- virtual ~cmLocalGenerator();
+ ~cmLocalGenerator() override;
/**
* Generate the makefile for this directory.
@@ -183,6 +183,12 @@ public:
cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
+ void AppendDependencyInfoLinkerFlags(std::string& flags,
+ cmGeneratorTarget* target,
+ const std::string& config,
+ const std::string& lang);
+ virtual std::string GetLinkDependencyFile(cmGeneratorTarget* target,
+ const std::string& config) const;
void AppendModuleDefinitionFlag(std::string& flags,
cmGeneratorTarget const* target,
cmLinkLineComputer* linkLineComputer,
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index a047233a57..82d5a607b9 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -41,7 +41,7 @@
cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
cmMakefile* mf)
- : cmLocalCommonGenerator(gg, mf, WorkDir::TopBin)
+ : cmLocalCommonGenerator(gg, mf)
{
}
@@ -188,6 +188,26 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
return static_cast<cmGlobalNinjaGenerator*>(this->GetGlobalGenerator());
}
+std::string const& cmLocalNinjaGenerator::GetWorkingDirectory() const
+{
+ return this->GetState()->GetBinaryDirectory();
+}
+
+std::string cmLocalNinjaGenerator::MaybeRelativeToWorkDir(
+ std::string const& path) const
+{
+ return this->GetGlobalNinjaGenerator()->NinjaOutputPath(
+ this->MaybeRelativeToTopBinDir(path));
+}
+
+std::string cmLocalNinjaGenerator::GetLinkDependencyFile(
+ cmGeneratorTarget* target, std::string const& config) const
+{
+ return cmStrCat(target->GetSupportDirectory(),
+ this->GetGlobalNinjaGenerator()->ConfigDirectory(config),
+ "/link.d");
+}
+
// Virtual protected methods.
std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 4d393d9c3a..0bc462b038 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -52,6 +52,10 @@ public:
const cmake* GetCMakeInstance() const;
cmake* GetCMakeInstance();
+ std::string const& GetWorkingDirectory() const override;
+
+ std::string MaybeRelativeToWorkDir(std::string const& path) const override;
+
/// @returns the relative path between the HomeOutputDirectory and this
/// local generators StartOutputDirectory.
std::string GetHomeRelativeOutputPath() const
@@ -90,6 +94,9 @@ public:
bool HasUniqueByproducts(std::vector<std::string> const& byproducts,
cmListFileBacktrace const& bt);
+ std::string GetLinkDependencyFile(cmGeneratorTarget* target,
+ std::string const& config) const override;
+
protected:
std::string ConvertToIncludeReference(
std::string const& path, cmOutputConverter::OutputFormat format) override;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index d8f532f790..9f3894adbd 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -111,7 +111,7 @@ private:
cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
cmGlobalGenerator* gg, cmMakefile* mf)
- : cmLocalCommonGenerator(gg, mf, WorkDir::CurBin)
+ : cmLocalCommonGenerator(gg, mf)
{
this->MakefileVariableSize = 0;
this->ColorMakefile = false;
@@ -239,6 +239,12 @@ void cmLocalUnixMakefileGenerator3::GetIndividualFileTargets(
}
}
+std::string cmLocalUnixMakefileGenerator3::GetLinkDependencyFile(
+ cmGeneratorTarget* target, std::string const& /*config*/) const
+{
+ return cmStrCat(target->GetSupportDirectory(), "/link.d");
+}
+
void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
{
// generate the includes
@@ -2008,6 +2014,18 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
<< this->MaybeRelativeToTopBinDir(src) << "\"\n";
}
}
+ } else if (compilerLang.first == "LINK"_s) {
+ auto depFormat = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", target->GetLinkerLanguage(this->GetConfigName()),
+ "_LINKER_DEPFILE_FORMAT"));
+ for (auto const& compilerPair : compilerPairs) {
+ for (auto const& src : compilerPair.second) {
+ cmakefileStream << R"( "" ")"
+ << this->MaybeRelativeToTopBinDir(compilerPair.first)
+ << "\" \"" << depFormat << "\" \""
+ << this->MaybeRelativeToTopBinDir(src) << "\"\n";
+ }
+ }
} else {
auto depFormat = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 78aa7f9c2f..7d5a9224b4 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -191,6 +191,9 @@ public:
// Eclipse generator.
void GetIndividualFileTargets(std::vector<std::string>& targets);
+ std::string GetLinkDependencyFile(cmGeneratorTarget* target,
+ std::string const& config) const override;
+
protected:
void WriteLocalMakefile();
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 3caabde0bc..be8318cd12 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -70,6 +70,8 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
this->WriteExecutableRule(true);
}
+ this->WriteTargetLinkDependRules();
+
// Write clean target
this->WriteTargetCleanRules();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 691edf4c21..0ebbe4d190 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -62,6 +62,9 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
// write in rules for object files and custom commands
this->WriteTargetBuildRules();
+ // Write in the rules for the link dependency file
+ this->WriteTargetLinkDependRules();
+
// write the link rules
// Write the rule for this target type.
switch (this->GeneratorTarget->GetType()) {
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index a0a7324070..97e3fad85f 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -150,6 +150,8 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
+ this->LocalGenerator->AppendDependencyInfoLinkerFlags(
+ flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
}
void cmMakefileTargetGenerator::CreateRuleFile()
@@ -414,8 +416,10 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
this->GlobalGenerator->SupportsCompilerDependencies() &&
(!this->Makefile->IsDefinitionSet(depsUseCompiler) ||
this->Makefile->IsOn(depsUseCompiler));
+ bool linkerGenerateDeps =
+ this->GeneratorTarget->HasLinkDependencyFile(this->GetConfigName());
- if (compilerGenerateDeps || ccGenerateDeps) {
+ if (compilerGenerateDeps || linkerGenerateDeps || ccGenerateDeps) {
std::string compilerDependFile =
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
*this->BuildFileStream << "# Include any dependencies generated by the "
@@ -1499,6 +1503,21 @@ bool cmMakefileTargetGenerator::WriteMakeRule(
return symbolic;
}
+void cmMakefileTargetGenerator::WriteTargetLinkDependRules()
+{
+ if (!this->GeneratorTarget->HasLinkDependencyFile(this->GetConfigName())) {
+ return;
+ }
+
+ auto depFile = this->LocalGenerator->GetLinkDependencyFile(
+ this->GeneratorTarget, this->GetConfigName());
+ this->CleanFiles.insert(depFile);
+ this->LocalGenerator->AddImplicitDepends(
+ this->GeneratorTarget, "LINK",
+ this->GeneratorTarget->GetFullPath(this->GetConfigName()), depFile,
+ cmDependencyScannerKind::Compiler);
+}
+
void cmMakefileTargetGenerator::WriteTargetDependRules()
{
// must write the targets depend info file
@@ -2052,8 +2071,14 @@ void cmMakefileTargetGenerator::AppendTargetDepends(
return;
}
- // Loop over all library dependencies.
const std::string& cfg = this->GetConfigName();
+
+ if (this->GeneratorTarget->HasLinkDependencyFile(cfg)) {
+ depends.push_back(
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts"));
+ }
+
+ // Loop over all library dependencies.
if (cmComputeLinkInformation* cli =
this->GeneratorTarget->GetLinkInformation(cfg)) {
cm::append(depends, cli->GetDepends());
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 98c3a0e8db..ef7a60fa62 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -77,6 +77,8 @@ protected:
// write the clean rules for this target
void WriteTargetCleanRules();
+ // write the linker depend rules for this target
+ void WriteTargetLinkDependRules();
// write the depend rules for this target
void WriteTargetDependRules();
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index ee4fa90043..9903d63614 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -417,6 +417,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
std::string cmakeVarLang =
cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
+ if (this->GeneratorTarget->HasLinkDependencyFile(config)) {
+ auto DepFileFormat = this->GetMakefile()->GetDefinition(
+ cmStrCat(cmakeVarLang, "_LINKER_DEPFILE_FORMAT"));
+ rule.DepType = DepFileFormat;
+ rule.DepFile = "$DEP_FILE";
+ }
+
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
cmValue flag = this->GetMakefile()->GetDefinition(cmakeLinkVar);
@@ -1134,6 +1141,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmNinjaBuild linkBuild(this->LanguageLinkerRule(config));
cmNinjaVars& vars = linkBuild.Variables;
+ if (this->GeneratorTarget->HasLinkDependencyFile(config)) {
+ vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->ConvertToNinjaPath(
+ this->GetLocalGenerator()->GetLinkDependencyFile(this->GeneratorTarget,
+ config)),
+ cmOutputConverter::SHELL);
+ }
+
// Compute the comment.
linkBuild.Comment =
cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal);
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 2717bdd1c2..625d89768c 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -16,6 +16,7 @@ class cmOutputConverter
{
public:
cmOutputConverter(cmStateSnapshot const& snapshot);
+ virtual ~cmOutputConverter() = default;
/**
* Convert the given remote path to a relative path with respect to
@@ -27,6 +28,15 @@ public:
std::string MaybeRelativeToTopBinDir(std::string const& path) const;
std::string MaybeRelativeToCurBinDir(std::string const& path) const;
+ /**
+ * The effective working directory can be different for each generator.
+ * By default, equivalent to the current binary directory.
+ */
+ virtual std::string MaybeRelativeToWorkDir(std::string const& path) const
+ {
+ return this->MaybeRelativeToCurBinDir(path);
+ }
+
std::string const& GetRelativePathTopSource() const;
std::string const& GetRelativePathTopBinary() const;
void SetRelativePathTop(std::string const& topSource,