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;
const auto onPreParserSetup = [this](QbsRequest &request) {
request.setParseData(qbsBuildSystem());
request.setParseData({qbsBuildSystem(), {}});
};
const auto onBuildSetup = [this](QbsRequest &request) {
QbsSession *session = qbsBuildSystem()->session();

View File

@@ -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();

View File

@@ -96,7 +96,7 @@ public:
static ProjectExplorer::FileType fileTypeFor(const QSet<QString> &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(

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_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";

View File

@@ -613,7 +613,7 @@ void QbsProjectManagerPlugin::reparseProject(QbsProject *project)
return;
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)

View File

@@ -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)));

View File

@@ -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<QbsBuildSystem> &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<QbsBuildSystem> 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);
}

View File

@@ -9,12 +9,16 @@
#include <QJsonObject>
#include <utility>
namespace QbsProjectManager::Internal {
class QbsBuildSystem;
class QbsRequestObject;
class QbsSession;
using ParseData = std::pair<QPointer<QbsBuildSystem>, 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<QbsBuildSystem> &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<QJsonObject> m_requestData;
QPointer<QbsBuildSystem> m_parseData;
ParseData m_parseData;
QbsRequestObject *m_requestObject = nullptr;
};