Commit 591d693d authored by Tobias Hunger's avatar Tobias Hunger

CMake: Move code to read CMakeCache.txt into CMakeItem class

Change-Id: Ie5d76a2b50007c80d68b2e97d3339a582afce469
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent 3422e5cd
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <projectexplorer/kit.h> #include <projectexplorer/kit.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/macroexpander.h> #include <utils/macroexpander.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
...@@ -219,6 +221,91 @@ CMakeConfigItem CMakeConfigItem::fromString(const QString &s) ...@@ -219,6 +221,91 @@ CMakeConfigItem CMakeConfigItem::fromString(const QString &s)
return item; return item;
} }
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);
}
QList<CMakeConfigItem> CMakeConfigItem::itemsFromFile(const Utils::FileName &cacheFile, QString *errorMessage)
{
CMakeConfig result;
QFile cache(cacheFile.toString());
if (!cache.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (errorMessage)
*errorMessage = QCoreApplication::translate("CMakeProjectManager::CMakeConfigItem", "Failed to open %1 for reading.")
.arg(cacheFile.toUserOutput());
return CMakeConfig();
}
QSet<QByteArray> advancedSet;
QMap<QByteArray, QByteArray> valuesMap;
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 if (key.endsWith("-STRINGS") && CMakeConfigItem::typeStringToType(type) == CMakeConfigItem::INTERNAL) {
valuesMap[key.left(key.count() - 8) /* "-STRINGS" */] = value;
} else {
CMakeConfigItem::Type t = CMakeConfigItem::typeStringToType(type);
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);
if (valuesMap.contains(item.key)) {
item.values = CMakeConfigItem::cmakeSplitValue(QString::fromUtf8(valuesMap[item.key]));
} else if (item.key == "CMAKE_BUILD_TYPE") {
// WA for known options
item.values << "" << "Debug" << "Release" << "MinSizeRel" << "RelWithDebInfo";
}
}
Utils::sort(result, CMakeConfigItem::sortOperator());
return result;
}
QString CMakeConfigItem::toString(const Utils::MacroExpander *expander) const QString CMakeConfigItem::toString(const Utils::MacroExpander *expander) const
{ {
if (key.isEmpty() || type == CMakeProjectManager::CMakeConfigItem::STATIC) if (key.isEmpty() || type == CMakeProjectManager::CMakeConfigItem::STATIC)
......
...@@ -31,7 +31,10 @@ ...@@ -31,7 +31,10 @@
#include <functional> #include <functional>
namespace ProjectExplorer { class Kit; } namespace ProjectExplorer { class Kit; }
namespace Utils { class MacroExpander; } namespace Utils {
class FileName;
class MacroExpander;
} // namespace Utils
namespace CMakeProjectManager { namespace CMakeProjectManager {
...@@ -55,6 +58,7 @@ public: ...@@ -55,6 +58,7 @@ public:
static std::function<bool(const CMakeConfigItem &a, const CMakeConfigItem &b)> sortOperator(); static std::function<bool(const CMakeConfigItem &a, const CMakeConfigItem &b)> sortOperator();
static CMakeConfigItem fromString(const QString &s); static CMakeConfigItem fromString(const QString &s);
static QList<CMakeConfigItem> itemsFromFile(const Utils::FileName &input, QString *errorMessage);
QString toString(const Utils::MacroExpander *expander = nullptr) const; QString toString(const Utils::MacroExpander *expander = nullptr) const;
QString toArgument(const Utils::MacroExpander *expander = nullptr) const; QString toArgument(const Utils::MacroExpander *expander = nullptr) const;
......
...@@ -123,28 +123,6 @@ static QStringList toArguments(const CMakeConfig &config, const MacroExpander *e ...@@ -123,28 +123,6 @@ static QStringList toArguments(const CMakeConfig &config, const MacroExpander *e
}); });
} }
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);
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// TeaLeafReader: // TeaLeafReader:
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -242,7 +220,7 @@ CMakeConfig TeaLeafReader::parsedConfiguration() const ...@@ -242,7 +220,7 @@ CMakeConfig TeaLeafReader::parsedConfiguration() const
if (!cacheFile.exists()) if (!cacheFile.exists())
return result; return result;
QString errorMessage; QString errorMessage;
m_cmakeCache = parseConfiguration(cacheFile, &errorMessage); m_cmakeCache = CMakeConfigItem::itemsFromFile(cacheFile, &errorMessage);
if (!errorMessage.isEmpty()) if (!errorMessage.isEmpty())
emit errorOccured(errorMessage); emit errorOccured(errorMessage);
const FileName sourceOfBuildDir const FileName sourceOfBuildDir
...@@ -257,67 +235,6 @@ CMakeConfig TeaLeafReader::parsedConfiguration() const ...@@ -257,67 +235,6 @@ CMakeConfig TeaLeafReader::parsedConfiguration() const
return result; return result;
} }
CMakeConfig TeaLeafReader::parseConfiguration(const FileName &cacheFile, QString *errorMessage) const
{
CMakeConfig result;
QFile cache(cacheFile.toString());
if (!cache.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (errorMessage)
*errorMessage = tr("Failed to open %1 for reading.").arg(cacheFile.toUserOutput());
return CMakeConfig();
}
QSet<QByteArray> advancedSet;
QMap<QByteArray, QByteArray> valuesMap;
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 if (key.endsWith("-STRINGS") && CMakeConfigItem::typeStringToType(type) == CMakeConfigItem::INTERNAL) {
valuesMap[key.left(key.count() - 8) /* "-STRINGS" */] = value;
} else {
CMakeConfigItem::Type t = CMakeConfigItem::typeStringToType(type);
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);
if (valuesMap.contains(item.key)) {
item.values = CMakeConfigItem::cmakeSplitValue(QString::fromUtf8(valuesMap[item.key]));
} else if (item.key == "CMAKE_BUILD_TYPE") {
// WA for known options
item.values << "" << "Debug" << "Release" << "MinSizeRel" << "RelWithDebInfo";
}
}
sort(result, CMakeConfigItem::sortOperator());
return result;
}
void TeaLeafReader::generateProjectTree(CMakeListsNode *root, const QList<FileNode *> &allFiles) void TeaLeafReader::generateProjectTree(CMakeListsNode *root, const QList<FileNode *> &allFiles)
{ {
root->setDisplayName(m_projectName); root->setDisplayName(m_projectName);
......
...@@ -70,8 +70,6 @@ private: ...@@ -70,8 +70,6 @@ private:
bool extractCXXFlagsFromMake(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache); bool extractCXXFlagsFromMake(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
bool extractCXXFlagsFromNinja(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache); bool extractCXXFlagsFromNinja(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
CMakeConfig parseConfiguration(const Utils::FileName &cacheFile, QString *errorMessage) const;
Utils::QtcProcess *m_cmakeProcess = nullptr; Utils::QtcProcess *m_cmakeProcess = nullptr;
// For error reporting: // For error reporting:
......
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