|
|
@@ -19,6 +19,7 @@
|
|
|
|
|
|
#include "cmFileTime.h"
|
|
|
#include "cmGccDepfileReader.h"
|
|
|
+#include "cmGccDepfileReaderTypes.h"
|
|
|
#include "cmGlobalUnixMakefileGenerator3.h"
|
|
|
#include "cmLocalUnixMakefileGenerator3.h"
|
|
|
#include "cmStringAlgorithms.h"
|
|
|
@@ -86,7 +87,7 @@ bool cmDependsCompiler::CheckDependencies(
|
|
|
if (!forceReadDeps) {
|
|
|
depFileTime.Load(depFile);
|
|
|
}
|
|
|
- if (forceReadDeps || depFileTime.Newer(internalDepFileTime)) {
|
|
|
+ if (forceReadDeps || depFileTime.Compare(internalDepFileTime) >= 0) {
|
|
|
status = false;
|
|
|
if (this->Verbose) {
|
|
|
cmSystemTools::Stdout(cmStrCat("Dependencies file \"", depFile,
|
|
|
@@ -95,59 +96,92 @@ bool cmDependsCompiler::CheckDependencies(
|
|
|
}
|
|
|
|
|
|
std::vector<std::string> depends;
|
|
|
- if (format == "msvc"_s) {
|
|
|
- cmsys::ifstream fin(depFile.c_str());
|
|
|
- if (!fin) {
|
|
|
- continue;
|
|
|
+ if (format == "custom"_s) {
|
|
|
+ std::string prefix;
|
|
|
+ if (this->LocalGenerator->GetCurrentBinaryDirectory() !=
|
|
|
+ this->LocalGenerator->GetBinaryDirectory()) {
|
|
|
+ prefix =
|
|
|
+ cmStrCat(this->LocalGenerator->MaybeConvertToRelativePath(
|
|
|
+ this->LocalGenerator->GetBinaryDirectory(),
|
|
|
+ this->LocalGenerator->GetCurrentBinaryDirectory()),
|
|
|
+ '/');
|
|
|
}
|
|
|
|
|
|
- std::string line;
|
|
|
- if (!isValidPath) {
|
|
|
- // insert source as first dependency
|
|
|
- depends.push_back(source);
|
|
|
- }
|
|
|
- while (cmSystemTools::GetLineFromStream(fin, line)) {
|
|
|
- depends.emplace_back(std::move(line));
|
|
|
- }
|
|
|
- } else {
|
|
|
- auto deps = cmReadGccDepfile(depFile.c_str());
|
|
|
+ auto deps = cmReadGccDepfile(depFile.c_str(), prefix);
|
|
|
if (!deps) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- // dependencies generated by the compiler contains only one target
|
|
|
- depends = std::move(deps->front().paths);
|
|
|
- if (depends.empty()) {
|
|
|
- // unexpectedly empty, ignore it and continue
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // depending of the effective format of the dependencies file generated
|
|
|
- // by the compiler, the target can be wrongly identified as a
|
|
|
- // dependency so remove it from the list
|
|
|
- if (depends.front() == target) {
|
|
|
- depends.erase(depends.begin());
|
|
|
+ for (auto& entry : *deps) {
|
|
|
+ depends = std::move(entry.paths);
|
|
|
+ if (isValidPath) {
|
|
|
+ cm::erase_if(depends, isValidPath);
|
|
|
+ }
|
|
|
+ // copy depends for each target, except first one, which can be
|
|
|
+ // moved
|
|
|
+ for (auto index = entry.rules.size() - 1; index > 0; --index) {
|
|
|
+ dependencies[entry.rules[index]] = depends;
|
|
|
+ }
|
|
|
+ dependencies[entry.rules.front()] = std::move(depends);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ if (format == "msvc"_s) {
|
|
|
+ cmsys::ifstream fin(depFile.c_str());
|
|
|
+ if (!fin) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- // ensure source file is the first dependency
|
|
|
- if (depends.front() != source) {
|
|
|
- cm::erase(depends, source);
|
|
|
+ std::string line;
|
|
|
if (!isValidPath) {
|
|
|
- depends.insert(depends.begin(), source);
|
|
|
+ // insert source as first dependency
|
|
|
+ depends.push_back(source);
|
|
|
+ }
|
|
|
+ while (cmSystemTools::GetLineFromStream(fin, line)) {
|
|
|
+ depends.emplace_back(std::move(line));
|
|
|
+ }
|
|
|
+ } else if (format == "gcc"_s) {
|
|
|
+ auto deps = cmReadGccDepfile(depFile.c_str());
|
|
|
+ if (!deps) {
|
|
|
+ continue;
|
|
|
}
|
|
|
- } else if (isValidPath) {
|
|
|
- // remove first dependency because it must not be filtered out
|
|
|
- depends.erase(depends.begin());
|
|
|
+
|
|
|
+ // dependencies generated by the compiler contains only one target
|
|
|
+ depends = std::move(deps->front().paths);
|
|
|
+ if (depends.empty()) {
|
|
|
+ // unexpectedly empty, ignore it and continue
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // depending of the effective format of the dependencies file
|
|
|
+ // generated by the compiler, the target can be wrongly identified
|
|
|
+ // as a dependency so remove it from the list
|
|
|
+ if (depends.front() == target) {
|
|
|
+ depends.erase(depends.begin());
|
|
|
+ }
|
|
|
+
|
|
|
+ // ensure source file is the first dependency
|
|
|
+ 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 {
|
|
|
+ // unknown format, ignore it
|
|
|
+ continue;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (isValidPath) {
|
|
|
- cm::erase_if(depends, isValidPath);
|
|
|
- // insert source as first dependency
|
|
|
- depends.insert(depends.begin(), source);
|
|
|
- }
|
|
|
+ if (isValidPath) {
|
|
|
+ cm::erase_if(depends, isValidPath);
|
|
|
+ // insert source as first dependency
|
|
|
+ depends.insert(depends.begin(), source);
|
|
|
+ }
|
|
|
|
|
|
- dependencies[target] = std::move(depends);
|
|
|
+ dependencies[target] = std::move(depends);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -168,6 +202,8 @@ void cmDependsCompiler::WriteDependencies(
|
|
|
|
|
|
// external dependencies file
|
|
|
for (auto& node : makeDependencies) {
|
|
|
+ auto target = LocalGenerator->ConvertToMakefilePath(
|
|
|
+ this->LocalGenerator->MaybeConvertToRelativePath(binDir, node.first));
|
|
|
auto& deps = node.second;
|
|
|
std::transform(
|
|
|
deps.cbegin(), deps.cend(), deps.begin(),
|
|
|
@@ -176,13 +212,16 @@ void cmDependsCompiler::WriteDependencies(
|
|
|
this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep));
|
|
|
});
|
|
|
|
|
|
- makeDepends << this->LocalGenerator->ConvertToMakefilePath(node.first)
|
|
|
- << ": " << deps.front();
|
|
|
- // first dependency is the source, remove it because should not be declared
|
|
|
- // as phony target
|
|
|
- deps.erase(deps.begin());
|
|
|
+ bool first_dep = true;
|
|
|
+ makeDepends << target << ": ";
|
|
|
for (const auto& dep : deps) {
|
|
|
- makeDepends << ' ' << lineContinue << " " << dep;
|
|
|
+ if (first_dep) {
|
|
|
+ first_dep = false;
|
|
|
+ makeDepends << dep;
|
|
|
+ } else {
|
|
|
+ makeDepends << ' ' << lineContinue << " " << dep;
|
|
|
+ }
|
|
|
+
|
|
|
phonyTargets.emplace(dep.data(), dep.length());
|
|
|
}
|
|
|
makeDepends << std::endl << std::endl;
|