2019-10-22 14:33:31 +02:00
/****************************************************************************
* *
2020-07-02 16:04:31 +02:00
* * Copyright ( C ) 2020 The Qt Company Ltd .
* * Contact : https : //www.qt.io/licensing/
2019-10-22 14:33:31 +02:00
* *
* * This file is part of Qt Creator .
* *
* * Commercial License Usage
* * Licensees holding valid commercial Qt licenses may use this file in
* * accordance with the commercial license agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
* * a written agreement between you and The Qt Company . For licensing terms
* * and conditions see https : //www.qt.io/terms-conditions. For further
* * information use the contact form at https : //www.qt.io/contact-us.
* *
* * GNU General Public License Usage
* * Alternatively , this file may be used under the terms of the GNU
* * General Public License version 3 as published by the Free Software
* * Foundation with exceptions as appearing in the file LICENSE . GPL3 - EXCEPT
* * included in the packaging of this file . Please review the following
* * information to ensure the GNU General Public License requirements will
* * be met : https : //www.gnu.org/licenses/gpl-3.0.html.
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2022-02-15 11:18:56 +01:00
# include "mcusupportoptions.h"
2022-02-01 16:51:27 +01:00
# include "mcukitinformation.h"
2022-02-01 14:30:35 +01:00
# include "mcupackage.h"
2022-02-15 11:18:56 +01:00
# include "mcusupportcmakemapper.h"
2019-10-22 14:33:31 +02:00
# include "mcusupportconstants.h"
2021-03-10 16:38:45 +01:00
# include "mcusupportplugin.h"
2022-02-15 11:18:56 +01:00
# include "mcusupportsdk.h"
2019-10-22 14:33:31 +02:00
2020-11-13 14:00:18 +01:00
# include <baremetal/baremetalconstants.h>
2021-02-26 14:22:42 +01:00
# include <cmakeprojectmanager/cmakekitinformation.h>
2022-02-15 11:18:56 +01:00
# include <cmakeprojectmanager/cmaketoolmanager.h>
2020-03-24 18:58:29 +01:00
# include <coreplugin/helpmanager.h>
2022-02-15 11:18:56 +01:00
# include <coreplugin/icore.h>
2020-12-04 16:32:34 +01:00
# include <coreplugin/messagemanager.h>
2019-10-22 14:33:31 +02:00
# include <debugger/debuggeritem.h>
# include <debugger/debuggeritemmanager.h>
# include <debugger/debuggerkitinformation.h>
2020-04-07 18:19:32 +02:00
# include <projectexplorer/abi.h>
2022-02-15 11:18:56 +01:00
# include <projectexplorer/devicesupport/devicemanager.h>
# include <projectexplorer/kitinformation.h>
# include <projectexplorer/kitmanager.h>
2019-10-22 14:33:31 +02:00
# include <projectexplorer/projectexplorerconstants.h>
# include <projectexplorer/toolchain.h>
# include <projectexplorer/toolchainmanager.h>
# include <utils/algorithm.h>
# include <utils/fileutils.h>
2019-12-11 21:17:53 +01:00
# include <utils/infolabel.h>
2019-10-22 14:33:31 +02:00
# include <utils/pathchooser.h>
# include <utils/qtcassert.h>
# include <utils/utilsicons.h>
2022-02-15 11:18:56 +01:00
# include <qtsupport/qtkitinformation.h>
# include <qtsupport/qtversionmanager.h>
2019-10-22 14:33:31 +02:00
# include <QDesktopServices>
# include <QDir>
# include <QFileInfo>
# include <QLabel>
2021-03-10 16:38:45 +01:00
# include <QMessageBox>
# include <QPushButton>
2019-10-22 14:33:31 +02:00
# include <QToolButton>
# include <QVBoxLayout>
# include <QVariant>
2022-02-11 13:51:42 +01:00
using CMakeProjectManager : : CMakeConfigItem ;
using CMakeProjectManager : : CMakeConfigurationKitAspect ;
2020-09-17 11:05:28 +02:00
using namespace ProjectExplorer ;
using namespace Utils ;
2019-10-22 14:33:31 +02:00
namespace McuSupport {
namespace Internal {
2021-09-29 17:23:11 +02:00
static const int KIT_VERSION = 9 ; // Bumps up whenever details in Kit creation change
2020-04-22 23:24:54 +02:00
2020-08-31 00:05:50 +02:00
static bool kitNeedsQtVersion ( )
{
// Only on Windows, Qt is linked into the distributed qul Desktop libs. Also, the host tools
// are missing the Qt runtime libraries on non-Windows.
2020-09-17 11:05:28 +02:00
return ! HostOsInfo : : isWindowsHost ( ) ;
2020-08-31 00:05:50 +02:00
}
2020-09-23 10:11:44 +02:00
static ToolChain * msvcToolChain ( Id language )
2020-09-18 11:16:37 +02:00
{
ToolChain * toolChain = ToolChainManager : : toolChain ( [ language ] ( const ToolChain * t ) {
const Abi abi = t - > targetAbi ( ) ;
2021-11-03 13:34:47 +01:00
// TODO: Should Abi::WindowsMsvc2022Flavor be added too?
2022-02-15 11:18:56 +01:00
return ( abi . osFlavor ( ) = = Abi : : WindowsMsvc2017Flavor
| | abi . osFlavor ( ) = = Abi : : WindowsMsvc2019Flavor )
& & abi . architecture ( ) = = Abi : : X86Architecture & & abi . wordWidth ( ) = = 64
& & t - > language ( ) = = language ;
2020-09-18 11:16:37 +02:00
} ) ;
return toolChain ;
}
2020-09-23 10:11:44 +02:00
static ToolChain * gccToolChain ( Id language )
2020-04-07 18:19:32 +02:00
{
ToolChain * toolChain = ToolChainManager : : toolChain ( [ language ] ( const ToolChain * t ) {
const Abi abi = t - > targetAbi ( ) ;
2022-02-15 11:18:56 +01:00
return abi . os ( ) ! = Abi : : WindowsOS & & abi . architecture ( ) = = Abi : : X86Architecture
& & abi . wordWidth ( ) = = 64 & & t - > language ( ) = = language ;
2020-04-07 18:19:32 +02:00
} ) ;
return toolChain ;
}
2020-09-17 11:05:28 +02:00
static ToolChain * armGccToolChain ( const FilePath & path , Id language )
2020-02-26 16:41:52 +01:00
{
2022-02-15 11:18:56 +01:00
ToolChain * toolChain = ToolChainManager : : toolChain ( [ & path , language ] ( const ToolChain * t ) {
2020-02-26 16:41:52 +01:00
return t - > compilerCommand ( ) = = path & & t - > language ( ) = = language ;
} ) ;
if ( ! toolChain ) {
2022-02-15 11:18:56 +01:00
ToolChainFactory * gccFactory
= Utils : : findOrDefault ( ToolChainFactory : : allToolChainFactories ( ) ,
[ ] ( ToolChainFactory * f ) {
return f - > supportedToolChainType ( )
= = ProjectExplorer : : Constants : : GCC_TOOLCHAIN_TYPEID ;
} ) ;
2020-02-26 16:41:52 +01:00
if ( gccFactory ) {
2022-02-15 11:18:56 +01:00
const QList < ToolChain * > detected = gccFactory - > detectForImport ( { path , language } ) ;
2020-02-26 16:41:52 +01:00
if ( ! detected . isEmpty ( ) ) {
toolChain = detected . first ( ) ;
toolChain - > setDetection ( ToolChain : : ManualDetection ) ;
toolChain - > setDisplayName ( " Arm GCC " ) ;
ToolChainManager : : registerToolChain ( toolChain ) ;
}
}
}
return toolChain ;
}
2022-01-12 15:20:03 +01:00
static ToolChain * iarToolChain ( const FilePath & path , Id language )
2020-11-13 14:00:18 +01:00
{
2022-02-15 11:18:56 +01:00
ToolChain * toolChain = ToolChainManager : : toolChain ( [ language ] ( const ToolChain * t ) {
2020-11-13 14:00:18 +01:00
return t - > typeId ( ) = = BareMetal : : Constants : : IAREW_TOOLCHAIN_TYPEID
& & t - > language ( ) = = language ;
} ) ;
if ( ! toolChain ) {
2022-02-15 11:18:56 +01:00
ToolChainFactory * iarFactory
= Utils : : findOrDefault ( ToolChainFactory : : allToolChainFactories ( ) ,
[ ] ( ToolChainFactory * f ) {
return f - > supportedToolChainType ( )
= = BareMetal : : Constants : : IAREW_TOOLCHAIN_TYPEID ;
} ) ;
2020-11-13 14:00:18 +01:00
if ( iarFactory ) {
2022-01-14 17:29:02 +01:00
Toolchains detected = iarFactory - > autoDetect ( ToolchainDetector ( { } , { } ) ) ;
2022-01-12 15:20:03 +01:00
if ( detected . isEmpty ( ) )
detected = iarFactory - > detectForImport ( { path , language } ) ;
2022-02-15 11:18:56 +01:00
for ( auto tc : detected ) {
2020-11-13 14:00:18 +01:00
if ( tc - > language ( ) = = language ) {
toolChain = tc ;
toolChain - > setDetection ( ToolChain : : ManualDetection ) ;
toolChain - > setDisplayName ( " IAREW " ) ;
ToolChainManager : : registerToolChain ( toolChain ) ;
}
}
}
}
return toolChain ;
}
2020-09-17 11:05:28 +02:00
ToolChain * McuToolChainPackage : : toolChain ( Id language ) const
2020-02-26 16:41:52 +01:00
{
2022-02-01 16:29:11 +01:00
switch ( m_type ) {
case Type : : MSVC :
return msvcToolChain ( language ) ;
case Type : : GCC :
return gccToolChain ( language ) ;
case Type : : IAR : {
2022-01-12 15:20:03 +01:00
const FilePath compiler = path ( ) . pathAppended ( " /bin/iccarm " ) . withExecutableSuffix ( ) ;
2022-02-01 16:29:11 +01:00
return iarToolChain ( compiler , language ) ;
2020-11-13 14:00:18 +01:00
}
2022-02-01 16:29:11 +01:00
case Type : : ArmGcc :
case Type : : KEIL :
case Type : : GHS :
case Type : : GHSArm :
case Type : : Unsupported : {
2020-04-07 18:19:32 +02:00
const QLatin1String compilerName (
2022-02-01 16:29:11 +01:00
language = = ProjectExplorer : : Constants : : C_LANGUAGE_ID ? " gcc " : " g++ " ) ;
const QString comp = QLatin1String ( m_type = = Type : : ArmGcc ? " /bin/arm-none-eabi-%1 "
: " /bar/foo-keil-%1 " )
. arg ( compilerName ) ;
2021-09-30 18:30:02 +02:00
const FilePath compiler = path ( ) . pathAppended ( comp ) . withExecutableSuffix ( ) ;
2020-04-07 18:19:32 +02:00
2022-02-01 16:29:11 +01:00
return armGccToolChain ( compiler , language ) ;
}
default :
Q_UNREACHABLE ( ) ;
2020-04-07 18:19:32 +02:00
}
2020-02-26 16:41:52 +01:00
}
2020-11-13 14:00:18 +01:00
QString McuToolChainPackage : : toolChainName ( ) const
2020-02-26 16:41:52 +01:00
{
2021-05-10 11:35:46 +02:00
switch ( m_type ) {
2022-02-15 11:18:56 +01:00
case Type : : ArmGcc :
return QLatin1String ( " armgcc " ) ;
case Type : : IAR :
return QLatin1String ( " iar " ) ;
case Type : : KEIL :
return QLatin1String ( " keil " ) ;
case Type : : GHS :
return QLatin1String ( " ghs " ) ;
case Type : : GHSArm :
return QLatin1String ( " ghs-arm " ) ;
default :
return QLatin1String ( " unsupported " ) ;
2021-05-10 11:35:46 +02:00
}
2020-11-13 14:00:18 +01:00
}
QString McuToolChainPackage : : cmakeToolChainFileName ( ) const
{
return toolChainName ( ) + QLatin1String ( " .cmake " ) ;
2020-02-26 16:41:52 +01:00
}
QVariant McuToolChainPackage : : debuggerId ( ) const
{
using namespace Debugger ;
2021-11-30 16:13:11 +01:00
QString sub , displayName ;
DebuggerEngineType engineType ;
switch ( m_type ) {
2022-02-01 16:29:11 +01:00
case Type : : ArmGcc : {
2021-11-30 16:13:11 +01:00
sub = QString : : fromLatin1 ( " bin/arm-none-eabi-gdb-py " ) ;
displayName = McuPackage : : tr ( " Arm GDB at %1 " ) ;
engineType = Debugger : : GdbEngineType ;
2022-02-01 16:29:11 +01:00
break ;
}
case Type : : IAR : {
2021-11-30 16:13:11 +01:00
sub = QString : : fromLatin1 ( " ../common/bin/CSpyBat " ) ;
displayName = QLatin1String ( " CSpy " ) ;
engineType = Debugger : : NoEngineType ; // support for IAR missing
2022-02-01 16:29:11 +01:00
break ;
}
case Type : : KEIL : {
2021-11-30 16:13:11 +01:00
sub = QString : : fromLatin1 ( " UV4/UV4 " ) ;
displayName = QLatin1String ( " KEIL uVision Debugger " ) ;
engineType = Debugger : : UvscEngineType ;
2022-02-01 16:29:11 +01:00
break ;
}
default :
return QVariant ( ) ;
2021-11-30 16:13:11 +01:00
}
2021-09-30 18:30:02 +02:00
const FilePath command = path ( ) . pathAppended ( sub ) . withExecutableSuffix ( ) ;
2022-02-01 16:29:11 +01:00
if ( const DebuggerItem * debugger = DebuggerItemManager : : findByCommand ( command ) ) {
return debugger - > id ( ) ;
2020-02-26 16:41:52 +01:00
}
2022-02-01 16:29:11 +01:00
DebuggerItem newDebugger ;
newDebugger . setCommand ( command ) ;
newDebugger . setUnexpandedDisplayName ( displayName . arg ( command . toUserOutput ( ) ) ) ;
newDebugger . setEngineType ( engineType ) ;
return DebuggerItemManager : : registerDebugger ( newDebugger ) ;
2020-02-26 16:41:52 +01:00
}
2020-09-18 11:16:37 +02:00
McuTarget : : McuTarget ( const QVersionNumber & qulVersion ,
2022-02-07 16:17:35 +01:00
const Platform & platform ,
OS os ,
2022-02-11 13:51:42 +01:00
const QVector < McuAbstractPackage * > & packages ,
2022-02-07 16:17:35 +01:00
const McuToolChainPackage * toolChainPackage ,
int colorDepth )
2020-06-30 17:09:03 +02:00
: m_qulVersion ( qulVersion )
2020-09-18 11:16:37 +02:00
, m_platform ( platform )
2020-04-27 20:51:08 +02:00
, m_os ( os )
2019-10-22 14:33:31 +02:00
, m_packages ( packages )
2020-02-26 16:41:52 +01:00
, m_toolChainPackage ( toolChainPackage )
2022-02-07 16:17:35 +01:00
, m_colorDepth ( colorDepth )
2022-02-15 11:18:56 +01:00
{ }
2019-10-22 14:33:31 +02:00
2022-02-11 13:51:42 +01:00
const QVector < McuAbstractPackage * > & McuTarget : : packages ( ) const
2019-11-20 13:32:10 +01:00
{
return m_packages ;
}
2020-04-23 23:30:40 +02:00
const McuToolChainPackage * McuTarget : : toolChainPackage ( ) const
2019-11-20 13:32:10 +01:00
{
2020-02-26 16:41:52 +01:00
return m_toolChainPackage ;
2019-10-22 14:33:31 +02:00
}
2020-04-27 20:51:08 +02:00
McuTarget : : OS McuTarget : : os ( ) const
{
return m_os ;
}
2022-02-01 16:07:50 +01:00
const McuTarget : : Platform & McuTarget : : platform ( ) const
2019-10-22 14:33:31 +02:00
{
2020-09-18 11:16:37 +02:00
return m_platform ;
2019-10-22 14:33:31 +02:00
}
2019-11-15 08:38:55 +01:00
bool McuTarget : : isValid ( ) const
2019-11-13 18:37:27 +01:00
{
2022-02-11 13:51:42 +01:00
return Utils : : allOf ( packages ( ) , [ ] ( McuAbstractPackage * package ) {
2020-12-04 16:32:34 +01:00
package - > updateStatus ( ) ;
2021-02-15 16:20:38 +01:00
return package - > validStatus ( ) ;
2019-11-13 18:37:27 +01:00
} ) ;
}
2020-12-04 16:32:34 +01:00
void McuTarget : : printPackageProblems ( ) const
{
2022-02-15 11:18:56 +01:00
for ( auto package : packages ( ) ) {
2020-12-04 16:32:34 +01:00
package - > updateStatus ( ) ;
2021-02-15 16:20:38 +01:00
if ( ! package - > validStatus ( ) )
2022-02-15 11:18:56 +01:00
printMessage ( tr ( " Error creating kit for target %1, package %2: %3 " )
. arg ( McuSupportOptions : : kitName ( this ) ,
package - > label ( ) ,
package - > statusText ( ) ) ,
2020-12-04 16:32:34 +01:00
true ) ;
2022-02-15 14:35:35 +01:00
if ( package - > status ( ) = = McuAbstractPackage : : Status : : ValidPackageMismatchedVersion )
2022-02-15 11:18:56 +01:00
printMessage ( tr ( " Warning creating kit for target %1, package %2: %3 " )
. arg ( McuSupportOptions : : kitName ( this ) ,
package - > label ( ) ,
package - > statusText ( ) ) ,
2021-02-15 16:20:38 +01:00
false ) ;
2020-12-04 16:32:34 +01:00
}
}
2022-02-01 16:07:50 +01:00
const QVersionNumber & McuTarget : : qulVersion ( ) const
2020-06-30 17:09:03 +02:00
{
return m_qulVersion ;
}
2019-11-21 01:22:28 +01:00
int McuTarget : : colorDepth ( ) const
{
return m_colorDepth ;
}
2021-09-29 17:23:11 +02:00
void McuSdkRepository : : deletePackagesAndTargets ( )
{
qDeleteAll ( packages ) ;
packages . clear ( ) ;
qDeleteAll ( mcuTargets ) ;
mcuTargets . clear ( ) ;
}
2019-10-22 14:33:31 +02:00
McuSupportOptions : : McuSupportOptions ( QObject * parent )
: QObject ( parent )
2020-03-12 14:25:49 +01:00
, qtForMCUsSdkPackage ( Sdk : : createQtForMCUsPackage ( ) )
2019-10-22 14:33:31 +02:00
{
2022-02-15 11:18:56 +01:00
connect ( qtForMCUsSdkPackage ,
& McuAbstractPackage : : changed ,
this ,
& McuSupportOptions : : populatePackagesAndTargets ) ;
2019-10-22 14:33:31 +02:00
}
McuSupportOptions : : ~ McuSupportOptions ( )
2020-03-18 03:17:35 +01:00
{
deletePackagesAndTargets ( ) ;
delete qtForMCUsSdkPackage ;
}
void McuSupportOptions : : populatePackagesAndTargets ( )
{
2021-09-30 18:30:02 +02:00
setQulDir ( qtForMCUsSdkPackage - > path ( ) ) ;
2020-03-18 03:17:35 +01:00
}
2020-09-17 11:05:28 +02:00
static FilePath qulDocsDir ( )
2020-04-02 19:31:52 +02:00
{
2020-09-17 11:05:28 +02:00
const FilePath qulDir = McuSupportOptions : : qulDirFromSettings ( ) ;
2020-04-02 19:31:52 +02:00
if ( qulDir . isEmpty ( ) | | ! qulDir . exists ( ) )
return { } ;
2020-09-17 11:05:28 +02:00
const FilePath docsDir = qulDir . pathAppended ( " docs " ) ;
return docsDir . exists ( ) ? docsDir : FilePath ( ) ;
2020-04-02 19:31:52 +02:00
}
2020-03-24 18:58:29 +01:00
void McuSupportOptions : : registerQchFiles ( )
{
2020-04-02 19:31:52 +02:00
const QString docsDir = qulDocsDir ( ) . toString ( ) ;
if ( docsDir . isEmpty ( ) )
2020-03-24 18:58:29 +01:00
return ;
2020-12-04 08:47:55 +01:00
const QFileInfoList qchFiles = QDir ( docsDir , " *.qch " ) . entryInfoList ( ) ;
2020-09-17 13:47:30 +02:00
Core : : HelpManager : : registerDocumentation (
2022-02-15 11:18:56 +01:00
Utils : : transform < QStringList > ( qchFiles ,
[ ] ( const QFileInfo & fi ) { return fi . absoluteFilePath ( ) ; } ) ) ;
2020-03-24 18:58:29 +01:00
}
2020-04-02 19:31:52 +02:00
void McuSupportOptions : : registerExamples ( )
{
2020-09-17 11:05:28 +02:00
const FilePath docsDir = qulDocsDir ( ) ;
2020-04-02 19:31:52 +02:00
if ( docsDir . isEmpty ( ) )
return ;
2022-02-15 11:18:56 +01:00
auto examples = { std : : make_pair ( QStringLiteral ( " demos " ) , tr ( " Qt for MCUs Demos " ) ) ,
std : : make_pair ( QStringLiteral ( " examples " ) , tr ( " Qt for MCUs Examples " ) ) } ;
2021-02-09 17:06:24 +01:00
for ( const auto & dir : examples ) {
2022-02-15 11:18:56 +01:00
const FilePath examplesDir = McuSupportOptions : : qulDirFromSettings ( ) . pathAppended ( dir . first ) ;
2021-02-09 17:06:24 +01:00
if ( ! examplesDir . exists ( ) )
continue ;
2022-02-15 11:18:56 +01:00
QtSupport : : QtVersionManager : : registerExampleSet ( dir . second ,
docsDir . toString ( ) ,
2021-02-09 17:06:24 +01:00
examplesDir . toString ( ) ) ;
}
2020-04-02 19:31:52 +02:00
}
2020-06-30 17:09:03 +02:00
const QVersionNumber & McuSupportOptions : : minimalQulVersion ( )
2020-03-25 15:09:02 +01:00
{
2022-02-15 12:20:44 +01:00
static const QVersionNumber v ( { 2 , 0 } ) ;
2020-03-25 15:09:02 +01:00
return v ;
}
2020-09-17 11:05:28 +02:00
void McuSupportOptions : : setQulDir ( const FilePath & dir )
2020-03-18 03:17:35 +01:00
{
deletePackagesAndTargets ( ) ;
2020-12-04 16:32:34 +01:00
qtForMCUsSdkPackage - > updateStatus ( ) ;
2021-02-15 16:20:38 +01:00
if ( qtForMCUsSdkPackage - > validStatus ( ) )
2021-09-29 17:23:11 +02:00
Sdk : : targetsAndPackages ( dir , & sdkRepository ) ;
for ( const auto & package : qAsConst ( sdkRepository . packages ) )
2022-02-11 13:51:42 +01:00
connect ( package , & McuAbstractPackage : : changed , this , & McuSupportOptions : : changed ) ;
2020-09-17 11:05:28 +02:00
2020-03-18 03:17:35 +01:00
emit changed ( ) ;
}
2020-09-17 11:05:28 +02:00
FilePath McuSupportOptions : : qulDirFromSettings ( )
2020-03-24 18:58:29 +01:00
{
2022-02-01 14:30:35 +01:00
return Sdk : : packagePathFromSettings ( Constants : : SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK ,
2022-02-15 12:20:44 +01:00
QSettings : : UserScope , { } ) ;
2020-03-24 18:58:29 +01:00
}
2022-02-15 11:18:56 +01:00
static void setKitProperties ( const QString & kitName ,
Kit * k ,
const McuTarget * mcuTarget ,
2021-09-30 18:30:02 +02:00
const FilePath & sdkPath )
2019-10-22 14:33:31 +02:00
{
2020-04-23 23:30:40 +02:00
using namespace Constants ;
2019-10-22 14:33:31 +02:00
2019-11-12 10:39:18 +01:00
k - > setUnexpandedDisplayName ( kitName ) ;
2020-09-18 11:16:37 +02:00
k - > setValue ( KIT_MCUTARGET_VENDOR_KEY , mcuTarget - > platform ( ) . vendor ) ;
k - > setValue ( KIT_MCUTARGET_MODEL_KEY , mcuTarget - > platform ( ) . name ) ;
2020-04-23 23:30:40 +02:00
k - > setValue ( KIT_MCUTARGET_COLORDEPTH_KEY , mcuTarget - > colorDepth ( ) ) ;
2020-06-30 17:09:03 +02:00
k - > setValue ( KIT_MCUTARGET_SDKVERSION_KEY , mcuTarget - > qulVersion ( ) . toString ( ) ) ;
2020-04-23 23:30:40 +02:00
k - > setValue ( KIT_MCUTARGET_KITVERSION_KEY , KIT_VERSION ) ;
2020-04-27 20:51:08 +02:00
k - > setValue ( KIT_MCUTARGET_OS_KEY , static_cast < int > ( mcuTarget - > os ( ) ) ) ;
2020-12-07 10:46:13 +01:00
k - > setValue ( KIT_MCUTARGET_TOOCHAIN_KEY , mcuTarget - > toolChainPackage ( ) - > toolChainName ( ) ) ;
2021-03-31 16:47:22 +02:00
k - > setAutoDetected ( false ) ;
2019-11-13 18:37:27 +01:00
k - > makeSticky ( ) ;
2020-09-18 11:16:37 +02:00
if ( mcuTarget - > toolChainPackage ( ) - > isDesktopToolchain ( ) )
2020-04-23 23:30:40 +02:00
k - > setDeviceTypeForIcon ( DEVICE_TYPE ) ;
2021-02-09 17:27:02 +01:00
k - > setValue ( QtSupport : : SuppliesQtQuickImportPath : : id ( ) , true ) ;
2021-09-30 18:30:02 +02:00
k - > setValue ( QtSupport : : KitQmlImportPath : : id ( ) , sdkPath . pathAppended ( " include/qul " ) . toVariant ( ) ) ;
2021-02-26 14:33:34 +01:00
k - > setValue ( QtSupport : : KitHasMergedHeaderPathsWithQmlImportPaths : : id ( ) , true ) ;
2021-02-26 14:22:42 +01:00
QSet < Id > irrelevant = {
SysRootKitAspect : : id ( ) ,
QtSupport : : SuppliesQtQuickImportPath : : id ( ) ,
2021-02-26 14:33:34 +01:00
QtSupport : : KitQmlImportPath : : id ( ) ,
QtSupport : : KitHasMergedHeaderPathsWithQmlImportPaths : : id ( ) ,
2021-02-26 14:22:42 +01:00
} ;
2020-08-31 00:05:50 +02:00
if ( ! kitNeedsQtVersion ( ) )
irrelevant . insert ( QtSupport : : QtKitAspect : : id ( ) ) ;
2020-04-07 18:19:32 +02:00
k - > setIrrelevantAspects ( irrelevant ) ;
2019-10-22 14:33:31 +02:00
}
2022-02-11 13:51:42 +01:00
void McuSupportOptions : : remapQul2xCmakeVars ( Kit * kit , const EnvironmentItems & envItems )
{
const auto cmakeVars = mapEnvVarsToQul2xCmakeVars ( envItems ) ;
const auto cmakeVarNames = Utils : : transform ( cmakeVars , & CMakeConfigItem : : key ) ;
// First filter out all Qul2.x CMake vars
auto config = Utils : : filtered ( CMakeConfigurationKitAspect : : configuration ( kit ) ,
[ & ] ( const auto & configItem ) {
2022-02-15 11:18:56 +01:00
return ! cmakeVarNames . contains ( configItem . key ) ;
} ) ;
2022-02-11 13:51:42 +01:00
// Then append them with new values
config . append ( cmakeVars ) ;
CMakeConfigurationKitAspect : : setConfiguration ( kit , config ) ;
}
2020-09-17 11:05:28 +02:00
static void setKitToolchains ( Kit * k , const McuToolChainPackage * tcPackage )
2019-10-22 14:33:31 +02:00
{
2022-02-01 16:29:11 +01:00
switch ( tcPackage - > type ( ) ) {
case McuToolChainPackage : : Type : : Unsupported :
return ;
case McuToolChainPackage : : Type : : GHS :
case McuToolChainPackage : : Type : : GHSArm :
return ; // No Green Hills toolchain, because support for it is missing.
case McuToolChainPackage : : Type : : IAR :
case McuToolChainPackage : : Type : : KEIL :
case McuToolChainPackage : : Type : : MSVC :
case McuToolChainPackage : : Type : : GCC :
case McuToolChainPackage : : Type : : ArmGcc :
ToolChainKitAspect : : setToolChain ( k ,
tcPackage - > toolChain (
ProjectExplorer : : Constants : : C_LANGUAGE_ID ) ) ;
ToolChainKitAspect : : setToolChain ( k ,
tcPackage - > toolChain (
ProjectExplorer : : Constants : : CXX_LANGUAGE_ID ) ) ;
2020-04-09 23:50:03 +02:00
return ;
2022-02-01 16:29:11 +01:00
default :
Q_UNREACHABLE ( ) ;
}
2019-10-22 14:33:31 +02:00
}
2020-09-17 11:05:28 +02:00
static void setKitDebugger ( Kit * k , const McuToolChainPackage * tcPackage )
2019-10-22 14:33:31 +02:00
{
2022-02-01 16:29:11 +01:00
if ( tcPackage - > isDesktopToolchain ( ) ) {
// Qt Creator seems to be smart enough to deduce the right Kit debugger from the ToolChain
2020-04-07 18:19:32 +02:00
return ;
2022-02-01 16:29:11 +01:00
}
2020-04-07 18:19:32 +02:00
2022-02-01 16:29:11 +01:00
switch ( tcPackage - > type ( ) ) {
case McuToolChainPackage : : Type : : Unsupported :
case McuToolChainPackage : : Type : : GHS :
case McuToolChainPackage : : Type : : GHSArm :
case McuToolChainPackage : : Type : : IAR :
return ; // No Green Hills and IAR debugger, because support for it is missing.
case McuToolChainPackage : : Type : : KEIL :
case McuToolChainPackage : : Type : : MSVC :
case McuToolChainPackage : : Type : : GCC :
case McuToolChainPackage : : Type : : ArmGcc : {
const QVariant debuggerId = tcPackage - > debuggerId ( ) ;
if ( debuggerId . isValid ( ) ) {
Debugger : : DebuggerKitAspect : : setDebugger ( k , debuggerId ) ;
}
return ;
}
default :
Q_UNREACHABLE ( ) ;
}
2019-10-22 14:33:31 +02:00
}
2022-02-15 11:18:56 +01:00
static void setKitDevice ( Kit * k , const McuTarget * mcuTarget )
2019-10-22 14:33:31 +02:00
{
2020-04-07 18:19:32 +02:00
// "Device Type" Desktop is the default. We use that for the Qt for MCUs Desktop Kit
2020-09-18 11:16:37 +02:00
if ( mcuTarget - > toolChainPackage ( ) - > isDesktopToolchain ( ) )
2020-04-07 18:19:32 +02:00
return ;
2020-09-17 11:05:28 +02:00
DeviceTypeKitAspect : : setDeviceTypeId ( k , Constants : : DEVICE_TYPE ) ;
2019-10-22 14:33:31 +02:00
}
2021-09-29 17:23:11 +02:00
static bool expectsCmakeVars ( const McuTarget * mcuTarget )
{
2022-02-15 11:18:56 +01:00
return mcuTarget - > qulVersion ( ) > = QVersionNumber { 2 , 0 } ;
2021-09-29 17:23:11 +02:00
}
2022-02-15 11:18:56 +01:00
void McuSupportOptions : : setKitEnvironment ( Kit * k ,
const McuTarget * mcuTarget ,
const McuAbstractPackage * qtForMCUsSdkPackage )
2019-10-22 14:33:31 +02:00
{
2020-09-17 11:05:28 +02:00
EnvironmentItems changes ;
2019-10-22 14:33:31 +02:00
QStringList pathAdditions ;
2020-03-04 19:59:50 +01:00
2020-04-07 18:19:32 +02:00
// The Desktop version depends on the Qt shared libs in Qul_DIR/bin.
// If CMake's fileApi is avaialble, we can rely on the "Add library search path to PATH"
// feature of the run configuration. Otherwise, we just prepend the path, here.
2020-09-18 11:16:37 +02:00
if ( mcuTarget - > toolChainPackage ( ) - > isDesktopToolchain ( )
2022-02-15 11:18:56 +01:00
& & ! CMakeProjectManager : : CMakeToolManager : : defaultCMakeTool ( ) - > hasFileApi ( ) )
2021-09-30 18:30:02 +02:00
pathAdditions . append ( qtForMCUsSdkPackage - > path ( ) . pathAppended ( " bin " ) . toUserOutput ( ) ) ;
2020-04-07 18:19:32 +02:00
2022-02-11 13:51:42 +01:00
auto processPackage = [ & pathAdditions , & changes ] ( const McuAbstractPackage * package ) {
2019-10-22 14:33:31 +02:00
if ( package - > addToPath ( ) )
2021-09-30 18:30:02 +02:00
pathAdditions . append ( package - > path ( ) . toUserOutput ( ) ) ;
2019-10-22 14:33:31 +02:00
if ( ! package - > environmentVariableName ( ) . isEmpty ( ) )
2021-09-30 18:30:02 +02:00
changes . append ( { package - > environmentVariableName ( ) , package - > path ( ) . toUserOutput ( ) } ) ;
2020-04-23 23:30:40 +02:00
} ;
for ( auto package : mcuTarget - > packages ( ) )
processPackage ( package ) ;
processPackage ( qtForMCUsSdkPackage ) ;
2020-08-31 00:05:50 +02:00
if ( kitNeedsQtVersion ( ) )
changes . append ( { QLatin1String ( " LD_LIBRARY_PATH " ) , " %{Qt:QT_INSTALL_LIBS} " } ) ;
2021-09-29 17:23:11 +02:00
// Hack, this problem should be solved in lower layer
if ( expectsCmakeVars ( mcuTarget ) ) {
2022-02-11 13:51:42 +01:00
McuSupportOptions : : remapQul2xCmakeVars ( k , changes ) ;
2021-09-29 17:23:11 +02:00
}
2019-10-22 14:33:31 +02:00
EnvironmentKitAspect : : setEnvironmentChanges ( k , changes ) ;
}
2022-02-15 11:18:56 +01:00
static void setKitDependencies ( Kit * k ,
const McuTarget * mcuTarget ,
const McuAbstractPackage * qtForMCUsSdkPackage )
2021-03-09 18:28:58 +01:00
{
NameValueItems dependencies ;
2022-02-11 13:51:42 +01:00
auto processPackage = [ & dependencies ] ( const McuAbstractPackage * package ) {
2021-03-09 18:28:58 +01:00
if ( ! package - > environmentVariableName ( ) . isEmpty ( ) )
dependencies . append ( { package - > environmentVariableName ( ) ,
2022-02-15 11:18:56 +01:00
QDir : : toNativeSeparators ( package - > detectionPath ( ) ) } ) ;
2021-03-09 18:28:58 +01:00
} ;
for ( auto package : mcuTarget - > packages ( ) )
processPackage ( package ) ;
processPackage ( qtForMCUsSdkPackage ) ;
McuDependenciesKitAspect : : setDependencies ( k , dependencies ) ;
auto irrelevant = k - > irrelevantAspects ( ) ;
irrelevant . insert ( McuDependenciesKitAspect : : id ( ) ) ;
k - > setIrrelevantAspects ( irrelevant ) ;
}
2022-02-11 13:51:42 +01:00
void McuSupportOptions : : updateKitEnvironment ( Kit * k , const McuTarget * mcuTarget )
2021-04-08 17:14:55 +02:00
{
EnvironmentItems changes = EnvironmentKitAspect : : environmentChanges ( k ) ;
for ( auto package : mcuTarget - > packages ( ) ) {
const QString varName = package - > environmentVariableName ( ) ;
if ( ! varName . isEmpty ( ) & & package - > validStatus ( ) ) {
const int index = Utils : : indexOf ( changes , [ varName ] ( const EnvironmentItem & item ) {
return item . name = = varName ;
} ) ;
const EnvironmentItem item = { package - > environmentVariableName ( ) ,
2021-09-30 18:30:02 +02:00
package - > path ( ) . toUserOutput ( ) } ;
2021-04-08 17:14:55 +02:00
if ( index ! = - 1 )
changes . replace ( index , item ) ;
else
changes . append ( item ) ;
}
}
2021-09-29 17:23:11 +02:00
// Hack, this problem should be solved in lower layer
if ( expectsCmakeVars ( mcuTarget ) ) {
remapQul2xCmakeVars ( k , changes ) ;
}
2021-04-08 17:14:55 +02:00
EnvironmentKitAspect : : setEnvironmentChanges ( k , changes ) ;
}
2022-02-15 11:18:56 +01:00
static void setKitCMakeOptions ( Kit * k , const McuTarget * mcuTarget , const FilePath & qulDir )
2019-10-22 14:33:31 +02:00
{
using namespace CMakeProjectManager ;
CMakeConfig config = CMakeConfigurationKitAspect : : configuration ( k ) ;
2020-04-09 23:50:03 +02:00
// CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously
2022-02-15 11:18:56 +01:00
if ( mcuTarget - > toolChainPackage ( ) - > type ( ) ! = McuToolChainPackage : : Type : : GHS
& & mcuTarget - > toolChainPackage ( ) - > type ( ) ! = McuToolChainPackage : : Type : : GHSArm ) {
2020-04-09 23:50:03 +02:00
config . append ( CMakeConfigItem ( " CMAKE_CXX_COMPILER " , " %{Compiler:Executable:Cxx} " ) ) ;
config . append ( CMakeConfigItem ( " CMAKE_C_COMPILER " , " %{Compiler:Executable:C} " ) ) ;
}
2020-12-04 16:32:34 +01:00
if ( ! mcuTarget - > toolChainPackage ( ) - > isDesktopToolchain ( ) ) {
2022-02-15 11:18:56 +01:00
const FilePath cMakeToolchainFile = qulDir . pathAppended (
" lib/cmake/Qul/toolchain/ " + mcuTarget - > toolChainPackage ( ) - > cmakeToolChainFileName ( ) ) ;
2020-12-04 16:32:34 +01:00
2022-02-15 11:18:56 +01:00
config . append (
CMakeConfigItem ( " CMAKE_TOOLCHAIN_FILE " , cMakeToolchainFile . toString ( ) . toUtf8 ( ) ) ) ;
2020-12-04 16:32:34 +01:00
if ( ! cMakeToolchainFile . exists ( ) ) {
2022-02-15 11:18:56 +01:00
printMessage ( McuTarget : : tr (
" Warning for target %1: missing CMake toolchain file expected at %2. " )
. arg ( McuSupportOptions : : kitName ( mcuTarget ) ,
cMakeToolchainFile . toUserOutput ( ) ) ,
false ) ;
2020-12-04 16:32:34 +01:00
}
}
2021-09-30 18:30:02 +02:00
const FilePath generatorsPath = qulDir . pathAppended ( " /lib/cmake/Qul/QulGenerators.cmake " ) ;
2022-02-15 11:18:56 +01:00
config . append ( CMakeConfigItem ( " QUL_GENERATORS " , generatorsPath . toString ( ) . toUtf8 ( ) ) ) ;
2020-12-04 16:32:34 +01:00
if ( ! generatorsPath . exists ( ) ) {
printMessage ( McuTarget : : tr ( " Warning for target %1: missing QulGenerators expected at %2. " )
2022-02-15 11:18:56 +01:00
. arg ( McuSupportOptions : : kitName ( mcuTarget ) , generatorsPath . toUserOutput ( ) ) ,
false ) ;
2020-12-04 16:32:34 +01:00
}
2022-02-15 11:18:56 +01:00
config . append ( CMakeConfigItem ( " QUL_PLATFORM " , mcuTarget - > platform ( ) . name . toUtf8 ( ) ) ) ;
2020-08-13 13:10:52 +02:00
2022-02-07 16:17:35 +01:00
if ( mcuTarget - > colorDepth ( ) ! = McuTarget : : UnspecifiedColorDepth )
2019-11-21 01:22:28 +01:00
config . append ( CMakeConfigItem ( " QUL_COLOR_DEPTH " ,
QString : : number ( mcuTarget - > colorDepth ( ) ) . toLatin1 ( ) ) ) ;
2020-08-31 00:05:50 +02:00
if ( kitNeedsQtVersion ( ) )
config . append ( CMakeConfigItem ( " CMAKE_PREFIX_PATH " , " %{Qt:QT_INSTALL_PREFIX} " ) ) ;
2019-12-06 17:58:38 +01:00
CMakeConfigurationKitAspect : : setConfiguration ( k , config ) ;
2021-05-10 14:20:26 +02:00
if ( HostOsInfo : : isWindowsHost ( ) ) {
auto type = mcuTarget - > toolChainPackage ( ) - > type ( ) ;
2022-02-01 16:29:11 +01:00
if ( type = = McuToolChainPackage : : Type : : GHS | | type = = McuToolChainPackage : : Type : : GHSArm ) {
2021-05-10 14:20:26 +02:00
// See https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565802&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565802
// and https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565803&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565803
CMakeGeneratorKitAspect : : setGenerator ( k , " NMake Makefiles JOM " ) ;
}
}
2019-10-22 14:33:31 +02:00
}
2020-09-17 11:05:28 +02:00
static void setKitQtVersionOptions ( Kit * k )
2020-04-07 18:19:32 +02:00
{
2020-08-31 00:05:50 +02:00
if ( ! kitNeedsQtVersion ( ) )
QtSupport : : QtKitAspect : : setQtVersion ( k , nullptr ) ;
// else: auto-select a Qt version
2020-04-07 18:19:32 +02:00
}
2020-04-23 23:30:40 +02:00
QString McuSupportOptions : : kitName ( const McuTarget * mcuTarget )
2019-11-12 15:14:20 +01:00
{
2020-11-13 14:00:18 +01:00
const McuToolChainPackage * tcPkg = mcuTarget - > toolChainPackage ( ) ;
const QString compilerName = tcPkg & & ! tcPkg - > isDesktopToolchain ( )
2022-02-15 11:18:56 +01:00
? QString : : fromLatin1 ( " (%1) " ) . arg (
tcPkg - > toolChainName ( ) . toUpper ( ) )
: " " ;
2022-02-07 16:17:35 +01:00
const QString colorDepth = mcuTarget - > colorDepth ( ) ! = McuTarget : : UnspecifiedColorDepth
2022-02-15 11:18:56 +01:00
? QString : : fromLatin1 ( " %1bpp " ) . arg ( mcuTarget - > colorDepth ( ) )
: " " ;
2020-09-18 11:16:37 +02:00
const QString targetName = mcuTarget - > platform ( ) . displayName . isEmpty ( )
2022-02-15 11:18:56 +01:00
? mcuTarget - > platform ( ) . name
: mcuTarget - > platform ( ) . displayName ;
2022-02-15 12:20:44 +01:00
return QString : : fromLatin1 ( " Qt for MCUs %1.%2 - %3%4%5 " )
2022-02-15 11:18:56 +01:00
. arg ( QString : : number ( mcuTarget - > qulVersion ( ) . majorVersion ( ) ) ,
QString : : number ( mcuTarget - > qulVersion ( ) . minorVersion ( ) ) ,
targetName ,
colorDepth ,
compilerName ) ;
2019-11-12 15:14:20 +01:00
}
2021-03-31 16:47:22 +02:00
QList < Kit * > McuSupportOptions : : existingKits ( const McuTarget * mcuTarget )
2019-10-22 14:33:31 +02:00
{
2020-04-23 23:30:40 +02:00
using namespace Constants ;
2021-03-31 16:47:22 +02:00
return Utils : : filtered ( KitManager : : kits ( ) , [ mcuTarget ] ( Kit * kit ) {
return kit - > value ( KIT_MCUTARGET_KITVERSION_KEY ) = = KIT_VERSION
2022-02-15 11:18:56 +01:00
& & ( ! mcuTarget
| | ( kit - > value ( KIT_MCUTARGET_VENDOR_KEY ) = = mcuTarget - > platform ( ) . vendor
& & kit - > value ( KIT_MCUTARGET_MODEL_KEY ) = = mcuTarget - > platform ( ) . name
& & kit - > value ( KIT_MCUTARGET_COLORDEPTH_KEY ) = = mcuTarget - > colorDepth ( )
& & kit - > value ( KIT_MCUTARGET_OS_KEY ) . toInt ( )
= = static_cast < int > ( mcuTarget - > os ( ) )
& & kit - > value ( KIT_MCUTARGET_TOOCHAIN_KEY )
= = mcuTarget - > toolChainPackage ( ) - > toolChainName ( ) ) ) ;
2019-10-22 14:33:31 +02:00
} ) ;
2019-11-13 18:37:27 +01:00
}
2019-10-22 14:33:31 +02:00
2022-02-15 11:18:56 +01:00
QList < Kit * > McuSupportOptions : : matchingKits ( const McuTarget * mcuTarget ,
const McuAbstractPackage * qtForMCUsSdkPackage )
2021-03-31 16:47:22 +02:00
{
return Utils : : filtered ( existingKits ( mcuTarget ) , [ mcuTarget , qtForMCUsSdkPackage ] ( Kit * kit ) {
return kitUpToDate ( kit , mcuTarget , qtForMCUsSdkPackage ) ;
} ) ;
}
2022-02-15 11:18:56 +01:00
QList < Kit * > McuSupportOptions : : upgradeableKits ( const McuTarget * mcuTarget ,
const McuAbstractPackage * qtForMCUsSdkPackage )
2021-03-31 16:47:22 +02:00
{
return Utils : : filtered ( existingKits ( mcuTarget ) , [ mcuTarget , qtForMCUsSdkPackage ] ( Kit * kit ) {
return ! kitUpToDate ( kit , mcuTarget , qtForMCUsSdkPackage ) ;
} ) ;
}
2021-04-08 17:14:55 +02:00
QList < Kit * > McuSupportOptions : : kitsWithMismatchedDependencies ( const McuTarget * mcuTarget )
{
2021-03-31 16:47:22 +02:00
return Utils : : filtered ( existingKits ( mcuTarget ) , [ mcuTarget ] ( Kit * kit ) {
2021-04-08 17:14:55 +02:00
const auto environment = Utils : : NameValueDictionary (
2022-02-15 11:18:56 +01:00
Utils : : NameValueItem : : toStringList ( EnvironmentKitAspect : : environmentChanges ( kit ) ) ) ;
return Utils : : anyOf ( mcuTarget - > packages ( ) ,
[ & environment ] ( const McuAbstractPackage * package ) {
return ! package - > environmentVariableName ( ) . isEmpty ( )
& & environment . value ( package - > environmentVariableName ( ) )
! = package - > path ( ) . toUserOutput ( ) ;
} ) ;
2021-04-08 17:14:55 +02:00
} ) ;
}
2020-09-17 11:05:28 +02:00
QList < Kit * > McuSupportOptions : : outdatedKits ( )
2020-04-22 23:24:54 +02:00
{
2020-09-17 11:05:28 +02:00
return Utils : : filtered ( KitManager : : kits ( ) , [ ] ( Kit * kit ) {
2021-03-31 16:47:22 +02:00
return ! kit - > value ( Constants : : KIT_MCUTARGET_VENDOR_KEY ) . isNull ( )
2022-02-15 11:18:56 +01:00
& & kit - > value ( Constants : : KIT_MCUTARGET_KITVERSION_KEY ) ! = KIT_VERSION ;
2019-10-22 14:33:31 +02:00
} ) ;
2019-11-13 18:37:27 +01:00
}
2019-10-22 14:33:31 +02:00
2020-04-22 23:24:54 +02:00
void McuSupportOptions : : removeOutdatedKits ( )
{
for ( auto kit : McuSupportOptions : : outdatedKits ( ) )
2020-09-17 11:05:28 +02:00
KitManager : : deregisterKit ( kit ) ;
2020-04-22 23:24:54 +02:00
}
2022-02-11 13:51:42 +01:00
Kit * McuSupportOptions : : newKit ( const McuTarget * mcuTarget , const McuAbstractPackage * qtForMCUsSdk )
2019-11-13 18:37:27 +01:00
{
2020-04-23 23:30:40 +02:00
const auto init = [ mcuTarget , qtForMCUsSdk ] ( Kit * k ) {
2019-11-13 18:37:27 +01:00
KitGuard kitGuard ( k ) ;
2021-02-26 14:22:42 +01:00
setKitProperties ( kitName ( mcuTarget ) , k , mcuTarget , qtForMCUsSdk - > path ( ) ) ;
2020-04-07 18:19:32 +02:00
setKitDevice ( k , mcuTarget ) ;
setKitToolchains ( k , mcuTarget - > toolChainPackage ( ) ) ;
setKitDebugger ( k , mcuTarget - > toolChainPackage ( ) ) ;
2020-04-23 23:30:40 +02:00
setKitEnvironment ( k , mcuTarget , qtForMCUsSdk ) ;
2021-03-09 18:28:58 +01:00
setKitDependencies ( k , mcuTarget , qtForMCUsSdk ) ;
2020-04-23 23:30:40 +02:00
setKitCMakeOptions ( k , mcuTarget , qtForMCUsSdk - > path ( ) ) ;
2020-04-07 18:19:32 +02:00
setKitQtVersionOptions ( k ) ;
2019-11-13 18:37:27 +01:00
k - > setup ( ) ;
k - > fix ( ) ;
} ;
return KitManager : : registerKit ( init ) ;
2019-10-22 14:33:31 +02:00
}
2020-12-04 16:32:34 +01:00
void printMessage ( const QString & message , bool important )
2020-10-16 15:10:17 +02:00
{
2022-02-15 11:18:56 +01:00
const QString displayMessage = QCoreApplication : : translate ( " QtForMCUs " , " Qt for MCUs: %1 " )
. arg ( message ) ;
2020-12-04 16:32:34 +01:00
if ( important )
Core : : MessageManager : : writeFlashing ( displayMessage ) ;
else
Core : : MessageManager : : writeSilently ( displayMessage ) ;
}
2020-10-16 15:10:17 +02:00
2021-03-31 16:47:22 +02:00
QVersionNumber McuSupportOptions : : kitQulVersion ( const Kit * kit )
2021-03-10 16:38:45 +01:00
{
return QVersionNumber : : fromString (
2022-02-15 11:18:56 +01:00
kit - > value ( McuSupport : : Constants : : KIT_MCUTARGET_SDKVERSION_KEY ) . toString ( ) ) ;
2021-03-10 16:38:45 +01:00
}
2021-09-30 18:30:02 +02:00
static FilePath kitDependencyPath ( const Kit * kit , const QString & variableName )
2021-03-10 16:38:45 +01:00
{
for ( const NameValueItem & nameValueItem : EnvironmentKitAspect : : environmentChanges ( kit ) ) {
if ( nameValueItem . name = = variableName )
2021-09-30 18:30:02 +02:00
return FilePath : : fromUserInput ( nameValueItem . value ) ;
2021-03-10 16:38:45 +01:00
}
2021-09-30 18:30:02 +02:00
return FilePath ( ) ;
2021-03-10 16:38:45 +01:00
}
2022-02-15 11:18:56 +01:00
bool McuSupportOptions : : kitUpToDate ( const Kit * kit ,
const McuTarget * mcuTarget ,
2022-02-11 13:51:42 +01:00
const McuAbstractPackage * qtForMCUsSdkPackage )
2021-03-31 16:47:22 +02:00
{
2022-02-15 11:18:56 +01:00
return kitQulVersion ( kit ) = = mcuTarget - > qulVersion ( )
& & kitDependencyPath ( kit , qtForMCUsSdkPackage - > environmentVariableName ( ) ) . toUserOutput ( )
= = qtForMCUsSdkPackage - > path ( ) . toUserOutput ( ) ;
2021-03-31 16:47:22 +02:00
}
2021-09-29 17:23:11 +02:00
void McuSupportOptions : : deletePackagesAndTargets ( )
{
sdkRepository . deletePackagesAndTargets ( ) ;
}
2021-03-10 16:38:45 +01:00
McuSupportOptions : : UpgradeOption McuSupportOptions : : askForKitUpgrades ( )
{
QMessageBox upgradePopup ( Core : : ICore : : dialogParent ( ) ) ;
upgradePopup . setStandardButtons ( QMessageBox : : Cancel ) ;
2022-02-15 11:18:56 +01:00
QPushButton * replaceButton = upgradePopup . addButton ( tr ( " Replace Existing Kits " ) ,
QMessageBox : : NoRole ) ;
QPushButton * keepButton = upgradePopup . addButton ( tr ( " Create New Kits " ) , QMessageBox : : NoRole ) ;
2021-03-10 16:38:45 +01:00
upgradePopup . setWindowTitle ( tr ( " Qt for MCUs " ) ) ;
2021-07-02 15:00:36 +02:00
upgradePopup . setText ( tr ( " New version of Qt for MCUs detected. Upgrade existing kits? " ) ) ;
2021-03-10 16:38:45 +01:00
upgradePopup . exec ( ) ;
if ( upgradePopup . clickedButton ( ) = = keepButton )
return Keep ;
if ( upgradePopup . clickedButton ( ) = = replaceButton )
return Replace ;
return Ignore ;
}
2020-12-04 16:32:34 +01:00
void McuSupportOptions : : createAutomaticKits ( )
{
2020-10-16 15:10:17 +02:00
auto qtForMCUsPackage = Sdk : : createQtForMCUsPackage ( ) ;
2020-12-04 16:32:34 +01:00
const auto createKits = [ qtForMCUsPackage ] ( ) {
2022-02-15 11:18:56 +01:00
if ( qtForMCUsPackage - > automaticKitCreationEnabled ( ) ) {
qtForMCUsPackage - > updateStatus ( ) ;
if ( ! qtForMCUsPackage - > validStatus ( ) ) {
switch ( qtForMCUsPackage - > status ( ) ) {
2022-02-15 14:35:35 +01:00
case McuAbstractPackage : : Status : : ValidPathInvalidPackage : {
2022-02-15 11:18:56 +01:00
const QString displayPath
= FilePath : : fromString ( qtForMCUsPackage - > detectionPath ( ) ) . toUserOutput ( ) ;
2020-12-04 16:32:34 +01:00
printMessage ( tr ( " Path %1 exists, but does not contain %2. " )
2022-02-15 11:18:56 +01:00
. arg ( qtForMCUsPackage - > path ( ) . toUserOutput ( ) , displayPath ) ,
2020-12-04 16:32:34 +01:00
true ) ;
break ;
}
2022-02-15 14:35:35 +01:00
case McuAbstractPackage : : Status : : InvalidPath : {
2022-02-15 11:18:56 +01:00
printMessage ( tr ( " Path %1 does not exist. Add the path in Tools > Options > "
" Devices > MCU. " )
. arg ( qtForMCUsPackage - > path ( ) . toUserOutput ( ) ) ,
2020-12-04 16:32:34 +01:00
true ) ;
break ;
}
2022-02-15 14:35:35 +01:00
case McuAbstractPackage : : Status : : EmptyPath : {
2020-12-04 16:32:34 +01:00
printMessage ( tr ( " Missing %1. Add the path in Tools > Options > Devices > MCU. " )
2022-02-15 11:18:56 +01:00
. arg ( qtForMCUsPackage - > detectionPath ( ) ) ,
2020-12-04 16:32:34 +01:00
true ) ;
return ;
}
2022-02-15 11:18:56 +01:00
default :
break ;
}
return ;
2020-12-04 16:32:34 +01:00
}
2022-02-15 11:18:56 +01:00
if ( CMakeProjectManager : : CMakeToolManager : : cmakeTools ( ) . isEmpty ( ) ) {
printMessage ( tr ( " No CMake tool was detected. Add a CMake tool in Tools > Options > "
" Kits > CMake. " ) ,
true ) ;
return ;
}
2020-10-16 15:10:17 +02:00
2022-02-15 11:18:56 +01:00
FilePath dir = qtForMCUsPackage - > path ( ) ;
McuSdkRepository repo ;
Sdk : : targetsAndPackages ( dir , & repo ) ;
bool needsUpgrade = false ;
for ( const auto & target : qAsConst ( repo . mcuTargets ) ) {
// if kit already exists, skip
if ( ! matchingKits ( target , qtForMCUsPackage ) . empty ( ) )
continue ;
if ( ! upgradeableKits ( target , qtForMCUsPackage ) . empty ( ) ) {
// if kit exists but wrong version/path
needsUpgrade = true ;
} else {
// if no kits for this target, create
if ( target - > isValid ( ) )
newKit ( target , qtForMCUsPackage ) ;
target - > printPackageProblems ( ) ;
}
2020-12-04 16:32:34 +01:00
}
2020-10-16 15:10:17 +02:00
2022-02-15 11:18:56 +01:00
repo . deletePackagesAndTargets ( ) ;
2021-03-10 16:38:45 +01:00
2022-02-15 11:18:56 +01:00
if ( needsUpgrade )
McuSupportPlugin : : askUserAboutMcuSupportKitsUpgrade ( ) ;
}
} ;
2020-10-16 15:10:17 +02:00
2020-12-04 16:32:34 +01:00
createKits ( ) ;
2020-10-16 15:10:17 +02:00
delete qtForMCUsPackage ;
}
2021-03-10 16:38:45 +01:00
void McuSupportOptions : : checkUpgradeableKits ( )
{
2021-09-29 17:23:11 +02:00
if ( ! qtForMCUsSdkPackage - > validStatus ( ) | | sdkRepository . mcuTargets . length ( ) = = 0 )
2021-03-10 16:38:45 +01:00
return ;
2021-09-29 17:23:11 +02:00
if ( Utils : : anyOf ( sdkRepository . mcuTargets , [ this ] ( const McuTarget * target ) {
2022-02-15 11:18:56 +01:00
return ! upgradeableKits ( target , this - > qtForMCUsSdkPackage ) . empty ( )
& & matchingKits ( target , this - > qtForMCUsSdkPackage ) . empty ( ) ;
2021-03-10 16:38:45 +01:00
} ) )
upgradeKits ( askForKitUpgrades ( ) ) ;
}
void McuSupportOptions : : upgradeKits ( UpgradeOption upgradeOption )
{
if ( upgradeOption = = Ignore )
return ;
auto qtForMCUsPackage = Sdk : : createQtForMCUsPackage ( ) ;
2021-09-30 18:30:02 +02:00
auto dir = qtForMCUsPackage - > path ( ) ;
2021-09-29 17:23:11 +02:00
McuSdkRepository repo ;
Sdk : : targetsAndPackages ( dir , & repo ) ;
2021-03-10 16:38:45 +01:00
2022-02-15 11:18:56 +01:00
for ( const auto & target : qAsConst ( repo . mcuTargets ) ) {
2021-03-31 16:47:22 +02:00
if ( ! matchingKits ( target , qtForMCUsPackage ) . empty ( ) )
2021-03-10 16:38:45 +01:00
// already up-to-date
continue ;
2021-03-31 16:47:22 +02:00
const auto kits = upgradeableKits ( target , qtForMCUsPackage ) ;
if ( ! kits . empty ( ) ) {
if ( upgradeOption = = Replace )
for ( auto existingKit : kits )
2021-03-10 16:38:45 +01:00
KitManager : : deregisterKit ( existingKit ) ;
if ( target - > isValid ( ) )
newKit ( target , qtForMCUsPackage ) ;
target - > printPackageProblems ( ) ;
}
}
2021-09-29 17:23:11 +02:00
repo . deletePackagesAndTargets ( ) ;
2021-03-10 16:38:45 +01:00
delete qtForMCUsPackage ;
}
2022-02-15 11:18:56 +01:00
void McuSupportOptions : : upgradeKitInPlace ( ProjectExplorer : : Kit * kit ,
const McuTarget * mcuTarget ,
const McuAbstractPackage * qtForMCUsSdk )
2021-03-31 16:47:22 +02:00
{
setKitProperties ( kitName ( mcuTarget ) , kit , mcuTarget , qtForMCUsSdk - > path ( ) ) ;
setKitEnvironment ( kit , mcuTarget , qtForMCUsSdk ) ;
setKitDependencies ( kit , mcuTarget , qtForMCUsSdk ) ;
}
2021-04-08 17:14:55 +02:00
void McuSupportOptions : : fixKitsDependencies ( )
{
auto qtForMCUsPackage = Sdk : : createQtForMCUsPackage ( ) ;
2021-09-30 18:30:02 +02:00
FilePath dir = qtForMCUsPackage - > path ( ) ;
2021-09-29 17:23:11 +02:00
McuSdkRepository repo ;
Sdk : : targetsAndPackages ( dir , & repo ) ;
2022-02-15 11:18:56 +01:00
for ( const auto & target : qAsConst ( repo . mcuTargets ) ) {
2021-04-08 17:14:55 +02:00
if ( target - > isValid ( ) ) {
2022-02-15 11:18:56 +01:00
for ( auto * kit : kitsWithMismatchedDependencies ( target ) ) {
2021-04-08 17:14:55 +02:00
updateKitEnvironment ( kit , target ) ;
}
}
}
2021-09-29 17:23:11 +02:00
repo . deletePackagesAndTargets ( ) ;
2021-04-08 17:14:55 +02:00
delete qtForMCUsPackage ;
}
2021-02-09 17:27:02 +01:00
/**
* @ brief Fix / update existing kits if needed
*/
void McuSupportOptions : : fixExistingKits ( )
{
for ( Kit * kit : KitManager : : kits ( ) ) {
2022-02-15 11:18:56 +01:00
if ( ! kit - > hasValue ( Constants : : KIT_MCUTARGET_KITVERSION_KEY ) )
2021-02-09 17:27:02 +01:00
continue ;
2021-03-31 16:47:22 +02:00
if ( kit - > isAutoDetected ( ) ) {
kit - > setAutoDetected ( false ) ;
}
2021-02-09 17:27:02 +01:00
// Check if the MCU kits are flagged as supplying a QtQuick import path, in order
// to tell the QMLJS code-model that it won't need to add a fall-back import
// path.
const auto bringsQtQuickImportPath = QtSupport : : SuppliesQtQuickImportPath : : id ( ) ;
auto irrelevantAspects = kit - > irrelevantAspects ( ) ;
if ( ! irrelevantAspects . contains ( bringsQtQuickImportPath ) ) {
irrelevantAspects . insert ( bringsQtQuickImportPath ) ;
kit - > setIrrelevantAspects ( irrelevantAspects ) ;
}
if ( ! kit - > hasValue ( bringsQtQuickImportPath ) ) {
kit - > setValue ( bringsQtQuickImportPath , true ) ;
}
2021-02-26 14:22:42 +01:00
// Check if the MCU kit supplies its import path.
const auto kitQmlImportPath = QtSupport : : KitQmlImportPath : : id ( ) ;
if ( ! irrelevantAspects . contains ( kitQmlImportPath ) ) {
irrelevantAspects . insert ( kitQmlImportPath ) ;
kit - > setIrrelevantAspects ( irrelevantAspects ) ;
}
if ( ! kit - > hasValue ( kitQmlImportPath ) ) {
auto config = CMakeProjectManager : : CMakeConfigurationKitAspect : : configuration ( kit ) ;
for ( const auto & cfgItem : qAsConst ( config ) ) {
if ( cfgItem . key = = " QUL_GENERATORS " ) {
auto idx = cfgItem . value . indexOf ( " /lib/cmake/Qul " ) ;
auto qulDir = cfgItem . value . left ( idx ) ;
kit - > setValue ( kitQmlImportPath , QVariant ( qulDir + " /include/qul " ) ) ;
break ;
}
}
}
2021-02-26 14:33:34 +01:00
// Check if the MCU kit has the flag for merged header/qml-import paths set.
const auto mergedPaths = QtSupport : : KitHasMergedHeaderPathsWithQmlImportPaths : : id ( ) ;
if ( ! irrelevantAspects . contains ( mergedPaths ) ) {
irrelevantAspects . insert ( mergedPaths ) ;
kit - > setIrrelevantAspects ( irrelevantAspects ) ;
}
if ( ! kit - > value ( mergedPaths , false ) . toBool ( ) ) {
kit - > setValue ( mergedPaths , true ) ;
}
2021-02-09 17:27:02 +01:00
}
2021-03-09 18:28:58 +01:00
// Fix kit dependencies for known targets
auto qtForMCUsPackage = Sdk : : createQtForMCUsPackage ( ) ;
qtForMCUsPackage - > updateStatus ( ) ;
if ( qtForMCUsPackage - > validStatus ( ) ) {
2021-09-30 18:30:02 +02:00
FilePath dir = qtForMCUsPackage - > path ( ) ;
2021-09-29 17:23:11 +02:00
McuSdkRepository repo ;
Sdk : : targetsAndPackages ( dir , & repo ) ;
2022-02-15 11:18:56 +01:00
for ( const auto & target : qAsConst ( repo . mcuTargets ) )
for ( auto kit : existingKits ( target ) ) {
2021-03-09 18:28:58 +01:00
if ( McuDependenciesKitAspect : : dependencies ( kit ) . isEmpty ( ) ) {
setKitDependencies ( kit , target , qtForMCUsPackage ) ;
}
}
2021-09-29 17:23:11 +02:00
repo . deletePackagesAndTargets ( ) ;
2021-03-09 18:28:58 +01:00
}
delete qtForMCUsPackage ;
2021-02-09 17:27:02 +01:00
}
2022-02-15 11:18:56 +01:00
} // namespace Internal
} // namespace McuSupport