2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2012-04-24 15:49:09 +02:00
|
|
|
|
2023-08-11 09:18:56 +02:00
|
|
|
#include "kitaspects.h"
|
2012-04-24 15:49:09 +02:00
|
|
|
|
2017-12-08 17:20:48 +01:00
|
|
|
#include "abi.h"
|
2012-04-24 15:49:09 +02:00
|
|
|
#include "devicesupport/devicemanager.h"
|
2019-02-06 15:04:17 +01:00
|
|
|
#include "devicesupport/devicemanagermodel.h"
|
|
|
|
|
#include "devicesupport/idevicefactory.h"
|
2022-05-13 01:08:44 +02:00
|
|
|
#include "devicesupport/sshparameters.h"
|
2012-04-24 15:49:09 +02:00
|
|
|
#include "projectexplorerconstants.h"
|
2023-01-13 12:38:22 +01:00
|
|
|
#include "projectexplorertr.h"
|
2012-09-03 18:31:44 +02:00
|
|
|
#include "kit.h"
|
2012-04-24 15:49:09 +02:00
|
|
|
#include "toolchain.h"
|
|
|
|
|
#include "toolchainmanager.h"
|
|
|
|
|
|
2014-07-07 19:02:26 +02:00
|
|
|
#include <utils/algorithm.h>
|
2019-11-21 15:35:24 +01:00
|
|
|
#include <utils/elidinglabel.h>
|
2019-02-06 15:04:17 +01:00
|
|
|
#include <utils/environment.h>
|
|
|
|
|
#include <utils/environmentdialog.h>
|
2022-07-22 11:19:45 +02:00
|
|
|
#include <utils/guard.h>
|
2021-04-07 18:55:21 +02:00
|
|
|
#include <utils/layoutbuilder.h>
|
2014-10-22 10:00:07 +02:00
|
|
|
#include <utils/macroexpander.h>
|
2019-02-06 15:04:17 +01:00
|
|
|
#include <utils/pathchooser.h>
|
2013-02-28 14:06:17 +01:00
|
|
|
#include <utils/qtcassert.h>
|
2020-09-18 12:11:40 +02:00
|
|
|
#include <utils/variablechooser.h>
|
2012-04-24 15:49:09 +02:00
|
|
|
|
2019-02-06 15:04:17 +01:00
|
|
|
#include <QCheckBox>
|
|
|
|
|
#include <QComboBox>
|
|
|
|
|
#include <QFontMetrics>
|
|
|
|
|
#include <QGridLayout>
|
|
|
|
|
#include <QLabel>
|
|
|
|
|
#include <QPushButton>
|
|
|
|
|
#include <QVBoxLayout>
|
2012-04-24 15:49:09 +02:00
|
|
|
|
2021-04-07 18:55:21 +02:00
|
|
|
using namespace Utils;
|
|
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
namespace ProjectExplorer {
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
2019-02-06 12:50:51 +01:00
|
|
|
// SysRootKitAspect:
|
2012-04-24 15:49:09 +02:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2019-02-06 15:04:17 +01:00
|
|
|
namespace Internal {
|
2023-08-10 15:47:26 +02:00
|
|
|
class SysRootKitAspectImpl : public KitAspect
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2023-08-16 10:20:01 +02:00
|
|
|
SysRootKitAspectImpl(Kit *k, const KitAspectFactory *factory) : KitAspect(k, factory)
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
2021-04-07 18:55:21 +02:00
|
|
|
m_chooser = createSubWidget<PathChooser>();
|
2022-06-29 16:22:28 +02:00
|
|
|
m_chooser->setExpectedKind(PathChooser::ExistingDirectory);
|
2023-08-24 12:41:45 +02:00
|
|
|
m_chooser->setHistoryCompleter("PE.SysRoot.History");
|
2020-04-09 11:05:50 +02:00
|
|
|
m_chooser->setFilePath(SysRootKitAspect::sysRoot(k));
|
2022-09-02 11:49:36 +02:00
|
|
|
connect(m_chooser, &PathChooser::textChanged,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &SysRootKitAspectImpl::pathWasChanged);
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
~SysRootKitAspectImpl() override { delete m_chooser; }
|
2019-02-06 15:04:17 +01:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void makeReadOnly() override { m_chooser->setReadOnly(true); }
|
2021-04-07 18:55:21 +02:00
|
|
|
|
2023-08-22 09:54:38 +02:00
|
|
|
void addToLayoutImpl(Layouting::LayoutItem &builder) override
|
2021-04-07 18:55:21 +02:00
|
|
|
{
|
|
|
|
|
addMutableAction(m_chooser);
|
|
|
|
|
builder.addItem(Layouting::Span(2, m_chooser));
|
|
|
|
|
}
|
2019-02-06 15:04:17 +01:00
|
|
|
|
|
|
|
|
void refresh() override
|
|
|
|
|
{
|
2022-07-22 11:19:45 +02:00
|
|
|
if (!m_ignoreChanges.isLocked())
|
2020-04-09 11:05:50 +02:00
|
|
|
m_chooser->setFilePath(SysRootKitAspect::sysRoot(m_kit));
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pathWasChanged()
|
|
|
|
|
{
|
2022-07-22 11:19:45 +02:00
|
|
|
const GuardLocker locker(m_ignoreChanges);
|
2020-04-09 11:05:50 +02:00
|
|
|
SysRootKitAspect::setSysRoot(m_kit, m_chooser->filePath());
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
PathChooser *m_chooser;
|
2022-07-22 11:19:45 +02:00
|
|
|
Guard m_ignoreChanges;
|
2019-02-06 15:04:17 +01:00
|
|
|
};
|
|
|
|
|
} // namespace Internal
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
class SysRootKitAspectFactory : public KitAspectFactory
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
SysRootKitAspectFactory();
|
|
|
|
|
|
|
|
|
|
Tasks validate(const Kit *k) const override;
|
|
|
|
|
KitAspect *createKitAspect(Kit *k) const override;
|
|
|
|
|
ItemList toUserOutput(const Kit *k) const override;
|
|
|
|
|
void addToMacroExpander(Kit *kit, MacroExpander *expander) const override;
|
|
|
|
|
};
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
SysRootKitAspectFactory::SysRootKitAspectFactory()
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-02-06 12:50:51 +01:00
|
|
|
setId(SysRootKitAspect::id());
|
2023-01-13 12:38:22 +01:00
|
|
|
setDisplayName(Tr::tr("Sysroot"));
|
|
|
|
|
setDescription(Tr::tr("The root directory of the system image to use.<br>"
|
2019-02-06 16:16:07 +01:00
|
|
|
"Leave empty when building for the desktop."));
|
2023-08-21 17:06:04 +02:00
|
|
|
setPriority(27000);
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
Tasks SysRootKitAspectFactory::validate(const Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-05-27 16:09:44 +02:00
|
|
|
Tasks result;
|
2022-06-29 16:22:28 +02:00
|
|
|
const FilePath dir = SysRootKitAspect::sysRoot(k);
|
2016-04-15 11:03:33 +02:00
|
|
|
if (dir.isEmpty())
|
|
|
|
|
return result;
|
|
|
|
|
|
2021-09-29 18:18:56 +02:00
|
|
|
if (dir.startsWith("target:") || dir.startsWith("remote:"))
|
2017-10-04 18:18:50 +02:00
|
|
|
return result;
|
|
|
|
|
|
2021-09-29 18:18:56 +02:00
|
|
|
if (!dir.exists()) {
|
2020-01-15 08:56:11 +01:00
|
|
|
result << BuildSystemTask(Task::Warning,
|
2023-01-13 12:38:22 +01:00
|
|
|
Tr::tr("Sys Root \"%1\" does not exist in the file system.").arg(dir.toUserOutput()));
|
2021-09-29 18:18:56 +02:00
|
|
|
} else if (!dir.isDir()) {
|
2020-01-15 08:56:11 +01:00
|
|
|
result << BuildSystemTask(Task::Warning,
|
2023-01-13 12:38:22 +01:00
|
|
|
Tr::tr("Sys Root \"%1\" is not a directory.").arg(dir.toUserOutput()));
|
2021-09-29 18:18:56 +02:00
|
|
|
} else if (dir.dirEntries(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) {
|
2020-01-15 08:56:11 +01:00
|
|
|
result << BuildSystemTask(Task::Warning,
|
2023-01-13 12:38:22 +01:00
|
|
|
Tr::tr("Sys Root \"%1\" is empty.").arg(dir.toUserOutput()));
|
2012-07-27 15:43:00 +02:00
|
|
|
}
|
2012-04-24 15:49:09 +02:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspect *SysRootKitAspectFactory::createKitAspect(Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return nullptr);
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
return new Internal::SysRootKitAspectImpl(k, this);
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspectFactory::ItemList SysRootKitAspectFactory::toUserOutput(const Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
return {{Tr::tr("Sys Root"), SysRootKitAspect::sysRoot(k).toUserOutput()}};
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void SysRootKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const
|
2016-03-22 12:21:01 +01:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(kit, return);
|
|
|
|
|
|
2023-01-13 12:38:22 +01:00
|
|
|
expander->registerFileVariables("SysRoot", Tr::tr("Sys Root"), [kit] {
|
2021-06-01 18:18:02 +02:00
|
|
|
return SysRootKitAspect::sysRoot(kit);
|
2016-03-22 12:21:01 +01:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
Id SysRootKitAspect::id()
|
2013-09-09 17:10:41 +02:00
|
|
|
{
|
|
|
|
|
return "PE.Profile.SysRoot";
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
FilePath SysRootKitAspect::sysRoot(const Kit *k)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2012-09-03 18:31:44 +02:00
|
|
|
if (!k)
|
2023-08-01 20:52:58 +02:00
|
|
|
return {};
|
2019-01-07 12:15:40 +01:00
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
if (!k->value(SysRootKitAspect::id()).toString().isEmpty())
|
2023-08-22 09:48:25 +02:00
|
|
|
return FilePath::fromSettings(k->value(SysRootKitAspect::id()));
|
2019-01-07 12:15:40 +01:00
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
for (ToolChain *tc : ToolChainKitAspect::toolChains(k)) {
|
2019-01-07 12:15:40 +01:00
|
|
|
if (!tc->sysRoot().isEmpty())
|
2022-06-29 16:22:28 +02:00
|
|
|
return FilePath::fromString(tc->sysRoot());
|
2019-01-07 12:15:40 +01:00
|
|
|
}
|
2023-08-01 20:52:58 +02:00
|
|
|
return {};
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
void SysRootKitAspect::setSysRoot(Kit *k, const FilePath &v)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-01-07 12:15:40 +01:00
|
|
|
if (!k)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
for (ToolChain *tc : ToolChainKitAspect::toolChains(k)) {
|
2019-01-07 12:15:40 +01:00
|
|
|
if (!tc->sysRoot().isEmpty()) {
|
|
|
|
|
// It's the sysroot from toolchain, don't set it.
|
|
|
|
|
if (tc->sysRoot() == v.toString())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// We've changed the default toolchain sysroot, set it.
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-06 12:50:51 +01:00
|
|
|
k->setValue(SysRootKitAspect::id(), v.toString());
|
2013-07-24 16:22:37 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
const SysRootKitAspectFactory theSyRootKitAspectFactory;
|
|
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
// --------------------------------------------------------------------------
|
2019-02-06 12:50:51 +01:00
|
|
|
// ToolChainKitAspect:
|
2012-04-24 15:49:09 +02:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2019-02-06 15:04:17 +01:00
|
|
|
namespace Internal {
|
2023-08-10 15:47:26 +02:00
|
|
|
class ToolChainKitAspectImpl final : public KitAspect
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2023-08-16 10:20:01 +02:00
|
|
|
ToolChainKitAspectImpl(Kit *k, const KitAspectFactory *factory) : KitAspect(k, factory)
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
2021-04-07 18:55:21 +02:00
|
|
|
m_mainWidget = createSubWidget<QWidget>();
|
2019-02-06 15:04:17 +01:00
|
|
|
m_mainWidget->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
auto layout = new QGridLayout(m_mainWidget);
|
|
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
layout->setColumnStretch(1, 2);
|
|
|
|
|
|
2022-10-21 14:05:12 +02:00
|
|
|
const QList<Id> languageList = sorted(ToolChainManager::allLanguages(), [](Id l1, Id l2) {
|
2019-02-06 15:04:17 +01:00
|
|
|
return ToolChainManager::displayNameOfLanguageId(l1)
|
|
|
|
|
< ToolChainManager::displayNameOfLanguageId(l2);
|
|
|
|
|
});
|
|
|
|
|
QTC_ASSERT(!languageList.isEmpty(), return);
|
|
|
|
|
int row = 0;
|
2022-10-07 14:46:06 +02:00
|
|
|
for (Id l : std::as_const(languageList)) {
|
2019-02-06 15:04:17 +01:00
|
|
|
layout->addWidget(new QLabel(ToolChainManager::displayNameOfLanguageId(l) + ':'), row, 0);
|
|
|
|
|
auto cb = new QComboBox;
|
|
|
|
|
cb->setSizePolicy(QSizePolicy::Ignored, cb->sizePolicy().verticalPolicy());
|
2023-08-16 10:20:01 +02:00
|
|
|
cb->setToolTip(factory->description());
|
2019-02-06 15:04:17 +01:00
|
|
|
|
|
|
|
|
m_languageComboboxMap.insert(l, cb);
|
|
|
|
|
layout->addWidget(cb, row, 1);
|
|
|
|
|
++row;
|
|
|
|
|
|
2022-07-19 22:42:48 +02:00
|
|
|
connect(cb, &QComboBox::currentIndexChanged, this, [this, l](int idx) {
|
|
|
|
|
currentToolChainChanged(l, idx);
|
|
|
|
|
});
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
refresh();
|
|
|
|
|
|
2023-08-22 10:25:30 +02:00
|
|
|
setManagingPage(Constants::TOOLCHAIN_SETTINGS_PAGE_ID);
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
~ToolChainKitAspectImpl() override
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
|
|
|
|
delete m_mainWidget;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2023-08-22 09:54:38 +02:00
|
|
|
void addToLayoutImpl(Layouting::LayoutItem &builder) override
|
2021-04-07 18:55:21 +02:00
|
|
|
{
|
|
|
|
|
addMutableAction(m_mainWidget);
|
|
|
|
|
builder.addItem(m_mainWidget);
|
|
|
|
|
}
|
2019-02-06 15:04:17 +01:00
|
|
|
|
|
|
|
|
void refresh() override
|
|
|
|
|
{
|
2023-05-30 13:47:49 +02:00
|
|
|
IDeviceConstPtr device = BuildDeviceKitAspect::device(kit());
|
|
|
|
|
|
2022-07-22 11:19:45 +02:00
|
|
|
const GuardLocker locker(m_ignoreChanges);
|
2022-06-29 16:22:28 +02:00
|
|
|
const QList<Id> keys = m_languageComboboxMap.keys();
|
|
|
|
|
for (const Id l : keys) {
|
|
|
|
|
const Toolchains ltcList = ToolChainManager::toolchains(equal(&ToolChain::language, l));
|
2019-02-06 15:04:17 +01:00
|
|
|
|
|
|
|
|
QComboBox *cb = m_languageComboboxMap.value(l);
|
|
|
|
|
cb->clear();
|
2023-01-13 12:38:22 +01:00
|
|
|
cb->addItem(Tr::tr("<No compiler>"), QByteArray());
|
2019-02-06 15:04:17 +01:00
|
|
|
|
2023-05-30 13:47:49 +02:00
|
|
|
const QList<ToolChain *> same = Utils::filtered(ltcList, [device](ToolChain *tc) {
|
|
|
|
|
return tc->compilerCommand().isSameDevice(device->rootPath());
|
|
|
|
|
});
|
|
|
|
|
const QList<ToolChain *> other = Utils::filtered(ltcList, [device](ToolChain *tc) {
|
|
|
|
|
return !tc->compilerCommand().isSameDevice(device->rootPath());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (ToolChain *item : same)
|
|
|
|
|
cb->addItem(item->displayName(), item->id());
|
|
|
|
|
|
|
|
|
|
if (!same.isEmpty() && !other.isEmpty())
|
|
|
|
|
cb->insertSeparator(cb->count());
|
|
|
|
|
|
|
|
|
|
for (ToolChain *item : other)
|
|
|
|
|
cb->addItem(item->displayName(), item->id());
|
2019-02-06 15:04:17 +01:00
|
|
|
|
|
|
|
|
cb->setEnabled(cb->count() > 1 && !m_isReadOnly);
|
|
|
|
|
const int index = indexOf(cb, ToolChainKitAspect::toolChain(m_kit, l));
|
|
|
|
|
cb->setCurrentIndex(index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void makeReadOnly() override
|
|
|
|
|
{
|
|
|
|
|
m_isReadOnly = true;
|
2022-06-29 16:22:28 +02:00
|
|
|
const QList<Id> keys = m_languageComboboxMap.keys();
|
|
|
|
|
for (const Id l : keys) {
|
2019-02-06 15:04:17 +01:00
|
|
|
m_languageComboboxMap.value(l)->setEnabled(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
void currentToolChainChanged(Id language, int idx)
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
2022-07-22 11:19:45 +02:00
|
|
|
if (m_ignoreChanges.isLocked() || idx < 0)
|
2019-02-06 15:04:17 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const QByteArray id = m_languageComboboxMap.value(language)->itemData(idx).toByteArray();
|
|
|
|
|
ToolChain *tc = ToolChainManager::findToolChain(id);
|
|
|
|
|
QTC_ASSERT(!tc || tc->language() == language, return);
|
|
|
|
|
if (tc)
|
|
|
|
|
ToolChainKitAspect::setToolChain(m_kit, tc);
|
|
|
|
|
else
|
|
|
|
|
ToolChainKitAspect::clearToolChain(m_kit, language);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int indexOf(QComboBox *cb, const ToolChain *tc)
|
|
|
|
|
{
|
|
|
|
|
const QByteArray id = tc ? tc->id() : QByteArray();
|
|
|
|
|
for (int i = 0; i < cb->count(); ++i) {
|
|
|
|
|
if (id == cb->itemData(i).toByteArray())
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *m_mainWidget = nullptr;
|
2022-06-29 16:22:28 +02:00
|
|
|
QHash<Id, QComboBox *> m_languageComboboxMap;
|
2022-07-22 11:19:45 +02:00
|
|
|
Guard m_ignoreChanges;
|
2019-02-06 15:04:17 +01:00
|
|
|
bool m_isReadOnly = false;
|
|
|
|
|
};
|
|
|
|
|
} // namespace Internal
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
class ToolChainKitAspectFactory : public KitAspectFactory
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
ToolChainKitAspectFactory();
|
|
|
|
|
|
2023-08-18 14:12:19 +02:00
|
|
|
private:
|
2023-08-15 12:45:54 +02:00
|
|
|
Tasks validate(const Kit *k) const override;
|
|
|
|
|
void fix(Kit *k) override;
|
|
|
|
|
void setup(Kit *k) override;
|
|
|
|
|
|
|
|
|
|
KitAspect *createKitAspect(Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
QString displayNamePostfix(const Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
ItemList toUserOutput(const Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
void addToBuildEnvironment(const Kit *k, Environment &env) const override;
|
|
|
|
|
void addToRunEnvironment(const Kit *, Environment &) const override {}
|
|
|
|
|
|
|
|
|
|
void addToMacroExpander(Kit *kit, MacroExpander *expander) const override;
|
|
|
|
|
QList<OutputLineParser *> createOutputParsers(const Kit *k) const override;
|
|
|
|
|
QSet<Id> availableFeatures(const Kit *k) const override;
|
|
|
|
|
|
2023-08-18 14:12:19 +02:00
|
|
|
void onKitsLoaded() override;
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
void toolChainUpdated(ToolChain *tc);
|
|
|
|
|
void toolChainRemoved(ToolChain *tc);
|
|
|
|
|
};
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
ToolChainKitAspectFactory::ToolChainKitAspectFactory()
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-02-06 12:50:51 +01:00
|
|
|
setId(ToolChainKitAspect::id());
|
2023-01-13 12:38:22 +01:00
|
|
|
setDisplayName(Tr::tr("Compiler"));
|
|
|
|
|
setDescription(Tr::tr("The compiler to use for building.<br>"
|
2019-02-06 16:16:07 +01:00
|
|
|
"Make sure the compiler will produce binaries compatible "
|
|
|
|
|
"with the target device, Qt version and other libraries used."));
|
2013-08-28 18:57:25 +02:00
|
|
|
setPriority(30000);
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2016-07-20 16:24:32 +02:00
|
|
|
// language id -> tool chain id
|
2022-06-29 16:22:28 +02:00
|
|
|
static QMap<Id, QByteArray> defaultToolChainIds()
|
2016-07-20 16:24:32 +02:00
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
QMap<Id, QByteArray> toolChains;
|
2016-09-14 11:48:46 +02:00
|
|
|
const Abi abi = Abi::hostAbi();
|
2022-06-29 16:22:28 +02:00
|
|
|
const Toolchains tcList = ToolChainManager::toolchains(equal(&ToolChain::targetAbi, abi));
|
|
|
|
|
const QList<Id> languages = ToolChainManager::allLanguages();
|
|
|
|
|
for (Id l : languages) {
|
|
|
|
|
ToolChain *tc = findOrDefault(tcList, equal(&ToolChain::language, l));
|
2016-07-20 16:24:32 +02:00
|
|
|
toolChains.insert(l, tc ? tc->id() : QByteArray());
|
|
|
|
|
}
|
|
|
|
|
return toolChains;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-29 09:30:38 +02:00
|
|
|
static Store defaultToolChainValue()
|
2016-07-20 16:24:32 +02:00
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
const QMap<Id, QByteArray> toolChains = defaultToolChainIds();
|
2023-08-29 09:30:38 +02:00
|
|
|
Store result;
|
2016-07-20 16:24:32 +02:00
|
|
|
auto end = toolChains.end();
|
2023-08-29 09:30:38 +02:00
|
|
|
for (auto it = toolChains.begin(); it != end; ++it)
|
|
|
|
|
result.insert(it.key().toKey(), it.value());
|
2016-07-20 16:24:32 +02:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
Tasks ToolChainKitAspectFactory::validate(const Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-05-27 16:09:44 +02:00
|
|
|
Tasks result;
|
2013-03-21 12:27:18 +01:00
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
const QList<ToolChain*> tcList = ToolChainKitAspect::toolChains(k);
|
2016-07-12 16:27:45 +02:00
|
|
|
if (tcList.isEmpty()) {
|
2020-01-15 08:56:11 +01:00
|
|
|
result << BuildSystemTask(Task::Warning, ToolChainKitAspect::msgNoToolChainInTarget());
|
2013-03-21 12:27:18 +01:00
|
|
|
} else {
|
2016-07-12 16:33:19 +02:00
|
|
|
QSet<Abi> targetAbis;
|
2022-05-03 16:48:36 +02:00
|
|
|
for (const ToolChain *tc : tcList) {
|
2016-07-12 16:33:19 +02:00
|
|
|
targetAbis.insert(tc->targetAbi());
|
2016-07-12 16:27:45 +02:00
|
|
|
result << tc->validateKit(k);
|
2016-07-12 16:33:19 +02:00
|
|
|
}
|
|
|
|
|
if (targetAbis.count() != 1) {
|
2020-01-15 08:56:11 +01:00
|
|
|
result << BuildSystemTask(Task::Error,
|
2023-01-13 12:38:22 +01:00
|
|
|
Tr::tr("Compilers produce code for different ABIs: %1")
|
2020-01-15 08:56:11 +01:00
|
|
|
.arg(Utils::transform<QList>(targetAbis, &Abi::toString).join(", ")));
|
2016-07-12 16:33:19 +02:00
|
|
|
}
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void ToolChainKitAspectFactory::fix(Kit *k)
|
2012-10-11 13:47:23 +02:00
|
|
|
{
|
2013-08-29 13:14:19 +02:00
|
|
|
QTC_ASSERT(ToolChainManager::isLoaded(), return);
|
2022-06-29 16:22:28 +02:00
|
|
|
const QList<Id> languages = ToolChainManager::allLanguages();
|
|
|
|
|
for (const Id l : languages) {
|
2023-08-10 15:47:26 +02:00
|
|
|
const QByteArray tcId = ToolChainKitAspect::toolChainId(k, l);
|
2018-04-19 15:59:05 +02:00
|
|
|
if (!tcId.isEmpty() && !ToolChainManager::findToolChain(tcId)) {
|
|
|
|
|
qWarning("Tool chain set up in kit \"%s\" for \"%s\" not found.",
|
2016-12-09 13:53:09 +01:00
|
|
|
qPrintable(k->displayName()),
|
2016-12-16 00:43:14 +01:00
|
|
|
qPrintable(ToolChainManager::displayNameOfLanguageId(l)));
|
2023-08-10 15:47:26 +02:00
|
|
|
ToolChainKitAspect::clearToolChain(k, l); // make sure to clear out no longer known tool chains
|
2016-07-12 16:27:45 +02:00
|
|
|
}
|
|
|
|
|
}
|
2012-10-11 13:47:23 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
static Id findLanguage(const QString &ls)
|
2016-12-16 00:43:14 +01:00
|
|
|
{
|
|
|
|
|
QString lsUpper = ls.toUpper();
|
|
|
|
|
return Utils::findOrDefault(ToolChainManager::allLanguages(),
|
2022-06-29 16:22:28 +02:00
|
|
|
[lsUpper](Id l) { return lsUpper == l.toString().toUpper(); });
|
2016-12-16 00:43:14 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void ToolChainKitAspectFactory::setup(Kit *k)
|
2013-01-22 12:47:07 +01:00
|
|
|
{
|
2013-08-29 13:14:19 +02:00
|
|
|
QTC_ASSERT(ToolChainManager::isLoaded(), return);
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return);
|
|
|
|
|
|
2023-08-29 09:30:38 +02:00
|
|
|
Store value = storeFromVariant(k->value(id()));
|
2021-08-09 14:41:52 +02:00
|
|
|
bool lockToolchains = k->isSdkProvided() && !value.isEmpty();
|
2019-03-12 16:50:39 +01:00
|
|
|
if (value.empty())
|
2023-08-29 09:30:38 +02:00
|
|
|
value = defaultToolChainValue();
|
2016-07-15 13:15:27 +02:00
|
|
|
|
|
|
|
|
for (auto i = value.constBegin(); i != value.constEnd(); ++i) {
|
2023-08-29 09:30:38 +02:00
|
|
|
Id l = findLanguage(stringFromKey(i.key()));
|
2016-12-16 00:43:14 +01:00
|
|
|
|
2021-08-09 14:41:52 +02:00
|
|
|
if (!l.isValid()) {
|
|
|
|
|
lockToolchains = false;
|
2016-07-15 13:15:27 +02:00
|
|
|
continue;
|
2021-08-09 14:41:52 +02:00
|
|
|
}
|
2016-07-15 13:15:27 +02:00
|
|
|
|
|
|
|
|
const QByteArray id = i.value().toByteArray();
|
|
|
|
|
ToolChain *tc = ToolChainManager::findToolChain(id);
|
|
|
|
|
if (tc)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// ID is not found: Might be an ABI string...
|
2021-08-09 14:41:52 +02:00
|
|
|
lockToolchains = false;
|
2016-07-15 13:15:27 +02:00
|
|
|
const QString abi = QString::fromUtf8(id);
|
2023-05-30 13:47:49 +02:00
|
|
|
const Toolchains possibleTcs = ToolChainManager::toolchains([abi, l](const ToolChain *t) {
|
|
|
|
|
return t->targetAbi().toString() == abi && t->language() == l;
|
|
|
|
|
});
|
2021-10-22 15:00:54 +02:00
|
|
|
ToolChain *bestTc = nullptr;
|
|
|
|
|
for (ToolChain *tc : possibleTcs) {
|
|
|
|
|
if (!bestTc || tc->priority() > bestTc->priority())
|
|
|
|
|
bestTc = tc;
|
|
|
|
|
}
|
|
|
|
|
if (bestTc)
|
2023-08-10 15:47:26 +02:00
|
|
|
ToolChainKitAspect::setToolChain(k, bestTc);
|
2016-12-12 17:13:29 +01:00
|
|
|
else
|
2023-08-10 15:47:26 +02:00
|
|
|
ToolChainKitAspect::clearToolChain(k, l);
|
2013-01-22 12:47:07 +01:00
|
|
|
}
|
2021-08-09 14:41:52 +02:00
|
|
|
|
|
|
|
|
k->setSticky(id(), lockToolchains);
|
2013-01-22 12:47:07 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspect *ToolChainKitAspectFactory::createKitAspect(Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return nullptr);
|
2023-08-10 15:47:26 +02:00
|
|
|
return new Internal::ToolChainKitAspectImpl(k, this);
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
QString ToolChainKitAspectFactory::displayNamePostfix(const Kit *k) const
|
2012-08-07 13:09:56 +02:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
ToolChain *tc = ToolChainKitAspect::cxxToolChain(k);
|
2012-08-07 13:09:56 +02:00
|
|
|
return tc ? tc->displayName() : QString();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspectFactory::ItemList ToolChainKitAspectFactory::toUserOutput(const Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
ToolChain *tc = ToolChainKitAspect::cxxToolChain(k);
|
2023-01-13 12:38:22 +01:00
|
|
|
return {{Tr::tr("Compiler"), tc ? tc->displayName() : Tr::tr("None")}};
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void ToolChainKitAspectFactory::addToBuildEnvironment(const Kit *k, Environment &env) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
ToolChain *tc = ToolChainKitAspect::cxxToolChain(k);
|
2012-04-24 15:49:09 +02:00
|
|
|
if (tc)
|
|
|
|
|
tc->addToEnvironment(env);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void ToolChainKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const
|
2014-11-17 17:46:19 +01:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(kit, return);
|
|
|
|
|
|
2016-07-15 11:15:27 +02:00
|
|
|
// Compatibility with Qt Creator < 4.2:
|
2023-01-13 12:38:22 +01:00
|
|
|
expander->registerVariable("Compiler:Name", Tr::tr("Compiler"),
|
2020-02-18 18:25:26 +01:00
|
|
|
[kit] {
|
2023-08-10 15:47:26 +02:00
|
|
|
const ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit);
|
2023-01-13 12:38:22 +01:00
|
|
|
return tc ? tc->displayName() : Tr::tr("None");
|
2014-11-17 17:46:19 +01:00
|
|
|
});
|
2016-03-16 11:56:28 +01:00
|
|
|
|
2023-01-13 12:38:22 +01:00
|
|
|
expander->registerVariable("Compiler:Executable", Tr::tr("Path to the compiler executable"),
|
2020-02-18 18:25:26 +01:00
|
|
|
[kit] {
|
2023-08-10 15:47:26 +02:00
|
|
|
const ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit);
|
2021-06-17 08:59:06 +02:00
|
|
|
return tc ? tc->compilerCommand().path() : QString();
|
2016-03-16 11:56:28 +01:00
|
|
|
});
|
2016-07-15 11:15:27 +02:00
|
|
|
|
2021-06-17 08:59:06 +02:00
|
|
|
// After 4.2
|
2023-01-13 12:38:22 +01:00
|
|
|
expander->registerPrefix("Compiler:Name", Tr::tr("Compiler for different languages"),
|
2020-02-18 18:25:26 +01:00
|
|
|
[kit](const QString &ls) {
|
2023-08-10 15:47:26 +02:00
|
|
|
const ToolChain *tc = ToolChainKitAspect::toolChain(kit, findLanguage(ls));
|
2023-01-13 12:38:22 +01:00
|
|
|
return tc ? tc->displayName() : Tr::tr("None");
|
2016-07-15 11:15:27 +02:00
|
|
|
});
|
2023-01-13 12:38:22 +01:00
|
|
|
expander->registerPrefix("Compiler:Executable", Tr::tr("Compiler executable for different languages"),
|
2020-02-18 18:25:26 +01:00
|
|
|
[kit](const QString &ls) {
|
2023-08-10 15:47:26 +02:00
|
|
|
const ToolChain *tc = ToolChainKitAspect::toolChain(kit, findLanguage(ls));
|
2021-06-17 08:59:06 +02:00
|
|
|
return tc ? tc->compilerCommand().path() : QString();
|
2016-07-15 11:15:27 +02:00
|
|
|
});
|
2014-11-17 17:46:19 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
QList<OutputLineParser *> ToolChainKitAspectFactory::createOutputParsers(const Kit *k) const
|
2012-11-02 12:45:09 +01:00
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
for (const Id langId : {Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID}) {
|
2023-08-10 15:47:26 +02:00
|
|
|
if (const ToolChain * const tc = ToolChainKitAspect::toolChain(k, langId))
|
2020-04-15 14:59:51 +02:00
|
|
|
return tc->createOutputParsers();
|
2019-02-07 15:20:58 +01:00
|
|
|
}
|
2020-04-08 17:45:39 +02:00
|
|
|
return {};
|
2012-11-02 12:45:09 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
QSet<Id> ToolChainKitAspectFactory::availableFeatures(const Kit *k) const
|
2017-02-07 00:26:51 +01:00
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
QSet<Id> result;
|
2023-08-10 15:47:26 +02:00
|
|
|
for (ToolChain *tc : ToolChainKitAspect::toolChains(k))
|
2017-02-07 00:26:51 +01:00
|
|
|
result.insert(tc->typeId().withPrefix("ToolChain."));
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
Id ToolChainKitAspect::id()
|
2013-09-09 17:10:41 +02:00
|
|
|
{
|
2023-08-28 17:32:11 +02:00
|
|
|
// "PE.Profile.ToolChain" until 4.2
|
|
|
|
|
// "PE.Profile.ToolChains" temporarily before 4.3 (May 2017)
|
|
|
|
|
return "PE.Profile.ToolChainsV3";
|
2013-09-09 17:10:41 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
QByteArray ToolChainKitAspect::toolChainId(const Kit *k, Id language)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(ToolChainManager::isLoaded(), return nullptr);
|
2012-09-03 18:31:44 +02:00
|
|
|
if (!k)
|
2023-08-01 20:52:58 +02:00
|
|
|
return {};
|
2023-08-29 09:30:38 +02:00
|
|
|
Store value = storeFromVariant(k->value(ToolChainKitAspect::id()));
|
|
|
|
|
return value.value(language.toKey(), QByteArray()).toByteArray();
|
2018-04-19 15:59:05 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
ToolChain *ToolChainKitAspect::toolChain(const Kit *k, Id language)
|
2018-04-19 15:59:05 +02:00
|
|
|
{
|
|
|
|
|
return ToolChainManager::findToolChain(toolChainId(k, language));
|
2016-07-12 16:27:45 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-18 18:25:26 +01:00
|
|
|
ToolChain *ToolChainKitAspect::cToolChain(const Kit *k)
|
|
|
|
|
{
|
|
|
|
|
return ToolChainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::C_LANGUAGE_ID));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ToolChain *ToolChainKitAspect::cxxToolChain(const Kit *k)
|
|
|
|
|
{
|
|
|
|
|
return ToolChainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
QList<ToolChain *> ToolChainKitAspect::toolChains(const Kit *k)
|
2016-07-12 16:27:45 +02:00
|
|
|
{
|
2023-08-01 21:19:48 +02:00
|
|
|
QTC_ASSERT(k, return {});
|
2018-02-12 12:49:22 +01:00
|
|
|
|
2023-08-29 09:30:38 +02:00
|
|
|
const Store value = storeFromVariant(k->value(ToolChainKitAspect::id()));
|
2016-07-12 16:27:45 +02:00
|
|
|
const QList<ToolChain *> tcList
|
2021-09-29 18:18:56 +02:00
|
|
|
= transform<QList>(ToolChainManager::allLanguages(), [&value](Id l) {
|
2023-08-29 09:30:38 +02:00
|
|
|
return ToolChainManager::findToolChain(value.value(l.toKey()).toByteArray());
|
2021-09-29 18:18:56 +02:00
|
|
|
});
|
|
|
|
|
return filtered(tcList, [](ToolChain *tc) { return tc; });
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
void ToolChainKitAspect::setToolChain(Kit *k, ToolChain *tc)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2016-07-12 16:27:45 +02:00
|
|
|
QTC_ASSERT(tc, return);
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return);
|
2023-08-29 09:30:38 +02:00
|
|
|
Store result = storeFromVariant(k->value(ToolChainKitAspect::id()));
|
|
|
|
|
result.insert(tc->language().toKey(), tc->id());
|
2016-12-16 00:43:14 +01:00
|
|
|
|
2023-08-29 09:30:38 +02:00
|
|
|
k->setValue(id(), variantFromStore(result));
|
2016-07-12 16:27:45 +02:00
|
|
|
}
|
|
|
|
|
|
2017-08-04 13:56:57 +02:00
|
|
|
/**
|
2019-02-06 12:50:51 +01:00
|
|
|
* @brief ToolChainKitAspect::setAllToolChainsToMatch
|
2017-08-04 13:56:57 +02:00
|
|
|
*
|
|
|
|
|
* Set up all toolchains to be similar to the one toolchain provided. Similar ideally means
|
|
|
|
|
* that all toolchains use the "same" compiler from the same installation, but we will
|
|
|
|
|
* settle for a toolchain with a matching API instead.
|
|
|
|
|
*
|
|
|
|
|
* @param k The kit to set up
|
|
|
|
|
* @param tc The toolchain to match other languages for.
|
|
|
|
|
*/
|
2019-02-06 12:50:51 +01:00
|
|
|
void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, ToolChain *tc)
|
2017-08-04 13:56:57 +02:00
|
|
|
{
|
|
|
|
|
QTC_ASSERT(tc, return);
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return);
|
2017-08-04 13:56:57 +02:00
|
|
|
|
2022-01-18 18:40:41 +01:00
|
|
|
const Toolchains allTcList = ToolChainManager::toolchains();
|
2017-08-04 13:56:57 +02:00
|
|
|
QTC_ASSERT(allTcList.contains(tc), return);
|
|
|
|
|
|
2023-08-29 09:30:38 +02:00
|
|
|
Store result = storeFromVariant(k->value(ToolChainKitAspect::id()));
|
|
|
|
|
result.insert(tc->language().toKey(), tc->id());
|
2017-08-04 13:56:57 +02:00
|
|
|
|
2021-09-29 18:18:56 +02:00
|
|
|
for (const Id l : ToolChainManager::allLanguages()) {
|
2017-08-04 13:56:57 +02:00
|
|
|
if (l == tc->language())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
ToolChain *match = nullptr;
|
|
|
|
|
ToolChain *bestMatch = nullptr;
|
|
|
|
|
for (ToolChain *other : allTcList) {
|
|
|
|
|
if (!other->isValid() || other->language() != l)
|
|
|
|
|
continue;
|
|
|
|
|
if (other->targetAbi() == tc->targetAbi())
|
|
|
|
|
match = other;
|
|
|
|
|
if (match == other
|
|
|
|
|
&& other->compilerCommand().parentDir() == tc->compilerCommand().parentDir()) {
|
|
|
|
|
bestMatch = other;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (bestMatch)
|
2023-08-29 09:30:38 +02:00
|
|
|
result.insert(l.toKey(), bestMatch->id());
|
2017-08-04 13:56:57 +02:00
|
|
|
else if (match)
|
2023-08-29 09:30:38 +02:00
|
|
|
result.insert(l.toKey(), match->id());
|
2017-08-04 13:56:57 +02:00
|
|
|
else
|
2023-08-29 09:30:38 +02:00
|
|
|
result.insert(l.toKey(), QByteArray());
|
2017-08-04 13:56:57 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-29 09:30:38 +02:00
|
|
|
k->setValue(id(), variantFromStore(result));
|
2017-08-04 13:56:57 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-29 18:18:56 +02:00
|
|
|
void ToolChainKitAspect::clearToolChain(Kit *k, Id language)
|
2016-07-12 16:27:45 +02:00
|
|
|
{
|
2016-12-16 00:43:14 +01:00
|
|
|
QTC_ASSERT(language.isValid(), return);
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return);
|
2016-07-12 16:27:45 +02:00
|
|
|
|
2023-08-29 09:30:38 +02:00
|
|
|
Store result = storeFromVariant(k->value(ToolChainKitAspect::id()));
|
|
|
|
|
result.insert(language.toKey(), QByteArray());
|
|
|
|
|
k->setValue(id(), variantFromStore(result));
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
Abi ToolChainKitAspect::targetAbi(const Kit *k)
|
2016-07-13 10:40:05 +02:00
|
|
|
{
|
2022-05-03 16:48:36 +02:00
|
|
|
const QList<ToolChain *> tcList = toolChains(k);
|
2016-07-13 10:40:05 +02:00
|
|
|
// Find the best possible ABI for all the tool chains...
|
|
|
|
|
Abi cxxAbi;
|
|
|
|
|
QHash<Abi, int> abiCount;
|
2022-05-03 16:48:36 +02:00
|
|
|
for (ToolChain *tc : tcList) {
|
2016-07-13 10:40:05 +02:00
|
|
|
Abi ta = tc->targetAbi();
|
2021-09-29 18:18:56 +02:00
|
|
|
if (tc->language() == Id(Constants::CXX_LANGUAGE_ID))
|
2016-07-13 10:40:05 +02:00
|
|
|
cxxAbi = tc->targetAbi();
|
|
|
|
|
abiCount[ta] = (abiCount.contains(ta) ? abiCount[ta] + 1 : 1);
|
|
|
|
|
}
|
|
|
|
|
QVector<Abi> candidates;
|
|
|
|
|
int count = -1;
|
|
|
|
|
candidates.reserve(tcList.count());
|
|
|
|
|
for (auto i = abiCount.begin(); i != abiCount.end(); ++i) {
|
|
|
|
|
if (i.value() > count) {
|
|
|
|
|
candidates.clear();
|
|
|
|
|
candidates.append(i.key());
|
|
|
|
|
count = i.value();
|
|
|
|
|
} else if (i.value() == count) {
|
|
|
|
|
candidates.append(i.key());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Found a good candidate:
|
|
|
|
|
if (candidates.isEmpty())
|
|
|
|
|
return Abi::hostAbi();
|
|
|
|
|
if (candidates.contains(cxxAbi)) // Use Cxx compiler as a tie breaker
|
|
|
|
|
return cxxAbi;
|
|
|
|
|
return candidates.at(0); // Use basically a random Abi...
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
QString ToolChainKitAspect::msgNoToolChainInTarget()
|
2012-07-27 15:43:00 +02:00
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
return Tr::tr("No compiler set in kit.");
|
2012-07-27 15:43:00 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-18 14:12:19 +02:00
|
|
|
void ToolChainKitAspectFactory::onKitsLoaded()
|
2012-10-17 17:27:17 +02:00
|
|
|
{
|
2023-08-18 14:12:19 +02:00
|
|
|
for (Kit *k : KitManager::kits())
|
2013-02-28 15:07:01 +01:00
|
|
|
fix(k);
|
|
|
|
|
|
2016-01-29 16:38:37 +02:00
|
|
|
connect(ToolChainManager::instance(), &ToolChainManager::toolChainRemoved,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &ToolChainKitAspectFactory::toolChainRemoved);
|
2016-01-29 16:38:37 +02:00
|
|
|
connect(ToolChainManager::instance(), &ToolChainManager::toolChainUpdated,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &ToolChainKitAspectFactory::toolChainUpdated);
|
2013-02-28 15:07:01 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void ToolChainKitAspectFactory::toolChainUpdated(ToolChain *tc)
|
2013-02-28 15:07:01 +01:00
|
|
|
{
|
2019-08-13 14:03:12 +02:00
|
|
|
for (Kit *k : KitManager::kits()) {
|
2023-08-10 15:47:26 +02:00
|
|
|
if (ToolChainKitAspect::toolChain(k, tc->language()) == tc)
|
2019-08-13 14:03:12 +02:00
|
|
|
notifyAboutUpdate(k);
|
|
|
|
|
}
|
2013-02-28 15:07:01 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void ToolChainKitAspectFactory::toolChainRemoved(ToolChain *tc)
|
2012-10-17 17:27:17 +02:00
|
|
|
{
|
2019-07-23 10:58:00 +02:00
|
|
|
Q_UNUSED(tc)
|
2023-08-18 14:12:19 +02:00
|
|
|
for (Kit *k : KitManager::kits())
|
2013-02-28 15:07:01 +01:00
|
|
|
fix(k);
|
2012-10-17 17:27:17 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
const ToolChainKitAspectFactory thsToolChainKitAspectFactory;
|
|
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
// --------------------------------------------------------------------------
|
2019-02-06 12:50:51 +01:00
|
|
|
// DeviceTypeKitAspect:
|
2012-04-24 15:49:09 +02:00
|
|
|
// --------------------------------------------------------------------------
|
2019-02-06 15:04:17 +01:00
|
|
|
namespace Internal {
|
2023-08-10 15:47:26 +02:00
|
|
|
class DeviceTypeKitAspectImpl final : public KitAspect
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2023-08-16 10:20:01 +02:00
|
|
|
DeviceTypeKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
|
|
|
|
|
: KitAspect(workingCopy, factory), m_comboBox(createSubWidget<QComboBox>())
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
|
|
|
|
for (IDeviceFactory *factory : IDeviceFactory::allDeviceFactories())
|
|
|
|
|
m_comboBox->addItem(factory->displayName(), factory->deviceType().toSetting());
|
2023-08-16 10:20:01 +02:00
|
|
|
m_comboBox->setToolTip(factory->description());
|
2019-02-06 15:04:17 +01:00
|
|
|
refresh();
|
2022-07-19 22:42:48 +02:00
|
|
|
connect(m_comboBox, &QComboBox::currentIndexChanged,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &DeviceTypeKitAspectImpl::currentTypeChanged);
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
~DeviceTypeKitAspectImpl() override { delete m_comboBox; }
|
2019-02-06 15:04:17 +01:00
|
|
|
|
|
|
|
|
private:
|
2023-08-22 09:54:38 +02:00
|
|
|
void addToLayoutImpl(Layouting::LayoutItem &builder) override
|
2021-04-07 18:55:21 +02:00
|
|
|
{
|
|
|
|
|
addMutableAction(m_comboBox);
|
|
|
|
|
builder.addItem(m_comboBox);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 15:04:17 +01:00
|
|
|
void makeReadOnly() override { m_comboBox->setEnabled(false); }
|
|
|
|
|
|
|
|
|
|
void refresh() override
|
|
|
|
|
{
|
2021-09-29 18:18:56 +02:00
|
|
|
Id devType = DeviceTypeKitAspect::deviceTypeId(m_kit);
|
2019-02-06 15:04:17 +01:00
|
|
|
if (!devType.isValid())
|
|
|
|
|
m_comboBox->setCurrentIndex(-1);
|
|
|
|
|
for (int i = 0; i < m_comboBox->count(); ++i) {
|
|
|
|
|
if (m_comboBox->itemData(i) == devType.toSetting()) {
|
|
|
|
|
m_comboBox->setCurrentIndex(i);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void currentTypeChanged(int idx)
|
|
|
|
|
{
|
2021-09-29 18:18:56 +02:00
|
|
|
Id type = idx < 0 ? Id() : Id::fromSetting(m_comboBox->itemData(idx));
|
2019-02-06 15:04:17 +01:00
|
|
|
DeviceTypeKitAspect::setDeviceTypeId(m_kit, type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QComboBox *m_comboBox;
|
|
|
|
|
};
|
|
|
|
|
} // namespace Internal
|
2012-04-24 15:49:09 +02:00
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
class DeviceTypeKitAspectFactory : public KitAspectFactory
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
DeviceTypeKitAspectFactory();
|
|
|
|
|
|
|
|
|
|
void setup(Kit *k) override;
|
|
|
|
|
Tasks validate(const Kit *k) const override;
|
|
|
|
|
KitAspect *createKitAspect(Kit *k) const override;
|
|
|
|
|
ItemList toUserOutput(const Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
QSet<Id> supportedPlatforms(const Kit *k) const override;
|
|
|
|
|
QSet<Id> availableFeatures(const Kit *k) const override;
|
|
|
|
|
};
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
DeviceTypeKitAspectFactory::DeviceTypeKitAspectFactory()
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-02-06 12:50:51 +01:00
|
|
|
setId(DeviceTypeKitAspect::id());
|
2023-05-09 16:27:47 +02:00
|
|
|
setDisplayName(Tr::tr("Run device type"));
|
2023-01-13 12:38:22 +01:00
|
|
|
setDescription(Tr::tr("The type of device to run applications on."));
|
2013-08-28 18:57:25 +02:00
|
|
|
setPriority(33000);
|
2019-02-05 14:42:30 +01:00
|
|
|
makeEssential();
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void DeviceTypeKitAspectFactory::setup(Kit *k)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-05-06 14:55:34 +02:00
|
|
|
if (k && !k->hasValue(id()))
|
2019-03-12 16:50:39 +01:00
|
|
|
k->setValue(id(), QByteArray(Constants::DESKTOP_DEVICE_TYPE));
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
Tasks DeviceTypeKitAspectFactory::validate(const Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-07-23 10:58:00 +02:00
|
|
|
Q_UNUSED(k)
|
2019-05-27 16:09:44 +02:00
|
|
|
return {};
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspect *DeviceTypeKitAspectFactory::createKitAspect(Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return nullptr);
|
2023-08-10 15:47:26 +02:00
|
|
|
return new Internal::DeviceTypeKitAspectImpl(k, this);
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspectFactory::ItemList DeviceTypeKitAspectFactory::toUserOutput(const Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return {});
|
2023-08-10 15:47:26 +02:00
|
|
|
Id type = DeviceTypeKitAspect::deviceTypeId(k);
|
2023-01-13 12:38:22 +01:00
|
|
|
QString typeDisplayName = Tr::tr("Unknown device type");
|
2012-04-24 15:49:09 +02:00
|
|
|
if (type.isValid()) {
|
2018-10-04 19:08:16 +02:00
|
|
|
if (IDeviceFactory *factory = IDeviceFactory::find(type))
|
|
|
|
|
typeDisplayName = factory->displayName();
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
2023-01-13 12:38:22 +01:00
|
|
|
return {{Tr::tr("Device type"), typeDisplayName}};
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-29 18:18:56 +02:00
|
|
|
const Id DeviceTypeKitAspect::id()
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2013-09-09 17:10:41 +02:00
|
|
|
return "PE.Profile.DeviceType";
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-29 18:18:56 +02:00
|
|
|
const Id DeviceTypeKitAspect::deviceTypeId(const Kit *k)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2021-09-29 18:18:56 +02:00
|
|
|
return k ? Id::fromSetting(k->value(DeviceTypeKitAspect::id())) : Id();
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-29 18:18:56 +02:00
|
|
|
void DeviceTypeKitAspect::setDeviceTypeId(Kit *k, Id type)
|
2013-07-24 16:22:37 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return);
|
2019-02-06 12:50:51 +01:00
|
|
|
k->setValue(DeviceTypeKitAspect::id(), type.toSetting());
|
2013-07-24 16:22:37 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
QSet<Id> DeviceTypeKitAspectFactory::supportedPlatforms(const Kit *k) const
|
2015-11-27 16:14:14 +01:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
return {DeviceTypeKitAspect::deviceTypeId(k)};
|
2015-11-27 16:14:14 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
QSet<Id> DeviceTypeKitAspectFactory::availableFeatures(const Kit *k) const
|
2014-07-29 15:15:27 +02:00
|
|
|
{
|
2021-09-29 18:18:56 +02:00
|
|
|
Id id = DeviceTypeKitAspect::deviceTypeId(k);
|
2014-07-29 15:15:27 +02:00
|
|
|
if (id.isValid())
|
2017-02-22 15:09:35 +01:00
|
|
|
return {id.withPrefix("DeviceType.")};
|
2021-09-29 18:18:56 +02:00
|
|
|
return {};
|
2014-07-29 15:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
2023-09-26 13:59:23 +02:00
|
|
|
const DeviceTypeKitAspectFactory theDeviceTypeKitAspectFactory;
|
|
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
// --------------------------------------------------------------------------
|
2019-02-06 12:50:51 +01:00
|
|
|
// DeviceKitAspect:
|
2012-04-24 15:49:09 +02:00
|
|
|
// --------------------------------------------------------------------------
|
2019-02-06 15:04:17 +01:00
|
|
|
namespace Internal {
|
2023-08-10 15:47:26 +02:00
|
|
|
class DeviceKitAspectImpl final : public KitAspect
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2023-08-16 10:20:01 +02:00
|
|
|
DeviceKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
|
|
|
|
|
: KitAspect(workingCopy, factory),
|
2021-04-07 18:55:21 +02:00
|
|
|
m_comboBox(createSubWidget<QComboBox>()),
|
2019-02-06 15:04:17 +01:00
|
|
|
m_model(new DeviceManagerModel(DeviceManager::instance()))
|
|
|
|
|
{
|
2023-08-22 10:25:30 +02:00
|
|
|
setManagingPage(Constants::DEVICE_SETTINGS_PAGE_ID);
|
2021-12-08 23:21:36 +01:00
|
|
|
m_comboBox->setSizePolicy(QSizePolicy::Preferred,
|
|
|
|
|
m_comboBox->sizePolicy().verticalPolicy());
|
2019-02-06 15:04:17 +01:00
|
|
|
m_comboBox->setModel(m_model);
|
2021-12-08 23:21:36 +01:00
|
|
|
m_comboBox->setMinimumContentsLength(16); // Don't stretch too much for Kit Page
|
2019-02-06 15:04:17 +01:00
|
|
|
refresh();
|
2023-08-16 10:20:01 +02:00
|
|
|
m_comboBox->setToolTip(factory->description());
|
2019-02-06 15:04:17 +01:00
|
|
|
|
|
|
|
|
connect(m_model, &QAbstractItemModel::modelAboutToBeReset,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &DeviceKitAspectImpl::modelAboutToReset);
|
2019-02-06 15:04:17 +01:00
|
|
|
connect(m_model, &QAbstractItemModel::modelReset,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &DeviceKitAspectImpl::modelReset);
|
2022-07-19 22:42:48 +02:00
|
|
|
connect(m_comboBox, &QComboBox::currentIndexChanged,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &DeviceKitAspectImpl::currentDeviceChanged);
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
~DeviceKitAspectImpl() override
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
|
|
|
|
delete m_comboBox;
|
|
|
|
|
delete m_model;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2023-08-22 09:54:38 +02:00
|
|
|
void addToLayoutImpl(Layouting::LayoutItem &builder) override
|
2021-04-07 18:55:21 +02:00
|
|
|
{
|
|
|
|
|
addMutableAction(m_comboBox);
|
|
|
|
|
builder.addItem(m_comboBox);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 15:04:17 +01:00
|
|
|
void makeReadOnly() override { m_comboBox->setEnabled(false); }
|
|
|
|
|
|
|
|
|
|
void refresh() override
|
|
|
|
|
{
|
|
|
|
|
m_model->setTypeFilter(DeviceTypeKitAspect::deviceTypeId(m_kit));
|
|
|
|
|
m_comboBox->setCurrentIndex(m_model->indexOf(DeviceKitAspect::device(m_kit)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void modelAboutToReset()
|
|
|
|
|
{
|
|
|
|
|
m_selectedId = m_model->deviceId(m_comboBox->currentIndex());
|
2022-07-22 11:54:45 +02:00
|
|
|
m_ignoreChanges.lock();
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void modelReset()
|
|
|
|
|
{
|
|
|
|
|
m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId));
|
2022-07-22 11:54:45 +02:00
|
|
|
m_ignoreChanges.unlock();
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void currentDeviceChanged()
|
|
|
|
|
{
|
2022-07-22 11:54:45 +02:00
|
|
|
if (m_ignoreChanges.isLocked())
|
2019-02-06 15:04:17 +01:00
|
|
|
return;
|
|
|
|
|
DeviceKitAspect::setDeviceId(m_kit, m_model->deviceId(m_comboBox->currentIndex()));
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-22 11:54:45 +02:00
|
|
|
Guard m_ignoreChanges;
|
2019-02-06 15:04:17 +01:00
|
|
|
QComboBox *m_comboBox;
|
|
|
|
|
DeviceManagerModel *m_model;
|
2022-06-29 16:22:28 +02:00
|
|
|
Id m_selectedId;
|
2019-02-06 15:04:17 +01:00
|
|
|
};
|
|
|
|
|
} // namespace Internal
|
2012-04-24 15:49:09 +02:00
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
class DeviceKitAspectFactory : public KitAspectFactory
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
DeviceKitAspectFactory();
|
|
|
|
|
|
2023-08-18 14:12:19 +02:00
|
|
|
private:
|
2023-08-15 12:45:54 +02:00
|
|
|
Tasks validate(const Kit *k) const override;
|
|
|
|
|
void fix(Kit *k) override;
|
|
|
|
|
void setup(Kit *k) override;
|
|
|
|
|
|
|
|
|
|
KitAspect *createKitAspect(Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
QString displayNamePostfix(const Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
ItemList toUserOutput(const Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
void addToMacroExpander(Kit *kit, MacroExpander *expander) const override;
|
|
|
|
|
|
|
|
|
|
QVariant defaultValue(const Kit *k) const;
|
|
|
|
|
|
2023-08-18 14:12:19 +02:00
|
|
|
void onKitsLoaded() override;
|
2023-08-15 12:45:54 +02:00
|
|
|
void deviceUpdated(Id dataId);
|
|
|
|
|
void devicesChanged();
|
|
|
|
|
void kitUpdated(Kit *k);
|
|
|
|
|
};
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
DeviceKitAspectFactory::DeviceKitAspectFactory()
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-02-06 12:50:51 +01:00
|
|
|
setId(DeviceKitAspect::id());
|
2023-05-09 16:27:47 +02:00
|
|
|
setDisplayName(Tr::tr("Run device"));
|
2023-01-13 12:38:22 +01:00
|
|
|
setDescription(Tr::tr("The device to run the applications on."));
|
2013-08-28 18:57:25 +02:00
|
|
|
setPriority(32000);
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
QVariant DeviceKitAspectFactory::defaultValue(const Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
Id type = DeviceTypeKitAspect::deviceTypeId(k);
|
2014-08-01 13:06:21 +02:00
|
|
|
// Use default device if that is compatible:
|
2012-10-11 18:17:15 +02:00
|
|
|
IDevice::ConstPtr dev = DeviceManager::instance()->defaultDevice(type);
|
2014-08-01 13:06:21 +02:00
|
|
|
if (dev && dev->isCompatibleWith(k))
|
|
|
|
|
return dev->id().toString();
|
|
|
|
|
// Use any other device that is compatible:
|
|
|
|
|
for (int i = 0; i < DeviceManager::instance()->deviceCount(); ++i) {
|
|
|
|
|
dev = DeviceManager::instance()->deviceAt(i);
|
|
|
|
|
if (dev && dev->isCompatibleWith(k))
|
|
|
|
|
return dev->id().toString();
|
|
|
|
|
}
|
|
|
|
|
// Fail: No device set up.
|
2023-08-01 20:52:58 +02:00
|
|
|
return {};
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
Tasks DeviceKitAspectFactory::validate(const Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2019-02-06 12:50:51 +01:00
|
|
|
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
|
2019-05-27 16:09:44 +02:00
|
|
|
Tasks result;
|
2012-10-11 18:17:15 +02:00
|
|
|
if (dev.isNull())
|
2023-01-13 12:38:22 +01:00
|
|
|
result.append(BuildSystemTask(Task::Warning, Tr::tr("No device set.")));
|
2014-08-01 13:06:21 +02:00
|
|
|
else if (!dev->isCompatibleWith(k))
|
2023-01-13 12:38:22 +01:00
|
|
|
result.append(BuildSystemTask(Task::Error, Tr::tr("Device is incompatible with this kit.")));
|
2014-08-01 13:06:21 +02:00
|
|
|
|
2021-09-29 13:58:45 +02:00
|
|
|
if (dev)
|
|
|
|
|
result.append(dev->validate());
|
|
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void DeviceKitAspectFactory::fix(Kit *k)
|
2012-10-11 13:47:23 +02:00
|
|
|
{
|
2019-02-06 12:50:51 +01:00
|
|
|
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
|
2014-08-01 13:06:21 +02:00
|
|
|
if (!dev.isNull() && !dev->isCompatibleWith(k)) {
|
|
|
|
|
qWarning("Device is no longer compatible with kit \"%s\", removing it.",
|
|
|
|
|
qPrintable(k->displayName()));
|
2023-08-10 15:47:26 +02:00
|
|
|
DeviceKitAspect::setDeviceId(k, Id());
|
2013-11-29 12:17:53 +01:00
|
|
|
}
|
2013-02-28 14:06:17 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void DeviceKitAspectFactory::setup(Kit *k)
|
2013-02-28 14:06:17 +01:00
|
|
|
{
|
|
|
|
|
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return);
|
2019-02-06 12:50:51 +01:00
|
|
|
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
|
2014-08-01 13:06:21 +02:00
|
|
|
if (!dev.isNull() && dev->isCompatibleWith(k))
|
2013-02-28 14:06:17 +01:00
|
|
|
return;
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
DeviceKitAspect::setDeviceId(k, Id::fromSetting(defaultValue(k)));
|
2012-10-11 13:47:23 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspect *DeviceKitAspectFactory::createKitAspect(Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return nullptr);
|
2023-08-10 15:47:26 +02:00
|
|
|
return new Internal::DeviceKitAspectImpl(k, this);
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
QString DeviceKitAspectFactory::displayNamePostfix(const Kit *k) const
|
2012-08-07 13:09:56 +02:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
|
2012-08-07 13:09:56 +02:00
|
|
|
return dev.isNull() ? QString() : dev->displayName();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspectFactory::ItemList DeviceKitAspectFactory::toUserOutput(const Kit *k) const
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
IDevice::ConstPtr dev = DeviceKitAspect::device(k);
|
2023-01-13 12:38:22 +01:00
|
|
|
return {{Tr::tr("Device"), dev.isNull() ? Tr::tr("Unconfigured") : dev->displayName()}};
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void DeviceKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const
|
2014-10-22 10:00:07 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(kit, return);
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("Device:HostAddress", Tr::tr("Host address"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
|
|
|
|
|
return device ? device->sshParameters().host() : QString();
|
2019-08-28 07:51:56 +00:00
|
|
|
});
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("Device:SshPort", Tr::tr("SSH port"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
|
|
|
|
|
return device ? QString::number(device->sshParameters().port()) : QString();
|
2019-08-28 07:51:56 +00:00
|
|
|
});
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("Device:UserName", Tr::tr("User name"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
|
|
|
|
|
return device ? device->sshParameters().userName() : QString();
|
2019-08-28 07:51:56 +00:00
|
|
|
});
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("Device:KeyFile", Tr::tr("Private key file"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
|
|
|
|
|
return device ? device->sshParameters().privateKeyFile.toString() : QString();
|
2019-08-28 07:51:56 +00:00
|
|
|
});
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("Device:Name", Tr::tr("Device name"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
|
|
|
|
|
return device ? device->displayName() : QString();
|
|
|
|
|
});
|
|
|
|
|
expander->registerFileVariables("Device::Root", Tr::tr("Device root directory"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = DeviceKitAspect::device(kit);
|
|
|
|
|
return device ? device->rootPath() : FilePath{};
|
2019-08-28 07:51:56 +00:00
|
|
|
});
|
2014-10-22 10:00:07 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
Id DeviceKitAspect::id()
|
2013-09-09 17:10:41 +02:00
|
|
|
{
|
|
|
|
|
return "PE.Profile.Device";
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
IDevice::ConstPtr DeviceKitAspect::device(const Kit *k)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2013-02-28 14:06:17 +01:00
|
|
|
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return IDevice::ConstPtr());
|
2013-02-28 17:07:05 +01:00
|
|
|
return DeviceManager::instance()->find(deviceId(k));
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
Id DeviceKitAspect::deviceId(const Kit *k)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
return k ? Id::fromSetting(k->value(DeviceKitAspect::id())) : Id();
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
void DeviceKitAspect::setDevice(Kit *k, IDevice::ConstPtr dev)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
setDeviceId(k, dev ? dev->id() : Id());
|
2012-04-24 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
void DeviceKitAspect::setDeviceId(Kit *k, Id id)
|
2012-04-24 15:49:09 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return);
|
2019-02-06 12:50:51 +01:00
|
|
|
k->setValue(DeviceKitAspect::id(), id.toSetting());
|
2013-07-24 16:22:37 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-24 10:11:08 +02:00
|
|
|
FilePath DeviceKitAspect::deviceFilePath(const Kit *k, const QString &pathOnDevice)
|
|
|
|
|
{
|
|
|
|
|
if (IDevice::ConstPtr dev = device(k))
|
|
|
|
|
return dev->filePath(pathOnDevice);
|
|
|
|
|
return FilePath::fromString(pathOnDevice);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-18 14:12:19 +02:00
|
|
|
void DeviceKitAspectFactory::onKitsLoaded()
|
2012-10-17 17:27:17 +02:00
|
|
|
{
|
2023-08-18 14:12:19 +02:00
|
|
|
for (Kit *k : KitManager::kits())
|
2013-02-28 14:06:17 +01:00
|
|
|
fix(k);
|
|
|
|
|
|
2013-07-08 16:39:03 +02:00
|
|
|
DeviceManager *dm = DeviceManager::instance();
|
2023-08-10 15:47:26 +02:00
|
|
|
connect(dm, &DeviceManager::deviceListReplaced, this, &DeviceKitAspectFactory::devicesChanged);
|
|
|
|
|
connect(dm, &DeviceManager::deviceAdded, this, &DeviceKitAspectFactory::devicesChanged);
|
|
|
|
|
connect(dm, &DeviceManager::deviceRemoved, this, &DeviceKitAspectFactory::devicesChanged);
|
|
|
|
|
connect(dm, &DeviceManager::deviceUpdated, this, &DeviceKitAspectFactory::deviceUpdated);
|
2016-01-29 16:38:37 +02:00
|
|
|
|
|
|
|
|
connect(KitManager::instance(), &KitManager::kitUpdated,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &DeviceKitAspectFactory::kitUpdated);
|
2016-01-29 16:38:37 +02:00
|
|
|
connect(KitManager::instance(), &KitManager::unmanagedKitUpdated,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &DeviceKitAspectFactory::kitUpdated);
|
2013-02-28 14:06:17 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void DeviceKitAspectFactory::deviceUpdated(Id id)
|
2013-02-28 14:06:17 +01:00
|
|
|
{
|
2023-08-18 14:12:19 +02:00
|
|
|
for (Kit *k : KitManager::kits()) {
|
2023-08-10 15:47:26 +02:00
|
|
|
if (DeviceKitAspect::deviceId(k) == id)
|
2012-10-17 17:27:17 +02:00
|
|
|
notifyAboutUpdate(k);
|
2013-02-28 14:06:17 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void DeviceKitAspectFactory::kitUpdated(Kit *k)
|
2013-02-28 18:29:16 +01:00
|
|
|
{
|
|
|
|
|
setup(k); // Set default device if necessary
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void DeviceKitAspectFactory::devicesChanged()
|
2013-02-28 14:06:17 +01:00
|
|
|
{
|
2023-08-18 14:12:19 +02:00
|
|
|
for (Kit *k : KitManager::kits())
|
2013-02-28 18:29:16 +01:00
|
|
|
setup(k); // Set default device if necessary
|
2012-10-17 17:27:17 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
const DeviceKitAspectFactory theDeviceKitAspectFactory;
|
|
|
|
|
|
|
|
|
|
|
2021-04-12 12:09:47 +02:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// BuildDeviceKitAspect:
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
namespace Internal {
|
2023-08-10 15:47:26 +02:00
|
|
|
class BuildDeviceKitAspectImpl final : public KitAspect
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
public:
|
2023-08-16 10:20:01 +02:00
|
|
|
BuildDeviceKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
|
|
|
|
|
: KitAspect(workingCopy, factory),
|
2021-04-12 12:09:47 +02:00
|
|
|
m_comboBox(createSubWidget<QComboBox>()),
|
|
|
|
|
m_model(new DeviceManagerModel(DeviceManager::instance()))
|
|
|
|
|
{
|
2023-08-22 10:25:30 +02:00
|
|
|
setManagingPage(Constants::DEVICE_SETTINGS_PAGE_ID);
|
2021-04-12 12:09:47 +02:00
|
|
|
m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy());
|
|
|
|
|
m_comboBox->setModel(m_model);
|
|
|
|
|
refresh();
|
2023-08-16 10:20:01 +02:00
|
|
|
m_comboBox->setToolTip(factory->description());
|
2021-04-12 12:09:47 +02:00
|
|
|
|
|
|
|
|
connect(m_model, &QAbstractItemModel::modelAboutToBeReset,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &BuildDeviceKitAspectImpl::modelAboutToReset);
|
2021-04-12 12:09:47 +02:00
|
|
|
connect(m_model, &QAbstractItemModel::modelReset,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &BuildDeviceKitAspectImpl::modelReset);
|
2022-07-19 22:42:48 +02:00
|
|
|
connect(m_comboBox, &QComboBox::currentIndexChanged,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &BuildDeviceKitAspectImpl::currentDeviceChanged);
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
~BuildDeviceKitAspectImpl() override
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
delete m_comboBox;
|
|
|
|
|
delete m_model;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2023-08-22 09:54:38 +02:00
|
|
|
void addToLayoutImpl(Layouting::LayoutItem &builder) override
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
addMutableAction(m_comboBox);
|
|
|
|
|
builder.addItem(m_comboBox);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void makeReadOnly() override { m_comboBox->setEnabled(false); }
|
|
|
|
|
|
|
|
|
|
void refresh() override
|
|
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
QList<Id> blackList;
|
2021-04-12 12:09:47 +02:00
|
|
|
const DeviceManager *dm = DeviceManager::instance();
|
|
|
|
|
for (int i = 0; i < dm->deviceCount(); ++i) {
|
|
|
|
|
IDevice::ConstPtr device = dm->deviceAt(i);
|
2022-09-30 12:38:51 +02:00
|
|
|
if (!device->usableAsBuildDevice())
|
2021-04-12 12:09:47 +02:00
|
|
|
blackList.append(device->id());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_model->setFilter(blackList);
|
|
|
|
|
m_comboBox->setCurrentIndex(m_model->indexOf(BuildDeviceKitAspect::device(m_kit)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void modelAboutToReset()
|
|
|
|
|
{
|
|
|
|
|
m_selectedId = m_model->deviceId(m_comboBox->currentIndex());
|
2022-07-22 11:54:45 +02:00
|
|
|
m_ignoreChanges.lock();
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void modelReset()
|
|
|
|
|
{
|
|
|
|
|
m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId));
|
2022-07-22 11:54:45 +02:00
|
|
|
m_ignoreChanges.unlock();
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void currentDeviceChanged()
|
|
|
|
|
{
|
2022-07-22 11:54:45 +02:00
|
|
|
if (m_ignoreChanges.isLocked())
|
2021-04-12 12:09:47 +02:00
|
|
|
return;
|
|
|
|
|
BuildDeviceKitAspect::setDeviceId(m_kit, m_model->deviceId(m_comboBox->currentIndex()));
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-22 11:54:45 +02:00
|
|
|
Guard m_ignoreChanges;
|
2021-04-12 12:09:47 +02:00
|
|
|
QComboBox *m_comboBox;
|
|
|
|
|
DeviceManagerModel *m_model;
|
2021-09-29 18:18:56 +02:00
|
|
|
Id m_selectedId;
|
2021-04-12 12:09:47 +02:00
|
|
|
};
|
|
|
|
|
} // namespace Internal
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
class BuildDeviceKitAspectFactory : public KitAspectFactory
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
BuildDeviceKitAspectFactory();
|
|
|
|
|
|
2023-08-18 14:12:19 +02:00
|
|
|
private:
|
2023-08-15 12:45:54 +02:00
|
|
|
void setup(Kit *k) override;
|
|
|
|
|
Tasks validate(const Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
KitAspect *createKitAspect(Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
QString displayNamePostfix(const Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
ItemList toUserOutput(const Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
void addToMacroExpander(Kit *kit, MacroExpander *expander) const override;
|
|
|
|
|
|
2023-08-18 14:12:19 +02:00
|
|
|
void onKitsLoaded() override;
|
2023-08-15 12:45:54 +02:00
|
|
|
void deviceUpdated(Id dataId);
|
|
|
|
|
void devicesChanged();
|
|
|
|
|
void kitUpdated(Kit *k);
|
|
|
|
|
};
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
BuildDeviceKitAspectFactory::BuildDeviceKitAspectFactory()
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
setId(BuildDeviceKitAspect::id());
|
2023-01-13 12:38:22 +01:00
|
|
|
setDisplayName(Tr::tr("Build device"));
|
|
|
|
|
setDescription(Tr::tr("The device used to build applications on."));
|
2021-04-12 12:09:47 +02:00
|
|
|
setPriority(31900);
|
2023-08-10 15:47:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static IDeviceConstPtr defaultDevice()
|
|
|
|
|
{
|
|
|
|
|
return DeviceManager::defaultDesktopDevice();
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void BuildDeviceKitAspectFactory::setup(Kit *k)
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
2022-03-29 11:10:19 +02:00
|
|
|
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return );
|
|
|
|
|
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
|
2022-04-01 15:01:05 +02:00
|
|
|
if (!dev.isNull())
|
2022-03-29 11:10:19 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
dev = defaultDevice();
|
2023-08-10 15:47:26 +02:00
|
|
|
BuildDeviceKitAspect::setDeviceId(k, dev ? dev->id() : Id());
|
2022-03-29 11:10:19 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
Tasks BuildDeviceKitAspectFactory::validate(const Kit *k) const
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
|
|
|
|
|
Tasks result;
|
|
|
|
|
if (dev.isNull())
|
2023-01-13 12:38:22 +01:00
|
|
|
result.append(BuildSystemTask(Task::Warning, Tr::tr("No build device set.")));
|
2021-04-12 12:09:47 +02:00
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspect *BuildDeviceKitAspectFactory::createKitAspect(Kit *k) const
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
QTC_ASSERT(k, return nullptr);
|
2023-08-10 15:47:26 +02:00
|
|
|
return new Internal::BuildDeviceKitAspectImpl(k, this);
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
QString BuildDeviceKitAspectFactory::displayNamePostfix(const Kit *k) const
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
|
2021-04-12 12:09:47 +02:00
|
|
|
return dev.isNull() ? QString() : dev->displayName();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspectFactory::ItemList BuildDeviceKitAspectFactory::toUserOutput(const Kit *k) const
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
IDevice::ConstPtr dev = BuildDeviceKitAspect::device(k);
|
2023-01-13 12:38:22 +01:00
|
|
|
return {{Tr::tr("Build device"), dev.isNull() ? Tr::tr("Unconfigured") : dev->displayName()}};
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void BuildDeviceKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
QTC_ASSERT(kit, return);
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("BuildDevice:HostAddress", Tr::tr("Build host address"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
|
|
|
|
|
return device ? device->sshParameters().host() : QString();
|
2021-04-12 12:09:47 +02:00
|
|
|
});
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("BuildDevice:SshPort", Tr::tr("Build SSH port"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
|
|
|
|
|
return device ? QString::number(device->sshParameters().port()) : QString();
|
2021-04-12 12:09:47 +02:00
|
|
|
});
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("BuildDevice:UserName", Tr::tr("Build user name"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
|
|
|
|
|
return device ? device->sshParameters().userName() : QString();
|
2021-04-12 12:09:47 +02:00
|
|
|
});
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("BuildDevice:KeyFile", Tr::tr("Build private key file"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
|
|
|
|
|
return device ? device->sshParameters().privateKeyFile.toString() : QString();
|
2021-04-12 12:09:47 +02:00
|
|
|
});
|
2023-04-04 10:13:03 +02:00
|
|
|
expander->registerVariable("BuildDevice:Name", Tr::tr("Build device name"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
|
2023-09-07 14:04:19 +02:00
|
|
|
return device ? device->settings()->displayName() : QString();
|
2021-04-12 12:09:47 +02:00
|
|
|
});
|
2023-04-04 10:13:03 +02:00
|
|
|
expander
|
|
|
|
|
->registerFileVariables("BuildDevice::Root", Tr::tr("Build device root directory"), [kit] {
|
|
|
|
|
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
|
|
|
|
|
return device ? device->rootPath() : FilePath{};
|
|
|
|
|
});
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
Id BuildDeviceKitAspect::id()
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
return "PE.Profile.BuildDevice";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDevice::ConstPtr BuildDeviceKitAspect::device(const Kit *k)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(DeviceManager::instance()->isLoaded(), return IDevice::ConstPtr());
|
2021-05-12 12:21:04 +02:00
|
|
|
IDevice::ConstPtr dev = DeviceManager::instance()->find(deviceId(k));
|
|
|
|
|
if (!dev)
|
2022-03-29 11:10:19 +02:00
|
|
|
dev = defaultDevice();
|
2021-05-12 12:21:04 +02:00
|
|
|
return dev;
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
Id BuildDeviceKitAspect::deviceId(const Kit *k)
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
return k ? Id::fromSetting(k->value(BuildDeviceKitAspect::id())) : Id();
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildDeviceKitAspect::setDevice(Kit *k, IDevice::ConstPtr dev)
|
|
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
setDeviceId(k, dev ? dev->id() : Id());
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
void BuildDeviceKitAspect::setDeviceId(Kit *k, Id id)
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
QTC_ASSERT(k, return);
|
|
|
|
|
k->setValue(BuildDeviceKitAspect::id(), id.toSetting());
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-18 14:12:19 +02:00
|
|
|
void BuildDeviceKitAspectFactory::onKitsLoaded()
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
2023-08-18 14:12:19 +02:00
|
|
|
for (Kit *k : KitManager::kits())
|
2021-04-12 12:09:47 +02:00
|
|
|
fix(k);
|
|
|
|
|
|
|
|
|
|
DeviceManager *dm = DeviceManager::instance();
|
2023-08-10 15:47:26 +02:00
|
|
|
connect(dm, &DeviceManager::deviceListReplaced,
|
|
|
|
|
this, &BuildDeviceKitAspectFactory::devicesChanged);
|
|
|
|
|
connect(dm, &DeviceManager::deviceAdded,
|
|
|
|
|
this, &BuildDeviceKitAspectFactory::devicesChanged);
|
|
|
|
|
connect(dm, &DeviceManager::deviceRemoved,
|
|
|
|
|
this, &BuildDeviceKitAspectFactory::devicesChanged);
|
|
|
|
|
connect(dm, &DeviceManager::deviceUpdated,
|
|
|
|
|
this, &BuildDeviceKitAspectFactory::deviceUpdated);
|
2021-04-12 12:09:47 +02:00
|
|
|
connect(KitManager::instance(), &KitManager::kitUpdated,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &BuildDeviceKitAspectFactory::kitUpdated);
|
2021-04-12 12:09:47 +02:00
|
|
|
connect(KitManager::instance(), &KitManager::unmanagedKitUpdated,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &BuildDeviceKitAspectFactory::kitUpdated);
|
2021-04-12 12:09:47 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void BuildDeviceKitAspectFactory::deviceUpdated(Id id)
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
2022-05-03 16:48:36 +02:00
|
|
|
const QList<Kit *> kits = KitManager::kits();
|
|
|
|
|
for (Kit *k : kits) {
|
2023-08-10 15:47:26 +02:00
|
|
|
if (BuildDeviceKitAspect::deviceId(k) == id)
|
2021-04-12 12:09:47 +02:00
|
|
|
notifyAboutUpdate(k);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void BuildDeviceKitAspectFactory::kitUpdated(Kit *k)
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
|
|
|
|
setup(k); // Set default device if necessary
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void BuildDeviceKitAspectFactory::devicesChanged()
|
2021-04-12 12:09:47 +02:00
|
|
|
{
|
2022-05-03 16:48:36 +02:00
|
|
|
const QList<Kit *> kits = KitManager::kits();
|
|
|
|
|
for (Kit *k : kits)
|
2021-04-12 12:09:47 +02:00
|
|
|
setup(k); // Set default device if necessary
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
const BuildDeviceKitAspectFactory theBuildDeviceKitAspectFactory;
|
|
|
|
|
|
2014-07-22 21:12:34 +02:00
|
|
|
// --------------------------------------------------------------------------
|
2019-02-06 12:50:51 +01:00
|
|
|
// EnvironmentKitAspect:
|
2014-07-22 21:12:34 +02:00
|
|
|
// --------------------------------------------------------------------------
|
2023-08-01 12:16:14 +02:00
|
|
|
static EnvironmentItem forceMSVCEnglishItem()
|
|
|
|
|
{
|
|
|
|
|
static EnvironmentItem item("VSLANG", "1033");
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool enforcesMSVCEnglish(const EnvironmentItems &changes)
|
|
|
|
|
{
|
|
|
|
|
return changes.contains(forceMSVCEnglishItem());
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 15:04:17 +01:00
|
|
|
namespace Internal {
|
2023-08-10 15:47:26 +02:00
|
|
|
class EnvironmentKitAspectImpl final : public KitAspect
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2023-08-16 10:20:01 +02:00
|
|
|
EnvironmentKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory)
|
|
|
|
|
: KitAspect(workingCopy, factory),
|
2022-06-29 16:22:28 +02:00
|
|
|
m_summaryLabel(createSubWidget<ElidingLabel>()),
|
2021-04-07 18:55:21 +02:00
|
|
|
m_manageButton(createSubWidget<QPushButton>()),
|
|
|
|
|
m_mainWidget(createSubWidget<QWidget>())
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
|
|
|
|
auto *layout = new QVBoxLayout;
|
|
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
layout->addWidget(m_summaryLabel);
|
2022-06-29 16:22:28 +02:00
|
|
|
if (HostOsInfo::isWindowsHost())
|
2019-02-06 15:04:17 +01:00
|
|
|
initMSVCOutputSwitch(layout);
|
|
|
|
|
m_mainWidget->setLayout(layout);
|
|
|
|
|
refresh();
|
2023-01-13 12:38:22 +01:00
|
|
|
m_manageButton->setText(Tr::tr("Change..."));
|
2019-02-06 15:04:17 +01:00
|
|
|
connect(m_manageButton, &QAbstractButton::clicked,
|
2023-08-10 15:47:26 +02:00
|
|
|
this, &EnvironmentKitAspectImpl::editEnvironmentChanges);
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2023-08-22 09:54:38 +02:00
|
|
|
void addToLayoutImpl(Layouting::LayoutItem &builder) override
|
2021-04-07 18:55:21 +02:00
|
|
|
{
|
|
|
|
|
addMutableAction(m_mainWidget);
|
|
|
|
|
builder.addItem(m_mainWidget);
|
|
|
|
|
builder.addItem(m_manageButton);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 15:04:17 +01:00
|
|
|
void makeReadOnly() override { m_manageButton->setEnabled(false); }
|
|
|
|
|
|
|
|
|
|
void refresh() override
|
|
|
|
|
{
|
2023-08-01 12:16:14 +02:00
|
|
|
const EnvironmentItems changes = envWithoutMSVCEnglishEnforcement();
|
2022-06-29 16:22:28 +02:00
|
|
|
const QString shortSummary = EnvironmentItem::toStringList(changes).join("; ");
|
2023-01-13 12:38:22 +01:00
|
|
|
m_summaryLabel->setText(shortSummary.isEmpty() ? Tr::tr("No changes to apply.") : shortSummary);
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void editEnvironmentChanges()
|
|
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
MacroExpander *expander = m_kit->macroExpander();
|
|
|
|
|
EnvironmentDialog::Polisher polisher = [expander](QWidget *w) {
|
|
|
|
|
VariableChooser::addSupportForChildWidgets(w, expander);
|
2019-02-06 15:04:17 +01:00
|
|
|
};
|
2022-06-29 16:22:28 +02:00
|
|
|
auto changes = EnvironmentDialog::getEnvironmentItems(m_summaryLabel,
|
2023-08-01 12:16:14 +02:00
|
|
|
envWithoutMSVCEnglishEnforcement(),
|
2022-06-29 16:22:28 +02:00
|
|
|
QString(),
|
|
|
|
|
polisher);
|
2019-05-07 16:51:22 +02:00
|
|
|
if (!changes)
|
2019-02-06 15:04:17 +01:00
|
|
|
return;
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
if (HostOsInfo::isWindowsHost()) {
|
2023-08-01 12:16:14 +02:00
|
|
|
// re-add what envWithoutMSVCEnglishEnforcement removed
|
|
|
|
|
// or update vslang checkbox if user added it manually
|
|
|
|
|
if (m_vslangCheckbox->isChecked() && !enforcesMSVCEnglish(*changes))
|
|
|
|
|
changes->append(forceMSVCEnglishItem());
|
|
|
|
|
else if (enforcesMSVCEnglish(*changes))
|
|
|
|
|
m_vslangCheckbox->setChecked(true);
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
2019-05-07 16:51:22 +02:00
|
|
|
EnvironmentKitAspect::setEnvironmentChanges(m_kit, *changes);
|
2019-02-06 15:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-01 12:16:14 +02:00
|
|
|
EnvironmentItems envWithoutMSVCEnglishEnforcement() const
|
2019-02-06 15:04:17 +01:00
|
|
|
{
|
2022-06-29 16:22:28 +02:00
|
|
|
EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(m_kit);
|
2019-02-06 15:04:17 +01:00
|
|
|
|
2023-08-01 12:16:14 +02:00
|
|
|
if (HostOsInfo::isWindowsHost())
|
|
|
|
|
changes.removeAll(forceMSVCEnglishItem());
|
2019-02-06 15:04:17 +01:00
|
|
|
|
2022-10-21 14:05:12 +02:00
|
|
|
return sorted(std::move(changes), [](const EnvironmentItem &lhs, const EnvironmentItem &rhs)
|
2019-02-06 15:04:17 +01:00
|
|
|
{ return QString::localeAwareCompare(lhs.name, rhs.name) < 0; });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void initMSVCOutputSwitch(QVBoxLayout *layout)
|
|
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
m_vslangCheckbox = new QCheckBox(Tr::tr("Force UTF-8 MSVC compiler output"));
|
2019-02-06 15:04:17 +01:00
|
|
|
layout->addWidget(m_vslangCheckbox);
|
2023-01-13 12:38:22 +01:00
|
|
|
m_vslangCheckbox->setToolTip(Tr::tr("Either switches MSVC to English or keeps the language and "
|
2019-02-06 15:04:17 +01:00
|
|
|
"just forces UTF-8 output (may vary depending on the used MSVC "
|
|
|
|
|
"compiler)."));
|
2023-08-01 12:16:14 +02:00
|
|
|
if (enforcesMSVCEnglish(EnvironmentKitAspect::environmentChanges(m_kit)))
|
|
|
|
|
m_vslangCheckbox->setChecked(true);
|
|
|
|
|
connect(m_vslangCheckbox, &QCheckBox::clicked, this, [this](bool checked) {
|
2022-06-29 16:22:28 +02:00
|
|
|
EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(m_kit);
|
2023-08-01 12:16:14 +02:00
|
|
|
if (!checked && changes.indexOf(forceMSVCEnglishItem()) >= 0)
|
|
|
|
|
changes.removeAll(forceMSVCEnglishItem());
|
|
|
|
|
if (checked && changes.indexOf(forceMSVCEnglishItem()) < 0)
|
|
|
|
|
changes.append(forceMSVCEnglishItem());
|
2019-02-06 15:04:17 +01:00
|
|
|
EnvironmentKitAspect::setEnvironmentChanges(m_kit, changes);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
ElidingLabel *m_summaryLabel;
|
2019-02-06 15:04:17 +01:00
|
|
|
QPushButton *m_manageButton;
|
|
|
|
|
QCheckBox *m_vslangCheckbox;
|
|
|
|
|
QWidget *m_mainWidget;
|
|
|
|
|
};
|
|
|
|
|
} // namespace Internal
|
2014-07-22 21:12:34 +02:00
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
class EnvironmentKitAspectFactory : public KitAspectFactory
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
EnvironmentKitAspectFactory();
|
|
|
|
|
|
|
|
|
|
Tasks validate(const Kit *k) const override;
|
|
|
|
|
void fix(Kit *k) override;
|
|
|
|
|
|
|
|
|
|
void addToBuildEnvironment(const Kit *k, Environment &env) const override;
|
|
|
|
|
void addToRunEnvironment(const Kit *, Environment &) const override;
|
|
|
|
|
|
|
|
|
|
KitAspect *createKitAspect(Kit *k) const override;
|
|
|
|
|
|
|
|
|
|
ItemList toUserOutput(const Kit *k) const override;
|
|
|
|
|
};
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
EnvironmentKitAspectFactory::EnvironmentKitAspectFactory()
|
2014-07-22 21:12:34 +02:00
|
|
|
{
|
2019-02-06 12:50:51 +01:00
|
|
|
setId(EnvironmentKitAspect::id());
|
2023-01-13 12:38:22 +01:00
|
|
|
setDisplayName(Tr::tr("Environment"));
|
|
|
|
|
setDescription(Tr::tr("Additional build environment settings when using this kit."));
|
2014-07-22 21:12:34 +02:00
|
|
|
setPriority(29000);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
Tasks EnvironmentKitAspectFactory::validate(const Kit *k) const
|
2014-07-22 21:12:34 +02:00
|
|
|
{
|
2019-05-27 16:09:44 +02:00
|
|
|
Tasks result;
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return result);
|
|
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
const QVariant variant = k->value(EnvironmentKitAspect::id());
|
2020-01-15 08:56:11 +01:00
|
|
|
if (!variant.isNull() && !variant.canConvert(QVariant::List))
|
2023-01-13 12:38:22 +01:00
|
|
|
result << BuildSystemTask(Task::Error, Tr::tr("The environment setting value is invalid."));
|
2020-01-15 08:56:11 +01:00
|
|
|
|
2014-07-22 21:12:34 +02:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void EnvironmentKitAspectFactory::fix(Kit *k)
|
2014-07-22 21:12:34 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return);
|
|
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
const QVariant variant = k->value(EnvironmentKitAspect::id());
|
2014-07-22 21:12:34 +02:00
|
|
|
if (!variant.isNull() && !variant.canConvert(QVariant::List)) {
|
|
|
|
|
qWarning("Kit \"%s\" has a wrong environment value set.", qPrintable(k->displayName()));
|
2023-08-10 15:47:26 +02:00
|
|
|
EnvironmentKitAspect::setEnvironmentChanges(k, EnvironmentItems());
|
2014-07-22 21:12:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void EnvironmentKitAspectFactory::addToBuildEnvironment(const Kit *k, Environment &env) const
|
2014-07-22 21:12:34 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
const QStringList values
|
2023-08-10 15:47:26 +02:00
|
|
|
= transform(EnvironmentItem::toStringList(EnvironmentKitAspect::environmentChanges(k)),
|
2018-02-12 12:49:22 +01:00
|
|
|
[k](const QString &v) { return k->macroExpander()->expand(v); });
|
2022-06-29 16:22:28 +02:00
|
|
|
env.modify(EnvironmentItem::fromStringList(values));
|
2014-07-22 21:12:34 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
void EnvironmentKitAspectFactory::addToRunEnvironment(const Kit *k, Environment &env) const
|
2021-05-25 16:44:20 +02:00
|
|
|
{
|
|
|
|
|
addToBuildEnvironment(k, env);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspect *EnvironmentKitAspectFactory::createKitAspect(Kit *k) const
|
2014-07-22 21:12:34 +02:00
|
|
|
{
|
2018-02-12 12:49:22 +01:00
|
|
|
QTC_ASSERT(k, return nullptr);
|
2023-08-10 15:47:26 +02:00
|
|
|
return new Internal::EnvironmentKitAspectImpl(k, this);
|
2014-07-22 21:12:34 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:47:26 +02:00
|
|
|
KitAspectFactory::ItemList EnvironmentKitAspectFactory::toUserOutput(const Kit *k) const
|
2014-07-22 21:12:34 +02:00
|
|
|
{
|
2023-08-10 15:47:26 +02:00
|
|
|
return {{Tr::tr("Environment"),
|
|
|
|
|
EnvironmentItem::toStringList(EnvironmentKitAspect::environmentChanges(k)).join("<br>")}};
|
2014-07-22 21:12:34 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
Id EnvironmentKitAspect::id()
|
2014-07-22 21:12:34 +02:00
|
|
|
{
|
|
|
|
|
return "PE.Profile.Environment";
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
EnvironmentItems EnvironmentKitAspect::environmentChanges(const Kit *k)
|
2014-07-22 21:12:34 +02:00
|
|
|
{
|
|
|
|
|
if (k)
|
2022-06-29 16:22:28 +02:00
|
|
|
return EnvironmentItem::fromStringList(k->value(EnvironmentKitAspect::id()).toStringList());
|
2023-08-01 20:52:58 +02:00
|
|
|
return {};
|
2014-07-22 21:12:34 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-29 16:22:28 +02:00
|
|
|
void EnvironmentKitAspect::setEnvironmentChanges(Kit *k, const EnvironmentItems &changes)
|
2014-07-22 21:12:34 +02:00
|
|
|
{
|
|
|
|
|
if (k)
|
2022-06-29 16:22:28 +02:00
|
|
|
k->setValue(EnvironmentKitAspect::id(), EnvironmentItem::toStringList(changes));
|
2014-07-22 21:12:34 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-15 12:45:54 +02:00
|
|
|
const EnvironmentKitAspectFactory theEnvironmentKitAspectFactory;
|
|
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
} // namespace ProjectExplorer
|