diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2020-12-04 17:35:04 (GMT) |
---|---|---|
committer | Marc Chevrier <marc.chevrier@gmail.com> | 2020-12-23 14:47:46 (GMT) |
commit | cfd8a5ac1f443725342517ddbaee51692d8d0324 (patch) | |
tree | bf2224cb9c6b6ba1a7aed1eb2fbcaf31799cbc17 /Source/cmDependsCompiler.cxx | |
parent | a526f71266c2fed017c65a3d90b63286221476c0 (diff) | |
download | CMake-cfd8a5ac1f443725342517ddbaee51692d8d0324.zip CMake-cfd8a5ac1f443725342517ddbaee51692d8d0324.tar.gz CMake-cfd8a5ac1f443725342517ddbaee51692d8d0324.tar.bz2 |
Makefiles: Add support of DEPFILE for add_custom_command
Issue: #20286
Fixes: #21415
Diffstat (limited to 'Source/cmDependsCompiler.cxx')
-rw-r--r-- | Source/cmDependsCompiler.cxx | 133 |
1 files changed, 86 insertions, 47 deletions
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx index f6e5af8..beb080f 100644 --- a/Source/cmDependsCompiler.cxx +++ b/Source/cmDependsCompiler.cxx @@ -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; |