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 <hjk@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Dominik Holland
2023-12-20 10:38:09 +01:00
parent 5e1993e0ae
commit 3916a0637a
16 changed files with 370 additions and 12 deletions

View File

@@ -4,7 +4,7 @@ add_qtc_plugin(QtApplicationManagerIntegration
PLUGIN_DEPENDS PLUGIN_DEPENDS
Core Debugger ProjectExplorer QmakeProjectManager Core Debugger ProjectExplorer QmakeProjectManager
QtSupport RemoteLinux QtSupport RemoteLinux
DEPENDS Qt::Network Qt::Widgets ExtensionSystem Utils DEPENDS Qt::Network Qt::Widgets ExtensionSystem Utils yaml-cpp
SOURCES SOURCES
appmanagerconstants.h appmanagerconstants.h
appmanagercreatepackagestep.cpp appmanagercreatepackagestep.h appmanagercreatepackagestep.cpp appmanagercreatepackagestep.h
@@ -12,7 +12,9 @@ add_qtc_plugin(QtApplicationManagerIntegration
appmanagerdeployconfigurationfactory.cpp appmanagerdeployconfigurationfactory.h appmanagerdeployconfigurationfactory.cpp appmanagerdeployconfigurationfactory.h
appmanagerdeploypackagestep.cpp appmanagerdeploypackagestep.h appmanagerdeploypackagestep.cpp appmanagerdeploypackagestep.h
appmanagerinstallpackagestep.cpp appmanagerinstallpackagestep.h appmanagerinstallpackagestep.cpp appmanagerinstallpackagestep.h
appmanagerremoteinstallpackagestep.cpp appmanagerremoteinstallpackagestep.h
appmanagermakeinstallstep.cpp appmanagermakeinstallstep.h appmanagermakeinstallstep.cpp appmanagermakeinstallstep.h
appmanagercmakepackagestep.cpp appmanagercmakepackagestep.h
appmanagerplugin.cpp appmanagerplugin.h appmanagerplugin.cpp appmanagerplugin.h
appmanagerrunconfiguration.cpp appmanagerrunconfiguration.h appmanagerrunconfiguration.cpp appmanagerrunconfiguration.h
appmanagerruncontrol.cpp appmanagerruncontrol.h appmanagerruncontrol.cpp appmanagerruncontrol.h

View File

@@ -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 <projectexplorer/processparameters.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
#include <cmakeprojectmanager/cmakeprojectconstants.h>
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

View File

@@ -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 <projectexplorer/buildstep.h>
#include <QCoreApplication>
namespace AppManager {
namespace Internal {
class AppManagerCMakePackageStepFactory final : public ProjectExplorer::BuildStepFactory
{
Q_DECLARE_TR_FUNCTIONS(Qtc::AppManager)
public:
AppManagerCMakePackageStepFactory();
};
} // namespace Internal
} // namespace AppManager

View File

@@ -16,11 +16,15 @@ const char APPMAN_LAUNCHER_QML[] = "appman-launcher-qml";
const char DEBUG_LAUNCHER_ID[] = "ApplicationManagerPlugin.Debug.Launcher"; const char DEBUG_LAUNCHER_ID[] = "ApplicationManagerPlugin.Debug.Launcher";
const char DEPLOYCONFIGURATION_ID[] = "ApplicationManagerPlugin.Deploy.Configuration"; const char DEPLOYCONFIGURATION_ID[] = "ApplicationManagerPlugin.Deploy.Configuration";
const char MAKE_INSTALL_STEP_ID[] = "ApplicationManagerPlugin.Deploy.MakeInstallStep"; 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 CREATE_PACKAGE_STEP_ID[] = "ApplicationManagerPlugin.Deploy.CreatePackageStep";
const char DEPLOY_PACKAGE_STEP_ID[] = "ApplicationManagerPlugin.Deploy.DeployPackageStep"; const char DEPLOY_PACKAGE_STEP_ID[] = "ApplicationManagerPlugin.Deploy.DeployPackageStep";
const char INSTALL_PACKAGE_STEP_ID[] = "ApplicationManagerPlugin.Deploy.InstallPackageStep"; 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 RUNCONFIGURATION_ID[] = "ApplicationManagerPlugin.Run.Configuration";
const char EXTRADATA_TARGET_ID[] = "ApplicationManagerPlugin.ExtraData.Target";
const char APPMAN_PACKAGE_TARGETS[] = "ApplicationmanagerPackageTargets"; const char APPMAN_PACKAGE_TARGETS[] = "ApplicationmanagerPackageTargets";
const char QMAKE_AM_MANIFEST_VARIABLE[] = "AM_MANIFEST"; const char QMAKE_AM_MANIFEST_VARIABLE[] = "AM_MANIFEST";

View File

@@ -82,11 +82,14 @@ AppManagerCreatePackageStep::AppManagerCreatePackageStep(BuildStepList *bsl, Id
sourceDirectory.setPlaceHolderPath(targetInformation.packageSourcesDirectory.absolutePath()); sourceDirectory.setPlaceHolderPath(targetInformation.packageSourcesDirectory.absolutePath());
buildDirectory.setPlaceHolderPath(targetInformation.buildDirectory.absolutePath()); buildDirectory.setPlaceHolderPath(targetInformation.buildDirectory.absolutePath());
packageFileName.setPlaceHolderText(targetInformation.packageFile.fileName()); packageFileName.setPlaceHolderText(targetInformation.packageFile.fileName());
setEnabled(!targetInformation.isBuiltin);
}; };
connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects); connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects);
connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects); connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects);
connect(target(), &Target::parsingFinished, this, updateAspects); connect(target(), &Target::parsingFinished, this, updateAspects);
connect(target(), &Target::runConfigurationsUpdated, this, updateAspects);
connect(project(), &Project::displayNameChanged, this, updateAspects); connect(project(), &Project::displayNameChanged, this, updateAspects);
updateAspects(); updateAspects();
} }
@@ -119,7 +122,7 @@ bool AppManagerCreatePackageStep::init()
AppManagerCreatePackageStepFactory::AppManagerCreatePackageStepFactory() AppManagerCreatePackageStepFactory::AppManagerCreatePackageStepFactory()
{ {
registerStep<AppManagerCreatePackageStep>(Constants::DEPLOY_PACKAGE_STEP_ID); registerStep<AppManagerCreatePackageStep>(Constants::CREATE_PACKAGE_STEP_ID);
setDisplayName(AppManagerCreatePackageStep::tr("Create Application Manager package")); setDisplayName(AppManagerCreatePackageStep::tr("Create Application Manager package"));
setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY);
} }

View File

@@ -6,6 +6,7 @@
#include "appmanagerdeployconfigurationfactory.h" #include "appmanagerdeployconfigurationfactory.h"
#include "appmanagerconstants.h" #include "appmanagerconstants.h"
#include "appmanagertargetinformation.h"
#include <projectexplorer/devicesupport/idevice.h> #include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/kitaspects.h> #include <projectexplorer/kitaspects.h>
@@ -28,13 +29,16 @@ static bool isNecessaryToDeploy(const Target *target)
AppManagerDeployConfigurationFactory::AppManagerDeployConfigurationFactory() AppManagerDeployConfigurationFactory::AppManagerDeployConfigurationFactory()
{ {
setConfigBaseId(Constants::DEPLOYCONFIGURATION_ID); 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(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType); 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::DEPLOY_PACKAGE_STEP_ID, isNecessaryToDeploy);
addInitialStep(Constants::INSTALL_PACKAGE_STEP_ID); addInitialStep(Constants::REMOTE_INSTALL_PACKAGE_STEP_ID, isNecessaryToDeploy);
} }
} // namespace Internal } // namespace Internal

View File

@@ -54,11 +54,14 @@ public:
packageFilePath.setPlaceHolderPath(targetInformation.packageFile.absoluteFilePath()); packageFilePath.setPlaceHolderPath(targetInformation.packageFile.absoluteFilePath());
targetDirectory.setPlaceHolderPath(targetInformation.runDirectory.absolutePath()); targetDirectory.setPlaceHolderPath(targetInformation.runDirectory.absolutePath());
setEnabled(!targetInformation.isBuiltin);
}; };
connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects); connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects);
connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects); connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects);
connect(target(), &Target::parsingFinished, this, updateAspects); connect(target(), &Target::parsingFinished, this, updateAspects);
connect(target(), &Target::runConfigurationsUpdated, this, updateAspects);
connect(project(), &Project::displayNameChanged, this, updateAspects); connect(project(), &Project::displayNameChanged, this, updateAspects);
updateAspects(); updateAspects();

View File

@@ -15,6 +15,7 @@
#include <projectexplorer/processparameters.h> #include <projectexplorer/processparameters.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <projectexplorer/kitaspects.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
@@ -75,13 +76,19 @@ AppManagerInstallPackageStep::AppManagerInstallPackageStep(BuildStepList *bsl, I
executable.setPlaceHolderPath(getToolFilePath(Constants::APPMAN_CONTROLLER, target()->kit(), targetInformation.device)); executable.setPlaceHolderPath(getToolFilePath(Constants::APPMAN_CONTROLLER, target()->kit(), targetInformation.device));
arguments.setPlaceHolderText(ArgumentsDefault); arguments.setPlaceHolderText(ArgumentsDefault);
packageFileName.setPlaceHolderText(targetInformation.packageFile.fileName()); 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); packageDirectory.setButtonsVisible(!targetInformation.remote);
setEnabled(!targetInformation.isBuiltin);
}; };
connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects); connect(target(), &Target::activeRunConfigurationChanged, this, updateAspects);
connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects); connect(target(), &Target::activeDeployConfigurationChanged, this, updateAspects);
connect(target(), &Target::parsingFinished, this, updateAspects); connect(target(), &Target::parsingFinished, this, updateAspects);
connect(target(), &Target::runConfigurationsUpdated, this, updateAspects);
connect(project(), &Project::displayNameChanged, this, updateAspects); connect(project(), &Project::displayNameChanged, this, updateAspects);
updateAspects(); updateAspects();
} }
@@ -98,7 +105,10 @@ bool AppManagerInstallPackageStep::init()
const FilePath controller = executable.valueOrDefault(getToolFilePath(Constants::APPMAN_CONTROLLER, target()->kit(), targetInformation.device)); const FilePath controller = executable.valueOrDefault(getToolFilePath(Constants::APPMAN_CONTROLLER, target()->kit(), targetInformation.device));
const QString controllerArguments = arguments.valueOrDefault(ArgumentsDefault); const QString controllerArguments = arguments.valueOrDefault(ArgumentsDefault);
const QString packageFile = packageFileName.valueOrDefault(targetInformation.packageFile.fileName()); 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())); CommandLine cmd(targetInformation.device->filePath(controller.path()));
cmd.addArgs(controllerArguments, CommandLine::Raw); cmd.addArgs(controllerArguments, CommandLine::Raw);

View File

@@ -11,7 +11,9 @@
#include "appmanagerdeployconfigurationfactory.h" #include "appmanagerdeployconfigurationfactory.h"
#include "appmanagerdeploypackagestep.h" #include "appmanagerdeploypackagestep.h"
#include "appmanagerinstallpackagestep.h" #include "appmanagerinstallpackagestep.h"
#include "appmanagerremoteinstallpackagestep.h"
#include "appmanagermakeinstallstep.h" #include "appmanagermakeinstallstep.h"
#include "appmanagercmakepackagestep.h"
#include "appmanagerrunconfiguration.h" #include "appmanagerrunconfiguration.h"
#include "appmanagerruncontrol.h" #include "appmanagerruncontrol.h"
#include "appmanagerutilities.h" #include "appmanagerutilities.h"
@@ -73,17 +75,19 @@ void cloneAutodetectedBoot2QtKits()
class AppManagerPluginPrivate class AppManagerPluginPrivate
{ {
public: public:
AppManagerCMakePackageStepFactory cmakePackageStepFactory;
AppManagerMakeInstallStepFactory makeInstallStepFactory; AppManagerMakeInstallStepFactory makeInstallStepFactory;
AppManagerCreatePackageStepFactory createPackageStepFactory; AppManagerCreatePackageStepFactory createPackageStepFactory;
AppManagerDeployPackageStepFactory deployPackageStepFactory; AppManagerDeployPackageStepFactory deployPackageStepFactory;
AppManagerInstallPackageStepFactory installPackageStepFactory; AppManagerInstallPackageStepFactory installPackageStepFactory;
AppManagerRemoteInstallPackageStepFactory remoteInstallPackageStepFactory;
AppManagerDeployConfigurationAutoSwitcher deployConfigurationAutoSwitcher; AppManagerDeployConfigurationAutoSwitcher deployConfigurationAutoSwitcher;
AppManagerDeployConfigurationFactory deployConfigFactory; AppManagerDeployConfigurationFactory deployConfigFactory;
AppManagerRunConfigurationFactory runConfigFactory; AppManagerRunConfigurationFactory runConfigFactory;
AppManagerDebugWorkerFactory debugWorkerFactory;
AppManagerRunWorkerFactory runWorkerFactory; AppManagerRunWorkerFactory runWorkerFactory;
AppManagerDebugWorkerFactory debugWorkerFactory;
}; };
AppManagerPlugin::~AppManagerPlugin() AppManagerPlugin::~AppManagerPlugin()

View File

@@ -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 <remotelinux/abstractremotelinuxdeploystep.h>
#include <projectexplorer/deployconfiguration.h>
#include <projectexplorer/processparameters.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
#include <projectexplorer/kitaspects.h>
#include <projectexplorer/devicesupport/idevice.h>
#include <utils/process.h>
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<AppManagerRemoteInstallPackageStep>(Constants::REMOTE_INSTALL_PACKAGE_STEP_ID);
setDisplayName(AppManagerRemoteInstallPackageStep::tr("Remote Install Application Manager package"));
setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY);
}
} // namespace AppManager::Internal

View File

@@ -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 <projectexplorer/buildstep.h>
namespace AppManager::Internal {
class AppManagerRemoteInstallPackageStepFactory final : public ProjectExplorer::BuildStepFactory
{
public:
AppManagerRemoteInstallPackageStepFactory();
};
} // namespace AppManager::Internal

View File

@@ -18,6 +18,9 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/filesystemwatcher.h> #include <utils/filesystemwatcher.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitaspect.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
@@ -59,7 +62,13 @@ QList<RunConfigurationCreationInfo> AppManagerRunConfigurationFactory::available
QObject::connect(&d->fileSystemWatcher, &FileSystemWatcher::fileChanged, target->project(), &Project::displayNameChanged, Qt::UniqueConnection); QObject::connect(&d->fileSystemWatcher, &FileSystemWatcher::fileChanged, target->project(), &Project::displayNameChanged, Qt::UniqueConnection);
const auto buildTargets = TargetInformation::readFromProject(target); 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; RunConfigurationCreationInfo rci;
rci.factory = this; rci.factory = this;
rci.buildKey = ti.buildKey; rci.buildKey = ti.buildKey;
@@ -72,6 +81,7 @@ QList<RunConfigurationCreationInfo> AppManagerRunConfigurationFactory::available
} }
return rci; return rci;
}); });
return result; return result;
} }

View File

@@ -7,6 +7,8 @@
#include <projectexplorer/runconfigurationaspects.h> #include <projectexplorer/runconfigurationaspects.h>
using namespace ProjectExplorer;
namespace AppManager { namespace AppManager {
namespace Internal { namespace Internal {

View File

@@ -145,7 +145,7 @@ public:
return ti.buildKey == targetInformation.manifest.code || ti.projectFilePath.toString() == targetInformation.manifest.code; return ti.buildKey == targetInformation.manifest.code || ti.projectFilePath.toString() == targetInformation.manifest.code;
}).targetFilePath.toString(); }).targetFilePath.toString();
} else { } 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()); addSearchDirectory(version->qmlPath());
} }
setSysRoot(SysRootKitAspect().sysRoot(runControl()->kit())); auto sysroot = SysRootKitAspect().sysRoot(runControl()->kit());
if (sysroot.isEmpty())
setSysRoot("/");
else
setSysRoot(sysroot);
} }
setInferior(inferior); setInferior(inferior);

View File

@@ -19,6 +19,8 @@
#include <qtsupport/profilereader.h> #include <qtsupport/profilereader.h>
#include <yaml-cpp/yaml.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace QmakeProjectManager; using namespace QmakeProjectManager;
using namespace QtSupport; using namespace QtSupport;
@@ -220,6 +222,66 @@ QList<TargetInformation> TargetInformation::readFromProject(const Target *target
} }
result.append(ati); 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<FilePath>();
const QString cmakeTarget = packageTargetMap.value("cmakeTarget").toString();
const FilePath packageFilePath = packageTargetMap.value("packageFilePath").value<FilePath>();
const bool isBuiltinPackage = packageTargetMap.value("isBuiltinPackage").toBool();
const Utils::expected_str<QByteArray> 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<std::string>());
const QString runtime = QString::fromStdString(document["runtime"].as<std::string>());
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<YAML::Node> 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<std::string>();
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; return result;
} }

View File

@@ -9,6 +9,7 @@
#include <projectexplorer/runcontrol.h> #include <projectexplorer/runcontrol.h>
#include <qmakeprojectmanager/qmakeparsernodes.h> #include <qmakeprojectmanager/qmakeparsernodes.h>
#include <cmakeprojectmanager/cmakebuildsystem.h>
namespace AppManager { namespace AppManager {
namespace Internal { namespace Internal {
@@ -49,6 +50,8 @@ public:
QString buildKey; QString buildKey;
QString displayName; QString displayName;
QString displayNameUniquifier; QString displayNameUniquifier;
QString cmakeBuildTarget;
bool isBuiltin = false;
bool remote = false; bool remote = false;
bool isValid() const; bool isValid() const;