Partially decouple local CMakeRunConfiguration from CMakeProject

Funnel all relevant data through target.applicationTargets() as
done for the non-local CMake-supporting setups and QBS already.

There is cleanup potential left for later changes.

Change-Id: I49ed6abd98c058a7fd1545e41b3bcd6ecb758a8b
Task-number: QTCREATORBUG-19985
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
hjk
2018-03-12 16:33:28 +01:00
parent 3f86d55587
commit a5d6fe33cb
9 changed files with 43 additions and 87 deletions

View File

@@ -473,20 +473,9 @@ void CMakeProject::startParsing(int reparseParameters)
m_buildDirManager.parse(reparseParameters);
}
QStringList CMakeProject::buildTargetTitles(bool runnable) const
QStringList CMakeProject::buildTargetTitles() const
{
const QList<CMakeBuildTarget> targets
= runnable ? filtered(buildTargets(),
[](const CMakeBuildTarget &ct) {
return !ct.executable.isEmpty() && ct.targetType == ExecutableType;
})
: buildTargets();
return transform(targets, [](const CMakeBuildTarget &ct) { return ct.title; });
}
bool CMakeProject::hasBuildTarget(const QString &title) const
{
return anyOf(buildTargets(), [title](const CMakeBuildTarget &ct) { return ct.title == title; });
return transform(buildTargets(), [](const CMakeBuildTarget &ct) { return ct.title; });
}
Project::RestoreResult CMakeProject::fromMap(const QVariantMap &map, QString *errorMessage)
@@ -562,14 +551,6 @@ void CMakeProject::combineScanAndParse(CMakeBuildConfiguration *bc)
emitParsingFinished(m_combinedScanAndParseResult);
}
CMakeBuildTarget CMakeProject::buildTargetForTitle(const QString &title)
{
foreach (const CMakeBuildTarget &ct, buildTargets())
if (ct.title == title)
return ct;
return CMakeBuildTarget();
}
QStringList CMakeProject::filesGeneratedFrom(const QString &sourceFile) const
{
if (!activeTarget())
@@ -676,10 +657,15 @@ void CMakeProject::updateApplicationAndDeploymentTargets()
}
}
if (ct.targetType == ExecutableType) {
FileName srcWithTrailingSlash = FileName::fromString(ct.sourceDirectory.toString());
srcWithTrailingSlash.appendString('/');
// TODO: Put a path to corresponding .cbp file into projectFilePath?
appTargetList.list << BuildTargetInfo(ct.title, ct.executable, srcWithTrailingSlash);
BuildTargetInfo bti;
bti.targetName = ct.title;
bti.displayName = ct.title;
bti.targetFilePath = ct.executable;
bti.projectFilePath = ct.sourceDirectory;
bti.projectFilePath.appendString('/');
bti.workingDirectory = ct.workingDirectory;
bti.buildKey = ct.title + QChar('\n') + bti.projectFilePath.toString();
appTargetList.list.append(bti);
}
}

View File

@@ -63,10 +63,7 @@ public:
explicit CMakeProject(const Utils::FileName &filename);
~CMakeProject() final;
QStringList buildTargetTitles(bool runnable = false) const;
bool hasBuildTarget(const QString &title) const;
CMakeBuildTarget buildTargetForTitle(const QString &title);
QStringList buildTargetTitles() const;
bool knowsAllBuildExecutables() const final;

View File

@@ -25,8 +25,6 @@
#include "cmakerunconfiguration.h"
#include "cmakebuildconfiguration.h"
#include "cmakeproject.h"
#include "cmakeprojectconstants.h"
#include <coreplugin/coreicons.h>
@@ -40,18 +38,11 @@
#include <utils/detailswidget.h>
#include <utils/fancylineedit.h>
#include <utils/hostosinfo.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/stringutils.h>
#include <QFormLayout>
#include <QLineEdit>
#include <QGroupBox>
#include <QLabel>
#include <QComboBox>
#include <QToolButton>
#include <QCheckBox>
using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
@@ -97,14 +88,6 @@ Runnable CMakeRunConfiguration::runnable() const
return r;
}
QString CMakeRunConfiguration::baseWorkingDirectory() const
{
const QString exe = m_executable;
if (!exe.isEmpty())
return QFileInfo(m_executable).absolutePath();
return QString();
}
QString CMakeRunConfiguration::title() const
{
return m_title;
@@ -140,15 +123,22 @@ bool CMakeRunConfiguration::fromMap(const QVariantMap &map)
m_executable = extraId;
if (m_title.isEmpty())
m_title = extraId;
CMakeProject *project = static_cast<CMakeProject *>(target()->project());
const CMakeBuildTarget ct = project->buildTargetForTitle(m_title);
extraAspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(ct.workingDirectory);
}
return true;
}
void CMakeRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &info)
{
m_buildSystemTarget = info.targetName;
m_title = info.displayName;
m_executable = info.displayName;
setDefaultDisplayName(info.displayName);
setDisplayName(info.displayName);
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(info.buildKey);
extraAspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(bti.workingDirectory);
}
QString CMakeRunConfiguration::defaultDisplayName() const
{
if (m_title.isEmpty())
@@ -156,10 +146,16 @@ QString CMakeRunConfiguration::defaultDisplayName() const
return m_title;
}
bool CMakeRunConfiguration::isBuildTargetValid() const
{
return Utils::anyOf(target()->applicationTargets().list, [this](const BuildTargetInfo &bti) {
return bti.targetName == m_buildSystemTarget;
});
}
void CMakeRunConfiguration::updateEnabledState()
{
auto cp = qobject_cast<CMakeProject *>(target()->project());
if (!cp->hasBuildTarget(m_buildSystemTarget))
if (!isBuildTargetValid())
setEnabled(false);
else
RunConfiguration::updateEnabledState();
@@ -172,10 +168,7 @@ QWidget *CMakeRunConfiguration::createConfigurationWidget()
QString CMakeRunConfiguration::disabledReason() const
{
auto cp = qobject_cast<CMakeProject *>(target()->project());
QTC_ASSERT(cp, return QString());
if (!cp->hasBuildTarget(m_buildSystemTarget))
if (!isBuildTargetValid())
return tr("The project no longer builds the target associated with this run configuration.");
return RunConfiguration::disabledReason();
}
@@ -235,18 +228,3 @@ CMakeRunConfigurationFactory::CMakeRunConfigurationFactory()
registerRunConfiguration<CMakeRunConfiguration>(CMAKE_RC_PREFIX);
addSupportedProjectType(CMakeProjectManager::Constants::CMAKEPROJECT_ID);
}
QList<RunConfigurationCreationInfo>
CMakeRunConfigurationFactory::availableCreators(Target *parent) const
{
CMakeProject *project = qobject_cast<CMakeProject *>(parent->project());
QTC_ASSERT(project, return {});
const QStringList titles = project->buildTargetTitles(true);
return Utils::transform(titles, [this](const QString &title) { return convert(title, title); });
}
bool CMakeRunConfigurationFactory::canCreateHelper(Target *parent, const QString &buildTarget) const
{
CMakeProject *project = static_cast<CMakeProject *>(parent->project());
return project->hasBuildTarget(buildTarget);
}

View File

@@ -26,7 +26,6 @@
#pragma once
#include <projectexplorer/runnables.h>
#include <utils/environment.h>
namespace CMakeProjectManager {
namespace Internal {
@@ -34,7 +33,6 @@ namespace Internal {
class CMakeRunConfiguration : public ProjectExplorer::RunConfiguration
{
Q_OBJECT
friend class CMakeRunConfigurationWidget;
public:
explicit CMakeRunConfiguration(ProjectExplorer::Target *target);
@@ -56,13 +54,13 @@ public:
private:
bool fromMap(const QVariantMap &map) override;
void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &) override;
QString defaultDisplayName() const;
bool isBuildTargetValid() const;
void updateEnabledState() final;
QString extraId() const final;
QString baseWorkingDirectory() const;
QString m_buildSystemTarget;
QString m_executable;
QString m_title;
@@ -82,10 +80,6 @@ class CMakeRunConfigurationFactory : public ProjectExplorer::RunConfigurationFac
public:
CMakeRunConfigurationFactory();
QList<ProjectExplorer::RunConfigurationCreationInfo>
availableCreators(ProjectExplorer::Target *parent) const override;
bool canCreateHelper(ProjectExplorer::Target *parent, const QString &suffix) const override;
};
} // namespace Internal

View File

@@ -54,6 +54,7 @@ public:
Utils::FileName targetFilePath;
Utils::FileName projectFilePath;
Utils::FileName workingDirectory;
bool isQtcRunnable = true;
bool usesTerminal = false;

View File

@@ -550,7 +550,7 @@ RunConfiguration *RunConfigurationCreationInfo::create(Target *target) const
QTC_ASSERT(factory->canHandle(target), return nullptr);
QTC_ASSERT(id == factory->runConfigurationBaseId(), return nullptr);
if (!factory->canCreateHelper(target, extra))
if (!factory->canCreateHelper(target, targetName))
return nullptr;
QTC_ASSERT(factory->m_creator, return nullptr);
@@ -560,9 +560,9 @@ RunConfiguration *RunConfigurationCreationInfo::create(Target *target) const
// "FIX" ids by mangling in the extra data (build system target etc)
// for compatibility for the current format used in settings.
if (!extra.isEmpty()) {
if (!targetName.isEmpty()) {
QVariantMap data = rc->toMap();
data[ProjectConfiguration::settingsIdKey()] = id.withSuffix(extra).toString();
data[ProjectConfiguration::settingsIdKey()] = id.withSuffix(targetName).toString();
rc->fromMap(data);
}

View File

@@ -290,7 +290,7 @@ public:
CreationMode creationMode = AlwaysCreate,
bool useTerminal = false)
: factory(factory), id(id),
extra(extra),
targetName(extra),
displayName(displayName),
creationMode(creationMode),
useTerminal(useTerminal)
@@ -300,7 +300,7 @@ public:
const RunConfigurationFactory *factory = nullptr;
Core::Id id;
QString extra;
QString targetName;
QString displayName;
QString buildKey;
CreationMode creationMode = AlwaysCreate;

View File

@@ -564,7 +564,7 @@ void Target::updateDefaultRunConfigurations()
bool present = false;
for (const RunConfigurationCreationInfo &item : creators) {
QString rcExtraId = rc->extraId();
if (item.id == rc->id() && (item.extra == rcExtraId || item.buildKey == rcExtraId)) {
if (item.id == rc->id() && (item.targetName == rcExtraId || item.buildKey == rcExtraId)) {
existing.append(item);
present = true;
}
@@ -580,7 +580,7 @@ void Target::updateDefaultRunConfigurations()
continue;
bool exists = false;
for (const RunConfigurationCreationInfo &ex : existing) {
if (ex.id == item.id && ex.extra == item.extra)
if (ex.id == item.id && ex.targetName == item.targetName)
exists = true;
}
if (exists)

View File

@@ -204,7 +204,7 @@ void PythonRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInf
Environment sysEnv = Environment::systemEnvironment();
const QString exec = sysEnv.searchInPath("python").toString();
m_interpreter = exec.isEmpty() ? "python" : exec;
m_mainScript = info.extra;
m_mainScript = info.targetName;
setDefaultDisplayName(defaultDisplayName());
}