Members of the KDE Community are recommended to subscribe to the kde-community mailing list at to allow them to participate in important discussions and receive other important announcements

Commit 41a0f0ce authored by René J.V. Bertin's avatar René J.V. Bertin

clang: detect Clang builtin dirs at runtime on Unix

ec5477f3 introduced runtime detection
of the clang builtin header directory on MS Windows. This commit
implements the same behaviour on Unix. Some refactoring and code
cleanup too.

Differential Revision:
parent 48e5892f
......@@ -181,11 +181,10 @@ ClangSupport::ClangSupport(QObject* parent, const QVariantList& )
const auto builtinDir = ClangHelpers::clangBuiltinIncludePath();
const auto headerToCheck = QLatin1String("cpuid.h");
if (!QFile::exists(builtinDir + QLatin1Char('/') + headerToCheck)) {
setErrorDescription(i18n("The clang builtin include path \"%1\" is invalid (missing %2 header).\n"
if (!ClangHelpers::isValidClangBuiltingIncludePath(builtinDir)) {
setErrorDescription(i18n("The clang builtin include path \"%1\" is invalid (missing cpuid.h header).\n"
"Try setting the KDEV_CLANG_BUILTIN_DIR environment variable manually to fix this.\n"
"See also:", builtinDir, headerToCheck));
"See also:", builtinDir));
......@@ -369,11 +369,18 @@ QString ClangHelpers::clangVersion()
return clangVersion;
bool ClangHelpers::isValidClangBuiltingIncludePath(const QString& path)
return QFile::exists(path + QLatin1String("/cpuid.h"));
QString ClangHelpers::clangBuiltinIncludePath()
// use a lambda to store the result in a static variable which can be
// returned without recomputing the string on subsequent calls.
static const auto dir = []() -> QString {
auto dir = QString::fromUtf8(qgetenv("KDEV_CLANG_BUILTIN_DIR"));
if (!dir.isEmpty()) {
if (!dir.isEmpty() && isValidClangBuiltingIncludePath(dir)) {
clangDebug() << "Using dir from $KDEV_CLANG_BUILTIN_DIR:" << dir;
return dir;
......@@ -382,8 +389,19 @@ QString ClangHelpers::clangBuiltinIncludePath()
// attempt to use the bundled copy on Windows
dir = QDir::cleanPath(QStringLiteral("%1/../lib/clang/%2/include")
.arg(QCoreApplication::applicationDirPath(), clangVersion()));
clangDebug() << "Trying" << dir;
if (QFileInfo(dir).isDir()) {
if (isValidClangBuiltingIncludePath(dir)) {
clangDebug() << "Using builtin dir:" << dir;
return dir;
#elif defined(Q_OS_UNIX)
// a clang version upgrade since we were last built can
// cause problems if the "clang/$fullversion/include" path component
// changed. Try to generate the correct builtin_dir for the current
// major.minor.patchlevel version: pop the last 2 components then
// chdir through with the updated version directory.
dir = QDir::cleanPath(QStringLiteral(KDEV_CLANG_BUILTIN_DIR "/../../%1/include").arg(clangVersion()));
if (isValidClangBuiltingIncludePath(dir)) {
clangDebug() << "Using builtin dir:" << dir;
return dir;
......@@ -104,11 +104,20 @@ KDEVCLANGPRIVATE_EXPORT QString clangVersion();
* @return The path containing Clang built includes (e.g. stddef.h, stdarg.h, cpuid.h)
* The returned path is the env. var KDEV_CLANG_BUILTIN_DIR when set otherwise the path
* to the headers used when kdev-clang was built, possibly updated for upgrades to
* the library (e.g. 7.0.0 -> 7.0.1).
* Returns an empty string if none of the checked locations contain the file cpuid.h .
* Also see:
KDEVCLANGPRIVATE_EXPORT QString clangBuiltinIncludePath();
* @return True if the given @a path is a valid clang builtin directory.
KDEVCLANGPRIVATE_EXPORT bool isValidClangBuiltingIncludePath(const QString& path);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment