mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 14:08:35 +08:00
cmDependsCompiler: rely now on cmGccDepfileReader for depfile parser
To avoid duplicate effort of depfile parsing and enhance robustness of parsing against mal-formed depfiles in preparation of DEPFILE option support of add_custom_command command for makefiles generators.
This commit is contained in:
@@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <cm/optional>
|
||||||
#include <cm/string_view>
|
#include <cm/string_view>
|
||||||
#include <cm/vector>
|
#include <cm/vector>
|
||||||
#include <cmext/string_view>
|
#include <cmext/string_view>
|
||||||
@@ -16,77 +18,12 @@
|
|||||||
#include "cmsys/FStream.hxx"
|
#include "cmsys/FStream.hxx"
|
||||||
|
|
||||||
#include "cmFileTime.h"
|
#include "cmFileTime.h"
|
||||||
|
#include "cmGccDepfileReader.h"
|
||||||
#include "cmGlobalUnixMakefileGenerator3.h"
|
#include "cmGlobalUnixMakefileGenerator3.h"
|
||||||
#include "cmLocalUnixMakefileGenerator3.h"
|
#include "cmLocalUnixMakefileGenerator3.h"
|
||||||
#include "cmStringAlgorithms.h"
|
#include "cmStringAlgorithms.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
|
|
||||||
namespace {
|
|
||||||
std::string& ReplaceAll(std::string& data, const std::string& toSearch,
|
|
||||||
const std::string& replaceStr)
|
|
||||||
{
|
|
||||||
// Get the first occurrence
|
|
||||||
auto pos = data.find(toSearch);
|
|
||||||
// Repeat until the end is reached
|
|
||||||
while (pos != std::string::npos) {
|
|
||||||
// Replace this occurrence of Sub String
|
|
||||||
data.replace(pos, toSearch.size(), replaceStr);
|
|
||||||
// Get the next occurrence from the current position
|
|
||||||
pos = data.find(toSearch, pos + replaceStr.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string& NormalizePath(std::string& item)
|
|
||||||
{
|
|
||||||
ReplaceAll(item, "$$", "$");
|
|
||||||
ReplaceAll(item, "\\ ", " ");
|
|
||||||
ReplaceAll(item, "\\#", "#");
|
|
||||||
ReplaceAll(item, "\\", "/");
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ParseLine(const std::string& line, std::vector<std::string>& depends)
|
|
||||||
{
|
|
||||||
auto start = line.find_first_not_of(' ');
|
|
||||||
if (start == std::string::npos || line[start] == '#') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto index = start;
|
|
||||||
while ((index = line.find(' ', index)) != std::string::npos) {
|
|
||||||
if (line[index - 1] == '\\') {
|
|
||||||
index += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto item = line.substr(start, index - start);
|
|
||||||
if (item.back() != ':') {
|
|
||||||
// check that ':' is not present after some spaces
|
|
||||||
auto index2 = line.find_first_not_of(' ', index + 1);
|
|
||||||
if (index2 == std::string::npos || line[index2] != ':') {
|
|
||||||
// this is a dependency, add it
|
|
||||||
depends.emplace_back(std::move(NormalizePath(item)));
|
|
||||||
} else {
|
|
||||||
index = index2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
start = line.find_first_not_of(' ', index + 1);
|
|
||||||
index = start;
|
|
||||||
}
|
|
||||||
if (start != std::string::npos) {
|
|
||||||
auto item = line.substr(start);
|
|
||||||
if (line.back() != ':') {
|
|
||||||
// this is a dependency, add it
|
|
||||||
depends.emplace_back(std::move(NormalizePath(item)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cmDependsCompiler::CheckDependencies(
|
bool cmDependsCompiler::CheckDependencies(
|
||||||
const std::string& internalDepFile, const std::vector<std::string>& depFiles,
|
const std::string& internalDepFile, const std::vector<std::string>& depFiles,
|
||||||
cmDepends::DependencyMap& dependencies,
|
cmDepends::DependencyMap& dependencies,
|
||||||
@@ -156,14 +93,15 @@ bool cmDependsCompiler::CheckDependencies(
|
|||||||
"\" is newer than depends file \"",
|
"\" is newer than depends file \"",
|
||||||
internalDepFile, "\".\n"));
|
internalDepFile, "\".\n"));
|
||||||
}
|
}
|
||||||
cmsys::ifstream fin(depFile.c_str());
|
|
||||||
if (!fin) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> depends;
|
std::vector<std::string> depends;
|
||||||
std::string line;
|
|
||||||
if (format == "msvc"_s) {
|
if (format == "msvc"_s) {
|
||||||
|
cmsys::ifstream fin(depFile.c_str());
|
||||||
|
if (!fin) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
if (!isValidPath) {
|
if (!isValidPath) {
|
||||||
// insert source as first dependency
|
// insert source as first dependency
|
||||||
depends.push_back(source);
|
depends.push_back(source);
|
||||||
@@ -172,16 +110,13 @@ bool cmDependsCompiler::CheckDependencies(
|
|||||||
depends.emplace_back(std::move(line));
|
depends.emplace_back(std::move(line));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (cmSystemTools::GetLineFromStream(fin, line)) {
|
auto deps = cmReadGccDepfile(depFile.c_str());
|
||||||
if (line.empty()) {
|
if (!deps) {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (line.back() == '\\') {
|
|
||||||
line.pop_back();
|
|
||||||
}
|
|
||||||
ParseLine(line, depends);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dependencies generated by the compiler contains only one target
|
||||||
|
depends = std::move(deps->front().paths);
|
||||||
if (depends.empty()) {
|
if (depends.empty()) {
|
||||||
// unexpectedly empty, ignore it and continue
|
// unexpectedly empty, ignore it and continue
|
||||||
continue;
|
continue;
|
||||||
|
Reference in New Issue
Block a user