From 67b51d15056459863009493d1c9e5a8f040e53b3 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 2 Dec 2024 13:24:35 +0100 Subject: [PATCH] QbsProjectManager: Force full resolving on "Reparse Qbs" This option is intended for "trying again" if something failed in a way that changes to the problematic file won't get picked up because it was so broken that it did not end up in the list of build system files to watch. However, if that is the case, then qbs' own change tracking mechanism will also not detect a change, so the whole procedure was useless. We fix this by explicitly instrucing qbs to do a full (re-)resolve for that particular action. Change-Id: I8d686e5e5a4312c3c8f23498edd4af871090e96e Reviewed-by: Christian Stenger --- .../qbsprojectmanager/qbsbuildstep.cpp | 2 +- src/plugins/qbsprojectmanager/qbsproject.cpp | 11 +++++--- src/plugins/qbsprojectmanager/qbsproject.h | 4 +-- .../qbsprojectmanagerconstants.h | 1 + .../qbsprojectmanagerplugin.cpp | 2 +- .../qbsprojectmanager/qbsprojectparser.cpp | 2 ++ src/plugins/qbsprojectmanager/qbsrequest.cpp | 28 +++++++++++-------- src/plugins/qbsprojectmanager/qbsrequest.h | 8 ++++-- 8 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp index c28e52e0262..9aec496e0ef 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp @@ -382,7 +382,7 @@ Tasking::GroupItem QbsBuildStep::runRecipe() { using namespace Tasking; const auto onPreParserSetup = [this](QbsRequest &request) { - request.setParseData(qbsBuildSystem()); + request.setParseData({qbsBuildSystem(), {}}); }; const auto onBuildSetup = [this](QbsRequest &request) { QbsSession *session = qbsBuildSystem()->session(); diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 2a14b493ecd..508d9eac36a 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -599,7 +599,7 @@ void QbsBuildSystem::changeActiveTarget(Target *t) void QbsBuildSystem::triggerParsing() { - scheduleParsing(); + scheduleParsing({}); } void QbsBuildSystem::delayParsing() @@ -613,17 +613,17 @@ ExtraCompiler *QbsBuildSystem::findExtraCompiler(const ExtraCompilerFilter &filt return Utils::findOrDefault(m_extraCompilers, filter); } -void QbsBuildSystem::scheduleParsing() +void QbsBuildSystem::scheduleParsing(const QVariantMap &extraConfig) { m_parseRequest.reset(new QbsRequest); - m_parseRequest->setParseData(this); + m_parseRequest->setParseData({this, extraConfig}); connect(m_parseRequest.get(), &QbsRequest::done, this, [this] { m_parseRequest.release()->deleteLater(); }); m_parseRequest->start(); } -void QbsBuildSystem::startParsing() +void QbsBuildSystem::startParsing(const QVariantMap &extraConfig) { QTC_ASSERT(!m_qbsProjectParser, return); @@ -632,6 +632,9 @@ void QbsBuildSystem::startParsing() config.insert(Constants::QBS_INSTALL_ROOT_KEY, m_buildConfiguration->macroExpander() ->expand(QbsSettings::defaultInstallDirTemplate())); } + config.insert(Constants::QBS_RESTORE_BEHAVIOR_KEY, "restore-and-track-changes"); + for (auto it = extraConfig.begin(); it != extraConfig.end(); ++it) + config.insert(keyFromString(it.key()), it.value()); Environment env = m_buildConfiguration->environment(); FilePath dir = m_buildConfiguration->buildDirectory(); diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h index 4dffaf01044..0edb7e67c41 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.h +++ b/src/plugins/qbsprojectmanager/qbsproject.h @@ -96,7 +96,7 @@ public: static ProjectExplorer::FileType fileTypeFor(const QSet &tags); QString profile() const; - void scheduleParsing(); + void scheduleParsing(const QVariantMap &extraConfig); void updateAfterBuild(); QbsSession *session() const { return m_session; } @@ -110,7 +110,7 @@ private: friend class QbsProject; friend class QbsRequestObject; - void startParsing(); + void startParsing(const QVariantMap &extraConfig); void cancelParsing(); ProjectExplorer::ExtraCompiler *findExtraCompiler( diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h index c03ef27356a..b5a3fa4272c 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h @@ -48,6 +48,7 @@ const char QBS_CONFIG_QUICK_DEBUG_KEY[] = "modules.Qt.quick.qmlDebugging"; const char QBS_CONFIG_QUICK_COMPILER_KEY[] = "modules.Qt.quick.useCompiler"; const char QBS_CONFIG_SEPARATE_DEBUG_INFO_KEY[] = "modules.cpp.separateDebugInformation"; const char QBS_FORCE_PROBES_KEY[] = "qbspm.forceProbes"; +const char QBS_RESTORE_BEHAVIOR_KEY[] = "restore-behavior"; // Toolchain related settings: const char QBS_TARGETPLATFORM[] = "qbs.targetPlatform"; diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp index 1290d0162f3..4e9dc0de72b 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp @@ -613,7 +613,7 @@ void QbsProjectManagerPlugin::reparseProject(QbsProject *project) return; if (auto bs = qobject_cast(t->buildSystem())) - bs->scheduleParsing(); + bs->scheduleParsing({{Constants::QBS_RESTORE_BEHAVIOR_KEY, "resolve-only"}}); } void buildNamedProduct(QbsProject *project, const QString &product) diff --git a/src/plugins/qbsprojectmanager/qbsprojectparser.cpp b/src/plugins/qbsprojectmanager/qbsprojectparser.cpp index 88fb59bc0fc..dd69935e185 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectparser.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectparser.cpp @@ -69,6 +69,8 @@ void QbsProjectParser::parse(const Store &config, const Environment &env, request.insert("configuration-name", configName); request.insert("force-probe-execution", userConfig.take(Constants::QBS_FORCE_PROBES_KEY).toBool()); + request.insert(Constants::QBS_RESTORE_BEHAVIOR_KEY, + userConfig.take(Constants::QBS_RESTORE_BEHAVIOR_KEY).toString()); if (QbsSettings::useCreatorSettingsDirForQbs()) request.insert("settings-directory", QbsSettings::qbsSettingsBaseDir()); request.insert("overridden-properties", QJsonObject::fromVariantMap(mapFromStore(userConfig))); diff --git a/src/plugins/qbsprojectmanager/qbsrequest.cpp b/src/plugins/qbsprojectmanager/qbsrequest.cpp index e6ac1c2fb89..ba984d84cbc 100644 --- a/src/plugins/qbsprojectmanager/qbsrequest.cpp +++ b/src/plugins/qbsprojectmanager/qbsrequest.cpp @@ -36,7 +36,8 @@ public: void setSession(QbsSession *session) { m_session = session; } QbsSession *session() const { return m_session; } void setRequestData(const QJsonObject &requestData) { m_requestData = requestData; } - void setParseData(const QPointer &buildSystem) { m_parseData = buildSystem; } + void setParseData(const ParseData &parseData) { m_parseData = parseData; } + void start(); void cancel(); @@ -49,7 +50,7 @@ signals: private: QbsSession *m_session = nullptr; QJsonObject m_requestData; - QPointer m_parseData; + ParseData m_parseData; QString m_description; int m_maxProgress = 100; }; @@ -112,13 +113,15 @@ static QbsRequestManager &manager() void QbsRequestObject::start() { - if (m_parseData) { - connect(m_parseData->target(), &Target::parsingFinished, this, [this](bool success) { - disconnect(m_parseData->target(), &Target::parsingFinished, this, nullptr); + if (m_parseData.first) { + connect(m_parseData.first->target(), &Target::parsingFinished, this, [this](bool success) { + disconnect(m_parseData.first->target(), &Target::parsingFinished, this, nullptr); emit done(toDoneResult(success)); }); - QMetaObject::invokeMethod(m_parseData.get(), &QbsBuildSystem::startParsing, - Qt::QueuedConnection); + QMetaObject::invokeMethod( + m_parseData.first.get(), + [parseData = m_parseData] { parseData.first->startParsing(parseData.second); }, + Qt::QueuedConnection); return; } @@ -172,8 +175,8 @@ void QbsRequestObject::start() void QbsRequestObject::cancel() { - if (m_parseData) - m_parseData->cancelParsing(); + if (m_parseData.first) + m_parseData.first->cancelParsing(); else m_session->cancelCurrentJob(); } @@ -189,14 +192,15 @@ QbsRequest::~QbsRequest() void QbsRequest::start() { QTC_ASSERT(!m_requestObject, return); - QTC_ASSERT(m_parseData || (m_session && m_requestData), emit done(DoneResult::Error); return); + QTC_ASSERT(m_parseData.first || (m_session && m_requestData), emit done(DoneResult::Error); + return); m_requestObject = new QbsRequestObject; m_requestObject->setSession(m_session); if (m_requestData) m_requestObject->setRequestData(*m_requestData); - if (m_parseData) { - m_requestObject->setSession(m_parseData->session()); + if (m_parseData.first) { + m_requestObject->setSession(m_parseData.first->session()); m_requestObject->setParseData(m_parseData); } diff --git a/src/plugins/qbsprojectmanager/qbsrequest.h b/src/plugins/qbsprojectmanager/qbsrequest.h index 340bbe0f12f..763a44fced6 100644 --- a/src/plugins/qbsprojectmanager/qbsrequest.h +++ b/src/plugins/qbsprojectmanager/qbsrequest.h @@ -9,12 +9,16 @@ #include +#include + namespace QbsProjectManager::Internal { class QbsBuildSystem; class QbsRequestObject; class QbsSession; +using ParseData = std::pair, QVariantMap>; + class QbsRequest final : public QObject { Q_OBJECT @@ -24,7 +28,7 @@ public: void setSession(QbsSession *session) { m_session = session; } void setRequestData(const QJsonObject &requestData) { m_requestData = requestData; } - void setParseData(const QPointer &buildSystem) { m_parseData = buildSystem; } + void setParseData(const ParseData &parseData) { m_parseData = parseData; } void start(); signals: @@ -36,7 +40,7 @@ signals: private: QbsSession *m_session = nullptr; // TODO: Should we keep a QPointer? std::optional m_requestData; - QPointer m_parseData; + ParseData m_parseData; QbsRequestObject *m_requestObject = nullptr; };