CMakeProjectManager: Fix clang code model when CMake PCHs are used

CMake gives the path to the cmake_pch.h[xx] file as relative path
to build directory. Making it absolute fixes the code model.

Fixes: QTCREATORBUG-22888
Change-Id: I2fdc080be779f22b737788be2074254290994aaa
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Cristian Adam
2019-10-21 15:06:28 +02:00
parent 78e5a8a80a
commit 8ee22dd597
3 changed files with 26 additions and 8 deletions

View File

@@ -925,6 +925,12 @@ bool FilePath::isChildOf(const QDir &dir) const
return isChildOf(FilePath::fromString(dir.absolutePath())); return isChildOf(FilePath::fromString(dir.absolutePath()));
} }
/// \returns whether FilePath startsWith \a s
bool FilePath::startsWith(const QString &s) const
{
return m_data.startsWith(s, HostOsInfo::fileNameCaseSensitivity());
}
/// \returns whether FilePath endsWith \a s /// \returns whether FilePath endsWith \a s
bool FilePath::endsWith(const QString &s) const bool FilePath::endsWith(const QString &s) const
{ {

View File

@@ -97,6 +97,7 @@ public:
bool isChildOf(const FilePath &s) const; bool isChildOf(const FilePath &s) const;
bool isChildOf(const QDir &dir) const; bool isChildOf(const QDir &dir) const;
bool startsWith(const QString &s) const;
bool endsWith(const QString &s) const; bool endsWith(const QString &s) const;
bool isLocal() const; bool isLocal() const;

View File

@@ -271,13 +271,15 @@ static QStringList splitFragments(const QStringList &fragments)
} }
RawProjectParts generateRawProjectParts(const PreprocessedData &input, RawProjectParts generateRawProjectParts(const PreprocessedData &input,
const FilePath &sourceDirectory) const FilePath &sourceDirectory,
const FilePath &buildDirectory)
{ {
RawProjectParts rpps; RawProjectParts rpps;
int counter = 0; int counter = 0;
for (const TargetDetails &t : input.targetDetails) { for (const TargetDetails &t : input.targetDetails) {
QDir sourceDir(sourceDirectory.toString()); QDir sourceDir(sourceDirectory.toString());
QDir buildDir(buildDirectory.toString());
bool needPostfix = t.compileGroups.size() > 1; bool needPostfix = t.compileGroups.size() > 1;
int count = 1; int count = 1;
@@ -321,16 +323,25 @@ RawProjectParts generateRawProjectParts(const PreprocessedData &input,
cxxProjectFlags.commandLineFlags = cProjectFlags.commandLineFlags; cxxProjectFlags.commandLineFlags = cProjectFlags.commandLineFlags;
rpp.setFlagsForCxx(cxxProjectFlags); rpp.setFlagsForCxx(cxxProjectFlags);
const QString precompiled_header FilePath precompiled_header
= findOrDefault(t.sources, [&ending](const SourceInfo &si) { = FilePath::fromString(findOrDefault(t.sources, [&ending](const SourceInfo &si) {
return si.path.endsWith(ending); return si.path.endsWith(ending);
}).path; }).path);
rpp.setFiles(transform<QList>(ci.sources, [&t, &sourceDir](const int si) { rpp.setFiles(transform<QList>(ci.sources, [&t, &sourceDir](const int si) {
return sourceDir.absoluteFilePath(t.sources[static_cast<size_t>(si)].path); return sourceDir.absoluteFilePath(t.sources[static_cast<size_t>(si)].path);
})); }));
if (!precompiled_header.isEmpty()) if (!precompiled_header.isEmpty()) {
rpp.setPreCompiledHeaders({precompiled_header}); if (precompiled_header.toFileInfo().isRelative()) {
const FilePath parentDir = FilePath::fromString(buildDir.absolutePath());
const QString dirName = buildDir.dirName();
if (precompiled_header.startsWith(dirName))
precompiled_header = FilePath::fromString(
precompiled_header.toString().mid(dirName.length() + 1));
precompiled_header = parentDir.pathAppended(precompiled_header.toString());
}
rpp.setPreCompiledHeaders({precompiled_header.toString()});
}
const bool isExecutable = t.type == "EXECUTABLE"; const bool isExecutable = t.type == "EXECUTABLE";
rpp.setBuildTargetType(isExecutable ? ProjectExplorer::BuildTargetType::Executable rpp.setBuildTargetType(isExecutable ? ProjectExplorer::BuildTargetType::Executable
@@ -602,7 +613,7 @@ FileApiQtcData extractData(FileApiData &input,
result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory); result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory);
result.cmakeFiles = std::move(data.cmakeFiles); result.cmakeFiles = std::move(data.cmakeFiles);
result.projectParts = generateRawProjectParts(data, sourceDirectory); result.projectParts = generateRawProjectParts(data, sourceDirectory, buildDirectory);
auto pair = generateRootProjectNode(data, sourceDirectory, buildDirectory); auto pair = generateRootProjectNode(data, sourceDirectory, buildDirectory);
result.rootProjectNode = std::move(pair.first); result.rootProjectNode = std::move(pair.first);