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.
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "mcusupportconstants.h"
# include "mcusupportoptions.h"
2020-03-12 14:25:49 +01:00
# include "mcusupportsdk.h"
2021-03-10 16:38:45 +01:00
# include "mcusupportplugin.h"
2019-10-22 14:33:31 +02:00
2020-11-13 14:00:18 +01:00
# include <baremetal/baremetalconstants.h>
2020-04-07 18:19:32 +02:00
# include <cmakeprojectmanager/cmaketoolmanager.h>
2021-02-26 14:22:42 +01:00
# include <cmakeprojectmanager/cmakekitinformation.h>
2019-10-22 14:33:31 +02:00
# include <coreplugin/icore.h>
2020-03-24 18:58:29 +01:00
# include <coreplugin/helpmanager.h>
2020-12-04 16:32:34 +01:00
# include <coreplugin/messagemanager.h>
2019-10-22 14:33:31 +02:00
# include <cmakeprojectmanager/cmakekitinformation.h>
# include <debugger/debuggeritem.h>
# include <debugger/debuggeritemmanager.h>
# include <debugger/debuggerkitinformation.h>
2020-04-07 18:19:32 +02:00
# include <projectexplorer/abi.h>
2019-10-22 14:33:31 +02:00
# include <projectexplorer/projectexplorerconstants.h>
# include <projectexplorer/toolchain.h>
# include <projectexplorer/toolchainmanager.h>
# include <projectexplorer/kitmanager.h>
# include <projectexplorer/kitinformation.h>
# include <projectexplorer/devicesupport/devicemanager.h>
2020-04-07 18:19:32 +02:00
# include <qtsupport/qtkitinformation.h>
2020-04-02 19:31:52 +02:00
# include <qtsupport/qtversionmanager.h>
2019-10-22 14:33:31 +02:00
# 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>
# 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>
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 {
2020-12-07 10:46:13 +01:00
static const int KIT_VERSION = 8 ; // Bumps up whenever details in Kit creation change
2020-04-22 23:24:54 +02:00
2020-06-05 00:33:06 +02:00
static QString packagePathFromSettings ( const QString & settingsKey ,
QSettings : : Scope scope = QSettings : : UserScope ,
const QString & defaultPath = { } )
2020-03-24 18:58:29 +01:00
{
2020-10-16 15:10:17 +02:00
QSettings * settings = Core : : ICore : : settings ( scope ) ;
const QString key = QLatin1String ( Constants : : SETTINGS_GROUP ) + ' / ' +
QLatin1String ( Constants : : SETTINGS_KEY_PACKAGE_PREFIX ) + settingsKey ;
const QString path = settings - > value ( key , defaultPath ) . toString ( ) ;
2020-11-20 16:08:08 +01:00
return FilePath : : fromUserInput ( path ) . toString ( ) ;
2020-03-24 18:58:29 +01:00
}
2020-10-16 15:10:17 +02:00
static bool automaticKitCreationFromSettings ( QSettings : : Scope scope = QSettings : : UserScope )
{
QSettings * settings = Core : : ICore : : settings ( scope ) ;
const QString key = QLatin1String ( Constants : : SETTINGS_GROUP ) + ' / ' +
QLatin1String ( Constants : : SETTINGS_KEY_AUTOMATIC_KIT_CREATION ) ;
bool automaticKitCreation = settings - > value ( key , true ) . toBool ( ) ;
return automaticKitCreation ;
}
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
}
2019-11-15 08:38:55 +01:00
McuPackage : : McuPackage ( const QString & label , const QString & defaultPath ,
2021-02-15 16:20:38 +01:00
const QString & detectionPath , const QString & settingsKey ,
const McuPackageVersionDetector * versionDetector )
2019-10-22 14:33:31 +02:00
: m_label ( label )
2020-06-05 00:33:06 +02:00
, m_defaultPath ( packagePathFromSettings ( settingsKey , QSettings : : SystemScope , defaultPath ) )
2019-10-22 14:33:31 +02:00
, m_detectionPath ( detectionPath )
, m_settingsKey ( settingsKey )
2021-02-15 16:20:38 +01:00
, m_versionDetector ( versionDetector )
2019-10-22 14:33:31 +02:00
{
2020-06-05 00:33:06 +02:00
m_path = packagePathFromSettings ( settingsKey , QSettings : : UserScope , m_defaultPath ) ;
2020-10-16 15:10:17 +02:00
m_automaticKitCreation = automaticKitCreationFromSettings ( QSettings : : UserScope ) ;
2019-10-22 14:33:31 +02:00
}
2020-12-04 16:32:34 +01:00
QString McuPackage : : basePath ( ) const
{
return m_fileChooser ! = nullptr ? m_fileChooser - > filePath ( ) . toString ( ) : m_path ;
}
2019-11-15 08:38:55 +01:00
QString McuPackage : : path ( ) const
2019-10-22 14:33:31 +02:00
{
2020-12-04 16:32:34 +01:00
return QFileInfo ( basePath ( ) + m_relativePathModifier ) . absoluteFilePath ( ) ;
2019-10-22 14:33:31 +02:00
}
2019-11-15 08:38:55 +01:00
QString McuPackage : : label ( ) const
2019-10-22 14:33:31 +02:00
{
return m_label ;
}
2020-07-03 09:46:44 +02:00
QString McuPackage : : defaultPath ( ) const
{
return m_defaultPath ;
}
2019-11-15 08:38:55 +01:00
QString McuPackage : : detectionPath ( ) const
2019-10-22 14:33:31 +02:00
{
return m_detectionPath ;
}
2019-11-15 08:38:55 +01:00
QWidget * McuPackage : : widget ( )
2019-10-22 14:33:31 +02:00
{
if ( m_widget )
return m_widget ;
m_widget = new QWidget ;
2020-09-17 11:05:28 +02:00
m_fileChooser = new PathChooser ;
m_fileChooser - > lineEdit ( ) - > setButtonIcon ( FancyLineEdit : : Right ,
Icons : : RESET . icon ( ) ) ;
m_fileChooser - > lineEdit ( ) - > setButtonVisible ( FancyLineEdit : : Right , true ) ;
connect ( m_fileChooser - > lineEdit ( ) , & FancyLineEdit : : rightButtonClicked , this , [ & ] {
2020-06-05 00:33:06 +02:00
m_fileChooser - > setPath ( m_defaultPath ) ;
} ) ;
2019-10-22 14:33:31 +02:00
auto layout = new QGridLayout ( m_widget ) ;
layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
2020-09-17 11:05:28 +02:00
m_infoLabel = new InfoLabel ( ) ;
2019-10-22 14:33:31 +02:00
if ( ! m_downloadUrl . isEmpty ( ) ) {
auto downLoadButton = new QToolButton ;
2020-09-17 11:05:28 +02:00
downLoadButton - > setIcon ( Icons : : ONLINE . icon ( ) ) ;
2019-10-22 14:33:31 +02:00
downLoadButton - > setToolTip ( tr ( " Download from \" %1 \" " ) . arg ( m_downloadUrl ) ) ;
2020-09-17 11:05:28 +02:00
QObject : : connect ( downLoadButton , & QToolButton : : pressed , this , [ this ] {
2019-10-22 14:33:31 +02:00
QDesktopServices : : openUrl ( m_downloadUrl ) ;
} ) ;
layout - > addWidget ( downLoadButton , 0 , 2 ) ;
}
layout - > addWidget ( m_fileChooser , 0 , 0 , 1 , 2 ) ;
2019-12-11 21:17:53 +01:00
layout - > addWidget ( m_infoLabel , 1 , 0 , 1 , - 1 ) ;
2019-10-22 14:33:31 +02:00
2019-11-13 18:37:27 +01:00
m_fileChooser - > setPath ( m_path ) ;
2020-12-04 16:32:34 +01:00
QObject : : connect ( this , & McuPackage : : statusChanged , this , [ this ] {
updateStatusUi ( ) ;
} ) ;
2020-09-17 11:05:28 +02:00
QObject : : connect ( m_fileChooser , & PathChooser : : pathChanged , this , [ this ] {
2020-12-04 16:32:34 +01:00
updatePath ( ) ;
2019-11-13 18:37:27 +01:00
emit changed ( ) ;
} ) ;
updateStatus ( ) ;
2019-10-22 14:33:31 +02:00
return m_widget ;
}
2019-11-15 08:38:55 +01:00
McuPackage : : Status McuPackage : : status ( ) const
2019-10-22 14:33:31 +02:00
{
return m_status ;
}
2021-02-15 16:20:38 +01:00
bool McuPackage : : validStatus ( ) const
{
return m_status = = McuPackage : : ValidPackage | | m_status = = McuPackage : : ValidPackageMismatchedVersion ;
}
2019-11-15 08:38:55 +01:00
void McuPackage : : setDownloadUrl ( const QString & url )
2019-10-22 14:33:31 +02:00
{
m_downloadUrl = url ;
}
2019-11-15 08:38:55 +01:00
void McuPackage : : setEnvironmentVariableName ( const QString & name )
2019-10-22 14:33:31 +02:00
{
m_environmentVariableName = name ;
}
2019-11-15 08:38:55 +01:00
QString McuPackage : : environmentVariableName ( ) const
2019-10-22 14:33:31 +02:00
{
return m_environmentVariableName ;
}
2019-11-15 08:38:55 +01:00
void McuPackage : : setAddToPath ( bool addToPath )
2019-10-22 14:33:31 +02:00
{
m_addToPath = addToPath ;
}
2019-11-15 08:38:55 +01:00
bool McuPackage : : addToPath ( ) const
2019-10-22 14:33:31 +02:00
{
return m_addToPath ;
}
2020-10-16 15:10:17 +02:00
void McuPackage : : writeGeneralSettings ( ) const
{
const QString key = QLatin1String ( Constants : : SETTINGS_GROUP ) + ' / ' +
QLatin1String ( Constants : : SETTINGS_KEY_AUTOMATIC_KIT_CREATION ) ;
QSettings * settings = Core : : ICore : : settings ( ) ;
settings - > setValue ( key , m_automaticKitCreation ) ;
}
2021-04-08 17:14:55 +02:00
bool McuPackage : : writeToSettings ( ) const
2019-10-22 14:33:31 +02:00
{
2021-04-08 17:14:55 +02:00
const QString savedPath = packagePathFromSettings ( m_settingsKey , QSettings : : UserScope , m_defaultPath ) ;
2020-06-03 09:28:47 +02:00
const QString key = QLatin1String ( Constants : : SETTINGS_GROUP ) + ' / ' +
QLatin1String ( Constants : : SETTINGS_KEY_PACKAGE_PREFIX ) + m_settingsKey ;
2020-11-19 15:34:59 +01:00
Core : : ICore : : settings ( ) - > setValueWithDefault ( key , m_path , m_defaultPath ) ;
2021-04-08 17:14:55 +02:00
return savedPath ! = m_path ;
2019-10-22 14:33:31 +02:00
}
2019-11-15 08:38:55 +01:00
void McuPackage : : setRelativePathModifier ( const QString & path )
2019-10-22 14:33:31 +02:00
{
m_relativePathModifier = path ;
}
2021-02-15 16:20:38 +01:00
void McuPackage : : setVersions ( const QVector < QString > & versions )
{
m_versions = versions ;
}
2020-10-16 15:10:17 +02:00
bool McuPackage : : automaticKitCreationEnabled ( ) const
{
return m_automaticKitCreation ;
}
void McuPackage : : setAutomaticKitCreationEnabled ( const bool enabled )
{
m_automaticKitCreation = enabled ;
}
2020-12-04 16:32:34 +01:00
void McuPackage : : updatePath ( )
{
m_path = m_fileChooser - > rawPath ( ) ;
m_fileChooser - > lineEdit ( ) - > button ( FancyLineEdit : : Right ) - > setEnabled ( m_path ! = m_defaultPath ) ;
updateStatus ( ) ;
}
2019-11-15 08:38:55 +01:00
void McuPackage : : updateStatus ( )
2019-10-22 14:33:31 +02:00
{
2020-12-04 16:32:34 +01:00
bool validPath = ! m_path . isEmpty ( ) & & FilePath : : fromString ( m_path ) . exists ( ) ;
const FilePath detectionPath = FilePath : : fromString ( basePath ( ) + " / " + m_detectionPath ) ;
2020-04-09 23:50:03 +02:00
const bool validPackage = m_detectionPath . isEmpty ( ) | | detectionPath . exists ( ) ;
2021-02-15 16:20:38 +01:00
m_detectedVersion = validPath & & validPackage & & m_versionDetector ? m_versionDetector - > parseVersion ( basePath ( ) ) : QString ( ) ;
const bool validVersion = m_detectedVersion . isEmpty ( ) | |
m_versions . isEmpty ( ) | | m_versions . contains ( m_detectedVersion ) ;
2019-10-22 14:33:31 +02:00
2021-02-15 16:20:38 +01:00
m_status = validPath ?
( validPackage ?
( validVersion ? ValidPackage : ValidPackageMismatchedVersion )
: ValidPathInvalidPackage )
: m_path . isEmpty ( ) ? EmptyPath : InvalidPath ;
2020-12-04 16:32:34 +01:00
emit statusChanged ( ) ;
}
2019-10-22 14:33:31 +02:00
2020-12-04 16:32:34 +01:00
void McuPackage : : updateStatusUi ( )
{
2021-03-04 17:07:49 +01:00
switch ( m_status ) {
case ValidPackage : m_infoLabel - > setType ( InfoLabel : : Ok ) ; break ;
case ValidPackageMismatchedVersion : m_infoLabel - > setType ( InfoLabel : : Warning ) ; break ;
default : m_infoLabel - > setType ( InfoLabel : : NotOk ) ; break ;
}
2020-12-04 16:32:34 +01:00
m_infoLabel - > setText ( statusText ( ) ) ;
}
2019-10-22 14:33:31 +02:00
2020-12-04 16:32:34 +01:00
QString McuPackage : : statusText ( ) const
{
const QString displayPackagePath = FilePath : : fromString ( m_path ) . toUserOutput ( ) ;
2021-03-04 17:07:49 +01:00
const QString displayVersions = QStringList ( m_versions . toList ( ) ) . join ( " or " ) ;
2021-02-15 16:20:38 +01:00
const QString displayRequiredPath = QString ( " %1 %2 " ) . arg (
FilePath : : fromString ( m_detectionPath ) . toUserOutput ( ) ,
displayVersions ) ;
const QString displayDetectedPath = QString ( " %1 %2 " ) . arg (
FilePath : : fromString ( m_detectionPath ) . toUserOutput ( ) ,
m_detectedVersion ) ;
2020-12-04 16:32:34 +01:00
QString response ;
2019-10-22 14:33:31 +02:00
switch ( m_status ) {
case ValidPackage :
2020-12-04 16:32:34 +01:00
response = m_detectionPath . isEmpty ( )
2021-02-15 16:20:38 +01:00
? ( m_detectedVersion . isEmpty ( )
? tr ( " Path %1 exists. " ) . arg ( displayPackagePath )
: tr ( " Path %1 exists. Version %2 was found. " )
. arg ( displayPackagePath , m_detectedVersion ) )
2020-12-04 16:32:34 +01:00
: tr ( " Path %1 is valid, %2 was found. " )
2021-02-15 16:20:38 +01:00
. arg ( displayPackagePath , displayDetectedPath ) ;
break ;
case ValidPackageMismatchedVersion : {
const QString versionWarning = m_versions . size ( ) = = 1 ?
2021-03-04 17:07:49 +01:00
tr ( " but only version %1 is supported " ) . arg ( m_versions . first ( ) ) :
tr ( " but only versions %1 are supported " ) . arg ( displayVersions ) ;
response = tr ( " Path %1 is valid, %2 was found, %3. " )
. arg ( displayPackagePath , displayDetectedPath , versionWarning ) ;
2019-10-22 14:33:31 +02:00
break ;
2021-02-15 16:20:38 +01:00
}
2019-10-22 14:33:31 +02:00
case ValidPathInvalidPackage :
2020-12-04 16:32:34 +01:00
response = tr ( " Path %1 exists, but does not contain %2. " )
2021-02-15 16:20:38 +01:00
. arg ( displayPackagePath , displayRequiredPath ) ;
2019-10-22 14:33:31 +02:00
break ;
case InvalidPath :
2020-12-04 16:32:34 +01:00
response = tr ( " Path %1 does not exist. " ) . arg ( displayPackagePath ) ;
break ;
case EmptyPath :
response = m_detectionPath . isEmpty ( )
? tr ( " Path is empty. " )
: tr ( " Path is empty, %1 not found. " )
2021-02-15 16:20:38 +01:00
. arg ( displayRequiredPath ) ;
2019-10-22 14:33:31 +02:00
break ;
}
2020-12-04 16:32:34 +01:00
return response ;
2019-10-22 14:33:31 +02:00
}
2020-09-18 11:16:37 +02:00
McuToolChainPackage : : McuToolChainPackage ( const QString & label ,
const QString & defaultPath ,
const QString & detectionPath ,
const QString & settingsKey ,
2021-02-15 16:20:38 +01:00
McuToolChainPackage : : Type type ,
const McuPackageVersionDetector * versionDetector )
: McuPackage ( label , defaultPath , detectionPath , settingsKey , versionDetector )
2020-02-26 16:41:52 +01:00
, m_type ( type )
{
}
McuToolChainPackage : : Type McuToolChainPackage : : type ( ) const
{
return m_type ;
}
2020-09-18 11:16:37 +02:00
bool McuToolChainPackage : : isDesktopToolchain ( ) const
{
return m_type = = TypeMSVC | | m_type = = TypeGCC ;
}
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 ( ) ;
return ( abi . osFlavor ( ) = = Abi : : WindowsMsvc2017Flavor | | abi . osFlavor ( ) = = Abi : : WindowsMsvc2019Flavor )
& & abi . architecture ( ) = = Abi : : X86Architecture
& & abi . wordWidth ( ) = = 64
& & t - > language ( ) = = language ;
} ) ;
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 ( ) ;
2020-09-18 11:16:37 +02:00
return abi . os ( ) ! = Abi : : WindowsOS
2020-04-07 18:19:32 +02:00
& & abi . architecture ( ) = = Abi : : X86Architecture
& & abi . wordWidth ( ) = = 64
& & t - > language ( ) = = language ;
} ) ;
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
{
ToolChain * toolChain = ToolChainManager : : toolChain ( [ & path , language ] ( const ToolChain * t ) {
return t - > compilerCommand ( ) = = path & & t - > language ( ) = = language ;
} ) ;
if ( ! toolChain ) {
ToolChainFactory * gccFactory =
Utils : : findOrDefault ( ToolChainFactory : : allToolChainFactories ( ) , [ ] ( ToolChainFactory * f ) {
return f - > supportedToolChainType ( ) = = ProjectExplorer : : Constants : : GCC_TOOLCHAIN_TYPEID ;
} ) ;
if ( gccFactory ) {
const QList < ToolChain * > detected = gccFactory - > detectForImport ( { path , language } ) ;
if ( ! detected . isEmpty ( ) ) {
toolChain = detected . first ( ) ;
toolChain - > setDetection ( ToolChain : : ManualDetection ) ;
toolChain - > setDisplayName ( " Arm GCC " ) ;
ToolChainManager : : registerToolChain ( toolChain ) ;
}
}
}
return toolChain ;
}
2020-11-13 14:00:18 +01:00
static ToolChain * iarToolChain ( Id language )
{
ToolChain * toolChain = ToolChainManager : : toolChain ( [ language ] ( const ToolChain * t ) {
return t - > typeId ( ) = = BareMetal : : Constants : : IAREW_TOOLCHAIN_TYPEID
& & t - > language ( ) = = language ;
} ) ;
if ( ! toolChain ) {
ToolChainFactory * iarFactory =
Utils : : findOrDefault ( ToolChainFactory : : allToolChainFactories ( ) , [ ] ( ToolChainFactory * f ) {
return f - > supportedToolChainType ( ) = = BareMetal : : Constants : : IAREW_TOOLCHAIN_TYPEID ;
} ) ;
if ( iarFactory ) {
2021-04-27 16:06:50 +02:00
const QList < ToolChain * > detected = iarFactory - > autoDetect ( { } , { } ) ;
2020-11-13 14:00:18 +01:00
for ( auto tc : detected ) {
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
{
2020-09-17 11:05:28 +02:00
ToolChain * tc = nullptr ;
2020-09-18 11:16:37 +02:00
if ( m_type = = TypeMSVC )
tc = msvcToolChain ( language ) ;
else if ( m_type = = TypeGCC )
tc = gccToolChain ( language ) ;
2020-11-13 14:00:18 +01:00
else if ( m_type = = TypeIAR ) {
tc = iarToolChain ( language ) ;
}
2020-09-18 11:16:37 +02:00
else {
2020-04-07 18:19:32 +02:00
const QLatin1String compilerName (
language = = ProjectExplorer : : Constants : : C_LANGUAGE_ID ? " gcc " : " g++ " ) ;
2020-09-17 11:05:28 +02:00
const FilePath compiler = FilePath : : fromUserInput (
HostOsInfo : : withExecutableSuffix (
2020-04-07 18:19:32 +02:00
path ( ) + (
m_type = = TypeArmGcc
2020-11-13 14:00:18 +01:00
? " /bin/arm-none-eabi-%1 " : " /bar/foo-keil-%1 " ) ) . arg ( compilerName ) ) ;
2020-04-07 18:19:32 +02:00
tc = armGccToolChain ( compiler , language ) ;
}
2020-02-26 16:41:52 +01:00
return tc ;
}
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 ) {
case TypeArmGcc : return QLatin1String ( " armgcc " ) ;
case TypeIAR : return QLatin1String ( " iar " ) ;
case TypeKEIL : return QLatin1String ( " keil " ) ;
case TypeGHS : return QLatin1String ( " ghs " ) ;
case TypeGHSArm : return QLatin1String ( " ghs-arm " ) ;
default : return QLatin1String ( " unsupported " ) ;
}
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 ;
2020-09-17 11:05:28 +02:00
const FilePath command = FilePath : : fromUserInput (
HostOsInfo : : withExecutableSuffix ( path ( ) + (
2020-02-26 16:41:52 +01:00
m_type = = TypeArmGcc
? " /bin/arm-none-eabi-gdb-py " : m_type = = TypeIAR
2020-11-13 14:00:18 +01:00
? " ../common/bin/CSpyBat " : " /bar/foo-keil-gdb " ) ) ) ;
2020-02-26 16:41:52 +01:00
const DebuggerItem * debugger = DebuggerItemManager : : findByCommand ( command ) ;
QVariant debuggerId ;
if ( ! debugger ) {
DebuggerItem newDebugger ;
newDebugger . setCommand ( command ) ;
2020-03-12 13:46:25 +01:00
const QString displayName = m_type = = TypeArmGcc
? McuPackage : : tr ( " Arm GDB at %1 " )
2020-11-13 14:00:18 +01:00
: m_type = = TypeIAR ? QLatin1String ( " CSpy " )
2020-03-12 13:46:25 +01:00
: QLatin1String ( " /bar/foo-keil-gdb " ) ;
2020-02-26 16:41:52 +01:00
newDebugger . setUnexpandedDisplayName ( displayName . arg ( command . toUserOutput ( ) ) ) ;
debuggerId = DebuggerItemManager : : registerDebugger ( newDebugger ) ;
} else {
debuggerId = debugger - > id ( ) ;
}
return debuggerId ;
}
2020-09-18 11:16:37 +02:00
McuTarget : : McuTarget ( const QVersionNumber & qulVersion ,
const Platform & platform , OS os ,
2020-04-23 23:30:40 +02:00
const QVector < McuPackage * > & packages ,
const McuToolChainPackage * toolChainPackage )
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 )
2019-10-22 14:33:31 +02:00
{
}
2019-11-20 13:32:10 +01:00
QVector < McuPackage * > McuTarget : : packages ( ) const
{
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 ;
}
2020-09-18 11:16:37 +02:00
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
{
2021-02-15 16:20:38 +01:00
return Utils : : allOf ( packages ( ) , [ ] ( McuPackage * 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
{
for ( auto package : packages ( ) ) {
package - > updateStatus ( ) ;
2021-02-15 16:20:38 +01:00
if ( ! package - > validStatus ( ) )
printMessage ( tr ( " Error creating kit for target %1, package %2: %3 " ) . arg (
2020-12-04 16:32:34 +01:00
McuSupportOptions : : kitName ( this ) ,
package - > label ( ) ,
package - > statusText ( ) ) ,
true ) ;
2021-02-15 16:20:38 +01:00
if ( package - > status ( ) = = McuPackage : : ValidPackageMismatchedVersion )
printMessage ( tr ( " Warning creating kit for target %1, package %2: %3 " ) . arg (
McuSupportOptions : : kitName ( this ) ,
package - > label ( ) ,
package - > statusText ( ) ) ,
false ) ;
2020-12-04 16:32:34 +01:00
}
}
2020-06-30 17:09:03 +02:00
QVersionNumber McuTarget : : qulVersion ( ) const
{
return m_qulVersion ;
}
2019-11-21 01:22:28 +01:00
int McuTarget : : colorDepth ( ) const
{
return m_colorDepth ;
}
void McuTarget : : setColorDepth ( int colorDepth )
{
m_colorDepth = colorDepth ;
}
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
{
2020-03-18 03:17:35 +01:00
connect ( qtForMCUsSdkPackage , & McuPackage : : 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 ( )
{
2020-09-17 11:05:28 +02:00
setQulDir ( FilePath : : fromUserInput ( 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 (
2020-12-04 08:47:55 +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 ;
2021-02-09 17:06:24 +01:00
auto examples = {
std : : make_pair ( QStringLiteral ( " demos " ) , tr ( " Qt for MCUs Demos " ) ) ,
std : : make_pair ( QStringLiteral ( " examples " ) , tr ( " Qt for MCUs Examples " ) )
} ;
for ( const auto & dir : examples ) {
const FilePath examplesDir =
McuSupportOptions : : qulDirFromSettings ( ) . pathAppended ( dir . first ) ;
if ( ! examplesDir . exists ( ) )
continue ;
QtSupport : : QtVersionManager : : registerExampleSet ( dir . second , docsDir . toString ( ) ,
examplesDir . toString ( ) ) ;
}
2020-04-02 19:31:52 +02:00
}
2020-03-18 03:17:35 +01:00
void McuSupportOptions : : deletePackagesAndTargets ( )
2019-10-22 14:33:31 +02:00
{
qDeleteAll ( packages ) ;
packages . clear ( ) ;
2019-11-15 08:38:55 +01:00
qDeleteAll ( mcuTargets ) ;
mcuTargets . clear ( ) ;
2019-10-22 14:33:31 +02:00
}
2020-06-30 17:09:03 +02:00
const QVersionNumber & McuSupportOptions : : minimalQulVersion ( )
2020-03-25 15:09:02 +01:00
{
2020-06-29 23:27:16 +02:00
static const QVersionNumber v ( { 1 , 3 } ) ;
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 ( ) )
2020-12-04 16:32:34 +01:00
Sdk : : targetsAndPackages ( dir , & packages , & mcuTargets ) ;
2021-02-09 17:27:02 +01:00
for ( auto package : qAsConst ( packages ) )
2020-09-17 11:05:28 +02:00
connect ( package , & McuPackage : : changed , this , & McuSupportOptions : : changed ) ;
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
{
2020-09-17 11:05:28 +02:00
return FilePath : : fromUserInput (
2020-06-05 00:33:06 +02:00
packagePathFromSettings ( Constants : : SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK ,
QSettings : : UserScope ) ) ;
2020-03-24 18:58:29 +01:00
}
2021-02-26 14:22:42 +01:00
static void setKitProperties ( const QString & kitName , Kit * k , const McuTarget * mcuTarget ,
const QString & 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-02-26 14:22:42 +01:00
k - > setValue ( QtSupport : : KitQmlImportPath : : id ( ) , QVariant ( sdkPath + " /include/qul " ) ) ;
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
}
2020-09-17 11:05:28 +02:00
static void setKitToolchains ( Kit * k , const McuToolChainPackage * tcPackage )
2019-10-22 14:33:31 +02:00
{
2020-04-09 23:50:03 +02:00
// No Green Hills toolchain, because support for it is missing.
2020-11-13 14:00:18 +01:00
if ( tcPackage - > type ( ) = = McuToolChainPackage : : TypeUnsupported
2021-05-27 10:48:22 +02:00
| | tcPackage - > type ( ) = = McuToolChainPackage : : TypeGHS
| | tcPackage - > type ( ) = = McuToolChainPackage : : TypeGHSArm )
2020-04-09 23:50:03 +02:00
return ;
2020-09-17 11:05:28 +02:00
ToolChainKitAspect : : setToolChain ( k , tcPackage - > toolChain (
ProjectExplorer : : Constants : : C_LANGUAGE_ID ) ) ;
ToolChainKitAspect : : setToolChain ( k , tcPackage - > toolChain (
ProjectExplorer : : Constants : : CXX_LANGUAGE_ID ) ) ;
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
{
2020-04-07 18:19:32 +02:00
// Qt Creator seems to be smart enough to deduce the right Kit debugger from the ToolChain
2020-04-09 23:50:03 +02:00
// We rely on that at least in the Desktop case.
2020-09-18 11:16:37 +02:00
if ( tcPackage - > isDesktopToolchain ( )
2020-11-13 14:00:18 +01:00
// No Green Hills and IAR debugger, because support for it is missing.
| | tcPackage - > type ( ) = = McuToolChainPackage : : TypeUnsupported
| | tcPackage - > type ( ) = = McuToolChainPackage : : TypeGHS
2021-05-27 10:48:22 +02:00
| | tcPackage - > type ( ) = = McuToolChainPackage : : TypeGHSArm
2020-11-13 14:00:18 +01:00
| | tcPackage - > type ( ) = = McuToolChainPackage : : TypeIAR )
2020-04-07 18:19:32 +02:00
return ;
2020-02-26 16:41:52 +01:00
Debugger : : DebuggerKitAspect : : setDebugger ( k , tcPackage - > debuggerId ( ) ) ;
2019-10-22 14:33:31 +02:00
}
2020-09-17 11:05:28 +02: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
}
2020-09-17 11:05:28 +02:00
static void setKitEnvironment ( Kit * k , const McuTarget * mcuTarget ,
2020-04-23 23:30:40 +02:00
const McuPackage * 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 ( )
2020-04-07 18:19:32 +02:00
& & ! CMakeProjectManager : : CMakeToolManager : : defaultCMakeTool ( ) - > hasFileApi ( ) )
pathAdditions . append ( QDir : : toNativeSeparators ( qtForMCUsSdkPackage - > path ( ) + " /bin " ) ) ;
2020-04-23 23:30:40 +02:00
auto processPackage = [ & pathAdditions , & changes ] ( const McuPackage * package ) {
2019-10-22 14:33:31 +02:00
if ( package - > addToPath ( ) )
pathAdditions . append ( QDir : : toNativeSeparators ( package - > path ( ) ) ) ;
if ( ! package - > environmentVariableName ( ) . isEmpty ( ) )
changes . append ( { package - > environmentVariableName ( ) ,
QDir : : toNativeSeparators ( package - > path ( ) ) } ) ;
2020-04-23 23:30:40 +02:00
} ;
for ( auto package : mcuTarget - > packages ( ) )
processPackage ( package ) ;
processPackage ( qtForMCUsSdkPackage ) ;
2021-01-26 12:08:52 +01:00
// Clang not needed in version 1.7+
if ( mcuTarget - > qulVersion ( ) < QVersionNumber { 1 , 7 } ) {
2021-02-02 12:20:00 +01:00
const QString path = QLatin1String ( HostOsInfo : : isWindowsHost ( ) ? " Path " : " PATH " ) ;
2021-01-26 12:08:52 +01:00
pathAdditions . append ( " ${ " + path + " } " ) ;
2021-04-26 15:46:09 +02:00
pathAdditions . append ( Core : : ICore : : libexecPath ( " clang/bin " ) . toUserOutput ( ) ) ;
2021-01-26 12:08:52 +01:00
changes . append ( { path , pathAdditions . join ( HostOsInfo : : pathListSeparator ( ) ) } ) ;
}
2020-08-31 00:05:50 +02:00
if ( kitNeedsQtVersion ( ) )
changes . append ( { QLatin1String ( " LD_LIBRARY_PATH " ) , " %{Qt:QT_INSTALL_LIBS} " } ) ;
2019-10-22 14:33:31 +02:00
EnvironmentKitAspect : : setEnvironmentChanges ( k , changes ) ;
}
2021-03-09 18:28:58 +01:00
static void setKitDependencies ( Kit * k , const McuTarget * mcuTarget ,
const McuPackage * qtForMCUsSdkPackage )
{
NameValueItems dependencies ;
auto processPackage = [ & dependencies ] ( const McuPackage * package ) {
if ( ! package - > environmentVariableName ( ) . isEmpty ( ) )
dependencies . append ( { package - > environmentVariableName ( ) ,
QDir : : toNativeSeparators ( package - > detectionPath ( ) ) } ) ;
} ;
for ( auto package : mcuTarget - > packages ( ) )
processPackage ( package ) ;
processPackage ( qtForMCUsSdkPackage ) ;
McuDependenciesKitAspect : : setDependencies ( k , dependencies ) ;
auto irrelevant = k - > irrelevantAspects ( ) ;
irrelevant . insert ( McuDependenciesKitAspect : : id ( ) ) ;
k - > setIrrelevantAspects ( irrelevant ) ;
}
2021-04-08 17:14:55 +02:00
static void updateKitEnvironment ( Kit * k , const McuTarget * mcuTarget )
{
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 ( ) ,
QDir : : toNativeSeparators ( package - > path ( ) ) } ;
if ( index ! = - 1 )
changes . replace ( index , item ) ;
else
changes . append ( item ) ;
}
}
EnvironmentKitAspect : : setEnvironmentChanges ( k , changes ) ;
}
2020-09-17 11:05:28 +02:00
static void setKitCMakeOptions ( Kit * k , const McuTarget * mcuTarget , const QString & 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
2021-05-27 10:48:22 +02:00
if ( mcuTarget - > toolChainPackage ( ) - > type ( ) ! = McuToolChainPackage : : TypeGHS & &
mcuTarget - > toolChainPackage ( ) - > type ( ) ! = McuToolChainPackage : : TypeGHSArm ) {
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 ( ) ) {
const FilePath cMakeToolchainFile = FilePath : : fromString ( qulDir + " /lib/cmake/Qul/toolchain/ "
+ mcuTarget - > toolChainPackage ( ) - > cmakeToolChainFileName ( ) ) ;
2020-02-26 16:41:52 +01:00
config . append ( CMakeConfigItem (
" CMAKE_TOOLCHAIN_FILE " ,
2020-12-04 16:32:34 +01:00
cMakeToolchainFile . toString ( ) . toUtf8 ( ) ) ) ;
if ( ! cMakeToolchainFile . exists ( ) ) {
2021-07-02 15:00:36 +02:00
printMessage ( McuTarget : : tr ( " Warning for target %1: missing CMake toolchain file expected at %2. " )
2020-12-04 16:32:34 +01:00
. arg ( McuSupportOptions : : kitName ( mcuTarget ) , cMakeToolchainFile . toUserOutput ( ) ) , false ) ;
}
}
const FilePath generatorsPath = FilePath : : fromString ( qulDir + " /lib/cmake/Qul/QulGenerators.cmake " ) ;
2020-02-06 00:17:04 +01:00
config . append ( CMakeConfigItem ( " QUL_GENERATORS " ,
2020-12-04 16:32:34 +01:00
generatorsPath . toString ( ) . toUtf8 ( ) ) ) ;
if ( ! generatorsPath . exists ( ) ) {
printMessage ( McuTarget : : tr ( " Warning for target %1: missing QulGenerators expected at %2. " )
. arg ( McuSupportOptions : : kitName ( mcuTarget ) , generatorsPath . toUserOutput ( ) ) , false ) ;
}
2020-02-06 00:17:04 +01:00
config . append ( CMakeConfigItem ( " QUL_PLATFORM " ,
2020-09-18 11:16:37 +02:00
mcuTarget - > platform ( ) . name . toUtf8 ( ) ) ) ;
2020-08-13 13:10:52 +02:00
if ( mcuTarget - > qulVersion ( ) < = QVersionNumber { 1 , 3 } // OS variable was removed in Qul 1.4
& & mcuTarget - > os ( ) = = McuTarget : : OS : : FreeRTOS )
2020-04-27 20:51:08 +02:00
config . append ( CMakeConfigItem ( " OS " , " FreeRTOS " ) ) ;
2019-11-21 01:22:28 +01:00
if ( mcuTarget - > colorDepth ( ) > = 0 )
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 ( ) ;
if ( type = = McuToolChainPackage : : TypeGHS | | type = = McuToolChainPackage : : TypeGHSArm ) {
// 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-08-13 13:10:52 +02:00
QString os ;
2020-09-18 11:16:37 +02:00
if ( mcuTarget - > qulVersion ( ) < = QVersionNumber { 1 , 3 } & & mcuTarget - > os ( ) = = McuTarget : : OS : : FreeRTOS )
2020-08-13 13:10:52 +02:00
// Starting from Qul 1.4 each OS is a separate platform
os = QLatin1String ( " FreeRTOS " ) ;
2020-11-13 14:00:18 +01:00
const McuToolChainPackage * tcPkg = mcuTarget - > toolChainPackage ( ) ;
const QString compilerName = tcPkg & & ! tcPkg - > isDesktopToolchain ( )
? QString : : fromLatin1 ( " (%1) " ) . arg ( tcPkg - > toolChainName ( ) . toUpper ( ) )
: " " ;
2019-11-21 01:22:28 +01:00
const QString colorDepth = mcuTarget - > colorDepth ( ) > 0
? QString : : fromLatin1 ( " %1bpp " ) . arg ( mcuTarget - > colorDepth ( ) )
: " " ;
2020-09-18 11:16:37 +02:00
const QString targetName = mcuTarget - > platform ( ) . displayName . isEmpty ( )
? mcuTarget - > platform ( ) . name
: mcuTarget - > platform ( ) . displayName ;
2020-11-13 14:00:18 +01:00
return QString : : fromLatin1 ( " Qt for MCUs %1.%2 - %3%4%5%6 " )
2020-08-13 13:10:52 +02:00
. arg ( QString : : number ( mcuTarget - > qulVersion ( ) . majorVersion ( ) ) ,
QString : : number ( mcuTarget - > qulVersion ( ) . minorVersion ( ) ) ,
targetName ,
os ,
2020-11-13 14:00:18 +01:00
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
2020-04-23 23:30:40 +02:00
& & ( ! mcuTarget | | (
2020-09-18 11:16:37 +02:00
kit - > value ( KIT_MCUTARGET_VENDOR_KEY ) = = mcuTarget - > platform ( ) . vendor
& & kit - > value ( KIT_MCUTARGET_MODEL_KEY ) = = mcuTarget - > platform ( ) . name
2020-04-23 23:30:40 +02:00
& & kit - > value ( KIT_MCUTARGET_COLORDEPTH_KEY ) = = mcuTarget - > colorDepth ( )
2020-04-27 20:51:08 +02:00
& & kit - > value ( KIT_MCUTARGET_OS_KEY ) . toInt ( )
= = static_cast < int > ( mcuTarget - > os ( ) )
2020-12-07 10:46:13 +01:00
& & kit - > value ( KIT_MCUTARGET_TOOCHAIN_KEY )
= = mcuTarget - > toolChainPackage ( ) - > toolChainName ( )
2020-04-23 23:30:40 +02:00
) ) ;
2019-10-22 14:33:31 +02:00
} ) ;
2019-11-13 18:37:27 +01:00
}
2019-10-22 14:33:31 +02:00
2021-03-31 16:47:22 +02:00
QList < Kit * > McuSupportOptions : : matchingKits ( const McuTarget * mcuTarget , const McuPackage * qtForMCUsSdkPackage )
{
return Utils : : filtered ( existingKits ( mcuTarget ) , [ mcuTarget , qtForMCUsSdkPackage ] ( Kit * kit ) {
return kitUpToDate ( kit , mcuTarget , qtForMCUsSdkPackage ) ;
} ) ;
}
QList < Kit * > McuSupportOptions : : upgradeableKits ( const McuTarget * mcuTarget , const McuPackage * qtForMCUsSdkPackage )
{
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 (
Utils : : NameValueItem : : toStringList (
EnvironmentKitAspect : : environmentChanges ( kit ) ) ) ;
return Utils : : anyOf ( mcuTarget - > packages ( ) , [ & environment ] ( const McuPackage * package ) {
return ! package - > environmentVariableName ( ) . isEmpty ( ) & &
environment . value ( package - > environmentVariableName ( ) ) ! = QDir : : toNativeSeparators ( package - > path ( ) ) ;
} ) ;
} ) ;
}
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 ( )
2020-04-22 23:24:54 +02: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
}
2020-09-17 11:05:28 +02:00
Kit * McuSupportOptions : : newKit ( const McuTarget * mcuTarget , const McuPackage * 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
{
2020-12-04 16:32:34 +01:00
const QString displayMessage = QCoreApplication : : translate ( " QtForMCUs " , " Qt for MCUs: %1 " ) . arg ( message ) ;
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 (
kit - > value ( McuSupport : : Constants : : KIT_MCUTARGET_SDKVERSION_KEY )
. toString ( ) ) ;
}
QString kitDependencyPath ( const Kit * kit , const QString & variableName )
{
for ( const NameValueItem & nameValueItem : EnvironmentKitAspect : : environmentChanges ( kit ) ) {
if ( nameValueItem . name = = variableName )
return nameValueItem . value ;
}
return QString ( ) ;
}
2021-03-31 16:47:22 +02:00
bool McuSupportOptions : : kitUpToDate ( const Kit * kit , const McuTarget * mcuTarget ,
const McuPackage * qtForMCUsSdkPackage )
{
return kitQulVersion ( kit ) = = mcuTarget - > qulVersion ( ) & &
kitDependencyPath ( kit , qtForMCUsSdkPackage - > environmentVariableName ( ) ) = = qtForMCUsSdkPackage - > path ( ) ;
}
2021-03-10 16:38:45 +01:00
McuSupportOptions : : UpgradeOption McuSupportOptions : : askForKitUpgrades ( )
{
QMessageBox upgradePopup ( Core : : ICore : : dialogParent ( ) ) ;
upgradePopup . setStandardButtons ( QMessageBox : : Cancel ) ;
2021-07-02 15:00:36 +02: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 ] ( ) {
2020-10-16 15:10:17 +02:00
if ( qtForMCUsPackage - > automaticKitCreationEnabled ( ) ) {
2020-12-04 16:32:34 +01:00
qtForMCUsPackage - > updateStatus ( ) ;
2021-02-15 16:20:38 +01:00
if ( ! qtForMCUsPackage - > validStatus ( ) ) {
2020-12-04 16:32:34 +01:00
switch ( qtForMCUsPackage - > status ( ) ) {
case McuPackage : : ValidPathInvalidPackage : {
const QString displayPath = FilePath : : fromString ( qtForMCUsPackage - > detectionPath ( ) )
. toUserOutput ( ) ;
printMessage ( tr ( " Path %1 exists, but does not contain %2. " )
. arg ( qtForMCUsPackage - > path ( ) , displayPath ) ,
true ) ;
break ;
}
case McuPackage : : InvalidPath : {
printMessage ( tr ( " Path %1 does not exist. Add the path in Tools > Options > Devices > MCU. " )
. arg ( qtForMCUsPackage - > path ( ) ) ,
true ) ;
break ;
}
case McuPackage : : EmptyPath : {
printMessage ( tr ( " Missing %1. Add the path in Tools > Options > Devices > MCU. " )
. arg ( qtForMCUsPackage - > detectionPath ( ) ) ,
true ) ;
return ;
}
default : break ;
}
return ;
}
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
auto dir = FilePath : : fromUserInput ( qtForMCUsPackage - > path ( ) ) ;
QVector < McuPackage * > packages ;
QVector < McuTarget * > mcuTargets ;
Sdk : : targetsAndPackages ( dir , & packages , & mcuTargets ) ;
2021-03-10 16:38:45 +01:00
bool needsUpgrade = false ;
for ( auto target : qAsConst ( mcuTargets ) ) {
2021-03-31 16:47:22 +02:00
// if kit already exists, skip
if ( ! matchingKits ( target , qtForMCUsPackage ) . empty ( ) )
2021-03-10 16:38:45 +01:00
continue ;
2021-03-31 16:47:22 +02:00
if ( ! upgradeableKits ( target , qtForMCUsPackage ) . empty ( ) ) {
2021-03-10 16:38:45 +01:00
// if kit exists but wrong version/path
needsUpgrade = true ;
} else {
// if no kits for this target, create
2020-12-04 16:32:34 +01:00
if ( target - > isValid ( ) )
newKit ( target , qtForMCUsPackage ) ;
2021-02-15 16:20:38 +01:00
target - > printPackageProblems ( ) ;
2020-12-04 16:32:34 +01:00
}
2021-03-10 16:38:45 +01:00
}
2020-10-16 15:10:17 +02:00
qDeleteAll ( packages ) ;
qDeleteAll ( mcuTargets ) ;
2021-03-10 16:38:45 +01:00
if ( needsUpgrade )
McuSupportPlugin : : askUserAboutMcuSupportKitsUpgrade ( ) ;
2020-10-16 15:10:17 +02:00
}
2020-12-04 16:32:34 +01:00
} ;
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 ( )
{
if ( ! qtForMCUsSdkPackage - > validStatus ( ) | | mcuTargets . length ( ) = = 0 )
return ;
2021-03-31 16:47:22 +02:00
if ( Utils : : anyOf ( mcuTargets , [ this ] ( const McuTarget * target ) {
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 ( ) ;
auto dir = FilePath : : fromUserInput ( qtForMCUsPackage - > path ( ) ) ;
QVector < McuPackage * > packages ;
QVector < McuTarget * > mcuTargets ;
Sdk : : targetsAndPackages ( dir , & packages , & mcuTargets ) ;
for ( auto target : qAsConst ( 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 ( ) ;
}
}
qDeleteAll ( packages ) ;
qDeleteAll ( mcuTargets ) ;
delete qtForMCUsPackage ;
}
2021-03-31 16:47:22 +02:00
void McuSupportOptions : : upgradeKitInPlace ( ProjectExplorer : : Kit * kit , const McuTarget * mcuTarget , const McuPackage * qtForMCUsSdk )
{
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 ( ) ;
auto dir = FilePath : : fromUserInput ( qtForMCUsPackage - > path ( ) ) ;
QVector < McuPackage * > packages ;
QVector < McuTarget * > mcuTargets ;
Sdk : : targetsAndPackages ( dir , & packages , & mcuTargets ) ;
for ( auto target : qAsConst ( mcuTargets ) ) {
if ( target - > isValid ( ) ) {
for ( auto kit : kitsWithMismatchedDependencies ( target ) ) {
updateKitEnvironment ( kit , target ) ;
}
}
}
qDeleteAll ( packages ) ;
qDeleteAll ( mcuTargets ) ;
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 ( ) ) {
if ( ! kit - > hasValue ( Constants : : KIT_MCUTARGET_KITVERSION_KEY ) )
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 ( ) ) {
auto dir = FilePath : : fromUserInput ( qtForMCUsPackage - > path ( ) ) ;
QVector < McuPackage * > packages ;
QVector < McuTarget * > mcuTargets ;
Sdk : : targetsAndPackages ( dir , & packages , & mcuTargets ) ;
for ( auto target : qAsConst ( mcuTargets ) )
for ( auto kit : existingKits ( target ) ) {
if ( McuDependenciesKitAspect : : dependencies ( kit ) . isEmpty ( ) ) {
setKitDependencies ( kit , target , qtForMCUsPackage ) ;
}
}
qDeleteAll ( packages ) ;
qDeleteAll ( mcuTargets ) ;
}
delete qtForMCUsPackage ;
2021-02-09 17:27:02 +01:00
}
2021-03-09 18:28:58 +01:00
class McuDependenciesKitAspectWidget final : public KitAspectWidget
{
Q_DECLARE_TR_FUNCTIONS ( McuSupport : : McuDependenciesKitAspect )
public :
McuDependenciesKitAspectWidget ( Kit * workingCopy , const KitAspect * ki )
: KitAspectWidget ( workingCopy , ki )
2021-04-07 18:55:21 +02:00
{ }
2021-03-09 18:28:58 +01:00
void makeReadOnly ( ) override { }
void refresh ( ) override { }
2021-04-07 18:55:21 +02:00
void addToLayout ( Utils : : LayoutBuilder & ) override { }
2021-03-09 18:28:58 +01:00
} ;
2019-10-22 14:33:31 +02:00
} // Internal
2021-03-09 18:28:58 +01:00
McuDependenciesKitAspect : : McuDependenciesKitAspect ( )
{
setObjectName ( QLatin1String ( " McuDependenciesKitAspect " ) ) ;
setId ( McuDependenciesKitAspect : : id ( ) ) ;
2021-07-02 15:00:36 +02:00
setDisplayName ( tr ( " MCU Dependencies " ) ) ;
2021-03-09 18:28:58 +01:00
setDescription ( tr ( " Paths to 3rd party dependencies " ) ) ;
setPriority ( 28500 ) ;
}
Tasks McuDependenciesKitAspect : : validate ( const Kit * k ) const
{
Tasks result ;
QTC_ASSERT ( k , return result ) ;
const QVariant checkFormat = k - > value ( McuDependenciesKitAspect : : id ( ) ) ;
if ( ! checkFormat . isNull ( ) & & ! checkFormat . canConvert ( QVariant : : List ) )
2021-07-02 15:00:36 +02:00
return { BuildSystemTask ( Task : : Error , tr ( " The MCU dependencies setting value is invalid. " ) ) } ;
2021-03-09 18:28:58 +01:00
const QVariant envStringList = k - > value ( EnvironmentKitAspect : : id ( ) ) ;
if ( ! envStringList . isNull ( ) & & ! envStringList . canConvert ( QVariant : : List ) )
return { BuildSystemTask ( Task : : Error , tr ( " The environment setting value is invalid. " ) ) } ;
const auto environment = Utils : : NameValueDictionary ( envStringList . toStringList ( ) ) ;
for ( const auto & dependency : dependencies ( k ) ) {
if ( ! environment . hasKey ( dependency . name ) ) {
result < < BuildSystemTask ( Task : : Warning , tr ( " Environment variable %1 not defined. " ) . arg ( dependency . name ) ) ;
} else {
const auto path = Utils : : FilePath : : fromString ( environment . value ( dependency . name ) + " / " + dependency . value ) ;
if ( ! path . exists ( ) ) {
result < < BuildSystemTask ( Task : : Warning , tr ( " %1 not found. " ) . arg ( path . toUserOutput ( ) ) ) ;
}
}
}
return result ;
}
void McuDependenciesKitAspect : : fix ( Kit * k )
{
QTC_ASSERT ( k , return ) ;
const QVariant variant = k - > value ( McuDependenciesKitAspect : : id ( ) ) ;
if ( ! variant . isNull ( ) & & ! variant . canConvert ( QVariant : : List ) ) {
qWarning ( " Kit \" %s \" has a wrong mcu dependencies value set. " , qPrintable ( k - > displayName ( ) ) ) ;
setDependencies ( k , Utils : : NameValueItems ( ) ) ;
}
}
KitAspectWidget * McuDependenciesKitAspect : : createConfigWidget ( Kit * k ) const
{
QTC_ASSERT ( k , return nullptr ) ;
return new Internal : : McuDependenciesKitAspectWidget ( k , this ) ;
}
KitAspect : : ItemList McuDependenciesKitAspect : : toUserOutput ( const Kit * k ) const
{
Q_UNUSED ( k ) ;
return { } ;
}
Utils : : Id McuDependenciesKitAspect : : id ( )
{
return " PE.Profile.McuDependencies " ;
}
Utils : : NameValueItems McuDependenciesKitAspect : : dependencies ( const Kit * k )
{
if ( k )
return Utils : : NameValueItem : : fromStringList ( k - > value ( McuDependenciesKitAspect : : id ( ) ) . toStringList ( ) ) ;
return Utils : : NameValueItems ( ) ;
}
void McuDependenciesKitAspect : : setDependencies ( Kit * k , const Utils : : NameValueItems & dependencies )
{
if ( k )
k - > setValue ( McuDependenciesKitAspect : : id ( ) , Utils : : NameValueItem : : toStringList ( dependencies ) ) ;
}
2019-10-22 14:33:31 +02:00
} // McuSupport