From f71b3652f40eb046957c7aff2f47e153d1f4a7d5 Mon Sep 17 00:00:00 2001 From: Tobias Hunger <tobias.hunger@theqtcompany.com> Date: Tue, 26 Jan 2016 17:26:46 +0100 Subject: [PATCH] CMake: Read CMakeCache.txt Read the configuration from CMakeCache.txt files. Change-Id: I7ddf9c9727420634086c973d0134059aac37ace0 Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com> --- .../cmakeprojectmanager/builddirmanager.cpp | 92 +++++++++++++++++++ .../cmakeprojectmanager/builddirmanager.h | 3 + 2 files changed, 95 insertions(+) diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index fac3b491291..3a753fe9630 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -42,6 +42,7 @@ #include <utils/synchronousprocess.h> #include <QDateTime> +#include <QFile> #include <QFileInfo> #include <QFileSystemWatcher> #include <QRegularExpression> @@ -187,6 +188,11 @@ QList<ProjectExplorer::FileNode *> BuildDirManager::files() const return m_files; } +CMakeConfig BuildDirManager::configuration() const +{ + return parseConfiguration(); +} + void BuildDirManager::extractData() { const Utils::FileName topCMake @@ -367,5 +373,91 @@ void BuildDirManager::processCMakeError() }); } +static QByteArray trimCMakeCacheLine(const QByteArray &in) { + int start = 0; + while (start < in.count() && (in.at(start) == ' ' || in.at(start) == '\t')) + ++start; + + return in.mid(start, in.count() - start - 1); +} + +static QByteArrayList splitCMakeCacheLine(const QByteArray &line) { + const int colonPos = line.indexOf(':'); + if (colonPos < 0) + return QByteArrayList(); + + const int equalPos = line.indexOf('=', colonPos + 1); + if (equalPos < colonPos) + return QByteArrayList(); + + return QByteArrayList() << line.mid(0, colonPos) + << line.mid(colonPos + 1, equalPos - colonPos - 1) + << line.mid(equalPos + 1); +} + +static CMakeConfigItem::Type fromByteArray(const QByteArray &type) { + if (type == "BOOL") + return CMakeConfigItem::BOOL; + if (type == "STRING") + return CMakeConfigItem::STRING; + if (type == "FILEPATH") + return CMakeConfigItem::FILEPATH; + if (type == "PATH") + return CMakeConfigItem::PATH; + QTC_CHECK(type == "INTERNAL" || type == "STATIC"); + + return CMakeConfigItem::INTERNAL; +} + +CMakeConfig BuildDirManager::parseConfiguration() const +{ + CMakeConfig result; + const QString cacheFile = QDir(m_buildDir.toString()).absoluteFilePath(QLatin1String("CMakeCache.txt")); + QFile cache(cacheFile); + if (!cache.open(QIODevice::ReadOnly | QIODevice::Text)) + return CMakeConfig(); + + QSet<QByteArray> advancedSet; + QByteArray documentation; + while (!cache.atEnd()) { + const QByteArray line = trimCMakeCacheLine(cache.readLine()); + + if (line.isEmpty() || line.startsWith('#')) + continue; + + if (line.startsWith("//")) { + documentation = line.mid(2); + continue; + } + + const QByteArrayList pieces = splitCMakeCacheLine(line); + if (pieces.isEmpty()) + continue; + + QTC_ASSERT(pieces.count() == 3, continue); + const QByteArray key = pieces.at(0); + const QByteArray type = pieces.at(1); + const QByteArray value = pieces.at(2); + + if (key.endsWith("-ADVANCED") && value == "1") { + advancedSet.insert(key.left(key.count() - 9 /* "-ADVANCED" */)); + } else { + CMakeConfigItem::Type t = fromByteArray(type); + if (t != CMakeConfigItem::INTERNAL) + result << CMakeConfigItem(key, t, documentation, value); + } + } + + // Set advanced flags: + for (int i = 0; i < result.count(); ++i) { + CMakeConfigItem &item = result[i]; + item.isAdvanced = advancedSet.contains(item.key); + } + + Utils::sort(result, CMakeConfigItem::sortOperator()); + + return result; +} + } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h index 6b903910e3a..7d234b5bbbd 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.h +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -78,6 +78,7 @@ public: QString projectName() const; QList<CMakeBuildTarget> buildTargets() const; QList<ProjectExplorer::FileNode *> files() const; + CMakeConfig configuration() const; signals: void parsingStarted() const; @@ -93,6 +94,8 @@ private: void processCMakeOutput(); void processCMakeError(); + CMakeConfig parseConfiguration() const; + const Utils::FileName m_sourceDir; Utils::FileName m_buildDir; const ProjectExplorer::Kit *const m_kit; -- GitLab