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 <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2024-12-02 13:24:35 +01:00
parent 071bd23bf9
commit 67b51d1505
8 changed files with 36 additions and 22 deletions

View File

@@ -382,7 +382,7 @@ Tasking::GroupItem QbsBuildStep::runRecipe()
{ {
using namespace Tasking; using namespace Tasking;
const auto onPreParserSetup = [this](QbsRequest &request) { const auto onPreParserSetup = [this](QbsRequest &request) {
request.setParseData(qbsBuildSystem()); request.setParseData({qbsBuildSystem(), {}});
}; };
const auto onBuildSetup = [this](QbsRequest &request) { const auto onBuildSetup = [this](QbsRequest &request) {
QbsSession *session = qbsBuildSystem()->session(); QbsSession *session = qbsBuildSystem()->session();

View File

@@ -599,7 +599,7 @@ void QbsBuildSystem::changeActiveTarget(Target *t)
void QbsBuildSystem::triggerParsing() void QbsBuildSystem::triggerParsing()
{ {
scheduleParsing(); scheduleParsing({});
} }
void QbsBuildSystem::delayParsing() void QbsBuildSystem::delayParsing()
@@ -613,17 +613,17 @@ ExtraCompiler *QbsBuildSystem::findExtraCompiler(const ExtraCompilerFilter &filt
return Utils::findOrDefault(m_extraCompilers, filter); return Utils::findOrDefault(m_extraCompilers, filter);
} }
void QbsBuildSystem::scheduleParsing() void QbsBuildSystem::scheduleParsing(const QVariantMap &extraConfig)
{ {
m_parseRequest.reset(new QbsRequest); m_parseRequest.reset(new QbsRequest);
m_parseRequest->setParseData(this); m_parseRequest->setParseData({this, extraConfig});
connect(m_parseRequest.get(), &QbsRequest::done, this, [this] { connect(m_parseRequest.get(), &QbsRequest::done, this, [this] {
m_parseRequest.release()->deleteLater(); m_parseRequest.release()->deleteLater();
}); });
m_parseRequest->start(); m_parseRequest->start();
} }
void QbsBuildSystem::startParsing() void QbsBuildSystem::startParsing(const QVariantMap &extraConfig)
{ {
QTC_ASSERT(!m_qbsProjectParser, return); QTC_ASSERT(!m_qbsProjectParser, return);
@@ -632,6 +632,9 @@ void QbsBuildSystem::startParsing()
config.insert(Constants::QBS_INSTALL_ROOT_KEY, m_buildConfiguration->macroExpander() config.insert(Constants::QBS_INSTALL_ROOT_KEY, m_buildConfiguration->macroExpander()
->expand(QbsSettings::defaultInstallDirTemplate())); ->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(); Environment env = m_buildConfiguration->environment();
FilePath dir = m_buildConfiguration->buildDirectory(); FilePath dir = m_buildConfiguration->buildDirectory();

View File

@@ -96,7 +96,7 @@ public:
static ProjectExplorer::FileType fileTypeFor(const QSet<QString> &tags); static ProjectExplorer::FileType fileTypeFor(const QSet<QString> &tags);
QString profile() const; QString profile() const;
void scheduleParsing(); void scheduleParsing(const QVariantMap &extraConfig);
void updateAfterBuild(); void updateAfterBuild();
QbsSession *session() const { return m_session; } QbsSession *session() const { return m_session; }
@@ -110,7 +110,7 @@ private:
friend class QbsProject; friend class QbsProject;
friend class QbsRequestObject; friend class QbsRequestObject;
void startParsing(); void startParsing(const QVariantMap &extraConfig);
void cancelParsing(); void cancelParsing();
ProjectExplorer::ExtraCompiler *findExtraCompiler( ProjectExplorer::ExtraCompiler *findExtraCompiler(

View File

@@ -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_QUICK_COMPILER_KEY[] = "modules.Qt.quick.useCompiler";
const char QBS_CONFIG_SEPARATE_DEBUG_INFO_KEY[] = "modules.cpp.separateDebugInformation"; const char QBS_CONFIG_SEPARATE_DEBUG_INFO_KEY[] = "modules.cpp.separateDebugInformation";
const char QBS_FORCE_PROBES_KEY[] = "qbspm.forceProbes"; const char QBS_FORCE_PROBES_KEY[] = "qbspm.forceProbes";
const char QBS_RESTORE_BEHAVIOR_KEY[] = "restore-behavior";
// Toolchain related settings: // Toolchain related settings:
const char QBS_TARGETPLATFORM[] = "qbs.targetPlatform"; const char QBS_TARGETPLATFORM[] = "qbs.targetPlatform";

View File

@@ -613,7 +613,7 @@ void QbsProjectManagerPlugin::reparseProject(QbsProject *project)
return; return;
if (auto bs = qobject_cast<QbsBuildSystem *>(t->buildSystem())) if (auto bs = qobject_cast<QbsBuildSystem *>(t->buildSystem()))
bs->scheduleParsing(); bs->scheduleParsing({{Constants::QBS_RESTORE_BEHAVIOR_KEY, "resolve-only"}});
} }
void buildNamedProduct(QbsProject *project, const QString &product) void buildNamedProduct(QbsProject *project, const QString &product)

View File

@@ -69,6 +69,8 @@ void QbsProjectParser::parse(const Store &config, const Environment &env,
request.insert("configuration-name", configName); request.insert("configuration-name", configName);
request.insert("force-probe-execution", request.insert("force-probe-execution",
userConfig.take(Constants::QBS_FORCE_PROBES_KEY).toBool()); 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()) if (QbsSettings::useCreatorSettingsDirForQbs())
request.insert("settings-directory", QbsSettings::qbsSettingsBaseDir()); request.insert("settings-directory", QbsSettings::qbsSettingsBaseDir());
request.insert("overridden-properties", QJsonObject::fromVariantMap(mapFromStore(userConfig))); request.insert("overridden-properties", QJsonObject::fromVariantMap(mapFromStore(userConfig)));

View File

@@ -36,7 +36,8 @@ public:
void setSession(QbsSession *session) { m_session = session; } void setSession(QbsSession *session) { m_session = session; }
QbsSession *session() const { return m_session; } QbsSession *session() const { return m_session; }
void setRequestData(const QJsonObject &requestData) { m_requestData = requestData; } void setRequestData(const QJsonObject &requestData) { m_requestData = requestData; }
void setParseData(const QPointer<QbsBuildSystem> &buildSystem) { m_parseData = buildSystem; } void setParseData(const ParseData &parseData) { m_parseData = parseData; }
void start(); void start();
void cancel(); void cancel();
@@ -49,7 +50,7 @@ signals:
private: private:
QbsSession *m_session = nullptr; QbsSession *m_session = nullptr;
QJsonObject m_requestData; QJsonObject m_requestData;
QPointer<QbsBuildSystem> m_parseData; ParseData m_parseData;
QString m_description; QString m_description;
int m_maxProgress = 100; int m_maxProgress = 100;
}; };
@@ -112,13 +113,15 @@ static QbsRequestManager &manager()
void QbsRequestObject::start() void QbsRequestObject::start()
{ {
if (m_parseData) { if (m_parseData.first) {
connect(m_parseData->target(), &Target::parsingFinished, this, [this](bool success) { connect(m_parseData.first->target(), &Target::parsingFinished, this, [this](bool success) {
disconnect(m_parseData->target(), &Target::parsingFinished, this, nullptr); disconnect(m_parseData.first->target(), &Target::parsingFinished, this, nullptr);
emit done(toDoneResult(success)); emit done(toDoneResult(success));
}); });
QMetaObject::invokeMethod(m_parseData.get(), &QbsBuildSystem::startParsing, QMetaObject::invokeMethod(
Qt::QueuedConnection); m_parseData.first.get(),
[parseData = m_parseData] { parseData.first->startParsing(parseData.second); },
Qt::QueuedConnection);
return; return;
} }
@@ -172,8 +175,8 @@ void QbsRequestObject::start()
void QbsRequestObject::cancel() void QbsRequestObject::cancel()
{ {
if (m_parseData) if (m_parseData.first)
m_parseData->cancelParsing(); m_parseData.first->cancelParsing();
else else
m_session->cancelCurrentJob(); m_session->cancelCurrentJob();
} }
@@ -189,14 +192,15 @@ QbsRequest::~QbsRequest()
void QbsRequest::start() void QbsRequest::start()
{ {
QTC_ASSERT(!m_requestObject, return); 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 = new QbsRequestObject;
m_requestObject->setSession(m_session); m_requestObject->setSession(m_session);
if (m_requestData) if (m_requestData)
m_requestObject->setRequestData(*m_requestData); m_requestObject->setRequestData(*m_requestData);
if (m_parseData) { if (m_parseData.first) {
m_requestObject->setSession(m_parseData->session()); m_requestObject->setSession(m_parseData.first->session());
m_requestObject->setParseData(m_parseData); m_requestObject->setParseData(m_parseData);
} }

View File

@@ -9,12 +9,16 @@
#include <QJsonObject> #include <QJsonObject>
#include <utility>
namespace QbsProjectManager::Internal { namespace QbsProjectManager::Internal {
class QbsBuildSystem; class QbsBuildSystem;
class QbsRequestObject; class QbsRequestObject;
class QbsSession; class QbsSession;
using ParseData = std::pair<QPointer<QbsBuildSystem>, QVariantMap>;
class QbsRequest final : public QObject class QbsRequest final : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -24,7 +28,7 @@ public:
void setSession(QbsSession *session) { m_session = session; } void setSession(QbsSession *session) { m_session = session; }
void setRequestData(const QJsonObject &requestData) { m_requestData = requestData; } void setRequestData(const QJsonObject &requestData) { m_requestData = requestData; }
void setParseData(const QPointer<QbsBuildSystem> &buildSystem) { m_parseData = buildSystem; } void setParseData(const ParseData &parseData) { m_parseData = parseData; }
void start(); void start();
signals: signals:
@@ -36,7 +40,7 @@ signals:
private: private:
QbsSession *m_session = nullptr; // TODO: Should we keep a QPointer? QbsSession *m_session = nullptr; // TODO: Should we keep a QPointer?
std::optional<QJsonObject> m_requestData; std::optional<QJsonObject> m_requestData;
QPointer<QbsBuildSystem> m_parseData; ParseData m_parseData;
QbsRequestObject *m_requestObject = nullptr; QbsRequestObject *m_requestObject = nullptr;
}; };