diff options
author | Christian Kandeler <[email protected]> | 2025-02-24 14:05:09 +0100 |
---|---|---|
committer | Christian Kandeler <[email protected]> | 2025-03-06 11:41:40 +0000 |
commit | afb8292d671ad87d85753fd0f6b4167d829e66dc (patch) | |
tree | 5e8a79a0fa05375ecc9268178b180b88978d5b54 | |
parent | 3ba55ce1a636921ab29cfe852f5234dc78f678da (diff) |
ProjectExplorer: Make run configurations per build configuration
Fixes: QTCREATORBUG-20986
Task-number: QTCREATORBUG-32380
Change-Id: Id5bcb8fcc6d97375f15a1266ae040ea637df9683
Reviewed-by: hjk <[email protected]>
Reviewed-by: Christian Stenger <[email protected]>
62 files changed, 801 insertions, 895 deletions
diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index eacb7232a2f..3951617becc 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -158,7 +158,7 @@ QVariant LibraryListModel::data(const QModelIndex &index, int role) const void LibraryListModel::addEntries(const QStringList &list) { - const QString buildKey = m_buildSystem->target()->activeBuildKey(); + const QString buildKey = m_buildSystem->buildConfiguration()->activeBuildKey(); const ProjectNode *node = m_buildSystem->project()->findNodeForBuildKey(buildKey); QTC_ASSERT(node, return); @@ -198,13 +198,13 @@ void LibraryListModel::removeEntries(QModelIndexList list) endRemoveRows(); } - const QString buildKey = m_buildSystem->target()->activeBuildKey(); + const QString buildKey = m_buildSystem->buildConfiguration()->activeBuildKey(); m_buildSystem->setExtraData(buildKey, Constants::AndroidExtraLibs, m_entries); } void LibraryListModel::updateModel() { - const QString buildKey = m_buildSystem->target()->activeBuildKey(); + const QString buildKey = m_buildSystem->buildConfiguration()->activeBuildKey(); const ProjectNode *node = m_buildSystem->project()->findNodeForBuildKey(buildKey); if (!node) return; @@ -530,8 +530,7 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step) removeLibButton->setEnabled(libSelection->hasSelection()); }); - Target *target = m_step->target(); - const QString buildKey = target->activeBuildKey(); + const QString buildKey = m_step->buildConfiguration()->activeBuildKey(); const ProjectNode *node = m_step->project()->findNodeForBuildKey(buildKey); additionalLibrariesGroup->setEnabled(node && !node->parseInProgress()); @@ -685,7 +684,7 @@ static QString packageSubPath(const AndroidBuildApkStep *step) static FilePath packagePath(const AndroidBuildApkStep *step) { - return androidBuildDirectory(step->target()) / "build/outputs" / packageSubPath(step); + return androidBuildDirectory(step->buildConfiguration()) / "build/outputs" / packageSubPath(step); } bool AndroidBuildApkStep::init() @@ -717,7 +716,7 @@ bool AndroidBuildApkStep::init() } const int minSDKForKit = minimumSDK(kit()); - if (minimumSDK(target()) < minSDKForKit) { + if (minimumSDK(buildConfiguration()) < minSDKForKit) { const QString error = Tr::tr("The API level set for the APK is less than the minimum required by the kit." "\nThe minimum API level required by the kit is %1.") @@ -727,18 +726,19 @@ bool AndroidBuildApkStep::init() } m_openPackageLocationForRun = openPackageLocation(); - const FilePath outputDir = androidBuildDirectory(target()); + const FilePath outputDir = androidBuildDirectory(buildConfiguration()); m_packagePath = packagePath(this); qCDebug(buildapkstepLog).noquote() << "APK or AAB path:" << m_packagePath.toUserOutput(); FilePath command = version->hostBinPath().pathAppended("androiddeployqt").withExecutableSuffix(); - m_inputFile = AndroidQtVersion::androidDeploymentSettings(target()); + m_inputFile = AndroidQtVersion::androidDeploymentSettings(buildConfiguration()); if (m_inputFile.isEmpty()) { m_skipBuilding = true; - reportWarningOrError(Tr::tr("No valid input file for \"%1\".").arg(target()->activeBuildKey()), - Task::Warning); + reportWarningOrError( + Tr::tr("No valid input file for \"%1\".").arg(buildConfiguration()->activeBuildKey()), + Task::Warning); return true; } m_skipBuilding = false; @@ -805,13 +805,13 @@ void AndroidBuildApkStep::setupOutputFormatter(OutputFormatter *formatter) const auto parser = new JavaParser; parser->setProjectFileList(project()->files(Project::AllFiles)); - const QString buildKey = target()->activeBuildKey(); + const QString buildKey = buildConfiguration()->activeBuildKey(); const ProjectNode *node = project()->findNodeForBuildKey(buildKey); FilePath sourceDirPath; if (node) sourceDirPath = FilePath::fromVariant(node->data(Constants::AndroidPackageSourceDir)); parser->setSourceDirectory(sourceDirPath.canonicalPath()); - parser->setBuildDirectory(androidBuildDirectory(target())); + parser->setBuildDirectory(androidBuildDirectory(buildConfiguration())); formatter->addLineParser(parser); AbstractProcessStep::setupOutputFormatter(formatter); } @@ -910,9 +910,9 @@ Tasking::GroupItem AndroidBuildApkStep::runRecipe() } const auto androidAbis = applicationAbis(target()); - const QString buildKey = target()->activeBuildKey(); + const QString buildKey = buildConfiguration()->activeBuildKey(); const FilePath buildDir = buildDirectory(); - const FilePath androidBuildDir = androidBuildDirectory(target()); + const FilePath androidBuildDir = androidBuildDirectory(buildConfiguration()); for (const auto &abi : androidAbis) { FilePath androidLibsDir = androidBuildDir / "libs" / abi; if (!androidLibsDir.exists()) { @@ -1040,7 +1040,7 @@ Tasking::GroupItem AndroidBuildApkStep::runRecipe() "not building an APK."), Task::Error); return SetupResult::StopWithSuccess; } - if (skipInstallationAndPackageSteps(target())) { + if (skipInstallationAndPackageSteps(buildConfiguration())) { reportWarningOrError(Tr::tr("Product type is not an application, not building an APK."), Task::Warning); return SetupResult::StopWithSuccess; @@ -1152,7 +1152,7 @@ QVariant AndroidBuildApkStep::data(Utils::Id id) const { if (id == Constants::AndroidNdkPlatform) { if (auto qtVersion = QtKitAspect::qtVersion(kit())) - return AndroidConfig::bestNdkPlatformMatch(minimumSDK(target()), qtVersion); + return AndroidConfig::bestNdkPlatformMatch(minimumSDK(buildConfiguration()), qtVersion); return {}; } if (id == Constants::NdkLocation) { diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index c2eb568d492..eff60003e07 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -13,6 +13,7 @@ #include <debugger/debuggerrunconfigurationaspect.h> #include <debugger/debuggerruncontrol.h> +#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/project.h> #include <projectexplorer/projectnodes.h> #include <projectexplorer/target.h> @@ -51,7 +52,7 @@ static FilePaths getSoLibSearchPath(const ProjectNode *node) }); const FilePath jsonFile = AndroidQtVersion::androidDeploymentSettings( - node->getProject()->activeTarget()); + node->getProject()->activeBuildConfiguration()); FileReader reader; if (reader.fetch(jsonFile)) { QJsonParseError error; @@ -98,10 +99,10 @@ public: auto runner = new AndroidRunner(runControl); debugger->addStartDependency(runner); - Target *target = runControl->target(); + BuildConfiguration *bc = runControl->buildConfiguration(); Kit *kit = runControl->kit(); rp.setStartMode(AttachToRemoteServer); - const QString packageName = Internal::packageName(target); + const QString packageName = Internal::packageName(bc); rp.setDisplayName(packageName); rp.setUseContinueInsteadOfRun(true); @@ -121,21 +122,21 @@ public: const FilePaths extraLibs = getExtraLibs(node); solibSearchPath.append(extraLibs); - FilePath buildDir = Internal::buildDirectory(target); - const RunConfiguration *activeRunConfig = target->activeRunConfiguration(); + FilePath buildDir = Internal::buildDirectory(bc); + const RunConfiguration *activeRunConfig = bc->activeRunConfiguration(); if (activeRunConfig) solibSearchPath.append(activeRunConfig->buildTargetInfo().workingDirectory); solibSearchPath.append(buildDir); - const FilePath androidLibsPath = androidBuildDirectory(target) + const FilePath androidLibsPath = androidBuildDirectory(bc) .pathAppended("libs") - .pathAppended(apkDevicePreferredAbi(target)); + .pathAppended(apkDevicePreferredAbi(bc)); solibSearchPath.append(androidLibsPath); FilePath::removeDuplicates(solibSearchPath); rp.setSolibSearchPath(solibSearchPath); qCDebug(androidDebugSupportLog).noquote() << "SoLibSearchPath: " << solibSearchPath; - rp.setSymbolFile(androidAppProcessDir(target).pathAppended("app_process")); + rp.setSymbolFile(androidAppProcessDir(bc).pathAppended("app_process")); rp.setUseExtendedRemote(true); - const QString devicePreferredAbi = apkDevicePreferredAbi(target); + const QString devicePreferredAbi = apkDevicePreferredAbi(bc); rp.setToolChainAbi(androidAbi2Abi(devicePreferredAbi)); auto qt = static_cast<AndroidQtVersion *>(qtVersion); @@ -171,7 +172,7 @@ public: rp.setAttachPid(runner->pid()); if (rp.isCppDebugging()) { if (rp.cppEngineType() == LldbEngineType) { - QString deviceSerialNumber = Internal::deviceSerialNumber(runControl->target()); + QString deviceSerialNumber = Internal::deviceSerialNumber(runControl->buildConfiguration()->target()); const int colonPos = deviceSerialNumber.indexOf(QLatin1Char(':')); if (colonPos > 0) { // When wireless debugging is used then the device serial number will include a port number diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 4e0566c9005..9dfdb8ddbf1 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -96,14 +96,14 @@ struct FileToPull FilePath to; }; -static QList<FileToPull> filesToPull(Target *target) +static QList<FileToPull> filesToPull(BuildConfiguration *bc) { QList<FileToPull> fileList; - const FilePath appProcessDir = androidAppProcessDir(target); + const FilePath appProcessDir = androidAppProcessDir(bc); QString linkerName("linker"); QString libDirName("lib"); - const QString preferredAbi = apkDevicePreferredAbi(target); + const QString preferredAbi = apkDevicePreferredAbi(bc); if (preferredAbi == ProjectExplorer::Constants::ANDROID_ABI_ARM64_V8A || preferredAbi == ProjectExplorer::Constants::ANDROID_ABI_X86_64) { fileList.append({"/system/bin/app_process64", appProcessDir / "app_process"}); @@ -194,14 +194,14 @@ bool AndroidDeployQtStep::init() Task::Error); return false); - const int minTargetApi = minimumSDK(target()); + const int minTargetApi = minimumSDK(buildConfiguration()); qCDebug(deployStepLog) << "Target architecture:" << androidABIs << "Min target API" << minTargetApi; const BuildSystem *bs = buildSystem(); QStringList selectedAbis = bs->property(Constants::AndroidAbis).toStringList(); - const QString buildKey = target()->activeBuildKey(); + const QString buildKey = buildConfiguration()->activeBuildKey(); if (selectedAbis.isEmpty()) selectedAbis = bs->extraData(buildKey, Constants::AndroidAbis).toStringList(); @@ -270,7 +270,7 @@ bool AndroidDeployQtStep::init() Internal::setManifestPath(target(), FilePath::fromString(node->data(Constants::AndroidManifest).toString())); } else { - FilePath jsonFile = AndroidQtVersion::androidDeploymentSettings(target()); + FilePath jsonFile = AndroidQtVersion::androidDeploymentSettings(buildConfiguration()); if (jsonFile.isEmpty()) { reportWarningOrError(Tr::tr("Cannot find the androiddeployqt input JSON file."), Task::Error); @@ -283,7 +283,7 @@ bool AndroidDeployQtStep::init() } m_command = m_command.pathAppended("androiddeployqt").withExecutableSuffix(); - m_workingDirectory = androidBuildDirectory(target()); + m_workingDirectory = androidBuildDirectory(buildConfiguration()); // clang-format off m_androiddeployqtArgs.addArgs({"--verbose", @@ -333,7 +333,7 @@ GroupItem AndroidDeployQtStep::runRecipe() return true; }; - const LoopList iterator(filesToPull(target())); + const LoopList iterator(filesToPull(buildConfiguration())); const auto onRemoveFileSetup = [iterator](Async<void> &async) { async.setConcurrentCallData(removeFile, iterator->to); }; @@ -394,12 +394,12 @@ Group AndroidDeployQtStep::deployRecipe() QTC_ASSERT(target()->activeRunConfiguration(), return SetupResult::StopWithError); - const QString packageName = Internal::packageName(target()); + const QString packageName = Internal::packageName(buildConfiguration()); if (packageName.isEmpty()) { reportWarningOrError( Tr::tr("Cannot find the package name from AndroidManifest.xml nor " "build.gradle files at \"%1\".") - .arg(androidBuildDirectory(target()).toUserOutput()), + .arg(androidBuildDirectory(buildConfiguration()).toUserOutput()), Task::Error); return SetupResult::StopWithError; } diff --git a/src/plugins/android/androidmanifesteditor.cpp b/src/plugins/android/androidmanifesteditor.cpp index 76b64b3e8d4..15bc23eb47a 100644 --- a/src/plugins/android/androidmanifesteditor.cpp +++ b/src/plugins/android/androidmanifesteditor.cpp @@ -1067,7 +1067,7 @@ void AndroidManifestEditorWidget::postSave() if (Target *target = androidTarget(docPath)) { if (BuildConfiguration *bc = target->activeBuildConfiguration()) { QString androidNdkPlatform = AndroidConfig::bestNdkPlatformMatch( - minimumSDK(target), + minimumSDK(bc), QtSupport::QtKitAspect::qtVersion( androidTarget(m_textEditorWidget->textDocument()->filePath())->kit())); if (m_androidNdkPlatform != androidNdkPlatform) { diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/android/androidpackageinstallationstep.cpp index eb6a312dd94..a3672f4425a 100644 --- a/src/plugins/android/androidpackageinstallationstep.cpp +++ b/src/plugins/android/androidpackageinstallationstep.cpp @@ -92,7 +92,7 @@ bool AndroidPackageInstallationStep::init() processParameters()->setCommandLine(cmd); // This is useful when running an example target from a Qt module project. - processParameters()->setWorkingDirectory(Internal::buildDirectory(target())); + processParameters()->setWorkingDirectory(Internal::buildDirectory(buildConfiguration())); m_androidDirsToClean.clear(); // don't remove gradle's cache, it takes ages to rebuild it. @@ -104,7 +104,7 @@ bool AndroidPackageInstallationStep::init() QString AndroidPackageInstallationStep::nativeAndroidBuildPath() const { - QString buildPath = androidBuildDirectory(target()).toFSPathString(); + QString buildPath = androidBuildDirectory(buildConfiguration()).toFSPathString(); if (HostOsInfo::isWindowsHost()) if (buildEnvironment().searchInPath("sh.exe").isEmpty()) buildPath = QDir::toNativeSeparators(buildPath); @@ -125,7 +125,7 @@ Tasking::GroupItem AndroidPackageInstallationStep::runRecipe() using namespace Tasking; const auto onSetup = [this] { - if (skipInstallationAndPackageSteps(target())) { + if (skipInstallationAndPackageSteps(buildConfiguration())) { reportWarningOrError(Tr::tr("Product type is not an application, not running the " "Make install step."), Task::Warning); return SetupResult::StopWithSuccess; diff --git a/src/plugins/android/androidqtversion.cpp b/src/plugins/android/androidqtversion.cpp index a1da35cd8c8..53843b97457 100644 --- a/src/plugins/android/androidqtversion.cpp +++ b/src/plugins/android/androidqtversion.cpp @@ -124,25 +124,25 @@ int AndroidQtVersion::minimumNDK() const return m_minNdk; } -QString AndroidQtVersion::androidDeploymentSettingsFileName(const Target *target) +QString AndroidQtVersion::androidDeploymentSettingsFileName(const BuildConfiguration *bc) { - const BuildSystem *bs = target->buildSystem(); + const BuildSystem *bs = bc->buildSystem(); if (!bs) return {}; - const QString buildKey = target->activeBuildKey(); + const QString buildKey = bc->activeBuildKey(); const QString displayName = bs->buildTarget(buildKey).displayName; - const QString fileName = isQt5CmakeProject(target) + const QString fileName = isQt5CmakeProject(bc->target()) ? QLatin1String("android_deployment_settings.json") : QString::fromLatin1("android-%1-deployment-settings.json") .arg(displayName); return fileName; } -Utils::FilePath AndroidQtVersion::androidDeploymentSettings(const Target *target) +Utils::FilePath AndroidQtVersion::androidDeploymentSettings(const BuildConfiguration *bc) { // Try to fetch the file name from node data as provided by qmake and Qbs - QString buildKey = target->activeBuildKey(); - const ProjectNode *node = target->project()->findNodeForBuildKey(buildKey); + QString buildKey = bc->activeBuildKey(); + const ProjectNode *node = bc->project()->findNodeForBuildKey(buildKey); if (node) { const QString nameFromData = node->data(Constants::AndroidDeploySettingsFile).toString(); if (!nameFromData.isEmpty()) @@ -150,8 +150,8 @@ Utils::FilePath AndroidQtVersion::androidDeploymentSettings(const Target *target } // If unavailable, construct the name by ourselves (CMake) - const QString fileName = androidDeploymentSettingsFileName(target); - return buildDirectory(target) / fileName; + const QString fileName = androidDeploymentSettingsFileName(bc); + return buildDirectory(bc) / fileName; } AndroidQtVersion::BuiltWith AndroidQtVersion::builtWith(bool *ok) const diff --git a/src/plugins/android/androidqtversion.h b/src/plugins/android/androidqtversion.h index d96276abb65..f07bf5fb988 100644 --- a/src/plugins/android/androidqtversion.h +++ b/src/plugins/android/androidqtversion.h @@ -5,6 +5,8 @@ #include <qtsupport/baseqtversion.h> +namespace ProjectExplorer { class BuildConfiguration; } + namespace Android::Internal { class AndroidQtVersion : public QtSupport::QtVersion @@ -28,8 +30,8 @@ public: const QStringList androidAbis() const; int minimumNDK() const; - static QString androidDeploymentSettingsFileName(const ProjectExplorer::Target *target); - static Utils::FilePath androidDeploymentSettings(const ProjectExplorer::Target *target); + static QString androidDeploymentSettingsFileName(const ProjectExplorer::BuildConfiguration *bc); + static Utils::FilePath androidDeploymentSettings(const ProjectExplorer::BuildConfiguration *bc); struct BuiltWith { int apiVersion = -1; diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp index 78e7baae2c5..f7d6367ad9c 100644 --- a/src/plugins/android/androidrunconfiguration.cpp +++ b/src/plugins/android/androidrunconfiguration.cpp @@ -47,15 +47,15 @@ public: class AndroidRunConfiguration : public RunConfiguration { public: - AndroidRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + AndroidRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { environment.addSupportedBaseEnvironment(Tr::tr("Clean Environment"), {}); - extraAppArgs.addOnChanged(this, [this, target] { - if (target->buildConfigurations().first()->buildType() == BuildConfiguration::BuildType::Release) { - const QString buildKey = target->activeBuildKey(); - target->buildSystem()->setExtraData(buildKey, + extraAppArgs.addOnChanged(this, [this, bc] { + if (bc->target()->buildConfigurations().first()->buildType() == BuildConfiguration::BuildType::Release) { + const QString buildKey = bc->activeBuildKey(); + bc->buildSystem()->setExtraData(buildKey, Android::Constants::AndroidApplicationArgs, extraAppArgs()); } @@ -82,8 +82,6 @@ public: setDisplayName(bti.displayName); setDefaultDisplayName(bti.displayName); }); - - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); } EnvironmentAspect environment{this}; diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index 58722228f22..dbf2d2e8561 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -9,6 +9,7 @@ #include "androidrunnerworker.h" #include "androidutils.h" +#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/devicesupport/devicekitaspects.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorersettings.h> @@ -47,8 +48,8 @@ AndroidRunner::AndroidRunner(RunControl *runControl) void AndroidRunner::start() { - auto target = runControl()->target(); - QTC_ASSERT(target, return); + BuildConfiguration *bc = runControl()->buildConfiguration(); + QTC_ASSERT(bc, return); QString deviceSerialNumber; int apiLevel = -1; @@ -61,7 +62,7 @@ void AndroidRunner::start() const IDevice::ConstPtr device = RunDeviceKitAspect::device(runControl()->kit()); AndroidDeviceInfo info = AndroidDevice::androidDeviceInfoFromDevice(device); - setDeviceSerialNumber(target, info.serialNumber); + setDeviceSerialNumber(bc->target(), info.serialNumber); deviceSerialNumber = info.serialNumber; apiLevel = info.sdk; qCDebug(androidRunnerLog) << "Android Device Info changed" << deviceSerialNumber @@ -78,8 +79,8 @@ void AndroidRunner::start() }); } } else { - deviceSerialNumber = Internal::deviceSerialNumber(target); - apiLevel = Internal::deviceApiLevel(target); + deviceSerialNumber = Internal::deviceSerialNumber(bc->target()); + apiLevel = Internal::deviceApiLevel(bc->target()); } const auto onSetup = [this, glueStorage, deviceSerialNumber, apiLevel] { diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index f1fbb073565..f710eb64802 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -96,14 +96,14 @@ static QString lldbServerArch2(const QString &androidAbi) return androidAbi; // x86_64 } -static FilePath debugServer(bool useLldb, const Target *target) +static FilePath debugServer(bool useLldb, const BuildConfiguration *bc) { - QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target->kit()); - QString preferredAbi = apkDevicePreferredAbi(target); + QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(bc->kit()); + QString preferredAbi = apkDevicePreferredAbi(bc); if (useLldb) { // Search suitable lldb-server binary. - const DebuggerItem *debugger = DebuggerKitAspect::debugger(target->kit()); + const DebuggerItem *debugger = DebuggerKitAspect::debugger(bc->kit()); if (!debugger || debugger->command().isEmpty()) return {}; // .../ndk/<ndk-version>/toolchains/llvm/prebuilt/<host-arch>/bin/lldb @@ -223,9 +223,9 @@ static void setupStorage(RunnerStorage *storage, RunnerInterface *glue) qCDebug(androidRunWorkerLog) << "QML server:" << storage->m_qmlServer.toDisplayString(); } - auto target = glue->runControl()->target(); - storage->m_packageName = packageName(target); - storage->m_intentName = storage->m_packageName + '/' + activityName(target); + BuildConfiguration *bc = glue->runControl()->buildConfiguration(); + storage->m_packageName = packageName(bc); + storage->m_intentName = storage->m_packageName + '/' + activityName(bc); qCDebug(androidRunWorkerLog) << "Intent name:" << storage->m_intentName << "Package name:" << storage->m_packageName; qCDebug(androidRunWorkerLog) << "Device API:" << glue->apiLevel(); @@ -234,7 +234,7 @@ static void setupStorage(RunnerStorage *storage, RunnerInterface *glue) qCDebug(androidRunWorkerLog).noquote() << "Environment variables for the app" << storage->m_extraEnvVars.toStringList(); - if (target->buildConfigurations().first()->buildType() != BuildConfiguration::BuildType::Release) + if (bc->buildType() != BuildConfiguration::BuildType::Release) storage->m_extraAppParams = glue->runControl()->commandLine().arguments(); if (const Store sd = glue->runControl()->settingsData(Constants::ANDROID_AM_START_ARGS); @@ -261,7 +261,7 @@ static void setupStorage(RunnerStorage *storage, RunnerInterface *glue) storage->m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd)); } - storage->m_debugServerPath = debugServer(storage->m_useLldb, target); + storage->m_debugServerPath = debugServer(storage->m_useLldb, bc); qCDebug(androidRunWorkerLog).noquote() << "Device Serial:" << glue->deviceSerialNumber() << ", API level:" << glue->apiLevel() << ", Extra Start Args:" << storage->m_amStartExtraArgs @@ -269,7 +269,7 @@ static void setupStorage(RunnerStorage *storage, RunnerInterface *glue) << ", After finish ADB cmds:" << storage->m_afterFinishAdbCommands << ", Debug server path:" << storage->m_debugServerPath; - QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit()); + QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(bc->kit()); storage->m_useAppParamsForQmlDebugger = version->qtVersion() >= QVersionNumber(5, 12); } @@ -919,7 +919,7 @@ ExecutableItem runnerRecipe(const Storage<RunnerInterface> &glueStorage) const Storage<RunnerStorage> storage; const auto onSetup = [glueStorage, storage] { - if (glueStorage->runControl()->target() == nullptr) + if (glueStorage->runControl()->buildConfiguration() == nullptr) return SetupResult::StopWithError; setupStorage(storage.activeStorage(), glueStorage.activeStorage()); return SetupResult::Continue; diff --git a/src/plugins/android/androidutils.cpp b/src/plugins/android/androidutils.cpp index 1ad0ca4244b..572ad5921b9 100644 --- a/src/plugins/android/androidutils.cpp +++ b/src/plugins/android/androidutils.cpp @@ -95,12 +95,12 @@ static int parseMinSdk(const QDomElement &manifestElem) return 0; } -static const ProjectNode *currentProjectNode(const Target *target) +static const ProjectNode *currentProjectNode(const BuildConfiguration *bc) { - return target->project()->findNodeForBuildKey(target->activeBuildKey()); + return bc->project()->findNodeForBuildKey(bc->activeBuildKey()); } -QString packageName(const Target *target) +QString packageName(const BuildConfiguration *bc) { QString packageName; @@ -109,7 +109,7 @@ QString packageName(const Target *target) return trimmed.startsWith("//") || trimmed.startsWith('*') || trimmed.startsWith("/*"); }; - const FilePath androidBuildDir = androidBuildDirectory(target); + const FilePath androidBuildDir = androidBuildDirectory(bc); const expected_str<QByteArray> gradleContents = androidBuildDir.pathAppended("build.gradle") .fileContents(); if (gradleContents) { @@ -143,7 +143,7 @@ QString packageName(const Target *target) if (packageName.isEmpty()) { // Check AndroidManifest.xml - const auto element = documentElement(manifestPath(target)); + const auto element = documentElement(manifestPath(bc)); if (element) packageName = element->attribute("package"); } @@ -151,18 +151,18 @@ QString packageName(const Target *target) return packageName; } -QString activityName(const Target *target) +QString activityName(const BuildConfiguration *bc) { - const auto element = documentElement(manifestPath(target)); + const auto element = documentElement(manifestPath(bc)); if (!element) return {}; return element->firstChildElement("application").firstChildElement("activity") .attribute("android:name"); } -static FilePath manifestSourcePath(const Target *target) +static FilePath manifestSourcePath(const BuildConfiguration *bc) { - if (const ProjectNode *node = currentProjectNode(target)) { + if (const ProjectNode *node = currentProjectNode(bc)) { const QString packageSource = node->data(Android::Constants::AndroidPackageSourceDir).toString(); if (!packageSource.isEmpty()) { @@ -171,7 +171,7 @@ static FilePath manifestSourcePath(const Target *target) return manifest; } } - return manifestPath(target); + return manifestPath(bc); } /*! @@ -179,15 +179,15 @@ static FilePath manifestSourcePath(const Target *target) of the kit is returned if the manifest file of the APK cannot be found or parsed. */ -int minimumSDK(const Target *target) +int minimumSDK(const BuildConfiguration *bc) { - const auto element = documentElement(manifestSourcePath(target)); + const auto element = documentElement(manifestSourcePath(bc)); if (!element) - return minimumSDK(target->kit()); + return minimumSDK(bc->kit()); const int minSdkVersion = parseMinSdk(*element); if (minSdkVersion == 0) - return defaultMinimumSDK(QtSupport::QtKitAspect::qtVersion(target->kit())); + return defaultMinimumSDK(QtSupport::QtKitAspect::qtVersion(bc->kit())); return minSdkVersion; } @@ -280,20 +280,20 @@ bool isQtCreatorGenerated(const FilePath &deploymentFile) return QJsonDocument::fromJson(*result).object()["_description"].toString() == qtcSignature; } -FilePath androidBuildDirectory(const Target *target) +FilePath androidBuildDirectory(const BuildConfiguration *bc) { QString suffix; - const Project *project = target->project(); + const Project *project = bc->project(); if (project->extraData(Android::Constants::AndroidBuildTargetDirSupport).toBool() && project->extraData(Android::Constants::UseAndroidBuildTargetDir).toBool()) - suffix = QString("-%1").arg(target->activeBuildKey()); + suffix = QString("-%1").arg(bc->activeBuildKey()); - return buildDirectory(target) / (Constants::ANDROID_BUILD_DIRECTORY + suffix); + return buildDirectory(bc) / (Constants::ANDROID_BUILD_DIRECTORY + suffix); } -FilePath androidAppProcessDir(const Target *target) +FilePath androidAppProcessDir(const BuildConfiguration *bc) { - return buildDirectory(target) / Constants::ANDROID_APP_PROCESS_DIRECTORY; + return buildDirectory(bc) / Constants::ANDROID_APP_PROCESS_DIRECTORY; } bool isQt5CmakeProject(const ProjectExplorer::Target *target) @@ -305,47 +305,43 @@ bool isQt5CmakeProject(const ProjectExplorer::Target *target) return isQt5 && isCmakeProject; } -FilePath buildDirectory(const Target *target) +FilePath buildDirectory(const BuildConfiguration *bc) { - if (const BuildSystem *bs = target->buildSystem()) { - const QString buildKey = target->activeBuildKey(); + const QString buildKey = bc->activeBuildKey(); - // Get the target build dir based on the settings file path - FilePath buildDir; - const ProjectNode *node = target->project()->findNodeForBuildKey(buildKey); - if (node) { - const QString settingsFile = node->data(Constants::AndroidDeploySettingsFile).toString(); - buildDir = FilePath::fromUserInput(settingsFile).parentDir(); - } + // Get the target build dir based on the settings file path + FilePath buildDir; + const ProjectNode *node = bc->project()->findNodeForBuildKey(buildKey); + if (node) { + const QString settingsFile = node->data(Constants::AndroidDeploySettingsFile).toString(); + buildDir = FilePath::fromUserInput(settingsFile).parentDir(); + } - if (!buildDir.isEmpty()) - return buildDir; - - // Otherwise fallback to target working dir - buildDir = bs->buildTarget(target->activeBuildKey()).workingDirectory; - if (isQt5CmakeProject(target)) { - // Return the main build dir and not the android libs dir - const QString libsDir = QString(Constants::ANDROID_BUILD_DIRECTORY) + "/libs"; - FilePath parentDuildDir = buildDir.parentDir(); - if (parentDuildDir.endsWith(libsDir) || libsDir.endsWith(libsDir + "/")) - return parentDuildDir.parentDir().parentDir(); - } else { - // Qt6 + CMake: Very cautios hack to work around QTCREATORBUG-26479 for simple projects - const QString jsonFileName = - AndroidQtVersion::androidDeploymentSettingsFileName(target); - const FilePath jsonFile = buildDir / jsonFileName; - if (!jsonFile.exists()) { - const FilePath projectBuildDir = bs->buildConfiguration()->buildDirectory(); - if (buildDir != projectBuildDir) { - const FilePath projectJsonFile = projectBuildDir / jsonFileName; - if (projectJsonFile.exists()) - buildDir = projectBuildDir; - } + if (!buildDir.isEmpty()) + return buildDir; + + // Otherwise fallback to target working dir + buildDir = bc->buildSystem()->buildTarget(buildKey).workingDirectory; + if (isQt5CmakeProject(bc->target())) { + // Return the main build dir and not the android libs dir + const QString libsDir = QString(Constants::ANDROID_BUILD_DIRECTORY) + "/libs"; + FilePath parentDuildDir = buildDir.parentDir(); + if (parentDuildDir.endsWith(libsDir) || libsDir.endsWith(libsDir + "/")) + return parentDuildDir.parentDir().parentDir(); + } else { + // Qt6 + CMake: Very cautios hack to work around QTCREATORBUG-26479 for simple projects + const QString jsonFileName = AndroidQtVersion::androidDeploymentSettingsFileName(bc); + const FilePath jsonFile = buildDir / jsonFileName; + if (!jsonFile.exists()) { + const FilePath projectBuildDir = bc->buildDirectory(); + if (buildDir != projectBuildDir) { + const FilePath projectJsonFile = projectBuildDir / jsonFileName; + if (projectJsonFile.exists()) + buildDir = projectBuildDir; } } - return buildDir; } - return {}; + return buildDir; } Abi androidAbi2Abi(const QString &androidAbi) @@ -383,17 +379,17 @@ Abi androidAbi2Abi(const QString &androidAbi) } } -bool skipInstallationAndPackageSteps(const Target *target) +bool skipInstallationAndPackageSteps(const BuildConfiguration *bc) { // For projects using Qt 5.15 and Qt 6, the deployment settings file // is generated by CMake/qmake and not Qt Creator, so if such file doesn't exist // or it's been generated by Qt Creator, we can assume the project is not // an android app. - const FilePath inputFile = AndroidQtVersion::androidDeploymentSettings(target); + const FilePath inputFile = AndroidQtVersion::androidDeploymentSettings(bc); if (!inputFile.exists() || isQtCreatorGenerated(inputFile)) return true; - const Project *p = target->project(); + const Project *p = bc->project(); const Context cmakeCtx(CMakeProjectManager::Constants::CMAKE_PROJECT_ID); const bool isCmakeProject = p->projectContext() == cmakeCtx; @@ -406,12 +402,12 @@ bool skipInstallationAndPackageSteps(const Target *target) return n == nullptr; // If no Application target found, then skip steps } -FilePath manifestPath(const Target *target) +FilePath manifestPath(const BuildConfiguration *bc) { - QVariant manifest = target->namedSettings(AndroidManifestName); + QVariant manifest = bc->target()->namedSettings(AndroidManifestName); if (manifest.isValid()) return manifest.value<FilePath>(); - return androidBuildDirectory(target).pathAppended(AndroidManifestName); + return androidBuildDirectory(bc).pathAppended(AndroidManifestName); } void setManifestPath(Target *target, const FilePath &path) @@ -441,13 +437,13 @@ static QString preferredAbi(const QStringList &appAbis, const Target *target) return {}; } -QString apkDevicePreferredAbi(const Target *target) +QString apkDevicePreferredAbi(const BuildConfiguration *bc) { - const FilePath libsPath = androidBuildDirectory(target).pathAppended("libs"); + const FilePath libsPath = androidBuildDirectory(bc).pathAppended("libs"); if (!libsPath.exists()) { - if (const ProjectNode *node = currentProjectNode(target)) { + if (const ProjectNode *node = currentProjectNode(bc)) { const QString abi = preferredAbi( - node->data(Android::Constants::AndroidAbis).toStringList(), target); + node->data(Android::Constants::AndroidAbis).toStringList(), bc->target()); if (abi.isEmpty()) return node->data(Android::Constants::AndroidAbi).toString(); } @@ -458,7 +454,7 @@ QString apkDevicePreferredAbi(const Target *target) if (!abiDir.dirEntries({{"*.so"}, QDir::Files | QDir::NoDotAndDotDot}).isEmpty()) apkAbis << abiDir.fileName(); } - return preferredAbi(apkAbis, target); + return preferredAbi(apkAbis, bc->target()); } void setDeviceAbis(Target *target, const QStringList &deviceAbis) diff --git a/src/plugins/android/androidutils.h b/src/plugins/android/androidutils.h index ccd3bbe08de..59e673b4320 100644 --- a/src/plugins/android/androidutils.h +++ b/src/plugins/android/androidutils.h @@ -6,6 +6,7 @@ #include <QStringList> namespace ProjectExplorer { +class BuildConfiguration; class Abi; class Kit; class Target; @@ -30,13 +31,13 @@ QT_END_NAMESPACE namespace Android::Internal { -QString packageName(const ProjectExplorer::Target *target); -QString activityName(const ProjectExplorer::Target *target); +QString packageName(const ProjectExplorer::BuildConfiguration *bc); +QString activityName(const ProjectExplorer::BuildConfiguration *bc); QString deviceSerialNumber(const ProjectExplorer::Target *target); void setDeviceSerialNumber(ProjectExplorer::Target *target, const QString &deviceSerialNumber); -QString apkDevicePreferredAbi(const ProjectExplorer::Target *target); +QString apkDevicePreferredAbi(const ProjectExplorer::BuildConfiguration *bc); void setDeviceAbis(ProjectExplorer::Target *target, const QStringList &deviceAbis); int deviceApiLevel(const ProjectExplorer::Target *target); @@ -44,7 +45,7 @@ void setDeviceApiLevel(ProjectExplorer::Target *target, int level); QString buildTargetSDK(const ProjectExplorer::Target *target); -int minimumSDK(const ProjectExplorer::Target *target); +int minimumSDK(const ProjectExplorer::BuildConfiguration *bc); int minimumSDK(const ProjectExplorer::Kit *kit); int defaultMinimumSDK(const QtSupport::QtVersion *qtVersion); @@ -53,13 +54,13 @@ QString archTriplet(const QString &abi); bool isQt5CmakeProject(const ProjectExplorer::Target *target); -Utils::FilePath androidBuildDirectory(const ProjectExplorer::Target *target); -Utils::FilePath androidAppProcessDir(const ProjectExplorer::Target *target); -Utils::FilePath buildDirectory(const ProjectExplorer::Target *target); -Utils::FilePath manifestPath(const ProjectExplorer::Target *target); +Utils::FilePath androidBuildDirectory(const ProjectExplorer::BuildConfiguration *bc); +Utils::FilePath androidAppProcessDir(const ProjectExplorer::BuildConfiguration *bc); +Utils::FilePath buildDirectory(const ProjectExplorer::BuildConfiguration *bc); +Utils::FilePath manifestPath(const ProjectExplorer::BuildConfiguration *bc); void setManifestPath(ProjectExplorer::Target *target, const Utils::FilePath &path); ProjectExplorer::Abi androidAbi2Abi(const QString &androidAbi); -bool skipInstallationAndPackageSteps(const ProjectExplorer::Target *target); +bool skipInstallationAndPackageSteps(const ProjectExplorer::BuildConfiguration *bc); QString androidNameForApiLevel(int x); diff --git a/src/plugins/android/manifestwizard.cpp b/src/plugins/android/manifestwizard.cpp index dc53ec0ba52..bc0083bd4ec 100644 --- a/src/plugins/android/manifestwizard.cpp +++ b/src/plugins/android/manifestwizard.cpp @@ -9,6 +9,7 @@ #include <coreplugin/editormanager/editormanager.h> +#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/buildsystem.h> #include <projectexplorer/project.h> #include <projectexplorer/projectnodes.h> @@ -105,7 +106,7 @@ ChooseProFilePage::ChooseProFilePage(CreateAndroidManifestWizard *wizard) fl->addRow(label); BuildSystem *buildSystem = wizard->buildSystem(); - QString currentBuildKey = buildSystem->target()->activeBuildKey(); + QString currentBuildKey = buildSystem->buildConfiguration()->activeBuildKey(); m_comboBox = new QComboBox(this); for (const BuildTargetInfo &bti : buildSystem->applicationTargets()) { diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp index 4972429a7d0..a722ac79af8 100644 --- a/src/plugins/autotest/testconfiguration.cpp +++ b/src/plugins/autotest/testconfiguration.cpp @@ -11,6 +11,7 @@ #include <projectexplorer/buildtargetinfo.h> #include <projectexplorer/deploymentdata.h> #include <projectexplorer/devicesupport/devicekitaspects.h> +#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/runconfiguration.h> #include <projectexplorer/projectmanager.h> #include <projectexplorer/target.h> @@ -115,11 +116,8 @@ void TestConfiguration::completeTestInformation(RunConfiguration *rc, if (!startupProject || startupProject != project()) return; - Target *target = startupProject->activeTarget(); - if (!target) - return; - - if (!target->runConfigurations().contains(rc)) + BuildConfiguration * const buildConfig = startupProject->activeBuildConfiguration(); + if (!buildConfig || buildConfig != rc->buildConfiguration()) return; m_runnable = rc->runnable(); @@ -129,17 +127,14 @@ void TestConfiguration::completeTestInformation(RunConfiguration *rc, if (!targetInfo.targetFilePath.isEmpty()) m_runnable.command.setExecutable(ensureExeEnding(targetInfo.targetFilePath)); - FilePath buildBase; - if (auto buildConfig = startupProject->activeBuildConfiguration()) { - buildBase = buildConfig->buildDirectory(); - const FilePath projBase = startupProject->projectDirectory(); - if (m_projectFile.isChildOf(projBase)) { - m_buildDir - = (buildBase.resolvePath(m_projectFile.relativePathFromDir(projBase))).absolutePath(); - } + const FilePath buildBase = buildConfig->buildDirectory(); + const FilePath projBase = startupProject->projectDirectory(); + if (m_projectFile.isChildOf(projBase)) { + m_buildDir + = (buildBase.resolvePath(m_projectFile.relativePathFromDir(projBase))).absolutePath(); } if (runMode == TestRunMode::Debug || runMode == TestRunMode::DebugWithoutDeploy) - m_runConfig = new Internal::TestRunConfiguration(rc->target(), this); + m_runConfig = new Internal::TestRunConfiguration(rc->buildConfiguration(), this); } void TestConfiguration::completeTestInformation(TestRunMode runMode) @@ -164,8 +159,8 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode) return; } - Target *target = startupProject->activeTarget(); - if (!target) + BuildConfiguration * const buildConfig = startupProject->activeBuildConfiguration(); + if (!buildConfig) return; if (const auto kit = startupProject->activeKit()) { qCDebug(LOG) << "ActiveTargetName\n " << kit->displayName(); @@ -218,7 +213,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode) // deployment information should get taken into account, but it pretty much seems as if // each build system uses it differently - const DeploymentData &deployData = target->deploymentData(); + const DeploymentData &deployData = buildConfig->buildSystem()->deploymentData(); const DeployableFile deploy = deployData.deployableForLocalFile(localExecutable); // we might have a deployable executable const FilePath deployedExecutable = ensureExeEnding((deploy.isValid() && deploy.isExecutable()) @@ -227,12 +222,12 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode) qCDebug(LOG) << " LocalExecutable" << localExecutable; qCDebug(LOG) << " DeployedExecutable" << deployedExecutable; qCDebug(LOG) << "Iterating run configurations - prefer active over others"; - QList<RunConfiguration *> runConfigurations = target->runConfigurations(); - runConfigurations.removeOne(target->activeRunConfiguration()); - runConfigurations.prepend(target->activeRunConfiguration()); + QList<RunConfiguration *> runConfigurations = buildConfig->runConfigurations(); + runConfigurations.removeOne(buildConfig->activeRunConfiguration()); + runConfigurations.prepend(buildConfig->activeRunConfiguration()); for (RunConfiguration *runConfig : std::as_const(runConfigurations)) { qCDebug(LOG) << "RunConfiguration" << runConfig->id(); - if (!isLocal(target)) { // TODO add device support + if (!isLocal(buildConfig->target())) { // TODO add device support qCDebug(LOG) << " Skipped as not being local"; continue; } @@ -253,7 +248,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode) m_runnable.command.setExecutable(currentExecutable); setDisplayName(runConfig->displayName()); if (runMode == TestRunMode::Debug || runMode == TestRunMode::DebugWithoutDeploy) - m_runConfig = new Internal::TestRunConfiguration(target, this); + m_runConfig = new Internal::TestRunConfiguration(runConfig->buildConfiguration(), this); break; } } @@ -267,14 +262,14 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode) if (displayName().isEmpty() && hasExecutable()) { qCDebug(LOG) << " Fallback"; // we failed to find a valid runconfiguration - but we've got the executable already - if (auto rc = target->activeRunConfiguration()) { - if (isLocal(target)) { // FIXME for now only Desktop support + if (auto rc = buildConfig->activeRunConfiguration()) { + if (isLocal(buildConfig->target())) { // FIXME for now only Desktop support const ProcessRunData runnable = rc->runnable(); m_runnable.environment = runnable.environment; m_deducedConfiguration = true; m_deducedFrom = rc->displayName(); if (runMode == TestRunMode::Debug) - m_runConfig = new Internal::TestRunConfiguration(rc->target(), this); + m_runConfig = new Internal::TestRunConfiguration(rc->buildConfiguration(), this); } else { qCDebug(LOG) << "not using the fallback as the current active run configuration " "appears to be non-Desktop"; diff --git a/src/plugins/autotest/testrunconfiguration.h b/src/plugins/autotest/testrunconfiguration.h index fb81fb4d890..53dc819fa73 100644 --- a/src/plugins/autotest/testrunconfiguration.h +++ b/src/plugins/autotest/testrunconfiguration.h @@ -9,7 +9,6 @@ #include <projectexplorer/devicesupport/devicemanager.h> #include <projectexplorer/projectexplorer.h> -#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/runconfiguration.h> #include <utils/qtcassert.h> @@ -22,9 +21,9 @@ namespace Internal { class TestRunConfiguration : public ProjectExplorer::RunConfiguration { public: - TestRunConfiguration(ProjectExplorer::Target *parent, TestConfiguration *config) - : ProjectExplorer::RunConfiguration(parent, "AutoTest.TestRunConfig"), - debuggerAspect(parent) + TestRunConfiguration(ProjectExplorer::BuildConfiguration *bc, TestConfiguration *config) + : ProjectExplorer::RunConfiguration(bc, "AutoTest.TestRunConfig"), + debuggerAspect(target()) { setDefaultDisplayName(QCoreApplication::translate("QtC::Autotest", "AutoTest Debug")); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 880aac181b8..51f3ab91c5d 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -245,16 +245,13 @@ static QString firstNonEmptyTestCaseTarget(const TestConfiguration *config) static RunConfiguration *getRunConfiguration(const QString &buildTargetKey) { - const Project *project = ProjectManager::startupProject(); - if (!project) - return nullptr; - const Target *target = project->activeTarget(); - if (!target) + const BuildConfiguration * const buildConfig = activeBuildConfigForActiveProject(); + if (!buildConfig) return nullptr; RunConfiguration *runConfig = nullptr; const QList<RunConfiguration *> runConfigurations - = Utils::filtered(target->runConfigurations(), [](const RunConfiguration *rc) { + = Utils::filtered(buildConfig->runConfigurations(), [](const RunConfiguration *rc) { return !rc->runnable().command.isEmpty(); }); @@ -614,8 +611,9 @@ void TestRunner::debugTests() static bool executablesEmpty() { - Target *target = ProjectManager::startupTarget(); - const QList<RunConfiguration *> configs = target->runConfigurations(); + const BuildConfiguration * const buildConfig = activeBuildConfigForActiveProject(); + QTC_ASSERT(buildConfig, return false); + const QList<RunConfiguration *> configs = buildConfig->runConfigurations(); QTC_ASSERT(!configs.isEmpty(), return false); if (auto execAspect = configs.first()->aspect<ExecutableAspect>()) return execAspect->executable().isEmpty(); @@ -801,16 +799,14 @@ void RunConfigurationSelectionDialog::populate() { m_rcCombo->addItem({}, QStringList{{}, {}, {}}); // empty default - if (auto project = ProjectManager::startupProject()) { - if (auto target = project->activeTarget()) { - for (RunConfiguration *rc : target->runConfigurations()) { - auto runnable = rc->runnable(); - const QStringList rcDetails - = {runnable.command.executable().toUserOutput(), - runnable.command.arguments(), - runnable.workingDirectory.toUserOutput()}; - m_rcCombo->addItem(rc->displayName(), rcDetails); - } + if (auto buildConfig = activeBuildConfigForActiveProject()) { + for (RunConfiguration *rc : buildConfig->runConfigurations()) { + auto runnable = rc->runnable(); + const QStringList rcDetails + = {runnable.command.executable().toUserOutput(), + runnable.command.arguments(), + runnable.workingDirectory.toUserOutput()}; + m_rcCombo->addItem(rc->displayName(), rcDetails); } } } diff --git a/src/plugins/baremetal/baremetalrunconfiguration.cpp b/src/plugins/baremetal/baremetalrunconfiguration.cpp index f021854e6ec..18242457436 100644 --- a/src/plugins/baremetal/baremetalrunconfiguration.cpp +++ b/src/plugins/baremetal/baremetalrunconfiguration.cpp @@ -24,18 +24,16 @@ namespace BareMetal::Internal { class BareMetalRunConfiguration final : public RunConfiguration { public: - explicit BareMetalRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + explicit BareMetalRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); executable.setPlaceHolderText(Tr::tr("Unknown")); setUpdater([this] { const BuildTargetInfo bti = buildTargetInfo(); executable.setExecutable(bti.targetFilePath); }); - - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); } ExecutableAspect executable{this}; @@ -46,10 +44,10 @@ public: class BareMetalCustomRunConfiguration final : public RunConfiguration { public: - explicit BareMetalCustomRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + explicit BareMetalCustomRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); executable.setSettingsKey("BareMetal.CustomRunConfig.Executable"); executable.setPlaceHolderText(Tr::tr("Unknown")); executable.setReadOnly(false); @@ -57,7 +55,7 @@ public: executable.setExpectedKind(PathChooser::Any); setDefaultDisplayName(RunConfigurationFactory::decoratedTargetName( - Tr::tr("Custom Executable"), target)); + Tr::tr("Custom Executable"), target())); setUsesEmptyBuildKeys(); } diff --git a/src/plugins/boot2qt/qdbrunconfiguration.cpp b/src/plugins/boot2qt/qdbrunconfiguration.cpp index 2ac17b1068f..f8f871feba4 100644 --- a/src/plugins/boot2qt/qdbrunconfiguration.cpp +++ b/src/plugins/boot2qt/qdbrunconfiguration.cpp @@ -30,12 +30,12 @@ namespace Qdb::Internal { class QdbRunConfiguration : public RunConfiguration { public: - QdbRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + QdbRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { setDefaultDisplayName(Tr::tr("Run on Boot to Qt Device")); - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); executable.setSettingsKey("QdbRunConfig.RemoteExecutable"); executable.setLabelText(Tr::tr("Executable on device:")); executable.setPlaceHolderText(Tr::tr("Remote path not set")); @@ -45,26 +45,23 @@ public: symbolFile.setSettingsKey("QdbRunConfig.LocalExecutable"); symbolFile.setLabelText(Tr::tr("Executable on host:")); - environment.setDeviceSelector(target, EnvironmentAspect::RunDevice); + environment.setDeviceSelector(target(), EnvironmentAspect::RunDevice); workingDir.setEnvironment(&environment); fullCommand.setLabelText(Tr::tr("Full command line:")); - setUpdater([this, target] { + setUpdater([this] { const BuildTargetInfo bti = buildTargetInfo(); const FilePath localExecutable = bti.targetFilePath; - const DeployableFile depFile = target->deploymentData().deployableForLocalFile(localExecutable); + const DeployableFile depFile = buildSystem()->deploymentData().deployableForLocalFile( + localExecutable); IDevice::ConstPtr dev = RunDeviceKitAspect::device(kit()); QTC_ASSERT(dev, return); executable.setExecutable(dev->filePath(depFile.remoteFilePath())); symbolFile.setValue(localExecutable); }); - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); - connect(target, &Target::deploymentDataChanged, this, &RunConfiguration::update); - connect(target, &Target::kitChanged, this, &RunConfiguration::update); - auto updateFullCommand = [this] { CommandLine plain{executable(), arguments(), CommandLine::Raw}; CommandLine cmd; diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index 8536f5f8ea0..52b5e0ac02b 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -83,9 +83,9 @@ public: }); RunControl *runControl = *task(); QTC_ASSERT(runControl, emit done(DoneResult::Error); return); - Target *target = runControl->target(); - QTC_ASSERT(target, emit done(DoneResult::Error); return); - if (!BuildManager::isBuilding(target)) { + BuildConfiguration *bc = runControl->buildConfiguration(); + QTC_ASSERT(bc, emit done(DoneResult::Error); return); + if (!BuildManager::isBuilding(bc->target())) { BuildManager::buildProjectWithDependencies(runControl->project(), ConfigSelection::Active, runControl); } @@ -669,8 +669,7 @@ Group ClangTool::runRecipe(const RunSettings &runSettings, std::shared_ptr<TemporaryDirectory> tempDir(new TemporaryDirectory("clangtools-XXXXXX")); tempDir->setAutoRemove(qtcEnvironmentVariable("QTC_CLANG_DONT_DELETE_OUTPUT_FILES") != "1"); - Target *target = m_runControl->target(); - BuildConfiguration *buildConfiguration = target->activeBuildConfiguration(); + BuildConfiguration *buildConfiguration = m_runControl->buildConfiguration(); QTC_ASSERT(buildConfiguration, return {}); const Environment environment = buildConfiguration->environment(); @@ -811,12 +810,12 @@ Group ClangTool::runRecipe(const RunSettings &runSettings, return SetupResult::Continue; }; - const auto onTreeDone = [this, target, runSettings] { + const auto onTreeDone = [this, buildConfiguration, runSettings] { if (m_filesFailed != 0) { m_runControl->postMessage(Tr::tr("Error: Failed to analyze %n files.", nullptr, m_filesFailed), ErrorMessageFormat); - if (target && target->activeBuildConfiguration() - && !target->activeBuildConfiguration()->buildDirectory().exists() + if (buildConfiguration + && !buildConfiguration->buildDirectory().exists() && !runSettings.buildBeforeAnalysis()) { m_runControl->postMessage( Tr::tr("Note: You might need to build the project to generate or update " @@ -873,7 +872,7 @@ void ClangTool::startTool(FileSelection fileSelection, const RunSettings &runSet m_runControl = new RunControl(Constants::CLANGTIDYCLAZY_RUN_MODE); m_runControl->setDisplayName(m_name); m_runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR); - m_runControl->setTarget(project->activeTarget()); + m_runControl->setBuildConfiguration(project->activeBuildConfiguration()); m_stopAction->disconnect(); connect(m_stopAction, &QAction::triggered, m_runControl, [this] { m_runControl->postMessage(Tr::tr("%1 tool stopped by user.").arg(m_name), diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index c25833f9a55..c13176dd561 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -2290,7 +2290,7 @@ void DebuggerPlugin::attachExternalApplication(RunControl *rc) ProcessHandle pid = rc->applicationProcessHandle(); auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE); - runControl->setTarget(rc->target()); + runControl->setBuildConfiguration(rc->buildConfiguration()); runControl->setDisplayName(Tr::tr("Process %1").arg(pid.pid())); auto debugger = new DebuggerRunTool(runControl); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index 3f53005d924..299e223a3cf 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -692,8 +692,10 @@ Project::RestoreResult GenericProject::fromMap(const Store &map, QString *errorM removeTarget(t); continue; } - if (!t->activeRunConfiguration()) - t->addRunConfiguration(new CustomExecutableRunConfiguration(t)); + for (BuildConfiguration * const bc : t->buildConfigurations()) { + if (!bc->activeRunConfiguration()) + bc->addRunConfiguration(new CustomExecutableRunConfiguration(bc)); + } } if (auto bs = activeBuildSystem()) diff --git a/src/plugins/haskell/haskellrunconfiguration.cpp b/src/plugins/haskell/haskellrunconfiguration.cpp index 146d6898ecf..1c65350d15a 100644 --- a/src/plugins/haskell/haskellrunconfiguration.cpp +++ b/src/plugins/haskell/haskellrunconfiguration.cpp @@ -29,10 +29,10 @@ namespace Haskell::Internal { class HaskellRunConfiguration final : public RunConfiguration { public: - HaskellRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + HaskellRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - environment.setSupportForBuildEnvironment(target); + environment.setSupportForBuildEnvironment(bc); executable.setSettingsKey("Haskell.Executable"); executable.setLabelText(Tr::tr("Executable")); @@ -42,8 +42,6 @@ public: workingDir.setVisible(false); setUpdater([this] { executable.setValue(buildTargetInfo().buildKey); }); - - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); update(); } diff --git a/src/plugins/ios/iosdeploystep.cpp b/src/plugins/ios/iosdeploystep.cpp index 7f999994b82..216ef52880f 100644 --- a/src/plugins/ios/iosdeploystep.cpp +++ b/src/plugins/ios/iosdeploystep.cpp @@ -205,7 +205,7 @@ bool IosDeployStep::init() { m_device = RunDeviceKitAspect::device(kit()); auto runConfig = qobject_cast<const IosRunConfiguration *>( - this->target()->activeRunConfiguration()); + buildConfiguration()->activeRunConfiguration()); QTC_ASSERT(runConfig, return false); m_bundlePath = runConfig->bundleDirectory(); diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp index 8896d8b8ea2..17cc96f1488 100644 --- a/src/plugins/ios/iosrunconfiguration.cpp +++ b/src/plugins/ios/iosrunconfiguration.cpp @@ -9,7 +9,6 @@ #include "simulatorcontrol.h" #include <projectexplorer/buildconfiguration.h> -#include <projectexplorer/buildstep.h> #include <projectexplorer/buildsteplist.h> #include <projectexplorer/deployconfiguration.h> #include <projectexplorer/devicesupport/devicekitaspects.h> @@ -25,7 +24,6 @@ #include <utils/async.h> #include <utils/filepath.h> #include <utils/layoutbuilder.h> -#include <utils/qtcassert.h> #include <utils/qtcprocess.h> #include <QAction> @@ -59,10 +57,10 @@ static IosDeviceType toIosDeviceType(const SimulatorInfo &device) return iosDeviceType; } -IosRunConfiguration::IosRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id), iosDeviceType(this, this) +IosRunConfiguration::IosRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id), iosDeviceType(this, this) { - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(bc->target(), ExecutableAspect::RunDevice); setUpdater([this] { IDevice::ConstPtr dev = RunDeviceKitAspect::device(kit()); diff --git a/src/plugins/ios/iosrunconfiguration.h b/src/plugins/ios/iosrunconfiguration.h index 549a418f20d..dd74b582453 100644 --- a/src/plugins/ios/iosrunconfiguration.h +++ b/src/plugins/ios/iosrunconfiguration.h @@ -66,7 +66,7 @@ class IosRunConfiguration : public ProjectExplorer::RunConfiguration Q_OBJECT // FIXME: Used in IosDsymBuildStep public: - IosRunConfiguration(ProjectExplorer::Target *target, Utils::Id id); + IosRunConfiguration(ProjectExplorer::BuildConfiguration *bc, Utils::Id id); QString applicationName() const; Utils::FilePath bundleDirectory() const; diff --git a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp index 550b13f6557..880782a3bcd 100644 --- a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp +++ b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp @@ -43,8 +43,8 @@ static QStringList flashAndRunArgs(const RunConfiguration *rc) class FlashAndRunConfiguration final : public RunConfiguration { public: - FlashAndRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + FlashAndRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { flashAndRunParameters.setLabelText(Tr::tr("Flash and run CMake parameters:")); flashAndRunParameters.setDisplayStyle(StringAspect::TextEditDisplay); @@ -82,11 +82,11 @@ FlashRunWorkerFactory::FlashRunWorkerFactory() setProducer([](RunControl *runControl) { auto worker = new ProcessRunner(runControl); worker->setStartModifier([worker, runControl] { - const Target *target = runControl->target(); - worker->setCommandLine({cmakeFilePath(target), + const BuildConfiguration *bc = runControl->buildConfiguration(); + worker->setCommandLine({cmakeFilePath(bc->target()), runControl->aspectData<StringAspect>()->value, CommandLine::Raw}); - worker->setWorkingDirectory(target->activeBuildConfiguration()->buildDirectory()); - worker->setEnvironment(target->activeBuildConfiguration()->environment()); + worker->setWorkingDirectory(bc->buildDirectory()); + worker->setEnvironment(bc->environment()); }); QObject::connect(runControl, &RunControl::started, runControl, [] { diff --git a/src/plugins/mesonprojectmanager/mesonrunconfiguration.cpp b/src/plugins/mesonprojectmanager/mesonrunconfiguration.cpp index caf0823e7cd..a74c535cd5b 100644 --- a/src/plugins/mesonprojectmanager/mesonrunconfiguration.cpp +++ b/src/plugins/mesonprojectmanager/mesonrunconfiguration.cpp @@ -24,12 +24,12 @@ namespace MesonProjectManager::Internal { class MesonRunConfiguration final : public RunConfiguration { public: - MesonRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + MesonRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - environment.setSupportForBuildEnvironment(target); + environment.setSupportForBuildEnvironment(bc); - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); workingDir.setEnvironment(&environment); @@ -54,17 +54,13 @@ public: }); setUpdater([this] { - if (!activeBuildSystem()) - return; - + QTC_ASSERT(buildSystem(), return); BuildTargetInfo bti = buildTargetInfo(); terminal.setUseTerminalHint(bti.usesTerminal); executable.setExecutable(bti.targetFilePath); workingDir.setDefaultWorkingDirectory(bti.workingDirectory); emit environment.environmentChanged(); }); - - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); } EnvironmentAspect environment{this}; diff --git a/src/plugins/nim/project/nimblerunconfiguration.cpp b/src/plugins/nim/project/nimblerunconfiguration.cpp index adecb710e9c..2aee49934c6 100644 --- a/src/plugins/nim/project/nimblerunconfiguration.cpp +++ b/src/plugins/nim/project/nimblerunconfiguration.cpp @@ -22,12 +22,12 @@ namespace Nim { class NimbleRunConfiguration : public RunConfiguration { public: - NimbleRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + NimbleRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - environment.setSupportForBuildEnvironment(target); + environment.setSupportForBuildEnvironment(bc); - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); setUpdater([this] { BuildTargetInfo bti = buildTargetInfo(); @@ -36,8 +36,6 @@ public: executable.setExecutable(bti.targetFilePath); workingDir.setDefaultWorkingDirectory(bti.workingDirectory); }); - - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); update(); } @@ -62,13 +60,13 @@ NimbleRunConfigurationFactory::NimbleRunConfigurationFactory() class NimbleTestConfiguration : public RunConfiguration { public: - NimbleTestConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + NimbleTestConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { setDisplayName(Tr::tr("Nimble Test")); setDefaultDisplayName(Tr::tr("Nimble Test")); - executable.setDeviceSelector(target, ExecutableAspect::BuildDevice); + executable.setDeviceSelector(target(), ExecutableAspect::BuildDevice); executable.setExecutable(Nim::nimblePathFromKit(kit())); arguments.setArguments("test"); diff --git a/src/plugins/nim/project/nimrunconfiguration.cpp b/src/plugins/nim/project/nimrunconfiguration.cpp index c640234c7b4..6f29a69eee3 100644 --- a/src/plugins/nim/project/nimrunconfiguration.cpp +++ b/src/plugins/nim/project/nimrunconfiguration.cpp @@ -24,27 +24,24 @@ namespace Nim { class NimRunConfiguration final : public RunConfiguration { public: - NimRunConfiguration(Target *target, Utils::Id id) - : RunConfiguration(target, id) + NimRunConfiguration(BuildConfiguration *bc, Utils::Id id) + : RunConfiguration(bc, id) { - environment.setSupportForBuildEnvironment(target); + environment.setSupportForBuildEnvironment(bc); - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); setDisplayName(Tr::tr("Current Build Target")); setDefaultDisplayName(Tr::tr("Current Build Target")); - setUpdater([this, target] { - auto buildConfiguration = qobject_cast<NimBuildConfiguration *>(target->activeBuildConfiguration()); + setUpdater([this, bc] { + auto buildConfiguration = qobject_cast<NimBuildConfiguration *>(bc); QTC_ASSERT(buildConfiguration, return); const QFileInfo outFileInfo = buildConfiguration->outFilePath().toFileInfo(); executable.setExecutable(FilePath::fromString(outFileInfo.absoluteFilePath())); const QString workingDirectory = outFileInfo.absoluteDir().absolutePath(); workingDir.setDefaultWorkingDirectory(FilePath::fromString(workingDirectory)); }); - - // Connect target signals - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); update(); } diff --git a/src/plugins/perfprofiler/perfdatareader.cpp b/src/plugins/perfprofiler/perfdatareader.cpp index d783a6a733a..422c7c2bbfa 100644 --- a/src/plugins/perfprofiler/perfdatareader.cpp +++ b/src/plugins/perfprofiler/perfdatareader.cpp @@ -384,7 +384,7 @@ void PerfDataReader::addTargetArguments(CommandLine *cmd, const RunControl *runC { ProjectExplorer::Kit *kit = runControl->kit(); QTC_ASSERT(kit, return); - ProjectExplorer::BuildConfiguration *buildConfig = runControl->target()->activeBuildConfiguration(); + ProjectExplorer::BuildConfiguration *buildConfig = runControl->buildConfiguration(); QString buildDir = buildConfig ? buildConfig->buildDirectory().toUrlishString() : QString(); collectArguments(cmd, buildDir, kit); } diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index a9ebcdf723e..c566b3f57b6 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -19,6 +19,7 @@ #include "projectconfigurationmodel.h" #include "projectexplorerconstants.h" #include "projectexplorer.h" +#include "projectexplorersettings.h" #include "projectexplorertr.h" #include "project.h" #include "projectmanager.h" @@ -27,7 +28,6 @@ #include <coreplugin/fileutils.h> #include <coreplugin/icore.h> -#include <coreplugin/idocument.h> #include <projectexplorer/devicesupport/idevice.h> @@ -57,6 +57,10 @@ const char ACTIVE_DC_KEY[] = "ProjectExplorer.Target.ActiveDeployConfiguration"; const char DC_KEY_PREFIX[] = "ProjectExplorer.Target.DeployConfiguration."; const char DC_COUNT_KEY[] = "ProjectExplorer.Target.DeployConfigurationCount"; +const char ACTIVE_RC_KEY[] = "ProjectExplorer.Target.ActiveRunConfiguration"; +const char RC_KEY_PREFIX[] = "ProjectExplorer.Target.RunConfiguration."; +const char RC_COUNT_KEY[] = "ProjectExplorer.Target.RunConfigurationCount"; + Q_LOGGING_CATEGORY(bcLog, "qtc.buildconfig", QtWarningMsg) namespace ProjectExplorer { @@ -146,6 +150,7 @@ public: , m_tooltipAspect(bc) , m_buildSystem(bc->project()->createBuildSystem(bc)) , m_deployConfigurationModel(bc->target()) + , m_runConfigurationModel(bc->target()) {} ~BuildConfigurationPrivate() { delete m_buildSystem; } @@ -167,8 +172,11 @@ public: BuildSystem * const m_buildSystem; QList<DeployConfiguration *> m_deployConfigurations; DeployConfiguration *m_activeDeployConfiguration = nullptr; + QList<RunConfiguration *> m_runConfigurations; + RunConfiguration* m_activeRunConfiguration = nullptr; ProjectConfigurationModel m_deployConfigurationModel; + ProjectConfigurationModel m_runConfigurationModel; // FIXME: Remove. BuildConfiguration::BuildType m_initialBuildType = BuildConfiguration::Unknown; @@ -242,6 +250,7 @@ BuildConfiguration::BuildConfiguration(Target *target, Utils::Id id) BuildConfiguration::~BuildConfiguration() { qDeleteAll(d->m_deployConfigurations); + qDeleteAll(d->m_runConfigurations); delete d; } @@ -366,6 +375,32 @@ bool BuildConfiguration::addConfigurationsFromMap( if (i == activeDc) setActiveDeployConfiguration(dc); } + + + int rcCount = map.value(RC_COUNT_KEY, 0).toInt(&ok); + if (!ok || rcCount < 0) + rcCount = 0; + int activeRc = map.value(ACTIVE_RC_KEY, 0).toInt(&ok); + if (!ok || 0 > activeRc || rcCount < activeRc) + activeRc = 0; + if (!setActiveConfigurations) + activeRc = -1; + + for (int i = 0; i < rcCount; ++i) { + const Key key = numberedKey(RC_KEY_PREFIX, i); + if (!map.contains(key)) + return false; + + // Ignore missing RCs: We will just populate them using the default ones. + Store valueMap = storeFromVariant(map.value(key)); + RunConfiguration *rc = RunConfigurationFactory::restore(this, valueMap); + if (!rc) + continue; + addRunConfiguration(rc); + if (i == activeRc) + setActiveRunConfiguration(rc); + } + return true; } @@ -379,6 +414,15 @@ void BuildConfiguration::storeConfigurationsToMap(Utils::Store &map) const dcs.at(i)->toMap(data); map.insert(numberedKey(DC_KEY_PREFIX, i), variantFromStore(data)); } + + const QList<RunConfiguration *> rcs = runConfigurations(); + map.insert(ACTIVE_RC_KEY, rcs.indexOf(d->m_activeRunConfiguration)); + map.insert(RC_COUNT_KEY, rcs.size()); + for (int i = 0; i < rcs.size(); ++i) { + Store data; + rcs.at(i)->toMap(data); + map.insert(numberedKey(RC_KEY_PREFIX, i), variantFromStore(data)); + } } void BuildConfiguration::setActiveDeployConfiguration(DeployConfiguration *dc) @@ -587,6 +631,228 @@ void BuildConfiguration::updateDefaultDeployConfigurations() } } +void BuildConfiguration::updateDefaultRunConfigurations() +{ + // Manual and Auto + const QList<RunConfigurationCreationInfo> creators + = RunConfigurationFactory::creatorsForTarget(target()); + + if (creators.isEmpty()) { + qWarning("No run configuration factory found for target id '%s'.", qPrintable(id().toString())); + return; + } + + QList<RunConfiguration *> existingConfigured; // Existing configured RCs + QList<RunConfiguration *> existingUnconfigured; // Existing unconfigured RCs + QList<RunConfiguration *> newConfigured; // NEW configured Rcs + QList<RunConfiguration *> newUnconfigured; // NEW unconfigured RCs + + // sort existing RCs into configured/unconfigured. + std::tie(existingConfigured, existingUnconfigured) + = Utils::partition(runConfigurations(), + [](const RunConfiguration *rc) { return rc->isConfigured(); }); + int configuredCount = existingConfigured.count(); + + // Put outdated RCs into toRemove, do not bother with factories + // that produce already existing RCs + QList<RunConfiguration *> toRemove; + QList<RunConfigurationCreationInfo> existing; + for (RunConfiguration *rc : std::as_const(existingConfigured)) { + bool present = false; + for (const RunConfigurationCreationInfo &item : creators) { + QString buildKey = rc->buildKey(); + if (item.factory->runConfigurationId() == rc->id() && item.buildKey == buildKey) { + existing.append(item); + present = true; + } + } + if (!present && + projectExplorerSettings().automaticallyCreateRunConfigurations && + !rc->isCustomized()) { + toRemove.append(rc); + } + } + configuredCount -= toRemove.count(); + + bool removeExistingUnconfigured = false; + if (projectExplorerSettings().automaticallyCreateRunConfigurations) { + // Create new "automatic" RCs and put them into newConfigured/newUnconfigured + for (const RunConfigurationCreationInfo &item : creators) { + if (item.creationMode == RunConfigurationCreationInfo::ManualCreationOnly) + continue; + bool exists = false; + for (const RunConfigurationCreationInfo &ex : existing) { + if (ex.factory == item.factory && ex.buildKey == item.buildKey) + exists = true; + } + if (exists) + continue; + + RunConfiguration *rc = item.create(this); + if (!rc) + continue; + QTC_CHECK(rc->id() == item.factory->runConfigurationId()); + if (!rc->isConfigured()) + newUnconfigured << rc; + else + newConfigured << rc; + } + configuredCount += newConfigured.count(); + + // Decide what to do with the different categories: + if (configuredCount > 0) { + // new non-Custom Executable RCs were added + removeExistingUnconfigured = true; + qDeleteAll(newUnconfigured); + newUnconfigured.clear(); + } else { + // no new RCs, use old or new CERCs? + if (!existingUnconfigured.isEmpty()) { + qDeleteAll(newUnconfigured); + newUnconfigured.clear(); + } + } + } + + // Do actual changes: + for (RunConfiguration *rc : std::as_const(newConfigured)) + addRunConfiguration(rc); + for (RunConfiguration *rc : std::as_const(newUnconfigured)) + addRunConfiguration(rc); + + // Generate complete list of RCs to remove later: + QList<RunConfiguration *> removalList; + for (RunConfiguration *rc : std::as_const(toRemove)) { + removalList << rc; + existingConfigured.removeOne(rc); // make sure to also remove them from existingConfigured! + } + + if (removeExistingUnconfigured) { + removalList.append(existingUnconfigured); + existingUnconfigured.clear(); + } + + // Make sure a configured RC will be active after we delete the RCs: + RunConfiguration *active = activeRunConfiguration(); + if (active && (removalList.contains(active) || !active->isEnabled(Constants::NORMAL_RUN_MODE))) { + RunConfiguration *newConfiguredDefault = newConfigured.isEmpty() ? nullptr : newConfigured.at(0); + + RunConfiguration *rc = Utils::findOrDefault(existingConfigured, [](RunConfiguration *rc) { + return rc->isEnabled(Constants::NORMAL_RUN_MODE); + }); + if (!rc) { + rc = Utils::findOr(newConfigured, newConfiguredDefault, + Utils::equal(&RunConfiguration::displayName, project()->displayName())); + } + if (!rc) + rc = newUnconfigured.isEmpty() ? nullptr : newUnconfigured.at(0); + if (!rc) { + // No RCs will be deleted, so use the one that will emit the minimum number of signals. + // One signal will be emitted from the next setActiveRunConfiguration, another one + // when the RC gets removed (and the activeRunConfiguration turns into a nullptr). + rc = removalList.isEmpty() ? nullptr : removalList.last(); + } + + if (rc) + setActiveRunConfiguration(rc); + } + + // Remove the RCs that are no longer needed: + for (RunConfiguration *rc : std::as_const(removalList)) + removeRunConfiguration(rc); + + if (this == target()->activeBuildConfiguration()) + emit target()->runConfigurationsUpdated(); +} + +const QList<RunConfiguration *> BuildConfiguration::runConfigurations() const +{ + return d->m_runConfigurations; +} + +void BuildConfiguration::addRunConfiguration(RunConfiguration *rc) +{ + QTC_ASSERT(rc && !d->m_runConfigurations.contains(rc), return); + Q_ASSERT(rc->target() == target()); + + // Check that we don't have a configuration with the same displayName + QString configurationDisplayName = rc->displayName(); + if (!configurationDisplayName.isEmpty()) { + QStringList displayNames = Utils::transform(d->m_runConfigurations, + &RunConfiguration::displayName); + configurationDisplayName = Utils::makeUniquelyNumbered(configurationDisplayName, + displayNames); + rc->setDisplayName(configurationDisplayName); + } + + d->m_runConfigurations.push_back(rc); + + ProjectExplorerPlugin::targetSelector()->addedRunConfiguration(rc); + d->m_runConfigurationModel.addProjectConfiguration(rc); + emit target()->addedRunConfiguration(rc); + + if (!activeRunConfiguration()) + setActiveRunConfiguration(rc); +} + +void BuildConfiguration::removeRunConfiguration(RunConfiguration *rc) +{ + QTC_ASSERT(rc && d->m_runConfigurations.contains(rc), return); + + d->m_runConfigurations.removeOne(rc); + + if (activeRunConfiguration() == rc) { + if (d->m_runConfigurations.isEmpty()) + setActiveRunConfiguration(nullptr); + else + setActiveRunConfiguration(d->m_runConfigurations.at(0)); + } + + emit target()->removedRunConfiguration(rc); + ProjectExplorerPlugin::targetSelector()->removedRunConfiguration(rc); + d->m_runConfigurationModel.removeProjectConfiguration(rc); + + delete rc; +} + +void BuildConfiguration::removeAllRunConfigurations() +{ + QList<RunConfiguration *> runConfigs = d->m_runConfigurations; + d->m_runConfigurations.clear(); + setActiveRunConfiguration(nullptr); + while (!runConfigs.isEmpty()) { + RunConfiguration * const rc = runConfigs.takeFirst(); + emit target()->removedRunConfiguration(rc); + ProjectExplorerPlugin::targetSelector()->removedRunConfiguration(rc); + d->m_runConfigurationModel.removeProjectConfiguration(rc); + delete rc; + } +} + +RunConfiguration *BuildConfiguration::activeRunConfiguration() const +{ + return d->m_activeRunConfiguration; +} + +void BuildConfiguration::setActiveRunConfiguration(RunConfiguration *rc) +{ + if (target()->isShuttingDown()) + return; + + if ((!rc && d->m_runConfigurations.isEmpty()) || + (rc && d->m_runConfigurations.contains(rc) && + rc != d->m_activeRunConfiguration)) { + d->m_activeRunConfiguration = rc; + emit target()->activeRunConfigurationChanged(d->m_activeRunConfiguration); + ProjectExplorerPlugin::updateActions(); + } +} + +ProjectConfigurationModel *BuildConfiguration::runConfigurationModel() const +{ + return &d->m_runConfigurationModel; +} + ProjectConfigurationModel *BuildConfiguration::deployConfigurationModel() const { return &d->m_deployConfigurationModel; @@ -815,6 +1081,15 @@ bool BuildConfiguration::isActive() const return project()->activeBuildConfiguration() == this; } +QString BuildConfiguration::activeBuildKey() const +{ + // Should not happen. If it does, return a buildKey that wont be found in + // the project tree, so that the project()->findNodeForBuildKey(buildKey) + // returns null. + QTC_ASSERT(d->m_activeRunConfiguration, return QString(QChar(0))); + return d->m_activeRunConfiguration->buildKey(); +} + FilePath BuildConfiguration::buildDirectoryFromTemplate(const FilePath &projectDir, const FilePath &mainFilePath, const QString &projectName, diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h index 98e381fc93b..a78f3b5c7be 100644 --- a/src/plugins/projectexplorer/buildconfiguration.h +++ b/src/plugins/projectexplorer/buildconfiguration.h @@ -82,6 +82,15 @@ public: void updateDefaultDeployConfigurations(); ProjectConfigurationModel *deployConfigurationModel() const; + void updateDefaultRunConfigurations(); + const QList<RunConfiguration *> runConfigurations() const; + void addRunConfiguration(RunConfiguration *rc); + void removeRunConfiguration(RunConfiguration *rc); + void removeAllRunConfigurations(); + RunConfiguration *activeRunConfiguration() const; + void setActiveRunConfiguration(RunConfiguration *rc); + ProjectConfigurationModel *runConfigurationModel() const; + virtual BuildConfiguration *clone(Target *target) const; void fromMap(const Utils::Store &map) override; void toMap(Utils::Store &map) const override; @@ -112,6 +121,7 @@ public: const QString &buildSystem); bool isActive() const; + QString activeBuildKey() const; // Build key of active run configuration void updateCacheAndEmitEnvironmentChanged(); diff --git a/src/plugins/projectexplorer/buildsystem.cpp b/src/plugins/projectexplorer/buildsystem.cpp index 9155dee9332..d919dac6f82 100644 --- a/src/plugins/projectexplorer/buildsystem.cpp +++ b/src/plugins/projectexplorer/buildsystem.cpp @@ -3,8 +3,12 @@ #include "buildsystem.h" +#include "buildaspects.h" #include "buildconfiguration.h" +#include "buildsteplist.h" +#include "deployconfiguration.h" #include "extracompiler.h" +#include "makestep.h" #include "projectexplorer.h" #include "projectexplorertr.h" #include "projectmanager.h" @@ -15,10 +19,6 @@ #include <coreplugin/messagemanager.h> #include <coreplugin/outputwindow.h> -#include <projectexplorer/buildaspects.h> -#include <projectexplorer/buildsteplist.h> -#include <projectexplorer/makestep.h> - #include <utils/algorithm.h> #include <utils/qtcassert.h> @@ -294,12 +294,17 @@ void BuildSystem::setDeploymentData(const DeploymentData &deploymentData) { if (d->m_deploymentData != deploymentData) { d->m_deploymentData = deploymentData; - emit target()->deploymentDataChanged(); + emit deploymentDataChanged(); + if (buildConfiguration() == target()->activeBuildConfiguration()) + emit target()->deploymentDataChanged(); } } DeploymentData BuildSystem::deploymentData() const { + const DeployConfiguration * const dc = buildConfiguration()->activeDeployConfiguration(); + if (dc && dc->usesCustomDeploymentData()) + return dc->customDeploymentData(); return d->m_deploymentData; } @@ -327,6 +332,7 @@ void BuildSystem::setRootProjectNode(std::unique_ptr<ProjectNode> &&root) void BuildSystem::emitBuildSystemUpdated() { + emit updated(); emit target()->buildSystemUpdated(this); } diff --git a/src/plugins/projectexplorer/buildsystem.h b/src/plugins/projectexplorer/buildsystem.h index f012e1e2a69..e6be18273aa 100644 --- a/src/plugins/projectexplorer/buildsystem.h +++ b/src/plugins/projectexplorer/buildsystem.h @@ -148,10 +148,12 @@ public: signals: void parsingStarted(); void parsingFinished(bool success); + void updated(); // FIXME: Redundant with parsingFinished()? void testInformationUpdated(); void debuggingStarted(); void errorOccurred(const QString &message); void warningOccurred(const QString &message); + void deploymentDataChanged(); protected: // Helper methods to manage parsing state and signalling diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp index fe4b707bf64..7cf56bc3e87 100644 --- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp +++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp @@ -8,24 +8,22 @@ #include "runconfigurationaspects.h" #include "target.h" -#include <utils/processinterface.h> - using namespace Utils; namespace ProjectExplorer { // CustomExecutableRunConfiguration -CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target) - : CustomExecutableRunConfiguration(target, Constants::CUSTOM_EXECUTABLE_RUNCONFIG_ID) +CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(BuildConfiguration *bc) + : CustomExecutableRunConfiguration(bc, Constants::CUSTOM_EXECUTABLE_RUNCONFIG_ID) {} -CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) +CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - environment.setSupportForBuildEnvironment(target); + environment.setSupportForBuildEnvironment(bc); - executable.setDeviceSelector(target, ExecutableAspect::HostDevice); + executable.setDeviceSelector(target(), ExecutableAspect::HostDevice); executable.setSettingsKey("ProjectExplorer.CustomExecutableRunConfiguration.Executable"); executable.setReadOnly(false); executable.setHistoryCompleter("Qt.CustomExecutable.History"); diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.h b/src/plugins/projectexplorer/customexecutablerunconfiguration.h index 3b9e8996b8a..73eb83cda95 100644 --- a/src/plugins/projectexplorer/customexecutablerunconfiguration.h +++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.h @@ -14,8 +14,8 @@ class PROJECTEXPLORER_EXPORT CustomExecutableRunConfiguration : public RunConfig Q_OBJECT public: - CustomExecutableRunConfiguration(Target *target, Utils::Id id); - explicit CustomExecutableRunConfiguration(Target *target); + CustomExecutableRunConfiguration(BuildConfiguration *bc, Utils::Id id); + explicit CustomExecutableRunConfiguration(BuildConfiguration *bc); QString defaultDisplayName() const; diff --git a/src/plugins/projectexplorer/desktoprunconfiguration.cpp b/src/plugins/projectexplorer/desktoprunconfiguration.cpp index 0fcaa7d3ee3..7ebc2983273 100644 --- a/src/plugins/projectexplorer/desktoprunconfiguration.cpp +++ b/src/plugins/projectexplorer/desktoprunconfiguration.cpp @@ -3,6 +3,7 @@ #include "desktoprunconfiguration.h" +#include "buildsystem.h" #include "deploymentdata.h" #include "projectexplorerconstants.h" #include "projectexplorertr.h" @@ -24,12 +25,12 @@ class DesktopRunConfiguration : public RunConfiguration protected: enum Kind { Qmake, Qbs, CMake }; // FIXME: Remove - DesktopRunConfiguration(Target *target, Id id, Kind kind) - : RunConfiguration(target, id), m_kind(kind) + DesktopRunConfiguration(BuildConfiguration *bc, Id id, Kind kind) + : RunConfiguration(bc, id), m_kind(kind) { - environment.setSupportForBuildEnvironment(target); + environment.setSupportForBuildEnvironment(bc); - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); workingDir.setEnvironment(&environment); @@ -70,8 +71,6 @@ protected: }); setUpdater([this] { updateTargetInformation(); }); - - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); } private: @@ -93,8 +92,7 @@ private: void DesktopRunConfiguration::updateTargetInformation() { - if (!activeBuildSystem()) - return; + QTC_ASSERT(buildSystem(), return); BuildTargetInfo bti = buildTargetInfo(); @@ -155,7 +153,7 @@ void DesktopRunConfiguration::updateTargetInformation() FilePath DesktopRunConfiguration::executableToRun(const BuildTargetInfo &targetInfo) const { const FilePath appInBuildDir = targetInfo.targetFilePath; - const DeploymentData deploymentData = target()->deploymentData(); + const DeploymentData deploymentData = buildSystem()->deploymentData(); if (deploymentData.localInstallRoot().isEmpty()) return appInBuildDir; @@ -175,24 +173,24 @@ FilePath DesktopRunConfiguration::executableToRun(const BuildTargetInfo &targetI class DesktopQmakeRunConfiguration final : public DesktopRunConfiguration { public: - DesktopQmakeRunConfiguration(Target *target, Id id) - : DesktopRunConfiguration(target, id, Qmake) + DesktopQmakeRunConfiguration(BuildConfiguration *bc, Id id) + : DesktopRunConfiguration(bc, id, Qmake) {} }; class QbsRunConfiguration final : public DesktopRunConfiguration { public: - QbsRunConfiguration(Target *target, Id id) - : DesktopRunConfiguration(target, id, Qbs) + QbsRunConfiguration(BuildConfiguration *bc, Id id) + : DesktopRunConfiguration(bc, id, Qbs) {} }; class CMakeRunConfiguration final : public DesktopRunConfiguration { public: - CMakeRunConfiguration(Target *target, Id id) - : DesktopRunConfiguration(target, id, CMake) + CMakeRunConfiguration(BuildConfiguration *bc, Id id) + : DesktopRunConfiguration(bc, id, CMake) {} }; diff --git a/src/plugins/projectexplorer/environmentaspect.cpp b/src/plugins/projectexplorer/environmentaspect.cpp index 5b2295d8132..f6c587f859b 100644 --- a/src/plugins/projectexplorer/environmentaspect.cpp +++ b/src/plugins/projectexplorer/environmentaspect.cpp @@ -123,7 +123,7 @@ int EnvironmentAspect::addPreferredBaseEnvironment(const QString &displayName, return index; } -void EnvironmentAspect::setSupportForBuildEnvironment(Target *target) +void EnvironmentAspect::setSupportForBuildEnvironment(BuildConfiguration *bc) { setIsLocal(true); addSupportedBaseEnvironment(Tr::tr("Clean Environment"), {}); @@ -131,16 +131,9 @@ void EnvironmentAspect::setSupportForBuildEnvironment(Target *target) addSupportedBaseEnvironment(Tr::tr("System Environment"), [] { return Environment::systemEnvironment(); }); - addPreferredBaseEnvironment(Tr::tr("Build Environment"), [target] { - if (BuildConfiguration *bc = target->activeBuildConfiguration()) - return bc->environment(); - // Fallback for targets without buildconfigurations: - return target->kit()->buildEnvironment(); - }); + addPreferredBaseEnvironment(Tr::tr("Build Environment"), [bc] { return bc->environment(); }); - connect(target, &Target::activeBuildConfigurationChanged, - this, &EnvironmentAspect::environmentChanged); - connect(target, &Target::buildEnvironmentChanged, + connect(bc, &BuildConfiguration::environmentChanged, this, &EnvironmentAspect::environmentChanged); } diff --git a/src/plugins/projectexplorer/environmentaspect.h b/src/plugins/projectexplorer/environmentaspect.h index 86d7d345008..7a7bdef3003 100644 --- a/src/plugins/projectexplorer/environmentaspect.h +++ b/src/plugins/projectexplorer/environmentaspect.h @@ -40,7 +40,7 @@ public: int addPreferredBaseEnvironment(const QString &displayName, const std::function<Utils::Environment()> &getter); - void setSupportForBuildEnvironment(Target *target); + void setSupportForBuildEnvironment(BuildConfiguration *bc); QString currentDisplayName() const; diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.cpp b/src/plugins/projectexplorer/miniprojecttargetselector.cpp index f75b2d9ee60..c155586c6b3 100644 --- a/src/plugins/projectexplorer/miniprojecttargetselector.cpp +++ b/src/plugins/projectexplorer/miniprojecttargetselector.cpp @@ -742,7 +742,7 @@ MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorActi }); connect(m_listWidgets[RUN], &GenericListWidget::changeActiveProjectConfiguration, this, [this](QObject *pc) { - m_project->activeTarget()->setActiveRunConfiguration(static_cast<RunConfiguration *>(pc)); + m_project->activeBuildConfiguration()->setActiveRunConfiguration(static_cast<RunConfiguration *>(pc)); }); } @@ -1027,8 +1027,6 @@ void MiniProjectTargetSelector::addedTarget(Target *target) for (BuildConfiguration *bc : target->buildConfigurations()) addedBuildConfiguration(bc, false); - for (RunConfiguration *rc : target->runConfigurations()) - addedRunConfiguration(rc, false); } void MiniProjectTargetSelector::removedTarget(Target *target) @@ -1040,8 +1038,6 @@ void MiniProjectTargetSelector::removedTarget(Target *target) for (BuildConfiguration *bc : target->buildConfigurations()) removedBuildConfiguration(bc, false); - for (RunConfiguration *rc : target->runConfigurations()) - removedRunConfiguration(rc, false); } void MiniProjectTargetSelector::addedBuildConfiguration(BuildConfiguration *bc, bool update) @@ -1051,6 +1047,8 @@ void MiniProjectTargetSelector::addedBuildConfiguration(BuildConfiguration *bc, for (DeployConfiguration *dc : bc->deployConfigurations()) addedDeployConfiguration(dc, false); + for (RunConfiguration *rc : bc->runConfigurations()) + addedRunConfiguration(rc, false); m_listWidgets[BUILD]->addProjectConfiguration(bc); if (update) @@ -1064,6 +1062,8 @@ void MiniProjectTargetSelector::removedBuildConfiguration(BuildConfiguration *bc for (DeployConfiguration *dc : bc->deployConfigurations()) removedDeployConfiguration(dc, false); + for (RunConfiguration *rc : bc->runConfigurations()) + removedRunConfiguration(rc, false); m_listWidgets[BUILD]->removeProjectConfiguration(bc); if (update) @@ -1174,8 +1174,10 @@ void MiniProjectTargetSelector::updateRunListVisible() int maxCount = 0; for (Project *p : ProjectManager::projects()) { const QList<Target *> targets = p->targets(); - for (Target *t : targets) - maxCount = qMax(t->runConfigurations().size(), maxCount); + for (Target *t : targets) { + for (const BuildConfiguration * const bc : t->buildConfigurations()) + maxCount = qMax(bc->runConfigurations().size(), maxCount); + } } bool visible = maxCount > 1; @@ -1252,16 +1254,6 @@ void MiniProjectTargetSelector::activeTargetChanged(Target *target) m_listWidgets[BUILD]->setProjectConfigurations(bl, target->activeBuildConfiguration()); activeBuildConfigurationChanged(target->activeBuildConfiguration()); - QObjectList rl; - for (RunConfiguration *rc : target->runConfigurations()) - rl.append(rc); - m_listWidgets[RUN]->setProjectConfigurations(rl, target->activeRunConfiguration()); - - m_runConfiguration = m_target->activeRunConfiguration(); - if (m_runConfiguration) - connect(m_runConfiguration, &ProjectConfiguration::displayNameChanged, - this, &MiniProjectTargetSelector::updateActionAndSummary); - connect(m_target, &Target::kitChanged, this, &MiniProjectTargetSelector::updateActionAndSummary); connect(m_target, &Target::iconChanged, @@ -1306,6 +1298,11 @@ void MiniProjectTargetSelector::activeBuildConfigurationChanged(BuildConfigurati dl.append(dc); m_listWidgets[DEPLOY]->setProjectConfigurations(dl, bc->activeDeployConfiguration()); activeDeployConfigurationChanged(m_buildConfiguration->activeDeployConfiguration()); + QObjectList rl; + for (RunConfiguration *rc : bc->runConfigurations()) + rl.append(rc); + m_listWidgets[RUN]->setProjectConfigurations(rl, bc->activeRunConfiguration()); + activeRunConfigurationChanged(m_buildConfiguration->activeRunConfiguration()); } else { m_listWidgets[DEPLOY]->setProjectConfigurations({}, nullptr); activeDeployConfigurationChanged(nullptr); diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 0467326f3d0..d2297e3e54b 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -514,7 +514,7 @@ Target *Project::createKitAndTargetFromStore(const Utils::Store &store) if (!t->fromMap(store)) return nullptr; - if (t->runConfigurations().isEmpty() && t->buildConfigurations().isEmpty()) + if (t->buildConfigurations().isEmpty()) return nullptr; auto pointer = t.get(); @@ -540,7 +540,6 @@ bool Project::copySteps(Target *sourceTarget, Target *newTarget) QStringList runconfigurationError; const Project * const project = newTarget->project(); - int dcCount = 0; for (BuildConfiguration *sourceBc : sourceTarget->buildConfigurations()) { BuildConfiguration *newBc = sourceBc->clone(newTarget); if (!newBc) { @@ -556,57 +555,17 @@ bool Project::copySteps(Target *sourceTarget, Target *newTarget) newTarget->addBuildConfiguration(newBc); if (sourceTarget->activeBuildConfiguration() == sourceBc) newTarget->setActiveBuildConfiguration(newBc, SetActive::NoCascade); - - for (DeployConfiguration *sourceDc : sourceBc->deployConfigurations()) { - ++dcCount; - DeployConfiguration *newDc = DeployConfigurationFactory::clone(newBc, sourceDc); - if (!newDc) { - deployconfigurationError << sourceDc->displayName(); - continue; - } - newDc->setDisplayName(sourceDc->displayName()); - newBc->addDeployConfiguration(newDc); - if (sourceBc->activeDeployConfiguration() == sourceDc) - newBc->setActiveDeployConfiguration(newDc, SetActive::NoCascade); - } - if (!newTarget->activeDeployConfiguration()) { - QList<DeployConfiguration *> dcs = newBc->deployConfigurations(); - if (!dcs.isEmpty()) - newBc->setActiveDeployConfiguration(dcs.first(), SetActive::NoCascade); - } } + if (!newTarget->activeBuildConfiguration()) { QList<BuildConfiguration *> bcs = newTarget->buildConfigurations(); if (!bcs.isEmpty()) newTarget->setActiveBuildConfiguration(bcs.first(), SetActive::NoCascade); } - for (RunConfiguration *sourceRc : sourceTarget->runConfigurations()) { - RunConfiguration *newRc = sourceRc->clone(newTarget); - if (!newRc) { - runconfigurationError << sourceRc->displayName(); - continue; - } - newRc->setDisplayName(sourceRc->displayName()); - newTarget->addRunConfiguration(newRc); - if (sourceTarget->activeRunConfiguration() == sourceRc) - newTarget->setActiveRunConfiguration(newRc); - } - if (!newTarget->activeRunConfiguration()) { - QList<RunConfiguration *> rcs = newTarget->runConfigurations(); - if (!rcs.isEmpty()) - newTarget->setActiveRunConfiguration(rcs.first()); - } - if (buildconfigurationError.count() == sourceTarget->buildConfigurations().count()) fatalError = true; - if (deployconfigurationError.count() == dcCount) - fatalError = true; - - if (runconfigurationError.count() == sourceTarget->runConfigurations().count()) - fatalError = true; - if (fatalError) { // That could be a more granular error message QMessageBox::critical(ICore::dialogParent(), @@ -657,7 +616,7 @@ bool Project::copySteps(const Utils::Store &store, Kit *targetKit) if (!t->fromMap(store)) return false; - if (t->runConfigurations().isEmpty() && t->buildConfigurations().isEmpty()) + if (t->buildConfigurations().isEmpty()) return false; addTarget(std::move(t)); @@ -926,7 +885,7 @@ void Project::createTargetFromMap(const Store &map, int index) if (!t->fromMap(targetMap)) return; - if (t->runConfigurations().isEmpty() && t->buildConfigurations().isEmpty()) + if (t->buildConfigurations().isEmpty()) return; addTarget(std::move(t)); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index e381c7474c5..6dd903a6c4b 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -290,16 +290,16 @@ static std::optional<Environment> buildEnv(const Project *project) return {}; } -static const RunConfiguration *runConfigForNode(const Target *target, const ProjectNode *node) +static const RunConfiguration *runConfigForNode(const BuildConfiguration *bc, const ProjectNode *node) { if (node && node->productType() == ProductType::App) { const QString buildKey = node->buildKey(); - for (const RunConfiguration * const rc : target->runConfigurations()) { + for (const RunConfiguration * const rc : bc->runConfigurations()) { if (rc->buildKey() == buildKey) return rc; } } - return target->activeRunConfiguration(); + return bc->activeRunConfiguration(); } static bool hideBuildMenu() @@ -316,10 +316,10 @@ static bool canOpenTerminalWithRunEnv(const Project *project, const ProjectNode { if (!project) return false; - const Target * const target = project->activeTarget(); - if (!target) + const BuildConfiguration * const bc = project->activeBuildConfiguration(); + if (!bc) return false; - const RunConfiguration * const runConfig = runConfigForNode(target, node); + const RunConfiguration * const runConfig = runConfigForNode(bc, node); if (!runConfig) return false; IDevice::ConstPtr device @@ -3348,9 +3348,9 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions(Node *currentNode) m_runActionContextMenu->setEnabled(true); } else { QList<RunConfiguration *> runConfigs; - if (Target *t = project->activeTarget()) { + if (BuildConfiguration *bc = project->activeBuildConfiguration()) { const QString buildKey = pn->buildKey(); - for (RunConfiguration *rc : t->runConfigurations()) { + for (RunConfiguration *rc : bc->runConfigurations()) { if (rc->buildKey() == buildKey) runConfigs.append(rc); } @@ -3807,16 +3807,15 @@ void ProjectExplorerPluginPrivate::openTerminalHereWithRunEnv() const Project * const project = ProjectTree::projectForNode(currentNode); QTC_ASSERT(project, return); - const Target * const target = project->activeTarget(); - QTC_ASSERT(target, return); - const RunConfiguration * const runConfig = runConfigForNode(target, - currentNode->asProjectNode()); + const BuildConfiguration * const bc = project->activeBuildConfiguration(); + QTC_ASSERT(bc, return); + const RunConfiguration * const runConfig = runConfigForNode(bc, currentNode->asProjectNode()); QTC_ASSERT(runConfig, return); const ProcessRunData runnable = runConfig->runnable(); IDevice::ConstPtr device = DeviceManager::deviceForPath(runnable.command.executable()); if (!device) - device = RunDeviceKitAspect::device(target->kit()); + device = RunDeviceKitAspect::device(bc->target()->kit()); QTC_ASSERT(device && device->canOpenTerminal(), return); FilePath workingDir = device->type() == Constants::DESKTOP_DEVICE_TYPE @@ -4244,10 +4243,10 @@ using RunAcceptor = std::function<void(RunConfiguration *)>; static RunConfiguration *runConfigurationForDisplayName(const QString &displayName) { - const Target *target = ProjectManager::startupTarget(); - if (!target) + const BuildConfiguration * const bc = activeBuildConfigForActiveProject(); + if (!bc) return nullptr; - const QList<RunConfiguration *> runconfigs = target->runConfigurations(); + const QList<RunConfiguration *> runconfigs = bc->runConfigurations(); return Utils::findOrDefault(runconfigs, [displayName](RunConfiguration *rc) { return rc->displayName() == displayName; }); @@ -4260,12 +4259,12 @@ static LocatorMatcherTasks runConfigurationMatchers(const RunAcceptor &acceptor) const auto onSetup = [acceptor] { const LocatorStorage &storage = *LocatorStorage::storage(); const QString input = storage.input(); - const Target *target = ProjectManager::startupTarget(); - if (!target) + const BuildConfiguration * const bc = activeBuildConfigForActiveProject(); + if (!bc) return; LocatorFilterEntries entries; - for (auto rc : target->runConfigurations()) { + for (auto rc : bc->runConfigurations()) { if (rc->displayName().contains(input, Qt::CaseInsensitive)) { LocatorFilterEntry entry; entry.displayName = rc->displayName(); @@ -4328,7 +4327,7 @@ LocatorMatcherTasks RunConfigurationDebugFilter::matchers() static void switchAcceptor(RunConfiguration *config) { - ProjectManager::startupTarget()->setActiveRunConfiguration(config); + activeBuildConfigForActiveProject()->setActiveRunConfiguration(config); QTimer::singleShot(200, ICore::mainWindow(), [name = config->displayName()] { if (auto ks = ICore::mainWindow()->findChild<QWidget *>("KitSelector.Button")) { ToolTip::show(ks->mapToGlobal(QPoint{25, 25}), diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 3aaf486b7a1..c9c3bc29d89 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -17,7 +17,6 @@ #include "runconfigurationaspects.h" #include "target.h" -#include <coreplugin/icontext.h> #include <coreplugin/icore.h> #include <projectexplorer/devicesupport/idevice.h> @@ -27,10 +26,8 @@ #include <utils/checkablemessagebox.h> #include <utils/detailswidget.h> #include <utils/layoutbuilder.h> -#include <utils/outputformatter.h> #include <utils/processinterface.h> #include <utils/qtcassert.h> -#include <utils/utilsicons.h> #include <utils/variablechooser.h> #include <QComboBox> @@ -200,19 +197,16 @@ static std::vector<RunConfiguration::AspectFactory> theAspectFactories; static QList<RunConfigurationFactory *> g_runConfigurationFactories; -RunConfiguration::RunConfiguration(Target *target, Utils::Id id) - : ProjectConfiguration(target, id) +RunConfiguration::RunConfiguration(BuildConfiguration *bc, Utils::Id id) + : ProjectConfiguration(bc->target(), id), m_buildConfiguration(bc) { forceDisplayNameSerialization(); - connect(target, &Target::parsingFinished, this, &RunConfiguration::update); + connect(bc->buildSystem(), &BuildSystem::parsingFinished, this, &RunConfiguration::update); MacroExpander &expander = *macroExpander(); expander.setDisplayName(Tr::tr("Run Settings")); expander.setAccumulating(true); - expander.registerSubProvider([target] { - BuildConfiguration *bc = target->activeBuildConfiguration(); - return bc ? bc->macroExpander() : target->macroExpander(); - }); + expander.registerSubProvider([bc] { return bc->macroExpander(); }); expander.registerPrefix("RunConfig:Env", Tr::tr("Variables in the run environment."), [this](const QString &var) { const auto envAspect = aspect<EnvironmentAspect>(); @@ -251,20 +245,23 @@ RunConfiguration::RunConfiguration(Target *target, Utils::Id id) return launcherCommand; }; + + connect(bc->buildSystem(), &BuildSystem::updated, this, &RunConfiguration::update); + connect(bc->buildSystem(), &BuildSystem::deploymentDataChanged, + this, &RunConfiguration::update); + connect(target(), &Target::kitChanged, this, &RunConfiguration::update); } RunConfiguration::~RunConfiguration() = default; QString RunConfiguration::disabledReason(Utils::Id) const { - BuildSystem *bs = activeBuildSystem(); - return bs ? bs->disabledReason(m_buildKey) : Tr::tr("No build system active"); + return buildSystem()->disabledReason(m_buildKey); } bool RunConfiguration::isEnabled(Utils::Id) const { - BuildSystem *bs = activeBuildSystem(); - return bs && bs->hasParsingData(); + return buildSystem()->hasParsingData(); } QWidget *RunConfiguration::createConfigurationWidget() @@ -346,9 +343,9 @@ AspectContainerData RunConfiguration::aspectData() const return data; } -BuildSystem *RunConfiguration::activeBuildSystem() const +BuildSystem *RunConfiguration::buildSystem() const { - return target()->buildSystem(); + return m_buildConfiguration->buildSystem(); } void RunConfiguration::setUpdater(const Updater &updater) @@ -413,16 +410,16 @@ void RunConfiguration::update() ProjectExplorerPlugin::updateRunActions(); } -RunConfiguration *RunConfiguration::clone(Target *parent) +RunConfiguration *RunConfiguration::clone(BuildConfiguration *bc) { Store map; toMap(map); - return RunConfigurationFactory::restore(parent, map); + return RunConfigurationFactory::restore(bc, map); } BuildTargetInfo RunConfiguration::buildTargetInfo() const { - BuildSystem *bs = target()->buildSystem(); + BuildSystem *bs = buildSystem(); QTC_ASSERT(bs, return {}); return bs->buildTarget(m_buildKey); } @@ -670,24 +667,24 @@ bool RunConfigurationFactory::canHandle(Target *target) const return true; } -RunConfiguration *RunConfigurationFactory::create(Target *target) const +RunConfiguration *RunConfigurationFactory::create(BuildConfiguration *bc) const { QTC_ASSERT(m_creator, return nullptr); - RunConfiguration *rc = m_creator(target); + RunConfiguration *rc = m_creator(bc); QTC_ASSERT(rc, return nullptr); // Add the universal aspects. for (const RunConfiguration::AspectFactory &factory : theAspectFactories) - rc->registerAspect(factory(target), true); + rc->registerAspect(factory(bc->target()), true); return rc; } -RunConfiguration *RunConfigurationCreationInfo::create(Target *target) const +RunConfiguration *RunConfigurationCreationInfo::create(BuildConfiguration *bc) const { - QTC_ASSERT(factory->canHandle(target), return nullptr); + QTC_ASSERT(factory->canHandle(bc->target()), return nullptr); - RunConfiguration *rc = factory->create(target); + RunConfiguration *rc = factory->create(bc); if (!rc) return nullptr; @@ -699,13 +696,13 @@ RunConfiguration *RunConfigurationCreationInfo::create(Target *target) const return rc; } -RunConfiguration *RunConfigurationFactory::restore(Target *parent, const Store &map) +RunConfiguration *RunConfigurationFactory::restore(BuildConfiguration *bc, const Store &map) { for (RunConfigurationFactory *factory : std::as_const(g_runConfigurationFactories)) { - if (factory->canHandle(parent)) { + if (factory->canHandle(bc->target())) { const Utils::Id id = idFromMap(map); if (id.name().startsWith(factory->m_runConfigurationId.name())) { - RunConfiguration *rc = factory->create(parent); + RunConfiguration *rc = factory->create(bc); rc->fromMap(map); if (!rc->hasError()) { rc->update(); diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 0b7ef7a1ac5..730402bd5c6 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -8,11 +8,9 @@ #include "task.h" #include <utils/aspects.h> -#include <utils/environment.h> #include <utils/macroexpander.h> #include <functional> -#include <memory> namespace Utils { class OutputFormatter; @@ -174,13 +172,14 @@ public: void update(); - virtual RunConfiguration *clone(Target *parent); + virtual RunConfiguration *clone(BuildConfiguration *bc); + + BuildConfiguration *buildConfiguration() const { return m_buildConfiguration; } protected: - RunConfiguration(Target *target, Utils::Id id); + RunConfiguration(BuildConfiguration *bc, Utils::Id id); - /// convenience function to get current build system. Try to avoid. - BuildSystem *activeBuildSystem() const; + BuildSystem *buildSystem() const; using Updater = std::function<void()>; void setUpdater(const Updater &updater); @@ -197,10 +196,12 @@ private: static void addAspectFactory(const AspectFactory &aspectFactory); + friend class BuildConfiguration; friend class RunConfigurationCreationInfo; friend class RunConfigurationFactory; friend class Target; + BuildConfiguration * const m_buildConfiguration; QString m_buildKey; CommandLineGetter m_commandLineGetter; RunnableModifier m_runnableModifier; @@ -214,7 +215,7 @@ class RunConfigurationCreationInfo { public: enum CreationMode {AlwaysCreate, ManualCreationOnly}; - RunConfiguration *create(Target *target) const; + RunConfiguration *create(BuildConfiguration *bc) const; const RunConfigurationFactory *factory = nullptr; QString buildKey; @@ -233,7 +234,7 @@ public: RunConfigurationFactory operator=(const RunConfigurationFactory &) = delete; virtual ~RunConfigurationFactory(); - static RunConfiguration *restore(Target *parent, const Utils::Store &map); + static RunConfiguration *restore(BuildConfiguration *bc, const Utils::Store &map); static const QList<RunConfigurationCreationInfo> creatorsForTarget(Target *parent); Utils::Id runConfigurationId() const { return m_runConfigurationId; } @@ -244,13 +245,13 @@ protected: virtual QList<RunConfigurationCreationInfo> availableCreators(Target *target) const; virtual bool supportsBuildKey(Target *target, const QString &key) const; - using RunConfigurationCreator = std::function<RunConfiguration *(Target *)>; + using RunConfigurationCreator = std::function<RunConfiguration *(BuildConfiguration *)>; template <class RunConfig> void registerRunConfiguration(Utils::Id runConfigurationId) { - m_creator = [runConfigurationId](Target *t) -> RunConfiguration * { - return new RunConfig(t, runConfigurationId); + m_creator = [runConfigurationId](BuildConfiguration *bc) -> RunConfiguration * { + return new RunConfig(bc, runConfigurationId); }; m_runConfigurationId = runConfigurationId; } @@ -261,7 +262,7 @@ protected: private: bool canHandle(Target *target) const; - RunConfiguration *create(Target *target) const; + RunConfiguration *create(BuildConfiguration *bc) const; friend class RunConfigurationCreationInfo; friend class RunConfiguration; diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp index 62cba86e8a0..e200d616385 100644 --- a/src/plugins/projectexplorer/runcontrol.cpp +++ b/src/plugins/projectexplorer/runcontrol.cpp @@ -274,7 +274,7 @@ public: FilePath buildDirectory; Environment buildEnvironment; Kit *kit = nullptr; // Not owned. - QPointer<Target> target; // Not owned. + QPointer<BuildConfiguration> buildConfiguration; // Not owned. QPointer<Project> project; // Not owned. std::function<bool(bool*)> promptToStop; std::vector<RunWorkerFactory> m_factories; @@ -399,28 +399,26 @@ void RunControl::copyDataFromRunConfiguration(RunConfiguration *runConfig) d->aspectData = runConfig->aspectData(); d->printEnvironment = runConfig->isPrintEnvironmentEnabled(); - setTarget(runConfig->target()); + setBuildConfiguration(runConfig->buildConfiguration()); d->macroExpander = runConfig->macroExpander(); } -void RunControl::setTarget(Target *target) +void RunControl::setBuildConfiguration(BuildConfiguration *bc) { - QTC_ASSERT(target, return); - QTC_CHECK(!d->target); - d->target = target; + QTC_ASSERT(bc, return); + QTC_CHECK(!d->buildConfiguration); + d->buildConfiguration = bc; - if (!d->buildKey.isEmpty() && target->buildSystem()) - d->buildTargetInfo = target->buildTarget(d->buildKey); + if (!d->buildKey.isEmpty()) + d->buildTargetInfo = bc->target()->buildTarget(d->buildKey); - if (auto bc = target->activeBuildConfiguration()) { - d->buildDirectory = bc->buildDirectory(); - d->buildEnvironment = bc->environment(); - } + d->buildDirectory = bc->buildDirectory(); + d->buildEnvironment = bc->environment(); - setKit(target->kit()); - d->macroExpander = target->macroExpander(); - d->project = target->project(); + setKit(bc->kit()); + d->macroExpander = bc->macroExpander(); + d->project = bc->project(); } void RunControl::setKit(Kit *kit) @@ -987,7 +985,7 @@ void RunControlPrivate::showError(const QString &msg) void RunControl::setupFormatter(OutputFormatter *formatter) const { - QList<Utils::OutputLineParser *> parsers = createOutputParsers(target()); + QList<Utils::OutputLineParser *> parsers = createOutputParsers(buildConfiguration()->target()); if (const auto customParsersAspect = aspectData<CustomParsersAspect>()) { for (const Id id : std::as_const(customParsersAspect->parsers)) { if (auto parser = createCustomParserFromId(id)) @@ -1085,9 +1083,9 @@ IDevice::ConstPtr RunControl::device() const return d->device; } -Target *RunControl::target() const +BuildConfiguration *RunControl::buildConfiguration() const { - return d->target; + return d->buildConfiguration; } Project *RunControl::project() const @@ -1535,8 +1533,8 @@ void ProcessRunnerPrivate::start() if (const auto rc = q->runControl()) { QString shellName = rc->displayName(); - if (rc->target()) { - if (BuildConfiguration *buildConfig = rc->target()->activeBuildConfiguration()) + if (rc->buildConfiguration()) { + if (BuildConfiguration *buildConfig = rc->buildConfiguration()) shellName += " - " + buildConfig->displayName(); } diff --git a/src/plugins/projectexplorer/runcontrol.h b/src/plugins/projectexplorer/runcontrol.h index 6ac749b200a..b3ab3cd4405 100644 --- a/src/plugins/projectexplorer/runcontrol.h +++ b/src/plugins/projectexplorer/runcontrol.h @@ -140,7 +140,7 @@ public: void start(); - void setTarget(Target *target); + void setBuildConfiguration(BuildConfiguration *bc); void setKit(Kit *kit); void copyDataFromRunConfiguration(RunConfiguration *runConfig); @@ -178,7 +178,7 @@ public: IDeviceConstPtr device() const; // FIXME: Try to cut down to amount of functions. - Target *target() const; + BuildConfiguration *buildConfiguration() const; Project *project() const; Kit *kit() const; const Utils::MacroExpander *macroExpander() const; diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp index 113acd1077a..160eb347426 100644 --- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp @@ -107,7 +107,16 @@ RunSettingsWidget::RunSettingsWidget(Target *target) : m_addDeployMenu = new QMenu(m_addDeployToolButton); m_addDeployToolButton->setMenu(m_addDeployMenu); + // run part + runWidget->setContentsMargins(0, 10, 0, 0); + m_runLayout = new QVBoxLayout(runWidget); + m_runLayout->setContentsMargins(0, 0, 0, 0); + m_runLayout->setSpacing(5); + m_disabledText = new Utils::InfoLabel({}, Utils::InfoLabel::Warning); + m_runLayout->addWidget(m_disabledText); + initForActiveBuildConfig(); + connect(m_addDeployMenu, &QMenu::aboutToShow, this, &RunSettingsWidget::aboutToShowDeployMenu); connect(m_removeDeployToolButton, &QAbstractButton::clicked, @@ -121,30 +130,8 @@ RunSettingsWidget::RunSettingsWidget(Target *target) : connect(m_target, &Target::activeBuildConfigurationChanged, this, &RunSettingsWidget::initForActiveBuildConfig); - // run part - runWidget->setContentsMargins(0, 10, 0, 0); - m_runLayout = new QVBoxLayout(runWidget); - m_runLayout->setContentsMargins(0, 0, 0, 0); - m_runLayout->setSpacing(5); - - m_disabledText = new Utils::InfoLabel({}, Utils::InfoLabel::Warning); - m_runLayout->addWidget(m_disabledText); - - ProjectConfigurationModel *model = m_target->runConfigurationModel(); - RunConfiguration *rc = m_target->activeRunConfiguration(); - m_runConfigurationCombo->setModel(model); - m_runConfigurationCombo->setCurrentIndex(model->indexFor(rc)); - - updateRemoveToolButtons(); - m_renameRunButton->setEnabled(rc); - m_cloneRunButton->setEnabled(rc); - - setConfigurationWidget(rc); - connect(m_addRunToolButton, &QAbstractButton::clicked, this, &RunSettingsWidget::showAddRunConfigDialog); - connect(m_runConfigurationCombo, &QComboBox::currentIndexChanged, - this, &RunSettingsWidget::currentRunConfigurationChanged); connect(m_removeRunToolButton, &QAbstractButton::clicked, this, &RunSettingsWidget::removeRunConfiguration); connect(m_removeAllRunConfigsButton, &QAbstractButton::clicked, @@ -175,12 +162,12 @@ void RunSettingsWidget::showAddRunConfigDialog() return; RunConfigurationCreationInfo rci = dlg.creationInfo(); QTC_ASSERT(rci.factory, return); - RunConfiguration *newRC = rci.create(m_target); + RunConfiguration *newRC = rci.create(m_target->activeBuildConfiguration()); if (!newRC) return; QTC_CHECK(newRC->id() == rci.factory->runConfigurationId()); - m_target->addRunConfiguration(newRC); - m_target->setActiveRunConfiguration(newRC); + m_target->activeBuildConfiguration()->addRunConfiguration(newRC); + m_target->activeBuildConfiguration()->setActiveRunConfiguration(newRC); updateRemoveToolButtons(); } @@ -198,13 +185,13 @@ void RunSettingsWidget::cloneRunConfiguration() if (name.isEmpty()) return; - RunConfiguration *newRc = activeRunConfiguration->clone(m_target); + RunConfiguration *newRc = activeRunConfiguration->clone(m_target->activeBuildConfiguration()); if (!newRc) return; newRc->setDisplayName(name); - m_target->addRunConfiguration(newRc); - m_target->setActiveRunConfiguration(newRc); + m_target->activeBuildConfiguration()->addRunConfiguration(newRc); + m_target->activeBuildConfiguration()->setActiveRunConfiguration(newRc); } void RunSettingsWidget::removeRunConfiguration() @@ -218,7 +205,7 @@ void RunSettingsWidget::removeRunConfiguration() if (msgBox.exec() == QMessageBox::No) return; - m_target->removeRunConfiguration(rc); + m_target->activeBuildConfiguration()->removeRunConfiguration(rc); updateRemoveToolButtons(); m_renameRunButton->setEnabled(m_target->activeRunConfiguration()); m_cloneRunButton->setEnabled(m_target->activeRunConfiguration()); @@ -237,7 +224,7 @@ void RunSettingsWidget::removeAllRunConfigurations() if (msgBox.exec() == QMessageBox::Cancel) return; - m_target->removeAllRunConfigurations(); + m_target->activeBuildConfiguration()->removeAllRunConfigurations(); updateRemoveToolButtons(); m_renameRunButton->setEnabled(false); m_cloneRunButton->setEnabled(false); @@ -248,7 +235,7 @@ void RunSettingsWidget::activeRunConfigurationChanged() if (m_ignoreChanges.isLocked()) return; - ProjectConfigurationModel *model = m_target->runConfigurationModel(); + ProjectConfigurationModel *model = m_target->activeBuildConfiguration()->runConfigurationModel(); int index = model->indexFor(m_target->activeRunConfiguration()); { const Utils::GuardLocker locker(m_ignoreChanges); @@ -285,14 +272,14 @@ void RunSettingsWidget::currentRunConfigurationChanged(int index) RunConfiguration *selectedRunConfiguration = nullptr; if (index >= 0) selectedRunConfiguration = qobject_cast<RunConfiguration *> - (m_target->runConfigurationModel()->projectConfigurationAt(index)); + (m_target->activeBuildConfiguration()->runConfigurationModel()->projectConfigurationAt(index)); if (selectedRunConfiguration == m_runConfiguration) return; { const Utils::GuardLocker locker(m_ignoreChanges); - m_target->setActiveRunConfiguration(selectedRunConfiguration); + m_target->activeBuildConfiguration()->setActiveRunConfiguration(selectedRunConfiguration); } // Update the run configuration configuration widget @@ -402,6 +389,20 @@ void RunSettingsWidget::initForActiveBuildConfig() m_removeDeployToolButton->setEnabled( m_target->activeBuildConfiguration()->deployConfigurations().count() > 1); updateDeployConfiguration(m_target->activeDeployConfiguration()); + + disconnect(m_runConfigurationCombo, &QComboBox::currentIndexChanged, + this, &RunSettingsWidget::currentRunConfigurationChanged); + RunConfiguration *rc = m_target->activeRunConfiguration(); + ProjectConfigurationModel *model = m_target->activeBuildConfiguration()->runConfigurationModel(); + m_runConfigurationCombo->setModel(model); + m_runConfigurationCombo->setCurrentIndex(model->indexFor(rc)); + connect(m_runConfigurationCombo, &QComboBox::currentIndexChanged, + this, &RunSettingsWidget::currentRunConfigurationChanged); + updateRemoveToolButtons(); + m_renameRunButton->setEnabled(rc); + m_cloneRunButton->setEnabled(rc); + + setConfigurationWidget(rc); } void RunSettingsWidget::updateRemoveToolButtons() @@ -409,7 +410,7 @@ void RunSettingsWidget::updateRemoveToolButtons() const BuildConfiguration * const bc = m_target->activeBuildConfiguration(); QTC_ASSERT(bc, return); m_removeDeployToolButton->setEnabled(bc->deployConfigurations().count() > 1); - const bool hasRunConfigs = !m_target->runConfigurations().isEmpty(); + const bool hasRunConfigs = !bc->runConfigurations().isEmpty(); m_removeRunToolButton->setEnabled(hasRunConfigs); m_removeAllRunConfigsButton->setEnabled(hasRunConfigs); } @@ -492,7 +493,8 @@ QString RunSettingsWidget::uniqueRCName(const QString &name) QString result = name.trimmed(); if (!result.isEmpty()) { QStringList rcNames; - const QList<RunConfiguration *> configurations = m_target->runConfigurations(); + const QList<RunConfiguration *> configurations + = m_target->activeBuildConfiguration()->runConfigurations(); for (RunConfiguration *rc : configurations) { if (rc == m_target->activeRunConfiguration()) continue; diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp index 601ea5a1eee..769c2000f15 100644 --- a/src/plugins/projectexplorer/target.cpp +++ b/src/plugins/projectexplorer/target.cpp @@ -18,9 +18,7 @@ #include "project.h" #include "projectconfigurationmodel.h" #include "projectexplorer.h" -#include "projectexplorerconstants.h" #include "projectexplorericons.h" -#include "projectexplorersettings.h" #include "projectexplorertr.h" #include "projectmanager.h" #include "runconfiguration.h" @@ -43,9 +41,6 @@ const char ACTIVE_BC_KEY[] = "ProjectExplorer.Target.ActiveBuildConfiguration"; const char BC_KEY_PREFIX[] = "ProjectExplorer.Target.BuildConfiguration."; const char BC_COUNT_KEY[] = "ProjectExplorer.Target.BuildConfigurationCount"; -const char ACTIVE_RC_KEY[] = "ProjectExplorer.Target.ActiveRunConfiguration"; -const char RC_KEY_PREFIX[] = "ProjectExplorer.Target.RunConfiguration."; -const char RC_COUNT_KEY[] = "ProjectExplorer.Target.RunConfigurationCount"; const char PLUGIN_SETTINGS_KEY[] = "ProjectExplorer.Target.PluginSettings"; const char HAS_PER_BC_DCS[] = "HasPerBcDcs"; @@ -68,23 +63,19 @@ class TargetPrivate public: TargetPrivate(Target *t, Kit *k) : m_kit(k), - m_buildConfigurationModel(t), - m_runConfigurationModel(t) + m_buildConfigurationModel(t) { } QIcon m_overlayIcon; QList<BuildConfiguration *> m_buildConfigurations; QPointer<BuildConfiguration> m_activeBuildConfiguration; - QList<RunConfiguration *> m_runConfigurations; - RunConfiguration* m_activeRunConfiguration = nullptr; Store m_pluginSettings; Kit *const m_kit; MacroExpander m_macroExpander; ProjectConfigurationModel m_buildConfigurationModel; - ProjectConfigurationModel m_runConfigurationModel; bool m_shuttingDown = false; }; @@ -134,7 +125,6 @@ Target::Target(Project *project, Kit *k, _constructor_tag) : Target::~Target() { qDeleteAll(d->m_buildConfigurations); - qDeleteAll(d->m_runConfigurations); } void Target::handleKitUpdates(Kit *k) @@ -182,20 +172,6 @@ BuildSystem *Target::buildSystem() const return d->m_activeBuildConfiguration->buildSystem(); } -DeploymentData Target::deploymentData() const -{ - const DeployConfiguration * const dc = activeDeployConfiguration(); - if (dc && dc->usesCustomDeploymentData()) - return dc->customDeploymentData(); - return buildSystemDeploymentData(); -} - -DeploymentData Target::buildSystemDeploymentData() const -{ - QTC_ASSERT(buildSystem(), return {}); - return buildSystem()->deploymentData(); -} - BuildTargetInfo Target::buildTarget(const QString &buildKey) const { QTC_ASSERT(buildSystem(), return {}); @@ -204,11 +180,8 @@ BuildTargetInfo Target::buildTarget(const QString &buildKey) const QString Target::activeBuildKey() const { - // Should not happen. If it does, return a buildKey that wont be found in - // the project tree, so that the project()->findNodeForBuildKey(buildKey) - // returns null. - QTC_ASSERT(d->m_activeRunConfiguration, return QString(QChar(0))); - return d->m_activeRunConfiguration->buildKey(); + QTC_ASSERT(activeBuildConfiguration(), return {}); + return activeBuildConfiguration()->activeBuildKey(); } void Target::setActiveBuildConfiguration(BuildConfiguration *bc, SetActive cascade) @@ -359,6 +332,12 @@ DeployConfiguration *Target::activeDeployConfiguration() const return activeBuildConfiguration()->activeDeployConfiguration(); } +RunConfiguration *Target::activeRunConfiguration() const +{ + QTC_ASSERT(activeBuildConfiguration(), return nullptr); + return activeBuildConfiguration()->activeRunConfiguration(); +} + void Target::setActiveBuildConfiguration(BuildConfiguration *bc) { if ((!bc && d->m_buildConfigurations.isEmpty()) || @@ -370,90 +349,6 @@ void Target::setActiveBuildConfiguration(BuildConfiguration *bc) } } -const QList<RunConfiguration *> Target::runConfigurations() const -{ - return d->m_runConfigurations; -} - -void Target::addRunConfiguration(RunConfiguration *rc) -{ - QTC_ASSERT(rc && !d->m_runConfigurations.contains(rc), return); - Q_ASSERT(rc->target() == this); - - // Check that we don't have a configuration with the same displayName - QString configurationDisplayName = rc->displayName(); - if (!configurationDisplayName.isEmpty()) { - QStringList displayNames = Utils::transform(d->m_runConfigurations, - &RunConfiguration::displayName); - configurationDisplayName = Utils::makeUniquelyNumbered(configurationDisplayName, - displayNames); - rc->setDisplayName(configurationDisplayName); - } - - d->m_runConfigurations.push_back(rc); - - ProjectExplorerPlugin::targetSelector()->addedRunConfiguration(rc); - d->m_runConfigurationModel.addProjectConfiguration(rc); - emit addedRunConfiguration(rc); - - if (!activeRunConfiguration()) - setActiveRunConfiguration(rc); -} - -void Target::removeRunConfiguration(RunConfiguration *rc) -{ - QTC_ASSERT(rc && d->m_runConfigurations.contains(rc), return); - - d->m_runConfigurations.removeOne(rc); - - if (activeRunConfiguration() == rc) { - if (d->m_runConfigurations.isEmpty()) - setActiveRunConfiguration(nullptr); - else - setActiveRunConfiguration(d->m_runConfigurations.at(0)); - } - - emit removedRunConfiguration(rc); - ProjectExplorerPlugin::targetSelector()->removedRunConfiguration(rc); - d->m_runConfigurationModel.removeProjectConfiguration(rc); - - delete rc; -} - -void Target::removeAllRunConfigurations() -{ - QList<RunConfiguration *> runConfigs = d->m_runConfigurations; - d->m_runConfigurations.clear(); - setActiveRunConfiguration(nullptr); - while (!runConfigs.isEmpty()) { - RunConfiguration * const rc = runConfigs.takeFirst(); - emit removedRunConfiguration(rc); - ProjectExplorerPlugin::targetSelector()->removedRunConfiguration(rc); - d->m_runConfigurationModel.removeProjectConfiguration(rc); - delete rc; - } -} - -RunConfiguration *Target::activeRunConfiguration() const -{ - return d->m_activeRunConfiguration; -} - -void Target::setActiveRunConfiguration(RunConfiguration *rc) -{ - if (isShuttingDown()) - return; - - if ((!rc && d->m_runConfigurations.isEmpty()) || - (rc && d->m_runConfigurations.contains(rc) && - rc != d->m_activeRunConfiguration)) { - d->m_activeRunConfiguration = rc; - emit activeRunConfigurationChanged(d->m_activeRunConfiguration); - ProjectExplorerPlugin::updateActions(); - } - updateDeviceState(); -} - QIcon Target::icon() const { return d->m_kit->icon(); @@ -504,20 +399,11 @@ Store Target::toMap() const } // Forward compatibility for Qt Creator < 17: Store the active build configuration's - // deploy configurations as the target-global ones. A special tag signifies that + // deploy and run configurations as the target-global ones. A special tag signifies that // we should not read these ourselves. d->m_activeBuildConfiguration->storeConfigurationsToMap(map); map.insert(HAS_PER_BC_DCS, true); - const QList<RunConfiguration *> rcs = runConfigurations(); - map.insert(ACTIVE_RC_KEY, rcs.indexOf(d->m_activeRunConfiguration)); - map.insert(RC_COUNT_KEY, rcs.size()); - for (int i = 0; i < rcs.size(); ++i) { - Store data; - rcs.at(i)->toMap(data); - map.insert(numberedKey(RC_KEY_PREFIX, i), variantFromStore(data)); - } - if (!d->m_pluginSettings.isEmpty()) map.insert(PLUGIN_SETTINGS_KEY, variantFromStore(d->m_pluginSettings)); @@ -545,135 +431,8 @@ void Target::updateDefaultDeployConfigurations() void Target::updateDefaultRunConfigurations() { - // Manual and Auto - const QList<RunConfigurationCreationInfo> creators - = RunConfigurationFactory::creatorsForTarget(this); - - if (creators.isEmpty()) { - qWarning("No run configuration factory found for target id '%s'.", qPrintable(id().toString())); - return; - } - - QList<RunConfiguration *> existingConfigured; // Existing configured RCs - QList<RunConfiguration *> existingUnconfigured; // Existing unconfigured RCs - QList<RunConfiguration *> newConfigured; // NEW configured Rcs - QList<RunConfiguration *> newUnconfigured; // NEW unconfigured RCs - - // sort existing RCs into configured/unconfigured. - std::tie(existingConfigured, existingUnconfigured) - = Utils::partition(runConfigurations(), - [](const RunConfiguration *rc) { return rc->isConfigured(); }); - int configuredCount = existingConfigured.count(); - - // Put outdated RCs into toRemove, do not bother with factories - // that produce already existing RCs - QList<RunConfiguration *> toRemove; - QList<RunConfigurationCreationInfo> existing; - for (RunConfiguration *rc : std::as_const(existingConfigured)) { - bool present = false; - for (const RunConfigurationCreationInfo &item : creators) { - QString buildKey = rc->buildKey(); - if (item.factory->runConfigurationId() == rc->id() && item.buildKey == buildKey) { - existing.append(item); - present = true; - } - } - if (!present && - projectExplorerSettings().automaticallyCreateRunConfigurations && - !rc->isCustomized()) { - toRemove.append(rc); - } - } - configuredCount -= toRemove.count(); - - bool removeExistingUnconfigured = false; - if (projectExplorerSettings().automaticallyCreateRunConfigurations) { - // Create new "automatic" RCs and put them into newConfigured/newUnconfigured - for (const RunConfigurationCreationInfo &item : creators) { - if (item.creationMode == RunConfigurationCreationInfo::ManualCreationOnly) - continue; - bool exists = false; - for (const RunConfigurationCreationInfo &ex : existing) { - if (ex.factory == item.factory && ex.buildKey == item.buildKey) - exists = true; - } - if (exists) - continue; - - RunConfiguration *rc = item.create(this); - if (!rc) - continue; - QTC_CHECK(rc->id() == item.factory->runConfigurationId()); - if (!rc->isConfigured()) - newUnconfigured << rc; - else - newConfigured << rc; - } - configuredCount += newConfigured.count(); - - // Decide what to do with the different categories: - if (configuredCount > 0) { - // new non-Custom Executable RCs were added - removeExistingUnconfigured = true; - qDeleteAll(newUnconfigured); - newUnconfigured.clear(); - } else { - // no new RCs, use old or new CERCs? - if (!existingUnconfigured.isEmpty()) { - qDeleteAll(newUnconfigured); - newUnconfigured.clear(); - } - } - } - - // Do actual changes: - for (RunConfiguration *rc : std::as_const(newConfigured)) - addRunConfiguration(rc); - for (RunConfiguration *rc : std::as_const(newUnconfigured)) - addRunConfiguration(rc); - - // Generate complete list of RCs to remove later: - QList<RunConfiguration *> removalList; - for (RunConfiguration *rc : std::as_const(toRemove)) { - removalList << rc; - existingConfigured.removeOne(rc); // make sure to also remove them from existingConfigured! - } - - if (removeExistingUnconfigured) { - removalList.append(existingUnconfigured); - existingUnconfigured.clear(); - } - - // Make sure a configured RC will be active after we delete the RCs: - RunConfiguration *active = activeRunConfiguration(); - if (active && (removalList.contains(active) || !active->isEnabled(Constants::NORMAL_RUN_MODE))) { - RunConfiguration *newConfiguredDefault = newConfigured.isEmpty() ? nullptr : newConfigured.at(0); - - RunConfiguration *rc = Utils::findOrDefault(existingConfigured, [](RunConfiguration *rc) { - return rc->isEnabled(Constants::NORMAL_RUN_MODE); - }); - if (!rc) { - rc = Utils::findOr(newConfigured, newConfiguredDefault, - Utils::equal(&RunConfiguration::displayName, project()->displayName())); - } - if (!rc) - rc = newUnconfigured.isEmpty() ? nullptr : newUnconfigured.at(0); - if (!rc) { - // No RCs will be deleted, so use the one that will emit the minimum number of signals. - // One signal will be emitted from the next setActiveRunConfiguration, another one - // when the RC gets removed (and the activeRunConfiguration turns into a nullptr). - rc = removalList.isEmpty() ? nullptr : removalList.last(); - } - - if (rc) - setActiveRunConfiguration(rc); - } - - // Remove the RCs that are no longer needed: - for (RunConfiguration *rc : std::as_const(removalList)) - removeRunConfiguration(rc); - - emit runConfigurationsUpdated(); + for (BuildConfiguration * const bc : std::as_const(d->m_buildConfigurations)) + bc->updateDefaultRunConfigurations(); } QVariant Target::namedSettings(const Key &name) const @@ -707,9 +466,9 @@ ProjectConfigurationModel *Target::buildConfigurationModel() const return &d->m_buildConfigurationModel; } -ProjectConfigurationModel *Target::runConfigurationModel() const +DeploymentData Target::deploymentData() const { - return &d->m_runConfigurationModel; + return buildSystem()->deploymentData(); } void Target::updateDeviceState() @@ -784,7 +543,7 @@ bool Target::addConfigurationsFromMap(const Utils::Store &map, bool setActiveCon } QTC_CHECK(bc->id() == ProjectExplorer::idFromMap(valueMap)); - // Pre-17 backward compatibility: Give each build config the formerly target-global deploy + // Pre-17 backward compatibility: Give each build config the formerly target-global // configurations. if (!hasDeployConfigsPerBuildConfig) { if (!bc->addConfigurationsFromMap(map, true)) @@ -795,31 +554,6 @@ bool Target::addConfigurationsFromMap(const Utils::Store &map, bool setActiveCon if (i == activeConfiguration) setActiveBuildConfiguration(bc); } - - int rcCount = map.value(RC_COUNT_KEY, 0).toInt(&ok); - if (!ok || rcCount < 0) - rcCount = 0; - activeConfiguration = map.value(ACTIVE_RC_KEY, 0).toInt(&ok); - if (!ok || 0 > activeConfiguration || rcCount < activeConfiguration) - activeConfiguration = 0; - if (!setActiveConfigurations) - activeConfiguration = -1; - - for (int i = 0; i < rcCount; ++i) { - const Key key = numberedKey(RC_KEY_PREFIX, i); - if (!map.contains(key)) - return false; - - // Ignore missing RCs: We will just populate them using the default ones. - Store valueMap = storeFromVariant(map.value(key)); - RunConfiguration *rc = RunConfigurationFactory::restore(this, valueMap); - if (!rc) - continue; - addRunConfiguration(rc); - if (i == activeConfiguration) - setActiveRunConfiguration(rc); - } - return true; } diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h index 3d66370da1b..e269de629b6 100644 --- a/src/plugins/projectexplorer/target.h +++ b/src/plugins/projectexplorer/target.h @@ -65,15 +65,7 @@ public: const QList<BuildConfiguration *> buildConfigurations() const; BuildConfiguration *activeBuildConfiguration() const; DeployConfiguration *activeDeployConfiguration() const; - - // Running - const QList<RunConfiguration *> runConfigurations() const; - void addRunConfiguration(RunConfiguration *rc); - void removeRunConfiguration(RunConfiguration *rc); - void removeAllRunConfigurations(); - RunConfiguration *activeRunConfiguration() const; - void setActiveRunConfiguration(RunConfiguration *rc); QIcon icon() const; QIcon overlayIcon() const; @@ -94,10 +86,8 @@ public: Utils::MacroExpander *macroExpander() const; ProjectConfigurationModel *buildConfigurationModel() const; - ProjectConfigurationModel *runConfigurationModel() const; DeploymentData deploymentData() const; - DeploymentData buildSystemDeploymentData() const; BuildTargetInfo buildTarget(const QString &buildKey) const; QString activeBuildKey() const; // Build key of active run configuaration @@ -115,12 +105,12 @@ signals: void kitChanged(); + // FIXME: Check all uses of all the following signals, plus the associated getters. + // Likely most of them should refer to the BC counterpart instead (which might not currently exist). void parsingStarted(); void parsingFinished(bool); void buildSystemUpdated(ProjectExplorer::BuildSystem *bs); - // TODO clean up signal names - // might be better to also have aboutToRemove signals void removedRunConfiguration(ProjectExplorer::RunConfiguration *rc); void addedRunConfiguration(ProjectExplorer::RunConfiguration *rc); void activeRunConfigurationChanged(ProjectExplorer::RunConfiguration *rc); diff --git a/src/plugins/projectexplorer/workspaceproject.cpp b/src/plugins/projectexplorer/workspaceproject.cpp index 39215592a77..b961985defb 100644 --- a/src/plugins/projectexplorer/workspaceproject.cpp +++ b/src/plugins/projectexplorer/workspaceproject.cpp @@ -355,8 +355,8 @@ bool WorkspaceBuildSystem::isFiltered(const FilePath &path, QList<IVersionContro class WorkspaceRunConfiguration : public RunConfiguration { public: - WorkspaceRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + WorkspaceRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { hint.setText(Tr::tr("Clone the configuration to change it. Or, make the changes in " "the .qtcreator/project.json file.")); @@ -398,14 +398,13 @@ public: auto enabledUpdater = [this] { setEnabled(enabled.value()); }; connect(&enabled, &BaseAspect::changed, this, enabledUpdater); connect(this, &AspectContainer::fromMapFinished, this, enabledUpdater); - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); enabledUpdater(); enabled.setSettingsKey("Workspace.RunConfiguration.Enabled"); } - RunConfiguration *clone(Target *parent) override + RunConfiguration *clone(BuildConfiguration *bc) override { - RunConfiguration *result = RunConfiguration::clone(parent); + RunConfiguration *result = RunConfiguration::clone(bc); dynamic_cast<WorkspaceRunConfiguration *>(result)->enabled.setValue(true); return result; } diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp index 8120f1fab07..f1b035c4800 100644 --- a/src/plugins/python/pythonrunconfiguration.cpp +++ b/src/plugins/python/pythonrunconfiguration.cpp @@ -104,8 +104,8 @@ private: class PythonRunConfiguration : public RunConfiguration { public: - PythonRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + PythonRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { buffered.setSettingsKey("PythonEditor.RunConfiguation.Buffered"); buffered.setLabelText(Tr::tr("Buffered output")); @@ -117,7 +117,7 @@ public: mainScript.setLabelText(Tr::tr("Script:")); mainScript.setReadOnly(true); - environment.setSupportForBuildEnvironment(target); + environment.setSupportForBuildEnvironment(bc); x11Forwarding.setVisible(HostOsInfo::isAnyUnixHost()); @@ -145,8 +145,6 @@ public: mainScript.setValue(bti.targetFilePath); workingDir.setDefaultWorkingDirectory(bti.targetFilePath.parentDir()); }); - - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); } FilePathAspect interpreter{this}; diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 781c65383da..98a3d425d5f 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -537,7 +537,7 @@ FilePath QbsBuildSystem::groupFilePath(const QJsonObject &group) const FilePath QbsBuildSystem::installRoot() { - const auto dc = target()->activeDeployConfiguration(); + const auto dc = buildConfiguration()->activeDeployConfiguration(); if (dc) { const QList<BuildStep *> steps = dc->stepList()->steps(); for (const BuildStep * const step : steps) { diff --git a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp index 242715d7c38..00cc4990d30 100644 --- a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp +++ b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp @@ -5,6 +5,7 @@ #include "qmlpreviewconnectionmanager.h" +#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/projectexplorer.h> #include <projectexplorer/qmldebugcommandlinearguments.h> #include <projectexplorer/target.h> @@ -107,7 +108,7 @@ void QmlPreviewRunner::start() { if (m_translationUpdater) m_translationUpdater->start(); - m_connectionManager.setTarget(runControl()->target()); + m_connectionManager.setTarget(runControl()->buildConfiguration()->target()); m_connectionManager.connectToServer(runControl()->qmlChannel()); reportStarted(); } @@ -168,7 +169,7 @@ LocalQmlPreviewSupportFactory::LocalQmlPreviewSupportFactory() if (const auto aspect = runControl->aspectData<QmlProjectManager::QmlMainFileAspect>()) { const auto qmlBuildSystem = qobject_cast<QmlProjectManager::QmlBuildSystem *>( - runControl->target()->buildSystem()); + runControl->buildConfiguration()->buildSystem()); QTC_ASSERT(qmlBuildSystem, return); const FilePath mainScript = aspect->mainScript; diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index cc456bc448f..2e644f5883a 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -33,6 +33,7 @@ #include <debugger/debuggericons.h> #include <debugger/debuggermainwindow.h> +#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/devicesupport/devicekitaspects.h> #include <projectexplorer/devicesupport/idevice.h> #include <projectexplorer/environmentaspect.h> @@ -365,7 +366,7 @@ void QmlProfilerTool::finalizeRunControl(RunControl *runControl) updateRunActions(); - d->m_profilerModelManager->populateFileFinder(runControl->target()); + d->m_profilerModelManager->populateFileFinder(runControl->buildConfiguration()->target()); d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning); } diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp index deef7d1b46f..1f616caf5cd 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp @@ -8,10 +8,7 @@ #include "qmlprojectmanagertr.h" #include "qmlprojectrunconfiguration.h" -#include <coreplugin/editormanager/editormanager.h> -#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/icore.h> -#include <coreplugin/idocument.h> #include <projectexplorer/buildsystem.h> #include <projectexplorer/deployconfiguration.h> @@ -30,18 +27,14 @@ #include <qmldesignerbase/utils/qmlpuppetpaths.h> #include <qtsupport/qtkitaspect.h> -#include <qtsupport/qtsupportconstants.h> #include <utils/algorithm.h> #include <utils/aspects.h> #include <utils/environment.h> -#include <utils/fileutils.h> #include <utils/qtcprocess.h> #include <utils/processinterface.h> #include <utils/winutils.h> -#include <qmljstools/qmljstoolsconstants.h> - using namespace Core; using namespace ProjectExplorer; using namespace QtSupport; @@ -54,7 +47,7 @@ namespace QmlProjectManager::Internal { class QmlProjectRunConfiguration final : public RunConfiguration { public: - QmlProjectRunConfiguration(Target *target, Id id); + QmlProjectRunConfiguration(BuildConfiguration *bc, Id id); private: QString disabledReason(Utils::Id runMode) const final; @@ -75,8 +68,8 @@ private: mutable bool usePuppetAsQmlRuntime = false; }; -QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) +QmlProjectRunConfiguration::QmlProjectRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { qmlViewer.setSettingsKey(Constants::QML_VIEWER_KEY); qmlViewer.setLabelText(Tr::tr("Override device QML viewer:")); @@ -85,7 +78,7 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id) arguments.setSettingsKey(Constants::QML_VIEWER_ARGUMENTS_KEY); - setCommandLineGetter([this, target] { + setCommandLineGetter([this] { const FilePath qmlRuntime = qmlRuntimeFilePath(); CommandLine cmd(qmlRuntime); if (usePuppetAsQmlRuntime) @@ -95,7 +88,7 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id) cmd.addArgs(arguments(), CommandLine::Raw); // arguments from .qmlproject file - const QmlBuildSystem *bs = qobject_cast<QmlBuildSystem *>(target->buildSystem()); + const QmlBuildSystem *bs = qobject_cast<QmlBuildSystem *>(buildSystem()); for (const QString &importPath : bs->targetImportPaths()) { cmd.addArg("-I"); cmd.addArg(importPath); @@ -124,7 +117,7 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id) return cmd; }); - qmlMainFile.setTarget(target); + qmlMainFile.setTarget(target()); connect(&qmlMainFile, &BaseAspect::changed, this, &RunConfiguration::update); if (Core::ICore::isQtDesignStudio()) @@ -132,18 +125,15 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id) else qtversion.setVisible(false); - connect(target, &Target::kitChanged, this, &RunConfiguration::update); - - multiLanguage.setTarget(target); - auto buildSystem = qobject_cast<const QmlBuildSystem *>(activeBuildSystem()); - if (buildSystem) - multiLanguage.setValue(buildSystem->multilanguageSupport()); + multiLanguage.setTarget(target()); + if (auto bs = qobject_cast<const QmlBuildSystem *>(buildSystem())) + multiLanguage.setValue(bs->multilanguageSupport()); connect(&multiLanguage, &BaseAspect::changed, &environment, &EnvironmentAspect::environmentChanged); auto envModifier = [this](Environment env) { - if (auto bs = qobject_cast<const QmlBuildSystem *>(activeBuildSystem())) + if (auto bs = qobject_cast<const QmlBuildSystem *>(buildSystem())) env.modify(bs->environment()); if (multiLanguage() && !multiLanguage.databaseFilePath().isEmpty()) { @@ -169,7 +159,7 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id) }); setRunnableModifier([this](ProcessRunData &r) { - const QmlBuildSystem *bs = static_cast<QmlBuildSystem *>(activeBuildSystem()); + const QmlBuildSystem *bs = static_cast<QmlBuildSystem *>(buildSystem()); r.workingDirectory = bs->targetDirectory(); }); @@ -304,7 +294,7 @@ bool QmlProjectRunConfiguration::isEnabled(Id) const { return const_cast<QmlProjectRunConfiguration *>(this)->qmlMainFile.isQmlFilePresent() && !qmlRuntimeFilePath().isEmpty() - && activeBuildSystem()->hasParsingData(); + && buildSystem()->hasParsingData(); } FilePath QmlProjectRunConfiguration::mainScript() const diff --git a/src/plugins/qnx/qnxrunconfiguration.cpp b/src/plugins/qnx/qnxrunconfiguration.cpp index 7c866c830a0..8c8a9e7931f 100644 --- a/src/plugins/qnx/qnxrunconfiguration.cpp +++ b/src/plugins/qnx/qnxrunconfiguration.cpp @@ -15,8 +15,6 @@ #include <remotelinux/remotelinuxenvironmentaspect.h> -#include <qtsupport/qtoutputformatter.h> - #include <utils/processinterface.h> using namespace ProjectExplorer; @@ -28,10 +26,10 @@ namespace Qnx::Internal { class QnxRunConfiguration final : public RunConfiguration { public: - QnxRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + QnxRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); executable.setLabelText(Tr::tr("Executable on device:")); executable.setPlaceHolderText(Tr::tr("Remote path not set")); executable.makeOverridable("RemoteLinux.RunConfig.AlternateRemoteExecutable", @@ -40,7 +38,7 @@ public: symbolFile.setLabelText(Tr::tr("Executable on host:")); - environment.setDeviceSelector(target, EnvironmentAspect::RunDevice); + environment.setDeviceSelector(target(), EnvironmentAspect::RunDevice); workingDir.setEnvironment(&environment); @@ -48,10 +46,10 @@ public: qtLibraries.setLabelText(Tr::tr("Path to Qt libraries on device")); qtLibraries.setDisplayStyle(StringAspect::LineEditDisplay); - setUpdater([this, target] { + setUpdater([this] { const BuildTargetInfo bti = buildTargetInfo(); const FilePath localExecutable = bti.targetFilePath; - const DeployableFile depFile = target->deploymentData() + const DeployableFile depFile = buildSystem()->deploymentData() .deployableForLocalFile(localExecutable); executable.setExecutable(FilePath::fromString(depFile.remoteFilePath())); symbolFile.setValue(localExecutable); @@ -67,8 +65,6 @@ public: r.environment.set("QT_QPA_FONTDIR", libPath + "/lib/fonts"); } }); - - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); } ExecutableAspect executable{this}; diff --git a/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.cpp b/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.cpp index f754becace7..f1f6ebabf81 100644 --- a/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.cpp +++ b/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.cpp @@ -12,6 +12,7 @@ #include "appmanagerutilities.h" #include <projectexplorer/devicesupport/devicekitaspects.h> +#include <projectexplorer/buildsystem.h> #include <projectexplorer/environmentaspect.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> @@ -30,14 +31,13 @@ namespace AppManager::Internal { class AppManagerRunConfiguration : public RunConfiguration { public: - AppManagerRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + AppManagerRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { setDefaultDisplayName(Tr::tr("Run an Application Manager Package")); - setUpdater([this, target] { - QList<TargetInformation> tis - = TargetInformation::readFromProject(target->activeBuildConfiguration(), buildKey()); + setUpdater([this, bc] { + QList<TargetInformation> tis = TargetInformation::readFromProject(bc, buildKey()); if (tis.isEmpty()) return; const TargetInformation targetInformation = tis.at(0); @@ -49,10 +49,7 @@ public: appId.setReadOnly(true); }); - connect(target, &Target::parsingFinished, this, &RunConfiguration::update); - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); - connect(target, &Target::deploymentDataChanged, this, &RunConfiguration::update); - connect(target, &Target::kitChanged, this, &RunConfiguration::update); + connect(buildSystem(), &BuildSystem::parsingFinished, this, &RunConfiguration::update); } AppManagerControllerAspect controller{this}; @@ -65,8 +62,8 @@ public: class AppManagerRunAndDebugConfiguration final : public AppManagerRunConfiguration { public: - AppManagerRunAndDebugConfiguration(Target *target, Id id) - : AppManagerRunConfiguration(target, id) + AppManagerRunAndDebugConfiguration(BuildConfiguration *bc, Id id) + : AppManagerRunConfiguration(bc, id) { setDefaultDisplayName(Tr::tr("Run and Debug an Application Manager Package")); environment.addPreferredBaseEnvironment(Tr::tr("Clean Environment"), {}); diff --git a/src/plugins/qtapplicationmanager/appmanagerruncontrol.cpp b/src/plugins/qtapplicationmanager/appmanagerruncontrol.cpp index 312bb6d0e94..5333477d3d5 100644 --- a/src/plugins/qtapplicationmanager/appmanagerruncontrol.cpp +++ b/src/plugins/qtapplicationmanager/appmanagerruncontrol.cpp @@ -173,9 +173,9 @@ public: debuggee->addStopDependency(debugger); QObject::connect(debuggee, &RunWorker::started, debugger, [debugger, runControl] { - Target *target = runControl->target(); + BuildConfiguration *bc = runControl->buildConfiguration(); - const Internal::TargetInformation targetInformation(target->activeBuildConfiguration()); + const Internal::TargetInformation targetInformation(bc); if (!targetInformation.isValid()) { debugger->reportFailure(Tr::tr("Cannot debug: Invalid target information.")); return; @@ -188,7 +188,7 @@ public: runControl->kit(), RunDeviceKitAspect::device(runControl->kit())); } else if (targetInformation.manifest.isNativeRuntime()) { - symbolFile = Utils::findOrDefault(target->buildSystem()->applicationTargets(), + symbolFile = Utils::findOrDefault(bc->buildSystem()->applicationTargets(), [&](const BuildTargetInfo &ti) { return ti.buildKey == targetInformation.manifest.code || ti.projectFilePath.toUrlishString() == targetInformation.manifest.code; diff --git a/src/plugins/qtapplicationmanager/appmanagertargetinformation.cpp b/src/plugins/qtapplicationmanager/appmanagertargetinformation.cpp index 603d8a0c149..6dc36e1240f 100644 --- a/src/plugins/qtapplicationmanager/appmanagertargetinformation.cpp +++ b/src/plugins/qtapplicationmanager/appmanagertargetinformation.cpp @@ -108,7 +108,7 @@ TargetInformation::TargetInformation(const BuildConfiguration *bc) if (!project) return; - const RunConfiguration *rc = bc->target()->activeRunConfiguration(); + const RunConfiguration *rc = bc->activeRunConfiguration(); if (!rc) return; if (rc->id() != Constants::RUNCONFIGURATION_ID && diff --git a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp index 5200e59b330..72ea04cbd0b 100644 --- a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp @@ -20,7 +20,7 @@ namespace RemoteLinux::Internal { class RemoteLinuxCustomRunConfiguration : public RunConfiguration { public: - RemoteLinuxCustomRunConfiguration(Target *target, Id id); + RemoteLinuxCustomRunConfiguration(BuildConfiguration *bc, Id id); QString runConfigDefaultDisplayName(); @@ -36,12 +36,12 @@ private: X11ForwardingAspect x11Forwarding{this}; }; -RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) +RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - environment.setDeviceSelector(target, EnvironmentAspect::RunDevice); + environment.setDeviceSelector(target(), EnvironmentAspect::RunDevice); - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); executable.setSettingsKey("RemoteLinux.CustomRunConfig.RemoteExecutable"); executable.setLabelText(Tr::tr("Remote executable:")); executable.setReadOnly(false); diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp index ade0de10c2d..e3446ba5b4e 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp @@ -26,7 +26,7 @@ namespace RemoteLinux::Internal { class RemoteLinuxRunConfiguration final : public RunConfiguration { public: - RemoteLinuxRunConfiguration(Target *target, Id id); + RemoteLinuxRunConfiguration(BuildConfiguration *bc, Id id); RemoteLinuxEnvironmentAspect environment{this}; ExecutableAspect executable{this}; @@ -38,12 +38,12 @@ public: UseLibraryPathsAspect useLibraryPath{this}; }; -RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) +RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - environment.setDeviceSelector(target, EnvironmentAspect::RunDevice); + environment.setDeviceSelector(target(), EnvironmentAspect::RunDevice); - executable.setDeviceSelector(target, ExecutableAspect::RunDevice); + executable.setDeviceSelector(target(), ExecutableAspect::RunDevice); executable.setLabelText(Tr::tr("Executable on device:")); executable.setPlaceHolderText(Tr::tr("Remote path not set")); executable.makeOverridable("RemoteLinux.RunConfig.AlternateRemoteExecutable", @@ -59,14 +59,14 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Id id) connect(&useLibraryPath, &BaseAspect::changed, &environment, &EnvironmentAspect::environmentChanged); - setUpdater([this, target] { + setUpdater([this] { const IDeviceConstPtr buildDevice = BuildDeviceKitAspect::device(kit()); const IDeviceConstPtr runDevice = RunDeviceKitAspect::device(kit()); QTC_ASSERT(buildDevice, return); QTC_ASSERT(runDevice, return); const BuildTargetInfo bti = buildTargetInfo(); const FilePath localExecutable = bti.targetFilePath; - const DeploymentData deploymentData = target->deploymentData(); + const DeploymentData deploymentData = buildSystem()->deploymentData(); const DeployableFile depFile = deploymentData.deployableForLocalFile(localExecutable); executable.setExecutable(runDevice->filePath(depFile.remoteFilePath())); @@ -84,10 +84,6 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Id id) if (bti.runEnvModifier) bti.runEnvModifier(env, useLibraryPath()); }); - - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); - connect(target, &Target::deploymentDataChanged, this, &RunConfiguration::update); - connect(target, &Target::kitChanged, this, &RunConfiguration::update); } // RemoteLinuxRunConfigurationFactory diff --git a/src/plugins/webassembly/webassemblyrunconfiguration.cpp b/src/plugins/webassembly/webassemblyrunconfiguration.cpp index 03da1e0afbc..c35efc3b023 100644 --- a/src/plugins/webassembly/webassemblyrunconfiguration.cpp +++ b/src/plugins/webassembly/webassemblyrunconfiguration.cpp @@ -58,32 +58,29 @@ static FilePath pythonInterpreter(const Environment &env) return {}; } -static CommandLine emrunCommand(const Target *target, +static CommandLine emrunCommand(const BuildConfiguration *bc, const QString &buildKey, const QString &browser, const QString &port) { - if (BuildConfiguration *bc = target->activeBuildConfiguration()) { - const Environment env = bc->environment(); - const FilePath emrun = env.searchInPath("emrun"); - const FilePath emrunPy = emrun.absolutePath().pathAppended(emrun.baseName() + ".py"); - const FilePath targetPath = bc->buildSystem()->buildTarget(buildKey).targetFilePath; - const FilePath html = targetPath.absolutePath() / (targetPath.baseName() + ".html"); - - QStringList args(emrunPy.path()); - if (!browser.isEmpty()) { - args.append("--browser"); - args.append(browser); - } - args.append("--port"); - args.append(port); - args.append("--no_emrun_detect"); - args.append("--serve_after_close"); - args.append(html.toUrlishString()); - - return CommandLine(pythonInterpreter(env), args); + const Environment env = bc->environment(); + const FilePath emrun = env.searchInPath("emrun"); + const FilePath emrunPy = emrun.absolutePath().pathAppended(emrun.baseName() + ".py"); + const FilePath targetPath = bc->buildSystem()->buildTarget(buildKey).targetFilePath; + const FilePath html = targetPath.absolutePath() / (targetPath.baseName() + ".html"); + + QStringList args(emrunPy.path()); + if (!browser.isEmpty()) { + args.append("--browser"); + args.append(browser); } - return {}; + args.append("--port"); + args.append(port); + args.append("--no_emrun_detect"); + args.append("--serve_after_close"); + args.append(html.toUrlishString()); + + return CommandLine(pythonInterpreter(env), args); } static const char BROWSER_KEY[] = "WASM.WebBrowserSelectionAspect.Browser"; @@ -173,24 +170,23 @@ private: class EmrunRunConfiguration : public RunConfiguration { public: - EmrunRunConfiguration(Target *target, Id id) - : RunConfiguration(target, id) + EmrunRunConfiguration(BuildConfiguration *bc, Id id) + : RunConfiguration(bc, id) { - webBrowser.setTarget(target); + webBrowser.setTarget(target()); effectiveEmrunCall.setLabelText(Tr::tr("Effective emrun call:")); effectiveEmrunCall.setDisplayStyle(StringAspect::TextEditDisplay); effectiveEmrunCall.setReadOnly(true); - setUpdater([this, target] { - effectiveEmrunCall.setValue(emrunCommand(target, + setUpdater([this] { + effectiveEmrunCall.setValue(emrunCommand(buildConfiguration(), buildKey(), webBrowser.currentBrowser(), "<port>").toUserOutput()); }); connect(&webBrowser, &BaseAspect::changed, this, &RunConfiguration::update); - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); } private: @@ -222,7 +218,7 @@ public: worker->setStartModifier([worker, runControl] { const QString browserId = runControl->aspectData<WebBrowserSelectionAspect>()->currentBrowser; - worker->setCommandLine(emrunCommand(runControl->target(), runControl->buildKey(), + worker->setCommandLine(emrunCommand(runControl->buildConfiguration(), runControl->buildKey(), browserId, QString::number(runControl->workerChannel().port()))); worker->setEnvironment(runControl->buildEnvironment()); }); |