diff options
Diffstat (limited to 'src/plugins/generator/iarew/archs/msp430/msp430generalsettingsgroup_v7.cpp')
-rw-r--r-- | src/plugins/generator/iarew/archs/msp430/msp430generalsettingsgroup_v7.cpp | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/src/plugins/generator/iarew/archs/msp430/msp430generalsettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/msp430/msp430generalsettingsgroup_v7.cpp new file mode 100644 index 000000000..ac1c475d1 --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430generalsettingsgroup_v7.cpp @@ -0,0 +1,483 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** 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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "msp430generalsettingsgroup_v7.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +constexpr int kGeneralArchiveVersion = 21; +constexpr int kGeneralDataVersion = 34; + +namespace { + +// Target page options. + +struct TargetPageOptions final +{ + enum CodeModel { + SmallCodeModel, + LargeCodeModel + }; + + enum DataModel { + SmallDataModel, + MediumDataModel, + LargeDataModel + }; + + enum FloatingPointDoubleSize { + DoubleSize32Bits, + DoubleSize64Bits + }; + + enum HardwareMultiplierType { + AllowDirectAccessMultiplier, + UseOnlyLibraryCallsMultiplier + }; + + explicit TargetPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("driverFlags")}); + // Detect target code model. + const QString codeModelValue = IarewUtils::flagValue( + flags, QStringLiteral("--code_model")); + if (codeModelValue == QLatin1String("small")) + codeModel = TargetPageOptions::SmallCodeModel; + else if (codeModelValue == QLatin1String("large")) + codeModel = TargetPageOptions::LargeCodeModel; + // Detect target data model. + const QString dataModelValue = IarewUtils::flagValue( + flags, QStringLiteral("--data_model")); + if (dataModelValue == QLatin1String("small")) + dataModel = TargetPageOptions::SmallDataModel; + else if (dataModelValue == QLatin1String("medium")) + dataModel = TargetPageOptions::MediumDataModel; + else if (dataModelValue == QLatin1String("large")) + dataModel = TargetPageOptions::LargeDataModel; + // Detect floating point double size. + const int doubleSize = IarewUtils::flagValue( + flags, QStringLiteral("--double")).toInt(); + if (doubleSize == 32) + floatingPointDoubleSize = DoubleSize32Bits; + else if (doubleSize == 64) + floatingPointDoubleSize = DoubleSize64Bits; + // Detect hardware multiplier. + const QString multiplier = IarewUtils::flagValue( + flags, QStringLiteral("--multiplier")); + enableHardwareMultiplier = (multiplier.compare(QLatin1String("16")) == 0 + || multiplier.compare(QLatin1String("16s")) == 0 + || multiplier.compare(QLatin1String("32")) == 0); + // Detect code and read-only data position-independence. + enableRopi = flags.contains(QLatin1String("--ropi")); + // No dynamic read-write initialization. + disableDynamicReadWriteInitialization = flags.contains( + QLatin1String("--no_rw_dynamic_init")); + + // Detect target device name. + detectDeviceMenu(qbsProduct); + } + + void detectDeviceMenu(const ProductData &qbsProduct) + { + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + + // Enumerate all product linker config files + // (which are set trough 'linkerscript' tag). + const auto qbsGroups = qbsProduct.groups(); + for (const auto &qbsGroup : qbsGroups) { + const auto qbsArtifacts = qbsGroup.sourceArtifacts(); + for (const auto &qbsArtifact : qbsArtifacts) { + const auto qbsTags = qbsArtifact.fileTags(); + if (!qbsTags.contains(QLatin1String("linkerscript"))) + continue; + const QString fullConfigPath = qbsArtifact.filePath(); + if (!fullConfigPath.startsWith(toolkitPath, Qt::CaseInsensitive)) + continue; + + const QFileInfo configInfo(fullConfigPath); + const QString configBase = configInfo.baseName(); + if (!configBase.startsWith(QLatin1String("lnk"))) + continue; + + // Remove 'lnk' prefix. + const QString deviceName = QStringLiteral("MSP%1") + .arg(configBase.mid(3).toUpper()); + + deviceMenu = QStringLiteral("%1\t%1").arg(deviceName); + return; + } + } + + // Falling back to generic menu. + if (deviceMenu.isEmpty()) { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + const QString cpuCore = IarewUtils::flagValue(flags, QStringLiteral("--core")); + if (cpuCore.isEmpty()) + return; + deviceMenu = QStringLiteral("MSP%1\tGeneric MSP%1 device").arg(cpuCore); + return; + } + } + + CodeModel codeModel = LargeCodeModel; + DataModel dataModel = SmallDataModel; + FloatingPointDoubleSize floatingPointDoubleSize = DoubleSize32Bits; + HardwareMultiplierType hardwareMultiplierType = AllowDirectAccessMultiplier; + int enableHardwareMultiplier = 0; + int enableRopi = 0; + int disableDynamicReadWriteInitialization = 0; + QString deviceMenu; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + binaryType = IarewUtils::outputBinaryType(qbsProduct); + binaryDirectory = gen::utils::binaryOutputDirectory( + baseDirectory, qbsProduct); + objectDirectory = gen::utils::objectsOutputDirectory( + baseDirectory, qbsProduct); + listingDirectory = gen::utils::listingOutputDirectory( + baseDirectory, qbsProduct); + } + + IarewUtils::OutputBinaryType binaryType = IarewUtils::ApplicationOutputType; + QString binaryDirectory; + QString objectDirectory; + QString listingDirectory; +}; + +// Library configuration page options. + +struct LibraryConfigPageOptions final +{ + enum RuntimeLibrary { + NoLibrary, + NormalDLibrary, + FullDLibrary, + CustomDLibrary, + CLibrary, // deprecated + CustomCLibrary, // deprecated + }; + + explicit LibraryConfigPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + + const QFileInfo configInfo(IarewUtils::flagValue( + flags, + QStringLiteral("--dlib_config"))); + const QString configFilePath = configInfo.absoluteFilePath(); + + if (!configFilePath.isEmpty()) { + const QString libToolkitPath = + IarewUtils::libToolkitRootPath(qbsProduct); + + if (configFilePath.startsWith(libToolkitPath, + Qt::CaseInsensitive)) { + if (configFilePath.endsWith(QLatin1String("n.h"), + Qt::CaseInsensitive)) { + libraryType = LibraryConfigPageOptions::NormalDLibrary; + } else if (configFilePath.endsWith(QLatin1String("f.h"), + Qt::CaseInsensitive)) { + libraryType = LibraryConfigPageOptions::FullDLibrary; + } else { + libraryType = LibraryConfigPageOptions::CustomDLibrary; + } + + configPath = IarewUtils::toolkitRelativeFilePath( + baseDirectory, configFilePath); + } else { + libraryType = LibraryConfigPageOptions::CustomDLibrary; + + configPath = configFilePath; + } + } + } + + RuntimeLibrary libraryType = NormalDLibrary; + QString libraryPath; + QString configPath; +}; + +// Library options page options. + +struct LibraryOptionsPageOptions final +{ + enum PrintfFormatter { + PrintfAutoFormatter = 0, + PrintfFullFormatter = 1, + PrintfFullNoMultibytesFormatter = 2, + PrintfLargeFormatter = 3, + PrintfLargeNoMultibytesFormatter = 4, + PrintfSmallFormatter = 5, + PrintfSmallNoMultibytesFormatter = 6, + PrintfTinyFormatter = 7 + }; + + enum ScanfFormatter { + ScanfAutoFormatter = 0, + ScanfFullFormatter = 1, + ScanfFullNoMultibytesFormatter = 2, + ScanfLargeFormatter = 3, + ScanfLargeNoMultibytesFormatter = 4, + ScanfSmallFormatter = 5, + ScanfSmallNoMultibytesFormatter = 6 + }; + + explicit LibraryOptionsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + for (auto flagIt = flags.cbegin(); flagIt < flags.cend(); ++flagIt) { + if (flagIt->endsWith(QLatin1String("=_printf"), + Qt::CaseInsensitive)) { + const QString prop = flagIt->split( + QLatin1Char('=')).at(0).toLower(); + if (prop == QLatin1String("_printffull")) + printfFormatter = PrintfFullFormatter; + else if (prop == QLatin1String("_printffullnomb")) + printfFormatter = PrintfFullNoMultibytesFormatter; + else if (prop == QLatin1String("_printflarge")) + printfFormatter = PrintfLargeFormatter; + else if (prop == QLatin1String("_printflargenomb")) + printfFormatter = PrintfLargeFormatter; + else if (prop == QLatin1String("_printfsmall")) + printfFormatter = PrintfSmallFormatter; + else if (prop == QLatin1String("_printfsmallnomb")) + printfFormatter = PrintfSmallNoMultibytesFormatter; + else if (prop == QLatin1String("_printftiny")) + printfFormatter = PrintfTinyFormatter; + } else if (flagIt->endsWith(QLatin1String("=_scanf"), + Qt::CaseInsensitive)) { + const QString prop = flagIt->split( + QLatin1Char('=')).at(0).toLower(); + if (prop == QLatin1String("_scanffull")) + scanfFormatter = ScanfFullFormatter; + else if (prop == QLatin1String("_scanffullnomb")) + scanfFormatter = ScanfFullNoMultibytesFormatter; + else if (prop == QLatin1String("_scanflarge")) + scanfFormatter = ScanfLargeFormatter; + else if (prop == QLatin1String("_scanflargenomb")) + scanfFormatter = ScanfLargeFormatter; + else if (prop == QLatin1String("_scanfsmall")) + scanfFormatter = ScanfSmallFormatter; + else if (prop == QLatin1String("_scanfsmallnomb")) + scanfFormatter = ScanfSmallNoMultibytesFormatter; + } + } + } + + PrintfFormatter printfFormatter = PrintfAutoFormatter; + ScanfFormatter scanfFormatter = ScanfAutoFormatter; +}; + +// Stack/heap page options. + +struct StackHeapPageOptions final +{ + explicit StackHeapPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + + // Detect stack size. + stackSize = IarewUtils::flagValue( + flags, QStringLiteral("-D_STACK_SIZE")); + if (stackSize.isEmpty()) + stackSize = QLatin1String("A0"); + // Detect data heap16 size. + data16HeapSize = IarewUtils::flagValue( + flags, QStringLiteral("-D_DATA16_HEAP_SIZE")); + if (data16HeapSize.isEmpty()) + stackSize = QLatin1String("A0"); + // Detect data heap20 size. + data20HeapSize = IarewUtils::flagValue( + flags, QStringLiteral("-D_DATA20_HEAP_SIZE")); + if (data20HeapSize.isEmpty()) + stackSize = QLatin1String("50"); + } + + QString stackSize; + QString data16HeapSize; + QString data20HeapSize; +}; + +} // namespace + +//Msp430GeneralSettingsGroup + +Msp430GeneralSettingsGroup::Msp430GeneralSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("General")); + setArchiveVersion(kGeneralArchiveVersion); + setDataVersion(kGeneralDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildTargetPage(qbsProduct); + buildOutputPage(buildRootDirectory, qbsProduct); + buildLibraryConfigPage(buildRootDirectory, qbsProduct); + buildLibraryOptionsPage(qbsProduct); + buildStackHeapPage(qbsProduct); +} + +void Msp430GeneralSettingsGroup::buildTargetPage( + const ProductData &qbsProduct) +{ + const TargetPageOptions opts(qbsProduct); + // Add 'OGChipSelectMenu' item + // (Device: xxx). + addOptionsGroup(QByteArrayLiteral("OGChipSelectMenu"), + {opts.deviceMenu}); + + // Add 'RadioCodeModelType' item + // (Code model: small/large). + addOptionsGroup(QByteArrayLiteral("RadioCodeModelType"), + {opts.codeModel}); + // Add 'RadioDataModelType' item + // (Data model: small/medium/large). + addOptionsGroup(QByteArrayLiteral("RadioDataModelType"), + {opts.dataModel}); + // Add 'OGDouble' item + // (Floating point double size: 32/64 bits). + addOptionsGroup(QByteArrayLiteral("OGDouble"), + {opts.floatingPointDoubleSize}); + // Add 'Hardware Multiplier' item + // (Hardware multiplier). + addOptionsGroup(QByteArrayLiteral("Hardware Multiplier"), + {opts.enableHardwareMultiplier}); + if (opts.enableHardwareMultiplier) { + // Add 'RadioHardwareMultiplierType' item. + addOptionsGroup(QByteArrayLiteral("Hardware RadioHardwareMultiplierType"), + {opts.hardwareMultiplierType}); + } + // Add 'Ropi' item. + // (Position independence: Code and read-only data). + addOptionsGroup(QByteArrayLiteral("Ropi"), + {opts.enableRopi}); + // Add 'NoRwDynamicInit' item. + // (Position independence: No dynamic read/write initialization). + addOptionsGroup(QByteArrayLiteral("NoRwDynamicInit"), + {opts.disableDynamicReadWriteInitialization}); +} + +void Msp430GeneralSettingsGroup::buildOutputPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(baseDirectory, qbsProduct); + // Add 'GOutputBinary' item (Output file: executable/library). + addOptionsGroup(QByteArrayLiteral("GOutputBinary"), + {opts.binaryType}); + // Add 'ExePath' item (Executable/binaries output directory). + addOptionsGroup(QByteArrayLiteral("ExePath"), + {opts.binaryDirectory}); + // Add 'ObjPath' item (Object files output directory). + addOptionsGroup(QByteArrayLiteral("ObjPath"), + {opts.objectDirectory}); + // Add 'ListPath' item (List files output directory). + addOptionsGroup(QByteArrayLiteral("ListPath"), + {opts.listingDirectory}); +} + +void Msp430GeneralSettingsGroup::buildLibraryConfigPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const LibraryConfigPageOptions opts(baseDirectory, qbsProduct); + // Add 'GRuntimeLibSelect' and 'GRuntimeLibSelectSlave' items + // (Link with runtime: none/normal/full/custom). + addOptionsGroup(QByteArrayLiteral("GRuntimeLibSelect"), + {opts.libraryType}); + addOptionsGroup(QByteArrayLiteral("GRuntimeLibSelectSlave"), + {opts.libraryType}); + // Add 'RTConfigPath' item (Runtime configuration file). + addOptionsGroup(QByteArrayLiteral("RTConfigPath"), + {opts.configPath}); + // Add 'RTLibraryPath' item (Runtime library file). + addOptionsGroup(QByteArrayLiteral("RTLibraryPath"), + {opts.libraryPath}); +} + +void Msp430GeneralSettingsGroup::buildLibraryOptionsPage( + const ProductData &qbsProduct) +{ + const LibraryOptionsPageOptions opts(qbsProduct); + // Add 'Output variant' item (Printf formatter). + addOptionsGroup(QByteArrayLiteral("Output variant"), + {opts.printfFormatter}); + // Add 'Input variant' item (Scanf formatter). + addOptionsGroup(QByteArrayLiteral("Input variant"), + {opts.scanfFormatter}); +} + +void Msp430GeneralSettingsGroup::buildStackHeapPage( + const ProductData &qbsProduct) +{ + const StackHeapPageOptions opts(qbsProduct); + // Add 'GStackHeapOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("GStackHeapOverride"), + {1}); + // Add 'GStackSize2' item (Stack size). + addOptionsGroup(QByteArrayLiteral("GStackSize2"), + {opts.stackSize}); + // Add 'GHeapSize2' item (Heap16 size). + addOptionsGroup(QByteArrayLiteral("GHeapSize2"), + {opts.data16HeapSize}); + // Add 'GHeap20Size' item (Heap16 size). + addOptionsGroup(QByteArrayLiteral("GHeap20Size"), + {opts.data20HeapSize}); +} + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs |