Use base make step for autotools projects

Unify generic and autotools make steps, by moving the better maintained
logic from the generic make step to the base make step.

Add fallback code for restoring settings from previous autotools make
steps, since a key was named slightly different.

The autotools make step was behaving a little bit better when there is
no C++ toolchain set in the kit, but on the other hand would just take
the make command from a random existing toolchain, which can be wrong
too. Anyhow, this must be fixed in a follow-up patch for all make steps.

Change-Id: I47af7d327feb9336790d30c8b9a4968c25b25db3
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Eike Ziller
2018-05-17 15:58:47 +02:00
parent 5aef87f155
commit 84cde047d0
8 changed files with 100 additions and 317 deletions

View File

@@ -31,216 +31,40 @@
#include "autotoolsbuildconfiguration.h"
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/gnumakeparser.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtparser.h>
#include <utils/qtcprocess.h>
#include <QVariantMap>
#include <QLineEdit>
#include <QFormLayout>
using namespace AutotoolsProjectManager;
using namespace AutotoolsProjectManager::Internal;
using namespace AutotoolsProjectManager::Constants;
using namespace ProjectExplorer;
using namespace ProjectExplorer::Constants;
const char MAKE_STEP_ID[] = "AutotoolsProjectManager.MakeStep";
const char CLEAN_KEY[] = "AutotoolsProjectManager.MakeStep.Clean";
const char BUILD_TARGETS_KEY[] = "AutotoolsProjectManager.MakeStep.BuildTargets";
const char MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY[] = "AutotoolsProjectManager.MakeStep.AdditionalArguments";
// MakeStepFactory
MakeStepFactory::MakeStepFactory()
{
struct Step : public MakeStep
{
Step(ProjectExplorer::BuildStepList *bsl) : MakeStep(bsl)
{
if (bsl->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
setBuildTarget("clean", true);
setClean(true);
} else {
setBuildTarget("all", true);
}
}
};
setObjectName("Autotools::MakeStepFactory");
registerStep<MakeStep>(MAKE_STEP_ID);
setDisplayName(tr("Make", "Display name for AutotoolsProjectManager::MakeStep id."));
registerStep<Step>(MAKE_STEP_ID);
setDisplayName(ProjectExplorer::MakeStep::defaultDisplayName());
setSupportedProjectType(AUTOTOOLS_PROJECT_ID);
}
// MakeStep
MakeStep::MakeStep(BuildStepList *bsl) : AbstractProcessStep(bsl, MAKE_STEP_ID)
MakeStep::MakeStep(ProjectExplorer::BuildStepList *bsl, const QString &buildTarget)
: ProjectExplorer::MakeStep(bsl, MAKE_STEP_ID, buildTarget, {"all", "clean"})
{
setDefaultDisplayName(tr("Make"));
}
void MakeStep::setClean(bool clean)
{
m_clean = clean;
}
bool MakeStep::init(QList<const BuildStep *> &earlierSteps)
{
BuildConfiguration *bc = buildConfiguration();
if (!bc)
emit addTask(Task::buildConfigurationMissingTask());
QList<ToolChain *> tcList = ToolChainKitInformation::toolChains(target()->kit());
if (tcList.isEmpty())
emit addTask(Task::compilerMissingTask());
if (tcList.isEmpty() || !bc) {
emitFaultyConfigurationMessage();
return false;
}
QString arguments = Utils::QtcProcess::joinArgs(m_buildTargets);
Utils::QtcProcess::addArgs(&arguments, additionalArguments());
setIgnoreReturnValue(m_clean);
ProcessParameters *pp = processParameters();
pp->setMacroExpander(bc->macroExpander());
Utils::Environment env = bc->environment();
Utils::Environment::setupEnglishOutput(&env);
pp->setEnvironment(env);
pp->setWorkingDirectory(bc->buildDirectory().toString());
pp->setCommand(tcList.at(0)->makeCommand(bc->environment()));
pp->setArguments(arguments);
pp->resolveAll();
setOutputParser(new GnuMakeParser());
IOutputParser *parser = target()->kit()->createOutputParser();
if (parser)
appendOutputParser(parser);
outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
return AbstractProcessStep::init(earlierSteps);
}
void MakeStep::run(QFutureInterface<bool> &interface)
{
AbstractProcessStep::run(interface);
}
BuildStepConfigWidget *MakeStep::createConfigWidget()
{
return new MakeStepConfigWidget(this);
}
bool MakeStep::immutable() const
{
return false;
}
void MakeStep::setBuildTarget(const QString &target, bool on)
{
QStringList old = m_buildTargets;
if (on && !old.contains(target))
old << target;
else if (!on && old.contains(target))
old.removeOne(target);
m_buildTargets = old;
}
void MakeStep::setAdditionalArguments(const QString &list)
{
if (list == m_additionalArguments)
return;
m_additionalArguments = list;
emit additionalArgumentsChanged(list);
}
QString MakeStep::additionalArguments() const
{
return m_additionalArguments;
}
QVariantMap MakeStep::toMap() const
{
QVariantMap map = AbstractProcessStep::toMap();
map.insert(BUILD_TARGETS_KEY, m_buildTargets);
map.insert(MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY, m_additionalArguments);
map.insert(CLEAN_KEY, m_clean);
return map;
}
bool MakeStep::fromMap(const QVariantMap &map)
{
m_buildTargets = map.value(BUILD_TARGETS_KEY).toStringList();
m_additionalArguments = map.value(MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY).toString();
m_clean = map.value(CLEAN_KEY).toBool();
return BuildStep::fromMap(map);
}
///////////////////////////////
// MakeStepConfigWidget class
///////////////////////////////
MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) :
m_makeStep(makeStep),
m_summaryText(),
m_additionalArguments(0)
{
QFormLayout *fl = new QFormLayout(this);
fl->setMargin(0);
fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
setLayout(fl);
m_additionalArguments = new QLineEdit(this);
fl->addRow(tr("Arguments:"), m_additionalArguments);
m_additionalArguments->setText(m_makeStep->additionalArguments());
updateDetails();
connect(m_additionalArguments, &QLineEdit::textChanged,
makeStep, &MakeStep::setAdditionalArguments);
connect(makeStep, &MakeStep::additionalArgumentsChanged,
this, &MakeStepConfigWidget::updateDetails);
m_makeStep->project()->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
if (static_cast<BuildConfiguration *>(sender())->isActive())
updateDetails();
});
connect(makeStep->project(), &Project::activeProjectConfigurationChanged,
this, [this](ProjectConfiguration *pc) {
if (pc && pc->isActive())
updateDetails();
});
}
QString MakeStepConfigWidget::displayName() const
{
return tr("Make", "AutotoolsProjectManager::MakeStepConfigWidget display name.");
}
QString MakeStepConfigWidget::summaryText() const
{
return m_summaryText;
}
void MakeStepConfigWidget::updateDetails()
{
BuildConfiguration *bc = m_makeStep->buildConfiguration();
QList<ToolChain *> tcList = ToolChainKitInformation::toolChains(m_makeStep->target()->kit());
if (!tcList.isEmpty()) {
QString arguments = Utils::QtcProcess::joinArgs(m_makeStep->m_buildTargets);
Utils::QtcProcess::addArgs(&arguments, m_makeStep->additionalArguments());
ProcessParameters param;
param.setMacroExpander(m_makeStep->macroExpander());
param.setEnvironment(bc->environment());
param.setWorkingDirectory(bc->buildDirectory().toString());
param.setCommand(tcList.at(0)->makeCommand(bc->environment()));
param.setArguments(arguments);
m_summaryText = param.summary(displayName());
} else {
m_summaryText = "<b>" + ToolChainKitInformation::msgNoToolChainInTarget() + "</b>";
}
emit updateSummary();
}