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
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

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 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";

View File

@@ -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<AppManagerCreatePackageStep>(Constants::DEPLOY_PACKAGE_STEP_ID);
registerStep<AppManagerCreatePackageStep>(Constants::CREATE_PACKAGE_STEP_ID);
setDisplayName(AppManagerCreatePackageStep::tr("Create Application Manager package"));
setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY);
}

View File

@@ -6,6 +6,7 @@
#include "appmanagerdeployconfigurationfactory.h"
#include "appmanagerconstants.h"
#include "appmanagertargetinformation.h"
#include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/kitaspects.h>
@@ -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

View File

@@ -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();

View File

@@ -15,6 +15,7 @@
#include <projectexplorer/processparameters.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
#include <projectexplorer/kitaspects.h>
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);

View File

@@ -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()

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/filesystemwatcher.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitaspect.h>
using namespace ProjectExplorer;
using namespace Utils;
@@ -59,7 +62,13 @@ QList<RunConfigurationCreationInfo> 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<RunConfigurationCreationInfo> AppManagerRunConfigurationFactory::available
}
return rci;
});
return result;
}

View File

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

View File

@@ -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);

View File

@@ -19,6 +19,8 @@
#include <qtsupport/profilereader.h>
#include <yaml-cpp/yaml.h>
using namespace ProjectExplorer;
using namespace QmakeProjectManager;
using namespace QtSupport;
@@ -220,6 +222,66 @@ QList<TargetInformation> 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<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;
}

View File

@@ -9,6 +9,7 @@
#include <projectexplorer/runcontrol.h>
#include <qmakeprojectmanager/qmakeparsernodes.h>
#include <cmakeprojectmanager/cmakebuildsystem.h>
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;