CppEditor: Try to find clangd include path more generically

Linux distributions can get creative with the location of the clang
headers. So if we find a clang executable alongside clangd, ask it for
the base directory and try the hardcoded paths only as a fallback.

Fixes: QTCREATORBUG-27760
Change-Id: I9480b170df05598255c01be44be4b0312d0929f8
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2022-06-30 11:42:30 +02:00
parent e661135d13
commit 88956d1e9b

View File

@@ -314,16 +314,38 @@ QVersionNumber ClangdSettings::clangdVersion(const FilePath &clangdFilePath)
return it->second;
}
FilePath ClangdSettings::clangdIncludePath() const
static FilePath getClangHeadersPathFromClang(const FilePath &clangdFilePath)
{
QTC_ASSERT(useClangd(), return {});
FilePath clangdPath = clangdFilePath();
QTC_ASSERT(!clangdPath.isEmpty() && clangdPath.exists(), return {});
const QVersionNumber version = clangdVersion();
const FilePath clangFilePath = clangdFilePath.absolutePath().pathAppended("clang")
.withExecutableSuffix();
if (!clangFilePath.exists())
return {};
QtcProcess clang;
clang.setCommand({clangFilePath, {"-print-resource-dir"}});
clang.start();
if (!clang.waitForFinished())
return {};
const FilePath resourceDir = FilePath::fromUserInput(QString::fromLocal8Bit(
clang.readAllStandardOutput().trimmed()));
if (resourceDir.isEmpty() || !resourceDir.exists())
return {};
const FilePath includeDir = resourceDir.pathAppended("include");
if (!includeDir.exists())
return {};
return includeDir;
}
static FilePath getClangHeadersPath(const FilePath &clangdFilePath)
{
const FilePath headersPath = getClangHeadersPathFromClang(clangdFilePath);
if (!headersPath.isEmpty())
return headersPath;
const QVersionNumber version = ClangdSettings::clangdVersion(clangdFilePath);
QTC_ASSERT(!version.isNull(), return {});
static const QStringList libDirs{"lib", "lib64"};
for (const QString &libDir : libDirs) {
const FilePath includePath = clangdPath.absolutePath().parentDir().pathAppended(libDir)
const FilePath includePath = clangdFilePath.absolutePath().parentDir().pathAppended(libDir)
.pathAppended("clang").pathAppended(version.toString()).pathAppended("include");
if (includePath.exists())
return includePath;
@@ -332,6 +354,21 @@ FilePath ClangdSettings::clangdIncludePath() const
return {};
}
FilePath ClangdSettings::clangdIncludePath() const
{
QTC_ASSERT(useClangd(), return {});
FilePath clangdPath = clangdFilePath();
QTC_ASSERT(!clangdPath.isEmpty() && clangdPath.exists(), return {});
static QHash<FilePath, FilePath> headersPathCache;
const auto it = headersPathCache.constFind(clangdPath);
if (it != headersPathCache.constEnd())
return *it;
const FilePath headersPath = getClangHeadersPath(clangdPath);
if (!headersPath.isEmpty())
headersPathCache.insert(clangdPath, headersPath);
return headersPath;
}
FilePath ClangdSettings::clangdUserConfigFilePath()
{
return FilePath::fromString(