forked from qt-creator/qt-creator
ProjectExplorer: Rework the build step run interface
Originally, the build manager used to run all build steps in a dedicated thread. Communication between the step and the manager happened via a QFutureInterface that was passed into the step's run() function. Later, new steps were added that operated asynchronously, so the build manager had to differentiate between the different kinds of steps for starting and stopping. These days, almost all build and deploy steps work asynchronously, which made the QFuture-based interface look increasingly odd. With this patch, all build steps are expected to work asynchronously, so the build manager no longer needs to differentiate. Steps are started and requested to stop via the run() and cancel() functions, respectively, and emit the finished() signal when they are done. Build step implementors no longer have to deal with a QFutureInterface. For steps whose implementation is inherently synchronous, the BuildStep base class offers a runInThread() function. Change-Id: If905c68b234c5a669f6e19f43142eaa57d594803 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -327,17 +327,18 @@ QString AndroidAvdManager::findAvd(const QString &avdName) const
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString AndroidAvdManager::waitForAvd(const QString &avdName, const QFutureInterface<bool> &fi) const
|
||||
QString AndroidAvdManager::waitForAvd(const QString &avdName,
|
||||
const std::function<bool()> &cancelChecker) const
|
||||
{
|
||||
// we cannot use adb -e wait-for-device, since that doesn't work if a emulator is already running
|
||||
// 60 rounds of 2s sleeping, two minutes for the avd to start
|
||||
QString serialNumber;
|
||||
for (int i = 0; i < 60; ++i) {
|
||||
if (fi.isCanceled())
|
||||
if (cancelChecker())
|
||||
return QString();
|
||||
serialNumber = findAvd(avdName);
|
||||
if (!serialNumber.isEmpty())
|
||||
return waitForBooted(serialNumber, fi) ? serialNumber : QString();
|
||||
return waitForBooted(serialNumber, cancelChecker) ? serialNumber : QString();
|
||||
QThread::sleep(2);
|
||||
}
|
||||
return QString();
|
||||
@@ -358,11 +359,12 @@ bool AndroidAvdManager::isAvdBooted(const QString &device) const
|
||||
return value == "stopped";
|
||||
}
|
||||
|
||||
bool AndroidAvdManager::waitForBooted(const QString &serialNumber, const QFutureInterface<bool> &fi) const
|
||||
bool AndroidAvdManager::waitForBooted(const QString &serialNumber,
|
||||
const std::function<bool()> &cancelChecker) const
|
||||
{
|
||||
// found a serial number, now wait until it's done booting...
|
||||
for (int i = 0; i < 60; ++i) {
|
||||
if (fi.isCanceled())
|
||||
if (cancelChecker())
|
||||
return false;
|
||||
if (isAvdBooted(serialNumber)) {
|
||||
return true;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "androidconfigurations.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace Android {
|
||||
@@ -51,11 +52,12 @@ public:
|
||||
bool startAvdAsync(const QString &avdName) const;
|
||||
QString findAvd(const QString &avdName) const;
|
||||
QString waitForAvd(const QString &avdName,
|
||||
const QFutureInterface<bool> &fi = QFutureInterface<bool>()) const;
|
||||
const std::function<bool()> &cancelChecker = {}) const;
|
||||
bool isAvdBooted(const QString &device) const;
|
||||
|
||||
private:
|
||||
bool waitForBooted(const QString &serialNumber, const QFutureInterface<bool> &fi) const;
|
||||
bool waitForBooted(const QString &serialNumber,
|
||||
const std::function<bool()> &cancelChecker) const;
|
||||
|
||||
private:
|
||||
const AndroidConfig &m_config;
|
||||
|
@@ -340,14 +340,14 @@ bool AndroidBuildApkStep::verifyCertificatePassword()
|
||||
return success;
|
||||
}
|
||||
|
||||
void AndroidBuildApkStep::run(QFutureInterface<bool> &fi)
|
||||
void AndroidBuildApkStep::doRun()
|
||||
{
|
||||
if (m_skipBuilding) {
|
||||
emit addOutput(tr("No application .pro file found, not building an APK."), BuildStep::OutputFormat::ErrorMessage);
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
return;
|
||||
}
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
void AndroidBuildApkStep::processStarted()
|
||||
|
@@ -86,7 +86,7 @@ private:
|
||||
bool verifyKeystorePassword();
|
||||
bool verifyCertificatePassword();
|
||||
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
void doRun() override;
|
||||
|
||||
bool m_signPackage = false;
|
||||
bool m_verbose = false;
|
||||
|
@@ -298,7 +298,7 @@ bool AndroidDeployQtStep::init()
|
||||
return true;
|
||||
}
|
||||
|
||||
AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy(QFutureInterface<bool> &fi)
|
||||
AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy()
|
||||
{
|
||||
QString args;
|
||||
if (m_useAndroiddeployqt) {
|
||||
@@ -386,7 +386,7 @@ AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy(QFutureInter
|
||||
if (m_process->state() == QProcess::NotRunning)
|
||||
break;
|
||||
|
||||
if (fi.isCanceled()) {
|
||||
if (isCanceled()) {
|
||||
m_process->kill();
|
||||
m_process->waitForFinished();
|
||||
}
|
||||
@@ -472,25 +472,23 @@ void AndroidDeployQtStep::slotSetSerialNumber(const QString &serialNumber)
|
||||
AndroidManager::setDeviceSerialNumber(target(), serialNumber);
|
||||
}
|
||||
|
||||
void AndroidDeployQtStep::run(QFutureInterface<bool> &fi)
|
||||
bool AndroidDeployQtStep::runImpl()
|
||||
{
|
||||
if (!m_avdName.isEmpty()) {
|
||||
QString serialNumber = AndroidAvdManager().waitForAvd(m_avdName, fi);
|
||||
QString serialNumber = AndroidAvdManager().waitForAvd(m_avdName, cancelChecker());
|
||||
qCDebug(deployStepLog) << "Deploying to AVD:" << m_avdName << serialNumber;
|
||||
if (serialNumber.isEmpty()) {
|
||||
reportRunResult(fi, false);
|
||||
return;
|
||||
}
|
||||
if (serialNumber.isEmpty())
|
||||
return false;
|
||||
m_serialNumber = serialNumber;
|
||||
emit setSerialNumber(serialNumber);
|
||||
}
|
||||
|
||||
DeployErrorCode returnValue = runDeploy(fi);
|
||||
DeployErrorCode returnValue = runDeploy();
|
||||
if (returnValue > DeployErrorCode::NoError && returnValue < DeployErrorCode::Failure) {
|
||||
emit askForUninstall(returnValue);
|
||||
if (m_askForUninstall) {
|
||||
m_uninstallPreviousPackageRun = true;
|
||||
returnValue = runDeploy(fi);
|
||||
returnValue = runDeploy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,7 +507,7 @@ void AndroidDeployQtStep::run(QFutureInterface<bool> &fi)
|
||||
}
|
||||
}
|
||||
|
||||
reportRunResult(fi, returnValue == NoError);
|
||||
return returnValue == NoError;
|
||||
}
|
||||
|
||||
void AndroidDeployQtStep::gatherFilesToPull()
|
||||
@@ -550,6 +548,11 @@ void AndroidDeployQtStep::gatherFilesToPull()
|
||||
qCDebug(deployStepLog) << itr.key() << "to" << itr.value();
|
||||
}
|
||||
|
||||
void AndroidDeployQtStep::doRun()
|
||||
{
|
||||
runInThread([this] { return runImpl(); });
|
||||
}
|
||||
|
||||
void AndroidDeployQtStep::runCommand(const QString &program, const QStringList &arguments)
|
||||
{
|
||||
Utils::SynchronousProcess buildProc;
|
||||
|
@@ -84,12 +84,14 @@ private:
|
||||
void runCommand(const QString &program, const QStringList &arguments);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
void doRun() override;
|
||||
void gatherFilesToPull();
|
||||
DeployErrorCode runDeploy(QFutureInterface<bool> &fi);
|
||||
DeployErrorCode runDeploy();
|
||||
void slotAskForUninstall(DeployErrorCode errorCode);
|
||||
void slotSetSerialNumber(const QString &serialNumber);
|
||||
|
||||
bool runImpl();
|
||||
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
void processReadyReadStdOutput(DeployErrorCode &errorCode);
|
||||
|
@@ -95,7 +95,7 @@ bool AndroidPackageInstallationStep::init()
|
||||
return AbstractProcessStep::init();
|
||||
}
|
||||
|
||||
void AndroidPackageInstallationStep::run(QFutureInterface<bool> &fi)
|
||||
void AndroidPackageInstallationStep::doRun()
|
||||
{
|
||||
QString error;
|
||||
foreach (const QString &dir, m_androidDirsToClean) {
|
||||
@@ -104,12 +104,12 @@ void AndroidPackageInstallationStep::run(QFutureInterface<bool> &fi)
|
||||
emit addOutput(tr("Removing directory %1").arg(dir), OutputFormat::NormalMessage);
|
||||
if (!FileUtils::removeRecursively(androidDir, &error)) {
|
||||
emit addOutput(error, OutputFormat::Stderr);
|
||||
reportRunResult(fi, false);
|
||||
emit finished(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *AndroidPackageInstallationStep::createConfigWidget()
|
||||
|
@@ -40,13 +40,13 @@ class ANDROID_EXPORT AndroidPackageInstallationStep : public ProjectExplorer::Ab
|
||||
|
||||
public:
|
||||
explicit AndroidPackageInstallationStep(ProjectExplorer::BuildStepList *bsl);
|
||||
bool init() override;
|
||||
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
|
||||
QStringList m_androidDirsToClean;
|
||||
};
|
||||
|
||||
|
@@ -86,7 +86,7 @@ bool AutogenStep::init()
|
||||
return AbstractProcessStep::init();
|
||||
}
|
||||
|
||||
void AutogenStep::run(QFutureInterface<bool> &fi)
|
||||
void AutogenStep::doRun()
|
||||
{
|
||||
BuildConfiguration *bc = buildConfiguration();
|
||||
|
||||
@@ -104,12 +104,12 @@ void AutogenStep::run(QFutureInterface<bool> &fi)
|
||||
|
||||
if (!m_runAutogen) {
|
||||
emit addOutput(tr("Configuration unchanged, skipping autogen step."), BuildStep::OutputFormat::NormalMessage);
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_runAutogen = false;
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *AutogenStep::createConfigWidget()
|
||||
|
@@ -66,11 +66,12 @@ class AutogenStep : public ProjectExplorer::AbstractProcessStep
|
||||
public:
|
||||
explicit AutogenStep(ProjectExplorer::BuildStepList *bsl);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
|
||||
ProjectExplorer::BaseStringAspect *m_additionalArgumentsAspect = nullptr;
|
||||
bool m_runAutogen = false;
|
||||
};
|
||||
|
@@ -84,7 +84,7 @@ bool AutoreconfStep::init()
|
||||
return AbstractProcessStep::init();
|
||||
}
|
||||
|
||||
void AutoreconfStep::run(QFutureInterface<bool> &fi)
|
||||
void AutoreconfStep::doRun()
|
||||
{
|
||||
BuildConfiguration *bc = buildConfiguration();
|
||||
|
||||
@@ -96,12 +96,12 @@ void AutoreconfStep::run(QFutureInterface<bool> &fi)
|
||||
|
||||
if (!m_runAutoreconf) {
|
||||
emit addOutput(tr("Configuration unchanged, skipping autoreconf step."), BuildStep::OutputFormat::NormalMessage);
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_runAutoreconf = false;
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *AutoreconfStep::createConfigWidget()
|
||||
|
@@ -67,7 +67,7 @@ public:
|
||||
explicit AutoreconfStep(ProjectExplorer::BuildStepList *bsl);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
void doRun() override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
private:
|
||||
|
@@ -105,7 +105,7 @@ bool ConfigureStep::init()
|
||||
return AbstractProcessStep::init();
|
||||
}
|
||||
|
||||
void ConfigureStep::run(QFutureInterface<bool>& fi)
|
||||
void ConfigureStep::doRun()
|
||||
{
|
||||
BuildConfiguration *bc = buildConfiguration();
|
||||
|
||||
@@ -121,12 +121,12 @@ void ConfigureStep::run(QFutureInterface<bool>& fi)
|
||||
|
||||
if (!m_runConfigure) {
|
||||
emit addOutput(tr("Configuration unchanged, skipping configure step."), BuildStep::OutputFormat::NormalMessage);
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_runConfigure = false;
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *ConfigureStep::createConfigWidget()
|
||||
|
@@ -67,14 +67,15 @@ class ConfigureStep : public ProjectExplorer::AbstractProcessStep
|
||||
public:
|
||||
explicit ConfigureStep(ProjectExplorer::BuildStepList *bsl);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
void setAdditionalArguments(const QString &list);
|
||||
void notifyBuildDirectoryChanged();
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
|
||||
void updateDetails();
|
||||
|
||||
ProjectExplorer::BaseStringAspect *m_additionalArgumentsAspect = nullptr;
|
||||
|
@@ -66,12 +66,11 @@ BareMetalGdbCommandsDeployStep::BareMetalGdbCommandsDeployStep(BuildStepList *bs
|
||||
: BuildStep(bsl, stepId())
|
||||
{
|
||||
setDefaultDisplayName(displayName());
|
||||
setRunInGuiThread(true);
|
||||
}
|
||||
|
||||
void BareMetalGdbCommandsDeployStep::run(QFutureInterface<bool> &fi)
|
||||
void BareMetalGdbCommandsDeployStep::doRun()
|
||||
{
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
}
|
||||
|
||||
bool BareMetalGdbCommandsDeployStep::fromMap(const QVariantMap &map)
|
||||
|
@@ -40,9 +40,6 @@ class BareMetalGdbCommandsDeployStep : public ProjectExplorer::BuildStep
|
||||
public:
|
||||
explicit BareMetalGdbCommandsDeployStep(ProjectExplorer::BuildStepList *bsl);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
@@ -55,6 +52,9 @@ public:
|
||||
QString gdbCommands() const;
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
|
||||
QString m_gdbCommands;
|
||||
};
|
||||
|
||||
|
@@ -233,46 +233,47 @@ bool CMakeBuildStep::init()
|
||||
return AbstractProcessStep::init();
|
||||
}
|
||||
|
||||
void CMakeBuildStep::run(QFutureInterface<bool> &fi)
|
||||
void CMakeBuildStep::doRun()
|
||||
{
|
||||
// Make sure CMake state was written to disk before trying to build:
|
||||
CMakeBuildConfiguration *bc = cmakeBuildConfiguration();
|
||||
QTC_ASSERT(bc, return);
|
||||
|
||||
bool mustDelay = false;
|
||||
m_waiting = false;
|
||||
auto p = static_cast<CMakeProject *>(bc->project());
|
||||
if (p->persistCMakeState()) {
|
||||
emit addOutput(tr("Persisting CMake state..."), BuildStep::OutputFormat::NormalMessage);
|
||||
mustDelay = true;
|
||||
m_waiting = true;
|
||||
} else if (p->mustUpdateCMakeStateBeforeBuild()) {
|
||||
emit addOutput(tr("Running CMake in preparation to build..."), BuildStep::OutputFormat::NormalMessage);
|
||||
mustDelay = true;
|
||||
} else {
|
||||
mustDelay = false;
|
||||
m_waiting = true;
|
||||
}
|
||||
|
||||
if (mustDelay) {
|
||||
if (m_waiting) {
|
||||
m_runTrigger = connect(project(), &Project::parsingFinished,
|
||||
this, [this, &fi](bool success) { handleProjectWasParsed(fi, success); });
|
||||
this, [this](bool success) { handleProjectWasParsed(success); });
|
||||
} else {
|
||||
runImpl(fi);
|
||||
runImpl();
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeBuildStep::runImpl(QFutureInterface<bool> &fi)
|
||||
void CMakeBuildStep::runImpl()
|
||||
{
|
||||
// Do the actual build:
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
void CMakeBuildStep::handleProjectWasParsed(QFutureInterface<bool> &fi, bool success)
|
||||
void CMakeBuildStep::handleProjectWasParsed(bool success)
|
||||
{
|
||||
m_waiting = false;
|
||||
disconnect(m_runTrigger);
|
||||
if (success) {
|
||||
runImpl(fi);
|
||||
if (isCanceled()) {
|
||||
emit finished(false);
|
||||
} else if (success) {
|
||||
runImpl();
|
||||
} else {
|
||||
AbstractProcessStep::stdError(tr("Project did not parse successfully, cannot build."));
|
||||
reportRunResult(fi, false);
|
||||
emit finished(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +289,7 @@ void CMakeBuildStep::stdOutput(const QString &line)
|
||||
bool ok = false;
|
||||
int percent = m_percentProgress.cap(1).toInt(&ok);
|
||||
if (ok)
|
||||
futureInterface()->setProgressValue(percent);
|
||||
emit progress(percent, QString());
|
||||
return;
|
||||
} else if (m_ninjaProgress.indexIn(line) != -1) {
|
||||
AbstractProcessStep::stdOutput(line);
|
||||
@@ -299,7 +300,7 @@ void CMakeBuildStep::stdOutput(const QString &line)
|
||||
int all = m_ninjaProgress.cap(2).toInt(&ok);
|
||||
if (ok && all != 0) {
|
||||
const int percent = static_cast<int>(100.0 * done/all);
|
||||
futureInterface()->setProgressValue(percent);
|
||||
emit progress(percent, QString());
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -551,12 +552,11 @@ CMakeBuildStepFactory::CMakeBuildStepFactory()
|
||||
void CMakeBuildStep::processStarted()
|
||||
{
|
||||
m_useNinja = false;
|
||||
futureInterface()->setProgressRange(0, 100);
|
||||
AbstractProcessStep::processStarted();
|
||||
}
|
||||
|
||||
void CMakeBuildStep::processFinished(int exitCode, QProcess::ExitStatus status)
|
||||
{
|
||||
AbstractProcessStep::processFinished(exitCode, status);
|
||||
futureInterface()->setProgressValue(100);
|
||||
emit progress(100, QString());
|
||||
}
|
||||
|
@@ -56,11 +56,6 @@ public:
|
||||
|
||||
CMakeBuildConfiguration *cmakeBuildConfiguration() const;
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
QString buildTarget() const;
|
||||
bool buildsBuildTarget(const QString &target) const;
|
||||
void setBuildTarget(const QString &target);
|
||||
@@ -98,8 +93,12 @@ protected:
|
||||
private:
|
||||
void ctor(ProjectExplorer::BuildStepList *bsl);
|
||||
|
||||
void runImpl(QFutureInterface<bool> &fi);
|
||||
void handleProjectWasParsed(QFutureInterface<bool> &fi, bool success);
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
void runImpl();
|
||||
void handleProjectWasParsed(bool success);
|
||||
|
||||
void handleBuildTargetChanges(bool success);
|
||||
CMakeRunConfiguration *targetsActiveRunConfiguration() const;
|
||||
@@ -112,6 +111,7 @@ private:
|
||||
QString m_buildTarget;
|
||||
QString m_toolArguments;
|
||||
bool m_useNinja = false;
|
||||
bool m_waiting = false;
|
||||
};
|
||||
|
||||
class CMakeBuildStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget
|
||||
|
@@ -169,9 +169,9 @@ QString IosBuildStep::buildCommand() const
|
||||
return QString("xcodebuild"); // add path?
|
||||
}
|
||||
|
||||
void IosBuildStep::run(QFutureInterface<bool> &fi)
|
||||
void IosBuildStep::doRun()
|
||||
{
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *IosBuildStep::createConfigWidget()
|
||||
|
@@ -48,9 +48,6 @@ class IosBuildStep : public ProjectExplorer::AbstractProcessStep
|
||||
public:
|
||||
explicit IosBuildStep(ProjectExplorer::BuildStepList *parent);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
void setBaseArguments(const QStringList &args);
|
||||
void setExtraArguments(const QStringList &extraArgs);
|
||||
@@ -60,6 +57,8 @@ public:
|
||||
QString buildCommand() const;
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
|
@@ -58,7 +58,6 @@ IosDeployStep::IosDeployStep(BuildStepList *parent)
|
||||
: BuildStep(parent, stepId())
|
||||
{
|
||||
setImmutable(true);
|
||||
setRunInGuiThread(true);
|
||||
updateDisplayNames();
|
||||
connect(DeviceManager::instance(), &DeviceManager::updated,
|
||||
this, &IosDeployStep::updateDisplayNames);
|
||||
@@ -101,22 +100,19 @@ bool IosDeployStep::init()
|
||||
return true;
|
||||
}
|
||||
|
||||
void IosDeployStep::run(QFutureInterface<bool> &fi)
|
||||
void IosDeployStep::doRun()
|
||||
{
|
||||
m_futureInterface = fi;
|
||||
QTC_CHECK(m_transferStatus == NoTransfer);
|
||||
if (device().isNull()) {
|
||||
TaskHub::addTask(Task::Error, tr("Deployment failed. No iOS device found."),
|
||||
ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
|
||||
reportRunResult(m_futureInterface, !iossimulator().isNull());
|
||||
emit finished(!iossimulator().isNull());
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
m_toolHandler = new IosToolHandler(m_deviceType, this);
|
||||
m_transferStatus = TransferInProgress;
|
||||
m_futureInterface.setProgressRange(0, 200);
|
||||
m_futureInterface.setProgressValueAndText(0, QLatin1String("Transferring application"));
|
||||
m_futureInterface.reportStarted();
|
||||
emit progress(0, tr("Transferring application"));
|
||||
connect(m_toolHandler, &IosToolHandler::isTransferringApp,
|
||||
this, &IosDeployStep::handleIsTransferringApp);
|
||||
connect(m_toolHandler, &IosToolHandler::didTransferApp,
|
||||
@@ -129,7 +125,7 @@ void IosDeployStep::run(QFutureInterface<bool> &fi)
|
||||
m_toolHandler->requestTransferApp(appBundle(), m_deviceType.identifier);
|
||||
}
|
||||
|
||||
void IosDeployStep::cancel()
|
||||
void IosDeployStep::doCancel()
|
||||
{
|
||||
if (m_toolHandler)
|
||||
m_toolHandler->stop();
|
||||
@@ -150,8 +146,7 @@ void IosDeployStep::handleIsTransferringApp(IosToolHandler *handler, const QStri
|
||||
{
|
||||
Q_UNUSED(handler); Q_UNUSED(bundlePath); Q_UNUSED(deviceId);
|
||||
QTC_CHECK(m_transferStatus == TransferInProgress);
|
||||
m_futureInterface.setProgressRange(0, maxProgress);
|
||||
m_futureInterface.setProgressValueAndText(progress, info);
|
||||
emit this->progress(progress * 100 / maxProgress, info);
|
||||
}
|
||||
|
||||
void IosDeployStep::handleDidTransferApp(IosToolHandler *handler, const QString &bundlePath,
|
||||
@@ -168,7 +163,7 @@ void IosDeployStep::handleDidTransferApp(IosToolHandler *handler, const QString
|
||||
tr("Deployment failed. The settings in the Devices window of Xcode might be incorrect."),
|
||||
ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
|
||||
}
|
||||
reportRunResult(m_futureInterface, status == IosToolHandler::Success);
|
||||
emit finished(status == IosToolHandler::Success);
|
||||
}
|
||||
|
||||
void IosDeployStep::handleFinished(IosToolHandler *handler)
|
||||
@@ -178,7 +173,7 @@ void IosDeployStep::handleFinished(IosToolHandler *handler)
|
||||
m_transferStatus = TransferFailed;
|
||||
TaskHub::addTask(Task::Error, tr("Deployment failed."),
|
||||
ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
|
||||
reportRunResult(m_futureInterface, false);
|
||||
emit finished(false);
|
||||
break;
|
||||
case NoTransfer:
|
||||
case TransferOk:
|
||||
|
@@ -32,7 +32,6 @@
|
||||
#include <projectexplorer/buildstep.h>
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
|
||||
#include <QFutureInterface>
|
||||
#include <QProcess>
|
||||
|
||||
namespace Ios {
|
||||
@@ -54,14 +53,13 @@ public:
|
||||
explicit IosDeployStep(ProjectExplorer::BuildStepList *bc);
|
||||
static Core::Id stepId();
|
||||
|
||||
void cleanup();
|
||||
private:
|
||||
void doRun() override;
|
||||
void doCancel() override;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
void cleanup();
|
||||
void cancel() override;
|
||||
|
||||
private:
|
||||
void handleIsTransferringApp(Ios::IosToolHandler *handler, const QString &bundlePath,
|
||||
const QString &deviceId, int progress, int maxProgress,
|
||||
const QString &info);
|
||||
@@ -85,7 +83,6 @@ private:
|
||||
|
||||
TransferStatus m_transferStatus = NoTransfer;
|
||||
IosToolHandler *m_toolHandler = nullptr;
|
||||
QFutureInterface<bool> m_futureInterface;
|
||||
ProjectExplorer::IDevice::ConstPtr m_device;
|
||||
QString m_bundlePath;
|
||||
IosDeviceType m_deviceType;
|
||||
|
@@ -187,9 +187,9 @@ bool IosDsymBuildStep::isDefault() const
|
||||
return arguments() == defaultArguments() && command() == defaultCommand();
|
||||
}
|
||||
|
||||
void IosDsymBuildStep::run(QFutureInterface<bool> &fi)
|
||||
void IosDsymBuildStep::doRun()
|
||||
{
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *IosDsymBuildStep::createConfigWidget()
|
||||
|
@@ -42,9 +42,6 @@ class IosDsymBuildStep : public ProjectExplorer::AbstractProcessStep
|
||||
public:
|
||||
IosDsymBuildStep(ProjectExplorer::BuildStepList *parent);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
void setArguments(const QStringList &args);
|
||||
QStringList arguments() const;
|
||||
@@ -54,10 +51,12 @@ public:
|
||||
void setCommand(const QString &command);
|
||||
bool isDefault() const;
|
||||
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
QVariantMap toMap() const override;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
|
||||
QStringList defaultCleanCmdList() const;
|
||||
QStringList defaultCmdList() const;
|
||||
|
||||
|
@@ -61,28 +61,33 @@ bool NimCompilerCleanStep::init()
|
||||
return result;
|
||||
}
|
||||
|
||||
void NimCompilerCleanStep::run(QFutureInterface<bool> &fi)
|
||||
void NimCompilerCleanStep::doRun()
|
||||
{
|
||||
if (!m_buildDir.exists()) {
|
||||
emit addOutput(tr("Build directory \"%1\" does not exist.").arg(m_buildDir.toUserOutput()), BuildStep::OutputFormat::ErrorMessage);
|
||||
reportRunResult(fi, false);
|
||||
emit finished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!removeCacheDirectory()) {
|
||||
emit addOutput(tr("Failed to delete the cache directory."), BuildStep::OutputFormat::ErrorMessage);
|
||||
reportRunResult(fi, false);
|
||||
emit finished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!removeOutFilePath()) {
|
||||
emit addOutput(tr("Failed to delete the out file."), BuildStep::OutputFormat::ErrorMessage);
|
||||
reportRunResult(fi, false);
|
||||
emit finished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
emit addOutput(tr("Clean step completed successfully."), BuildStep::OutputFormat::NormalMessage);
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
}
|
||||
|
||||
void NimCompilerCleanStep::doCancel()
|
||||
{
|
||||
// Can be left empty. The run() function hardly does anything.
|
||||
}
|
||||
|
||||
bool NimCompilerCleanStep::removeCacheDirectory()
|
||||
|
@@ -39,10 +39,12 @@ public:
|
||||
NimCompilerCleanStep(ProjectExplorer::BuildStepList *parentList);
|
||||
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
void doCancel() override;
|
||||
|
||||
bool removeCacheDirectory();
|
||||
bool removeOutFilePath();
|
||||
|
||||
|
@@ -104,7 +104,6 @@ public:
|
||||
Private(AbstractProcessStep *q) : q(q) {}
|
||||
|
||||
AbstractProcessStep *q;
|
||||
QFutureInterface<bool> *m_futureInterface = nullptr;
|
||||
std::unique_ptr<Utils::QtcProcess> m_process;
|
||||
std::unique_ptr<IOutputParser> m_outputParserChain;
|
||||
ProcessParameters m_param;
|
||||
@@ -125,7 +124,6 @@ AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl, Core::Id id) :
|
||||
BuildStep(bsl, id),
|
||||
d(new Private(this))
|
||||
{
|
||||
setRunInGuiThread(true);
|
||||
}
|
||||
|
||||
AbstractProcessStep::~AbstractProcessStep()
|
||||
@@ -209,7 +207,7 @@ bool AbstractProcessStep::init()
|
||||
YourBuildStep::run().
|
||||
*/
|
||||
|
||||
void AbstractProcessStep::run(QFutureInterface<bool> &fi)
|
||||
void AbstractProcessStep::doRun()
|
||||
{
|
||||
QDir wd(d->m_param.effectiveWorkingDirectory());
|
||||
if (!wd.exists()) {
|
||||
@@ -217,7 +215,7 @@ void AbstractProcessStep::run(QFutureInterface<bool> &fi)
|
||||
emit addOutput(tr("Could not create directory \"%1\"")
|
||||
.arg(QDir::toNativeSeparators(wd.absolutePath())),
|
||||
BuildStep::OutputFormat::ErrorMessage);
|
||||
reportRunResult(fi, false);
|
||||
finish(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -225,12 +223,10 @@ void AbstractProcessStep::run(QFutureInterface<bool> &fi)
|
||||
QString effectiveCommand = d->m_param.effectiveCommand();
|
||||
if (!QFileInfo::exists(effectiveCommand)) {
|
||||
processStartupFailed();
|
||||
reportRunResult(fi, false);
|
||||
finish(false);
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_futureInterface = &fi;
|
||||
|
||||
d->m_process.reset(new Utils::QtcProcess());
|
||||
d->m_process->setUseCtrlCStub(Utils::HostOsInfo::isWindowsHost());
|
||||
d->m_process->setWorkingDirectory(wd.absolutePath());
|
||||
@@ -249,13 +245,13 @@ void AbstractProcessStep::run(QFutureInterface<bool> &fi)
|
||||
processStartupFailed();
|
||||
d->m_process.reset();
|
||||
d->m_outputParserChain.reset();
|
||||
reportRunResult(fi, false);
|
||||
finish(false);
|
||||
return;
|
||||
}
|
||||
processStarted();
|
||||
}
|
||||
|
||||
void AbstractProcessStep::cancel()
|
||||
void AbstractProcessStep::doCancel()
|
||||
{
|
||||
Core::Reaper::reap(d->m_process.release());
|
||||
}
|
||||
@@ -275,7 +271,7 @@ void AbstractProcessStep::cleanUp(QProcess *process)
|
||||
d->m_process.reset();
|
||||
|
||||
// Report result
|
||||
reportRunResult(*d->m_futureInterface, returnValue);
|
||||
finish(returnValue);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -420,9 +416,9 @@ void AbstractProcessStep::stdError(const QString &line)
|
||||
emit addOutput(line, BuildStep::OutputFormat::Stderr, BuildStep::DontAppendNewline);
|
||||
}
|
||||
|
||||
QFutureInterface<bool> *AbstractProcessStep::futureInterface() const
|
||||
void AbstractProcessStep::finish(bool success)
|
||||
{
|
||||
return d->m_futureInterface;
|
||||
emit finished(success);
|
||||
}
|
||||
|
||||
void AbstractProcessStep::taskAdded(const Task &task, int linkedOutputLines, int skipLines)
|
||||
|
@@ -41,10 +41,6 @@ class PROJECTEXPLORER_EXPORT AbstractProcessStep : public BuildStep
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &) override;
|
||||
void cancel() override;
|
||||
|
||||
ProcessParameters *processParameters();
|
||||
|
||||
bool ignoreReturnValue();
|
||||
@@ -59,6 +55,8 @@ public:
|
||||
protected:
|
||||
AbstractProcessStep(BuildStepList *bsl, Core::Id id);
|
||||
~AbstractProcessStep() override;
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
|
||||
virtual void processStarted();
|
||||
virtual void processFinished(int exitCode, QProcess::ExitStatus status);
|
||||
@@ -67,9 +65,11 @@ protected:
|
||||
virtual void stdOutput(const QString &line);
|
||||
virtual void stdError(const QString &line);
|
||||
|
||||
QFutureInterface<bool> *futureInterface() const;
|
||||
void doCancel() override;
|
||||
|
||||
private:
|
||||
virtual void finish(bool success);
|
||||
|
||||
void processReadyReadStdOutput();
|
||||
void processReadyReadStdError();
|
||||
void slotProcessFinished(int, QProcess::ExitStatus);
|
||||
|
@@ -79,9 +79,8 @@ public:
|
||||
// is set to true while canceling, so that nextBuildStep knows that the BuildStep finished because of canceling
|
||||
bool m_skipDisabled = false;
|
||||
bool m_canceling = false;
|
||||
QFutureWatcher<bool> m_watcher;
|
||||
QFutureInterface<bool> m_futureInterfaceForAysnc;
|
||||
BuildStep *m_currentBuildStep;
|
||||
bool m_lastStepSucceeded = true;
|
||||
BuildStep *m_currentBuildStep = nullptr;
|
||||
QString m_currentConfiguration;
|
||||
// used to decide if we are building a project to decide when to emit buildStateChanged(Project *)
|
||||
QHash<Project *, int> m_activeBuildSteps;
|
||||
@@ -107,16 +106,6 @@ BuildManager::BuildManager(QObject *parent, QAction *cancelBuildAction)
|
||||
m_instance = this;
|
||||
d = new BuildManagerPrivate;
|
||||
|
||||
connect(&d->m_watcher, &QFutureWatcherBase::finished,
|
||||
this, &BuildManager::nextBuildQueue, Qt::QueuedConnection);
|
||||
|
||||
connect(&d->m_watcher, &QFutureWatcherBase::progressValueChanged,
|
||||
this, &BuildManager::progressChanged);
|
||||
connect(&d->m_watcher, &QFutureWatcherBase::progressTextChanged,
|
||||
this, &BuildManager::progressTextChanged);
|
||||
connect(&d->m_watcher, &QFutureWatcherBase::progressRangeChanged,
|
||||
this, &BuildManager::progressChanged);
|
||||
|
||||
connect(SessionManager::instance(), &SessionManager::aboutToRemoveProject,
|
||||
this, &BuildManager::aboutToRemoveProject);
|
||||
|
||||
@@ -203,14 +192,9 @@ void BuildManager::cancel()
|
||||
if (d->m_canceling)
|
||||
return;
|
||||
d->m_canceling = true;
|
||||
d->m_watcher.cancel();
|
||||
if (d->m_currentBuildStep->runInGuiThread()) {
|
||||
d->m_currentBuildStep->cancel();
|
||||
while (d->m_canceling)
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
} else {
|
||||
d->m_watcher.waitForFinished();
|
||||
}
|
||||
d->m_currentBuildStep->cancel();
|
||||
while (d->m_canceling)
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); // TODO: Is this really necessary?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,8 +336,6 @@ void BuildManager::addToOutputWindow(const QString &string, BuildStep::OutputFor
|
||||
|
||||
void BuildManager::nextBuildQueue()
|
||||
{
|
||||
d->m_futureInterfaceForAysnc = QFutureInterface<bool>();
|
||||
|
||||
d->m_outputWindow->flush();
|
||||
if (d->m_canceling) {
|
||||
d->m_canceling = false;
|
||||
@@ -375,7 +357,7 @@ void BuildManager::nextBuildQueue()
|
||||
d->m_progressFutureInterface->setProgressValueAndText(d->m_progress*100, msgProgress(d->m_progress, d->m_maxProgress));
|
||||
decrementActiveBuildSteps(d->m_currentBuildStep);
|
||||
|
||||
const bool success = d->m_skipDisabled || d->m_watcher.result();
|
||||
const bool success = d->m_skipDisabled || d->m_lastStepSucceeded;
|
||||
if (success) {
|
||||
nextStep();
|
||||
} else {
|
||||
@@ -397,28 +379,10 @@ void BuildManager::nextBuildQueue()
|
||||
}
|
||||
}
|
||||
|
||||
void BuildManager::progressChanged()
|
||||
void BuildManager::progressChanged(int percent, const QString &text)
|
||||
{
|
||||
if (!d->m_progressFutureInterface)
|
||||
return;
|
||||
int range = d->m_watcher.progressMaximum() - d->m_watcher.progressMinimum();
|
||||
if (range != 0) {
|
||||
int percent = (d->m_watcher.progressValue() - d->m_watcher.progressMinimum()) * 100 / range;
|
||||
d->m_progressFutureInterface->setProgressValueAndText(d->m_progress * 100 + percent, msgProgress(d->m_progress, d->m_maxProgress)
|
||||
+ QLatin1Char('\n') + d->m_watcher.progressText());
|
||||
}
|
||||
}
|
||||
|
||||
void BuildManager::progressTextChanged()
|
||||
{
|
||||
if (!d->m_progressFutureInterface)
|
||||
return;
|
||||
int range = d->m_watcher.progressMaximum() - d->m_watcher.progressMinimum();
|
||||
int percent = 0;
|
||||
if (range != 0)
|
||||
percent = (d->m_watcher.progressValue() - d->m_watcher.progressMinimum()) * 100 / range;
|
||||
d->m_progressFutureInterface->setProgressValueAndText(d->m_progress*100 + percent, msgProgress(d->m_progress, d->m_maxProgress) +
|
||||
QLatin1Char('\n') + d->m_watcher.progressText());
|
||||
if (d->m_progressFutureInterface)
|
||||
d->m_progressFutureInterface->setProgressValueAndText(percent, text);
|
||||
}
|
||||
|
||||
void BuildManager::nextStep()
|
||||
@@ -445,12 +409,16 @@ void BuildManager::nextStep()
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->m_currentBuildStep->runInGuiThread()) {
|
||||
d->m_watcher.setFuture(d->m_futureInterfaceForAysnc.future());
|
||||
d->m_currentBuildStep->run(d->m_futureInterfaceForAysnc);
|
||||
} else {
|
||||
d->m_watcher.setFuture(Utils::runAsync(&BuildStep::run, d->m_currentBuildStep));
|
||||
}
|
||||
static const auto finishedHandler = [](bool success) {
|
||||
d->m_lastStepSucceeded = success;
|
||||
disconnect(d->m_currentBuildStep, nullptr, instance(), nullptr);
|
||||
BuildManager::nextBuildQueue();
|
||||
};
|
||||
connect(d->m_currentBuildStep, &BuildStep::finished, instance(), finishedHandler,
|
||||
Qt::QueuedConnection);
|
||||
connect(d->m_currentBuildStep, &BuildStep::progress,
|
||||
instance(), &BuildManager::progressChanged);
|
||||
d->m_currentBuildStep->run();
|
||||
} else {
|
||||
d->m_running = false;
|
||||
d->m_previousBuildStepProject = nullptr;
|
||||
|
@@ -85,8 +85,7 @@ private:
|
||||
BuildStep::OutputNewlineSetting newlineSettings = BuildStep::DoAppendNewline);
|
||||
|
||||
static void nextBuildQueue();
|
||||
static void progressChanged();
|
||||
static void progressTextChanged();
|
||||
static void progressChanged(int percent, const QString &text);
|
||||
static void emitCancelMessage();
|
||||
static void showBuildResults();
|
||||
static void updateTaskCount();
|
||||
|
@@ -34,8 +34,11 @@
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/runextensions.h>
|
||||
|
||||
#include <QFormLayout>
|
||||
#include <QFutureWatcher>
|
||||
#include <QPointer>
|
||||
|
||||
/*!
|
||||
\class ProjectExplorer::BuildStep
|
||||
@@ -127,6 +130,18 @@ BuildStep::BuildStep(BuildStepList *bsl, Core::Id id) :
|
||||
expander->registerSubProvider([this] { return projectConfiguration()->macroExpander(); });
|
||||
}
|
||||
|
||||
void BuildStep::run()
|
||||
{
|
||||
m_cancelFlag = false;
|
||||
doRun();
|
||||
}
|
||||
|
||||
void BuildStep::cancel()
|
||||
{
|
||||
m_cancelFlag = true;
|
||||
doCancel();
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *BuildStep::createConfigWidget()
|
||||
{
|
||||
auto widget = new BuildStepConfigWidget(this);
|
||||
@@ -218,25 +233,32 @@ void BuildStep::setWidgetExpandedByDefault(bool widgetExpandedByDefault)
|
||||
immutable steps are run. The default implementation returns \c false.
|
||||
*/
|
||||
|
||||
bool BuildStep::runInGuiThread() const
|
||||
void BuildStep::runInThread(const std::function<bool()> &syncImpl)
|
||||
{
|
||||
return m_runInGuiThread;
|
||||
m_runInGuiThread = false;
|
||||
m_cancelFlag = false;
|
||||
auto * const watcher = new QFutureWatcher<bool>(this);
|
||||
connect(watcher, &QFutureWatcher<bool>::finished, this, [this, watcher] {
|
||||
emit finished(watcher->result());
|
||||
watcher->deleteLater();
|
||||
});
|
||||
watcher->setFuture(Utils::runAsync(syncImpl));
|
||||
}
|
||||
|
||||
void BuildStep::setRunInGuiThread(bool runInGuiThread)
|
||||
std::function<bool ()> BuildStep::cancelChecker() const
|
||||
{
|
||||
m_runInGuiThread = runInGuiThread;
|
||||
return [step = QPointer<const BuildStep>(this)] { return step && step->isCanceled(); };
|
||||
}
|
||||
|
||||
/*!
|
||||
This function needs to be reimplemented only for build steps that return
|
||||
\c false from runInGuiThread().
|
||||
|
||||
\sa runInGuiThread()
|
||||
*/
|
||||
void BuildStep::cancel()
|
||||
bool BuildStep::isCanceled() const
|
||||
{
|
||||
// Do nothing
|
||||
return m_cancelFlag;
|
||||
}
|
||||
|
||||
void BuildStep::doCancel()
|
||||
{
|
||||
QTC_ASSERT(!m_runInGuiThread, qWarning() << "Build step" << displayName()
|
||||
<< "neeeds to implement the doCancel() function");
|
||||
}
|
||||
|
||||
void BuildStep::setEnabled(bool b)
|
||||
|
@@ -33,6 +33,9 @@
|
||||
#include <QFutureInterface>
|
||||
#include <QWidget>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
class BuildConfiguration;
|
||||
@@ -54,11 +57,10 @@ protected:
|
||||
|
||||
public:
|
||||
virtual bool init() = 0;
|
||||
virtual void run(QFutureInterface<bool> &fi) = 0;
|
||||
void run();
|
||||
void cancel();
|
||||
virtual BuildStepConfigWidget *createConfigWidget();
|
||||
|
||||
virtual void cancel();
|
||||
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
@@ -88,9 +90,6 @@ public:
|
||||
bool isImmutable() const { return m_immutable; }
|
||||
void setImmutable(bool immutable) { m_immutable = immutable; }
|
||||
|
||||
bool runInGuiThread() const;
|
||||
void setRunInGuiThread(bool runInGuiThread);
|
||||
|
||||
signals:
|
||||
/// Adds a \p task to the Issues pane.
|
||||
/// Do note that for linking compile output with tasks, you should first emit the task
|
||||
@@ -104,11 +103,24 @@ signals:
|
||||
|
||||
void enabledChanged();
|
||||
|
||||
void progress(int percentage, const QString &message);
|
||||
void finished(bool result);
|
||||
|
||||
protected:
|
||||
void runInThread(const std::function<bool()> &syncImpl);
|
||||
|
||||
std::function<bool()> cancelChecker() const;
|
||||
bool isCanceled() const;
|
||||
|
||||
private:
|
||||
virtual void doRun() = 0;
|
||||
virtual void doCancel();
|
||||
|
||||
std::atomic_bool m_cancelFlag;
|
||||
bool m_enabled = true;
|
||||
bool m_immutable = false;
|
||||
bool m_widgetExpandedByDefault = true;
|
||||
bool m_runInGuiThread = false;
|
||||
bool m_runInGuiThread = true;
|
||||
};
|
||||
|
||||
class PROJECTEXPLORER_EXPORT BuildStepInfo
|
||||
|
@@ -77,9 +77,9 @@ bool DeviceCheckBuildStep::init()
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceCheckBuildStep::run(QFutureInterface<bool> &fi)
|
||||
void DeviceCheckBuildStep::doRun()
|
||||
{
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
}
|
||||
|
||||
Core::Id DeviceCheckBuildStep::stepId()
|
||||
|
@@ -39,7 +39,7 @@ public:
|
||||
explicit DeviceCheckBuildStep(BuildStepList *bsl);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
void doRun() override;
|
||||
|
||||
static Core::Id stepId();
|
||||
static QString displayName();
|
||||
|
@@ -71,9 +71,9 @@ bool ProcessStep::init()
|
||||
return AbstractProcessStep::init();
|
||||
}
|
||||
|
||||
void ProcessStep::run(QFutureInterface<bool> & fi)
|
||||
void ProcessStep::doRun()
|
||||
{
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *ProcessStep::createConfigWidget()
|
||||
|
@@ -45,9 +45,6 @@ class ProcessStep : public AbstractProcessStep
|
||||
public:
|
||||
explicit ProcessStep(BuildStepList *bsl);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &) override;
|
||||
|
||||
BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
QString command() const;
|
||||
@@ -58,9 +55,10 @@ public:
|
||||
void setArguments(const QString &arguments);
|
||||
void setWorkingDirectory(const QString &workingDirectory);
|
||||
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
QVariantMap toMap() const override;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
|
||||
QString m_command;
|
||||
|
@@ -127,14 +127,13 @@ QbsBuildStep::QbsBuildStep(ProjectExplorer::BuildStepList *bsl) :
|
||||
{
|
||||
setDisplayName(tr("Qbs Build"));
|
||||
setQbsConfiguration(QVariantMap());
|
||||
setRunInGuiThread(true);
|
||||
|
||||
// setQbsConfiguration(other->qbsConfiguration(PreserveVariables));
|
||||
}
|
||||
|
||||
QbsBuildStep::~QbsBuildStep()
|
||||
{
|
||||
cancel();
|
||||
doCancel();
|
||||
if (m_job) {
|
||||
m_job->deleteLater();
|
||||
m_job = nullptr;
|
||||
@@ -171,10 +170,8 @@ bool QbsBuildStep::init()
|
||||
return true;
|
||||
}
|
||||
|
||||
void QbsBuildStep::run(QFutureInterface<bool> &fi)
|
||||
void QbsBuildStep::doRun()
|
||||
{
|
||||
m_fi = &fi;
|
||||
|
||||
// We need a pre-build parsing step in order not to lose project file changes done
|
||||
// right before building (but before the delay has elapsed).
|
||||
parseProject();
|
||||
@@ -185,7 +182,7 @@ ProjectExplorer::BuildStepConfigWidget *QbsBuildStep::createConfigWidget()
|
||||
return new QbsBuildStepConfigWidget(this);
|
||||
}
|
||||
|
||||
void QbsBuildStep::cancel()
|
||||
void QbsBuildStep::doCancel()
|
||||
{
|
||||
if (m_parsingProject)
|
||||
qbsProject()->cancelParsing();
|
||||
@@ -354,17 +351,14 @@ void QbsBuildStep::reparsingDone(bool success)
|
||||
|
||||
void QbsBuildStep::handleTaskStarted(const QString &desciption, int max)
|
||||
{
|
||||
Q_UNUSED(desciption);
|
||||
QTC_ASSERT(m_fi, return);
|
||||
|
||||
m_progressBase = m_fi->progressValue();
|
||||
m_fi->setProgressRange(0, m_progressBase + max);
|
||||
m_currentTask = desciption;
|
||||
m_maxProgress = max;
|
||||
}
|
||||
|
||||
void QbsBuildStep::handleProgress(int value)
|
||||
{
|
||||
QTC_ASSERT(m_fi, return);
|
||||
m_fi->setProgressValue(m_progressBase + value);
|
||||
if (m_maxProgress > 0)
|
||||
emit progress(value * 100 / m_maxProgress, m_currentTask);
|
||||
}
|
||||
|
||||
void QbsBuildStep::handleCommandDescriptionReport(const QString &highlight, const QString &message)
|
||||
@@ -489,11 +483,11 @@ void QbsBuildStep::build()
|
||||
m_job = qbsProject()->build(options, m_products, error);
|
||||
if (!m_job) {
|
||||
emit addOutput(error, OutputFormat::ErrorMessage);
|
||||
reportRunResult(*m_fi, false);
|
||||
emit finished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_progressBase = 0;
|
||||
m_maxProgress = 0;
|
||||
|
||||
connect(m_job, &qbs::AbstractJob::finished, this, &QbsBuildStep::buildingDone);
|
||||
connect(m_job, &qbs::AbstractJob::taskStarted,
|
||||
@@ -509,9 +503,7 @@ void QbsBuildStep::build()
|
||||
|
||||
void QbsBuildStep::finish()
|
||||
{
|
||||
QTC_ASSERT(m_fi, return);
|
||||
reportRunResult(*m_fi, m_lastWasSuccess);
|
||||
m_fi = nullptr; // do not delete, it is not ours
|
||||
emit finished(m_lastWasSuccess);
|
||||
if (m_job) {
|
||||
m_job->deleteLater();
|
||||
m_job = nullptr;
|
||||
|
@@ -58,13 +58,6 @@ public:
|
||||
explicit QbsBuildStep(ProjectExplorer::BuildStepList *bsl);
|
||||
~QbsBuildStep() override;
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
void cancel() override;
|
||||
|
||||
QVariantMap qbsConfiguration(VariableHandling variableHandling) const;
|
||||
void setQbsConfiguration(const QVariantMap &config);
|
||||
|
||||
@@ -91,6 +84,10 @@ signals:
|
||||
void qbsBuildOptionsChanged();
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
void doCancel() override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
@@ -129,9 +126,9 @@ private:
|
||||
QStringList m_activeFileTags;
|
||||
QStringList m_products;
|
||||
|
||||
QFutureInterface<bool> *m_fi;
|
||||
qbs::BuildJob *m_job = nullptr;
|
||||
int m_progressBase;
|
||||
QString m_currentTask;
|
||||
int m_maxProgress;
|
||||
bool m_lastWasSuccess;
|
||||
ProjectExplorer::IOutputParser *m_parser = nullptr;
|
||||
bool m_parsingProject = false;
|
||||
|
@@ -49,7 +49,6 @@ QbsCleanStep::QbsCleanStep(ProjectExplorer::BuildStepList *bsl) :
|
||||
ProjectExplorer::BuildStep(bsl, Constants::QBS_CLEANSTEP_ID)
|
||||
{
|
||||
setDisplayName(tr("Qbs Clean"));
|
||||
setRunInGuiThread(true);
|
||||
|
||||
m_dryRunAspect = addAspect<BaseBoolAspect>();
|
||||
m_dryRunAspect->setSettingsKey("Qbs.DryRun");
|
||||
@@ -75,7 +74,7 @@ QbsCleanStep::QbsCleanStep(ProjectExplorer::BuildStepList *bsl) :
|
||||
|
||||
QbsCleanStep::~QbsCleanStep()
|
||||
{
|
||||
cancel();
|
||||
doCancel();
|
||||
if (m_job) {
|
||||
m_job->deleteLater();
|
||||
m_job = nullptr;
|
||||
@@ -96,10 +95,8 @@ bool QbsCleanStep::init()
|
||||
return true;
|
||||
}
|
||||
|
||||
void QbsCleanStep::run(QFutureInterface<bool> &fi)
|
||||
void QbsCleanStep::doRun()
|
||||
{
|
||||
m_fi = &fi;
|
||||
|
||||
auto pro = static_cast<QbsProject *>(project());
|
||||
qbs::CleanOptions options;
|
||||
options.setDryRun(m_dryRunAspect->value());
|
||||
@@ -109,11 +106,11 @@ void QbsCleanStep::run(QFutureInterface<bool> &fi)
|
||||
m_job = pro->clean(options, m_products, error);
|
||||
if (!m_job) {
|
||||
emit addOutput(error, OutputFormat::ErrorMessage);
|
||||
reportRunResult(*m_fi, false);
|
||||
emit finished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_progressBase = 0;
|
||||
m_maxProgress = 0;
|
||||
|
||||
connect(m_job, &qbs::AbstractJob::finished, this, &QbsCleanStep::cleaningDone);
|
||||
connect(m_job, &qbs::AbstractJob::taskStarted,
|
||||
@@ -131,7 +128,7 @@ ProjectExplorer::BuildStepConfigWidget *QbsCleanStep::createConfigWidget()
|
||||
return w;
|
||||
}
|
||||
|
||||
void QbsCleanStep::cancel()
|
||||
void QbsCleanStep::doCancel()
|
||||
{
|
||||
if (m_job)
|
||||
m_job->cancel();
|
||||
@@ -145,9 +142,7 @@ void QbsCleanStep::cleaningDone(bool success)
|
||||
item.codeLocation().filePath(), item.codeLocation().line());
|
||||
}
|
||||
|
||||
QTC_ASSERT(m_fi, return);
|
||||
reportRunResult(*m_fi, success);
|
||||
m_fi = nullptr; // do not delete, it is not ours
|
||||
emit finished(success);
|
||||
m_job->deleteLater();
|
||||
m_job = nullptr;
|
||||
}
|
||||
@@ -155,15 +150,13 @@ void QbsCleanStep::cleaningDone(bool success)
|
||||
void QbsCleanStep::handleTaskStarted(const QString &desciption, int max)
|
||||
{
|
||||
Q_UNUSED(desciption);
|
||||
QTC_ASSERT(m_fi, return);
|
||||
m_progressBase = m_fi->progressValue();
|
||||
m_fi->setProgressRange(0, m_progressBase + max);
|
||||
m_maxProgress = max;
|
||||
}
|
||||
|
||||
void QbsCleanStep::handleProgress(int value)
|
||||
{
|
||||
QTC_ASSERT(m_fi, return);
|
||||
m_fi->setProgressValue(m_progressBase + value);
|
||||
if (m_maxProgress > 0)
|
||||
emit progress(value * 100 / m_maxProgress, m_description);
|
||||
}
|
||||
|
||||
void QbsCleanStep::updateState()
|
||||
|
@@ -44,13 +44,6 @@ public:
|
||||
explicit QbsCleanStep(ProjectExplorer::BuildStepList *bsl);
|
||||
~QbsCleanStep() override;
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
void cancel() override;
|
||||
|
||||
bool dryRun() const { return m_dryRunAspect->value(); }
|
||||
bool keepGoing() const { return m_keepGoingAspect->value(); }
|
||||
|
||||
@@ -58,6 +51,11 @@ signals:
|
||||
void stateChanged();
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
void doCancel() override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
void cleaningDone(bool success);
|
||||
void handleTaskStarted(const QString &desciption, int max);
|
||||
void handleProgress(int value);
|
||||
@@ -72,9 +70,9 @@ private:
|
||||
|
||||
QStringList m_products;
|
||||
|
||||
QFutureInterface<bool> *m_fi = nullptr;
|
||||
qbs::CleanJob *m_job = nullptr;
|
||||
int m_progressBase;
|
||||
QString m_description;
|
||||
int m_maxProgress;
|
||||
bool m_showCompilerOutput = true;
|
||||
ProjectExplorer::IOutputParser *m_parser = nullptr;
|
||||
};
|
||||
|
@@ -61,7 +61,6 @@ QbsInstallStep::QbsInstallStep(ProjectExplorer::BuildStepList *bsl) :
|
||||
ProjectExplorer::BuildStep(bsl, Constants::QBS_INSTALLSTEP_ID)
|
||||
{
|
||||
setDisplayName(tr("Qbs Install"));
|
||||
setRunInGuiThread(true);
|
||||
|
||||
const QbsBuildConfiguration * const bc = buildConfig();
|
||||
connect(bc, &QbsBuildConfiguration::qbsConfigurationChanged,
|
||||
@@ -74,7 +73,7 @@ QbsInstallStep::QbsInstallStep(ProjectExplorer::BuildStepList *bsl) :
|
||||
|
||||
QbsInstallStep::~QbsInstallStep()
|
||||
{
|
||||
cancel();
|
||||
doCancel();
|
||||
if (m_job)
|
||||
m_job->deleteLater();
|
||||
m_job = nullptr;
|
||||
@@ -86,19 +85,17 @@ bool QbsInstallStep::init()
|
||||
return true;
|
||||
}
|
||||
|
||||
void QbsInstallStep::run(QFutureInterface<bool> &fi)
|
||||
void QbsInstallStep::doRun()
|
||||
{
|
||||
m_fi = &fi;
|
||||
|
||||
auto pro = static_cast<QbsProject *>(project());
|
||||
m_job = pro->install(m_qbsInstallOptions);
|
||||
|
||||
if (!m_job) {
|
||||
reportRunResult(*m_fi, false);
|
||||
emit finished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_progressBase = 0;
|
||||
m_maxProgress = 0;
|
||||
|
||||
connect(m_job, &qbs::AbstractJob::finished, this, &QbsInstallStep::installDone);
|
||||
connect(m_job, &qbs::AbstractJob::taskStarted,
|
||||
@@ -112,7 +109,7 @@ ProjectExplorer::BuildStepConfigWidget *QbsInstallStep::createConfigWidget()
|
||||
return new QbsInstallStepConfigWidget(this);
|
||||
}
|
||||
|
||||
void QbsInstallStep::cancel()
|
||||
void QbsInstallStep::doCancel()
|
||||
{
|
||||
if (m_job)
|
||||
m_job->cancel();
|
||||
@@ -180,25 +177,21 @@ void QbsInstallStep::installDone(bool success)
|
||||
item.codeLocation().filePath(), item.codeLocation().line());
|
||||
}
|
||||
|
||||
QTC_ASSERT(m_fi, return);
|
||||
reportRunResult(*m_fi, success);
|
||||
m_fi = nullptr; // do not delete, it is not ours
|
||||
emit finished(success);
|
||||
m_job->deleteLater();
|
||||
m_job = nullptr;
|
||||
}
|
||||
|
||||
void QbsInstallStep::handleTaskStarted(const QString &desciption, int max)
|
||||
{
|
||||
Q_UNUSED(desciption);
|
||||
QTC_ASSERT(m_fi, return);
|
||||
m_progressBase = m_fi->progressValue();
|
||||
m_fi->setProgressRange(0, m_progressBase + max);
|
||||
m_description = desciption;
|
||||
m_maxProgress = max;
|
||||
}
|
||||
|
||||
void QbsInstallStep::handleProgress(int value)
|
||||
{
|
||||
QTC_ASSERT(m_fi, return);
|
||||
m_fi->setProgressValue(m_progressBase + value);
|
||||
if (m_maxProgress > 0)
|
||||
emit progress(value * 100 / m_maxProgress, m_description);
|
||||
}
|
||||
|
||||
void QbsInstallStep::createTaskAndOutput(ProjectExplorer::Task::TaskType type,
|
||||
|
@@ -45,16 +45,6 @@ public:
|
||||
explicit QbsInstallStep(ProjectExplorer::BuildStepList *bsl);
|
||||
~QbsInstallStep() override;
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
void cancel() override;
|
||||
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
qbs::InstallOptions installOptions() const;
|
||||
QString installRoot() const;
|
||||
bool removeFirst() const;
|
||||
@@ -65,6 +55,13 @@ signals:
|
||||
void changed();
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
void doCancel() override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
const QbsBuildConfiguration *buildConfig() const;
|
||||
void installDone(bool success);
|
||||
void handleTaskStarted(const QString &desciption, int max);
|
||||
@@ -80,9 +77,9 @@ private:
|
||||
|
||||
qbs::InstallOptions m_qbsInstallOptions;
|
||||
|
||||
QFutureInterface<bool> *m_fi = nullptr;
|
||||
qbs::InstallJob *m_job = nullptr;
|
||||
int m_progressBase;
|
||||
QString m_description;
|
||||
int m_maxProgress;
|
||||
bool m_showCompilerOutput = true;
|
||||
ProjectExplorer::IOutputParser *m_parser = nullptr;
|
||||
|
||||
|
@@ -172,10 +172,10 @@ bool QmakeMakeStep::init()
|
||||
return AbstractProcessStep::init();
|
||||
}
|
||||
|
||||
void QmakeMakeStep::run(QFutureInterface<bool> & fi)
|
||||
void QmakeMakeStep::doRun()
|
||||
{
|
||||
if (m_scriptTarget) {
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -183,11 +183,11 @@ void QmakeMakeStep::run(QFutureInterface<bool> & fi)
|
||||
if (!ignoreReturnValue())
|
||||
emit addOutput(tr("Cannot find Makefile. Check your build settings."), BuildStep::OutputFormat::NormalMessage);
|
||||
const bool success = ignoreReturnValue();
|
||||
reportRunResult(fi, success);
|
||||
emit finished(success);
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
///
|
||||
|
@@ -55,7 +55,7 @@ public:
|
||||
QmakeBuildConfiguration *qmakeBuildConfiguration() const;
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &) override;
|
||||
void doRun() override;
|
||||
|
||||
private:
|
||||
bool m_scriptTarget = false;
|
||||
|
@@ -77,13 +77,6 @@ QMakeStep::QMakeStep(BuildStepList *bsl) : AbstractProcessStep(bsl, QMAKE_BS_ID)
|
||||
{
|
||||
//: QMakeStep default display name
|
||||
setDefaultDisplayName(tr("qmake"));
|
||||
|
||||
connect(&m_inputWatcher, &QFutureWatcher<bool>::canceled,
|
||||
this, [this]() {
|
||||
if (m_commandFuture)
|
||||
m_commandFuture->cancel();
|
||||
});
|
||||
connect(&m_commandWatcher, &QFutureWatcher<bool>::finished, this, &QMakeStep::runNextCommand);
|
||||
}
|
||||
|
||||
QmakeBuildConfiguration *QMakeStep::qmakeBuildConfiguration() const
|
||||
@@ -172,9 +165,6 @@ QMakeStepConfig QMakeStep::deducedArguments() const
|
||||
|
||||
bool QMakeStep::init()
|
||||
{
|
||||
if (m_commandFuture)
|
||||
return false;
|
||||
|
||||
QmakeBuildConfiguration *qmakeBc = qmakeBuildConfiguration();
|
||||
const BaseQtVersion *qtVersion = QtKitInformation::qtVersion(target()->kit());
|
||||
|
||||
@@ -262,21 +252,16 @@ bool QMakeStep::init()
|
||||
return AbstractProcessStep::init();
|
||||
}
|
||||
|
||||
void QMakeStep::run(QFutureInterface<bool> &fi)
|
||||
void QMakeStep::doRun()
|
||||
{
|
||||
m_inputFuture = fi;
|
||||
m_inputWatcher.setFuture(m_inputFuture.future());
|
||||
|
||||
fi.setProgressRange(0, static_cast<int>(State::POST_PROCESS));
|
||||
fi.setProgressValue(0);
|
||||
if (m_scriptTemplate) {
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_needToRunQMake) {
|
||||
emit addOutput(tr("Configuration unchanged, skipping qmake step."), BuildStep::OutputFormat::NormalMessage);
|
||||
reportRunResult(fi, true);
|
||||
emit finished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -312,6 +297,17 @@ bool QMakeStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
|
||||
return result;
|
||||
}
|
||||
|
||||
void QMakeStep::doCancel()
|
||||
{
|
||||
AbstractProcessStep::doCancel();
|
||||
}
|
||||
|
||||
void QMakeStep::finish(bool success)
|
||||
{
|
||||
m_wasSuccess = success;
|
||||
runNextCommand();
|
||||
}
|
||||
|
||||
void QMakeStep::startOneCommand(const QString &command, const QString &args)
|
||||
{
|
||||
ProcessParameters *pp = processParameters();
|
||||
@@ -319,31 +315,19 @@ void QMakeStep::startOneCommand(const QString &command, const QString &args)
|
||||
pp->setArguments(args);
|
||||
pp->resolveAll();
|
||||
|
||||
QTC_ASSERT(!m_commandFuture || m_commandFuture->future().isFinished(), return);
|
||||
m_commandFuture.reset(new QFutureInterface<bool>);
|
||||
|
||||
m_commandWatcher.setFuture(m_commandFuture->future());
|
||||
AbstractProcessStep::run(*m_commandFuture);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
void QMakeStep::runNextCommand()
|
||||
{
|
||||
bool wasSuccess = true;
|
||||
if (m_commandFuture) {
|
||||
if (m_commandFuture->isCanceled())
|
||||
wasSuccess = false;
|
||||
else if (m_commandFuture->isFinished())
|
||||
wasSuccess = m_commandFuture->future().result();
|
||||
else
|
||||
wasSuccess = false; // should not happen
|
||||
}
|
||||
if (isCanceled())
|
||||
m_wasSuccess = false;
|
||||
|
||||
m_commandFuture.reset();
|
||||
|
||||
if (!wasSuccess)
|
||||
if (!m_wasSuccess)
|
||||
m_nextState = State::POST_PROCESS;
|
||||
|
||||
m_inputFuture.setProgressValue(static_cast<int>(m_nextState));
|
||||
emit progress(static_cast<int>(m_nextState) * 100 / static_cast<int>(State::POST_PROCESS),
|
||||
QString());
|
||||
|
||||
switch (m_nextState) {
|
||||
case State::IDLE:
|
||||
@@ -364,8 +348,7 @@ void QMakeStep::runNextCommand()
|
||||
return;
|
||||
case State::POST_PROCESS:
|
||||
m_nextState = State::IDLE;
|
||||
reportRunResult(m_inputFuture, wasSuccess);
|
||||
m_inputFuture = QFutureInterface<bool>();
|
||||
emit finished(m_wasSuccess);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -29,7 +29,6 @@
|
||||
#include <projectexplorer/abstractprocessstep.h>
|
||||
|
||||
#include <QStringList>
|
||||
#include <QFutureWatcher>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -116,7 +115,7 @@ public:
|
||||
|
||||
QmakeBuildConfiguration *qmakeBuildConfiguration() const;
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &) override;
|
||||
void doRun() override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
void setForced(bool b);
|
||||
|
||||
@@ -165,6 +164,9 @@ protected:
|
||||
bool processSucceeded(int exitCode, QProcess::ExitStatus status) override;
|
||||
|
||||
private:
|
||||
void doCancel() override;
|
||||
void finish(bool success) override;
|
||||
|
||||
void startOneCommand(const QString &command, const QString &args);
|
||||
void runNextCommand();
|
||||
|
||||
@@ -176,13 +178,9 @@ private:
|
||||
// Extra arguments for qmake.
|
||||
QStringList m_extraArgs;
|
||||
|
||||
QFutureInterface<bool> m_inputFuture;
|
||||
QFutureWatcher<bool> m_inputWatcher;
|
||||
std::unique_ptr<QFutureInterface<bool>> m_commandFuture;
|
||||
QFutureWatcher<bool> m_commandWatcher;
|
||||
|
||||
// last values
|
||||
enum class State { IDLE = 0, RUN_QMAKE, RUN_MAKE_QMAKE_ALL, POST_PROCESS };
|
||||
bool m_wasSuccess = true;
|
||||
State m_nextState = State::IDLE;
|
||||
bool m_forced = false;
|
||||
bool m_needToRunQMake = false; // set in init(), read in run()
|
||||
|
@@ -40,7 +40,6 @@ class AbstractRemoteLinuxDeployStepPrivate
|
||||
{
|
||||
public:
|
||||
bool hasError;
|
||||
QFutureInterface<bool> future;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
@@ -48,7 +47,6 @@ public:
|
||||
AbstractRemoteLinuxDeployStep::AbstractRemoteLinuxDeployStep(BuildStepList *bsl, Core::Id id)
|
||||
: BuildStep(bsl, id), d(new Internal::AbstractRemoteLinuxDeployStepPrivate)
|
||||
{
|
||||
setRunInGuiThread(true);
|
||||
}
|
||||
|
||||
AbstractRemoteLinuxDeployStep::~AbstractRemoteLinuxDeployStep()
|
||||
@@ -79,7 +77,7 @@ bool AbstractRemoteLinuxDeployStep::init()
|
||||
return canDeploy;
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployStep::run(QFutureInterface<bool> &fi)
|
||||
void AbstractRemoteLinuxDeployStep::doRun()
|
||||
{
|
||||
connect(deployService(), &AbstractRemoteLinuxDeployService::errorMessage,
|
||||
this, &AbstractRemoteLinuxDeployStep::handleErrorMessage);
|
||||
@@ -95,11 +93,10 @@ void AbstractRemoteLinuxDeployStep::run(QFutureInterface<bool> &fi)
|
||||
this, &AbstractRemoteLinuxDeployStep::handleFinished);
|
||||
|
||||
d->hasError = false;
|
||||
d->future = fi;
|
||||
deployService()->start();
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployStep::cancel()
|
||||
void AbstractRemoteLinuxDeployStep::doCancel()
|
||||
{
|
||||
if (d->hasError)
|
||||
return;
|
||||
@@ -139,7 +136,7 @@ void AbstractRemoteLinuxDeployStep::handleFinished()
|
||||
else
|
||||
emit addOutput(tr("Deploy step finished."), OutputFormat::NormalMessage);
|
||||
disconnect(deployService(), nullptr, this, nullptr);
|
||||
reportRunResult(d->future, !d->hasError);
|
||||
emit finished(!d->hasError);
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxDeployStep::handleStdOutData(const QString &data)
|
||||
|
@@ -42,15 +42,15 @@ class REMOTELINUX_EXPORT AbstractRemoteLinuxDeployStep : public ProjectExplorer:
|
||||
|
||||
public:
|
||||
~AbstractRemoteLinuxDeployStep() override;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
void cancel() override;
|
||||
|
||||
virtual AbstractRemoteLinuxDeployService *deployService() const = 0;
|
||||
|
||||
protected:
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
void doCancel() override;
|
||||
|
||||
explicit AbstractRemoteLinuxDeployStep(ProjectExplorer::BuildStepList *bsl, Core::Id id);
|
||||
virtual bool initInternal(QString *error = nullptr) = 0;
|
||||
|
||||
|
@@ -94,32 +94,9 @@ bool TarPackageCreationStep::init()
|
||||
return true;
|
||||
}
|
||||
|
||||
void TarPackageCreationStep::run(QFutureInterface<bool> &fi)
|
||||
void TarPackageCreationStep::doRun()
|
||||
{
|
||||
setPackagingStarted();
|
||||
|
||||
const QList<DeployableFile> &files = target()->deploymentData().allFiles();
|
||||
|
||||
if (m_incrementalDeploymentAspect->value()) {
|
||||
m_files.clear();
|
||||
for (const DeployableFile &file : files)
|
||||
addNeededDeploymentFiles(file, target()->kit());
|
||||
} else {
|
||||
m_files = files;
|
||||
}
|
||||
|
||||
const bool success = doPackage(fi);
|
||||
|
||||
setPackagingFinished(success);
|
||||
if (success)
|
||||
emit addOutput(tr("Packaging finished successfully."), OutputFormat::NormalMessage);
|
||||
else
|
||||
emit addOutput(tr("Packaging failed."), OutputFormat::ErrorMessage);
|
||||
|
||||
connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
|
||||
this, &TarPackageCreationStep::deployFinished);
|
||||
|
||||
reportRunResult(fi, success);
|
||||
runInThread([this] { return runImpl(); });
|
||||
}
|
||||
|
||||
void TarPackageCreationStep::addNeededDeploymentFiles(
|
||||
@@ -151,7 +128,7 @@ void TarPackageCreationStep::addNeededDeploymentFiles(
|
||||
}
|
||||
}
|
||||
|
||||
bool TarPackageCreationStep::doPackage(QFutureInterface<bool> &fi)
|
||||
bool TarPackageCreationStep::doPackage()
|
||||
{
|
||||
emit addOutput(tr("Creating tarball..."), OutputFormat::NormalMessage);
|
||||
if (!m_packagingNeeded) {
|
||||
@@ -176,7 +153,7 @@ bool TarPackageCreationStep::doPackage(QFutureInterface<bool> &fi)
|
||||
}
|
||||
QFileInfo fileInfo = d.localFilePath().toFileInfo();
|
||||
if (!appendFile(tarFile, fileInfo, d.remoteDirectory() + QLatin1Char('/')
|
||||
+ fileInfo.fileName(), fi)) {
|
||||
+ fileInfo.fileName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -192,7 +169,7 @@ bool TarPackageCreationStep::doPackage(QFutureInterface<bool> &fi)
|
||||
}
|
||||
|
||||
bool TarPackageCreationStep::appendFile(QFile &tarFile, const QFileInfo &fileInfo,
|
||||
const QString &remoteFilePath, const QFutureInterface<bool> &fi)
|
||||
const QString &remoteFilePath)
|
||||
{
|
||||
if (!writeHeader(tarFile, fileInfo, remoteFilePath))
|
||||
return false;
|
||||
@@ -202,7 +179,7 @@ bool TarPackageCreationStep::appendFile(QFile &tarFile, const QFileInfo &fileInf
|
||||
dir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
|
||||
const QString thisLocalFilePath = dir.path() + QLatin1Char('/') + fileName;
|
||||
const QString thisRemoteFilePath = remoteFilePath + QLatin1Char('/') + fileName;
|
||||
if (!appendFile(tarFile, QFileInfo(thisLocalFilePath), thisRemoteFilePath, fi))
|
||||
if (!appendFile(tarFile, QFileInfo(thisLocalFilePath), thisRemoteFilePath))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -231,7 +208,7 @@ bool TarPackageCreationStep::appendFile(QFile &tarFile, const QFileInfo &fileInf
|
||||
while (!file.atEnd() && file.error() == QFile::NoError && tarFile.error() == QFile::NoError) {
|
||||
const QByteArray data = file.read(chunkSize);
|
||||
tarFile.write(data);
|
||||
if (fi.isCanceled())
|
||||
if (isCanceled())
|
||||
return false;
|
||||
}
|
||||
if (file.error() != QFile::NoError) {
|
||||
@@ -339,6 +316,34 @@ QString TarPackageCreationStep::packageFileName() const
|
||||
return project()->displayName() + QLatin1String(".tar");
|
||||
}
|
||||
|
||||
bool TarPackageCreationStep::runImpl()
|
||||
{
|
||||
setPackagingStarted();
|
||||
|
||||
const QList<DeployableFile> &files = target()->deploymentData().allFiles();
|
||||
|
||||
if (m_incrementalDeploymentAspect->value()) {
|
||||
m_files.clear();
|
||||
for (const DeployableFile &file : files)
|
||||
addNeededDeploymentFiles(file, target()->kit());
|
||||
} else {
|
||||
m_files = files;
|
||||
}
|
||||
|
||||
const bool success = doPackage();
|
||||
|
||||
setPackagingFinished(success);
|
||||
if (success)
|
||||
emit addOutput(tr("Packaging finished successfully."), OutputFormat::NormalMessage);
|
||||
else
|
||||
emit addOutput(tr("Packaging failed."), OutputFormat::ErrorMessage);
|
||||
|
||||
connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
|
||||
this, &TarPackageCreationStep::deployFinished);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *TarPackageCreationStep::createConfigWidget()
|
||||
{
|
||||
auto widget = BuildStep::createConfigWidget();
|
||||
|
@@ -48,9 +48,6 @@ public:
|
||||
static Core::Id stepId();
|
||||
static QString displayName();
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
|
||||
void setIgnoreMissingFiles(bool ignoreMissingFiles);
|
||||
bool ignoreMissingFiles() const;
|
||||
|
||||
@@ -58,6 +55,9 @@ public:
|
||||
bool isIncrementalDeployment() const;
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
|
||||
void deployFinished(bool success);
|
||||
|
||||
void addNeededDeploymentFiles(const ProjectExplorer::DeployableFile &deployable,
|
||||
@@ -69,9 +69,10 @@ private:
|
||||
|
||||
QString packageFileName() const override;
|
||||
|
||||
bool doPackage(QFutureInterface<bool> &fi);
|
||||
bool runImpl();
|
||||
bool doPackage();
|
||||
bool appendFile(QFile &tarFile, const QFileInfo &fileInfo,
|
||||
const QString &remoteFilePath, const QFutureInterface<bool> &fi);
|
||||
const QString &remoteFilePath);
|
||||
bool writeHeader(QFile &tarFile, const QFileInfo &fileInfo,
|
||||
const QString &remoteFilePath);
|
||||
|
||||
|
@@ -114,7 +114,7 @@ bool WinRtPackageDeploymentStep::init()
|
||||
return AbstractProcessStep::init();
|
||||
}
|
||||
|
||||
void WinRtPackageDeploymentStep::run(QFutureInterface<bool> &fi)
|
||||
void WinRtPackageDeploymentStep::doRun()
|
||||
{
|
||||
const QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(target()->kit());
|
||||
if (!qt)
|
||||
@@ -143,7 +143,7 @@ void WinRtPackageDeploymentStep::run(QFutureInterface<bool> &fi)
|
||||
}
|
||||
}
|
||||
|
||||
AbstractProcessStep::run(fi);
|
||||
AbstractProcessStep::doRun();
|
||||
}
|
||||
|
||||
bool WinRtPackageDeploymentStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
|
||||
|
@@ -38,18 +38,18 @@ class WinRtPackageDeploymentStep : public ProjectExplorer::AbstractProcessStep
|
||||
public:
|
||||
explicit WinRtPackageDeploymentStep(ProjectExplorer::BuildStepList *bsl);
|
||||
|
||||
bool init() override;
|
||||
void run(QFutureInterface<bool> &fi) override;
|
||||
bool processSucceeded(int exitCode, QProcess::ExitStatus status) override;
|
||||
void stdOutput(const QString &line) override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
QString defaultWinDeployQtArguments() const;
|
||||
|
||||
void raiseError(const QString &errorMessage);
|
||||
void raiseWarning(const QString &warningMessage);
|
||||
|
||||
private:
|
||||
bool init() override;
|
||||
void doRun() override;
|
||||
bool processSucceeded(int exitCode, QProcess::ExitStatus status) override;
|
||||
void stdOutput(const QString &line) override;
|
||||
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
|
||||
|
||||
bool parseIconsAndExecutableFromManifest(QString manifestFileName, QStringList *items, QString *executable);
|
||||
|
||||
ProjectExplorer::BaseStringAspect *m_argsAspect = nullptr;
|
||||
|
Reference in New Issue
Block a user