diff options
| author | Sami Shalayel <[email protected]> | 2025-11-28 14:23:16 +0100 |
|---|---|---|
| committer | Sami Shalayel <[email protected]> | 2025-12-04 21:01:20 +0100 |
| commit | 691ad1d9b29a1b9cbe20a52f88f76ef65d2f3632 (patch) | |
| tree | 9daba2d5892877e5484ffd1c13b434c5aeb284b9 /src | |
| parent | a464f3d27ba7f6f27b9508516329026bbc828e8a (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.cpp | 75 | ||||
| -rw-r--r-- | src/qmlls/qqmlcodemodel.cpp | 23 | ||||
| -rw-r--r-- | src/qmlls/qqmlcodemodel_p.h | 6 | ||||
| -rw-r--r-- | src/qmlls/qqmlcodemodelmanager.cpp | 7 | ||||
| -rw-r--r-- | src/qmlls/qqmlcodemodelmanager_p.h | 2 | ||||
| -rw-r--r-- | src/qmlls/qqmllsutils.cpp | 6 | ||||
| -rw-r--r-- | src/qmlls/qqmllsutils_p.h | 2 |
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); |
