2022-02-16 16:48:28 +01:00
/****************************************************************************
* *
* * Copyright ( C ) 2020 The Qt Company Ltd .
* * Contact : https : //www.qt.io/licensing/
* *
* * 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 "mcukitmanager.h"
2022-04-25 19:52:29 +02:00
# include "mculegacyconstants.h"
2022-02-16 16:48:28 +01:00
# include "mcusupportoptions.h"
# include "mcukitinformation.h"
# include "mcupackage.h"
2022-02-22 13:36:55 +01:00
# include "mcusupportconstants.h"
2022-02-16 16:48:28 +01:00
# include "mcusupportplugin.h"
# include "mcusupportsdk.h"
2022-02-22 13:36:55 +01:00
# include "mcutarget.h"
2022-02-16 16:48:28 +01:00
# include <cmakeprojectmanager/cmakekitinformation.h>
# include <cmakeprojectmanager/cmaketoolmanager.h>
# include <coreplugin/icore.h>
# include <debugger/debuggeritem.h>
# include <debugger/debuggeritemmanager.h>
# include <debugger/debuggerkitinformation.h>
# include <utils/algorithm.h>
# include <qtsupport/qtkitinformation.h>
# include <qtsupport/qtversionmanager.h>
# include <QMessageBox>
# include <QPushButton>
2022-02-22 13:36:55 +01:00
using CMakeProjectManager : : CMakeConfig ;
2022-02-16 16:48:28 +01:00
using CMakeProjectManager : : CMakeConfigItem ;
using CMakeProjectManager : : CMakeConfigurationKitAspect ;
using namespace ProjectExplorer ;
using namespace Utils ;
2022-02-22 13:36:55 +01:00
namespace McuSupport : : Internal {
2022-02-28 16:35:54 +01:00
2022-02-22 13:36:55 +01:00
// Utils for managing CMake Configurations
static QMap < QByteArray , QByteArray > cMakeConfigToMap ( const CMakeConfig & config )
2022-02-16 16:48:28 +01:00
{
2022-02-22 13:36:55 +01:00
QMap < QByteArray , QByteArray > map ;
for ( const auto & configItem : qAsConst ( config . toList ( ) ) ) {
map . insert ( configItem . key , configItem . value ) ;
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
return map ;
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
static CMakeConfig mapToCMakeConfig ( const QMap < QByteArray , QByteArray > & map )
2022-02-16 16:48:28 +01:00
{
2022-02-22 13:36:55 +01:00
QList < CMakeConfigItem > asList ;
for ( auto it = map . constKeyValueBegin ( ) ; it ! = map . constKeyValueEnd ( ) ; + + it ) {
asList . append ( CMakeConfigItem ( it - > first , it - > second ) ) ;
}
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
return CMakeConfig ( asList ) ;
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
namespace McuKitManager {
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
static const int KIT_VERSION = 9 ; // Bumps up whenever details in Kit creation change
2022-02-28 16:35:54 +01:00
2022-02-22 13:36:55 +01:00
class McuKitFactory
{
public :
2022-03-28 16:42:51 +02:00
static void setKitToolchains ( Kit * k , const McuToolChainPackagePtr & tcPackage )
2022-02-22 13:36:55 +01:00
{
switch ( tcPackage - > toolchainType ( ) ) {
case McuToolChainPackage : : ToolChainType : : Unsupported :
return ;
case McuToolChainPackage : : ToolChainType : : GHS :
case McuToolChainPackage : : ToolChainType : : GHSArm :
return ; // No Green Hills toolchain, because support for it is missing.
case McuToolChainPackage : : ToolChainType : : IAR :
case McuToolChainPackage : : ToolChainType : : KEIL :
case McuToolChainPackage : : ToolChainType : : MSVC :
case McuToolChainPackage : : ToolChainType : : GCC :
case McuToolChainPackage : : ToolChainType : : ArmGcc :
ToolChainKitAspect : : setToolChain ( k ,
tcPackage - > toolChain (
ProjectExplorer : : Constants : : C_LANGUAGE_ID ) ) ;
ToolChainKitAspect : : setToolChain ( k ,
tcPackage - > toolChain (
ProjectExplorer : : Constants : : CXX_LANGUAGE_ID ) ) ;
return ;
default :
Q_UNREACHABLE ( ) ;
}
}
2022-02-28 16:35:54 +01:00
2022-04-25 00:02:44 +02:00
static void setKitProperties ( Kit * k , const McuTarget * mcuTarget , const FilePath & sdkPath )
2022-02-22 13:36:55 +01:00
{
using namespace Constants ;
2022-04-25 00:02:44 +02:00
const QString kitName { generateKitNameFromTarget ( mcuTarget ) } ;
2022-02-22 13:36:55 +01:00
k - > setUnexpandedDisplayName ( kitName ) ;
k - > setValue ( KIT_MCUTARGET_VENDOR_KEY , mcuTarget - > platform ( ) . vendor ) ;
k - > setValue ( KIT_MCUTARGET_MODEL_KEY , mcuTarget - > platform ( ) . name ) ;
k - > setValue ( KIT_MCUTARGET_COLORDEPTH_KEY , mcuTarget - > colorDepth ( ) ) ;
k - > setValue ( KIT_MCUTARGET_SDKVERSION_KEY , mcuTarget - > qulVersion ( ) . toString ( ) ) ;
k - > setValue ( KIT_MCUTARGET_KITVERSION_KEY , KIT_VERSION ) ;
k - > setValue ( KIT_MCUTARGET_OS_KEY , static_cast < int > ( mcuTarget - > os ( ) ) ) ;
2022-04-25 19:52:29 +02:00
k - > setValue ( KIT_MCUTARGET_TOOLCHAIN_KEY , mcuTarget - > toolChainPackage ( ) - > toolChainName ( ) ) ;
2022-02-22 13:36:55 +01:00
k - > setAutoDetected ( false ) ;
k - > makeSticky ( ) ;
if ( mcuTarget - > toolChainPackage ( ) - > isDesktopToolchain ( ) )
k - > setDeviceTypeForIcon ( DEVICE_TYPE ) ;
k - > setValue ( QtSupport : : SuppliesQtQuickImportPath : : id ( ) , true ) ;
2022-04-25 00:02:44 +02:00
k - > setValue ( QtSupport : : KitQmlImportPath : : id ( ) , ( sdkPath / " include/qul " ) . toVariant ( ) ) ;
2022-02-22 13:36:55 +01:00
k - > setValue ( QtSupport : : KitHasMergedHeaderPathsWithQmlImportPaths : : id ( ) , true ) ;
QSet < Id > irrelevant = {
SysRootKitAspect : : id ( ) ,
QtSupport : : SuppliesQtQuickImportPath : : id ( ) ,
QtSupport : : KitQmlImportPath : : id ( ) ,
QtSupport : : KitHasMergedHeaderPathsWithQmlImportPaths : : id ( ) ,
} ;
if ( ! McuSupportOptions : : kitsNeedQtVersion ( ) )
irrelevant . insert ( QtSupport : : QtKitAspect : : id ( ) ) ;
k - > setIrrelevantAspects ( irrelevant ) ;
2022-02-28 16:35:54 +01:00
}
2022-03-28 16:42:51 +02:00
static void setKitDebugger ( Kit * k , const McuToolChainPackagePtr & tcPackage )
2022-02-22 13:36:55 +01:00
{
if ( tcPackage - > isDesktopToolchain ( ) ) {
// Qt Creator seems to be smart enough to deduce the right Kit debugger from the ToolChain
return ;
}
2022-02-28 16:35:54 +01:00
2022-02-22 13:36:55 +01:00
switch ( tcPackage - > toolchainType ( ) ) {
case McuToolChainPackage : : ToolChainType : : Unsupported :
case McuToolChainPackage : : ToolChainType : : GHS :
case McuToolChainPackage : : ToolChainType : : GHSArm :
case McuToolChainPackage : : ToolChainType : : IAR :
return ; // No Green Hills and IAR debugger, because support for it is missing.
case McuToolChainPackage : : ToolChainType : : KEIL :
case McuToolChainPackage : : ToolChainType : : MSVC :
case McuToolChainPackage : : ToolChainType : : GCC :
case McuToolChainPackage : : ToolChainType : : ArmGcc : {
const QVariant debuggerId = tcPackage - > debuggerId ( ) ;
if ( debuggerId . isValid ( ) ) {
Debugger : : DebuggerKitAspect : : setDebugger ( k , debuggerId ) ;
}
return ;
2022-02-28 16:35:54 +01:00
}
2022-02-22 13:36:55 +01:00
default :
Q_UNREACHABLE ( ) ;
}
2022-02-28 16:35:54 +01:00
}
2022-02-22 13:36:55 +01:00
static void setKitDevice ( Kit * k , const McuTarget * mcuTarget )
{
// "Device Type" Desktop is the default. We use that for the Qt for MCUs Desktop Kit
if ( mcuTarget - > toolChainPackage ( ) - > isDesktopToolchain ( ) )
return ;
2022-02-28 16:35:54 +01:00
2022-02-22 13:36:55 +01:00
DeviceTypeKitAspect : : setDeviceTypeId ( k , Constants : : DEVICE_TYPE ) ;
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
static void setKitDependencies ( Kit * k ,
const McuTarget * mcuTarget ,
2022-03-28 16:42:51 +02:00
const McuPackagePtr & qtForMCUsSdkPackage )
2022-02-22 13:36:55 +01:00
{
NameValueItems dependencies ;
2022-03-28 16:42:51 +02:00
auto processPackage = [ & dependencies ] ( const McuPackagePtr & package ) {
2022-02-22 13:36:55 +01:00
const auto cmakeVariableName = package - > cmakeVariableName ( ) ;
if ( ! cmakeVariableName . isEmpty ( ) )
dependencies . append ( { cmakeVariableName , package - > detectionPath ( ) . toUserOutput ( ) } ) ;
} ;
2022-03-28 16:42:51 +02:00
for ( const auto & package : mcuTarget - > packages ( ) )
2022-02-22 13:36:55 +01:00
processPackage ( package ) ;
processPackage ( qtForMCUsSdkPackage ) ;
McuDependenciesKitAspect : : setDependencies ( k , dependencies ) ;
auto irrelevant = k - > irrelevantAspects ( ) ;
irrelevant . insert ( McuDependenciesKitAspect : : id ( ) ) ;
k - > setIrrelevantAspects ( irrelevant ) ;
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
static void setKitEnvironment ( Kit * k ,
const McuTarget * mcuTarget ,
2022-03-28 16:42:51 +02:00
const McuPackagePtr & qtForMCUsSdkPackage )
2022-02-22 13:36:55 +01:00
{
EnvironmentItems changes ;
QStringList pathAdditions ; // clazy:exclude=inefficient-qlist-soft
// 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.
if ( mcuTarget - > toolChainPackage ( ) - > isDesktopToolchain ( )
& & ! CMakeProjectManager : : CMakeToolManager : : defaultCMakeTool ( ) - > hasFileApi ( ) )
2022-04-21 12:27:51 +02:00
pathAdditions . append ( ( qtForMCUsSdkPackage - > path ( ) / " bin " ) . toUserOutput ( ) ) ;
2022-02-22 13:36:55 +01:00
2022-03-28 16:42:51 +02:00
auto processPackage = [ & pathAdditions ] ( const McuPackagePtr & package ) {
2022-02-22 13:36:55 +01:00
if ( package - > isAddToSystemPath ( ) )
pathAdditions . append ( package - > path ( ) . toUserOutput ( ) ) ;
} ;
2022-03-28 16:42:51 +02:00
for ( const auto & package : mcuTarget - > packages ( ) )
2022-02-22 13:36:55 +01:00
processPackage ( package ) ;
processPackage ( qtForMCUsSdkPackage ) ;
if ( ! pathAdditions . isEmpty ( ) ) {
const QString path = QLatin1String ( HostOsInfo : : isWindowsHost ( ) ? " Path " : " PATH " ) ;
pathAdditions . append ( " ${ " + path + " } " ) ;
changes . append ( { path , pathAdditions . join ( HostOsInfo : : pathListSeparator ( ) ) } ) ;
}
if ( McuSupportOptions : : kitsNeedQtVersion ( ) )
changes . append ( { QLatin1String ( " LD_LIBRARY_PATH " ) , " %{Qt:QT_INSTALL_LIBS} " } ) ;
EnvironmentKitAspect : : setEnvironmentChanges ( k , changes ) ;
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
static void setKitCMakeOptions ( Kit * k ,
const McuTarget * mcuTarget ,
2022-03-28 16:42:51 +02:00
const McuPackagePtr & qtForMCUsSdkPackage )
2022-02-22 13:36:55 +01:00
{
using namespace CMakeProjectManager ;
auto configMap = cMakeConfigToMap ( CMakeConfigurationKitAspect : : configuration ( k ) ) ;
// CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously
if ( mcuTarget - > toolChainPackage ( ) - > toolchainType ( ) ! = McuToolChainPackage : : ToolChainType : : GHS
& & mcuTarget - > toolChainPackage ( ) - > toolchainType ( )
! = McuToolChainPackage : : ToolChainType : : GHSArm ) {
configMap . insert ( " CMAKE_CXX_COMPILER " , " %{Compiler:Executable:Cxx} " ) ;
configMap . insert ( " CMAKE_C_COMPILER " , " %{Compiler:Executable:C} " ) ;
}
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
if ( ! mcuTarget - > toolChainPackage ( ) - > isDesktopToolchain ( ) ) {
2022-04-25 19:52:29 +02:00
const FilePath cMakeToolchainFile = mcuTarget - > toolChainFilePackage ( ) - > path ( ) ;
2022-02-22 13:36:55 +01:00
2022-04-25 19:52:29 +02:00
configMap . insert ( Constants : : TOOLCHAIN_FILE_CMAKE_VARIABLE ,
cMakeToolchainFile . toUserOutput ( ) . toUtf8 ( ) ) ;
2022-02-22 13:36:55 +01:00
if ( ! cMakeToolchainFile . exists ( ) ) {
printMessage (
McuTarget : : tr (
" Warning for target %1: missing CMake toolchain file expected at %2. " )
. arg ( generateKitNameFromTarget ( mcuTarget ) ,
cMakeToolchainFile . toUserOutput ( ) ) ,
false ) ;
}
}
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
const FilePath generatorsPath = qtForMCUsSdkPackage - > path ( ) . pathAppended (
" /lib/cmake/Qul/QulGenerators.cmake " ) ;
configMap . insert ( " QUL_GENERATORS " , generatorsPath . toString ( ) . toUtf8 ( ) ) ;
if ( ! generatorsPath . exists ( ) ) {
printMessage ( McuTarget : : tr (
" Warning for target %1: missing QulGenerators expected at %2. " )
. arg ( generateKitNameFromTarget ( mcuTarget ) ,
generatorsPath . toUserOutput ( ) ) ,
false ) ;
}
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
configMap . insert ( " QUL_PLATFORM " , mcuTarget - > platform ( ) . name . toUtf8 ( ) ) ;
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
if ( mcuTarget - > colorDepth ( ) ! = McuTarget : : UnspecifiedColorDepth )
configMap . insert ( " QUL_COLOR_DEPTH " , QString : : number ( mcuTarget - > colorDepth ( ) ) . toLatin1 ( ) ) ;
if ( McuSupportOptions : : kitsNeedQtVersion ( ) )
configMap . insert ( " CMAKE_PREFIX_PATH " , " %{Qt:QT_INSTALL_PREFIX} " ) ;
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
if ( HostOsInfo : : isWindowsHost ( ) ) {
auto type = mcuTarget - > toolChainPackage ( ) - > toolchainType ( ) ;
if ( type = = McuToolChainPackage : : ToolChainType : : GHS
| | type = = McuToolChainPackage : : ToolChainType : : GHSArm ) {
// 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 " ) ;
}
}
2022-02-16 16:48:28 +01:00
2022-03-28 16:42:51 +02:00
auto processPackage = [ & configMap ] ( const McuPackagePtr & package ) {
2022-02-22 13:36:55 +01:00
if ( ! package - > cmakeVariableName ( ) . isEmpty ( ) )
configMap . insert ( package - > cmakeVariableName ( ) . toUtf8 ( ) ,
package - > path ( ) . toUserOutput ( ) . toUtf8 ( ) ) ;
} ;
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
for ( auto package : mcuTarget - > packages ( ) )
processPackage ( package ) ;
processPackage ( qtForMCUsSdkPackage ) ;
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
CMakeConfigurationKitAspect : : setConfiguration ( k , mapToCMakeConfig ( configMap ) ) ;
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
static void setKitQtVersionOptions ( Kit * k )
{
if ( ! McuSupportOptions : : kitsNeedQtVersion ( ) )
QtSupport : : QtKitAspect : : setQtVersion ( k , nullptr ) ;
// else: auto-select a Qt version
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
} ; // class McuKitFactory
2022-02-16 16:48:28 +01:00
2022-02-22 13:36:55 +01:00
// Construct kit
2022-03-28 16:42:51 +02:00
Kit * newKit ( const McuTarget * mcuTarget , const McuPackagePtr & qtForMCUsSdk )
2022-02-16 16:48:28 +01:00
{
2022-03-28 16:42:51 +02:00
const auto init = [ & mcuTarget , qtForMCUsSdk ] ( Kit * k ) {
2022-02-22 13:36:55 +01:00
KitGuard kitGuard ( k ) ;
2022-04-25 00:02:44 +02:00
McuKitFactory : : setKitProperties ( k , mcuTarget , qtForMCUsSdk - > path ( ) ) ;
2022-02-22 13:36:55 +01:00
McuKitFactory : : setKitDevice ( k , mcuTarget ) ;
McuKitFactory : : setKitToolchains ( k , mcuTarget - > toolChainPackage ( ) ) ;
McuKitFactory : : setKitDebugger ( k , mcuTarget - > toolChainPackage ( ) ) ;
McuKitFactory : : setKitEnvironment ( k , mcuTarget , qtForMCUsSdk ) ;
McuKitFactory : : setKitCMakeOptions ( k , mcuTarget , qtForMCUsSdk ) ;
McuKitFactory : : setKitDependencies ( k , mcuTarget , qtForMCUsSdk ) ;
McuKitFactory : : setKitQtVersionOptions ( k ) ;
k - > setup ( ) ;
k - > fix ( ) ;
} ;
return KitManager : : registerKit ( init ) ;
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
// Kit Information
QString generateKitNameFromTarget ( const McuTarget * mcuTarget )
2022-02-16 16:48:28 +01:00
{
2022-03-28 16:42:51 +02:00
McuToolChainPackagePtr tcPkg = mcuTarget - > toolChainPackage ( ) ;
2022-02-16 16:48:28 +01:00
const QString compilerName = tcPkg & & ! tcPkg - > isDesktopToolchain ( )
? QString : : fromLatin1 ( " (%1) " ) . arg (
tcPkg - > toolChainName ( ) . toUpper ( ) )
: " " ;
const QString colorDepth = mcuTarget - > colorDepth ( ) ! = McuTarget : : UnspecifiedColorDepth
? QString : : fromLatin1 ( " %1bpp " ) . arg ( mcuTarget - > colorDepth ( ) )
: " " ;
const QString targetName = mcuTarget - > platform ( ) . displayName . isEmpty ( )
? mcuTarget - > platform ( ) . name
: mcuTarget - > platform ( ) . displayName ;
return QString : : fromLatin1 ( " Qt for MCUs %1.%2 - %3%4%5 " )
. arg ( QString : : number ( mcuTarget - > qulVersion ( ) . majorVersion ( ) ) ,
QString : : number ( mcuTarget - > qulVersion ( ) . minorVersion ( ) ) ,
targetName ,
colorDepth ,
compilerName ) ;
}
2022-02-22 13:36:55 +01:00
// Kit Information
QVersionNumber kitQulVersion ( const Kit * kit )
{
return QVersionNumber : : fromString (
kit - > value ( McuSupport : : Constants : : KIT_MCUTARGET_SDKVERSION_KEY ) . toString ( ) ) ;
}
// Kit Information
2022-04-25 00:02:44 +02:00
static FilePath kitDependencyPath ( const Kit * kit , const QString & cmakeVariableName )
2022-02-22 13:36:55 +01:00
{
const auto config = CMakeConfigurationKitAspect : : configuration ( kit ) . toList ( ) ;
2022-04-25 00:02:44 +02:00
const auto keyName = cmakeVariableName . toUtf8 ( ) ;
2022-02-22 13:36:55 +01:00
for ( const CMakeConfigItem & configItem : config ) {
if ( configItem . key = = keyName )
return FilePath : : fromUserInput ( QString : : fromUtf8 ( configItem . value ) ) ;
}
return FilePath ( ) ;
}
// Kit Information
bool kitIsUpToDate ( const Kit * kit ,
const McuTarget * mcuTarget ,
2022-03-28 16:42:51 +02:00
const McuPackagePtr & qtForMCUsSdkPackage )
2022-02-22 13:36:55 +01:00
{
return kitQulVersion ( kit ) = = mcuTarget - > qulVersion ( )
& & kitDependencyPath ( kit , qtForMCUsSdkPackage - > cmakeVariableName ( ) ) . toUserOutput ( )
= = qtForMCUsSdkPackage - > path ( ) . toUserOutput ( ) ;
}
// Queries
2022-02-16 16:48:28 +01:00
QList < Kit * > existingKits ( const McuTarget * mcuTarget )
{
using namespace Constants ;
return Utils : : filtered ( KitManager : : kits ( ) , [ mcuTarget ] ( Kit * kit ) {
return kit - > value ( KIT_MCUTARGET_KITVERSION_KEY ) = = KIT_VERSION
& & ( ! 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 ( ) )
2022-04-25 19:52:29 +02:00
& & kit - > value ( KIT_MCUTARGET_TOOLCHAIN_KEY )
2022-02-16 16:48:28 +01:00
= = mcuTarget - > toolChainPackage ( ) - > toolChainName ( ) ) ) ;
} ) ;
}
2022-02-22 13:36:55 +01:00
// Queries
2022-03-28 16:42:51 +02:00
QList < Kit * > matchingKits ( const McuTarget * mcuTarget , const McuPackagePtr & qtForMCUsSdkPackage )
2022-02-16 16:48:28 +01:00
{
2022-03-28 16:42:51 +02:00
return Utils : : filtered ( existingKits ( mcuTarget ) , [ & mcuTarget , qtForMCUsSdkPackage ] ( Kit * kit ) {
2022-02-16 16:48:28 +01:00
return kitIsUpToDate ( kit , mcuTarget , qtForMCUsSdkPackage ) ;
} ) ;
}
2022-02-22 13:36:55 +01:00
// Queries
2022-03-28 16:42:51 +02:00
QList < Kit * > upgradeableKits ( const McuTarget * mcuTarget , const McuPackagePtr & qtForMCUsSdkPackage )
2022-02-16 16:48:28 +01:00
{
2022-03-28 16:42:51 +02:00
return Utils : : filtered ( existingKits ( mcuTarget ) , [ & mcuTarget , qtForMCUsSdkPackage ] ( Kit * kit ) {
2022-02-16 16:48:28 +01:00
return ! kitIsUpToDate ( kit , mcuTarget , qtForMCUsSdkPackage ) ;
} ) ;
}
2022-02-22 13:36:55 +01:00
// Queries
2022-02-16 16:48:28 +01:00
QList < Kit * > kitsWithMismatchedDependencies ( const McuTarget * mcuTarget )
{
2022-03-28 16:42:51 +02:00
return Utils : : filtered ( existingKits ( mcuTarget ) , [ & mcuTarget ] ( Kit * kit ) {
2022-02-22 13:36:55 +01:00
const auto entries = Utils : : NameValueDictionary (
McuDependenciesKitAspect : : configuration ( kit ) ) ;
2022-03-28 16:42:51 +02:00
return Utils : : anyOf ( mcuTarget - > packages ( ) , [ & entries ] ( const McuPackagePtr & package ) {
2022-02-22 13:36:55 +01:00
const QString cmakeVariableName = package - > cmakeVariableName ( ) ;
return ! cmakeVariableName . isEmpty ( )
& & entries . value ( cmakeVariableName ) ! = package - > path ( ) . toUserOutput ( ) ;
} ) ;
2022-02-16 16:48:28 +01:00
} ) ;
}
2022-02-22 13:36:55 +01:00
// Queries
2022-02-16 16:48:28 +01:00
QList < Kit * > outdatedKits ( )
{
return Utils : : filtered ( KitManager : : kits ( ) , [ ] ( Kit * kit ) {
return ! kit - > value ( Constants : : KIT_MCUTARGET_VENDOR_KEY ) . isNull ( )
& & kit - > value ( Constants : : KIT_MCUTARGET_KITVERSION_KEY ) ! = KIT_VERSION ;
} ) ;
}
2022-02-22 13:36:55 +01:00
// Maintenance
2022-04-22 11:41:33 +02:00
void createAutomaticKits ( const SettingsHandler : : Ptr & settingsHandler )
2022-02-16 16:48:28 +01:00
{
2022-04-22 11:41:33 +02:00
McuPackagePtr qtForMCUsPackage { Sdk : : createQtForMCUsPackage ( settingsHandler ) } ;
2022-02-16 16:48:28 +01:00
2022-04-22 11:41:33 +02:00
const auto createKits = [ qtForMCUsPackage , settingsHandler ] ( ) {
2022-05-03 15:01:42 +02:00
if ( settingsHandler - > isAutomaticKitCreationEnabled ( ) ) {
2022-02-16 16:48:28 +01:00
qtForMCUsPackage - > updateStatus ( ) ;
2022-02-21 15:24:46 +01:00
if ( ! qtForMCUsPackage - > isValidStatus ( ) ) {
2022-02-16 16:48:28 +01:00
switch ( qtForMCUsPackage - > status ( ) ) {
case McuAbstractPackage : : Status : : ValidPathInvalidPackage : {
printMessage ( McuPackage : : tr ( " Path %1 exists, but does not contain %2. " )
2022-02-21 15:24:46 +01:00
. arg ( qtForMCUsPackage - > path ( ) . toUserOutput ( ) ,
qtForMCUsPackage - > detectionPath ( ) . toUserOutput ( ) ) ,
2022-02-16 16:48:28 +01:00
true ) ;
break ;
}
case McuAbstractPackage : : Status : : InvalidPath : {
2022-02-22 13:36:55 +01:00
printMessage ( McuPackage : : tr (
" Path %1 does not exist. Add the path in Tools > Options > "
" Devices > MCU. " )
2022-02-16 16:48:28 +01:00
. arg ( qtForMCUsPackage - > path ( ) . toUserOutput ( ) ) ,
true ) ;
break ;
}
case McuAbstractPackage : : Status : : EmptyPath : {
2022-02-22 13:36:55 +01:00
printMessage ( McuPackage : : tr (
" Missing %1. Add the path in Tools > Options > Devices > MCU. " )
2022-02-21 15:24:46 +01:00
. arg ( qtForMCUsPackage - > detectionPath ( ) . toUserOutput ( ) ) ,
2022-02-16 16:48:28 +01:00
true ) ;
return ;
}
default :
break ;
}
return ;
}
if ( CMakeProjectManager : : CMakeToolManager : : cmakeTools ( ) . isEmpty ( ) ) {
2022-02-22 13:36:55 +01:00
printMessage (
McuPackage : : tr (
" No CMake tool was detected. Add a CMake tool in Tools > Options > "
" Kits > CMake. " ) ,
true ) ;
2022-02-16 16:48:28 +01:00
return ;
}
FilePath dir = qtForMCUsPackage - > path ( ) ;
2022-04-22 11:41:33 +02:00
McuSdkRepository repo { Sdk : : targetsAndPackages ( dir , settingsHandler ) } ;
2022-02-16 16:48:28 +01:00
bool needsUpgrade = false ;
for ( const auto & target : qAsConst ( repo . mcuTargets ) ) {
// if kit already exists, skip
2022-03-28 16:42:51 +02:00
if ( ! matchingKits ( target . get ( ) , qtForMCUsPackage ) . empty ( ) )
2022-02-16 16:48:28 +01:00
continue ;
2022-03-28 16:42:51 +02:00
if ( ! upgradeableKits ( target . get ( ) , qtForMCUsPackage ) . empty ( ) ) {
2022-02-16 16:48:28 +01:00
// if kit exists but wrong version/path
needsUpgrade = true ;
} else {
// if no kits for this target, create
if ( target - > isValid ( ) )
2022-03-28 16:42:51 +02:00
newKit ( target . get ( ) , qtForMCUsPackage ) ;
2022-02-16 16:48:28 +01:00
target - > printPackageProblems ( ) ;
}
}
if ( needsUpgrade )
2022-04-22 11:41:33 +02:00
McuSupportPlugin : : askUserAboutMcuSupportKitsUpgrade ( settingsHandler ) ;
2022-02-16 16:48:28 +01:00
}
} ;
createKits ( ) ;
}
2022-02-22 13:36:55 +01:00
// Maintenance
// when the SDK version has changed, and the user has given permission
// to upgrade, create new kits with current data, for the targets
// for which kits already existed
// function parameter is option to keep the old ones or delete them
2022-04-22 11:41:33 +02:00
void upgradeKitsByCreatingNewPackage ( const SettingsHandler : : Ptr & settingsHandler ,
UpgradeOption upgradeOption )
2022-02-16 16:48:28 +01:00
{
if ( upgradeOption = = UpgradeOption : : Ignore )
return ;
2022-04-22 11:41:33 +02:00
McuPackagePtr qtForMCUsPackage { Sdk : : createQtForMCUsPackage ( settingsHandler ) } ;
2022-02-16 16:48:28 +01:00
auto dir = qtForMCUsPackage - > path ( ) ;
2022-04-22 11:41:33 +02:00
McuSdkRepository repo { Sdk : : targetsAndPackages ( dir , settingsHandler ) } ;
2022-02-16 16:48:28 +01:00
for ( const auto & target : qAsConst ( repo . mcuTargets ) ) {
2022-03-28 16:42:51 +02:00
if ( ! matchingKits ( target . get ( ) , qtForMCUsPackage ) . empty ( ) )
2022-02-16 16:48:28 +01:00
// already up-to-date
continue ;
2022-03-28 16:42:51 +02:00
const auto kits = upgradeableKits ( target . get ( ) , qtForMCUsPackage ) ;
2022-02-16 16:48:28 +01:00
if ( ! kits . empty ( ) ) {
if ( upgradeOption = = UpgradeOption : : Replace ) {
for ( auto existingKit : kits )
KitManager : : deregisterKit ( existingKit ) ;
}
if ( target - > isValid ( ) )
2022-03-28 16:42:51 +02:00
newKit ( target . get ( ) , qtForMCUsPackage ) ;
2022-02-16 16:48:28 +01:00
target - > printPackageProblems ( ) ;
}
}
}
2022-02-22 13:36:55 +01:00
// Maintenance
// when the user manually asks to upgrade a specific kit
// button is available if SDK version changed
2022-02-16 16:48:28 +01:00
void upgradeKitInPlace ( ProjectExplorer : : Kit * kit ,
2022-02-22 13:36:55 +01:00
const McuTarget * mcuTarget ,
2022-03-28 16:42:51 +02:00
const McuPackagePtr & qtForMCUsSdk )
2022-02-16 16:48:28 +01:00
{
2022-04-25 00:02:44 +02:00
McuKitFactory : : setKitProperties ( kit , mcuTarget , qtForMCUsSdk - > path ( ) ) ;
2022-02-22 13:36:55 +01:00
McuKitFactory : : setKitEnvironment ( kit , mcuTarget , qtForMCUsSdk ) ;
McuKitFactory : : setKitCMakeOptions ( kit , mcuTarget , qtForMCUsSdk ) ;
McuKitFactory : : setKitDependencies ( kit , mcuTarget , qtForMCUsSdk ) ;
2022-02-16 16:48:28 +01:00
}
2022-02-22 13:36:55 +01:00
// Maintenance
// If the user changed a path in the McuSupport plugin's UI
// update the corresponding cmake variables in all existing kits
2022-04-22 11:41:33 +02:00
void updatePathsInExistingKits ( const SettingsHandler : : Ptr & settingsHandler )
2022-02-16 16:48:28 +01:00
{
2022-04-22 11:41:33 +02:00
McuPackagePtr qtForMCUsPackage { Sdk : : createQtForMCUsPackage ( settingsHandler ) } ;
2022-02-16 16:48:28 +01:00
FilePath dir = qtForMCUsPackage - > path ( ) ;
2022-04-22 11:41:33 +02:00
McuSdkRepository repo { Sdk : : targetsAndPackages ( dir , settingsHandler ) } ;
2022-02-16 16:48:28 +01:00
for ( const auto & target : qAsConst ( repo . mcuTargets ) ) {
if ( target - > isValid ( ) ) {
2022-03-28 16:42:51 +02:00
for ( auto * kit : kitsWithMismatchedDependencies ( target . get ( ) ) ) {
2022-02-22 13:36:55 +01:00
auto changes = cMakeConfigToMap ( CMakeConfigurationKitAspect : : configuration ( kit ) ) ;
2022-03-28 16:42:51 +02:00
const auto updateForPackage = [ & changes ] ( const McuPackagePtr & package ) {
2022-02-22 13:36:55 +01:00
if ( ! package - > cmakeVariableName ( ) . isEmpty ( ) & & package - > isValidStatus ( ) ) {
changes . insert ( package - > cmakeVariableName ( ) . toUtf8 ( ) ,
package - > path ( ) . toUserOutput ( ) . toUtf8 ( ) ) ;
}
} ;
2022-03-28 16:42:51 +02:00
for ( const auto & package : target - > packages ( ) ) {
2022-02-22 13:36:55 +01:00
updateForPackage ( package ) ;
}
updateForPackage ( qtForMCUsPackage ) ;
CMakeConfigurationKitAspect : : setConfiguration ( kit ,
CMakeProjectManager : : CMakeConfig (
mapToCMakeConfig ( changes ) ) ) ;
2022-02-16 16:48:28 +01:00
}
}
}
}
2022-02-22 13:36:55 +01:00
// Maintenance
// if we changed minor details in the kits across versions of QtCreator
// this function updates those details in existing older kits
2022-04-22 11:41:33 +02:00
void fixExistingKits ( const SettingsHandler : : Ptr & settingsHandler )
2022-02-16 16:48:28 +01:00
{
for ( Kit * kit : KitManager : : kits ( ) ) {
if ( ! kit - > hasValue ( Constants : : KIT_MCUTARGET_KITVERSION_KEY ) )
continue ;
if ( kit - > isAutoDetected ( ) ) {
kit - > setAutoDetected ( false ) ;
}
// 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 ) ;
}
// 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 ;
}
}
}
// 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 ) ;
}
}
// Fix kit dependencies for known targets
2022-04-22 11:41:33 +02:00
McuPackagePtr qtForMCUsPackage { Sdk : : createQtForMCUsPackage ( settingsHandler ) } ;
2022-02-16 16:48:28 +01:00
qtForMCUsPackage - > updateStatus ( ) ;
2022-02-21 15:24:46 +01:00
if ( qtForMCUsPackage - > isValidStatus ( ) ) {
2022-02-16 16:48:28 +01:00
FilePath dir = qtForMCUsPackage - > path ( ) ;
2022-04-22 11:41:33 +02:00
McuSdkRepository repo { Sdk : : targetsAndPackages ( dir , settingsHandler ) } ;
2022-02-16 16:48:28 +01:00
for ( const auto & target : qAsConst ( repo . mcuTargets ) )
2022-03-28 16:42:51 +02:00
for ( auto kit : existingKits ( target . get ( ) ) ) {
2022-02-16 16:48:28 +01:00
if ( McuDependenciesKitAspect : : dependencies ( kit ) . isEmpty ( ) ) {
2022-03-28 16:42:51 +02:00
McuKitFactory : : setKitCMakeOptions ( kit , target . get ( ) , qtForMCUsPackage ) ;
McuKitFactory : : setKitDependencies ( kit , target . get ( ) , qtForMCUsPackage ) ;
2022-02-16 16:48:28 +01:00
}
}
}
}
2022-02-22 13:36:55 +01:00
// Maintenance
// removes kits with older schemes
void removeOutdatedKits ( )
{
for ( auto kit : outdatedKits ( ) )
KitManager : : deregisterKit ( kit ) ;
}
2022-02-16 16:48:28 +01:00
} // namespace McuKitManager
2022-03-28 16:42:51 +02:00
} // namespace McuSupport::Internal