forked from qt-creator/qt-creator
Add option for parallel jobs to make step and use it by default
By default the make step uses idealThreadCount jobs, except if it finds a "-j" option in the MAKEFLAGS variable. The user can opt-in to override MAKEFLAGS anyhow, and can also choose a different number of build jobs (including 1). This option is available for unix-style make. It is not available on Windows with MSVC tool chain, which would use either nmake (does not support parallel jobs) or jom (does parallel building by default). Task-number: QTCREATORBUG-18414 Change-Id: Ic0b5c732d899607ce67ef0b496cc758497a3113a Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -37,7 +37,11 @@
|
|||||||
|
|
||||||
#include <coreplugin/id.h>
|
#include <coreplugin/id.h>
|
||||||
#include <coreplugin/variablechooser.h>
|
#include <coreplugin/variablechooser.h>
|
||||||
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
|
||||||
@@ -45,6 +49,10 @@ const char BUILD_TARGETS_SUFFIX[] = ".BuildTargets";
|
|||||||
const char MAKE_ARGUMENTS_SUFFIX[] = ".MakeArguments";
|
const char MAKE_ARGUMENTS_SUFFIX[] = ".MakeArguments";
|
||||||
const char MAKE_COMMAND_SUFFIX[] = ".MakeCommand";
|
const char MAKE_COMMAND_SUFFIX[] = ".MakeCommand";
|
||||||
const char CLEAN_SUFFIX[] = ".Clean";
|
const char CLEAN_SUFFIX[] = ".Clean";
|
||||||
|
const char OVERRIDE_MAKEFLAGS_SUFFIX[] = ".OverrideMakeflags";
|
||||||
|
const char JOBCOUNT_SUFFIX[] = ".JobCount";
|
||||||
|
|
||||||
|
const char MAKEFLAGS[] = "MAKEFLAGS";
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
@@ -53,7 +61,8 @@ MakeStep::MakeStep(BuildStepList *parent,
|
|||||||
const QString &buildTarget,
|
const QString &buildTarget,
|
||||||
const QStringList &availableTargets)
|
const QStringList &availableTargets)
|
||||||
: AbstractProcessStep(parent, id),
|
: AbstractProcessStep(parent, id),
|
||||||
m_availableTargets(availableTargets)
|
m_availableTargets(availableTargets),
|
||||||
|
m_userJobCount(defaultJobCount())
|
||||||
{
|
{
|
||||||
setDefaultDisplayName(defaultDisplayName());
|
setDefaultDisplayName(defaultDisplayName());
|
||||||
if (!buildTarget.isEmpty())
|
if (!buildTarget.isEmpty())
|
||||||
@@ -158,6 +167,45 @@ Task MakeStep::makeCommandMissingTask()
|
|||||||
Constants::TASK_CATEGORY_BUILDSYSTEM);
|
Constants::TASK_CATEGORY_BUILDSYSTEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MakeStep::isJobCountSupported() const
|
||||||
|
{
|
||||||
|
const QList<ToolChain *> tcs = preferredToolChains(target()->kit());
|
||||||
|
const ToolChain *tc = tcs.isEmpty() ? nullptr : tcs.constFirst();
|
||||||
|
return tc
|
||||||
|
&& (tc->targetAbi().os() != Abi::WindowsOS
|
||||||
|
|| tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MakeStep::jobCount() const
|
||||||
|
{
|
||||||
|
return m_userJobCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeStep::setJobCount(int count)
|
||||||
|
{
|
||||||
|
m_userJobCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MakeStep::jobCountOverridesMakeflags() const
|
||||||
|
{
|
||||||
|
return m_overrideMakeflags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeStep::setJobCountOverrideMakeflags(bool override)
|
||||||
|
{
|
||||||
|
m_overrideMakeflags = override;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MakeStep::makeflagsContainsJobCount() const
|
||||||
|
{
|
||||||
|
const Utils::Environment env = environment(buildConfiguration());
|
||||||
|
if (!env.hasKey(MAKEFLAGS))
|
||||||
|
return false;
|
||||||
|
const QStringList args = Utils::QtcProcess::splitArgs(env.value(MAKEFLAGS),
|
||||||
|
Utils::HostOsInfo::hostOs());
|
||||||
|
return Utils::anyOf(args, [](const QString &arg) { return arg.startsWith("-j"); });
|
||||||
|
}
|
||||||
|
|
||||||
Utils::Environment MakeStep::environment(BuildConfiguration *bc) const
|
Utils::Environment MakeStep::environment(BuildConfiguration *bc) const
|
||||||
{
|
{
|
||||||
Utils::Environment env = bc ? bc->environment() : Utils::Environment::systemEnvironment();
|
Utils::Environment env = bc ? bc->environment() : Utils::Environment::systemEnvironment();
|
||||||
@@ -168,8 +216,7 @@ Utils::Environment MakeStep::environment(BuildConfiguration *bc) const
|
|||||||
const ToolChain *tc = tcs.isEmpty() ? nullptr : tcs.constFirst();
|
const ToolChain *tc = tcs.isEmpty() ? nullptr : tcs.constFirst();
|
||||||
if (tc && tc->targetAbi().os() == Abi::WindowsOS
|
if (tc && tc->targetAbi().os() == Abi::WindowsOS
|
||||||
&& tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) {
|
&& tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) {
|
||||||
const QString makeFlags = "MAKEFLAGS";
|
env.set(MAKEFLAGS, 'L' + env.value(MAKEFLAGS));
|
||||||
env.set(makeFlags, 'L' + env.value(makeFlags));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return env;
|
return env;
|
||||||
@@ -188,6 +235,12 @@ QVariantMap MakeStep::toMap() const
|
|||||||
map.insert(id().withSuffix(MAKE_ARGUMENTS_SUFFIX).toString(), m_makeArguments);
|
map.insert(id().withSuffix(MAKE_ARGUMENTS_SUFFIX).toString(), m_makeArguments);
|
||||||
map.insert(id().withSuffix(MAKE_COMMAND_SUFFIX).toString(), m_makeCommand);
|
map.insert(id().withSuffix(MAKE_COMMAND_SUFFIX).toString(), m_makeCommand);
|
||||||
map.insert(id().withSuffix(CLEAN_SUFFIX).toString(), m_clean);
|
map.insert(id().withSuffix(CLEAN_SUFFIX).toString(), m_clean);
|
||||||
|
const QString jobCountKey = id().withSuffix(JOBCOUNT_SUFFIX).toString();
|
||||||
|
if (m_userJobCount != defaultJobCount())
|
||||||
|
map.insert(jobCountKey, m_userJobCount);
|
||||||
|
else
|
||||||
|
map.remove(jobCountKey);
|
||||||
|
map.insert(id().withSuffix(OVERRIDE_MAKEFLAGS_SUFFIX).toString(), m_overrideMakeflags);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,14 +250,27 @@ bool MakeStep::fromMap(const QVariantMap &map)
|
|||||||
m_makeArguments = map.value(id().withSuffix(MAKE_ARGUMENTS_SUFFIX).toString()).toString();
|
m_makeArguments = map.value(id().withSuffix(MAKE_ARGUMENTS_SUFFIX).toString()).toString();
|
||||||
m_makeCommand = map.value(id().withSuffix(MAKE_COMMAND_SUFFIX).toString()).toString();
|
m_makeCommand = map.value(id().withSuffix(MAKE_COMMAND_SUFFIX).toString()).toString();
|
||||||
m_clean = map.value(id().withSuffix(CLEAN_SUFFIX).toString()).toBool();
|
m_clean = map.value(id().withSuffix(CLEAN_SUFFIX).toString()).toBool();
|
||||||
|
m_overrideMakeflags = map.value(id().withSuffix(OVERRIDE_MAKEFLAGS_SUFFIX).toString(), false).toBool();
|
||||||
|
m_userJobCount = map.value(id().withSuffix(JOBCOUNT_SUFFIX).toString(), defaultJobCount()).toInt();
|
||||||
return BuildStep::fromMap(map);
|
return BuildStep::fromMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MakeStep::defaultJobCount()
|
||||||
|
{
|
||||||
|
return QThread::idealThreadCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList MakeStep::jobArguments() const
|
||||||
|
{
|
||||||
|
if (!isJobCountSupported() || (makeflagsContainsJobCount() && !jobCountOverridesMakeflags()))
|
||||||
|
return {};
|
||||||
|
return {"-j" + QString::number(m_userJobCount)};
|
||||||
|
}
|
||||||
|
|
||||||
QString MakeStep::allArguments() const
|
QString MakeStep::allArguments() const
|
||||||
{
|
{
|
||||||
QString args = m_makeArguments;
|
QString args = m_makeArguments;
|
||||||
Utils::QtcProcess::addArgs(&args, m_buildTargets);
|
Utils::QtcProcess::addArgs(&args, jobArguments() + m_buildTargets);
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,6 +353,10 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) :
|
|||||||
m_ui->makeLineEdit->setHistoryCompleter("PE.MakeCommand.History");
|
m_ui->makeLineEdit->setHistoryCompleter("PE.MakeCommand.History");
|
||||||
m_ui->makeLineEdit->setPath(m_makeStep->makeCommand());
|
m_ui->makeLineEdit->setPath(m_makeStep->makeCommand());
|
||||||
m_ui->makeArgumentsLineEdit->setText(m_makeStep->userArguments());
|
m_ui->makeArgumentsLineEdit->setText(m_makeStep->userArguments());
|
||||||
|
m_ui->nonOverrideWarning->setToolTip("<html><body><p>" +
|
||||||
|
tr("<code>MAKEFLAGS</code> specifies parallel jobs. Check \"%1\" to override.")
|
||||||
|
.arg(m_ui->overrideMakeflags->text()) + "</p></body></html>");
|
||||||
|
m_ui->nonOverrideWarning->setPixmap(Utils::Icons::WARNING.pixmap());
|
||||||
updateDetails();
|
updateDetails();
|
||||||
|
|
||||||
connect(m_ui->targetsList, &QListWidget::itemChanged,
|
connect(m_ui->targetsList, &QListWidget::itemChanged,
|
||||||
@@ -295,6 +365,14 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) :
|
|||||||
this, &MakeStepConfigWidget::makeLineEditTextEdited);
|
this, &MakeStepConfigWidget::makeLineEditTextEdited);
|
||||||
connect(m_ui->makeArgumentsLineEdit, &QLineEdit::textEdited,
|
connect(m_ui->makeArgumentsLineEdit, &QLineEdit::textEdited,
|
||||||
this, &MakeStepConfigWidget::makeArgumentsLineEditTextEdited);
|
this, &MakeStepConfigWidget::makeArgumentsLineEditTextEdited);
|
||||||
|
connect(m_ui->userJobCount, qOverload<int>(&QSpinBox::valueChanged), this, [this](int value) {
|
||||||
|
m_makeStep->setJobCount(value);
|
||||||
|
updateDetails();
|
||||||
|
});
|
||||||
|
connect(m_ui->overrideMakeflags, &QCheckBox::stateChanged, this, [this](int state) {
|
||||||
|
m_makeStep->setJobCountOverrideMakeflags(state == Qt::Checked);
|
||||||
|
updateDetails();
|
||||||
|
});
|
||||||
|
|
||||||
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
|
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
|
||||||
this, &MakeStepConfigWidget::updateDetails);
|
this, &MakeStepConfigWidget::updateDetails);
|
||||||
@@ -341,6 +419,13 @@ void MakeStepConfigWidget::setSummaryText(const QString &text)
|
|||||||
emit updateSummary();
|
emit updateSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MakeStepConfigWidget::setUserJobCountVisible(bool visible)
|
||||||
|
{
|
||||||
|
m_ui->jobsLabel->setVisible(visible);
|
||||||
|
m_ui->userJobCount->setVisible(visible);
|
||||||
|
m_ui->overrideMakeflags->setVisible(visible);
|
||||||
|
}
|
||||||
|
|
||||||
void MakeStepConfigWidget::updateDetails()
|
void MakeStepConfigWidget::updateDetails()
|
||||||
{
|
{
|
||||||
BuildConfiguration *bc = m_makeStep->buildConfiguration();
|
BuildConfiguration *bc = m_makeStep->buildConfiguration();
|
||||||
@@ -360,6 +445,13 @@ void MakeStepConfigWidget::updateDetails()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setUserJobCountVisible(m_makeStep->isJobCountSupported());
|
||||||
|
m_ui->userJobCount->setValue(m_makeStep->jobCount());
|
||||||
|
m_ui->overrideMakeflags->setCheckState(
|
||||||
|
m_makeStep->jobCountOverridesMakeflags() ? Qt::Checked : Qt::Unchecked);
|
||||||
|
m_ui->nonOverrideWarning->setVisible(m_makeStep->makeflagsContainsJobCount()
|
||||||
|
&& !m_makeStep->jobCountOverridesMakeflags());
|
||||||
|
|
||||||
ProcessParameters param;
|
ProcessParameters param;
|
||||||
param.setMacroExpander(bc->macroExpander());
|
param.setMacroExpander(bc->macroExpander());
|
||||||
param.setWorkingDirectory(bc->buildDirectory().toString());
|
param.setWorkingDirectory(bc->buildDirectory().toString());
|
||||||
|
@@ -68,16 +68,27 @@ public:
|
|||||||
static QString msgNoMakeCommand();
|
static QString msgNoMakeCommand();
|
||||||
static Task makeCommandMissingTask();
|
static Task makeCommandMissingTask();
|
||||||
|
|
||||||
|
bool isJobCountSupported() const;
|
||||||
|
int jobCount() const;
|
||||||
|
void setJobCount(int count);
|
||||||
|
bool jobCountOverridesMakeflags() const;
|
||||||
|
void setJobCountOverrideMakeflags(bool override);
|
||||||
|
bool makeflagsContainsJobCount() const;
|
||||||
|
|
||||||
Utils::Environment environment(BuildConfiguration *bc) const;
|
Utils::Environment environment(BuildConfiguration *bc) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
bool fromMap(const QVariantMap &map) override;
|
bool fromMap(const QVariantMap &map) override;
|
||||||
|
static int defaultJobCount();
|
||||||
|
QStringList jobArguments() const;
|
||||||
|
|
||||||
QStringList m_buildTargets;
|
QStringList m_buildTargets;
|
||||||
QStringList m_availableTargets;
|
QStringList m_availableTargets;
|
||||||
QString m_makeArguments;
|
QString m_makeArguments;
|
||||||
QString m_makeCommand;
|
QString m_makeCommand;
|
||||||
|
int m_userJobCount = 4;
|
||||||
|
bool m_overrideMakeflags = false;
|
||||||
bool m_clean = false;
|
bool m_clean = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -98,6 +109,7 @@ private:
|
|||||||
void makeArgumentsLineEditTextEdited();
|
void makeArgumentsLineEditTextEdited();
|
||||||
void updateDetails();
|
void updateDetails();
|
||||||
void setSummaryText(const QString &text);
|
void setSummaryText(const QString &text);
|
||||||
|
void setUserJobCountVisible(bool visible);
|
||||||
|
|
||||||
Internal::Ui::MakeStep *m_ui;
|
Internal::Ui::MakeStep *m_ui;
|
||||||
MakeStep *m_makeStep;
|
MakeStep *m_makeStep;
|
||||||
|
@@ -53,6 +53,13 @@
|
|||||||
<widget class="QLineEdit" name="makeArgumentsLineEdit"/>
|
<widget class="QLineEdit" name="makeArgumentsLineEdit"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="jobsLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Parallel jobs:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="targetsLabel">
|
<widget class="QLabel" name="targetsLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Targets:</string>
|
<string>Targets:</string>
|
||||||
@@ -62,9 +69,37 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QListWidget" name="targetsList"/>
|
<widget class="QListWidget" name="targetsList"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="jobLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="userJobCount">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="overrideMakeflags">
|
||||||
|
<property name="text">
|
||||||
|
<string>Override MAKEFLAGS</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="nonOverrideWarning">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
Reference in New Issue
Block a user