QMake: Adapt DesktopQMakeRunConfiguration to applicationTargets() use

Change-Id: I2844e2e97ca78c12c4abdb1538c37e77b841918e
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
hjk
2018-03-13 14:18:02 +01:00
parent e20d620043
commit 55961a367d
4 changed files with 112 additions and 178 deletions

View File

@@ -25,13 +25,13 @@
#include "desktopqmakerunconfiguration.h" #include "desktopqmakerunconfiguration.h"
#include "qmakebuildconfiguration.h"
#include "qmakenodes.h"
#include "qmakeproject.h"
#include "qmakeprojectmanagerconstants.h" #include "qmakeprojectmanagerconstants.h"
#include <coreplugin/variablechooser.h> #include <coreplugin/variablechooser.h>
#include <projectexplorer/localenvironmentaspect.h> #include <projectexplorer/localenvironmentaspect.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/runconfigurationaspects.h> #include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h> #include <qtsupport/qtkitinformation.h>
@@ -49,13 +49,11 @@
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <QCheckBox> #include <QCheckBox>
#include <QComboBox>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QFormLayout> #include <QFormLayout>
#include <QLabel> #include <QLabel>
#include <QLineEdit> #include <QLineEdit>
#include <QToolButton>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
@@ -69,7 +67,7 @@ const char USE_DYLD_IMAGE_SUFFIX_KEY[] = "Qt4ProjectManager.Qt4RunConfiguration.
const char USE_LIBRARY_SEARCH_PATH[] = "QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath"; const char USE_LIBRARY_SEARCH_PATH[] = "QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath";
// //
// QmakeRunConfiguration // DesktopQmakeRunConfiguration
// //
DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *target) DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *target)
@@ -108,9 +106,9 @@ void DesktopQmakeRunConfiguration::updateTargetInformation()
emit effectiveTargetInformationChanged(); emit effectiveTargetInformationChanged();
} }
////// //
/// DesktopQmakeRunConfigurationWidget // DesktopQmakeRunConfigurationWidget
///// //
DesktopQmakeRunConfigurationWidget::DesktopQmakeRunConfigurationWidget(DesktopQmakeRunConfiguration *qmakeRunConfiguration) DesktopQmakeRunConfigurationWidget::DesktopQmakeRunConfigurationWidget(DesktopQmakeRunConfiguration *qmakeRunConfiguration)
: m_qmakeRunConfiguration(qmakeRunConfiguration) : m_qmakeRunConfiguration(qmakeRunConfiguration)
@@ -243,25 +241,35 @@ QVariantMap DesktopQmakeRunConfiguration::toMap() const
bool DesktopQmakeRunConfiguration::fromMap(const QVariantMap &map) bool DesktopQmakeRunConfiguration::fromMap(const QVariantMap &map)
{ {
const bool res = RunConfiguration::fromMap(map);
if (!res)
return false;
const QDir projectDir = QDir(target()->project()->projectDirectory().toString()); const QDir projectDir = QDir(target()->project()->projectDirectory().toString());
m_proFilePath = Utils::FileName::fromUserInput(projectDir.filePath(map.value(QLatin1String(PRO_FILE_KEY)).toString())); m_proFilePath = Utils::FileName::fromUserInput(projectDir.filePath(map.value(QLatin1String(PRO_FILE_KEY)).toString()));
m_isUsingDyldImageSuffix = map.value(QLatin1String(USE_DYLD_IMAGE_SUFFIX_KEY), false).toBool(); m_isUsingDyldImageSuffix = map.value(QLatin1String(USE_DYLD_IMAGE_SUFFIX_KEY), false).toBool();
m_isUsingLibrarySearchPath = map.value(QLatin1String(USE_LIBRARY_SEARCH_PATH), true).toBool(); m_isUsingLibrarySearchPath = map.value(QLatin1String(USE_LIBRARY_SEARCH_PATH), true).toBool();
QString extraId = ProjectExplorer::idFromMap(map).suffixAfter(id());
if (!extraId.isEmpty())
m_proFilePath = FileName::fromString(extraId);
const bool res = RunConfiguration::fromMap(map);
updateTargetInformation(); updateTargetInformation();
return res; return true;
}
void DesktopQmakeRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &info)
{
m_proFilePath = FileName::fromString(info.buildKey);
updateTargetInformation();
} }
QString DesktopQmakeRunConfiguration::executable() const QString DesktopQmakeRunConfiguration::executable() const
{ {
if (QmakeProFile *pro = proFile()) BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(buildKey());
return extractWorkingDirAndExecutable(pro).second; return bti.targetFilePath.toString();
return QString(); }
QString DesktopQmakeRunConfiguration::baseWorkingDirectory() const
{
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(buildKey());
return bti.workingDirectory.toString();
} }
bool DesktopQmakeRunConfiguration::isUsingDyldImageSuffix() const bool DesktopQmakeRunConfiguration::isUsingDyldImageSuffix() const
@@ -290,54 +298,19 @@ void DesktopQmakeRunConfiguration::setUsingLibrarySearchPath(bool state)
return extraAspect<LocalEnvironmentAspect>()->environmentChanged(); return extraAspect<LocalEnvironmentAspect>()->environmentChanged();
} }
QString DesktopQmakeRunConfiguration::baseWorkingDirectory() const
{
if (QmakeProFile *pro = proFile())
return extractWorkingDirAndExecutable(pro).first;
return QString();
}
bool DesktopQmakeRunConfiguration::isConsoleApplication() const bool DesktopQmakeRunConfiguration::isConsoleApplication() const
{ {
if (QmakeProFile *pro = proFile()) { BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(buildKey());
const QStringList config = pro->variableValue(Variable::Config); return bti.usesTerminal;
if (!config.contains("console") || config.contains("testcase"))
return false;
const QStringList qt = pro->variableValue(Variable::Qt);
return !qt.contains("testlib") && !qt.contains("qmltest");
}
return false;
} }
void DesktopQmakeRunConfiguration::addToBaseEnvironment(Environment &env) const void DesktopQmakeRunConfiguration::addToBaseEnvironment(Environment &env) const
{ {
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(buildKey());
if (bti.runEnvModifier)
bti.runEnvModifier(env, m_isUsingLibrarySearchPath);
if (m_isUsingDyldImageSuffix) if (m_isUsingDyldImageSuffix)
env.set(QLatin1String("DYLD_IMAGE_SUFFIX"), QLatin1String("_debug")); env.set(QLatin1String("DYLD_IMAGE_SUFFIX"), QLatin1String("_debug"));
QStringList libraryPaths;
// The user could be linking to a library found via a -L/some/dir switch
// to find those libraries while actually running we explicitly prepend those
// dirs to the library search path
const QmakeProFile *pro = proFile();
if (m_isUsingLibrarySearchPath && pro) {
const QStringList libDirectories = pro->variableValue(Variable::LibDirectories);
if (!libDirectories.isEmpty()) {
const QString proDirectory = pro->buildDir().toString();
foreach (QString dir, libDirectories) {
// Fix up relative entries like "LIBS+=-L.."
const QFileInfo fi(dir);
if (!fi.isAbsolute())
dir = QDir::cleanPath(proDirectory + QLatin1Char('/') + dir);
libraryPaths << dir;
} // foreach
} // libDirectories
} // pro
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(target()->kit());
if (qtVersion && m_isUsingLibrarySearchPath)
libraryPaths << qtVersion->librarySearchPath().toString();
env.prependOrSetLibrarySearchPaths(libraryPaths);
} }
QString DesktopQmakeRunConfiguration::buildSystemTarget() const QString DesktopQmakeRunConfiguration::buildSystemTarget() const
@@ -345,9 +318,9 @@ QString DesktopQmakeRunConfiguration::buildSystemTarget() const
return m_proFilePath.toString(); return m_proFilePath.toString();
} }
Utils::FileName DesktopQmakeRunConfiguration::proFilePath() const QString DesktopQmakeRunConfiguration::buildKey() const
{ {
return m_proFilePath; return m_proFilePath.toString();
} }
bool DesktopQmakeRunConfiguration::canRunForNode(const Node *node) const bool DesktopQmakeRunConfiguration::canRunForNode(const Node *node) const
@@ -355,30 +328,11 @@ bool DesktopQmakeRunConfiguration::canRunForNode(const Node *node) const
return node->filePath() == m_proFilePath; return node->filePath() == m_proFilePath;
} }
QmakeProject *DesktopQmakeRunConfiguration::qmakeProject() const
{
return static_cast<QmakeProject *>(target()->project());
}
QmakeProFile *DesktopQmakeRunConfiguration::proFile() const
{
QmakeProject *project = qmakeProject();
QTC_ASSERT(project, return nullptr);
QmakeProFile *rootProFile = project->rootProFile();
return rootProFile ? rootProFile->findProFile(m_proFilePath) : nullptr;
}
QString DesktopQmakeRunConfiguration::defaultDisplayName() QString DesktopQmakeRunConfiguration::defaultDisplayName()
{ {
if (QmakeProFile *pro = proFile())
return pro->displayName();
QString defaultName;
if (!m_proFilePath.isEmpty()) if (!m_proFilePath.isEmpty())
defaultName = m_proFilePath.toFileInfo().completeBaseName(); return m_proFilePath.toFileInfo().completeBaseName();
else return tr("Qt Run Configuration");
defaultName = tr("Qt Run Configuration");
return defaultName;
} }
OutputFormatter *DesktopQmakeRunConfiguration::createOutputFormatter() const OutputFormatter *DesktopQmakeRunConfiguration::createOutputFormatter() const
@@ -386,52 +340,9 @@ OutputFormatter *DesktopQmakeRunConfiguration::createOutputFormatter() const
return new QtSupport::QtOutputFormatter(target()->project()); return new QtSupport::QtOutputFormatter(target()->project());
} }
QPair<QString, QString> DesktopQmakeRunConfiguration::extractWorkingDirAndExecutable(const QmakeProFile *proFile) const //
{ // DesktopQmakeRunConfigurationFactory
if (!proFile) //
return {};
TargetInformation ti = proFile->targetInformation();
if (!ti.valid)
return qMakePair(QString(), QString());
const QStringList &config = proFile->variableValue(Variable::Config);
QString destDir = ti.destDir.toString();
QString workingDir;
if (!destDir.isEmpty()) {
bool workingDirIsBaseDir = false;
if (destDir == ti.buildTarget)
workingDirIsBaseDir = true;
if (QDir::isRelativePath(destDir))
destDir = QDir::cleanPath(ti.buildDir.toString() + '/' + destDir);
if (workingDirIsBaseDir)
workingDir = ti.buildDir.toString();
else
workingDir = destDir;
} else {
destDir = ti.buildDir.toString();
workingDir = ti.buildDir.toString();
}
if (HostOsInfo::isMacHost() && config.contains(QLatin1String("app_bundle"))) {
const QString infix = QLatin1Char('/') + ti.target
+ QLatin1String(".app/Contents/MacOS");
workingDir += infix;
destDir += infix;
}
QString executable = QDir::cleanPath(destDir + QLatin1Char('/') + ti.target);
executable = HostOsInfo::withExecutableSuffix(executable);
//qDebug() << "##### QmakeRunConfiguration::extractWorkingDirAndExecutable:" workingDir << executable;
return qMakePair(workingDir, executable);
}
///
/// DesktopQmakeRunConfigurationFactory
/// This class is used to restore run settings (saved in .user files)
///
DesktopQmakeRunConfigurationFactory::DesktopQmakeRunConfigurationFactory() DesktopQmakeRunConfigurationFactory::DesktopQmakeRunConfigurationFactory()
{ {
@@ -440,20 +351,5 @@ DesktopQmakeRunConfigurationFactory::DesktopQmakeRunConfigurationFactory()
addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
} }
bool DesktopQmakeRunConfigurationFactory::canCreateHelper(Target *parent, const QString &buildTarget) const
{
QmakeProject *project = qobject_cast<QmakeProject *>(parent->project());
QTC_ASSERT(project, return {});
return project->hasApplicationProFile(Utils::FileName::fromString(buildTarget));
}
QList<RunConfigurationCreationInfo>
DesktopQmakeRunConfigurationFactory::availableCreators(Target *parent) const
{
QmakeProject *project = qobject_cast<QmakeProject *>(parent->project());
QTC_ASSERT(project, return {});
return project->runConfigurationCreators(this);
}
} // namespace Internal } // namespace Internal
} // namespace QmakeProjectManager } // namespace QmakeProjectManager

View File

@@ -39,17 +39,11 @@ class QLineEdit;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace QmakeProjectManager { namespace QmakeProjectManager {
class QmakeProFile;
class QmakeProject;
namespace Internal { namespace Internal {
class DesktopQmakeRunConfiguration : public ProjectExplorer::RunConfiguration class DesktopQmakeRunConfiguration : public ProjectExplorer::RunConfiguration
{ {
Q_OBJECT Q_OBJECT
// to change the display name and arguments and set the userenvironmentchanges
friend class DesktopQmakeRunConfigurationWidget;
public: public:
explicit DesktopQmakeRunConfiguration(ProjectExplorer::Target *target); explicit DesktopQmakeRunConfiguration(ProjectExplorer::Target *target);
@@ -65,8 +59,6 @@ public:
bool isUsingLibrarySearchPath() const; bool isUsingLibrarySearchPath() const;
void setUsingLibrarySearchPath(bool state); void setUsingLibrarySearchPath(bool state);
Utils::FileName proFilePath() const;
QVariantMap toMap() const override; QVariantMap toMap() const override;
Utils::OutputFormatter *createOutputFormatter() const override; Utils::OutputFormatter *createOutputFormatter() const override;
@@ -83,25 +75,20 @@ signals:
// Note: These signals might not get emitted for every change! // Note: These signals might not get emitted for every change!
void effectiveTargetInformationChanged(); void effectiveTargetInformationChanged();
protected: private:
bool fromMap(const QVariantMap &map) override; bool fromMap(const QVariantMap &map) override;
QString extraId() const override; QString extraId() const override;
void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &) override;
private:
void updateTargetInformation(); void updateTargetInformation();
QPair<QString, QString> extractWorkingDirAndExecutable(const QmakeProFile *proFile) const;
QString baseWorkingDirectory() const; QString baseWorkingDirectory() const;
QString defaultDisplayName(); QString defaultDisplayName();
bool isConsoleApplication() const; bool isConsoleApplication() const;
QmakeProject *qmakeProject() const;
QmakeProFile *proFile() const;
bool canRunForNode(const ProjectExplorer::Node *node) const final; bool canRunForNode(const ProjectExplorer::Node *node) const final;
QString buildKey() const;
void updateTarget();
Utils::FileName m_proFilePath; // Full path to the Application Pro File Utils::FileName m_proFilePath; // Full path to the Application Pro File
// Cached startup sub project information
bool m_isUsingDyldImageSuffix = false; bool m_isUsingDyldImageSuffix = false;
bool m_isUsingLibrarySearchPath = true; bool m_isUsingLibrarySearchPath = true;
}; };
@@ -136,11 +123,6 @@ class DesktopQmakeRunConfigurationFactory : public ProjectExplorer::RunConfigura
public: public:
DesktopQmakeRunConfigurationFactory(); DesktopQmakeRunConfigurationFactory();
bool canCreateHelper(ProjectExplorer::Target *parent, const QString &suffix) const override;
QList<ProjectExplorer::RunConfigurationCreationInfo>
availableCreators(ProjectExplorer::Target *parent) const override;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -1066,14 +1066,6 @@ QString QmakeProject::disabledReasonForRunConfiguration(const FileName &proFileP
.arg(proFilePath.fileName()); .arg(proFilePath.fileName());
} }
QString QmakeProject::buildNameFor(const Kit *k)
{
if (!k)
return QLatin1String("unknown");
return k->fileSystemFriendlyName();
}
void QmakeProject::updateBuildSystemData() void QmakeProject::updateBuildSystemData()
{ {
Target *const target = activeTarget(); Target *const target = activeTarget();
@@ -1088,10 +1080,77 @@ void QmakeProject::updateBuildSystemData()
target->setDeploymentData(deploymentData); target->setDeploymentData(deploymentData);
BuildTargetInfoList appTargetList; BuildTargetInfoList appTargetList;
for (const QmakeProFile * const file : applicationProFiles()) { for (const QmakeProFile * const proFile : applicationProFiles()) {
appTargetList.list << BuildTargetInfo(file->targetInformation().target, TargetInformation ti = proFile->targetInformation();
FileName::fromString(executableFor(file)), if (!ti.valid)
file->filePath()); continue;
const QStringList &config = proFile->variableValue(Variable::Config);
QString destDir = ti.destDir.toString();
QString workingDir;
if (!destDir.isEmpty()) {
bool workingDirIsBaseDir = false;
if (destDir == ti.buildTarget)
workingDirIsBaseDir = true;
if (QDir::isRelativePath(destDir))
destDir = QDir::cleanPath(ti.buildDir.toString() + '/' + destDir);
if (workingDirIsBaseDir)
workingDir = ti.buildDir.toString();
else
workingDir = destDir;
} else {
destDir = ti.buildDir.toString();
workingDir = ti.buildDir.toString();
}
if (HostOsInfo::isMacHost() && config.contains("app_bundle")) {
const QString infix = '/' + ti.target + ".app/Contents/MacOS";
workingDir += infix;
destDir += infix;
}
BuildTargetInfo bti;
bti.targetName = proFile->targetInformation().target;
bti.targetFilePath = FileName::fromString(executableFor(proFile));
bti.projectFilePath = proFile->filePath();
bti.workingDirectory = FileName::fromString(workingDir);
bti.displayName = proFile->filePath().toFileInfo().completeBaseName();
bti.buildKey = bti.projectFilePath.toString();
bti.isQtcRunnable = config.contains("qtc_runnable");
if (config.contains("console") && !config.contains("testcase")) {
const QStringList qt = proFile->variableValue(Variable::Qt);
bti.usesTerminal = !qt.contains("testlib") && !qt.contains("qmltest");
}
QStringList libraryPaths;
// The user could be linking to a library found via a -L/some/dir switch
// to find those libraries while actually running we explicitly prepend those
// dirs to the library search path
const QStringList libDirectories = proFile->variableValue(Variable::LibDirectories);
if (!libDirectories.isEmpty()) {
const QString proDirectory = proFile->buildDir().toString();
foreach (QString dir, libDirectories) {
// Fix up relative entries like "LIBS+=-L.."
const QFileInfo fi(dir);
if (!fi.isAbsolute())
dir = QDir::cleanPath(proDirectory + '/' + dir);
libraryPaths.append(dir);
}
}
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(target->kit());
if (qtVersion)
libraryPaths.append(qtVersion->librarySearchPath().toString());
bti.runEnvModifier = [libraryPaths](Environment &env, bool useLibrarySearchPath) {
if (useLibrarySearchPath)
env.prependOrSetLibrarySearchPaths(libraryPaths);
};
appTargetList.list.append(bti);
} }
target->setApplicationTargets(appTargetList); target->setApplicationTargets(appTargetList);
} }

View File

@@ -110,9 +110,6 @@ public:
/// \internal /// \internal
QString disabledReasonForRunConfiguration(const Utils::FileName &proFilePath); QString disabledReasonForRunConfiguration(const Utils::FileName &proFilePath);
/// used by the default implementation of shadowBuildDirectory
static QString buildNameFor(const ProjectExplorer::Kit *k);
void emitBuildDirectoryInitialized(); void emitBuildDirectoryInitialized();
static void proFileParseError(const QString &errorMessage); static void proFileParseError(const QString &errorMessage);