diff options
author | hjk <hjk@qt.io> | 2019-08-06 16:50:30 +0200 |
---|---|---|
committer | hjk <hjk@qt.io> | 2019-08-07 10:35:41 +0000 |
commit | 07a918c89a0993f4c9568920d1155ff6c831fbf7 (patch) | |
tree | fb72827341f9de72c3b1e12c3533de48ff393502 /src/plugins/qtsupport | |
parent | 2521023627066ba6dd6f6446f2ad6a6f144efc01 (diff) | |
download | qt-creator-07a918c89a0993f4c9568920d1155ff6c831fbf7.tar.gz |
Unification of desktop run configurations, step 1
First step, move {DesktopQt,Qbs,CMake}RunConfiguration{,Factory}
into the same new files.
This only moves down to QtSupport, not ProjectExplorer, as there
are in all three cases direct dependencies on QtSupport. Long term
I would expect them to move further down.
Change-Id: Ib16b19df7f3f642ed7f7db89a1f6904601d976ba
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/plugins/qtsupport')
-rw-r--r-- | src/plugins/qtsupport/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/qtsupport/desktoprunconfiguration.cpp | 332 | ||||
-rw-r--r-- | src/plugins/qtsupport/desktoprunconfiguration.h | 103 | ||||
-rw-r--r-- | src/plugins/qtsupport/qtsupport.pro | 6 | ||||
-rw-r--r-- | src/plugins/qtsupport/qtsupport.qbs | 2 | ||||
-rw-r--r-- | src/plugins/qtsupport/qtsupportplugin.cpp | 15 |
6 files changed, 457 insertions, 2 deletions
diff --git a/src/plugins/qtsupport/CMakeLists.txt b/src/plugins/qtsupport/CMakeLists.txt index 125e949b35..c2b46010b0 100644 --- a/src/plugins/qtsupport/CMakeLists.txt +++ b/src/plugins/qtsupport/CMakeLists.txt @@ -9,6 +9,7 @@ add_qtc_plugin(QtSupport codegensettingspage.cpp codegensettingspage.h codegensettingspagewidget.ui desktopqtversion.cpp desktopqtversion.h + desktoprunconfiguration.cpp desktoprunconfiguration.h exampleslistmodel.cpp exampleslistmodel.h gettingstartedwelcomepage.cpp gettingstartedwelcomepage.h profilereader.cpp profilereader.h diff --git a/src/plugins/qtsupport/desktoprunconfiguration.cpp b/src/plugins/qtsupport/desktoprunconfiguration.cpp new file mode 100644 index 0000000000..a7d9f4452a --- /dev/null +++ b/src/plugins/qtsupport/desktoprunconfiguration.cpp @@ -0,0 +1,332 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "desktoprunconfiguration.h" + +#include "qtkitinformation.h" +#include "qtoutputformatter.h" + +#include <projectexplorer/localenvironmentaspect.h> +#include <projectexplorer/project.h> +#include <projectexplorer/runconfigurationaspects.h> +#include <projectexplorer/target.h> + +#include <cmakeprojectmanager/cmakeprojectconstants.h> +#include <qbsprojectmanager/qbsprojectmanagerconstants.h> +#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h> + +#include <utils/fileutils.h> +#include <utils/pathchooser.h> +#include <utils/qtcassert.h> +#include <utils/stringutils.h> + +#include <QFileInfo> + +using namespace ProjectExplorer; +using namespace Utils; + +namespace QtSupport { +namespace Internal { + +// DesktopQmakeRunConfiguration + +DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *target, Core::Id id) + : RunConfiguration(target, id) +{ + auto envAspect = addAspect<LocalEnvironmentAspect>(target); + envAspect->addModifier([this](Environment &env) { + BuildTargetInfo bti = buildTargetInfo(); + if (bti.runEnvModifier) + bti.runEnvModifier(env, aspect<UseLibraryPathsAspect>()->value()); + }); + + addAspect<ExecutableAspect>(); + addAspect<ArgumentsAspect>(); + addAspect<WorkingDirectoryAspect>(); + addAspect<TerminalAspect>(); + + setOutputFormatter<QtSupport::QtOutputFormatter>(); + + auto libAspect = addAspect<UseLibraryPathsAspect>(); + connect(libAspect, &UseLibraryPathsAspect::changed, + envAspect, &EnvironmentAspect::environmentChanged); + + if (HostOsInfo::isMacHost()) { + auto dyldAspect = addAspect<UseDyldSuffixAspect>(); + connect(dyldAspect, &UseLibraryPathsAspect::changed, + envAspect, &EnvironmentAspect::environmentChanged); + envAspect->addModifier([dyldAspect](Environment &env) { + if (dyldAspect->value()) + env.set(QLatin1String("DYLD_IMAGE_SUFFIX"), QLatin1String("_debug")); + }); + } + + connect(target->project(), &Project::parsingFinished, + this, &DesktopQmakeRunConfiguration::updateTargetInformation); +} + +void DesktopQmakeRunConfiguration::updateTargetInformation() +{ + setDefaultDisplayName(defaultDisplayName()); + aspect<EnvironmentAspect>()->environmentChanged(); + + BuildTargetInfo bti = buildTargetInfo(); + + auto wda = aspect<WorkingDirectoryAspect>(); + wda->setDefaultWorkingDirectory(bti.workingDirectory); + if (wda->pathChooser()) + wda->pathChooser()->setBaseFileName(target()->project()->projectDirectory()); + + auto terminalAspect = aspect<TerminalAspect>(); + terminalAspect->setUseTerminalHint(bti.usesTerminal); + + aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath); +} + +bool DesktopQmakeRunConfiguration::fromMap(const QVariantMap &map) +{ + if (!RunConfiguration::fromMap(map)) + return false; + updateTargetInformation(); + return true; +} + +void DesktopQmakeRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &) +{ + updateTargetInformation(); +} + +FilePath DesktopQmakeRunConfiguration::proFilePath() const +{ + return FilePath::fromString(buildKey()); +} + +QString DesktopQmakeRunConfiguration::defaultDisplayName() +{ + FilePath profile = proFilePath(); + if (!profile.isEmpty()) + return profile.toFileInfo().completeBaseName(); + return tr("Qt Run Configuration"); +} + + +// Qbs + +QbsRunConfiguration::QbsRunConfiguration(Target *target, Core::Id id) + : RunConfiguration(target, id) +{ + auto envAspect = addAspect<LocalEnvironmentAspect>(target); + envAspect->addModifier([this](Environment &env) { + bool usingLibraryPaths = aspect<UseLibraryPathsAspect>()->value(); + + BuildTargetInfo bti = buildTargetInfo(); + if (bti.runEnvModifier) + bti.runEnvModifier(env, usingLibraryPaths); + }); + + addAspect<ExecutableAspect>(); + addAspect<ArgumentsAspect>(); + addAspect<WorkingDirectoryAspect>(); + addAspect<TerminalAspect>(); + + setOutputFormatter<QtSupport::QtOutputFormatter>(); + + auto libAspect = addAspect<UseLibraryPathsAspect>(); + connect(libAspect, &UseLibraryPathsAspect::changed, + envAspect, &EnvironmentAspect::environmentChanged); + if (HostOsInfo::isMacHost()) { + auto dyldAspect = addAspect<UseDyldSuffixAspect>(); + connect(dyldAspect, &UseDyldSuffixAspect::changed, + envAspect, &EnvironmentAspect::environmentChanged); + envAspect->addModifier([dyldAspect](Environment &env) { + if (dyldAspect->value()) + env.set("DYLD_IMAGE_SUFFIX", "_debug"); + }); + } + + connect(project(), &Project::parsingFinished, + envAspect, &EnvironmentAspect::environmentChanged); + + connect(target, &Target::deploymentDataChanged, + this, &QbsRunConfiguration::updateTargetInformation); + connect(target, &Target::applicationTargetsChanged, + this, &QbsRunConfiguration::updateTargetInformation); + // Handles device changes, etc. + connect(target, &Target::kitChanged, + this, &QbsRunConfiguration::updateTargetInformation); + + connect(target->project(), &Project::parsingFinished, + this, &QbsRunConfiguration::updateTargetInformation); +} + +QVariantMap QbsRunConfiguration::toMap() const +{ + return RunConfiguration::toMap(); +} + +bool QbsRunConfiguration::fromMap(const QVariantMap &map) +{ + if (!RunConfiguration::fromMap(map)) + return false; + + updateTargetInformation(); + return true; +} + +void QbsRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &info) +{ + setDefaultDisplayName(info.displayName); + updateTargetInformation(); +} + +Utils::FilePath QbsRunConfiguration::executableToRun(const BuildTargetInfo &targetInfo) const +{ + const FilePath appInBuildDir = targetInfo.targetFilePath; + if (target()->deploymentData().localInstallRoot().isEmpty()) + return appInBuildDir; + const QString deployedAppFilePath = target()->deploymentData() + .deployableForLocalFile(appInBuildDir.toString()).remoteFilePath(); + if (deployedAppFilePath.isEmpty()) + return appInBuildDir; + const FilePath appInLocalInstallDir = target()->deploymentData().localInstallRoot() + + deployedAppFilePath; + return appInLocalInstallDir.exists() ? appInLocalInstallDir : appInBuildDir; +} + +void QbsRunConfiguration::updateTargetInformation() +{ + BuildTargetInfo bti = buildTargetInfo(); + setDefaultDisplayName(bti.displayName); + const FilePath executable = executableToRun(bti); + auto terminalAspect = aspect<TerminalAspect>(); + terminalAspect->setUseTerminalHint(bti.usesTerminal); + + aspect<ExecutableAspect>()->setExecutable(executable); + + if (!executable.isEmpty()) { + QString defaultWorkingDir = QFileInfo(executable.toString()).absolutePath(); + if (!defaultWorkingDir.isEmpty()) { + auto wdAspect = aspect<WorkingDirectoryAspect>(); + wdAspect->setDefaultWorkingDirectory(FilePath::fromString(defaultWorkingDir)); + } + } + + emit enabledChanged(); +} + +// CMakeRunConfiguration + +CMakeRunConfiguration::CMakeRunConfiguration(Target *target, Core::Id id) + : RunConfiguration(target, id) +{ + auto envAspect = addAspect<LocalEnvironmentAspect>(target); + + // Workaround for QTCREATORBUG-19354: + if (HostOsInfo::isWindowsHost()) { + envAspect->addModifier([target](Environment &env) { + const Kit *k = target->kit(); + if (const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k)) { + const QString installBinPath = qt->qmakeProperty("QT_INSTALL_BINS"); + env.prependOrSetPath(installBinPath); + } + }); + } + + addAspect<ExecutableAspect>(); + addAspect<ArgumentsAspect>(); + addAspect<WorkingDirectoryAspect>(); + addAspect<TerminalAspect>(); + + connect(target->project(), &Project::parsingFinished, + this, &CMakeRunConfiguration::updateTargetInformation); + + if (QtSupport::QtKitAspect::qtVersion(target->kit())) + setOutputFormatter<QtSupport::QtOutputFormatter>(); +} + +void CMakeRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &info) +{ + Q_UNUSED(info) + updateTargetInformation(); +} + +bool CMakeRunConfiguration::isBuildTargetValid() const +{ + return Utils::anyOf(target()->applicationTargets(), [this](const BuildTargetInfo &bti) { + return bti.buildKey == buildKey(); + }); +} + +void CMakeRunConfiguration::updateEnabledState() +{ + if (!isBuildTargetValid()) + setEnabled(false); + else + RunConfiguration::updateEnabledState(); +} + +QString CMakeRunConfiguration::disabledReason() const +{ + if (!isBuildTargetValid()) + return tr("The project no longer builds the target associated with this run configuration."); + return RunConfiguration::disabledReason(); +} + +void CMakeRunConfiguration::updateTargetInformation() +{ + BuildTargetInfo bti = buildTargetInfo(); + aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath); + aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(bti.workingDirectory); + aspect<LocalEnvironmentAspect>()->environmentChanged(); + + auto terminalAspect = aspect<TerminalAspect>(); + terminalAspect->setUseTerminalHint(bti.usesTerminal); +} + +// Factory + +CMakeRunConfigurationFactory::CMakeRunConfigurationFactory() +{ + registerRunConfiguration<CMakeRunConfiguration>("CMakeProjectManager.CMakeRunConfiguration."); + addSupportedProjectType(CMakeProjectManager::Constants::CMAKEPROJECT_ID); + addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); +} + +QbsRunConfigurationFactory::QbsRunConfigurationFactory() +{ + registerRunConfiguration<QbsRunConfiguration>("Qbs.RunConfiguration:"); + addSupportedProjectType(QbsProjectManager::Constants::PROJECT_ID); + addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); +} + +DesktopQmakeRunConfigurationFactory::DesktopQmakeRunConfigurationFactory() +{ + registerRunConfiguration<DesktopQmakeRunConfiguration>("Qt4ProjectManager.Qt4RunConfiguration:"); + addSupportedProjectType(QmakeProjectManager::Constants::QMAKEPROJECT_ID); + addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); +} + +} // namespace Internal +} // namespace ProjectExplorer diff --git a/src/plugins/qtsupport/desktoprunconfiguration.h b/src/plugins/qtsupport/desktoprunconfiguration.h new file mode 100644 index 0000000000..52960045a3 --- /dev/null +++ b/src/plugins/qtsupport/desktoprunconfiguration.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "qtsupport_global.h" + +#include "projectexplorer/runconfigurationaspects.h" + +namespace QtSupport { +namespace Internal { + +class DesktopQmakeRunConfiguration : public ProjectExplorer::RunConfiguration +{ + Q_OBJECT + +public: + DesktopQmakeRunConfiguration(ProjectExplorer::Target *target, Core::Id id); + +private: + void updateTargetInformation(); + bool fromMap(const QVariantMap &map) final; + void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &info) final; + + QString defaultDisplayName(); + Utils::FilePath proFilePath() const; +}; + +class QbsRunConfiguration : public ProjectExplorer::RunConfiguration +{ + Q_OBJECT + +public: + QbsRunConfiguration(ProjectExplorer::Target *target, Core::Id id); + +private: + Utils::FilePath executableToRun(const ProjectExplorer::BuildTargetInfo &targetInfo) const; + QVariantMap toMap() const final; + bool fromMap(const QVariantMap &map) final; + void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &rci) final; + + void updateTargetInformation(); +}; + +class CMakeRunConfiguration : public ProjectExplorer::RunConfiguration +{ + Q_OBJECT + +public: + CMakeRunConfiguration(ProjectExplorer::Target *target, Core::Id id); + +private: + QString disabledReason() const override; + + void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &) override; + bool isBuildTargetValid() const; + void updateTargetInformation(); + + void updateEnabledState() final; +}; + +class DesktopQmakeRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory +{ +public: + DesktopQmakeRunConfigurationFactory(); +}; + +class QbsRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory +{ +public: + QbsRunConfigurationFactory(); +}; + +class CMakeRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory +{ +public: + CMakeRunConfigurationFactory(); +}; + +} // namespace Internal +} // namespace QtSupport diff --git a/src/plugins/qtsupport/qtsupport.pro b/src/plugins/qtsupport/qtsupport.pro index 4c5900027f..fb7cbc20e2 100644 --- a/src/plugins/qtsupport/qtsupport.pro +++ b/src/plugins/qtsupport/qtsupport.pro @@ -31,7 +31,8 @@ HEADERS += \ qtconfigwidget.h \ desktopqtversion.h \ uicgenerator.h \ - qscxmlcgenerator.h + qscxmlcgenerator.h \ + desktoprunconfiguration.h SOURCES += \ codegenerator.cpp \ @@ -56,7 +57,8 @@ SOURCES += \ qtconfigwidget.cpp \ desktopqtversion.cpp \ uicgenerator.cpp \ - qscxmlcgenerator.cpp + qscxmlcgenerator.cpp \ + desktoprunconfiguration.cpp FORMS += \ codegensettingspagewidget.ui \ diff --git a/src/plugins/qtsupport/qtsupport.qbs b/src/plugins/qtsupport/qtsupport.qbs index 7e2aa71e32..1087304be6 100644 --- a/src/plugins/qtsupport/qtsupport.qbs +++ b/src/plugins/qtsupport/qtsupport.qbs @@ -67,6 +67,8 @@ Project { "codegensettingspage.cpp", "codegensettingspage.h", "codegensettingspagewidget.ui", + "desktoprunconfiguration.cpp", + "desktoprunconfiguration.h", "qtconfigwidget.cpp", "qtconfigwidget.h", "qtcppkitinfo.cpp", diff --git a/src/plugins/qtsupport/qtsupportplugin.cpp b/src/plugins/qtsupport/qtsupportplugin.cpp index a143db76b3..d1d4ca75f5 100644 --- a/src/plugins/qtsupport/qtsupportplugin.cpp +++ b/src/plugins/qtsupport/qtsupportplugin.cpp @@ -38,6 +38,7 @@ #include "qscxmlcgenerator.h" #include "desktopqtversion.h" +#include "desktoprunconfiguration.h" #include "profilereader.h" #include <coreplugin/icore.h> @@ -45,6 +46,7 @@ #include <projectexplorer/project.h> #include <projectexplorer/projecttree.h> +#include <projectexplorer/runcontrol.h> #include <projectexplorer/target.h> #include <utils/macroexpander.h> @@ -53,6 +55,7 @@ const char kHostBins[] = "CurrentProject:QT_HOST_BINS"; const char kInstallBins[] = "CurrentProject:QT_INSTALL_BINS"; using namespace Core; +using namespace ProjectExplorer; namespace QtSupport { namespace Internal { @@ -66,6 +69,18 @@ public: CodeGenSettingsPage codeGenSettingsPage; QtOptionsPage qtOptionsPage; + DesktopQmakeRunConfigurationFactory desktopQmakeRunConfigFactory; + SimpleRunWorkerFactory<SimpleTargetRunner, DesktopQmakeRunConfiguration> + desktopQmakeRunWorkerFactory; + + QbsRunConfigurationFactory desktopQbsRunConfigFactory; + SimpleRunWorkerFactory<SimpleTargetRunner, QbsRunConfiguration> + desktopQbsRunWorkerFactory; + + CMakeRunConfigurationFactory desktopCMakeRunConfigFactory; + SimpleRunWorkerFactory<SimpleTargetRunner, CMakeRunConfiguration> + desktopCMakeRunWorkerFactory; + ExamplesWelcomePage examplesPage{true}; ExamplesWelcomePage tutorialPage{false}; |