aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSami Shalayel <[email protected]>2025-11-28 14:23:16 +0100
committerSami Shalayel <[email protected]>2025-12-04 21:01:20 +0100
commit691ad1d9b29a1b9cbe20a52f88f76ef65d2f3632 (patch)
tree9daba2d5892877e5484ffd1c13b434c5aeb284b9 /src
parenta464f3d27ba7f6f27b9508516329026bbc828e8a (diff)
qmlls: use 1 job for background builds
Control the numbers of jobs to be used in Qmlls in background builds via the "-j" argument of CMake. Set the default to 1: a background build should not eat up all the CPU/RAM available of the users computer. [ChangeLog][qmlls] The number of CMake jobs can be set with a command line option, an environment variables, and a .ini setting option. The default was changed from using all available cores to 1. You can restore the previous behavior by passing "max" as number of CMake jobs. Task-number: QTBUG-142352 Change-Id: Icc8573906632272773c0a2812febbf06aa6b3079 Reviewed-by: Ulf Hermann <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/qmlls/qmllsmain.cpp75
-rw-r--r--src/qmlls/qqmlcodemodel.cpp23
-rw-r--r--src/qmlls/qqmlcodemodel_p.h6
-rw-r--r--src/qmlls/qqmlcodemodelmanager.cpp7
-rw-r--r--src/qmlls/qqmlcodemodelmanager_p.h2
-rw-r--r--src/qmlls/qqmllsutils.cpp6
-rw-r--r--src/qmlls/qqmllsutils_p.h2
7 files changed, 105 insertions, 16 deletions
diff --git a/src/qmlls/qmllsmain.cpp b/src/qmlls/qmllsmain.cpp
index 481fb21618..2495298600 100644
--- a/src/qmlls/qmllsmain.cpp
+++ b/src/qmlls/qmllsmain.cpp
@@ -221,6 +221,59 @@ static QStringList collectImportPaths(const QCommandLineParser &parser,
return importPaths;
}
+static int cmakeJobs(const QCommandLineParser &parser, const QCommandLineOption &cmakeJobsOption)
+{
+ auto parseAndWarn = [](const QString &valueString, const QString &infoMessage,
+ const QString &warningMessage) {
+ bool ok = false;
+ if (valueString == QQmlCodeModel::s_maxCMakeJobs) {
+ const int value = QThread::idealThreadCount();
+ qInfo().noquote() << infoMessage.arg("max (%1)"_L1.arg(QString::number(value)));
+ return value;
+ }
+
+ const int value = valueString.toInt(&ok);
+ if (!ok || value < 1) {
+ qInfo().noquote() << warningMessage.arg(valueString);
+ return QQmlCodeModel::s_defaultCMakeJobs;
+ }
+ qInfo().noquote() << infoMessage.arg(QString::number(value));
+ return value;
+ };
+
+ if (parser.isSet(cmakeJobsOption)) {
+ return parseAndWarn(
+ parser.value(cmakeJobsOption), "Using %1 jobs for CMake, set via --cmake-jobs."_L1,
+ "Value \"%1\" passed to --cmake-jobs is not a number greater than 0 and not "
+ "\"max\", using default value of 1 instead."_L1);
+ }
+
+ if (!qEnvironmentVariableIsSet("QMLLS_CMAKE_JOBS")) {
+ qInfo() << "Using 1 job for CMake, you can increase that value with the QMLLS_CMAKE_JOBS "
+ "environment variable or the --cmake-jobs option.";
+ return QQmlCodeModel::s_defaultCMakeJobs;
+ }
+ return parseAndWarn(
+ qEnvironmentVariable("QMLLS_CMAKE_JOBS"),
+ "Using %1 jobs for CMake, set via QMLLS_CMAKE_JOBS environment variable."_L1,
+ "Value \"%1\" passed to QMLLS_CMAKE_JOBS is not a number greater than 0 and not "
+ "\"max\", using default value of 1 instead."_L1);
+}
+
+static bool prepareCMakeFeature(const QCommandLineParser &parser,
+ const QCommandLineOption &noCMakeCallsOption)
+{
+ if (qmlGetConfigOption<bool, qmlConvertBoolConfigOption>("QMLLS_NO_CMAKE_CALLS")) {
+ qWarning() << "Disabling CMake calls via QMLLS_NO_CMAKE_CALLS environment variable.";
+ return false;
+ }
+ if (parser.isSet(noCMakeCallsOption)) {
+ qWarning() << "Disabling CMake calls via command line switch.";
+ return false;
+ }
+ return true;
+}
+
// To debug:
//
// * simple logging can be redirected to a file
@@ -319,6 +372,12 @@ int qmllsMain(int argv, char *argc[])
parser.addOption(noCMakeCallsOption);
settings.addOption("no-cmake-calls"_L1, "false"_L1);
+ QCommandLineOption cmakeJobsOption(QStringList() << "cmake-jobs"_L1 << "j"_L1,
+ "Number of CMake jobs for automatic CMake rebuilds. "_L1,
+ "jobs"_L1, "1"_L1);
+ parser.addOption(cmakeJobsOption);
+ settings.addOption("CMakeJobs"_L1, "1"_L1);
+
QCommandLineOption docDir({ { "d"_L1, "p"_L1, "doc-dir"_L1 },
"Documentation path to use for the documentation hints feature"_L1,
"path"_L1,
@@ -422,19 +481,11 @@ int qmllsMain(int argv, char *argc[])
qmlServer.codeModelManager()->setImportPaths(
collectImportPaths(parser, qmlImportPathOption, environmentOption, qmlImportNoDefault));
- const bool disableCMakeCallsViaEnvironment =
- qmlGetConfigOption<bool, qmlConvertBoolConfigOption>("QMLLS_NO_CMAKE_CALLS");
-
- if (disableCMakeCallsViaEnvironment || parser.isSet(noCMakeCallsOption)) {
- if (disableCMakeCallsViaEnvironment) {
- qWarning() << "Disabling CMake calls via QMLLS_NO_CMAKE_CALLS environment variable.";
- } else {
- qWarning() << "Disabling CMake calls via command line switch.";
- }
-
- qmlServer.codeModelManager()->disableCMakeCalls();
- } else {
+ if (prepareCMakeFeature(parser, noCMakeCallsOption)) {
+ qmlServer.codeModelManager()->setCMakeJobs(cmakeJobs(parser, cmakeJobsOption));
qmlServer.codeModelManager()->tryEnableCMakeCalls();
+ } else {
+ qmlServer.codeModelManager()->disableCMakeCalls();
}
auto r = parser.isSet(inputFile) && parser.value(inputFile) != "-"_L1
diff --git a/src/qmlls/qqmlcodemodel.cpp b/src/qmlls/qqmlcodemodel.cpp
index b7cae6cfdd..fa862f7801 100644
--- a/src/qmlls/qqmlcodemodel.cpp
+++ b/src/qmlls/qqmlcodemodel.cpp
@@ -318,16 +318,37 @@ QStringList QQmlCodeModel::buildPathsForOpenedFiles()
return result;
}
+static int cmakeJobsFromSettings(QQmlToolingSharedSettings *settings, const QString &rootPath,
+ int defaultValue)
+{
+ if (!settings)
+ return defaultValue;
+ const auto result = settings->search(rootPath);
+ if (!result.isValid())
+ return defaultValue;
+
+ bool ok = false;
+ const QString valueString = settings->value("CMakeJobs"_L1).toString();
+ if (valueString == QQmlCodeModel::s_maxCMakeJobs)
+ return QThread::idealThreadCount();
+
+ const int cmakeJobs = settings->value("CMakeJobs"_L1).toInt(&ok);
+ if (!ok || cmakeJobs < 1)
+ return defaultValue;
+ return cmakeJobs;
+}
+
void QQmlCodeModel::callCMakeBuild(QProcessScheduler *scheduler)
{
const QStringList buildPaths = buildPathsForOpenedFiles();
+ const int cmakeJobs = cmakeJobsFromSettings(m_settings, url2Path(m_rootUrl), m_cmakeJobs);
QList<QProcessScheduler::Command> commands;
for (const auto &path : buildPaths) {
if (!QFileInfo::exists(path + u"/.cmake"_s))
continue;
- const auto [program, arguments] = QQmlLSUtils::cmakeBuildCommand(path);
+ auto [program, arguments] = QQmlLSUtils::cmakeBuildCommand(path, cmakeJobs);
commands.append({ std::move(program), std::move(arguments) });
}
if (commands.isEmpty())
diff --git a/src/qmlls/qqmlcodemodel_p.h b/src/qmlls/qqmlcodemodel_p.h
index 990cf43583..e319a183fc 100644
--- a/src/qmlls/qqmlcodemodel_p.h
+++ b/src/qmlls/qqmlcodemodel_p.h
@@ -104,6 +104,9 @@ public:
enum class UrlLookup { Caching, ForceLookup };
enum class State { Running, Stopping };
+ static constexpr QLatin1String s_maxCMakeJobs = "max"_L1;
+ static constexpr int s_defaultCMakeJobs = 1;
+
explicit QQmlCodeModel(const QByteArray &rootUrl = {}, QObject *parent = nullptr,
QQmlToolingSharedSettings *settings = nullptr);
~QQmlCodeModel();
@@ -159,6 +162,8 @@ public:
QMutexLocker guard(&m_mutex);
return m_verbose;
}
+ void setCMakeJobs(int jobs) { m_cmakeJobs = jobs; }
+ int cmakeJobs() const { return m_cmakeJobs; }
Q_SIGNALS:
void updatedSnapshot(const QByteArray &url, UpdatePolicy policy);
@@ -220,6 +225,7 @@ private:
QSet<QString> m_ignoreForWatching;
int m_nUpdateInProgress = 0;
CMakeStatus m_cmakeStatus = RequiresInitialization;
+ int m_cmakeJobs = 1;
bool m_verbose = false;
};
diff --git a/src/qmlls/qqmlcodemodelmanager.cpp b/src/qmlls/qqmlcodemodelmanager.cpp
index 9d8105787a..3a6bccbdd3 100644
--- a/src/qmlls/qqmlcodemodelmanager.cpp
+++ b/src/qmlls/qqmlcodemodelmanager.cpp
@@ -125,6 +125,7 @@ void QQmlCodeModelManager::appendWorkspace(const QByteArray &url, ManagedBy mana
// the non-fallback codemodel inherits the default values from the fallback codemodel
if (!url.isEmpty()) {
+ ws.codeModel->setCMakeJobs(defaultCMakeJobs());
ws.codeModel->setDocumentationRootPath(defaultDocumentationRootPath());
ws.codeModel->setBuildPaths(defaultBuildPaths());
ws.codeModel->setImportPaths(
@@ -293,6 +294,12 @@ void QQmlCodeModelManager::setVerbose(bool verbose)
ws.codeModel->setVerbose(verbose);
}
+void QQmlCodeModelManager::setCMakeJobs(int jobs)
+{
+ for (const auto &ws : m_workspaces)
+ ws.codeModel->setCMakeJobs(jobs);
+}
+
void QQmlCodeModelManager::setBuildPathsForRootUrl(const QByteArray &url, const QStringList &paths)
{
const QStringList defaultPaths = defaultBuildPaths();
diff --git a/src/qmlls/qqmlcodemodelmanager_p.h b/src/qmlls/qqmlcodemodelmanager_p.h
index d74042d9e0..f112ae33fc 100644
--- a/src/qmlls/qqmlcodemodelmanager_p.h
+++ b/src/qmlls/qqmlcodemodelmanager_p.h
@@ -73,6 +73,8 @@ public:
HelpManager *helpManagerForUrl(const QByteArray &);
void tryEnableCMakeCalls();
+ void setCMakeJobs(int jobs);
+ int defaultCMakeJobs() const { return fallbackCodeModel()->cmakeJobs(); }
void setVerbose(bool verbose);
QStringList defaultImportPaths() const { return fallbackCodeModel()->importPaths(); }
diff --git a/src/qmlls/qqmllsutils.cpp b/src/qmlls/qqmllsutils.cpp
index 11451e9ea0..163ea485d5 100644
--- a/src/qmlls/qqmllsutils.cpp
+++ b/src/qmlls/qqmllsutils.cpp
@@ -2517,11 +2517,13 @@ https://doc.qt.io/qt-6/windows-building.html#step-2-install-build-requirements c
to have CMake in your path to build Qt. So a developer machine running qmlls has a high chance of
having CMake in their path, if CMake is installed and used.
*/
-std::pair<QString, QStringList> cmakeBuildCommand(const QString &path)
+std::pair<QString, QStringList> cmakeBuildCommand(const QString &path, int cmakeJobs)
{
- const std::pair<QString, QStringList> result{
+ std::pair<QString, QStringList> result{
u"cmake"_s, { u"--build"_s, path, u"-t"_s, u"all_qmltyperegistrations"_s }
};
+ if (cmakeJobs > 0)
+ result.second << "-j"_L1 << QString::number(cmakeJobs);
return result;
}
diff --git a/src/qmlls/qqmllsutils_p.h b/src/qmlls/qqmllsutils_p.h
index 78d524cc4f..ffa8b4c6ba 100644
--- a/src/qmlls/qqmllsutils_p.h
+++ b/src/qmlls/qqmllsutils_p.h
@@ -278,7 +278,7 @@ RenameUsages renameUsagesOf(const DomItem &item, const QString &newName,
std::optional<ExpressionType> resolveExpressionType(const DomItem &item, ResolveOptions);
bool isValidEcmaScriptIdentifier(QStringView view);
-std::pair<QString, QStringList> cmakeBuildCommand(const QString &path);
+std::pair<QString, QStringList> cmakeBuildCommand(const QString &path, int cmakeJobs = 0);
bool isFieldMemberExpression(const DomItem &item);
bool isFieldMemberAccess(const DomItem &item);