forked from qt-creator/qt-creator
QbsRunConfiguration: Re-model based on RemoteLinux precedence
Task-number: QTCREATORBUG-19985 Change-Id: Ifd95187b72fed3565552ecd14f3353b7e7df0069 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "projectexplorer_export.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QList>
|
||||
@@ -40,27 +41,31 @@ class PROJECTEXPLORER_EXPORT BuildTargetInfo
|
||||
public:
|
||||
BuildTargetInfo() = default;
|
||||
BuildTargetInfo(const QString &targetName, const Utils::FileName &targetFilePath,
|
||||
const Utils::FileName &projectFilePath) :
|
||||
const Utils::FileName &projectFilePath, bool isQtcRunnable = true) :
|
||||
targetName(targetName),
|
||||
targetFilePath(targetFilePath),
|
||||
projectFilePath(projectFilePath)
|
||||
projectFilePath(projectFilePath),
|
||||
isQtcRunnable(isQtcRunnable)
|
||||
{ }
|
||||
|
||||
QString targetName;
|
||||
QString displayName;
|
||||
QString buildKey; // Used to identify this BuildTargetInfo object in its list.
|
||||
|
||||
Utils::FileName targetFilePath;
|
||||
Utils::FileName projectFilePath;
|
||||
|
||||
bool isAutoRunnable = true;
|
||||
bool isQtcRunnable = true;
|
||||
bool usesTerminal = false;
|
||||
|
||||
bool isValid() const { return !targetName.isEmpty(); }
|
||||
std::function<void(Utils::Environment &, bool)> runEnvModifier;
|
||||
};
|
||||
|
||||
inline bool operator==(const BuildTargetInfo &ti1, const BuildTargetInfo &ti2)
|
||||
{
|
||||
return ti1.targetName == ti2.targetName && ti1.targetFilePath == ti2.targetFilePath
|
||||
return ti1.targetName == ti2.targetName
|
||||
&& ti1.displayName == ti2.displayName
|
||||
&& ti1.buildKey == ti2.buildKey
|
||||
&& ti1.targetFilePath == ti2.targetFilePath
|
||||
&& ti1.projectFilePath == ti2.projectFilePath;
|
||||
}
|
||||
|
||||
@@ -71,7 +76,7 @@ inline bool operator!=(const BuildTargetInfo &ti1, const BuildTargetInfo &ti2)
|
||||
|
||||
inline uint qHash(const BuildTargetInfo &ti)
|
||||
{
|
||||
return qHash(ti.targetName);
|
||||
return qHash(ti.targetName) ^ qHash(ti.displayName) ^ qHash(ti.buildKey);
|
||||
}
|
||||
|
||||
class PROJECTEXPLORER_EXPORT BuildTargetInfoList
|
||||
@@ -104,6 +109,12 @@ public:
|
||||
}).targetFilePath;
|
||||
}
|
||||
|
||||
BuildTargetInfo buildTargetInfo(const QString &buildKey) {
|
||||
return Utils::findOrDefault(list, [&buildKey](const BuildTargetInfo &ti) {
|
||||
return ti.buildKey == buildKey;
|
||||
});
|
||||
}
|
||||
|
||||
QList<BuildTargetInfo> list;
|
||||
};
|
||||
|
||||
|
@@ -470,14 +470,20 @@ QString RunConfigurationFactory::decoratedTargetName(const QString targetName, T
|
||||
QList<RunConfigurationCreationInfo>
|
||||
RunConfigurationFactory::availableCreators(Target *parent) const
|
||||
{
|
||||
return Utils::transform(parent->applicationTargets().list, [parent, this](const BuildTargetInfo &ti) {
|
||||
const QList<BuildTargetInfo> buildTargets = parent->applicationTargets().list;
|
||||
const bool hasAnyQtcRunnable = Utils::anyOf(buildTargets,
|
||||
Utils::equal(&BuildTargetInfo::isQtcRunnable, true));
|
||||
return Utils::transform(buildTargets, [&](const BuildTargetInfo &ti) {
|
||||
QString displayName = ti.displayName;
|
||||
if (displayName.isEmpty())
|
||||
displayName = decoratedTargetName(ti.targetName, parent);
|
||||
return RunConfigurationCreationInfo(this, m_runConfigBaseId, ti.targetName, displayName,
|
||||
ti.isAutoRunnable ? RunConfigurationCreationInfo::AlwaysCreate
|
||||
: RunConfigurationCreationInfo::ManualCreationOnly,
|
||||
ti.usesTerminal);
|
||||
RunConfigurationCreationInfo rci(this, m_runConfigBaseId, ti.targetName, displayName);
|
||||
rci.creationMode = ti.isQtcRunnable || !hasAnyQtcRunnable
|
||||
? RunConfigurationCreationInfo::AlwaysCreate
|
||||
: RunConfigurationCreationInfo::ManualCreationOnly;
|
||||
rci.useTerminal = ti.usesTerminal;
|
||||
rci.buildKey = ti.buildKey;
|
||||
return rci;
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -302,6 +302,7 @@ public:
|
||||
Core::Id id;
|
||||
QString extra;
|
||||
QString displayName;
|
||||
QString buildKey;
|
||||
CreationMode creationMode = AlwaysCreate;
|
||||
bool useTerminal = false;
|
||||
};
|
||||
|
@@ -563,7 +563,8 @@ void Target::updateDefaultRunConfigurations()
|
||||
foreach (RunConfiguration *rc, existingConfigured) {
|
||||
bool present = false;
|
||||
for (const RunConfigurationCreationInfo &item : creators) {
|
||||
if (item.id == rc->id() && item.extra == rc->extraId()) {
|
||||
QString rcExtraId = rc->extraId();
|
||||
if (item.id == rc->id() && (item.extra == rcExtraId || item.buildKey == rcExtraId)) {
|
||||
existing.append(item);
|
||||
present = true;
|
||||
}
|
||||
|
@@ -94,6 +94,8 @@ static const char CONFIG_SYSTEM_INCLUDEPATHS[] = "systemIncludePaths";
|
||||
static const char CONFIG_FRAMEWORKPATHS[] = "frameworkPaths";
|
||||
static const char CONFIG_SYSTEM_FRAMEWORKPATHS[] = "systemFrameworkPaths";
|
||||
|
||||
static QString rcNameSeparator() { return QLatin1String("---Qbs.RC.NameSeparator---"); }
|
||||
|
||||
class OpTimer
|
||||
{
|
||||
public:
|
||||
@@ -135,10 +137,18 @@ QbsProject::QbsProject(const FileName &fileName) :
|
||||
rebuildProjectTree();
|
||||
|
||||
connect(this, &Project::activeTargetChanged, this, &QbsProject::changeActiveTarget);
|
||||
connect(this, &Project::addedTarget,
|
||||
this, [this](Target *t) { m_qbsProjects.insert(t, qbs::Project()); });
|
||||
connect(this, &Project::removedTarget,
|
||||
this, [this](Target *t) {m_qbsProjects.remove(t); });
|
||||
connect(this, &Project::addedTarget, this, [this](Target *t) {
|
||||
m_qbsProjects.insert(t, qbs::Project());
|
||||
});
|
||||
connect(this, &Project::removedTarget, this, [this](Target *t) {
|
||||
const auto it = m_qbsProjects.find(t);
|
||||
QTC_ASSERT(it != m_qbsProjects.end(), return);
|
||||
if (it.value() == m_qbsProject) {
|
||||
m_qbsProject = qbs::Project();
|
||||
m_projectData = qbs::ProjectData();
|
||||
}
|
||||
m_qbsProjects.erase(it);
|
||||
});
|
||||
auto delayedParsing = [this]() {
|
||||
if (static_cast<ProjectConfiguration *>(sender())->isActive())
|
||||
delayParsing();
|
||||
@@ -1104,19 +1114,51 @@ void QbsProject::updateApplicationTargets()
|
||||
foreach (const qbs::ProductData &productData, m_projectData.allProducts()) {
|
||||
if (!productData.isEnabled() || !productData.isRunnable())
|
||||
continue;
|
||||
const QString displayName = productData.fullDisplayName();
|
||||
QString taName;
|
||||
const bool isQtcRunnable = productData.properties().value("qtcRunnable").toBool();
|
||||
const bool usesTerminal = productData.properties().value("consoleApplication").toBool();
|
||||
const QString projectFile = productData.location().filePath();
|
||||
QString targetFile;
|
||||
foreach (const qbs::ArtifactData &ta, productData.targetArtifacts()) {
|
||||
QTC_ASSERT(ta.isValid(), continue);
|
||||
if (ta.isExecutable()) {
|
||||
taName = ta.filePath();
|
||||
targetFile = ta.filePath();
|
||||
break;
|
||||
}
|
||||
}
|
||||
applications.list
|
||||
<< BuildTargetInfo(displayName, FileName::fromString(taName),
|
||||
FileName::fromString(productData.location().filePath()));
|
||||
BuildTargetInfo bti;
|
||||
bti.targetName = productData.fullDisplayName();
|
||||
bti.buildKey = QbsProject::uniqueProductName(productData)
|
||||
+ rcNameSeparator()
|
||||
+ productData.fullDisplayName();
|
||||
bti.targetFilePath = FileName::fromString(targetFile);
|
||||
bti.projectFilePath = FileName::fromString(projectFile);
|
||||
bti.isQtcRunnable = isQtcRunnable; // Fixed up below.
|
||||
bti.usesTerminal = usesTerminal;
|
||||
bti.displayName = productData.fullDisplayName();
|
||||
bti.runEnvModifier = [targetFile, productData, this](Utils::Environment &env, bool usingLibraryPaths) {
|
||||
QProcessEnvironment procEnv = env.toProcessEnvironment();
|
||||
procEnv.insert(QLatin1String("QBS_RUN_FILE_PATH"), targetFile);
|
||||
QStringList setupRunEnvConfig;
|
||||
if (!usingLibraryPaths)
|
||||
setupRunEnvConfig << QLatin1String("ignore-lib-dependencies");
|
||||
qbs::RunEnvironment qbsRunEnv = qbsProject().getRunEnvironment(productData,
|
||||
qbs::InstallOptions(), procEnv, setupRunEnvConfig, QbsManager::settings());
|
||||
qbs::ErrorInfo error;
|
||||
procEnv = qbsRunEnv.runEnvironment(&error);
|
||||
if (error.hasError()) {
|
||||
Core::MessageManager::write(tr("Error retrieving run environment: %1")
|
||||
.arg(error.toString()));
|
||||
}
|
||||
if (!procEnv.isEmpty()) {
|
||||
env = Utils::Environment();
|
||||
foreach (const QString &key, procEnv.keys())
|
||||
env.set(key, procEnv.value(key));
|
||||
}
|
||||
};
|
||||
|
||||
applications.list.append(bti);
|
||||
}
|
||||
if (activeTarget())
|
||||
activeTarget()->setApplicationTargets(applications);
|
||||
}
|
||||
|
||||
@@ -1129,6 +1171,7 @@ void QbsProject::updateDeploymentInfo()
|
||||
f.isExecutable() ? DeployableFile::TypeExecutable : DeployableFile::TypeNormal);
|
||||
}
|
||||
}
|
||||
if (activeTarget())
|
||||
activeTarget()->setDeploymentData(deploymentData);
|
||||
}
|
||||
|
||||
|
@@ -141,8 +141,8 @@ private:
|
||||
const QStringList &productNames, QString &error);
|
||||
|
||||
QHash<ProjectExplorer::Target *, qbs::Project> m_qbsProjects;
|
||||
qbs::Project m_qbsProject;
|
||||
qbs::ProjectData m_projectData;
|
||||
qbs::Project m_qbsProject; // for activeTarget()
|
||||
qbs::ProjectData m_projectData; // Cached m_qbsProject.projectData()
|
||||
QSet<Core::IDocument *> m_qbsDocuments;
|
||||
|
||||
QbsProjectParser *m_qbsProjectParser;
|
||||
|
@@ -26,42 +26,34 @@
|
||||
#include "qbsrunconfiguration.h"
|
||||
|
||||
#include "qbsprojectmanagerconstants.h"
|
||||
#include "qbsdeployconfigurationfactory.h"
|
||||
#include "qbsinstallstep.h"
|
||||
#include "qbsproject.h"
|
||||
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <coreplugin/variablechooser.h>
|
||||
|
||||
#include <projectexplorer/buildmanager.h>
|
||||
#include <projectexplorer/buildstep.h>
|
||||
#include <projectexplorer/buildsteplist.h>
|
||||
#include <projectexplorer/deployconfiguration.h>
|
||||
#include <projectexplorer/localenvironmentaspect.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/runconfigurationaspects.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/runconfigurationaspects.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/detailswidget.h>
|
||||
#include <utils/stringutils.h>
|
||||
#include <utils/persistentsettings.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
#include <qtsupport/qtoutputformatter.h>
|
||||
#include <qtsupport/qtsupportconstants.h>
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/detailswidget.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/persistentsettings.h>
|
||||
#include <utils/stringutils.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include "api/runenvironment.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QFormLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QCheckBox>
|
||||
#include <QToolButton>
|
||||
#include <QComboBox>
|
||||
#include <QDir>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
@@ -75,15 +67,6 @@ static QString rcNameSeparator() { return QLatin1String("---Qbs.RC.NameSeparator
|
||||
|
||||
static QString usingLibraryPathsKey() { return QString("Qbs.RunConfiguration.UsingLibraryPaths"); }
|
||||
|
||||
const qbs::ProductData findProduct(const qbs::ProjectData &pro, const QString &uniqeName)
|
||||
{
|
||||
foreach (const qbs::ProductData &product, pro.allProducts()) {
|
||||
if (QbsProject::uniqueProductName(product) == uniqeName)
|
||||
return product;
|
||||
}
|
||||
return qbs::ProductData();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// QbsRunConfiguration:
|
||||
// --------------------------------------------------------------------
|
||||
@@ -96,22 +79,22 @@ QbsRunConfiguration::QbsRunConfiguration(Target *target)
|
||||
static_cast<QbsRunConfiguration *>(rc)->addToBaseEnvironment(env);
|
||||
});
|
||||
addExtraAspect(envAspect);
|
||||
connect(static_cast<QbsProject *>(target->project()), &Project::parsingFinished, this,
|
||||
|
||||
connect(project(), &Project::parsingFinished, this,
|
||||
[envAspect]() { envAspect->buildEnvironmentHasChanged(); });
|
||||
addExtraAspect(new ArgumentsAspect(this, "Qbs.RunConfiguration.CommandLineArguments"));
|
||||
addExtraAspect(new WorkingDirectoryAspect(this, "Qbs.RunConfiguration.WorkingDirectory"));
|
||||
|
||||
addExtraAspect(new TerminalAspect(this, "Qbs.RunConfiguration.UseTerminal", isConsoleApplication()));
|
||||
|
||||
QbsProject *project = static_cast<QbsProject *>(target->project());
|
||||
connect(project, &Project::parsingFinished, this, [this](bool success) {
|
||||
connect(project(), &Project::parsingFinished, this, [this](bool success) {
|
||||
auto terminalAspect = extraAspect<TerminalAspect>();
|
||||
if (success && !terminalAspect->isUserSet())
|
||||
terminalAspect->setUseTerminal(isConsoleApplication());
|
||||
});
|
||||
connect(BuildManager::instance(), &BuildManager::buildStateChanged, this,
|
||||
[this, project](Project *p) {
|
||||
if (p == project && !BuildManager::isBuilding(p)) {
|
||||
[this](Project *p) {
|
||||
if (p == project() && !BuildManager::isBuilding(p)) {
|
||||
const QString defaultWorkingDir = baseWorkingDirectory();
|
||||
if (!defaultWorkingDir.isEmpty()) {
|
||||
extraAspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(
|
||||
@@ -122,8 +105,17 @@ QbsRunConfiguration::QbsRunConfiguration(Target *target)
|
||||
}
|
||||
);
|
||||
|
||||
connect(target, &Target::activeDeployConfigurationChanged,
|
||||
this, &QbsRunConfiguration::installStepChanged);
|
||||
connect(target, &Target::deploymentDataChanged,
|
||||
this, &QbsRunConfiguration::handleBuildSystemDataUpdated);
|
||||
connect(target, &Target::applicationTargetsChanged,
|
||||
this, &QbsRunConfiguration::handleBuildSystemDataUpdated);
|
||||
// Handles device changes, etc.
|
||||
connect(target, &Target::kitChanged,
|
||||
this, &QbsRunConfiguration::handleBuildSystemDataUpdated);
|
||||
}
|
||||
|
||||
QbsRunConfiguration::~QbsRunConfiguration()
|
||||
{
|
||||
}
|
||||
|
||||
QVariantMap QbsRunConfiguration::toMap() const
|
||||
@@ -138,16 +130,14 @@ bool QbsRunConfiguration::fromMap(const QVariantMap &map)
|
||||
if (!RunConfiguration::fromMap(map))
|
||||
return false;
|
||||
|
||||
QString extraId = ProjectExplorer::idFromMap(map).suffixAfter(id());
|
||||
if (!extraId.isEmpty()) {
|
||||
const int sepPos = extraId.indexOf(rcNameSeparator());
|
||||
m_uniqueProductName = extraId.left(sepPos);
|
||||
m_productDisplayName = sepPos == -1 ? QString() : extraId.mid(sepPos + rcNameSeparator().size());
|
||||
}
|
||||
m_buildKey = ProjectExplorer::idFromMap(map).suffixAfter(id());
|
||||
m_usingLibraryPaths = map.value(usingLibraryPathsKey(), true).toBool();
|
||||
|
||||
const int sepPos = m_buildKey.indexOf(rcNameSeparator());
|
||||
m_productDisplayName = sepPos == -1 ? QString() : m_buildKey.mid(sepPos + rcNameSeparator().size());
|
||||
m_uniqueProductName = m_buildKey.left(sepPos);
|
||||
|
||||
setDefaultDisplayName(defaultDisplayName());
|
||||
m_usingLibraryPaths = map.value(usingLibraryPathsKey(), true).toBool();
|
||||
installStepChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -157,59 +147,22 @@ QString QbsRunConfiguration::extraId() const
|
||||
return m_uniqueProductName + rcNameSeparator() + m_productDisplayName;
|
||||
}
|
||||
|
||||
void QbsRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &rci)
|
||||
{
|
||||
m_buildKey = rci.buildKey;
|
||||
|
||||
const int sepPos = m_buildKey.indexOf(rcNameSeparator());
|
||||
m_productDisplayName = sepPos == -1 ? QString() : m_buildKey.mid(sepPos + rcNameSeparator().size());
|
||||
m_uniqueProductName = m_buildKey.left(sepPos);
|
||||
|
||||
setDefaultDisplayName(defaultDisplayName());
|
||||
}
|
||||
|
||||
QWidget *QbsRunConfiguration::createConfigurationWidget()
|
||||
{
|
||||
return new QbsRunConfigurationWidget(this);
|
||||
}
|
||||
|
||||
void QbsRunConfiguration::installStepChanged()
|
||||
{
|
||||
if (m_currentInstallStep) {
|
||||
disconnect(m_currentInstallStep, &QbsInstallStep::changed,
|
||||
this, &QbsRunConfiguration::targetInformationChanged);
|
||||
}
|
||||
if (m_currentBuildStepList) {
|
||||
disconnect(m_currentBuildStepList, &BuildStepList::stepInserted,
|
||||
this, &QbsRunConfiguration::installStepChanged);
|
||||
disconnect(m_currentBuildStepList, &BuildStepList::stepRemoved,
|
||||
this, &QbsRunConfiguration::installStepChanged);
|
||||
disconnect(m_currentBuildStepList, &BuildStepList::stepMoved,
|
||||
this, &QbsRunConfiguration::installStepChanged);
|
||||
}
|
||||
|
||||
QbsDeployConfiguration *activeDc = qobject_cast<QbsDeployConfiguration *>(target()->activeDeployConfiguration());
|
||||
m_currentBuildStepList = activeDc ? activeDc->stepList() : 0;
|
||||
if (m_currentInstallStep) {
|
||||
connect(m_currentInstallStep, &QbsInstallStep::changed,
|
||||
this, &QbsRunConfiguration::targetInformationChanged);
|
||||
}
|
||||
if (m_currentBuildStepList) {
|
||||
connect(m_currentBuildStepList, &BuildStepList::stepInserted,
|
||||
this, &QbsRunConfiguration::installStepChanged);
|
||||
connect(m_currentBuildStepList, &BuildStepList::aboutToRemoveStep, this,
|
||||
&QbsRunConfiguration::installStepToBeRemoved);
|
||||
connect(m_currentBuildStepList, &BuildStepList::stepRemoved,
|
||||
this, &QbsRunConfiguration::installStepChanged);
|
||||
connect(m_currentBuildStepList, &BuildStepList::stepMoved,
|
||||
this, &QbsRunConfiguration::installStepChanged);
|
||||
}
|
||||
|
||||
emit targetInformationChanged();
|
||||
}
|
||||
|
||||
void QbsRunConfiguration::installStepToBeRemoved(int pos)
|
||||
{
|
||||
QTC_ASSERT(m_currentBuildStepList, return);
|
||||
// TODO: Our logic is rather broken. Users can create as many qbs install steps as they want,
|
||||
// but we ignore all but the first one.
|
||||
if (m_currentBuildStepList->steps().at(pos) != m_currentInstallStep)
|
||||
return;
|
||||
disconnect(m_currentInstallStep, &QbsInstallStep::changed,
|
||||
this, &QbsRunConfiguration::targetInformationChanged);
|
||||
m_currentInstallStep = 0;
|
||||
}
|
||||
|
||||
Runnable QbsRunConfiguration::runnable() const
|
||||
{
|
||||
StandardRunnable r;
|
||||
@@ -223,20 +176,14 @@ Runnable QbsRunConfiguration::runnable() const
|
||||
|
||||
QString QbsRunConfiguration::executable() const
|
||||
{
|
||||
QbsProject *pro = static_cast<QbsProject *>(target()->project());
|
||||
const qbs::ProductData product = findProduct(pro->qbsProjectData(), uniqueProductName());
|
||||
|
||||
if (!product.isValid() || !pro->qbsProject().isValid())
|
||||
return QString();
|
||||
|
||||
return product.targetExecutable();
|
||||
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey);
|
||||
return bti.targetFilePath.toString();
|
||||
}
|
||||
|
||||
bool QbsRunConfiguration::isConsoleApplication() const
|
||||
{
|
||||
QbsProject *pro = static_cast<QbsProject *>(target()->project());
|
||||
const qbs::ProductData product = findProduct(pro->qbsProjectData(), uniqueProductName());
|
||||
return product.properties().value(QLatin1String("consoleApplication"), false).toBool();
|
||||
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey);
|
||||
return bti.usesTerminal;
|
||||
}
|
||||
|
||||
void QbsRunConfiguration::setUsingLibraryPaths(bool useLibPaths)
|
||||
@@ -255,35 +202,14 @@ QString QbsRunConfiguration::baseWorkingDirectory() const
|
||||
|
||||
void QbsRunConfiguration::addToBaseEnvironment(Utils::Environment &env) const
|
||||
{
|
||||
QbsProject *project = static_cast<QbsProject *>(target()->project());
|
||||
if (project && project->qbsProject().isValid()) {
|
||||
const qbs::ProductData product = findProduct(project->qbsProjectData(), uniqueProductName());
|
||||
if (product.isValid()) {
|
||||
QProcessEnvironment procEnv = env.toProcessEnvironment();
|
||||
procEnv.insert(QLatin1String("QBS_RUN_FILE_PATH"), executable());
|
||||
QStringList setupRunEnvConfig;
|
||||
if (!m_usingLibraryPaths)
|
||||
setupRunEnvConfig << QLatin1String("ignore-lib-dependencies");
|
||||
qbs::RunEnvironment qbsRunEnv = project->qbsProject().getRunEnvironment(product,
|
||||
qbs::InstallOptions(), procEnv, setupRunEnvConfig, QbsManager::settings());
|
||||
qbs::ErrorInfo error;
|
||||
procEnv = qbsRunEnv.runEnvironment(&error);
|
||||
if (error.hasError()) {
|
||||
Core::MessageManager::write(tr("Error retrieving run environment: %1")
|
||||
.arg(error.toString()));
|
||||
}
|
||||
if (!procEnv.isEmpty()) {
|
||||
env = Utils::Environment();
|
||||
foreach (const QString &key, procEnv.keys())
|
||||
env.set(key, procEnv.value(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey);
|
||||
if (bti.runEnvModifier)
|
||||
bti.runEnvModifier(env, m_usingLibraryPaths);
|
||||
}
|
||||
|
||||
QString QbsRunConfiguration::buildSystemTarget() const
|
||||
{
|
||||
return m_productDisplayName;
|
||||
return m_buildKey;
|
||||
}
|
||||
|
||||
QString QbsRunConfiguration::uniqueProductName() const
|
||||
@@ -304,64 +230,78 @@ Utils::OutputFormatter *QbsRunConfiguration::createOutputFormatter() const
|
||||
return new QtSupport::QtOutputFormatter(target()->project());
|
||||
}
|
||||
|
||||
void QbsRunConfiguration::handleBuildSystemDataUpdated()
|
||||
{
|
||||
emit targetInformationChanged();
|
||||
emit enabledChanged();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// QbsRunConfigurationWidget:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
QbsRunConfigurationWidget::QbsRunConfigurationWidget(QbsRunConfiguration *rc)
|
||||
: m_rc(rc)
|
||||
class QbsRunConfigurationWidgetPrivate
|
||||
{
|
||||
auto vboxTopLayout = new QVBoxLayout(this);
|
||||
vboxTopLayout->setMargin(0);
|
||||
public:
|
||||
QbsRunConfiguration *runConfiguration = nullptr;
|
||||
QLabel *executableLineLabel = nullptr;
|
||||
};
|
||||
|
||||
QbsRunConfigurationWidget::QbsRunConfigurationWidget(QbsRunConfiguration *rc)
|
||||
: d(new QbsRunConfigurationWidgetPrivate)
|
||||
{
|
||||
d->runConfiguration = rc;
|
||||
|
||||
auto mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setMargin(0);
|
||||
|
||||
auto detailsContainer = new Utils::DetailsWidget(this);
|
||||
detailsContainer->setState(Utils::DetailsWidget::NoSummary);
|
||||
vboxTopLayout->addWidget(detailsContainer);
|
||||
|
||||
mainLayout->addWidget(detailsContainer);
|
||||
auto detailsWidget = new QWidget(detailsContainer);
|
||||
detailsContainer->setWidget(detailsWidget);
|
||||
auto toplayout = new QFormLayout(detailsWidget);
|
||||
toplayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
|
||||
toplayout->setMargin(0);
|
||||
|
||||
m_executableLineLabel = new QLabel(this);
|
||||
m_executableLineLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
setExecutableLineText();
|
||||
toplayout->addRow(tr("Executable:"), m_executableLineLabel);
|
||||
d->executableLineLabel = new QLabel(this);
|
||||
d->executableLineLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
toplayout->addRow(tr("Executable:"), d->executableLineLabel);
|
||||
|
||||
m_rc->extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(this, toplayout);
|
||||
m_rc->extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(this, toplayout);
|
||||
d->runConfiguration->extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(this, toplayout);
|
||||
d->runConfiguration->extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(this, toplayout);
|
||||
d->runConfiguration->extraAspect<TerminalAspect>()->addToMainConfigurationWidget(this, toplayout);
|
||||
|
||||
m_rc->extraAspect<TerminalAspect>()->addToMainConfigurationWidget(this, toplayout);
|
||||
m_usingLibPathsCheckBox = new QCheckBox(tr("Add library paths to run environment"));
|
||||
m_usingLibPathsCheckBox->setChecked(m_rc->usingLibraryPaths());
|
||||
connect(m_usingLibPathsCheckBox, &QCheckBox::toggled, m_rc,
|
||||
&QbsRunConfiguration::setUsingLibraryPaths);
|
||||
toplayout->addRow(QString(), m_usingLibPathsCheckBox);
|
||||
auto usingLibPathsCheckBox = new QCheckBox(tr("Add library paths to run environment"));
|
||||
usingLibPathsCheckBox->setChecked(d->runConfiguration->usingLibraryPaths());
|
||||
connect(usingLibPathsCheckBox, &QCheckBox::toggled,
|
||||
d->runConfiguration, &QbsRunConfiguration::setUsingLibraryPaths);
|
||||
toplayout->addRow(QString(), usingLibPathsCheckBox);
|
||||
|
||||
connect(m_rc, &QbsRunConfiguration::targetInformationChanged,
|
||||
connect(d->runConfiguration, &QbsRunConfiguration::targetInformationChanged,
|
||||
this, &QbsRunConfigurationWidget::targetInformationHasChanged, Qt::QueuedConnection);
|
||||
|
||||
connect(m_rc, &RunConfiguration::enabledChanged,
|
||||
connect(d->runConfiguration, &RunConfiguration::enabledChanged,
|
||||
this, &QbsRunConfigurationWidget::targetInformationHasChanged);
|
||||
targetInformationHasChanged();
|
||||
|
||||
Core::VariableChooser::addSupportForChildWidgets(this, rc->macroExpander());
|
||||
|
||||
targetInformationHasChanged();
|
||||
}
|
||||
|
||||
void QbsRunConfigurationWidget::targetInformationHasChanged()
|
||||
{
|
||||
m_ignoreChange = true;
|
||||
setExecutableLineText(m_rc->executable());
|
||||
WorkingDirectoryAspect *aspect = d->runConfiguration->extraAspect<WorkingDirectoryAspect>();
|
||||
aspect->pathChooser()->setBaseFileName(d->runConfiguration->target()->project()->projectDirectory());
|
||||
|
||||
WorkingDirectoryAspect *aspect = m_rc->extraAspect<WorkingDirectoryAspect>();
|
||||
aspect->pathChooser()->setBaseFileName(m_rc->target()->project()->projectDirectory());
|
||||
m_ignoreChange = false;
|
||||
QString text = d->runConfiguration->executable();
|
||||
d->executableLineLabel->setText(text.isEmpty() ? tr("<unknown>") : text);
|
||||
}
|
||||
|
||||
void QbsRunConfigurationWidget::setExecutableLineText(const QString &text)
|
||||
QbsRunConfigurationWidget::~QbsRunConfigurationWidget()
|
||||
{
|
||||
const QString newText = text.isEmpty() ? tr("<unknown>") : text;
|
||||
m_executableLineLabel->setText(newText);
|
||||
delete d;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -375,46 +315,5 @@ QbsRunConfigurationFactory::QbsRunConfigurationFactory()
|
||||
addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
|
||||
}
|
||||
|
||||
bool QbsRunConfigurationFactory::canCreateHelper(Target *parent, const QString &buildTarget) const
|
||||
{
|
||||
QbsProject *project = static_cast<QbsProject *>(parent->project());
|
||||
QString product = buildTarget.left(buildTarget.indexOf(rcNameSeparator()));
|
||||
return findProduct(project->qbsProjectData(), product).isValid();
|
||||
}
|
||||
|
||||
QList<RunConfigurationCreationInfo>
|
||||
QbsRunConfigurationFactory::availableCreators(Target *parent) const
|
||||
{
|
||||
QList<qbs::ProductData> products;
|
||||
|
||||
QbsProject *project = static_cast<QbsProject *>(parent->project());
|
||||
if (!project || !project->qbsProject().isValid())
|
||||
return {};
|
||||
|
||||
foreach (const qbs::ProductData &product, project->qbsProjectData().allProducts()) {
|
||||
if (product.isRunnable() && product.isEnabled())
|
||||
products << product;
|
||||
}
|
||||
|
||||
const auto isQtcRunnable = [](const qbs::ProductData &product) {
|
||||
return product.properties().value("qtcRunnable").toBool();
|
||||
};
|
||||
const bool hasAnyQtcRunnable = Utils::anyOf(products, isQtcRunnable);
|
||||
|
||||
return Utils::transform(products, [&](const qbs::ProductData &product) {
|
||||
const QString displayName = product.fullDisplayName();
|
||||
const QString targetName = QbsProject::uniqueProductName(product) + rcNameSeparator() + displayName;
|
||||
return RunConfigurationCreationInfo {
|
||||
this,
|
||||
runConfigurationBaseId(),
|
||||
targetName,
|
||||
displayName,
|
||||
(hasAnyQtcRunnable && !isQtcRunnable(product))
|
||||
? RunConfigurationCreationInfo::ManualCreationOnly
|
||||
: RunConfigurationCreationInfo::AlwaysCreate
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QbsProjectManager
|
||||
|
@@ -32,25 +32,19 @@
|
||||
#include <QStringList>
|
||||
#include <QWidget>
|
||||
|
||||
namespace qbs { class InstallOptions; }
|
||||
|
||||
namespace ProjectExplorer { class BuildStepList; }
|
||||
|
||||
namespace QbsProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class QbsInstallStep;
|
||||
|
||||
class QbsRunConfiguration : public ProjectExplorer::RunConfiguration
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// to change the display name and arguments and set the userenvironmentchanges
|
||||
friend class QbsRunConfigurationWidget;
|
||||
friend class ProjectExplorer::RunConfigurationFactory;
|
||||
|
||||
public:
|
||||
explicit QbsRunConfiguration(ProjectExplorer::Target *target);
|
||||
~QbsRunConfiguration();
|
||||
|
||||
QWidget *createConfigurationWidget() override;
|
||||
|
||||
@@ -72,22 +66,23 @@ signals:
|
||||
void usingDyldImageSuffixChanged(bool);
|
||||
|
||||
private:
|
||||
QVariantMap toMap() const final;
|
||||
QVariantMap toMap() const;
|
||||
bool fromMap(const QVariantMap &map) final;
|
||||
QString extraId() const final;
|
||||
void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &rci);
|
||||
|
||||
void installStepChanged();
|
||||
void installStepToBeRemoved(int pos);
|
||||
QString baseWorkingDirectory() const;
|
||||
QString defaultDisplayName();
|
||||
void handleBuildSystemDataUpdated();
|
||||
|
||||
void updateTarget();
|
||||
|
||||
QbsInstallStep *m_currentInstallStep = nullptr; // We do not take ownership!
|
||||
ProjectExplorer::BuildStepList *m_currentBuildStepList = nullptr; // We do not take ownership!
|
||||
QString m_uniqueProductName;
|
||||
QString m_productDisplayName;
|
||||
bool m_usingLibraryPaths = true;
|
||||
|
||||
QString m_buildKey;
|
||||
|
||||
// m_buildKey consists of the two below initially, but
|
||||
// m_productDisplayName main be changed for clones etc.
|
||||
QString m_productDisplayName;
|
||||
QString m_uniqueProductName;
|
||||
};
|
||||
|
||||
class QbsRunConfigurationWidget : public QWidget
|
||||
@@ -95,31 +90,19 @@ class QbsRunConfigurationWidget : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QbsRunConfigurationWidget(QbsRunConfiguration *rc);
|
||||
explicit QbsRunConfigurationWidget(QbsRunConfiguration *rc);
|
||||
~QbsRunConfigurationWidget();
|
||||
|
||||
private:
|
||||
void runConfigurationEnabledChange();
|
||||
void targetInformationHasChanged();
|
||||
void setExecutableLineText(const QString &text = QString());
|
||||
|
||||
QbsRunConfiguration *m_rc;
|
||||
QLabel *m_executableLineLabel;
|
||||
QCheckBox *m_usingLibPathsCheckBox;
|
||||
bool m_ignoreChange = false;
|
||||
bool m_isShown = false;
|
||||
class QbsRunConfigurationWidgetPrivate * const d;
|
||||
};
|
||||
|
||||
class QbsRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QbsRunConfigurationFactory();
|
||||
|
||||
bool canCreateHelper(ProjectExplorer::Target *parent, const QString &suffix) const override;
|
||||
|
||||
QList<ProjectExplorer::RunConfigurationCreationInfo>
|
||||
availableCreators(ProjectExplorer::Target *parent) const override;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
Reference in New Issue
Block a user