forked from qt-creator/qt-creator
QbsProjectManager: Switch to an out-of-process approach
That is, do not link to the qbscore library anymore. Instead, use the
JSON-based API.
Advantages:
- We can build Qt Creator with qbs support without qbs being present
on the build machine.
- Smaller memory footprint for Qt Creator, as the qbs build graphs
are now being managed by a separate process.
- Potential crashes in qbs will not kill the Qt Creator process.
Fixes: QTCREATORBUG-20622
Task-number: QTCREATORBUG-22904
Change-Id: If7d344b0ac65a99ff0a3a3db215d61b8d903e47e
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "qbsbuildconfiguration.h"
|
||||
#include "qbsproject.h"
|
||||
#include "qbsprojectmanagerconstants.h"
|
||||
#include "qbssession.h"
|
||||
|
||||
#include <projectexplorer/buildsteplist.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
@@ -36,6 +37,9 @@
|
||||
#include <projectexplorer/target.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
namespace QbsProjectManager {
|
||||
@@ -73,66 +77,60 @@ QbsCleanStep::QbsCleanStep(ProjectExplorer::BuildStepList *bsl) :
|
||||
QbsCleanStep::~QbsCleanStep()
|
||||
{
|
||||
doCancel();
|
||||
if (m_job) {
|
||||
m_job->deleteLater();
|
||||
m_job = nullptr;
|
||||
}
|
||||
if (m_session)
|
||||
m_session->disconnect(this);
|
||||
}
|
||||
|
||||
bool QbsCleanStep::init()
|
||||
{
|
||||
if (buildSystem()->isParsing() || m_job)
|
||||
if (buildSystem()->isParsing() || m_session)
|
||||
return false;
|
||||
|
||||
auto bc = static_cast<QbsBuildConfiguration *>(buildConfiguration());
|
||||
|
||||
const auto bc = static_cast<QbsBuildConfiguration *>(buildConfiguration());
|
||||
if (!bc)
|
||||
return false;
|
||||
|
||||
m_products = bc->products();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QbsCleanStep::doRun()
|
||||
{
|
||||
qbs::CleanOptions options;
|
||||
options.setDryRun(m_dryRunAspect->value());
|
||||
options.setKeepGoing(m_keepGoingAspect->value());
|
||||
|
||||
QString error;
|
||||
m_job = qbsBuildSystem()->clean(options, m_products, error);
|
||||
if (!m_job) {
|
||||
emit addOutput(error, OutputFormat::ErrorMessage);
|
||||
m_session = static_cast<QbsBuildSystem*>(buildSystem())->session();
|
||||
if (!m_session) {
|
||||
emit addOutput(tr("No qbs session exists for this target."), OutputFormat::ErrorMessage);
|
||||
emit finished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject request;
|
||||
request.insert("type", "clean-project");
|
||||
if (!m_products.isEmpty())
|
||||
request.insert("products", QJsonArray::fromStringList(m_products));
|
||||
request.insert("dry-run", m_dryRunAspect->value());
|
||||
request.insert("keep-going", m_keepGoingAspect->value());
|
||||
m_session->sendRequest(request);
|
||||
m_maxProgress = 0;
|
||||
|
||||
connect(m_job, &qbs::AbstractJob::finished, this, &QbsCleanStep::cleaningDone);
|
||||
connect(m_job, &qbs::AbstractJob::taskStarted,
|
||||
this, &QbsCleanStep::handleTaskStarted);
|
||||
connect(m_job, &qbs::AbstractJob::taskProgress,
|
||||
this, &QbsCleanStep::handleProgress);
|
||||
connect(m_session, &QbsSession::projectCleaned, this, &QbsCleanStep::cleaningDone);
|
||||
connect(m_session, &QbsSession::taskStarted, this, &QbsCleanStep::handleTaskStarted);
|
||||
connect(m_session, &QbsSession::taskProgress, this, &QbsCleanStep::handleProgress);
|
||||
connect(m_session, &QbsSession::errorOccurred, this, [this] {
|
||||
cleaningDone(ErrorInfo(tr("Cleaning canceled: Qbs session failed.")));
|
||||
});
|
||||
}
|
||||
|
||||
void QbsCleanStep::doCancel()
|
||||
{
|
||||
if (m_job)
|
||||
m_job->cancel();
|
||||
if (m_session)
|
||||
m_session->cancelCurrentJob();
|
||||
}
|
||||
|
||||
void QbsCleanStep::cleaningDone(bool success)
|
||||
void QbsCleanStep::cleaningDone(const ErrorInfo &error)
|
||||
{
|
||||
// Report errors:
|
||||
foreach (const qbs::ErrorItem &item, m_job->error().items()) {
|
||||
createTaskAndOutput(ProjectExplorer::Task::Error, item.description(),
|
||||
item.codeLocation().filePath(), item.codeLocation().line());
|
||||
}
|
||||
m_session->disconnect(this);
|
||||
m_session = nullptr;
|
||||
|
||||
emit finished(success);
|
||||
m_job->deleteLater();
|
||||
m_job = nullptr;
|
||||
for (const ErrorInfoItem &item : error.items)
|
||||
createTaskAndOutput(Task::Error, item.description, item.filePath.toString(), item.line);
|
||||
emit finished(!error.hasError());
|
||||
}
|
||||
|
||||
void QbsCleanStep::handleTaskStarted(const QString &desciption, int max)
|
||||
@@ -149,9 +147,8 @@ void QbsCleanStep::handleProgress(int value)
|
||||
|
||||
void QbsCleanStep::createTaskAndOutput(ProjectExplorer::Task::TaskType type, const QString &message, const QString &file, int line)
|
||||
{
|
||||
ProjectExplorer::Task task = ProjectExplorer::Task(type, message,
|
||||
Utils::FilePath::fromString(file), line,
|
||||
ProjectExplorer::Constants::TASK_CATEGORY_COMPILE);
|
||||
Task task(type, message, Utils::FilePath::fromString(file), line,
|
||||
ProjectExplorer::Constants::TASK_CATEGORY_COMPILE);
|
||||
emit addTask(task, 1);
|
||||
emit addOutput(message, OutputFormat::Stdout);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user