summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/qmakeprojectmanager/makestep.cpp20
-rw-r--r--src/plugins/qmakeprojectmanager/makestep.h2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakestep.cpp193
-rw-r--r--src/plugins/qmakeprojectmanager/qmakestep.h31
4 files changed, 186 insertions, 60 deletions
diff --git a/src/plugins/qmakeprojectmanager/makestep.cpp b/src/plugins/qmakeprojectmanager/makestep.cpp
index a61dccab0c..3f495124db 100644
--- a/src/plugins/qmakeprojectmanager/makestep.cpp
+++ b/src/plugins/qmakeprojectmanager/makestep.cpp
@@ -108,6 +108,19 @@ QString MakeStep::makeCommand() const
return m_makeCmd;
}
+QString MakeStep::effectiveMakeCommand() const
+{
+ QString makeCmd = m_makeCmd;
+ if (makeCmd.isEmpty()) {
+ QmakeBuildConfiguration *bc = qmakeBuildConfiguration();
+ ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit());
+
+ if (bc && tc)
+ makeCmd = tc->makeCommand(bc->environment());
+ }
+ return makeCmd;
+}
+
QVariantMap MakeStep::toMap() const
{
QVariantMap map(AbstractProcessStep::toMap());
@@ -169,10 +182,7 @@ bool MakeStep::init(QList<const BuildStep *> &earlierSteps)
workingDirectory = bc->buildDirectory().toString();
pp->setWorkingDirectory(workingDirectory);
- QString makeCmd = tc->makeCommand(bc->environment());
- if (!m_makeCmd.isEmpty())
- makeCmd = m_makeCmd;
- pp->setCommand(makeCmd);
+ pp->setCommand(effectiveMakeCommand());
// If we are cleaning, then make can fail with a error code, but that doesn't mean
// we should stop the clean queue
@@ -235,7 +245,7 @@ bool MakeStep::init(QList<const BuildStep *> &earlierSteps)
Utils::Environment env = bc->environment();
Utils::Environment::setupEnglishOutput(&env);
// We also prepend "L" to the MAKEFLAGS, so that nmake / jom are less verbose
- if (tc && m_makeCmd.isEmpty()) {
+ if (tc && makeCommand().isEmpty()) {
if (tc->targetAbi().os() == Abi::WindowsOS
&& tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) {
const QString makeFlags = QLatin1String("MAKEFLAGS");
diff --git a/src/plugins/qmakeprojectmanager/makestep.h b/src/plugins/qmakeprojectmanager/makestep.h
index e3618f4f9c..555420a2af 100644
--- a/src/plugins/qmakeprojectmanager/makestep.h
+++ b/src/plugins/qmakeprojectmanager/makestep.h
@@ -87,6 +87,8 @@ public:
bool isClean() const;
QString makeCommand() const;
+ QString effectiveMakeCommand() const;
+
QVariantMap toMap() const override;
signals:
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp
index 003355e63c..ae94d87224 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp
@@ -26,15 +26,17 @@
#include "qmakestep.h"
#include "ui_qmakestep.h"
-#include "qmakeparser.h"
+#include "makestep.h"
#include "qmakebuildconfiguration.h"
-#include "qmakeproject.h"
-#include "qmakeprojectmanagerconstants.h"
#include "qmakekitinformation.h"
#include "qmakenodes.h"
+#include "qmakeparser.h"
+#include "qmakeproject.h"
+#include "qmakeprojectmanagerconstants.h"
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/buildsteplist.h>
+#include <projectexplorer/gnumakeparser.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
@@ -83,8 +85,8 @@ QMakeStep::QMakeStep(BuildStepList *bsl, Core::Id id) :
QMakeStep::QMakeStep(BuildStepList *bsl, QMakeStep *bs) :
AbstractProcessStep(bsl, bs),
- m_forced(bs->m_forced),
m_userArgs(bs->m_userArgs),
+ m_forced(bs->m_forced),
m_linkQmlDebuggingLibrary(bs->m_linkQmlDebuggingLibrary),
m_useQtQuickCompiler(bs->m_useQtQuickCompiler),
m_separateDebugInfo(bs->m_separateDebugInfo)
@@ -96,6 +98,13 @@ void QMakeStep::ctor()
{
//: 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
@@ -110,7 +119,7 @@ QmakeBuildConfiguration *QMakeStep::qmakeBuildConfiguration() const
/// config arguemnts
/// moreArguments
/// user arguments
-QString QMakeStep::allArguments(bool shorted)
+QString QMakeStep::allArguments(const BaseQtVersion *v, bool shorted) const
{
QmakeBuildConfiguration *bc = qmakeBuildConfiguration();
QStringList arguments;
@@ -121,7 +130,8 @@ QString QMakeStep::allArguments(bool shorted)
else
arguments << project()->projectFilePath().toUserOutput();
- arguments << QLatin1String("-r");
+ if (v->qtVersion() < QtVersionNumber(5, 0, 0))
+ arguments << QLatin1String("-r");
bool userProvidedMkspec = false;
for (QtcProcess::ConstArgIterator ait(m_userArgs); ait.next(); ) {
if (ait.value() == QLatin1String("-spec")) {
@@ -146,7 +156,7 @@ QString QMakeStep::allArguments(bool shorted)
return args;
}
-QMakeStepConfig QMakeStep::deducedArguments()
+QMakeStepConfig QMakeStep::deducedArguments() const
{
ProjectExplorer::Kit *kit = target()->kit();
QMakeStepConfig config;
@@ -156,7 +166,7 @@ QMakeStepConfig QMakeStep::deducedArguments()
if (tc)
targetAbi = tc->targetAbi();
- QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit());
+ BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit());
config.archConfig = QMakeStepConfig::targetArchFor(targetAbi, version);
config.osType = QMakeStepConfig::osTypeFor(targetAbi, version);
@@ -175,55 +185,63 @@ QMakeStepConfig QMakeStep::deducedArguments()
bool QMakeStep::init(QList<const BuildStep *> &earlierSteps)
{
- QmakeBuildConfiguration *qt4bc = qmakeBuildConfiguration();
- const QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(target()->kit());
+ if (m_commandFuture)
+ return false;
+
+ QmakeBuildConfiguration *qmakeBc = qmakeBuildConfiguration();
+ const BaseQtVersion *qtVersion = QtKitInformation::qtVersion(target()->kit());
if (!qtVersion)
return false;
- QString args = allArguments();
QString workingDirectory;
- if (qt4bc->subNodeBuild())
- workingDirectory = qt4bc->subNodeBuild()->buildDir();
+ if (qmakeBc->subNodeBuild())
+ workingDirectory = qmakeBc->subNodeBuild()->buildDir();
else
- workingDirectory = qt4bc->buildDirectory().toString();
-
- FileName program = qtVersion->qmakeCommand();
+ workingDirectory = qmakeBc->buildDirectory().toString();
+
+ m_qmakeExecutable = qtVersion->qmakeCommand().toString();
+ m_qmakeArguments = allArguments(qtVersion);
+ m_runMakeQmake = (qtVersion->qtVersion() >= QtVersionNumber(5, 0 ,0));
+ if (m_runMakeQmake) {
+ m_makeExecutable = makeCommand();
+ if (m_makeExecutable.isEmpty())
+ return false;
+ } else {
+ m_makeExecutable.clear();
+ }
QString makefile = workingDirectory;
- if (qt4bc->subNodeBuild()) {
- if (!qt4bc->subNodeBuild()->makefile().isEmpty())
- makefile.append(qt4bc->subNodeBuild()->makefile());
+ if (qmakeBc->subNodeBuild()) {
+ if (!qmakeBc->subNodeBuild()->makefile().isEmpty())
+ makefile.append(qmakeBc->subNodeBuild()->makefile());
else
makefile.append(QLatin1String("/Makefile"));
- } else if (!qt4bc->makefile().isEmpty()) {
+ } else if (!qmakeBc->makefile().isEmpty()) {
makefile.append(QLatin1Char('/'));
- makefile.append(qt4bc->makefile());
+ makefile.append(qmakeBc->makefile());
} else {
makefile.append(QLatin1String("/Makefile"));
}
// Check whether we need to run qmake
- bool makefileOutDated = (qt4bc->compareToImportFrom(makefile) != QmakeBuildConfiguration::MakefileMatches);
+ bool makefileOutDated = (qmakeBc->compareToImportFrom(makefile) != QmakeBuildConfiguration::MakefileMatches);
if (m_forced || makefileOutDated)
m_needToRunQMake = true;
m_forced = false;
ProcessParameters *pp = processParameters();
- pp->setMacroExpander(qt4bc->macroExpander());
+ pp->setMacroExpander(qmakeBc->macroExpander());
pp->setWorkingDirectory(workingDirectory);
- pp->setCommand(program.toString());
- pp->setArguments(args);
- pp->setEnvironment(qt4bc->environment());
- pp->resolveAll();
+ pp->setEnvironment(qmakeBc->environment());
setOutputParser(new QMakeParser);
- QmakeProFileNode *node = static_cast<QmakeProject *>(qt4bc->target()->project())->rootProjectNode();
- if (qt4bc->subNodeBuild())
- node = qt4bc->subNodeBuild();
+ QmakeProFileNode *node = static_cast<QmakeProject *>(qmakeBc->target()->project())->rootProjectNode();
+ if (qmakeBc->subNodeBuild())
+ node = qmakeBc->subNodeBuild();
QString proFile = node->filePath().toString();
QList<ProjectExplorer::Task> tasks = qtVersion->reportIssues(proFile, workingDirectory);
@@ -249,6 +267,11 @@ bool QMakeStep::init(QList<const BuildStep *> &earlierSteps)
void QMakeStep::run(QFutureInterface<bool> &fi)
{
+ 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);
return;
@@ -261,7 +284,9 @@ void QMakeStep::run(QFutureInterface<bool> &fi)
}
m_needToRunQMake = false;
- AbstractProcessStep::run(fi);
+
+ m_nextState = State::RUN_QMAKE;
+ runNextCommand();
}
void QMakeStep::setForced(bool b)
@@ -300,6 +325,58 @@ bool QMakeStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
return result;
}
+void QMakeStep::startOneCommand(const QString &command, const QString &args)
+{
+ ProcessParameters *pp = processParameters();
+ pp->setCommand(command);
+ pp->setArguments(args);
+ pp->resolveAll();
+
+ QTC_ASSERT(!m_commandFuture || m_commandFuture->future().isFinished(), return);
+ delete m_commandFuture;
+ m_commandFuture = new QFutureInterface<bool>;
+
+ m_commandWatcher.setFuture(m_commandFuture->future());
+ AbstractProcessStep::run(*m_commandFuture);
+}
+
+void QMakeStep::runNextCommand()
+{
+ bool wasSuccess = m_commandFuture ? m_commandFuture->future().result() : true;
+
+ delete m_commandFuture;
+ m_commandFuture = nullptr;
+
+ if (!wasSuccess)
+ m_nextState = State::POST_PROCESS;
+
+ m_inputFuture.setProgressValue(static_cast<int>(m_nextState));
+
+ switch (m_nextState) {
+ case State::IDLE:
+ return;
+ case State::RUN_QMAKE:
+ setOutputParser(new QMakeParser);
+ m_nextState = (m_runMakeQmake ? State::RUN_MAKE_QMAKE_ALL : State::POST_PROCESS);
+ startOneCommand(m_qmakeExecutable, m_qmakeArguments);
+ return;
+ case State::RUN_MAKE_QMAKE_ALL:
+ {
+ GnuMakeParser *parser = new GnuMakeParser;
+ parser->setWorkingDirectory(processParameters()->workingDirectory());
+ setOutputParser(parser);
+ m_nextState = State::POST_PROCESS;
+ startOneCommand(m_makeExecutable, QLatin1String("qmake_all"));
+ }
+ return;
+ case State::POST_PROCESS:
+ m_nextState = State::IDLE;
+ reportRunResult(m_inputFuture, wasSuccess);
+ m_inputFuture = QFutureInterface<bool>();
+ return;
+ }
+}
+
void QMakeStep::setUserArguments(const QString &arguments)
{
if (m_userArgs == arguments)
@@ -365,12 +442,37 @@ void QMakeStep::setSeparateDebugInfo(bool enable)
qmakeBuildConfiguration()->emitProFileEvaluateNeeded();
}
+QString QMakeStep::makeCommand() const
+{
+ MakeStep *ms = qobject_cast<BuildStepList *>(parent())->firstOfType<MakeStep>();
+ return ms ? ms->effectiveMakeCommand() : QString();
+}
+
+QString QMakeStep::effectiveQMakeCall() const
+{
+ BaseQtVersion *qtVersion = QtKitInformation::qtVersion(target()->kit());
+ QString qmake = qtVersion ? qtVersion->qmakeCommand().fileName() : QString();
+ if (qmake.isEmpty())
+ qmake = tr("<no Qt version>");
+ QString make = makeCommand();
+ if (make.isEmpty())
+ make = tr("<no Make step found>");
+
+ QString result = qmake + QLatin1Char(' ') + allArguments(qtVersion);
+ if (qtVersion->qtVersion() >= QtVersionNumber(5, 0, 0))
+ result.append(QString::fromLatin1(" && %1 qmake_all").arg(make));
+ return result;
+}
+
QStringList QMakeStep::parserArguments()
{
QStringList result;
- for (QtcProcess::ConstArgIterator ait(allArguments()); ait.next(); )
+ BaseQtVersion *qt = QtKitInformation::qtVersion(target()->kit());
+ QTC_ASSERT(qt, return QStringList());
+ for (QtcProcess::ConstArgIterator ait(allArguments(qt)); ait.next(); ) {
if (ait.isSimple())
result << ait.value();
+ }
return result;
}
@@ -379,7 +481,7 @@ QString QMakeStep::userArguments()
return m_userArgs;
}
-FileName QMakeStep::mkspec()
+FileName QMakeStep::mkspec() const
{
QString additionalArguments = m_userArgs;
for (QtcProcess::ArgIterator ait(&additionalArguments); ait.next(); ) {
@@ -476,7 +578,7 @@ QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step)
connect(step->qmakeBuildConfiguration(), SIGNAL(qmakeBuildConfigurationChanged()),
this, SLOT(qmakeBuildConfigChanged()));
connect(step->target(), SIGNAL(kitChanged()), this, SLOT(qtVersionChanged()));
- connect(QtSupport::QtVersionManager::instance(), SIGNAL(dumpUpdatedFor(Utils::FileName)),
+ connect(QtVersionManager::instance(), SIGNAL(dumpUpdatedFor(Utils::FileName)),
this, SLOT(qtVersionChanged()));
}
@@ -511,7 +613,7 @@ void QMakeStepConfigWidget::qtVersionChanged()
void QMakeStepConfigWidget::qmakeBuildConfigChanged()
{
QmakeBuildConfiguration *bc = m_step->qmakeBuildConfiguration();
- bool debug = bc->qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild;
+ bool debug = bc->qmakeBuildConfiguration() & BaseQtVersion::DebugBuild;
m_ignoreChange = true;
m_ui->buildConfigurationComboBox->setCurrentIndex(debug? 0 : 1);
m_ignoreChange = false;
@@ -574,11 +676,11 @@ void QMakeStepConfigWidget::buildConfigurationSelected()
if (m_ignoreChange)
return;
QmakeBuildConfiguration *bc = m_step->qmakeBuildConfiguration();
- QtSupport::BaseQtVersion::QmakeBuildConfigs buildConfiguration = bc->qmakeBuildConfiguration();
+ BaseQtVersion::QmakeBuildConfigs buildConfiguration = bc->qmakeBuildConfiguration();
if (m_ui->buildConfigurationComboBox->currentIndex() == 0) { // debug
- buildConfiguration = buildConfiguration | QtSupport::BaseQtVersion::DebugBuild;
+ buildConfiguration = buildConfiguration | BaseQtVersion::DebugBuild;
} else {
- buildConfiguration = buildConfiguration & ~QtSupport::BaseQtVersion::DebugBuild;
+ buildConfiguration = buildConfiguration & ~BaseQtVersion::DebugBuild;
}
m_ignoreChange = true;
bc->setQMakeBuildConfiguration(buildConfiguration);
@@ -643,13 +745,13 @@ void QMakeStepConfigWidget::separateDebugInfoChecked(bool checked)
void QMakeStepConfigWidget::updateSummaryLabel()
{
- QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(m_step->target()->kit());
+ BaseQtVersion *qtVersion = QtKitInformation::qtVersion(m_step->target()->kit());
if (!qtVersion) {
setSummaryText(tr("<b>qmake:</b> No Qt version set. Cannot run qmake."));
return;
}
// We don't want the full path to the .pro file
- QString args = m_step->allArguments(true);
+ QString args = m_step->allArguments(qtVersion, true);
// And we only use the .pro filename not the full path
QString program = qtVersion->qmakeCommand().fileName();
setSummaryText(tr("<b>qmake:</b> %1 %2").arg(program, args));
@@ -658,7 +760,7 @@ void QMakeStepConfigWidget::updateSummaryLabel()
void QMakeStepConfigWidget::updateQmlDebuggingOption()
{
QString warningText;
- bool supported = QtSupport::BaseQtVersion::isQmlDebuggingSupported(m_step->target()->kit(),
+ bool supported = BaseQtVersion::isQmlDebuggingSupported(m_step->target()->kit(),
&warningText);
m_ui->qmlDebuggingLibraryCheckBox->setEnabled(supported);
@@ -676,7 +778,7 @@ void QMakeStepConfigWidget::updateQmlDebuggingOption()
void QMakeStepConfigWidget::updateQtQuickCompilerOption()
{
QString warningText;
- bool supported = QtSupport::BaseQtVersion::isQtQuickCompilerSupported(m_step->target()->kit(),
+ bool supported = BaseQtVersion::isQtQuickCompilerSupported(m_step->target()->kit(),
&warningText);
m_ui->qtQuickCompilerCheckBox->setEnabled(supported);
m_ui->qtQuickCompilerLabel->setText(tr("Enable Qt Quick Compiler:"));
@@ -690,11 +792,7 @@ void QMakeStepConfigWidget::updateQtQuickCompilerOption()
void QMakeStepConfigWidget::updateEffectiveQMakeCall()
{
- QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(m_step->target()->kit());
- QString program = tr("<No Qt version>");
- if (qtVersion)
- program = qtVersion->qmakeCommand().fileName();
- m_ui->qmakeArgumentsEdit->setPlainText(program + QLatin1Char(' ') + m_step->allArguments());
+ m_ui->qmakeArgumentsEdit->setPlainText(m_step->effectiveQMakeCall());
}
void QMakeStepConfigWidget::recompileMessageBoxFinished(int button)
@@ -860,4 +958,3 @@ QStringList QMakeStepConfig::toArguments() const
return arguments;
}
-
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h
index 5d80671d07..4baeb3d721 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.h
+++ b/src/plugins/qmakeprojectmanager/qmakestep.h
@@ -29,8 +29,7 @@
#include <projectexplorer/abstractprocessstep.h>
#include <QStringList>
-
-#include <tuple>
+#include <QFutureWatcher>
namespace Utils { class FileName; }
@@ -40,7 +39,7 @@ class BuildStep;
class IBuildStepFactory;
class Project;
class Kit;
-}
+} // namespace ProjectExplorer
namespace QtSupport { class BaseQtVersion; }
@@ -133,13 +132,13 @@ public:
bool forced();
// the complete argument line
- QString allArguments(bool shorted = false);
- QMakeStepConfig deducedArguments();
+ QString allArguments(const QtSupport::BaseQtVersion *v, bool shorted = false) const;
+ QMakeStepConfig deducedArguments() const;
// arguments passed to the pro file parser
QStringList parserArguments();
// arguments set by the user
QString userArguments();
- Utils::FileName mkspec();
+ Utils::FileName mkspec() const;
void setUserArguments(const QString &arguments);
bool linkQmlDebuggingLibrary() const;
void setLinkQmlDebuggingLibrary(bool enable);
@@ -148,6 +147,9 @@ public:
bool separateDebugInfo() const;
void setSeparateDebugInfo(bool enable);
+ QString makeCommand() const;
+ QString effectiveQMakeCall() const;
+
QVariantMap toMap() const override;
signals:
@@ -165,12 +167,27 @@ protected:
bool processSucceeded(int exitCode, QProcess::ExitStatus status) override;
private:
+ void startOneCommand(const QString &command, const QString &args);
+ void runNextCommand();
void ctor();
+ QString m_qmakeExecutable;
+ QString m_qmakeArguments;
+ QString m_makeExecutable;
+ QString m_userArgs;
+
+ QFutureInterface<bool> m_inputFuture;
+ QFutureWatcher<bool> m_inputWatcher;
+ QFutureInterface<bool> *m_commandFuture = nullptr;
+ QFutureWatcher<bool> m_commandWatcher;
+
// last values
+ enum class State { IDLE = 0, RUN_QMAKE, RUN_MAKE_QMAKE_ALL, POST_PROCESS };
+ State m_nextState = State::IDLE;
bool m_forced = false;
bool m_needToRunQMake = false; // set in init(), read in run()
- QString m_userArgs;
+
+ bool m_runMakeQmake = false;
bool m_linkQmlDebuggingLibrary = false;
bool m_useQtQuickCompiler = false;
bool m_scriptTemplate = false;