aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/corelib/tools')
-rw-r--r--src/lib/corelib/tools/buildoptions.cpp41
-rw-r--r--src/lib/corelib/tools/buildoptions.h10
-rw-r--r--src/lib/corelib/tools/fileinfo.cpp11
-rw-r--r--src/lib/corelib/tools/filetime.cpp19
-rw-r--r--src/lib/corelib/tools/joblimits.cpp185
-rw-r--r--src/lib/corelib/tools/joblimits.h102
-rw-r--r--src/lib/corelib/tools/persistence.cpp75
-rw-r--r--src/lib/corelib/tools/persistence.h130
-rw-r--r--src/lib/corelib/tools/preferences.cpp26
-rw-r--r--src/lib/corelib/tools/preferences.h2
-rw-r--r--src/lib/corelib/tools/profile.h4
-rw-r--r--src/lib/corelib/tools/qbspluginmanager.cpp6
-rw-r--r--src/lib/corelib/tools/qttools.cpp9
-rw-r--r--src/lib/corelib/tools/qttools.h5
-rw-r--r--src/lib/corelib/tools/settingsmodel.h18
-rw-r--r--src/lib/corelib/tools/setupprojectparameters.h4
-rw-r--r--src/lib/corelib/tools/stringconstants.h2
-rw-r--r--src/lib/corelib/tools/tools.pri3
18 files changed, 550 insertions, 102 deletions
diff --git a/src/lib/corelib/tools/buildoptions.cpp b/src/lib/corelib/tools/buildoptions.cpp
index ac8e39867..5507e0842 100644
--- a/src/lib/corelib/tools/buildoptions.cpp
+++ b/src/lib/corelib/tools/buildoptions.cpp
@@ -58,6 +58,8 @@ public:
QStringList changedFiles;
QStringList filesToConsider;
QStringList activeFileTags;
+ JobLimits jobLimits;
+ QString settingsDir;
int maxJobCount;
bool dryRun;
bool keepGoing;
@@ -68,6 +70,7 @@ public:
bool install;
bool removeExistingInstallation;
bool onlyExecuteRules;
+ bool jobLimitsFromProjectTakePrecedence = false;
};
} // namespace Internal
@@ -189,6 +192,44 @@ void BuildOptions::setMaxJobCount(int jobCount)
}
/*!
+ * \brief The base directory for qbs settings.
+ * This value is used to locate profiles and preferences.
+ */
+QString BuildOptions::settingsDirectory() const
+{
+ return d->settingsDir;
+}
+
+/*!
+ * \brief Sets the base directory for qbs settings.
+ * \param settingsBaseDir Will be used to locate profiles and preferences.
+ */
+void BuildOptions::setSettingsDirectory(const QString &settingsBaseDir)
+{
+ d->settingsDir = settingsBaseDir;
+}
+
+JobLimits BuildOptions::jobLimits() const
+{
+ return d->jobLimits;
+}
+
+void BuildOptions::setJobLimits(const JobLimits &jobLimits)
+{
+ d->jobLimits = jobLimits;
+}
+
+bool BuildOptions::projectJobLimitsTakePrecedence() const
+{
+ return d->jobLimitsFromProjectTakePrecedence;
+}
+
+void BuildOptions::setProjectJobLimitsTakePrecedence(bool toggle)
+{
+ d->jobLimitsFromProjectTakePrecedence = toggle;
+}
+
+/*!
* \brief Returns true iff qbs will not actually execute any commands, but just show what
* would happen.
* The default is false.
diff --git a/src/lib/corelib/tools/buildoptions.h b/src/lib/corelib/tools/buildoptions.h
index 630a6aa22..cea89d0ea 100644
--- a/src/lib/corelib/tools/buildoptions.h
+++ b/src/lib/corelib/tools/buildoptions.h
@@ -42,6 +42,7 @@
#include "qbs_export.h"
#include "commandechomode.h"
+#include "joblimits.h"
#include <QtCore/qshareddata.h>
@@ -73,6 +74,15 @@ public:
int maxJobCount() const;
void setMaxJobCount(int jobCount);
+ QString settingsDirectory() const;
+ void setSettingsDirectory(const QString &settingsBaseDir);
+
+ JobLimits jobLimits() const;
+ void setJobLimits(const JobLimits &jobLimits);
+
+ bool projectJobLimitsTakePrecedence() const;
+ void setProjectJobLimitsTakePrecedence(bool toggle);
+
bool dryRun() const;
void setDryRun(bool dryRun);
diff --git a/src/lib/corelib/tools/fileinfo.cpp b/src/lib/corelib/tools/fileinfo.cpp
index 3adacc883..15a8e8783 100644
--- a/src/lib/corelib/tools/fileinfo.cpp
+++ b/src/lib/corelib/tools/fileinfo.cpp
@@ -295,15 +295,10 @@ bool FileInfo::fileExists(const QFileInfo &fi)
#define z(x) reinterpret_cast<WIN32_FILE_ATTRIBUTE_DATA*>(const_cast<FileInfo::InternalStatType*>(&x))
-template<bool> struct CompileTimeAssert;
-template<> struct CompileTimeAssert<true> {};
-
FileInfo::FileInfo(const QString &fileName)
{
- static CompileTimeAssert<
- sizeof(FileInfo::InternalStatType) == sizeof(WIN32_FILE_ATTRIBUTE_DATA)
- > internal_type_has_wrong_size;
- Q_UNUSED(internal_type_has_wrong_size);
+ static_assert(sizeof(FileInfo::InternalStatType) == sizeof(WIN32_FILE_ATTRIBUTE_DATA),
+ "FileInfo::InternalStatType has wrong size.");
QString filePath = fileName;
@@ -368,7 +363,7 @@ FileInfo::FileInfo(const QString &fileName)
bool FileInfo::exists() const
{
- return m_stat.st_mtime != 0;
+ return m_stat.st_mode != 0;
}
FileTime FileInfo::lastModified() const
diff --git a/src/lib/corelib/tools/filetime.cpp b/src/lib/corelib/tools/filetime.cpp
index 14680ef6e..263950d9c 100644
--- a/src/lib/corelib/tools/filetime.cpp
+++ b/src/lib/corelib/tools/filetime.cpp
@@ -50,11 +50,6 @@
namespace qbs {
namespace Internal {
-#ifdef Q_OS_WIN
-template<bool> struct CompileTimeAssert;
-template<> struct CompileTimeAssert<true> {};
-#endif
-
#ifdef APPLE_CUSTOM_CLOCK_GETTIME
#include <sys/time.h>
@@ -77,8 +72,8 @@ int clock_gettime(int /*clk_id*/, struct timespec *t)
FileTime::FileTime()
{
#ifdef Q_OS_WIN
- static CompileTimeAssert<sizeof(FileTime::InternalType) == sizeof(FILETIME)> internal_type_has_wrong_size;
- Q_UNUSED(internal_type_has_wrong_size);
+ static_assert(sizeof(FileTime::InternalType) == sizeof(FILETIME),
+ "FileTime::InternalType has wrong size.");
m_fileTime = 0;
#elif HAS_CLOCK_GETTIME
m_fileTime = {0, 0};
@@ -98,8 +93,8 @@ FileTime::FileTime(const FileTime::InternalType &ft) : m_fileTime(ft)
int FileTime::compare(const FileTime &other) const
{
#ifdef Q_OS_WIN
- const FILETIME *const t1 = reinterpret_cast<const FILETIME *>(&m_fileTime);
- const FILETIME *const t2 = reinterpret_cast<const FILETIME *>(&other.m_fileTime);
+ auto const t1 = reinterpret_cast<const FILETIME *>(&m_fileTime);
+ auto const t2 = reinterpret_cast<const FILETIME *>(&other.m_fileTime);
return CompareFileTime(t1, t2);
#elif HAS_CLOCK_GETTIME
if (m_fileTime.tv_sec < other.m_fileTime.tv_sec)
@@ -140,7 +135,7 @@ FileTime FileTime::currentTime()
FileTime result;
SYSTEMTIME st;
GetSystemTime(&st);
- FILETIME *const ft = reinterpret_cast<FILETIME *>(&result.m_fileTime);
+ auto const ft = reinterpret_cast<FILETIME *>(&result.m_fileTime);
SystemTimeToFileTime(&st, ft);
return result;
#elif defined APPLE_CUSTOM_CLOCK_GETTIME
@@ -173,7 +168,7 @@ FileTime FileTime::oldestTime()
0
};
FileTime result;
- FILETIME *const ft = reinterpret_cast<FILETIME *>(&result.m_fileTime);
+ auto const ft = reinterpret_cast<FILETIME *>(&result.m_fileTime);
SystemTimeToFileTime(&st, ft);
return result;
#elif HAS_CLOCK_GETTIME
@@ -195,7 +190,7 @@ double FileTime::asDouble() const
QString FileTime::toString() const
{
#ifdef Q_OS_WIN
- const FILETIME *const ft = reinterpret_cast<const FILETIME *>(&m_fileTime);
+ auto const ft = reinterpret_cast<const FILETIME *>(&m_fileTime);
SYSTEMTIME stUTC, stLocal;
FileTimeToSystemTime(ft, &stUTC);
SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
diff --git a/src/lib/corelib/tools/joblimits.cpp b/src/lib/corelib/tools/joblimits.cpp
new file mode 100644
index 000000000..3b1fde83d
--- /dev/null
+++ b/src/lib/corelib/tools/joblimits.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "joblimits.h"
+
+#include <tools/persistence.h>
+
+#include <utility>
+#include <vector>
+
+namespace qbs {
+namespace Internal {
+
+static int transformLimit(int limitFromUser)
+{
+ return limitFromUser == 0
+ ? std::numeric_limits<int>::max()
+ : limitFromUser < -1 ? -1
+ : limitFromUser;
+}
+
+class JobLimitPrivate : public QSharedData
+{
+public:
+ JobLimitPrivate(const QString &pool, int limit)
+ : jobLimit(std::make_pair(pool, transformLimit(limit)))
+ {
+ }
+ template<PersistentPool::OpType opType> void serializationOp(PersistentPool &pool)
+ {
+ pool.serializationOp<opType>(jobLimit);
+ }
+ std::pair<QString, int> jobLimit;
+};
+
+class JobLimitsPrivate : public QSharedData
+{
+public:
+ template<PersistentPool::OpType opType> void serializationOp(PersistentPool &pool)
+ {
+ pool.serializationOp<opType>(jobLimits);
+ }
+ std::vector<JobLimit> jobLimits;
+};
+
+} // namespace Internal
+
+JobLimit::JobLimit() : JobLimit(QString(), -1)
+{
+}
+JobLimit::JobLimit(const QString &pool, int limit) : d(new Internal::JobLimitPrivate(pool, limit))
+{
+}
+JobLimit::JobLimit(const JobLimit &other) : d(other.d) { }
+JobLimit &JobLimit::operator=(const JobLimit &other)
+{
+ d = other.d;
+ return *this;
+}
+JobLimit::~JobLimit() {}
+QString JobLimit::pool() const { return d->jobLimit.first; }
+int JobLimit::limit() const { return d->jobLimit.second; }
+
+void JobLimit::load(Internal::PersistentPool &pool)
+{
+ d->serializationOp<Internal::PersistentPool::Load>(pool);
+}
+
+void JobLimit::store(Internal::PersistentPool &pool)
+{
+ d->serializationOp<Internal::PersistentPool::Store>(pool);
+}
+
+JobLimits::JobLimits() : d(new Internal::JobLimitsPrivate) { }
+JobLimits::JobLimits(const JobLimits &other) : d(other.d) { }
+JobLimits &JobLimits::operator=(const JobLimits &other)
+{
+ d = other.d;
+ return *this;
+}
+JobLimits::~JobLimits() {}
+
+void JobLimits::setJobLimit(const JobLimit &limit)
+{
+ for (std::size_t i = 0; i < d->jobLimits.size(); ++i) {
+ JobLimit &currentLimit = d->jobLimits.at(i);
+ if (currentLimit.pool() == limit.pool()) {
+ if (currentLimit.limit() != limit.limit())
+ currentLimit = limit;
+ return;
+ }
+ }
+ d->jobLimits.push_back(limit);
+}
+
+void JobLimits::setJobLimit(const QString &pool, int limit)
+{
+ setJobLimit(JobLimit(pool, limit));
+}
+
+int JobLimits::getLimit(const QString &pool) const
+{
+ for (const JobLimit &l : d->jobLimits) {
+ if (l.pool() == pool)
+ return l.limit();
+ }
+ return -1;
+}
+
+bool JobLimits::isEmpty() const
+{
+ return d->jobLimits.empty();
+}
+
+int JobLimits::count() const
+{
+ return d->jobLimits.size();
+}
+
+JobLimit JobLimits::jobLimitAt(int i) const
+{
+ return d->jobLimits.at(i);
+}
+
+JobLimits &JobLimits::update(const JobLimits &other)
+{
+ if (isEmpty()) {
+ *this = other;
+ } else {
+ for (int i = 0; i < other.count(); ++i) {
+ const JobLimit &l = other.jobLimitAt(i);
+ if (l.limit() != -1)
+ setJobLimit(l);
+ }
+ }
+ return *this;
+}
+
+void JobLimits::load(Internal::PersistentPool &pool)
+{
+ d->serializationOp<Internal::PersistentPool::Load>(pool);
+}
+
+void JobLimits::store(Internal::PersistentPool &pool)
+{
+ d->serializationOp<Internal::PersistentPool::Store>(pool);
+}
+
+} // namespace qbs
diff --git a/src/lib/corelib/tools/joblimits.h b/src/lib/corelib/tools/joblimits.h
new file mode 100644
index 000000000..de95f5513
--- /dev/null
+++ b/src/lib/corelib/tools/joblimits.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QBS_JOB_LIMITS_H
+#define QBS_JOB_LIMITS_H
+
+#include "qbs_export.h"
+
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+class QString;
+QT_END_NAMESPACE
+
+namespace qbs {
+namespace Internal {
+class JobLimitPrivate;
+class JobLimitsPrivate;
+class PersistentPool;
+}
+
+class QBS_EXPORT JobLimit
+{
+public:
+ JobLimit();
+ JobLimit(const QString &pool, int limit);
+ JobLimit(const JobLimit &other);
+ JobLimit &operator=(const JobLimit &other);
+ ~JobLimit();
+
+ QString pool() const;
+ int limit() const;
+
+ void load(Internal::PersistentPool &pool);
+ void store(Internal::PersistentPool &pool);
+private:
+ QSharedDataPointer<Internal::JobLimitPrivate> d;
+};
+
+class QBS_EXPORT JobLimits
+{
+public:
+ JobLimits();
+ JobLimits(const JobLimits &other);
+ JobLimits &operator=(const JobLimits &other);
+ ~JobLimits();
+
+ void setJobLimit(const JobLimit &limit);
+ void setJobLimit(const QString &pool, int limit);
+ int getLimit(const QString &pool) const;
+ bool hasLimit(const QString &pool) const { return getLimit(pool) != -1; }
+ bool isEmpty() const;
+
+ int count() const;
+ JobLimit jobLimitAt(int i) const;
+
+ JobLimits &update(const JobLimits &other);
+
+ void load(Internal::PersistentPool &pool);
+ void store(Internal::PersistentPool &pool);
+private:
+ QSharedDataPointer<Internal::JobLimitsPrivate> d;
+};
+
+} // namespace qbs
+
+#endif // include guard
diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp
index 996c8415d..ec412cf3b 100644
--- a/src/lib/corelib/tools/persistence.cpp
+++ b/src/lib/corelib/tools/persistence.cpp
@@ -42,14 +42,13 @@
#include "fileinfo.h"
#include <logging/translator.h>
#include <tools/error.h>
-#include <tools/qbsassert.h>
#include <QtCore/qdir.h>
namespace qbs {
namespace Internal {
-static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-120";
+static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-124";
NoBuildGraphError::NoBuildGraphError(const QString &filePath)
: ErrorInfo(Tr::tr("Build graph not found for configuration '%1'. Expected location was '%2'.")
@@ -82,7 +81,7 @@ void PersistentPool::load(const QString &filePath)
QByteArray magic;
m_stream >> magic;
if (magic != QBS_PERSISTENCE_MAGIC) {
- m_stream.setDevice(0);
+ m_stream.setDevice(nullptr);
throw ErrorInfo(Tr::tr("Cannot use stored build graph at '%1': Incompatible file format. "
"Expected magic token '%2', got '%3'.")
.arg(filePath, QString::fromLatin1(QBS_PERSISTENCE_MAGIC),
@@ -121,6 +120,8 @@ void PersistentPool::setupWriteStream(const QString &filePath)
m_stream << QByteArray(qstrlen(QBS_PERSISTENCE_MAGIC), 0) << m_headData.projectConfig;
m_lastStoredObjectId = 0;
m_lastStoredStringId = 0;
+ m_lastStoredEnvId = 0;
+ m_lastStoredStringListId = 0;
}
void PersistentPool::finalizeWriteStream()
@@ -153,7 +154,7 @@ void PersistentPool::storeVariant(const QVariant &variant)
m_stream << type;
switch (type) {
case QMetaType::QString:
- storeString(variant.toString());
+ store(variant.toString());
break;
case QMetaType::QStringList:
store(variant.toStringList());
@@ -175,7 +176,7 @@ QVariant PersistentPool::loadVariant()
QVariant value;
switch (type) {
case QMetaType::QString:
- value = idLoadString();
+ value = load<QString>();
break;
case QMetaType::QStringList:
value = load<QStringList>();
@@ -200,50 +201,48 @@ void PersistentPool::clear()
m_inverseStringStorage.clear();
}
-const int StringNotFoundId = -1;
-const int NullStringId = -2;
-
-void PersistentPool::storeString(const QString &t)
+void PersistentPool::doLoadValue(QString &s)
{
- if (t.isNull()) {
- m_stream << NullStringId;
- return;
- }
-
- int id = m_inverseStringStorage.value(t, StringNotFoundId);
- if (id < 0) {
- id = m_lastStoredStringId++;
- m_inverseStringStorage.insert(t, id);
- m_stream << id << t;
- } else {
- m_stream << id;
- }
+ m_stream >> s;
}
-QString PersistentPool::loadString(int id)
+void PersistentPool::doLoadValue(QStringList &l)
{
- if (id == NullStringId)
- return QString();
+ int size;
+ m_stream >> size;
+ for (int i = 0; i < size; ++i)
+ l << load<QString>();
+}
- QBS_CHECK(id >= 0);
+void PersistentPool::doLoadValue(QProcessEnvironment &env)
+{
+ const QStringList keys = load<QStringList>();
+ for (const QString &key : keys)
+ env.insert(key, load<QString>());
+}
- if (id >= static_cast<int>(m_stringStorage.size())) {
- QString s;
- m_stream >> s;
- m_stringStorage.resize(id + 1);
- m_stringStorage[id] = s;
- return s;
- }
+void PersistentPool::doStoreValue(const QString &s)
+{
+ m_stream << s;
+}
- return m_stringStorage.at(id);
+void PersistentPool::doStoreValue(const QStringList &l)
+{
+ m_stream << l.size();
+ for (const QString &s : l)
+ store(s);
}
-QString PersistentPool::idLoadString()
+void PersistentPool::doStoreValue(const QProcessEnvironment &env)
{
- int id;
- m_stream >> id;
- return loadString(id);
+ const QStringList &keys = env.keys();
+ store(keys);
+ for (const QString &key : keys)
+ store(env.value(key));
}
+const PersistentPool::PersistentObjectId PersistentPool::ValueNotFoundId;
+const PersistentPool::PersistentObjectId PersistentPool::EmptyValueId;
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h
index 2687d6120..e8d938ad3 100644
--- a/src/lib/corelib/tools/persistence.h
+++ b/src/lib/corelib/tools/persistence.h
@@ -42,6 +42,8 @@
#include "error.h"
#include <logging/logger.h>
+#include <tools/qbsassert.h>
+#include <tools/qttools.h>
#include <QtCore/qdatastream.h>
#include <QtCore/qflags.h>
@@ -137,20 +139,34 @@ private:
template <typename T> T *idLoad();
template <class T> std::shared_ptr<T> idLoadS();
+ template <typename T> T idLoadValue();
+
+ void doLoadValue(QString &s);
+ void doLoadValue(QStringList &l);
+ void doLoadValue(QProcessEnvironment &env);
template<typename T> void storeSharedObject(const T *object);
void storeVariant(const QVariant &variant);
QVariant loadVariant();
- void storeString(const QString &t);
- QString loadString(int id);
- QString idLoadString();
+ template <typename T> void idStoreValue(const T &value);
+
+ void doStoreValue(const QString &s);
+ void doStoreValue(const QStringList &l);
+ void doStoreValue(const QProcessEnvironment &env);
+
+ template<typename T> std::vector<T> &idStorage();
+ template<typename T> QHash<T, PersistentObjectId> &idMap();
+ template<typename T> PersistentObjectId &lastStoredId();
// Recursion termination
void store() {}
void load() {}
+ static const PersistentObjectId ValueNotFoundId = -1;
+ static const PersistentObjectId EmptyValueId = -2;
+
QDataStream m_stream;
HeadData m_headData;
std::vector<void *> m_loadedRaw;
@@ -161,6 +177,12 @@ private:
std::vector<QString> m_stringStorage;
QHash<QString, int> m_inverseStringStorage;
PersistentObjectId m_lastStoredStringId;
+ std::vector<QProcessEnvironment> m_envStorage;
+ QHash<QProcessEnvironment, int> m_inverseEnvStorage;
+ PersistentObjectId m_lastStoredEnvId;
+ std::vector<QStringList> m_stringListStorage;
+ QHash<QStringList, int> m_inverseStringListStorage;
+ PersistentObjectId m_lastStoredStringListId;
Logger &m_logger;
template<typename T, typename Enable>
@@ -209,6 +231,42 @@ template <typename T> inline T *PersistentPool::idLoad()
return t;
}
+template<> inline std::vector<QString> &PersistentPool::idStorage() { return m_stringStorage; }
+template<> inline QHash<QString, PersistentPool::PersistentObjectId> &PersistentPool::idMap()
+{
+ return m_inverseStringStorage;
+}
+template<> inline PersistentPool::PersistentObjectId &PersistentPool::lastStoredId<QString>()
+{
+ return m_lastStoredStringId;
+}
+template<> inline std::vector<QStringList> &PersistentPool::idStorage()
+{
+ return m_stringListStorage;
+}
+template<> inline QHash<QStringList, PersistentPool::PersistentObjectId> &PersistentPool::idMap()
+{
+ return m_inverseStringListStorage;
+}
+template<> inline PersistentPool::PersistentObjectId &PersistentPool::lastStoredId<QStringList>()
+{
+ return m_lastStoredStringListId;
+}
+template<> inline std::vector<QProcessEnvironment> &PersistentPool::idStorage()
+{
+ return m_envStorage;
+}
+template<> inline QHash<QProcessEnvironment, PersistentPool::PersistentObjectId>
+&PersistentPool::idMap()
+{
+ return m_inverseEnvStorage;
+}
+template<> inline PersistentPool::PersistentObjectId
+&PersistentPool::lastStoredId<QProcessEnvironment>()
+{
+ return m_lastStoredEnvId;
+}
+
template <class T> inline std::shared_ptr<T> PersistentPool::idLoadS()
{
PersistentObjectId id;
@@ -227,6 +285,41 @@ template <class T> inline std::shared_ptr<T> PersistentPool::idLoadS()
return t;
}
+template<typename T> inline T PersistentPool::idLoadValue()
+{
+ int id;
+ m_stream >> id;
+ if (id == EmptyValueId)
+ return T();
+ QBS_CHECK(id >= 0);
+ if (id >= static_cast<int>(idStorage<T>().size())) {
+ T value;
+ doLoadValue(value);
+ idStorage<T>().resize(id + 1);
+ idStorage<T>()[id] = value;
+ return value;
+ }
+ return idStorage<T>().at(id);
+}
+
+template<typename T>
+void PersistentPool::idStoreValue(const T &value)
+{
+ if (value.isEmpty()) {
+ m_stream << EmptyValueId;
+ return;
+ }
+ int id = idMap<T>().value(value, ValueNotFoundId);
+ if (id < 0) {
+ id = lastStoredId<T>()++;
+ idMap<T>().insert(value, id);
+ m_stream << id;
+ doStoreValue(value);
+ } else {
+ m_stream << id;
+ }
+}
+
// We need a helper class template, because we require partial specialization for some of
// the aggregate types, which is not possible with function templates.
// The generic implementation assumes that T is of class type and has load() and store()
@@ -320,10 +413,11 @@ template<typename T> struct PPHelper<T *>
static void load(T* &value, PersistentPool *pool) { value = pool->idLoad<T>(); }
};
-template<> struct PPHelper<QString>
+template<typename T> struct PPHelper<T, std::enable_if_t<std::is_same<T, QString>::value
+ || std::is_same<T, QStringList>::value || std::is_same<T, QProcessEnvironment>::value>>
{
- static void store(const QString &s, PersistentPool *pool) { pool->storeString(s); }
- static void load(QString &s, PersistentPool *pool) { s = pool->idLoadString(); }
+ static void store(const T &v, PersistentPool *pool) { pool->idStoreValue(v); }
+ static void load(T &v, PersistentPool *pool) { v = pool->idLoadValue<T>(); }
};
template<> struct PPHelper<QVariant>
@@ -335,30 +429,9 @@ template<> struct PPHelper<QVariant>
template<> struct PPHelper<QRegExp>
{
static void store(const QRegExp &re, PersistentPool *pool) { pool->store(re.pattern()); }
- static void load(QRegExp &re, PersistentPool *pool) { re.setPattern(pool->idLoadString()); }
+ static void load(QRegExp &re, PersistentPool *pool) { re.setPattern(pool->load<QString>()); }
};
-template<> struct PPHelper<QProcessEnvironment>
-{
- static void store(const QProcessEnvironment &env, PersistentPool *pool)
- {
- const QStringList &keys = env.keys();
- pool->store(keys.size());
- for (const QString &key : keys) {
- pool->store(key);
- pool->store(env.value(key));
- }
- }
- static void load(QProcessEnvironment &env, PersistentPool *pool)
- {
- const int count = pool->load<int>();
- for (int i = 0; i < count; ++i) {
- const auto &key = pool->load<QString>();
- const auto &value = pool->load<QString>();
- env.insert(key, value);
- }
- }
-};
template<typename T, typename U> struct PPHelper<std::pair<T, U>>
{
static void store(const std::pair<T, U> &pair, PersistentPool *pool)
@@ -387,7 +460,6 @@ template<typename T> struct PPHelper<QFlags<T>>
};
template<typename T> struct IsSimpleContainer : std::false_type { };
-template<> struct IsSimpleContainer<QStringList> : std::true_type { };
template<typename T> struct IsSimpleContainer<QList<T>> : std::true_type { };
template<typename T> struct IsSimpleContainer<std::vector<T>> : std::true_type { };
diff --git a/src/lib/corelib/tools/preferences.cpp b/src/lib/corelib/tools/preferences.cpp
index 66803a0f5..12af4e9c7 100644
--- a/src/lib/corelib/tools/preferences.cpp
+++ b/src/lib/corelib/tools/preferences.cpp
@@ -124,6 +124,32 @@ QStringList Preferences::pluginPaths(const QString &baseDir) const
return pathList(QLatin1String("pluginsPath"), baseDir + QLatin1String("/qbs/plugins"));
}
+/*!
+ * \brief Returns the per-pool job limits.
+ */
+JobLimits Preferences::jobLimits() const
+{
+ const QString prefix = QLatin1String("preferences.jobLimit");
+ JobLimits limits;
+ for (const QString &key : m_settings->allKeysWithPrefix(prefix, Settings::allScopes())) {
+ limits.setJobLimit(key, m_settings->value(prefix + QLatin1Char('.') + key,
+ Settings::allScopes()).toInt());
+ }
+ const QString fullPrefix = prefix + QLatin1Char('.');
+ if (!m_profile.isEmpty()) {
+ Profile p(m_profile, m_settings, m_profileContents);
+ for (const QString &key : p.allKeys(Profile::KeySelectionRecursive)) {
+ if (!key.startsWith(fullPrefix))
+ continue;
+ const QString jobPool = key.mid(fullPrefix.size());
+ const int limit = p.value(key).toInt();
+ if (limit >= 0)
+ limits.setJobLimit(jobPool, limit);
+ }
+ }
+ return limits;
+}
+
QVariant Preferences::getPreference(const QString &key, const QVariant &defaultValue) const
{
static const QString keyPrefix = QLatin1String("preferences");
diff --git a/src/lib/corelib/tools/preferences.h b/src/lib/corelib/tools/preferences.h
index 07f0edcd7..661b39d7f 100644
--- a/src/lib/corelib/tools/preferences.h
+++ b/src/lib/corelib/tools/preferences.h
@@ -42,6 +42,7 @@
#include "qbs_export.h"
#include "commandechomode.h"
+#include "joblimits.h"
#include "settings.h"
#include <QtCore/qstringlist.h>
@@ -63,6 +64,7 @@ public:
CommandEchoMode defaultEchoMode() const;
QStringList searchPaths(const QString &baseDir = QString()) const;
QStringList pluginPaths(const QString &baseDir = QString()) const;
+ JobLimits jobLimits() const;
private:
QVariant getPreference(const QString &key, const QVariant &defaultValue = QVariant()) const;
diff --git a/src/lib/corelib/tools/profile.h b/src/lib/corelib/tools/profile.h
index a4c6a91f1..2ccc99def 100644
--- a/src/lib/corelib/tools/profile.h
+++ b/src/lib/corelib/tools/profile.h
@@ -59,7 +59,7 @@ public:
bool exists() const;
QVariant value(const QString &key, const QVariant &defaultValue = QVariant(),
- ErrorInfo *error = 0) const;
+ ErrorInfo *error = nullptr) const;
void setValue(const QString &key, const QVariant &value);
void remove(const QString &key);
@@ -72,7 +72,7 @@ public:
void removeProfile();
enum KeySelection { KeySelectionRecursive, KeySelectionNonRecursive };
- QStringList allKeys(KeySelection selection, ErrorInfo *error = 0) const;
+ QStringList allKeys(KeySelection selection, ErrorInfo *error = nullptr) const;
static QString cleanName(const QString &name);
diff --git a/src/lib/corelib/tools/qbspluginmanager.cpp b/src/lib/corelib/tools/qbspluginmanager.cpp
index a8d22f458..d0be73891 100644
--- a/src/lib/corelib/tools/qbspluginmanager.cpp
+++ b/src/lib/corelib/tools/qbspluginmanager.cpp
@@ -80,8 +80,7 @@ QbsPluginManager::~QbsPluginManager()
unloadStaticPlugins();
for (QLibrary * const lib : qAsConst(d->libs)) {
- QbsPluginUnloadFunction unload = reinterpret_cast<QbsPluginUnloadFunction>(
- lib->resolve("QbsPluginUnload"));
+ auto unload = reinterpret_cast<QbsPluginUnloadFunction>(lib->resolve("QbsPluginUnload"));
if (unload)
unload();
lib->unload();
@@ -146,8 +145,7 @@ void QbsPluginManager::loadPlugins(const std::vector<std::string> &pluginPaths,
continue;
}
- QbsPluginLoadFunction load = reinterpret_cast<QbsPluginLoadFunction>(
- lib->resolve("QbsPluginLoad"));
+ auto load = reinterpret_cast<QbsPluginLoadFunction>(lib->resolve("QbsPluginLoad"));
if (load) {
load();
qCDebug(lcPluginManager) << "plugin" << QDir::toNativeSeparators(fileName)
diff --git a/src/lib/corelib/tools/qttools.cpp b/src/lib/corelib/tools/qttools.cpp
index 4e20a7f45..ffd336d56 100644
--- a/src/lib/corelib/tools/qttools.cpp
+++ b/src/lib/corelib/tools/qttools.cpp
@@ -39,7 +39,10 @@
#include "qttools.h"
+#include <QtCore/qprocess.h>
+
QT_BEGIN_NAMESPACE
+
uint qHash(const QStringList &list)
{
uint s = 0;
@@ -47,4 +50,10 @@ uint qHash(const QStringList &list)
s ^= qHash(n) + 0x9e3779b9 + (s << 6) + (s >> 2);
return s;
}
+
+uint qHash(const QProcessEnvironment &env)
+{
+ return qHash(env.toStringList());
+}
+
QT_END_NAMESPACE
diff --git a/src/lib/corelib/tools/qttools.h b/src/lib/corelib/tools/qttools.h
index 50b2829d1..2252c12d3 100644
--- a/src/lib/corelib/tools/qttools.h
+++ b/src/lib/corelib/tools/qttools.h
@@ -45,6 +45,10 @@
#include <functional>
+QT_BEGIN_NAMESPACE
+class QProcessEnvironment;
+QT_END_NAMESPACE
+
namespace std {
template<> struct hash<QString> {
std::size_t operator()(const QString &s) const { return qHash(s); }
@@ -53,6 +57,7 @@ template<> struct hash<QString> {
QT_BEGIN_NAMESPACE
uint qHash(const QStringList &list);
+uint qHash(const QProcessEnvironment &env);
QT_END_NAMESPACE
#endif // QBSQTTOOLS_H
diff --git a/src/lib/corelib/tools/settingsmodel.h b/src/lib/corelib/tools/settingsmodel.h
index 6f9631585..27936ba52 100644
--- a/src/lib/corelib/tools/settingsmodel.h
+++ b/src/lib/corelib/tools/settingsmodel.h
@@ -68,14 +68,16 @@ public:
void addNewKey(const QModelIndex &parent);
void removeKey(const QModelIndex &index);
- Qt::ItemFlags flags(const QModelIndex &index) const;
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex &child) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const override;
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const override;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+ QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const override;
+ QModelIndex parent(const QModelIndex &child) const override;
private:
class SettingsModelPrivate;
diff --git a/src/lib/corelib/tools/setupprojectparameters.h b/src/lib/corelib/tools/setupprojectparameters.h
index fd73d0748..fe7e3d487 100644
--- a/src/lib/corelib/tools/setupprojectparameters.h
+++ b/src/lib/corelib/tools/setupprojectparameters.h
@@ -97,7 +97,9 @@ public:
void setOverriddenValues(const QVariantMap &values);
QVariantMap overriddenValuesTree() const;
- static QVariantMap expandedBuildConfiguration(const Profile &profile, const QString &configurationName, ErrorInfo *errorInfo = 0);
+ static QVariantMap expandedBuildConfiguration(const Profile &profile,
+ const QString &configurationName,
+ ErrorInfo *errorInfo = nullptr);
ErrorInfo expandBuildConfiguration();
QVariantMap buildConfiguration() const;
QVariantMap buildConfigurationTree() const;
diff --git a/src/lib/corelib/tools/stringconstants.h b/src/lib/corelib/tools/stringconstants.h
index f2666e070..6fcf3002b 100644
--- a/src/lib/corelib/tools/stringconstants.h
+++ b/src/lib/corelib/tools/stringconstants.h
@@ -104,6 +104,8 @@ public:
QBS_STRING_CONSTANT(installPrefixProperty, "installPrefix")
QBS_STRING_CONSTANT(installDirProperty, "installDir")
QBS_STRING_CONSTANT(installSourceBaseProperty, "installSourceBase")
+ QBS_STRING_CONSTANT(jobCountProperty, "jobCount")
+ QBS_STRING_CONSTANT(jobPoolProperty, "jobPool")
QBS_STRING_CONSTANT(lengthProperty, "length")
QBS_STRING_CONSTANT(limitToSubProjectProperty, "limitToSubProject")
QBS_STRING_CONSTANT(minimumQbsVersionProperty, "minimumQbsVersion")
diff --git a/src/lib/corelib/tools/tools.pri b/src/lib/corelib/tools/tools.pri
index bb3a55f12..f9c6be9a5 100644
--- a/src/lib/corelib/tools/tools.pri
+++ b/src/lib/corelib/tools/tools.pri
@@ -21,6 +21,7 @@ HEADERS += \
$$PWD/generateoptions.h \
$$PWD/id.h \
$$PWD/iosutils.h \
+ $$PWD/joblimits.h \
$$PWD/jsliterals.h \
$$PWD/launcherinterface.h \
$$PWD/launcherpackets.h \
@@ -75,6 +76,7 @@ SOURCES += \
$$PWD/filetime.cpp \
$$PWD/generateoptions.cpp \
$$PWD/id.cpp \
+ $$PWD/joblimits.cpp \
$$PWD/jsliterals.cpp \
$$PWD/launcherinterface.cpp \
$$PWD/launcherpackets.cpp \
@@ -124,6 +126,7 @@ osx {
$$PWD/error.h \
$$PWD/generateoptions.h \
$$PWD/installoptions.h \
+ $$PWD/joblimits.h \
$$PWD/preferences.h \
$$PWD/processresult.h \
$$PWD/profile.h \