From 3916a0637a45c5eabaad573a02d0868ad9fd5093 Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Wed, 20 Dec 2023 10:38:09 +0100 Subject: [PATCH] Appman: Initial CMake integration * Detection of packages created using CMake API * Run target for all detected packages * Special CMake package step for installable packages * Run/Debug of builtin apps * Package/Install/Run/Debug of installable packages * Works locally and with Remote Linux Change-Id: Ic297ba04f20caf0a5383ed016d759e654864a065 Reviewed-by: hjk Reviewed-by: --- .../qtapplicationmanager/CMakeLists.txt | 4 +- .../appmanagercmakepackagestep.cpp | 46 +++++ .../appmanagercmakepackagestep.h | 24 +++ .../appmanagerconstants.h | 4 + .../appmanagercreatepackagestep.cpp | 5 +- .../appmanagerdeployconfigurationfactory.cpp | 12 +- .../appmanagerdeploypackagestep.cpp | 3 + .../appmanagerinstallpackagestep.cpp | 14 +- .../qtapplicationmanager/appmanagerplugin.cpp | 6 +- .../appmanagerremoteinstallpackagestep.cpp | 159 ++++++++++++++++++ .../appmanagerremoteinstallpackagestep.h | 18 ++ .../appmanagerrunconfiguration.cpp | 12 +- .../appmanagerrunconfiguration.h | 2 + .../appmanagerruncontrol.cpp | 8 +- .../appmanagertargetinformation.cpp | 62 +++++++ .../appmanagertargetinformation.h | 3 + 16 files changed, 370 insertions(+), 12 deletions(-) create mode 100644 src/plugins/qtapplicationmanager/appmanagercmakepackagestep.cpp create mode 100644 src/plugins/qtapplicationmanager/appmanagercmakepackagestep.h create mode 100644 src/plugins/qtapplicationmanager/appmanagerremoteinstallpackagestep.cpp create mode 100644 src/plugins/qtapplicationmanager/appmanagerremoteinstallpackagestep.h diff --git a/src/plugins/qtapplicationmanager/CMakeLists.txt b/src/plugins/qtapplicationmanager/CMakeLists.txt index a5feb2f64d7..b5d53e551c0 100644 --- a/src/plugins/qtapplicationmanager/CMakeLists.txt +++ b/src/plugins/qtapplicationmanager/CMakeLists.txt @@ -4,7 +4,7 @@ add_qtc_plugin(QtApplicationManagerIntegration PLUGIN_DEPENDS Core Debugger ProjectExplorer QmakeProjectManager QtSupport RemoteLinux - DEPENDS Qt::Network Qt::Widgets ExtensionSystem Utils + DEPENDS Qt::Network Qt::Widgets ExtensionSystem Utils yaml-cpp SOURCES appmanagerconstants.h appmanagercreatepackagestep.cpp appmanagercreatepackagestep.h @@ -12,7 +12,9 @@ add_qtc_plugin(QtApplicationManagerIntegration appmanagerdeployconfigurationfactory.cpp appmanagerdeployconfigurationfactory.h appmanagerdeploypackagestep.cpp appmanagerdeploypackagestep.h appmanagerinstallpackagestep.cpp appmanagerinstallpackagestep.h + appmanagerremoteinstallpackagestep.cpp appmanagerremoteinstallpackagestep.h appmanagermakeinstallstep.cpp appmanagermakeinstallstep.h + appmanagercmakepackagestep.cpp appmanagercmakepackagestep.h appmanagerplugin.cpp appmanagerplugin.h appmanagerrunconfiguration.cpp appmanagerrunconfiguration.h appmanagerruncontrol.cpp appmanagerruncontrol.h diff --git a/src/plugins/qtapplicationmanager/appmanagercmakepackagestep.cpp b/src/plugins/qtapplicationmanager/appmanagercmakepackagestep.cpp new file mode 100644 index 00000000000..7f01dd33c3a --- /dev/null +++ b/src/plugins/qtapplicationmanager/appmanagercmakepackagestep.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2019 Luxoft Sweden AB +// Copyright (C) 2018 Pelagicore AG +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "appmanagercmakepackagestep.h" + +#include "appmanagerconstants.h" +#include "appmanagertargetinformation.h" + +#include +#include +#include + +#include + +using namespace ProjectExplorer; +using namespace CMakeProjectManager; +using namespace Utils; + +namespace AppManager { +namespace Internal { + +AppManagerCMakePackageStepFactory::AppManagerCMakePackageStepFactory() +{ + cloneStepCreator(CMakeProjectManager::Constants::CMAKE_BUILD_STEP_ID, Constants::CMAKE_PACKAGE_STEP_ID); + setExtraInit([] (BuildStep *step) { + // We update the build targets when the active run configuration changes + const auto updaterSlot = [step] { + const auto targetInformation = TargetInformation(step->target()); + step->setBuildTargets({targetInformation.cmakeBuildTarget}); + step->setEnabled(!targetInformation.isBuiltin); + }; + QObject::connect(step->target(), &Target::activeRunConfigurationChanged, step, updaterSlot); + QObject::connect(step->target(), &Target::activeDeployConfigurationChanged, step, updaterSlot); + QObject::connect(step->target(), &Target::parsingFinished, step, updaterSlot); + QObject::connect(step->target(), &Target::runConfigurationsUpdated, step, updaterSlot); + QObject::connect(step->project(), &Project::displayNameChanged, step, updaterSlot); + }); + + setDisplayName(tr("Create Appman package with CMake")); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); +} + +} // namespace Internal +} // namespace AppManager diff --git a/src/plugins/qtapplicationmanager/appmanagercmakepackagestep.h b/src/plugins/qtapplicationmanager/appmanagercmakepackagestep.h new file mode 100644 index 00000000000..0cb890746a6 --- /dev/null +++ b/src/plugins/qtapplicationmanager/appmanagercmakepackagestep.h @@ -0,0 +1,24 @@ +// Copyright (C) 2019 Luxoft Sweden AB +// Copyright (C) 2018 Pelagicore AG +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#include + +namespace AppManager { +namespace Internal { + +class AppManagerCMakePackageStepFactory final : public ProjectExplorer::BuildStepFactory +{ + Q_DECLARE_TR_FUNCTIONS(Qtc::AppManager) + +public: + AppManagerCMakePackageStepFactory(); +}; + +} // namespace Internal +} // namespace AppManager diff --git a/src/plugins/qtapplicationmanager/appmanagerconstants.h b/src/plugins/qtapplicationmanager/appmanagerconstants.h index 5be069fe1f1..283e8fd55e9 100644 --- a/src/plugins/qtapplicationmanager/appmanagerconstants.h +++ b/src/plugins/qtapplicationmanager/appmanagerconstants.h @@ -16,11 +16,15 @@ const char APPMAN_LAUNCHER_QML[] = "appman-launcher-qml"; const char DEBUG_LAUNCHER_ID[] = "ApplicationManagerPlugin.Debug.Launcher"; const char DEPLOYCONFIGURATION_ID[] = "ApplicationManagerPlugin.Deploy.Configuration"; const char MAKE_INSTALL_STEP_ID[] = "ApplicationManagerPlugin.Deploy.MakeInstallStep"; +const char CMAKE_PACKAGE_STEP_ID[] = "ApplicationManagerPlugin.Deploy.CMakePackageStep"; const char CREATE_PACKAGE_STEP_ID[] = "ApplicationManagerPlugin.Deploy.CreatePackageStep"; const char DEPLOY_PACKAGE_STEP_ID[] = "ApplicationManagerPlugin.Deploy.DeployPackageStep"; const char INSTALL_PACKAGE_STEP_ID[] = "ApplicationManagerPlugin.Deploy.InstallPackageStep"; +const char REMOTE_INSTALL_PACKAGE_STEP_ID[] = "ApplicationManagerPlugin.Deploy.RemoteInstallPackageStep"; const char RUNCONFIGURATION_ID[] = "ApplicationManagerPlugin.Run.Configuration"; +const char EXTRADATA_TARGET_ID[] = "ApplicationManagerPlugin.ExtraData.Target"; + const char APPMAN_PACKAGE_TARGETS[] = "ApplicationmanagerPackageTargets"; const char QMAKE_AM_MANIFEST_VARIABLE[] = "AM_MANIFEST"; diff --git a/src/plugins/qtapplicationmanager/appmanagercreatepackagestep.cpp b/src/plugins/qtapplicationmanager/appmanagercreatepackagestep.cpp index cc7e29d8425..7f369526e30 100644 --- a/src/plugins/qtapplicationmanager/appmanagercreatepackagestep.cpp +++ b/src/plugins/qtapplicationmanager/appmanagercreatepackagestep.cpp @@ -82,11 +82,14 @@ AppManagerCreatePackageStep::AppManagerCreatePackageStep(BuildStepList *bsl, Id sourceDirectory.setPlaceHolderPath(targetInformation.packageSourcesDirectory.absolutePath()); buildDirectory.setPlaceHolderPath(targetInformation.buildDirectory.absolutePath()); packageFileName.setPlaceHolderText(targetInformation.packageFile.fileName()); + + setEnabled(!targetInformation.isBuiltin); }; connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects); connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects); connect(target(), &Target::parsingFinished, this, updateAspects); + connect(target(), &Target::runConfigurationsUpdated, this, updateAspects); connect(project(), &Project::displayNameChanged, this, updateAspects); updateAspects(); } @@ -119,7 +122,7 @@ bool AppManagerCreatePackageStep::init() AppManagerCreatePackageStepFactory::AppManagerCreatePackageStepFactory() { - registerStep(Constants::DEPLOY_PACKAGE_STEP_ID); + registerStep(Constants::CREATE_PACKAGE_STEP_ID); setDisplayName(AppManagerCreatePackageStep::tr("Create Application Manager package")); setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); } diff --git a/src/plugins/qtapplicationmanager/appmanagerdeployconfigurationfactory.cpp b/src/plugins/qtapplicationmanager/appmanagerdeployconfigurationfactory.cpp index 13bcfe7f642..2add481f3e5 100644 --- a/src/plugins/qtapplicationmanager/appmanagerdeployconfigurationfactory.cpp +++ b/src/plugins/qtapplicationmanager/appmanagerdeployconfigurationfactory.cpp @@ -6,6 +6,7 @@ #include "appmanagerdeployconfigurationfactory.h" #include "appmanagerconstants.h" +#include "appmanagertargetinformation.h" #include #include @@ -28,13 +29,16 @@ static bool isNecessaryToDeploy(const Target *target) AppManagerDeployConfigurationFactory::AppManagerDeployConfigurationFactory() { setConfigBaseId(Constants::DEPLOYCONFIGURATION_ID); - setDefaultDisplayName(QCoreApplication::translate("AppManager", "Deploy to AM Device")); + setDefaultDisplayName(QCoreApplication::translate("AppManager", "Deploy Application Manager Package")); addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType); - addInitialStep(Constants::MAKE_INSTALL_STEP_ID); - addInitialStep(Constants::CREATE_PACKAGE_STEP_ID); + + addInitialStep(Constants::CMAKE_PACKAGE_STEP_ID); + addInitialStep(Constants::INSTALL_PACKAGE_STEP_ID, [](Target *target) { + return !isNecessaryToDeploy(target); + }); addInitialStep(Constants::DEPLOY_PACKAGE_STEP_ID, isNecessaryToDeploy); - addInitialStep(Constants::INSTALL_PACKAGE_STEP_ID); + addInitialStep(Constants::REMOTE_INSTALL_PACKAGE_STEP_ID, isNecessaryToDeploy); } } // namespace Internal diff --git a/src/plugins/qtapplicationmanager/appmanagerdeploypackagestep.cpp b/src/plugins/qtapplicationmanager/appmanagerdeploypackagestep.cpp index 1085a7e4d44..76f054c9faa 100644 --- a/src/plugins/qtapplicationmanager/appmanagerdeploypackagestep.cpp +++ b/src/plugins/qtapplicationmanager/appmanagerdeploypackagestep.cpp @@ -54,11 +54,14 @@ public: packageFilePath.setPlaceHolderPath(targetInformation.packageFile.absoluteFilePath()); targetDirectory.setPlaceHolderPath(targetInformation.runDirectory.absolutePath()); + + setEnabled(!targetInformation.isBuiltin); }; connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects); connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects); connect(target(), &Target::parsingFinished, this, updateAspects); + connect(target(), &Target::runConfigurationsUpdated, this, updateAspects); connect(project(), &Project::displayNameChanged, this, updateAspects); updateAspects(); diff --git a/src/plugins/qtapplicationmanager/appmanagerinstallpackagestep.cpp b/src/plugins/qtapplicationmanager/appmanagerinstallpackagestep.cpp index 3ea509ebf28..2e5ab7a460a 100644 --- a/src/plugins/qtapplicationmanager/appmanagerinstallpackagestep.cpp +++ b/src/plugins/qtapplicationmanager/appmanagerinstallpackagestep.cpp @@ -15,6 +15,7 @@ #include #include #include +#include using namespace ProjectExplorer; using namespace Utils; @@ -75,13 +76,19 @@ AppManagerInstallPackageStep::AppManagerInstallPackageStep(BuildStepList *bsl, I executable.setPlaceHolderPath(getToolFilePath(Constants::APPMAN_CONTROLLER, target()->kit(), targetInformation.device)); arguments.setPlaceHolderText(ArgumentsDefault); packageFileName.setPlaceHolderText(targetInformation.packageFile.fileName()); - packageDirectory.setPlaceHolderPath(targetInformation.runDirectory.absolutePath()); + auto device = DeviceKitAspect::device(target()->kit()); + auto remote = device && device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE; + auto packageDirectoryPath = remote ? QDir(Constants::REMOTE_DEFAULT_TMP_PATH) : targetInformation.packageFile.absolutePath(); + packageDirectory.setPlaceHolderPath(packageDirectoryPath.absolutePath()); packageDirectory.setButtonsVisible(!targetInformation.remote); + + setEnabled(!targetInformation.isBuiltin); }; connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects); connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects); connect(target(), &Target::parsingFinished, this, updateAspects); + connect(target(), &Target::runConfigurationsUpdated, this, updateAspects); connect(project(), &Project::displayNameChanged, this, updateAspects); updateAspects(); } @@ -98,7 +105,10 @@ bool AppManagerInstallPackageStep::init() const FilePath controller = executable.valueOrDefault(getToolFilePath(Constants::APPMAN_CONTROLLER, target()->kit(), targetInformation.device)); const QString controllerArguments = arguments.valueOrDefault(ArgumentsDefault); const QString packageFile = packageFileName.valueOrDefault(targetInformation.packageFile.fileName()); - const FilePath packageDir = packageDirectory.valueOrDefault(targetInformation.runDirectory.absolutePath()); + auto device = DeviceKitAspect::device(target()->kit()); + auto remote = device && device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE; + auto packageDirectoryPath = remote ? QDir(Constants::REMOTE_DEFAULT_TMP_PATH) : targetInformation.packageFile.absolutePath(); + const FilePath packageDir = packageDirectory.valueOrDefault(packageDirectoryPath.absolutePath()); CommandLine cmd(targetInformation.device->filePath(controller.path())); cmd.addArgs(controllerArguments, CommandLine::Raw); diff --git a/src/plugins/qtapplicationmanager/appmanagerplugin.cpp b/src/plugins/qtapplicationmanager/appmanagerplugin.cpp index ca074712b5f..9619f9e00e6 100644 --- a/src/plugins/qtapplicationmanager/appmanagerplugin.cpp +++ b/src/plugins/qtapplicationmanager/appmanagerplugin.cpp @@ -11,7 +11,9 @@ #include "appmanagerdeployconfigurationfactory.h" #include "appmanagerdeploypackagestep.h" #include "appmanagerinstallpackagestep.h" +#include "appmanagerremoteinstallpackagestep.h" #include "appmanagermakeinstallstep.h" +#include "appmanagercmakepackagestep.h" #include "appmanagerrunconfiguration.h" #include "appmanagerruncontrol.h" #include "appmanagerutilities.h" @@ -73,17 +75,19 @@ void cloneAutodetectedBoot2QtKits() class AppManagerPluginPrivate { public: + AppManagerCMakePackageStepFactory cmakePackageStepFactory; AppManagerMakeInstallStepFactory makeInstallStepFactory; AppManagerCreatePackageStepFactory createPackageStepFactory; AppManagerDeployPackageStepFactory deployPackageStepFactory; AppManagerInstallPackageStepFactory installPackageStepFactory; + AppManagerRemoteInstallPackageStepFactory remoteInstallPackageStepFactory; AppManagerDeployConfigurationAutoSwitcher deployConfigurationAutoSwitcher; AppManagerDeployConfigurationFactory deployConfigFactory; AppManagerRunConfigurationFactory runConfigFactory; - AppManagerDebugWorkerFactory debugWorkerFactory; AppManagerRunWorkerFactory runWorkerFactory; + AppManagerDebugWorkerFactory debugWorkerFactory; }; AppManagerPlugin::~AppManagerPlugin() diff --git a/src/plugins/qtapplicationmanager/appmanagerremoteinstallpackagestep.cpp b/src/plugins/qtapplicationmanager/appmanagerremoteinstallpackagestep.cpp new file mode 100644 index 00000000000..4c9986f6908 --- /dev/null +++ b/src/plugins/qtapplicationmanager/appmanagerremoteinstallpackagestep.cpp @@ -0,0 +1,159 @@ +// Copyright (C) 2019 Luxoft Sweden AB +// Copyright (C) 2018 Pelagicore AG +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "appmanagerremoteinstallpackagestep.h" + +#include "appmanagerstringaspect.h" +#include "appmanagerconstants.h" +#include "appmanagertargetinformation.h" +#include "appmanagerutilities.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace ProjectExplorer; +using namespace Utils; +using namespace Tasking; + +namespace AppManager::Internal { + +#define SETTINGSPREFIX "ApplicationManagerPlugin.Deploy.RemoteInstallPackageStep." + +const char ArgumentsDefault[] = "install-package -a"; + +class AppManagerRemoteInstallPackageStep final : public RemoteLinux::AbstractRemoteLinuxDeployStep +{ + Q_DECLARE_TR_FUNCTIONS(AppManager::Internal::AppManagerInstallPackageStep) + +public: + AppManagerRemoteInstallPackageStep(BuildStepList *bsl, Id id); + +private: + GroupItem deployRecipe() final; + +private: + AppManagerFilePathAspect executable{this}; + AppManagerStringAspect arguments{this}; + AppManagerStringAspect packageFileName{this}; + AppManagerFilePathAspect packageDirectory{this}; +}; + +AppManagerRemoteInstallPackageStep::AppManagerRemoteInstallPackageStep(BuildStepList *bsl, Id id) + : AbstractRemoteLinuxDeployStep(bsl, id) +{ + setDisplayName(tr("Remote Install Application Manager package")); + + executable.setSettingsKey(SETTINGSPREFIX "Executable"); + executable.setHistoryCompleter(SETTINGSPREFIX "Executable.History"); + executable.setLabelText(tr("Executable:")); + + arguments.setSettingsKey(SETTINGSPREFIX "Arguments"); + arguments.setHistoryCompleter(SETTINGSPREFIX "Arguments.History"); + arguments.setDisplayStyle(StringAspect::LineEditDisplay); + arguments.setLabelText(tr("Arguments:")); + + packageFileName.setSettingsKey(SETTINGSPREFIX "FileName"); + packageFileName.setHistoryCompleter(SETTINGSPREFIX "FileName.History"); + packageFileName.setDisplayStyle(StringAspect::LineEditDisplay); + packageFileName.setLabelText(tr("File name:")); + + packageDirectory.setSettingsKey(SETTINGSPREFIX "Directory"); + packageDirectory.setHistoryCompleter(SETTINGSPREFIX "Directory.History"); + packageDirectory.setExpectedKind(PathChooser::Directory); + packageDirectory.setLabelText(tr("Directory:")); + + setInternalInitializer([this] { return isDeploymentPossible(); }); + + const auto updateAspects = [this] { + const TargetInformation targetInformation(target()); + + executable.setPromptDialogFilter(getToolNameByDevice(Constants::APPMAN_CONTROLLER, targetInformation.device)); + executable.setButtonsVisible(!targetInformation.remote); + executable.setExpectedKind(targetInformation.remote ? PathChooser::Command : PathChooser::ExistingCommand); + executable.setPlaceHolderPath(getToolFilePath(Constants::APPMAN_CONTROLLER, target()->kit(), targetInformation.device)); + arguments.setPlaceHolderText(ArgumentsDefault); + packageFileName.setPlaceHolderText(targetInformation.packageFile.fileName()); + auto device = DeviceKitAspect::device(target()->kit()); + auto remote = device && device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE; + auto packageDirectoryPath = remote ? QDir(Constants::REMOTE_DEFAULT_TMP_PATH) : targetInformation.packageFile.absolutePath(); + packageDirectory.setPlaceHolderPath(packageDirectoryPath.absolutePath()); + packageDirectory.setButtonsVisible(!targetInformation.remote); + + setEnabled(!targetInformation.isBuiltin); + }; + + connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects); + connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects); + connect(target(), &Target::parsingFinished, this, updateAspects); + connect(target(), &Target::runConfigurationsUpdated, this, updateAspects); + connect(project(), &Project::displayNameChanged, this, updateAspects); + updateAspects(); +} + +GroupItem AppManagerRemoteInstallPackageStep::deployRecipe() +{ + const TargetInformation targetInformation(target()); + + const FilePath controller = executable.valueOrDefault(getToolFilePath(Constants::APPMAN_CONTROLLER, target()->kit(), targetInformation.device)); + const QString controllerArguments = arguments.valueOrDefault(ArgumentsDefault); + const QString packageFile = packageFileName.valueOrDefault(targetInformation.packageFile.fileName()); + auto device = DeviceKitAspect::device(target()->kit()); + auto remote = device && device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE; + auto packageDirectoryPath = remote ? QDir(Constants::REMOTE_DEFAULT_TMP_PATH) : targetInformation.packageFile.absolutePath(); + const FilePath packageDir = packageDirectory.valueOrDefault(packageDirectoryPath.absolutePath()); + + const auto setupHandler = [=](Process &process) { + CommandLine remoteCmd(controller); + remoteCmd.addArgs(controllerArguments, CommandLine::Raw); + remoteCmd.addArg(packageDir.toString() + '/' + packageFile); + + CommandLine cmd(deviceConfiguration()->filePath("/bin/sh")); + cmd.addArg("-c"); + cmd.addCommandLineAsSingleArg(remoteCmd); + + addProgressMessage(tr("Starting remote command \"%1\"...").arg(cmd.toUserOutput())); + process.setCommand(cmd); + Process *proc = &process; + connect(proc, &Process::readyReadStandardOutput, this, [this, proc] { + handleStdOutData(proc->readAllStandardOutput()); + }); + connect(proc, &Process::readyReadStandardError, this, [this, proc] { + handleStdErrData(proc->readAllStandardError()); + }); + }; + const auto doneHandler = [this](const Process &process, DoneWith result) { + if (result == DoneWith::Success) { + addProgressMessage(tr("Remote command finished successfully.")); + } else { + if (process.error() != QProcess::UnknownError + || process.exitStatus() != QProcess::NormalExit) { + addErrorMessage(tr("Remote process failed: %1").arg(process.errorString())); + } else if (process.exitCode() != 0) { + addErrorMessage(tr("Remote process finished with exit code %1.") + .arg(process.exitCode())); + } + } + }; + + return ProcessTask(setupHandler, doneHandler); +} + +// Factory + +AppManagerRemoteInstallPackageStepFactory::AppManagerRemoteInstallPackageStepFactory() +{ + registerStep(Constants::REMOTE_INSTALL_PACKAGE_STEP_ID); + setDisplayName(AppManagerRemoteInstallPackageStep::tr("Remote Install Application Manager package")); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); +} + +} // namespace AppManager::Internal diff --git a/src/plugins/qtapplicationmanager/appmanagerremoteinstallpackagestep.h b/src/plugins/qtapplicationmanager/appmanagerremoteinstallpackagestep.h new file mode 100644 index 00000000000..643b0649215 --- /dev/null +++ b/src/plugins/qtapplicationmanager/appmanagerremoteinstallpackagestep.h @@ -0,0 +1,18 @@ +// Copyright (C) 2019 Luxoft Sweden AB +// Copyright (C) 2018 Pelagicore AG +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace AppManager::Internal { + +class AppManagerRemoteInstallPackageStepFactory final : public ProjectExplorer::BuildStepFactory +{ +public: + AppManagerRemoteInstallPackageStepFactory(); +}; + +} // namespace AppManager::Internal diff --git a/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.cpp b/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.cpp index 4bd7581bfc3..f2760711ef8 100644 --- a/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.cpp +++ b/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.cpp @@ -18,6 +18,9 @@ #include #include +#include +#include + using namespace ProjectExplorer; using namespace Utils; @@ -59,7 +62,13 @@ QList AppManagerRunConfigurationFactory::available QObject::connect(&d->fileSystemWatcher, &FileSystemWatcher::fileChanged, target->project(), &Project::displayNameChanged, Qt::UniqueConnection); const auto buildTargets = TargetInformation::readFromProject(target); - const auto result = Utils::transform(buildTargets, [this](const TargetInformation &ti) { + auto result = Utils::transform(buildTargets, [this, target](const TargetInformation &ti) { + + QVariantMap settings; + // ti.buildKey is currently our app id + settings.insert("id", ti.buildKey); + target->setNamedSettings("runConfigurationSettings", settings); + RunConfigurationCreationInfo rci; rci.factory = this; rci.buildKey = ti.buildKey; @@ -72,6 +81,7 @@ QList AppManagerRunConfigurationFactory::available } return rci; }); + return result; } diff --git a/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.h b/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.h index 4cee68841ad..891cacca2d0 100644 --- a/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.h +++ b/src/plugins/qtapplicationmanager/appmanagerrunconfiguration.h @@ -7,6 +7,8 @@ #include +using namespace ProjectExplorer; + namespace AppManager { namespace Internal { diff --git a/src/plugins/qtapplicationmanager/appmanagerruncontrol.cpp b/src/plugins/qtapplicationmanager/appmanagerruncontrol.cpp index 307e254b257..ebbe9a48cce 100644 --- a/src/plugins/qtapplicationmanager/appmanagerruncontrol.cpp +++ b/src/plugins/qtapplicationmanager/appmanagerruncontrol.cpp @@ -145,7 +145,7 @@ public: return ti.buildKey == targetInformation.manifest.code || ti.projectFilePath.toString() == targetInformation.manifest.code; }).targetFilePath.toString(); } else { - reportFailure(tr("Cannot debug: Could not determine appman runtime.")); + reportFailure(tr("Cannot debug: Only QML and native applications are supported.")); } } @@ -187,7 +187,11 @@ void AppManagerDebugSupport::start() addSearchDirectory(version->qmlPath()); } - setSysRoot(SysRootKitAspect().sysRoot(runControl()->kit())); + auto sysroot = SysRootKitAspect().sysRoot(runControl()->kit()); + if (sysroot.isEmpty()) + setSysRoot("/"); + else + setSysRoot(sysroot); } setInferior(inferior); diff --git a/src/plugins/qtapplicationmanager/appmanagertargetinformation.cpp b/src/plugins/qtapplicationmanager/appmanagertargetinformation.cpp index 2f7c44a81b2..e21975264d9 100644 --- a/src/plugins/qtapplicationmanager/appmanagertargetinformation.cpp +++ b/src/plugins/qtapplicationmanager/appmanagertargetinformation.cpp @@ -19,6 +19,8 @@ #include +#include + using namespace ProjectExplorer; using namespace QmakeProjectManager; using namespace QtSupport; @@ -220,6 +222,66 @@ QList TargetInformation::readFromProject(const Target *target } result.append(ati); }); + } else { + QVariantList packageTargets = target->project()->extraData(AppManager::Constants::APPMAN_PACKAGE_TARGETS).toList(); +// qDebug() << "APPMAN TARGETS" << packageTargets; + + for (const auto &packageTarget : packageTargets) { + const QVariantMap packageTargetMap = packageTarget.toMap(); + const FilePath manifestFilePath = packageTargetMap.value("manifestFilePath").value(); + const QString cmakeTarget = packageTargetMap.value("cmakeTarget").toString(); + const FilePath packageFilePath = packageTargetMap.value("packageFilePath").value(); + const bool isBuiltinPackage = packageTargetMap.value("isBuiltinPackage").toBool(); + + const Utils::expected_str localFileContents = manifestFilePath.fileContents(); + if (!localFileContents.has_value()) { + qWarning() << "NOPE:" << localFileContents.error(); + } + + auto createTargetInformation = [buildKey, manifestFilePath, cmakeTarget, packageFilePath, isBuiltinPackage, &result](const YAML::Node &document) { + const QString id = QString::fromStdString(document["id"].as()); + const QString runtime = QString::fromStdString(document["runtime"].as()); + + if (!buildKey.isEmpty() && buildKey != id) + return; + + TargetInformation ati; + ati.displayNameUniquifier = id + " App"; + ati.displayName = id + " App"; + ati.buildKey = id; + ati.manifest.fileName = manifestFilePath.path(); + ati.manifest.id = id; + ati.manifest.runtime = runtime; + ati.isBuiltin = isBuiltinPackage; + ati.cmakeBuildTarget = cmakeTarget; + ati.packageFile = QFileInfo(packageFilePath.path()); + +// qCritical() << "CREATE CONFIG: BUILTIN:" << isBuiltinPackage << id << "TARGET:" << cmakeTarget; + + result.append(ati); + }; + + try { + std::vector documents = YAML::LoadAll(*localFileContents); + if (documents.size() != 2) + throw std::runtime_error("Must contain two documents"); + YAML::Node header = documents[0]; + YAML::Node document = documents[1]; + + std::string formatType = header["formatType"].as(); + if (formatType == "am-package") { + for (const auto &applicationNode : document["applications"]) + createTargetInformation(applicationNode); + } else if (formatType == "am-application") { + createTargetInformation(document); + } else { + throw std::runtime_error("unknown formatType"); + } + + } catch (const std::exception &e) { + qWarning() << "NOPE:" << e.what(); + } + } } return result; } diff --git a/src/plugins/qtapplicationmanager/appmanagertargetinformation.h b/src/plugins/qtapplicationmanager/appmanagertargetinformation.h index d188c4aa134..244ef34c037 100644 --- a/src/plugins/qtapplicationmanager/appmanagertargetinformation.h +++ b/src/plugins/qtapplicationmanager/appmanagertargetinformation.h @@ -9,6 +9,7 @@ #include #include +#include namespace AppManager { namespace Internal { @@ -49,6 +50,8 @@ public: QString buildKey; QString displayName; QString displayNameUniquifier; + QString cmakeBuildTarget; + bool isBuiltin = false; bool remote = false; bool isValid() const;