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/variablechooser.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QThread>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
@@ -45,6 +49,10 @@ const char BUILD_TARGETS_SUFFIX[] = ".BuildTargets";
|
||||
const char MAKE_ARGUMENTS_SUFFIX[] = ".MakeArguments";
|
||||
const char MAKE_COMMAND_SUFFIX[] = ".MakeCommand";
|
||||
const char CLEAN_SUFFIX[] = ".Clean";
|
||||
const char OVERRIDE_MAKEFLAGS_SUFFIX[] = ".OverrideMakeflags";
|
||||
const char JOBCOUNT_SUFFIX[] = ".JobCount";
|
||||
|
||||
const char MAKEFLAGS[] = "MAKEFLAGS";
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
@@ -53,7 +61,8 @@ MakeStep::MakeStep(BuildStepList *parent,
|
||||
const QString &buildTarget,
|
||||
const QStringList &availableTargets)
|
||||
: AbstractProcessStep(parent, id),
|
||||
m_availableTargets(availableTargets)
|
||||
m_availableTargets(availableTargets),
|
||||
m_userJobCount(defaultJobCount())
|
||||
{
|
||||
setDefaultDisplayName(defaultDisplayName());
|
||||
if (!buildTarget.isEmpty())
|
||||
@@ -158,6 +167,45 @@ Task MakeStep::makeCommandMissingTask()
|
||||
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 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();
|
||||
if (tc && tc->targetAbi().os() == Abi::WindowsOS
|
||||
&& 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;
|
||||
@@ -188,6 +235,12 @@ QVariantMap MakeStep::toMap() const
|
||||
map.insert(id().withSuffix(MAKE_ARGUMENTS_SUFFIX).toString(), m_makeArguments);
|
||||
map.insert(id().withSuffix(MAKE_COMMAND_SUFFIX).toString(), m_makeCommand);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -197,14 +250,27 @@ bool MakeStep::fromMap(const QVariantMap &map)
|
||||
m_makeArguments = map.value(id().withSuffix(MAKE_ARGUMENTS_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_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);
|
||||
}
|
||||
|
||||
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 args = m_makeArguments;
|
||||
Utils::QtcProcess::addArgs(&args, m_buildTargets);
|
||||
Utils::QtcProcess::addArgs(&args, jobArguments() + m_buildTargets);
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -287,6 +353,10 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) :
|
||||
m_ui->makeLineEdit->setHistoryCompleter("PE.MakeCommand.History");
|
||||
m_ui->makeLineEdit->setPath(m_makeStep->makeCommand());
|
||||
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();
|
||||
|
||||
connect(m_ui->targetsList, &QListWidget::itemChanged,
|
||||
@@ -295,6 +365,14 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) :
|
||||
this, &MakeStepConfigWidget::makeLineEditTextEdited);
|
||||
connect(m_ui->makeArgumentsLineEdit, &QLineEdit::textEdited,
|
||||
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,
|
||||
this, &MakeStepConfigWidget::updateDetails);
|
||||
@@ -341,6 +419,13 @@ void MakeStepConfigWidget::setSummaryText(const QString &text)
|
||||
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()
|
||||
{
|
||||
BuildConfiguration *bc = m_makeStep->buildConfiguration();
|
||||
@@ -360,6 +445,13 @@ void MakeStepConfigWidget::updateDetails()
|
||||
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;
|
||||
param.setMacroExpander(bc->macroExpander());
|
||||
param.setWorkingDirectory(bc->buildDirectory().toString());
|
||||
|
@@ -68,16 +68,27 @@ public:
|
||||
static QString msgNoMakeCommand();
|
||||
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;
|
||||
|
||||
private:
|
||||
QVariantMap toMap() const override;
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
static int defaultJobCount();
|
||||
QStringList jobArguments() const;
|
||||
|
||||
QStringList m_buildTargets;
|
||||
QStringList m_availableTargets;
|
||||
QString m_makeArguments;
|
||||
QString m_makeCommand;
|
||||
int m_userJobCount = 4;
|
||||
bool m_overrideMakeflags = false;
|
||||
bool m_clean = false;
|
||||
};
|
||||
|
||||
@@ -98,6 +109,7 @@ private:
|
||||
void makeArgumentsLineEditTextEdited();
|
||||
void updateDetails();
|
||||
void setSummaryText(const QString &text);
|
||||
void setUserJobCountVisible(bool visible);
|
||||
|
||||
Internal::Ui::MakeStep *m_ui;
|
||||
MakeStep *m_makeStep;
|
||||
|
@@ -53,6 +53,13 @@
|
||||
<widget class="QLineEdit" name="makeArgumentsLineEdit"/>
|
||||
</item>
|
||||
<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">
|
||||
<property name="text">
|
||||
<string>Targets:</string>
|
||||
@@ -62,9 +69,37 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QListWidget" name="targetsList"/>
|
||||
</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>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
Reference in New Issue
Block a user