diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index 8608756627d..3e8e2ac3bca 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -925,6 +925,12 @@ bool FilePath::isChildOf(const QDir &dir) const 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 bool FilePath::endsWith(const QString &s) const { diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index 2026ad1068a..4d1243cfdf7 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -97,6 +97,7 @@ public: bool isChildOf(const FilePath &s) const; bool isChildOf(const QDir &dir) const; + bool startsWith(const QString &s) const; bool endsWith(const QString &s) const; bool isLocal() const; diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index 53d8a126be6..81316f033bf 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -271,13 +271,15 @@ static QStringList splitFragments(const QStringList &fragments) } RawProjectParts generateRawProjectParts(const PreprocessedData &input, - const FilePath &sourceDirectory) + const FilePath &sourceDirectory, + const FilePath &buildDirectory) { RawProjectParts rpps; int counter = 0; for (const TargetDetails &t : input.targetDetails) { QDir sourceDir(sourceDirectory.toString()); + QDir buildDir(buildDirectory.toString()); bool needPostfix = t.compileGroups.size() > 1; int count = 1; @@ -321,16 +323,25 @@ RawProjectParts generateRawProjectParts(const PreprocessedData &input, cxxProjectFlags.commandLineFlags = cProjectFlags.commandLineFlags; rpp.setFlagsForCxx(cxxProjectFlags); - const QString precompiled_header - = findOrDefault(t.sources, [&ending](const SourceInfo &si) { - return si.path.endsWith(ending); - }).path; + FilePath precompiled_header + = FilePath::fromString(findOrDefault(t.sources, [&ending](const SourceInfo &si) { + return si.path.endsWith(ending); + }).path); rpp.setFiles(transform(ci.sources, [&t, &sourceDir](const int si) { return sourceDir.absoluteFilePath(t.sources[static_cast(si)].path); })); - if (!precompiled_header.isEmpty()) - rpp.setPreCompiledHeaders({precompiled_header}); + if (!precompiled_header.isEmpty()) { + 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"; rpp.setBuildTargetType(isExecutable ? ProjectExplorer::BuildTargetType::Executable @@ -602,7 +613,7 @@ FileApiQtcData extractData(FileApiData &input, result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory); result.cmakeFiles = std::move(data.cmakeFiles); - result.projectParts = generateRawProjectParts(data, sourceDirectory); + result.projectParts = generateRawProjectParts(data, sourceDirectory, buildDirectory); auto pair = generateRootProjectNode(data, sourceDirectory, buildDirectory); result.rootProjectNode = std::move(pair.first);