diff options
Diffstat (limited to 'src/plugins/generator/iarew/archs')
60 files changed, 11525 insertions, 0 deletions
diff --git a/src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.cpp b/src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.cpp new file mode 100644 index 000000000..cc0750627 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** 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 "armarchiversettingsgroup_v8.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +constexpr int kArchiverArchiveVersion = 0; +constexpr int kArchiverDataVersion = 0; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + outputFile = QLatin1String("$PROJ_DIR$/") + + gen::utils::targetBinaryPath(baseDirectory, qbsProduct); + } + + QString outputFile; +}; + +} // namespace + +// ArmArchiverSettingsGroup + +ArmArchiverSettingsGroup::ArmArchiverSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("IARCHIVE")); + setArchiveVersion(kArchiverArchiveVersion); + setDataVersion(kArchiverDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + buildOutputPage(buildRootDirectory, qbsProduct); +} + +void ArmArchiverSettingsGroup::buildOutputPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(baseDirectory, qbsProduct); + // Add 'IarchiveOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("IarchiveOverride"), + {1}); + // Add 'IarchiveOutput' item (Output filename). + addOptionsGroup(QByteArrayLiteral("IarchiveOutput"), + {opts.outputFile}); +} + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.h b/src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.h new file mode 100644 index 000000000..c99c2eeba --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWARMAARCHIVERSETTINGSGROUP_V8_H +#define QBS_IAREWARMAARCHIVERSETTINGSGROUP_V8_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +class ArmArchiverSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit ArmArchiverSettingsGroup(const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct); +}; + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWARMAARCHIVERSETTINGSGROUP_V8_H diff --git a/src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.cpp b/src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.cpp new file mode 100644 index 000000000..66c4c9ee6 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.cpp @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** 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 "armassemblersettingsgroup_v8.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +constexpr int kAssemblerArchiveVersion = 2; +constexpr int kAssemblerDataVersion = 10; + +namespace { + +// Language page options. + +struct LanguagePageOptions final +{ + enum MacroQuoteCharacter { + AngleBracketsQuote, + RoundBracketsQuote, + SquareBracketsQuote, + FigureBracketsQuote + }; + + explicit LanguagePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleAssemblerFlags(qbsProps); + enableSymbolsCaseSensitive = flags.contains(QLatin1String("-s+")); + allowAlternativeRegister = flags.contains(QLatin1String("-j")); + disableCodeMemoryDataReads = flags.contains( + QLatin1String("--no_literal_pool")); + if (flags.contains(QLatin1String("-M<>"))) + macroQuoteCharacter = LanguagePageOptions::AngleBracketsQuote; + else if (flags.contains(QLatin1String("-M()"))) + macroQuoteCharacter = LanguagePageOptions::RoundBracketsQuote; + else if (flags.contains(QLatin1String("-M[]"))) + macroQuoteCharacter = LanguagePageOptions::SquareBracketsQuote; + else if (flags.contains(QLatin1String("-M{}"))) + macroQuoteCharacter = LanguagePageOptions::FigureBracketsQuote; + } + + MacroQuoteCharacter macroQuoteCharacter = AngleBracketsQuote; + int enableSymbolsCaseSensitive = 0; + int allowAlternativeRegister = 0; + int disableCodeMemoryDataReads = 0; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + debugInfo = gen::utils::debugInformation(qbsProduct); + } + + int debugInfo = 0; +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + for (const QString &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString warningLevel = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("warningLevel")); + if (warningLevel == QLatin1String("all")) { + enableWarnings = 0; + enableAllWarnings = 0; + } else if (warningLevel == QLatin1String("none")) { + enableWarnings = 1; + enableAllWarnings = 0; + } else { + enableWarnings = 0; + enableAllWarnings = 1; + } + } + + int enableWarnings = 0; + int enableAllWarnings = 0; +}; + +} // namespace + +// ArmAssemblerSettingsGroup + +ArmAssemblerSettingsGroup::ArmAssemblerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("AARM")); + setArchiveVersion(kAssemblerArchiveVersion); + setDataVersion(kAssemblerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildLanguagePage(qbsProduct); + buildOutputPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); +} + +void ArmAssemblerSettingsGroup::buildLanguagePage( + const ProductData &qbsProduct) +{ + const LanguagePageOptions opts(qbsProduct); + // Add 'ACaseSensitivity' item (User symbols are case sensitive). + addOptionsGroup(QByteArrayLiteral("ACaseSensitivity"), + {opts.enableSymbolsCaseSensitive}); + // Add 'AltRegisterNames' item (Allow alternative register names, + // mnemonics and operands). + addOptionsGroup(QByteArrayLiteral("AltRegisterNames"), + {opts.allowAlternativeRegister}); + // Add 'AsmNoLiteralPool' item (No data reads in code memory). + addOptionsGroup(QByteArrayLiteral("AsmNoLiteralPool"), + {opts.disableCodeMemoryDataReads}); + // Add 'MacroChars' item (Macro quote characters: ()/[]/{}/<>). + addOptionsGroup(QByteArrayLiteral("MacroChars"), + {opts.macroQuoteCharacter}, 0); +} +void ArmAssemblerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'ADebug' item (Generate debug information). + addOptionsGroup(QByteArrayLiteral("ADebug"), + {opts.debugInfo}); +} + +void ArmAssemblerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'ADefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("ADefines"), + opts.defineSymbols); + // Add 'AUserIncludes' item (Additional include directories). + addOptionsGroup(QByteArrayLiteral("AUserIncludes"), + opts.includePaths); +} + +void ArmAssemblerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'AWarnEnable' item (Enable/disable warnings). + addOptionsGroup(QByteArrayLiteral("AWarnEnable"), + {opts.enableWarnings}); + // Add 'AWarnWhat' item (Enable/disable all warnings). + addOptionsGroup(QByteArrayLiteral("AWarnWhat"), + {opts.enableAllWarnings}); +} + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.h b/src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.h new file mode 100644 index 000000000..620dcf1f5 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWARMASSEMBLERSETTINGSGROUP_V8_H +#define QBS_IAREWARMASSEMBLERSETTINGSGROUP_V8_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +class ArmAssemblerSettingsGroup final + : public IarewSettingsPropertyGroup +{ +public: + explicit ArmAssemblerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildLanguagePage(const ProductData &qbsProduct); + void buildOutputPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); +}; + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWARMASSEMBLERSETTINGSGROUP_V8_H diff --git a/src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.cpp b/src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.cpp new file mode 100644 index 000000000..a16e57a42 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 "armarchiversettingsgroup_v8.h" +#include "armassemblersettingsgroup_v8.h" +#include "armbuildconfigurationgroup_v8.h" +#include "armcompilersettingsgroup_v8.h" +#include "armgeneralsettingsgroup_v8.h" +#include "armlinkersettingsgroup_v8.h" + +#include "../../iarewtoolchainpropertygroup.h" +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +ArmBuildConfigurationGroup::ArmBuildConfigurationGroup( + const qbs::Project &qbsProject, + const qbs::ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) + : gen::xml::PropertyGroup("configuration") +{ + // Append configuration name item. + const QString cfgName = gen::utils::buildConfigurationName(qbsProject); + appendProperty("name", cfgName); + + // Apend toolchain name group item. + appendChild<IarewToolchainPropertyGroup>("ARM"); + + // Append debug info item. + const int debugBuild = gen::utils::debugInformation(qbsProduct); + appendProperty("debug", debugBuild); + + // Append settings group items. + appendChild<ArmArchiverSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<ArmAssemblerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<ArmCompilerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<ArmGeneralSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<ArmLinkerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); +} + +bool ArmBuildConfigurationGroupFactory::canCreate( + gen::utils::Architecture arch, + const Version &version) const +{ + return arch == gen::utils::Architecture::Arm + && version.majorVersion() == 8; +} + +std::unique_ptr<gen::xml::PropertyGroup> +ArmBuildConfigurationGroupFactory::create( + const qbs::Project &qbsProject, + const qbs::ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const +{ + const auto group = new ArmBuildConfigurationGroup( + qbsProject, qbsProduct, qbsProductDeps); + return std::unique_ptr<ArmBuildConfigurationGroup>(group); +} + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.h b/src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.h new file mode 100644 index 000000000..26370c9b8 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWARMBUILDCONFIGURATIONGROUP_V8_H +#define QBS_IAREWARMBUILDCONFIGURATIONGROUP_V8_H + +#include <generators/xmlpropertygroup.h> + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +class ArmBuildConfigurationGroup final + : public gen::xml::PropertyGroup +{ +private: + explicit ArmBuildConfigurationGroup( + const qbs::Project &qbsProject, + const qbs::ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + + friend class ArmBuildConfigurationGroupFactory; +}; + +class ArmBuildConfigurationGroupFactory final + : public gen::xml::PropertyGroupFactory +{ +public: + bool canCreate(gen::utils::Architecture arch, + const Version &version) const final; + + std::unique_ptr<gen::xml::PropertyGroup> create( + const qbs::Project &qbsProject, + const qbs::ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const final; +}; + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWARMBUILDCONFIGURATIONGROUP_V8_H diff --git a/src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.cpp b/src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.cpp new file mode 100644 index 000000000..0981fade4 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.cpp @@ -0,0 +1,478 @@ +/**************************************************************************** +** +** 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 "armcompilersettingsgroup_v8.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +constexpr int kCompilerArchiveVersion = 2; +constexpr int kCompilerDataVersion = 34; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + debugInfo = gen::utils::debugInformation(qbsProduct); + } + + int debugInfo = 0; +}; + +// Language 1 page options. + +struct LanguageOnePageOptions final +{ + enum LanguageExtension { + CLanguageExtension, + CxxLanguageExtension, + AutoLanguageExtension + }; + + enum CLanguageDialect { + C89LanguageDialect, + C11LanguageDialect + }; + + enum LanguageConformance { + AllowIarExtension, + RelaxedStandard, + StrictStandard + }; + + explicit LanguageOnePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + // File extension based by default. + languageExtension = LanguageOnePageOptions::AutoLanguageExtension; + // Language dialect. + const QStringList cLanguageVersion = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("cLanguageVersion")}); + cLanguageDialect = cLanguageVersion.contains(QLatin1String("c89")) + ? LanguageOnePageOptions::C89LanguageDialect + : LanguageOnePageOptions::C11LanguageDialect; + + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + // Language conformance. + if (flags.contains(QLatin1String("-e"))) + languageConformance = LanguageOnePageOptions::AllowIarExtension; + else if (flags.contains(QLatin1String("--strict"))) + languageConformance = LanguageOnePageOptions::StrictStandard; + else + languageConformance = LanguageOnePageOptions::RelaxedStandard; + // Exceptions, rtti, static desrtuction. + enableExceptions = !flags.contains(QLatin1String("--no_exceptions")); + enableRtti = !flags.contains(QLatin1String("--no_rtti")); + destroyStaticObjects = !flags.contains( + QLatin1String("--no_static_destruction")); + allowVla = flags.contains(QLatin1String("--vla")); + enableInlineSemantics = flags.contains(QLatin1String("--use_c++_inline")); + requirePrototypes = flags.contains(QLatin1String("--require_prototypes")); + } + + LanguageExtension languageExtension = AutoLanguageExtension; + CLanguageDialect cLanguageDialect = C89LanguageDialect; + LanguageConformance languageConformance = AllowIarExtension; + // C++ options. + int enableExceptions = 0; + int enableRtti = 0; + int destroyStaticObjects = 0; + int allowVla = 0; + int enableInlineSemantics = 0; + int requirePrototypes = 0; +}; + +// Language 2 page options. + +struct LanguageTwoPageOptions final +{ + enum PlainCharacter { + SignedCharacter, + UnsignedCharacter + }; + + enum FloatingPointSemantic { + StrictSemantic, + RelaxedSemantic + }; + + explicit LanguageTwoPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + plainCharacter = flags.contains(QLatin1String("--char_is_signed")) + ? LanguageTwoPageOptions::SignedCharacter + : LanguageTwoPageOptions::UnsignedCharacter; + floatingPointSemantic = flags.contains(QLatin1String("--relaxed_fp")) + ? LanguageTwoPageOptions::RelaxedSemantic + : LanguageTwoPageOptions::StrictSemantic; + } + + PlainCharacter plainCharacter = SignedCharacter; + FloatingPointSemantic floatingPointSemantic = StrictSemantic; +}; + +// Optimizations page options. + +struct OptimizationsPageOptions final +{ + // Optimizations level radio-buttons with + // combo-box on "level" widget. + + enum Strategy { + StrategyBalanced, + StrategySize, + StrategySpeed + }; + + enum Level { + LevelNone, + LevelLow, + LevelMedium, + LevelHigh + }; + + enum LevelSlave { + LevelSlave0, + LevelSlave1, + LevelSlave2, + LevelSlave3 + }; + + explicit OptimizationsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString optimization = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("optimization")); + if (optimization == QLatin1String("none")) { + optimizationStrategy = OptimizationsPageOptions::StrategyBalanced; + optimizationLevel = OptimizationsPageOptions::LevelNone; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave0; + } else if (optimization == QLatin1String("fast")) { + optimizationStrategy = OptimizationsPageOptions::StrategySpeed; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } else if (optimization == QLatin1String("small")) { + optimizationStrategy = OptimizationsPageOptions::StrategySize; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } + + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + enableCommonSubexpressionElimination = !flags.contains( + QLatin1String("--no_cse")); + enableLoopUnroll = !flags.contains( + QLatin1String("--no_unroll")); + enableFunctionInlining = !flags.contains( + QLatin1String("--no_inline")); + enableCodeMotion = !flags.contains( + QLatin1String("--no_code_motion")); + enableTypeBasedAliasAnalysis = !flags.contains( + QLatin1String("--no_tbaa")); + enableStaticClustering = !flags.contains( + QLatin1String("--no_clustering")); + enableInstructionScheduling = !flags.contains( + QLatin1String("--no_scheduling")); + enableVectorization = flags.contains( + QLatin1String("--vectorize")); + disableSizeConstraints = flags.contains( + QLatin1String("--no_size_constraints")); + } + + Strategy optimizationStrategy = StrategyBalanced; + Level optimizationLevel = LevelNone; + LevelSlave optimizationLevelSlave = LevelSlave0; + // Eight bit-field flags on "enabled optimizations" widget. + int enableCommonSubexpressionElimination = 0; // Common sub-expression elimination. + int enableLoopUnroll = 0; // Loop unrolling. + int enableFunctionInlining = 0; // Function inlining. + int enableCodeMotion = 0; // Code motion. + int enableTypeBasedAliasAnalysis = 0; // Type-based alias analysis. + int enableStaticClustering = 0; // Static clustering. + int enableInstructionScheduling = 0; // Instruction scheduling. + int enableVectorization = 0; // Vectorization. + + // Separate "no size constraints" checkbox. + int disableSizeConstraints = 0; +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + for (const QString &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + treatWarningsAsErrors = gen::utils::cppIntegerModuleProperty( + qbsProps, QStringLiteral("treatWarningsAsErrors")); + } + + int treatWarningsAsErrors = 0; +}; + +// Code page options. + +struct CodePageOptions final +{ + enum ProcessorMode { + CpuArmMode, + CpuThumbMode + }; + + explicit CodePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + const QString cpuModeValue = IarewUtils::flagValue( + flags, QStringLiteral("--cpu_mode")); + if (cpuModeValue == QLatin1String("thumb")) + cpuMode = CodePageOptions::CpuThumbMode; + else if (cpuModeValue == QLatin1String("arm")) + cpuMode = CodePageOptions::CpuArmMode; + + generateReadOnlyPosIndependentCode = flags.contains( + QLatin1String("--ropi")); + generateReadWritePosIndependentCode = flags.contains( + QLatin1String("--rwpi")); + disableDynamicReadWriteInitialization = flags.contains( + QLatin1String("--no_rw_dynamic_init")); + disableCodeMemoryDataReads = flags.contains( + QLatin1String("--no_literal_pool")); + } + + ProcessorMode cpuMode = CpuThumbMode; + int generateReadOnlyPosIndependentCode = 0; + int generateReadWritePosIndependentCode = 0; + int disableDynamicReadWriteInitialization = 0; + int disableCodeMemoryDataReads = 0; +}; + +} // namespace + +// ArmCompilerSettingsGroup + +ArmCompilerSettingsGroup::ArmCompilerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProject) + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("ICCARM")); + setArchiveVersion(kCompilerArchiveVersion); + setDataVersion(kCompilerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildOutputPage(qbsProduct); + buildLanguageOnePage(qbsProduct); + buildLanguageTwoPage(qbsProduct); + buildOptimizationsPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); + buildCodePage(qbsProduct); +} + +void ArmCompilerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'CCDebugInfo' item (Generate debug info). + addOptionsGroup(QByteArrayLiteral("CCDebugInfo"), + {opts.debugInfo}); +} + +void ArmCompilerSettingsGroup::buildLanguageOnePage( + const ProductData &qbsProduct) +{ + const LanguageOnePageOptions opts(qbsProduct); + // Add 'IccLang' item with 'auto-extension based' + // value (Language: C/C++/Auto). + addOptionsGroup(QByteArrayLiteral("IccLang"), + {opts.languageExtension}); + // Add 'IccCDialect' item (C dialect: c89/99/11). + addOptionsGroup(QByteArrayLiteral("IccCDialect"), + {opts.cLanguageDialect}); + // Add 'CCExt' item (Language conformance: IAR/relaxed/strict). + addOptionsGroup(QByteArrayLiteral("CCLangConformance"), + {opts.languageConformance}); + // Add 'IccExceptions2' item (Enable exceptions). + addOptionsGroup(QByteArrayLiteral("IccExceptions2"), + {opts.enableExceptions}); + // Add 'IccRTTI2' item (Enable RTTI). + addOptionsGroup(QByteArrayLiteral("IccRTTI2"), + {opts.enableRtti}); + // Add 'IccStaticDestr' item (Destroy static objects). + addOptionsGroup(QByteArrayLiteral("IccStaticDestr"), + {opts.destroyStaticObjects}); + // Add 'IccAllowVLA' item (Allow VLA). + addOptionsGroup(QByteArrayLiteral("IccAllowVLA"), + {opts.allowVla}); + // Add 'IccCppInlineSemantics' item (C++ inline semantics). + addOptionsGroup(QByteArrayLiteral("IccCppInlineSemantics"), + {opts.enableInlineSemantics}); + // Add 'CCRequirePrototypes' item (Require prototypes). + addOptionsGroup(QByteArrayLiteral("CCRequirePrototypes"), + {opts.requirePrototypes}); +} + +void ArmCompilerSettingsGroup::buildLanguageTwoPage( + const ProductData &qbsProduct) +{ + const LanguageTwoPageOptions opts(qbsProduct); + // Add 'CCSignedPlainChar' item (Plain char is: signed/unsigned). + addOptionsGroup(QByteArrayLiteral("CCSignedPlainChar"), + {opts.plainCharacter}); + // Add 'IccFloatSemantics' item + // (Floating-point semantic: strict/relaxed). + addOptionsGroup(QByteArrayLiteral("IccFloatSemantics"), + {opts.floatingPointSemantic}); +} + +void ArmCompilerSettingsGroup::buildOptimizationsPage( + const ProductData &qbsProduct) +{ + const OptimizationsPageOptions opts(qbsProduct); + // Add 'CCOptStrategy', 'CCOptLevel' + // and 'CCOptLevelSlave' items (Level). + addOptionsGroup(QByteArrayLiteral("CCOptStrategy"), + {opts.optimizationStrategy}); + addOptionsGroup(QByteArrayLiteral("CCOptLevel"), + {opts.optimizationLevel}); + addOptionsGroup(QByteArrayLiteral("CCOptLevelSlave"), + {opts.optimizationLevelSlave}); + // Add 'CCAllowList' item (Enabled optimizations: 6 check boxes). + const QString transformations = QStringLiteral("%1%2%3%4%5%6%7%8") + .arg(opts.enableCommonSubexpressionElimination) + .arg(opts.enableLoopUnroll) + .arg(opts.enableFunctionInlining) + .arg(opts.enableCodeMotion) + .arg(opts.enableTypeBasedAliasAnalysis) + .arg(opts.enableStaticClustering) + .arg(opts.enableInstructionScheduling) + .arg(opts.enableVectorization); + addOptionsGroup(QByteArrayLiteral("CCAllowList"), + {transformations}); + // Add 'CCOptimizationNoSizeConstraints' item (No size constraints). + addOptionsGroup(QByteArrayLiteral("CCOptimizationNoSizeConstraints"), + {opts.disableSizeConstraints}); +} + +void ArmCompilerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'CCDefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("CCDefines"), + opts.defineSymbols); + // Add 'CCIncludePath2' item (Additional include directories). + addOptionsGroup(QByteArrayLiteral("CCIncludePath2"), + opts.includePaths); +} + +void ArmCompilerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'CCDiagWarnAreErr' item (Treat all warnings as errors). + addOptionsGroup(QByteArrayLiteral("CCDiagWarnAreErr"), + {opts.treatWarningsAsErrors}); +} + +void ArmCompilerSettingsGroup::buildCodePage( + const ProductData &qbsProduct) +{ + const CodePageOptions opts(qbsProduct); + // Add 'IProcessorMode2' item (Processor mode: arm/thumb). + addOptionsGroup(QByteArrayLiteral("IProcessorMode2"), + {opts.cpuMode}); + // Add 'CCPosIndRopi' item (Code and read-only data "ropi"). + addOptionsGroup(QByteArrayLiteral("CCPosIndRopi"), + {opts.generateReadOnlyPosIndependentCode}); + // Add 'CCPosIndRwpi' item (Read/write data "rwpi"). + addOptionsGroup(QByteArrayLiteral("CCPosIndRwpi"), + {opts.generateReadWritePosIndependentCode}); + // Add 'CCPosIndNoDynInit' item (No dynamic read/write initialization). + addOptionsGroup(QByteArrayLiteral("CCPosIndNoDynInit"), + {opts.disableDynamicReadWriteInitialization}); + // Add 'CCNoLiteralPool' item (No data reads in code memory). + addOptionsGroup(QByteArrayLiteral("CCNoLiteralPool"), + {opts.disableCodeMemoryDataReads}); +} + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.h b/src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.h new file mode 100644 index 000000000..6137bc976 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWARMCOMPILERSETTINGSGROUP_V8_H +#define QBS_IAREWARMCOMPILERSETTINGSGROUP_V8_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +class ArmCompilerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit ArmCompilerSettingsGroup(const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const ProductData &qbsProduct); + void buildLanguageOnePage(const ProductData &qbsProduct); + void buildLanguageTwoPage(const ProductData &qbsProduct); + void buildOptimizationsPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); + void buildCodePage(const ProductData &qbsProduct); +}; + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWARMCOMPILERSETTINGSGROUP_V8_H diff --git a/src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.cpp b/src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.cpp new file mode 100644 index 000000000..911873cf4 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.cpp @@ -0,0 +1,551 @@ +/**************************************************************************** +** +** 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 "armgeneralsettingsgroup_v8.h" + +#include "../../iarewutils.h" + +#include <QtCore/qdir.h> + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +constexpr int kGeneralArchiveVersion = 3; +constexpr int kGeneralDataVersion = 30; + +namespace { + +struct CpuCoreEntry final +{ + enum CpuCoreCode { + Arm7tdmi = 0, + Arm7tdmis = 1, + Arm710t = 2, + Arm720t = 3, + Arm740t = 4, + Arm7ejs = 5, + Arm9tdmi = 6, + Arm920t = 7, + Arm922t = 8, + Arm940t = 9, + Arm9e = 10, + Arm9es = 11, + Arm926ejs = 12, + Arm946es = 13, + Arm966es = 14, + Arm968es = 15, + Arm10e = 16, + Arm1020e = 17, + Arm1022e = 18, + Arm1026ejs = 19, + Arm1136j = 20, + Arm1136js = 21, + Arm1176j = 24, + Arm1176js = 25, + Xscale = 32, + XscaleIr7 = 33, + CortexM0 = 34, + CortexM0Plus = 35, + CortexM1 = 36, + CortexMs1 = 37, + CortexM3 = 38, + CortexM4 = 39, + CortexM7 = 41, + CortexR4 = 42, + CortexR5 = 44, + CortexR7 = 46, + CortexR8 = 48, + CortexR52 = 49, + CortexA5 = 50, + CortexA7 = 52, + CortexA8 = 53, + CortexA9 = 54, + CortexA15 = 55, + CortexA17 = 56, + CortexM23 = 58, + CortexM33 = 59 + }; + + // Required to compile in MSVC2015. + CpuCoreEntry(CpuCoreCode cc, QByteArray tf) + : coreCode(cc), targetFlag(std::move(tf)) + {} + + CpuCoreCode coreCode = Arm7tdmi; + QByteArray targetFlag; +}; + +// Dictionary of known ARM CPU cores and its compiler options. +static const CpuCoreEntry cpusDict[] = { + {CpuCoreEntry::Arm7tdmi, "arm7tdmi"}, // same as 'sc100' + {CpuCoreEntry::Arm7tdmis, "arm7tdmi-s"}, + {CpuCoreEntry::Arm710t, "arm710t"}, + {CpuCoreEntry::Arm720t, "arm720t"}, + {CpuCoreEntry::Arm740t, "arm740t"}, + {CpuCoreEntry::Arm7ejs, "arm7ej-s"}, + {CpuCoreEntry::Arm9tdmi, "arm9tdmi"}, + {CpuCoreEntry::Arm920t, "arm920t"}, + {CpuCoreEntry::Arm922t, "arm922t"}, + {CpuCoreEntry::Arm940t, "arm940t"}, + {CpuCoreEntry::Arm9e, "arm9e"}, + {CpuCoreEntry::Arm9es, "arm9e-s"}, + {CpuCoreEntry::Arm926ejs, "arm926ej-s"}, + {CpuCoreEntry::Arm946es, "arm946e-s"}, + {CpuCoreEntry::Arm966es, "arm966e-s"}, + {CpuCoreEntry::Arm968es, "arm968e-s"}, + {CpuCoreEntry::Arm10e, "arm10e"}, + {CpuCoreEntry::Arm1020e, "arm1020e"}, + {CpuCoreEntry::Arm1022e, "arm1022e"}, + {CpuCoreEntry::Arm1026ejs, "arm1026ej-s"}, + {CpuCoreEntry::Arm1136j, "arm1136j"}, + {CpuCoreEntry::Arm1136js, "arm1136j-s"}, + {CpuCoreEntry::Arm1176j, "arm1176j"}, + {CpuCoreEntry::Arm1176js, "arm1176j-s"}, + {CpuCoreEntry::Xscale, "xscale"}, + {CpuCoreEntry::XscaleIr7, "xscale-ir7"}, + {CpuCoreEntry::CortexM0, "cortex-m0"}, + {CpuCoreEntry::CortexM0Plus, "cortex-m0+"}, // same as 'sc000' + {CpuCoreEntry::CortexM1, "cortex-m1"}, + {CpuCoreEntry::CortexMs1, "cortex-ms1"}, + {CpuCoreEntry::CortexM3, "cortex-m3"}, // same as 'sc300' + {CpuCoreEntry::CortexM4, "cortex-m4"}, + {CpuCoreEntry::CortexM7, "cortex-m7"}, + {CpuCoreEntry::CortexR4, "cortex-r4"}, + {CpuCoreEntry::CortexR5, "cortex-r5"}, + {CpuCoreEntry::CortexR7, "cortex-r7"}, + {CpuCoreEntry::CortexR8, "cortex-r8"}, + {CpuCoreEntry::CortexR52, "cortex-r52"}, + {CpuCoreEntry::CortexA5, "cortex-a5"}, + {CpuCoreEntry::CortexA7, "cortex-a7"}, + {CpuCoreEntry::CortexA8, "cortex-a8"}, + {CpuCoreEntry::CortexA9, "cortex-a9"}, + {CpuCoreEntry::CortexA15, "cortex-a15"}, + {CpuCoreEntry::CortexA17, "cortex-a17"}, + {CpuCoreEntry::CortexM23, "cortex-m23"}, + {CpuCoreEntry::CortexM33, "cortex-m33"}, +}; + +struct FpuCoreEntry final +{ + enum FpuRegistersCount { + NoFpuRegisters, + Fpu16Registers, + Fpu32Registers + }; + + enum FpuCoreCode { + NoVfp = 0, + Vfp2 = 2, + Vfp3d16 = 3, + Vfp3 = 3, + Vfp4sp = 4, + Vfp4d16 = 5, + Vfp4 = 5, + Vfp5sp = 6, + Vfp5d16 = 7, + Vfp9s = 8 + }; + + // Required to compile in MSVC2015. + FpuCoreEntry(FpuCoreCode cc, FpuRegistersCount rc, + QByteArray tf) + : coreCode(cc), regsCount(rc), targetFlag(std::move(tf)) + {} + + FpuCoreCode coreCode = NoVfp; + FpuRegistersCount regsCount = NoFpuRegisters; + QByteArray targetFlag; +}; + +// Dictionary of known ARM FPU cores and its compiler options. +static const FpuCoreEntry fpusDict[] = { + {FpuCoreEntry::Vfp2, FpuCoreEntry::NoFpuRegisters, "vfpv2"}, + {FpuCoreEntry::Vfp3d16, FpuCoreEntry::Fpu16Registers, "vfpv3_d16"}, + {FpuCoreEntry::Vfp3, FpuCoreEntry::Fpu32Registers, "vfpv3"}, + {FpuCoreEntry::Vfp4sp, FpuCoreEntry::Fpu16Registers, "vfpv4_sp"}, + {FpuCoreEntry::Vfp4d16, FpuCoreEntry::Fpu16Registers, "vfpv4_d16"}, + {FpuCoreEntry::Vfp4, FpuCoreEntry::Fpu32Registers, "vfpv4"}, + {FpuCoreEntry::Vfp5sp, FpuCoreEntry::Fpu16Registers, "vfpv5_sp"}, + {FpuCoreEntry::Vfp5d16, FpuCoreEntry::Fpu16Registers, "vfpv5_d16"}, + {FpuCoreEntry::Vfp9s, FpuCoreEntry::NoFpuRegisters, "vfp9-s"}, +}; + +// Target page options. + +struct TargetPageOptions final +{ + enum Endianness { + LittleEndian, + BigEndian + }; + + explicit TargetPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("driverFlags")}); + // Detect target CPU code. + const QString cpuValue = IarewUtils::flagValue( + flags, QStringLiteral("--cpu")) + .toLower(); + const auto cpuEnd = std::cend(cpusDict); + const auto cpuIt = std::find_if(std::cbegin(cpusDict), cpuEnd, + [cpuValue]( + const CpuCoreEntry &entry) { + return entry.targetFlag == cpuValue.toLatin1(); + }); + if (cpuIt != cpuEnd) + targetCpu = cpuIt->coreCode; + // Detect target FPU code. + const QString fpuValue = IarewUtils::flagValue( + flags, QStringLiteral("--fpu")) + .toLower(); + const auto fpuEnd = std::cend(fpusDict); + const auto fpuIt = std::find_if(std::cbegin(fpusDict), fpuEnd, + [fpuValue]( + const FpuCoreEntry &entry) { + return entry.targetFlag == fpuValue.toLatin1(); + }); + if (fpuIt != fpuEnd) { + targetFpu = fpuIt->coreCode; + targetFpuRegs = fpuIt->regsCount; + } + // Detect endian. + const QString prop = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("endianness")); + if (prop == QLatin1String("big")) + endianness = TargetPageOptions::BigEndian; + else if (prop == QLatin1String("little")) + endianness = TargetPageOptions::LittleEndian; + } + + CpuCoreEntry::CpuCoreCode targetCpu = CpuCoreEntry::Arm7tdmi; + FpuCoreEntry::FpuCoreCode targetFpu = FpuCoreEntry::NoVfp; + FpuCoreEntry::FpuRegistersCount targetFpuRegs = FpuCoreEntry::NoFpuRegisters; + Endianness endianness = LittleEndian; +}; + +// Library 1 page options. + +struct LibraryOnePageOptions final +{ + enum PrintfFormatter { + PrintfAutoFormatter, + PrintfFullFormatter, + PrintfLargeFormatter, + PrintfSmallFormatter, + PrintfTinyFormatter + }; + + enum ScanfFormatter { + ScanfAutoFormatter, + ScanfFullFormatter, + ScanfLargeFormatter, + ScanfSmallFormatter + }; + + explicit LibraryOnePageOptions(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 != QLatin1String("--redirect")) + continue; + ++flagIt; + if (flagIt->startsWith(QLatin1String("_printf="), + Qt::CaseInsensitive)) { + const QString prop = flagIt->split( + QLatin1Char('=')).at(1).toLower(); + if (prop == QLatin1String("_printffullnomb")) + printfFormatter = LibraryOnePageOptions::PrintfFullFormatter; + else if (prop == QLatin1String("_printflargenomb")) + printfFormatter = LibraryOnePageOptions::PrintfLargeFormatter; + else if (prop == QLatin1String("_printfsmallnomb")) + printfFormatter = LibraryOnePageOptions::PrintfSmallFormatter; + else if (prop == QLatin1String("_printftiny")) + printfFormatter = LibraryOnePageOptions::PrintfTinyFormatter; + } else if (flagIt->startsWith(QLatin1String("_scanf="), + Qt::CaseInsensitive)) { + const QString prop = flagIt->split( + QLatin1Char('=')).at(1).toLower();; + if (prop == QLatin1String("_scanffullnomb")) + scanfFormatter = LibraryOnePageOptions::ScanfFullFormatter; + else if (prop == QLatin1String("_scanflargenomb")) + scanfFormatter = LibraryOnePageOptions::ScanfLargeFormatter; + else if (prop == QLatin1String("_scanfsmallnomb")) + scanfFormatter = LibraryOnePageOptions::ScanfSmallFormatter; + } + } + } + + PrintfFormatter printfFormatter = PrintfAutoFormatter; + ScanfFormatter scanfFormatter = ScanfAutoFormatter; +}; + +// Library 2 page options. + +struct LibraryTwoPageOptions final +{ + enum HeapType { + AutomaticHeap, + AdvancedHeap, + BasicHeap, + NoFreeHeap + }; + + explicit LibraryTwoPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + if (flags.contains(QLatin1String("--advanced_heap"))) + heapType = LibraryTwoPageOptions::AdvancedHeap; + else if (flags.contains(QLatin1String("--basic_heap"))) + heapType = LibraryTwoPageOptions::BasicHeap; + else if (flags.contains(QLatin1String("--no_free_heap"))) + heapType = LibraryTwoPageOptions::NoFreeHeap; + else + heapType = LibraryTwoPageOptions::AutomaticHeap; + } + + HeapType heapType = AutomaticHeap; +}; + +// Library configuration page options. + +struct LibraryConfigPageOptions final +{ + enum RuntimeLibrary { + NoLibrary, + NormalLibrary, + FullLibrary, + CustomLibrary + }; + + enum ThreadSupport { + NoThread, + EnableThread + }; + + enum LowLevelInterface { + NoInterface, + SemihostedInterface + }; + + explicit LibraryConfigPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + const QFileInfo dlibFileInfo(IarewUtils::flagValue( + flags, QStringLiteral("--dlib_config"))); + if (!dlibFileInfo.exists()) { + dlibType = LibraryConfigPageOptions::NoLibrary; + } else { + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QString dlibFilePath = dlibFileInfo.absoluteFilePath(); + if (dlibFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + if (dlibFilePath.endsWith(QLatin1String("dlib_config_normal.h"), + Qt::CaseInsensitive)) { + dlibType = LibraryConfigPageOptions::NormalLibrary; + } else if (dlibFilePath.endsWith( + QLatin1String("dlib_config_full.h"), + Qt::CaseInsensitive)) { + dlibType = LibraryConfigPageOptions::FullLibrary; + } else { + dlibType = LibraryConfigPageOptions::CustomLibrary; + } + + dlibConfigPath = IarewUtils::toolkitRelativeFilePath( + toolkitPath, dlibFilePath); + } else { + dlibType = LibraryConfigPageOptions::CustomLibrary; + dlibConfigPath = IarewUtils::projectRelativeFilePath( + baseDirectory, dlibFilePath); + } + } + + threadSupport = flags.contains(QLatin1String("--threaded_lib")) + ? LibraryConfigPageOptions::EnableThread + : LibraryConfigPageOptions::NoThread; + lowLevelInterface = flags.contains(QLatin1String("--semihosting")) + ? LibraryConfigPageOptions::SemihostedInterface + : LibraryConfigPageOptions::NoInterface; + } + + RuntimeLibrary dlibType = NoLibrary; + QString dlibConfigPath; + ThreadSupport threadSupport = NoThread; + LowLevelInterface lowLevelInterface = NoInterface; +}; + +// 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; +}; + +} // namespace + +// ArmGeneralSettingsGroup + +ArmGeneralSettingsGroup::ArmGeneralSettingsGroup( + 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); + buildLibraryOptionsOnePage(qbsProduct); + buildLibraryOptionsTwoPage(qbsProduct); + buildLibraryConfigPage(buildRootDirectory, qbsProduct); + buildOutputPage(buildRootDirectory, qbsProduct); +} + +void ArmGeneralSettingsGroup::buildTargetPage( + const ProductData &qbsProduct) +{ + const TargetPageOptions opts(qbsProduct); + // Add 'GBECoreSlave', 'CoreVariant', 'GFPUCoreSlave2' items + // (Processor variant chooser). + addOptionsGroup(QByteArrayLiteral("GBECoreSlave"), + {opts.targetCpu}, 26); + addOptionsGroup(QByteArrayLiteral("CoreVariant"), + {opts.targetCpu}, 26); + addOptionsGroup(QByteArrayLiteral("GFPUCoreSlave2"), + {opts.targetCpu}, 26); + // Add 'FPU2', 'NrRegs' item (Floating point settings chooser). + addOptionsGroup(QByteArrayLiteral("FPU2"), + {opts.targetFpu}, 0); + addOptionsGroup(QByteArrayLiteral("NrRegs"), + {opts.targetFpuRegs}, 0); + // Add 'GEndianMode' item (Endian mode chooser). + addOptionsGroup(QByteArrayLiteral("GEndianMode"), + {opts.endianness}); +} + +void ArmGeneralSettingsGroup::buildLibraryOptionsOnePage( + const ProductData &qbsProduct) +{ + const LibraryOnePageOptions opts(qbsProduct); + // Add 'OGPrintfVariant' item (Printf formatter). + addOptionsGroup(QByteArrayLiteral("OGPrintfVariant"), + {opts.printfFormatter}); + // Add 'OGScanfVariant' item (Printf formatter). + addOptionsGroup(QByteArrayLiteral("OGScanfVariant"), + {opts.scanfFormatter}); +} + +void ArmGeneralSettingsGroup::buildLibraryOptionsTwoPage( + const ProductData &qbsProduct) +{ + const LibraryTwoPageOptions opts(qbsProduct); + // Add 'OgLibHeap' item (Heap selection: + // auto/advanced/basic/nofree). + addOptionsGroup(QByteArrayLiteral("OgLibHeap"), + {opts.heapType}); +} + +void ArmGeneralSettingsGroup::buildLibraryConfigPage( + const QString baseDirectory, + const ProductData &qbsProduct) +{ + const LibraryConfigPageOptions opts(baseDirectory, qbsProduct); + // Add 'GRuntimeLibSelect', 'GRuntimeLibSelectSlave' + // and 'RTConfigPath2' items + // (Link with runtime: none/normal/full/custom). + addOptionsGroup(QByteArrayLiteral("GRuntimeLibSelect"), + {opts.dlibType}); + addOptionsGroup(QByteArrayLiteral("GRuntimeLibSelectSlave"), + {opts.dlibType}); + addOptionsGroup(QByteArrayLiteral("RTConfigPath2"), + {opts.dlibConfigPath}); + // Add 'GRuntimeLibThreads'item + // (Enable thread support in library). + addOptionsGroup(QByteArrayLiteral("GRuntimeLibThreads"), + {opts.threadSupport}); + // Add 'GenLowLevelInterface' item (Library low-level + // interface: none/semihosted/breakpoint). + addOptionsGroup(QByteArrayLiteral("GenLowLevelInterface"), + {opts.lowLevelInterface}); +} + +void ArmGeneralSettingsGroup::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}); +} + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.h b/src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.h new file mode 100644 index 000000000..420e98008 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWARMGENERALSETTINGSGROUP_V8_H +#define QBS_IAREWARMGENERALSETTINGSGROUP_V8_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +class ArmGeneralSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit ArmGeneralSettingsGroup(const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildTargetPage(const ProductData &qbsProduct); + void buildLibraryOptionsOnePage(const ProductData &qbsProduct); + void buildLibraryOptionsTwoPage(const ProductData &qbsProduct); + void buildLibraryConfigPage(const QString baseDirectory, + const ProductData &qbsProduct); + void buildOutputPage(const QString baseDirectory, + const ProductData &qbsProduct); +}; + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWARMGENERALSETTINGSGROUP_V8_H diff --git a/src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.cpp b/src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.cpp new file mode 100644 index 000000000..7e29c2788 --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.cpp @@ -0,0 +1,489 @@ +/**************************************************************************** +** +** 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 "armlinkersettingsgroup_v8.h" + +#include "../../iarewutils.h" + +#include <QtCore/qdir.h> + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +constexpr int kLinkerArchiveVersion = 0; +constexpr int kLinkerDataVersion = 20; + +namespace { + +// Config page options. + +struct ConfigPageOptions final +{ + explicit ConfigPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + // Accumulate config definitions (if exists). + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + configDefines = IarewUtils::flagValues( + flags, QStringLiteral("--config_def")); + 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) { + if (!qbsGroup.isEnabled()) + continue; + 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)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + configFilePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + configFilePaths.push_back(path); + } + } + } + + // Enumerate all product linker config files + // (which are set trough '--config' option). + const QVariantList configPathValues = IarewUtils::flagValues( + flags, QStringLiteral("--config")); + for (const auto &configPathValue : configPathValues) { + const QString fullConfigPath = configPathValue.toString(); + if (fullConfigPath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } + } + } + + QVariantList configFilePaths; + QVariantList configDefines; +}; + +// Library page options. + +struct LibraryPageOptions final +{ + explicit LibraryPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + + entryPoint = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("entryPoint")); + + // Add libraries search paths. + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList libraryPaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("libraryPaths")}); + for (const QString &libraryPath : libraryPaths) { + const QFileInfo libraryPathInfo(libraryPath); + const QString fullLibrarySearchPath = + libraryPathInfo.absoluteFilePath(); + if (fullLibrarySearchPath.startsWith( + toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullLibrarySearchPath); + librarySearchPaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory,fullLibrarySearchPath); + librarySearchPaths.push_back(path); + } + } + + // Add static libraries paths. + const QStringList staticLibrariesProps = + gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("staticLibraries")}); + for (const QString &staticLibrary : staticLibrariesProps) { + const QFileInfo staticLibraryInfo(staticLibrary); + if (staticLibraryInfo.isAbsolute()) { + const QString fullStaticLibraryPath = + staticLibraryInfo.absoluteFilePath(); + if (fullStaticLibraryPath.startsWith( + toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullStaticLibraryPath); + staticLibraries.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullStaticLibraryPath); + staticLibraries.push_back(path); + } + } else { + staticLibraries.push_back(staticLibrary); + } + } + + // Add static libraries from product dependencies. + for (const ProductData &qbsProductDep : qbsProductDeps) { + const QString depBinaryPath = QLatin1String("$PROJ_DIR$/") + + gen::utils::targetBinaryPath(baseDirectory, + qbsProductDep); + staticLibraries.push_back(depBinaryPath); + } + + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + enableRuntimeLibsSearch = !flags.contains( + QLatin1String("--no_library_search")); + } + + QString entryPoint; + QVariantList staticLibraries; + QVariantList librarySearchPaths; + int enableRuntimeLibsSearch = 0; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + debugInfo = !flags.contains(QLatin1String("--strip")); + outputFile = gen::utils::targetBinary(qbsProduct); + } + + int debugInfo = 0; + QString outputFile; +}; + +// Input page options. + +struct InputPageOptions final +{ + explicit InputPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + keepSymbols = IarewUtils::flagValues(flags, QStringLiteral("--keep")); + } + + QVariantList keepSymbols; +}; + +// List page options. + +struct ListPageOptions final +{ + enum ListingAction { + NoListing, + GenerateListing + }; + + explicit ListPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + generateMap = gen::utils::cppBooleanModuleProperty( + qbsProps, QStringLiteral("generateLinkerMapFile")) + ? ListPageOptions::GenerateListing + : ListPageOptions::NoListing; + } + + ListingAction generateMap = GenerateListing; +}; + +// Optimizations page options. + +struct OptimizationsPageOptions final +{ + explicit OptimizationsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + inlineSmallRoutines = flags.contains(QLatin1String("--inline")); + mergeDuplicateSections = flags.contains( + QLatin1String("--merge_duplicate_sections")); + virtualFuncElimination = flags.contains(QLatin1String("--vfe")); + } + + int inlineSmallRoutines = 0; + int mergeDuplicateSections = 0; + int virtualFuncElimination = 0; +}; + +// Advanced page options. + +struct AdvancedPageOptions final +{ + explicit AdvancedPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + allowExceptions = !flags.contains(QLatin1String("--no_exceptions")); + } + + int allowExceptions = 0; +}; + +// Defines page options. + +struct DefinesPageOptions final +{ + explicit DefinesPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + defineSymbols = IarewUtils::flagValues( + flags, QStringLiteral("--define_symbol")); + } + + QVariantList defineSymbols; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + treatWarningsAsErrors = gen::utils::cppIntegerModuleProperty( + qbsProps, QStringLiteral("treatWarningsAsErrors")); + } + + int treatWarningsAsErrors = 0; +}; + +} // namespace + +// ArmLinkerSettingsGroup + +ArmLinkerSettingsGroup::ArmLinkerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + setName(QByteArrayLiteral("ILINK")); + setArchiveVersion(kLinkerArchiveVersion); + setDataVersion(kLinkerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildConfigPage(buildRootDirectory, qbsProduct); + buildLibraryPage(buildRootDirectory, qbsProduct, qbsProductDeps); + buildOutputPage(qbsProduct); + buildInputPage(qbsProduct); + buildListPage(qbsProduct); + buildOptimizationsPage(qbsProduct); + buildAdvancedPage(qbsProduct); + buildDefinesPage(qbsProduct); + + // Should be called as latest stage! + buildExtraOptionsPage(qbsProduct); +} + +void ArmLinkerSettingsGroup::buildConfigPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + ConfigPageOptions opts(baseDirectory, qbsProduct); + // Add 'IlinkConfigDefines' item + // (Configuration file symbol definitions). + addOptionsGroup(QByteArrayLiteral("IlinkConfigDefines"), + opts.configDefines); + + if (opts.configFilePaths.count() > 0) { + // Note: IAR IDE does not allow to specify a multiple config files, + // although the IAR linker support it. So, we use followig 'trick': + // we take a first config file and to add it as usual to required items; + // and then an other remainders we forward to the "Extra options page". + const QVariant configPath = opts.configFilePaths.takeFirst(); + // Add 'IlinkIcfOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("IlinkIcfOverride"), + {1}); + // Add 'IlinkIcfFile' item (Linker configuration file). + addOptionsGroup(QByteArrayLiteral("IlinkIcfFile"), + {configPath}); + + // Add remainder configuration files to the "Extra options page". + if (!opts.configFilePaths.isEmpty()) { + for (QVariant &configPath : opts.configFilePaths) + configPath = QLatin1String("--config ") + + configPath.toString(); + + m_extraOptions << opts.configFilePaths; + } + } +} + +void ArmLinkerSettingsGroup::buildLibraryPage( + const QString &baseDirectory, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + LibraryPageOptions opts(baseDirectory, qbsProduct, qbsProductDeps); + // Add 'IlinkOverrideProgramEntryLabel' item + // (Override default program entry). + addOptionsGroup(QByteArrayLiteral("IlinkOverrideProgramEntryLabel"), + {1}); + const int select = opts.entryPoint.isEmpty() ? 1 : 0; + addOptionsGroup(QByteArrayLiteral("IlinkProgramEntryLabelSelect"), + {select}); + // Add 'IlinkProgramEntryLabel' item (Entry point name). + addOptionsGroup(QByteArrayLiteral("IlinkProgramEntryLabel"), + {opts.entryPoint}); + + if (!opts.staticLibraries.isEmpty()) { + // Add 'IlinkAdditionalLibs' item (Additional libraries). + addOptionsGroup(QByteArrayLiteral("IlinkAdditionalLibs"), + opts.staticLibraries); + } + + // Add 'IlinkAutoLibEnable' item + // (Automatic runtime library selection). + addOptionsGroup(QByteArrayLiteral("IlinkAutoLibEnable"), + {opts.enableRuntimeLibsSearch}); + + // Add library searh directories to the + // "Extra options page", because IAR IDE + // has not other options to add this paths. + for (QVariant &libraryPath : opts.librarySearchPaths) + libraryPath = QLatin1String("-L ") + libraryPath.toString(); + + m_extraOptions << opts.librarySearchPaths; +} + +void ArmLinkerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'IlinkDebugInfoEnable' item + // (Include debug information in output). + addOptionsGroup(QByteArrayLiteral("IlinkDebugInfoEnable"), + {opts.debugInfo}); + // Add 'IlinkOutputFile' item (Output filename). + addOptionsGroup(QByteArrayLiteral("IlinkOutputFile"), + {opts.outputFile}); +} + +void ArmLinkerSettingsGroup::buildInputPage( + const ProductData &qbsProduct) +{ + const InputPageOptions opts(qbsProduct); + // Add 'IlinkKeepSymbols' item (). + addOptionsGroup(QByteArrayLiteral("IlinkKeepSymbols"), + opts.keepSymbols); +} + +void ArmLinkerSettingsGroup::buildListPage( + const ProductData &qbsProduct) +{ + const ListPageOptions opts(qbsProduct); + // Add 'IlinkMapFile' item (Generate linker map file). + addOptionsGroup(QByteArrayLiteral("IlinkMapFile"), + {opts.generateMap}); +} + +void ArmLinkerSettingsGroup::buildOptimizationsPage( + const ProductData &qbsProduct) +{ + const OptimizationsPageOptions opts(qbsProduct); + // Add 'IlinkOptInline' item (Inline small routines). + addOptionsGroup(QByteArrayLiteral("IlinkOptInline"), + {opts.inlineSmallRoutines}); + // Add 'IlinkOptMergeDuplSections'item + // (Merge duplicate sections). + addOptionsGroup(QByteArrayLiteral("IlinkOptMergeDuplSections"), + {opts.mergeDuplicateSections}); + // Add 'IlinkOptUseVfe' item + // (Perform C++ virtual functions elimination). + addOptionsGroup(QByteArrayLiteral("IlinkOptUseVfe"), + {opts.virtualFuncElimination}); +} + +void ArmLinkerSettingsGroup::buildAdvancedPage( + const ProductData &qbsProduct) +{ + const AdvancedPageOptions opts(qbsProduct); + // Add 'IlinkOptExceptionsAllow' item (Allow C++ exceptions). + addOptionsGroup(QByteArrayLiteral("IlinkOptExceptionsAllow"), + {opts.allowExceptions}); +} + +void ArmLinkerSettingsGroup::buildDefinesPage( + const ProductData &qbsProduct) +{ + const DefinesPageOptions opts(qbsProduct); + // Add 'IlinkDefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("IlinkDefines"), + {opts.defineSymbols}); +} + +void ArmLinkerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'IlinkWarningsAreErrors' item + // (Treat all warnings as errors). + addOptionsGroup(QByteArrayLiteral("IlinkWarningsAreErrors"), + {opts.treatWarningsAsErrors}); +} + +void ArmLinkerSettingsGroup::buildExtraOptionsPage( + const ProductData &qbsProduct) +{ + Q_UNUSED(qbsProduct) + + // Add 'IlinkUseExtraOptions' and 'IlinkExtraOptions' items. + addOptionsGroup(QByteArrayLiteral("IlinkUseExtraOptions"), + {1}); + addOptionsGroup(QByteArrayLiteral("IlinkExtraOptions"), + m_extraOptions); +} + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.h b/src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.h new file mode 100644 index 000000000..e86297e6e --- /dev/null +++ b/src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWARMLINKERSETTINGSGROUP_V8_H +#define QBS_IAREWARMLINKERSETTINGSGROUP_V8_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace arm { +namespace v8 { + +class ArmLinkerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit ArmLinkerSettingsGroup(const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildConfigPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildLibraryPage(const QString &baseDirectory, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + void buildOutputPage(const ProductData &qbsProduct); + void buildInputPage(const ProductData &qbsProduct); + void buildListPage(const ProductData &qbsProduct); + void buildOptimizationsPage(const ProductData &qbsProduct); + void buildAdvancedPage(const ProductData &qbsProduct); + void buildDefinesPage(const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); + void buildExtraOptionsPage(const ProductData &qbsProduct); + + QVariantList m_extraOptions; +}; + +} // namespace v8 +} // namespace arm +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWARMLINKERSETTINGSGROUP_V8_H diff --git a/src/plugins/generator/iarew/archs/avr/avrarchiversettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/avr/avrarchiversettingsgroup_v7.cpp new file mode 100644 index 000000000..4e002d13f --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrarchiversettingsgroup_v7.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** 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 "avrarchiversettingsgroup_v7.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +constexpr int kArchiverArchiveVersion = 2; +constexpr int kArchiverDataVersion = 0; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + outputFile = QLatin1String("$PROJ_DIR$/") + + gen::utils::targetBinaryPath(baseDirectory, qbsProduct); + } + + QString outputFile; +}; + +} // namespace + +// AvrArchiverSettingsGroup + +AvrArchiverSettingsGroup::AvrArchiverSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("XAR")); + setArchiveVersion(kArchiverArchiveVersion); + setDataVersion(kArchiverDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + buildOutputPage(buildRootDirectory, qbsProduct); +} + +void AvrArchiverSettingsGroup::buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(baseDirectory, qbsProduct); + // Add 'XAROutOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("XAROutOverride"), + {1}); + // Add 'OutputFile' item (Output filename). + addOptionsGroup(QByteArrayLiteral("OutputFile"), + {opts.outputFile}); +} + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/avr/avrarchiversettingsgroup_v7.h b/src/plugins/generator/iarew/archs/avr/avrarchiversettingsgroup_v7.h new file mode 100644 index 000000000..2ff667e1d --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrarchiversettingsgroup_v7.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWAVRARCHIVERSETTINGSGROUP_V7_H +#define QBS_IAREWAVRARCHIVERSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +class AvrArchiverSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit AvrArchiverSettingsGroup(const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct); +}; + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWAVRARCHIVERSETTINGSGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/avr/avrassemblersettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/avr/avrassemblersettingsgroup_v7.cpp new file mode 100644 index 000000000..08e86be53 --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrassemblersettingsgroup_v7.cpp @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** 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 "avrassemblersettingsgroup_v7.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +constexpr int kAssemblerArchiveVersion = 5; +constexpr int kAssemblerDataVersion = 11; + +namespace { + +// Language page options. + +struct LanguagePageOptions final +{ + enum MacroQuoteCharacter { + AngleBracketsQuote, + RoundBracketsQuote, + SquareBracketsQuote, + FigureBracketsQuote + }; + + explicit LanguagePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("assemblerFlags")}); + enableSymbolsCaseSensitive = flags.contains(QLatin1String("-s+")); + enableMultibyteSupport = flags.contains(QLatin1String("-n")); + + if (flags.contains(QLatin1String("-M<>"))) + macroQuoteCharacter = LanguagePageOptions::AngleBracketsQuote; + else if (flags.contains(QLatin1String("-M()"))) + macroQuoteCharacter = LanguagePageOptions::RoundBracketsQuote; + else if (flags.contains(QLatin1String("-M[]"))) + macroQuoteCharacter = LanguagePageOptions::SquareBracketsQuote; + else if (flags.contains(QLatin1String("-M{}"))) + macroQuoteCharacter = LanguagePageOptions::FigureBracketsQuote; + } + + MacroQuoteCharacter macroQuoteCharacter = AngleBracketsQuote; + int enableSymbolsCaseSensitive = 0; + int enableMultibyteSupport = 0; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + debugInfo = gen::utils::debugInformation(qbsProduct); + } + + int debugInfo = 0; +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + for (const auto &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString warningLevel = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("warningLevel")); + if (warningLevel == QLatin1String("all")) { + enableWarnings = 0; + enableAllWarnings = 0; + } else if (warningLevel == QLatin1String("none")) { + enableWarnings = 1; + enableAllWarnings = 0; + } else { + enableWarnings = 0; + enableAllWarnings = 1; + } + } + + int enableWarnings = 0; + int enableAllWarnings = 0; +}; + +} // namespace + +// AvrAssemblerSettingsGroup + +AvrAssemblerSettingsGroup::AvrAssemblerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("AAVR")); + setArchiveVersion(kAssemblerArchiveVersion); + setDataVersion(kAssemblerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildLanguagePage(qbsProduct); + buildOutputPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); +} + +void AvrAssemblerSettingsGroup::buildLanguagePage( + const ProductData &qbsProduct) +{ + const LanguagePageOptions opts(qbsProduct); + // Add 'ACaseSensitivity' item (User symbols are case sensitive). + addOptionsGroup(QByteArrayLiteral("ACaseSensitivity"), + {opts.enableSymbolsCaseSensitive}); + // Add 'AsmMultiByteSupport' item (Enable multibyte support). + addOptionsGroup(QByteArrayLiteral("AsmMultiByteSupport"), + {opts.enableMultibyteSupport}); + // Add 'MacroChars' item (Macro quote characters: ()/[]/{}/<>). + addOptionsGroup(QByteArrayLiteral("MacroChars"), + {opts.macroQuoteCharacter}, 0); +} + +void AvrAssemblerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'CDebug' item (Generate debug information). + addOptionsGroup(QByteArrayLiteral("CDebug"), + {opts.debugInfo}); +} + +void AvrAssemblerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'ADefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("ADefines"), + opts.defineSymbols); + // Add 'AUserIncludes' item (Additional include directories). + addOptionsGroup(QByteArrayLiteral("ANewIncludes"), + opts.includePaths); +} + +void AvrAssemblerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'AWarnEnable' item (Enable/disable warnings). + addOptionsGroup(QByteArrayLiteral("AWarnEnable"), + {opts.enableWarnings}); + // Add 'AWarnWhat' item (Enable/disable all warnings). + addOptionsGroup(QByteArrayLiteral("AWarnWhat"), + {opts.enableAllWarnings}); +} + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/avr/avrassemblersettingsgroup_v7.h b/src/plugins/generator/iarew/archs/avr/avrassemblersettingsgroup_v7.h new file mode 100644 index 000000000..608a42652 --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrassemblersettingsgroup_v7.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWAVRASSEMBLERSETTINGSGROUP_V7_H +#define QBS_IAREWAVRASSEMBLERSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +class AvrAssemblerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit AvrAssemblerSettingsGroup(const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildLanguagePage(const ProductData &qbsProduct); + void buildOutputPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); +}; + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWAVRASSEMBLERSETTINGSGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/avr/avrbuildconfigurationgroup_v7.cpp b/src/plugins/generator/iarew/archs/avr/avrbuildconfigurationgroup_v7.cpp new file mode 100644 index 000000000..dbb5c6620 --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrbuildconfigurationgroup_v7.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 "avrarchiversettingsgroup_v7.h" +#include "avrassemblersettingsgroup_v7.h" +#include "avrbuildconfigurationgroup_v7.h" +#include "avrcompilersettingsgroup_v7.h" +#include "avrgeneralsettingsgroup_v7.h" +#include "avrlinkersettingsgroup_v7.h" + +#include "../../iarewtoolchainpropertygroup.h" +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +AvrBuildConfigurationGroup::AvrBuildConfigurationGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) + : gen::xml::PropertyGroup("configuration") +{ + // Append configuration name item. + const QString cfgName = gen::utils::buildConfigurationName(qbsProject); + appendProperty("name", cfgName); + + // Apend toolchain name group item. + appendChild<IarewToolchainPropertyGroup>("AVR"); + + // Append debug info item. + const int debugBuild = gen::utils::debugInformation(qbsProduct); + appendProperty("debug", debugBuild); + + // Append settings group items. + appendChild<AvrArchiverSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<AvrAssemblerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<AvrCompilerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<AvrGeneralSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<AvrLinkerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); +} + +bool AvrBuildConfigurationGroupFactory::canCreate( + gen::utils::Architecture arch, + const Version &version) const +{ + return arch == gen::utils::Architecture::Avr + && version.majorVersion() == 7; +} + +std::unique_ptr<gen::xml::PropertyGroup> +AvrBuildConfigurationGroupFactory::create( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const +{ + const auto group = new AvrBuildConfigurationGroup( + qbsProject, qbsProduct, qbsProductDeps); + return std::unique_ptr<AvrBuildConfigurationGroup>(group); +} + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/avr/avrbuildconfigurationgroup_v7.h b/src/plugins/generator/iarew/archs/avr/avrbuildconfigurationgroup_v7.h new file mode 100644 index 000000000..618cef4c6 --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrbuildconfigurationgroup_v7.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWAVRBUILDCONFIGURATIONGROUP_V7_H +#define QBS_IAREWAVRBUILDCONFIGURATIONGROUP_V7_H + +#include <generators/generatorutils.h> +#include <generators/xmlpropertygroup.h> + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +class AvrBuildConfigurationGroup final + : public gen::xml::PropertyGroup +{ +private: + explicit AvrBuildConfigurationGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + + friend class AvrBuildConfigurationGroupFactory; +}; + +class AvrBuildConfigurationGroupFactory final + : public gen::xml::PropertyGroupFactory +{ +public: + bool canCreate(gen::utils::Architecture arch, + const Version &version) const final; + + std::unique_ptr<gen::xml::PropertyGroup> create( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const final; +}; + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWAVRBUILDCONFIGURATIONGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/avr/avrcompilersettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/avr/avrcompilersettingsgroup_v7.cpp new file mode 100644 index 000000000..26b6858f1 --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrcompilersettingsgroup_v7.cpp @@ -0,0 +1,492 @@ +/**************************************************************************** +** +** 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 "avrcompilersettingsgroup_v7.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +constexpr int kCompilerArchiveVersion = 6; +constexpr int kCompilerDataVersion = 17; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + moduleType = flags.contains(QLatin1String("--library_module")) + ? OutputPageOptions::LibraryModule + : OutputPageOptions::ProgramModule; + debugInfo = gen::utils::debugInformation(qbsProduct); + disableErrorMessages = flags.contains( + QLatin1String("--no_ubrof_messages")); + } + + int debugInfo = 0; + int disableErrorMessages = 0; + enum ModuleType { ProgramModule, LibraryModule}; + ModuleType moduleType = ProgramModule; +}; + +// Language one page options. + +struct LanguageOnePageOptions final +{ + enum LanguageExtension { + CLanguageExtension, + CxxLanguageExtension, + AutoLanguageExtension + }; + + enum CLanguageDialect { + C89LanguageDialect, + C99LanguageDialect + }; + + enum CxxLanguageDialect { + EmbeddedCPlusPlus, + ExtendedEmbeddedCPlusPlus + }; + + enum LanguageConformance { + AllowIarExtension, + RelaxedStandard, + StrictStandard + }; + + explicit LanguageOnePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + // File extension based by default. + languageExtension = LanguageOnePageOptions::AutoLanguageExtension; + // C language dialect. + const QStringList cLanguageVersion = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("cLanguageVersion")}); + if (cLanguageVersion.contains(QLatin1String("c89"))) + cLanguageDialect = LanguageOnePageOptions::C89LanguageDialect; + else if (cLanguageVersion.contains(QLatin1String("c99"))) + cLanguageDialect = LanguageOnePageOptions::C99LanguageDialect; + // C++ language dialect. + if (flags.contains(QLatin1String("--ec++"))) + cxxLanguageDialect = LanguageOnePageOptions::EmbeddedCPlusPlus; + else if (flags.contains(QLatin1String("--eec++"))) + cxxLanguageDialect = LanguageOnePageOptions::ExtendedEmbeddedCPlusPlus; + // Language conformance. + if (flags.contains(QLatin1String("-e"))) + languageConformance = LanguageOnePageOptions::AllowIarExtension; + else if (flags.contains(QLatin1String("--strict"))) + languageConformance = LanguageOnePageOptions::StrictStandard; + else + languageConformance = LanguageOnePageOptions::RelaxedStandard; + + allowVla = flags.contains(QLatin1String("--vla")); + useCppInlineSemantics = flags.contains( + QLatin1String("--use_c++_inline")); + requirePrototypes = flags.contains( + QLatin1String("--require_prototypes")); + destroyStaticObjects = !flags.contains( + QLatin1String("--no_static_destruction")); + } + + LanguageExtension languageExtension = AutoLanguageExtension; + CLanguageDialect cLanguageDialect = C89LanguageDialect; + CxxLanguageDialect cxxLanguageDialect = EmbeddedCPlusPlus; + LanguageConformance languageConformance = AllowIarExtension; + int allowVla = 0; + int useCppInlineSemantics = 0; + int requirePrototypes = 0; + int destroyStaticObjects = 0; +}; + +// Language two page options. + +struct LanguageTwoPageOptions final +{ + enum PlainCharacter { + SignedCharacter, + UnsignedCharacter + }; + + enum FloatingPointSemantic { + StrictSemantic, + RelaxedSemantic + }; + + explicit LanguageTwoPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + plainCharacter = flags.contains(QLatin1String("--char_is_signed")) + ? LanguageTwoPageOptions::SignedCharacter + : LanguageTwoPageOptions::UnsignedCharacter; + floatingPointSemantic = flags.contains(QLatin1String("--relaxed_fp")) + ? LanguageTwoPageOptions::RelaxedSemantic + : LanguageTwoPageOptions::StrictSemantic; + enableMultibyteSupport = flags.contains( + QLatin1String("--enable_multibytes")); + } + + PlainCharacter plainCharacter = SignedCharacter; + FloatingPointSemantic floatingPointSemantic = StrictSemantic; + int enableMultibyteSupport = 0; +}; + +// Optimizations page options. + +struct OptimizationsPageOptions final +{ + // Optimizations level radio-buttons with + // combo-box on "level" widget. + enum Strategy { + StrategyBalanced, + StrategySize, + StrategySpeed + }; + + enum Level { + LevelNone, + LevelLow, + LevelMedium, + LevelHigh + }; + + enum LevelSlave { + LevelSlave0, + LevelSlave1, + LevelSlave2, + LevelSlave3 + }; + + explicit OptimizationsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString optimization = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("optimization")); + if (optimization == QLatin1String("none")) { + optimizationStrategy = OptimizationsPageOptions::StrategyBalanced; + optimizationLevel = OptimizationsPageOptions::LevelNone; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave0; + } else if (optimization == QLatin1String("fast")) { + optimizationStrategy = OptimizationsPageOptions::StrategySpeed; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } else if (optimization == QLatin1String("small")) { + optimizationStrategy = OptimizationsPageOptions::StrategySize; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } + + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + enableCommonSubexpressionElimination = !flags.contains( + QLatin1String("--no_cse")); + enableFunctionInlining = !flags.contains(QLatin1String("--no_inline")); + enableCodeMotion = !flags.contains(QLatin1String("--no_code_motion")); + enableCrossCall = !flags.contains(QLatin1String("--no_cross_call")); + enableVariableClustering = !flags.contains( + QLatin1String("--no_clustering")); + enableTypeBasedAliasAnalysis = !flags.contains( + QLatin1String("--no_tbaa")); + enableForceCrossCall = flags.contains( + QLatin1String("--do_cross_call")); + } + + Strategy optimizationStrategy = StrategyBalanced; + Level optimizationLevel = LevelNone; + LevelSlave optimizationLevelSlave = LevelSlave0; + // Six bit-field flags on "enabled optimizations" widget. + int enableCommonSubexpressionElimination = 0; // Common sub-expression elimination. + int enableFunctionInlining = 0; // Function inlining. + int enableCodeMotion = 0; // Code motion. + int enableCrossCall = 0; // Cross call optimization. + int enableVariableClustering = 0; // Variable clustering. + int enableTypeBasedAliasAnalysis = 0; // Type based alias analysis. + // Force cross-call optimization. + int enableForceCrossCall = 0; +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + for (const QString &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + warningsAsErrors = gen::utils::cppIntegerModuleProperty( + qbsProps, QStringLiteral("treatWarningsAsErrors")); + } + + int warningsAsErrors = 0; +}; + +// Code page options. + +struct CodePageOptions final +{ + explicit CodePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + placeConstantsInRam = flags.contains(QLatin1String("-y")); + placeInitializiersInFlash = flags.contains( + QLatin1String("--initializiers_in_flash")); + forceVariablesGeneration = flags.contains( + QLatin1String("--root_variables")); + useIccA90CallingConvention = flags.contains( + QLatin1String("--version1_calls")); + lockRegistersCount = IarewUtils::flagValue( + flags, QStringLiteral("--lock_regs")).toInt(); + } + + int placeConstantsInRam = 0; + int placeInitializiersInFlash = 0; + int forceVariablesGeneration = 0; + int useIccA90CallingConvention = 0; + int lockRegistersCount = 0; +}; + +} // namespace + +// AvrCompilerSettingsGroup + +AvrCompilerSettingsGroup::AvrCompilerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("ICCAVR")); + setArchiveVersion(kCompilerArchiveVersion); + setDataVersion(kCompilerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildOutputPage(qbsProduct); + buildLanguageOnePage(qbsProduct); + buildLanguageTwoPage(qbsProduct); + buildOptimizationsPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); + buildCodePage(qbsProduct); +} + +void AvrCompilerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'CCDebugInfo' item (Generate debug info). + addOptionsGroup(QByteArrayLiteral("CCDebugInfo"), + {opts.debugInfo}); + // Add 'CCNoErrorMsg' item (No error messages in output files). + addOptionsGroup(QByteArrayLiteral("CCNoErrorMsg"), + {opts.disableErrorMessages}); + // Add 'CCOverrideModuleTypeDefault' item + // (Override default module type). + addOptionsGroup(QByteArrayLiteral("CCOverrideModuleTypeDefault"), + {1}); + // Add 'CCRadioModuleType' item (Module type: program/library). + addOptionsGroup(QByteArrayLiteral("CCRadioModuleType"), + {opts.moduleType}); +} + +void AvrCompilerSettingsGroup::buildLanguageOnePage( + const ProductData &qbsProduct) +{ + const LanguageOnePageOptions opts(qbsProduct); + // Add 'IccLang' item with 'auto-extension based' + // value (Language: C/C++/Auto). + addOptionsGroup(QByteArrayLiteral("IccLang"), + {opts.languageExtension}); + // Add 'IccCDialect' item (C dialect: c89/99/11). + addOptionsGroup(QByteArrayLiteral("IccCDialect"), + {opts.cLanguageDialect}); + // Add 'IccCppDialect' item (C++ dialect: embedded/extended). + addOptionsGroup(QByteArrayLiteral("IccCppDialect"), + {opts.cxxLanguageDialect}); + // Add 'CCExt' item (Language conformance: IAR/relaxed/strict). + addOptionsGroup(QByteArrayLiteral("CCExt"), + {opts.languageConformance}); + // Add 'IccAllowVLA' item (Allow VLA). + addOptionsGroup(QByteArrayLiteral("IccAllowVLA"), + {opts.allowVla}); + // Add 'IccCppInlineSemantics' item (C++ inline semantics). + addOptionsGroup(QByteArrayLiteral("IccCppInlineSemantics"), + {opts.useCppInlineSemantics}); + // Add 'CCRequirePrototypes' item (Require prototypes). + addOptionsGroup(QByteArrayLiteral("CCRequirePrototypes"), + {opts.requirePrototypes}); + // Add 'IccStaticDestr' item (Destroy static objects). + addOptionsGroup(QByteArrayLiteral("IccStaticDestr"), + {opts.destroyStaticObjects}); +} + +void AvrCompilerSettingsGroup::buildLanguageTwoPage( + const ProductData &qbsProduct) +{ + const LanguageTwoPageOptions opts(qbsProduct); + // Add 'CCCharIs' item (Plain char is: signed/unsigned). + addOptionsGroup(QByteArrayLiteral("CCCharIs"), + {opts.plainCharacter}); + // Add 'IccFloatSemantics' item (Floatic-point + // semantics: strict/relaxed conformance). + addOptionsGroup(QByteArrayLiteral("IccFloatSemantics"), + {opts.floatingPointSemantic}); + // Add 'CCMultibyteSupport' item (Enable multibyte support). + addOptionsGroup(QByteArrayLiteral("CCMultibyteSupport"), + {opts.enableMultibyteSupport}); +} + +void AvrCompilerSettingsGroup::buildOptimizationsPage( + const ProductData &qbsProduct) +{ + const OptimizationsPageOptions opts(qbsProduct); + // Add 'CCOptStrategy', 'CCOptLevel' and + // 'CCOptLevelSlave' items (Level). + addOptionsGroup(QByteArrayLiteral("CCOptStrategy"), + {opts.optimizationStrategy}); + addOptionsGroup(QByteArrayLiteral("CCOptLevel"), + {opts.optimizationLevel}); + addOptionsGroup(QByteArrayLiteral("CCOptLevelSlave"), + {opts.optimizationLevelSlave}); + // Add 'CCAllowList' item + // (Enabled optimizations: 6 check boxes). + const QString bitflags = QStringLiteral("%1%2%3%4%5%6") + .arg(opts.enableCommonSubexpressionElimination) + .arg(opts.enableFunctionInlining) + .arg(opts.enableCodeMotion) + .arg(opts.enableCrossCall) + .arg(opts.enableVariableClustering) + .arg(opts.enableTypeBasedAliasAnalysis); + addOptionsGroup(QByteArrayLiteral("CCAllowList"), + {bitflags}); + // Add 'CCOptForceCrossCall' item + // (Always do cross call optimization). + addOptionsGroup(QByteArrayLiteral("CCOptForceCrossCall"), + {opts.enableForceCrossCall}); +} + +void AvrCompilerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'CCDefines' item (Defines symbols). + addOptionsGroup(QByteArrayLiteral("CCDefines"), + opts.defineSymbols); + // Add 'newCCIncludePaths' item + // (Additional include directories). + addOptionsGroup(QByteArrayLiteral("newCCIncludePaths"), + opts.includePaths); +} + +void AvrCompilerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'CCWarnAsError' item (Treat all warnings as errors). + addOptionsGroup(QByteArrayLiteral("CCWarnAsError"), + {opts.warningsAsErrors}); +} + +void AvrCompilerSettingsGroup::buildCodePage( + const ProductData &qbsProduct) +{ + const CodePageOptions opts(qbsProduct); + // Add 'CCConstInRAM' item (Place string literals + // and constants in initialized RAM). + addOptionsGroup(QByteArrayLiteral("CCConstInRAM"), + {opts.placeConstantsInRam}); + // Add 'CCInitInFlash' item (Place aggregate + // initializiers in flash memory). + addOptionsGroup(QByteArrayLiteral("CCInitInFlash"), + {opts.placeInitializiersInFlash}); + // Add 'CCForceVariables' item (Force generation of + // all global and static variables). + addOptionsGroup(QByteArrayLiteral("CCForceVariables"), + {opts.forceVariablesGeneration}); + // Add 'CCOldCallConv' item (Use ICCA90 1.x + // calling convention). + addOptionsGroup(QByteArrayLiteral("CCOldCallConv"), + {opts.useIccA90CallingConvention}); + // Add 'CCLockRegs' item (Number of registers to + // lock for global variables). + addOptionsGroup(QByteArrayLiteral("CCLockRegs"), + {opts.lockRegistersCount}); +} + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/avr/avrcompilersettingsgroup_v7.h b/src/plugins/generator/iarew/archs/avr/avrcompilersettingsgroup_v7.h new file mode 100644 index 000000000..2d8c53b84 --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrcompilersettingsgroup_v7.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWAVRCOMPILERSETTINGSGROUP_V7_H +#define QBS_IAREWAVRCOMPILERSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +class AvrCompilerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit AvrCompilerSettingsGroup(const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const ProductData &qbsProduct); + void buildLanguageOnePage(const ProductData &qbsProduct); + void buildLanguageTwoPage(const ProductData &qbsProduct); + void buildOptimizationsPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); + void buildCodePage(const ProductData &qbsProduct); +}; + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWAVRCOMPILERSETTINGSGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/avr/avrgeneralsettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/avr/avrgeneralsettingsgroup_v7.cpp new file mode 100644 index 000000000..a4819a90d --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrgeneralsettingsgroup_v7.cpp @@ -0,0 +1,774 @@ +/**************************************************************************** +** +** 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 "avrgeneralsettingsgroup_v7.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +constexpr int kGeneralArchiveVersion = 12; +constexpr int kGeneralDataVersion = 10; + +namespace { + +struct TargetMcuEntry final +{ + QByteArray targetName; + QByteArray targetFlag; +}; + +// Dictionary of known AVR MCU's and its compiler options. +static const TargetMcuEntry mcusDict[] = { + {"AT43USB320A", "at43usb320a"}, + {"AT43USB325", "at43usb325"}, + {"AT43USB326", "at43usb326"}, + {"AT43USB351M", "at43usb351m"}, + {"AT43USB353M", "at43usb353m"}, + {"AT43USB355", "at43usb355"}, + {"AT76C712", "at76c712"}, + {"AT76C713", "at76c713"}, + {"AT86RF401", "at86rf401"}, + {"AT90CAN128", "can128"}, + {"AT90CAN32", "can32"}, + {"AT90CAN64", "can64"}, + {"AT90PWM1", "pwm1"}, + {"AT90PWM161", "pwm161"}, + {"AT90PWM2", "pwm2"}, + {"AT90PWM216", "pwm216"}, + {"AT90PWM2B", "pwm2b"}, + {"AT90PWM3", "pwm3"}, + {"AT90PWM316", "pwm316"}, + {"AT90PWM3B", "pwm3b"}, + {"AT90PWM81", "pwm81"}, + {"AT90S1200", "1200"}, + {"AT90S2313", "2313"}, + {"AT90S2323", "2323"}, + {"AT90S2333", "2333"}, + {"AT90S2343", "2343"}, + {"AT90S4414", "4414"}, + {"AT90S4433", "4433"}, + {"AT90S4434", "4434"}, + {"AT90S8515", "8515"}, + {"AT90S8534", "8534"}, + {"AT90S8535", "8535"}, + {"AT90SCR050", "scr050"}, + {"AT90SCR075", "scr075"}, + {"AT90SCR100", "scr100"}, + {"AT90SCR200", "scr200"}, + {"AT90SCR400", "scr400"}, + {"AT90USB128", "usb128"}, + {"AT90USB1286", "usb1286"}, + {"AT90USB1287", "usb1287"}, + {"AT90USB162", "usb162"}, + {"AT90USB64", "usb64"}, + {"AT90USB646", "usb646"}, + {"AT90USB647", "usb647"}, + {"AT90USB82", "usb82"}, + {"AT94Kxx", "at94k"}, + {"ATA5272", "ata5272"}, + {"ATA5505", "ata5505"}, + {"ATA5700M322", "ata5700m322"}, + {"ATA5702M322", "ata5702m322"}, + {"ATA5781", "ata5781"}, + {"ATA5782", "ata5782"}, + {"ATA5783", "ata5783"}, + {"ATA5785", "ata5785"}, + {"ATA5787", "ata5787"}, + {"ATA5790", "ata5790"}, + {"ATA5790N", "ata5790n"}, + {"ATA5795", "ata5795"}, + {"ATA5830", "ata5830"}, + {"ATA5831", "ata5831"}, + {"ATA5832", "ata5832"}, + {"ATA5833", "ata5833"}, + {"ATA5835", "ata5835"}, + {"ATA6285", "ata6285"}, + {"ATA6286", "ata6286"}, + {"ATA6289", "ata6289"}, + {"ATA8210", "ata8210"}, + {"ATA8215", "ata8215"}, + {"ATA8510", "ata8510"}, + {"ATA8515", "ata8515"}, + {"ATmX224E", "mx224e"}, + {"ATmXT112SL", "mxt112sl"}, + {"ATmXT224", "mxt224"}, + {"ATmXT224E", "mxt224e"}, + {"ATmXT336S", "mxt336s"}, + {"ATmXT540S", "mxt540s"}, + {"ATmXT540S_RevA", "mxt540s_reva"}, + {"ATmXTS200", "mxts200"}, + {"ATmXTS220", "mxts220"}, + {"ATmXTS220E", "mxts220e"}, + {"ATmega007", "m007"}, + {"ATmega103", "m103"}, + {"ATmega128", "m128"}, + {"ATmega1280", "m1280"}, + {"ATmega1281", "m1281"}, + {"ATmega1284", "m1284"}, + {"ATmega1284P", "m1284p"}, + {"ATmega1284RFR2", "m1284rfr2"}, + {"ATmega128A", "m128a"}, + {"ATmega128RFA1", "m128rfa1"}, + {"ATmega128RFA2", "m128rfa2"}, + {"ATmega128RFR2", "m128rfr2"}, + {"ATmega16", "m16"}, + {"ATmega1608", "m1608"}, + {"ATmega1609", "m1609"}, + {"ATmega161", "m161"}, + {"ATmega162", "m162"}, + {"ATmega163", "m163"}, + {"ATmega164", "m164"}, + {"ATmega164A", "m164a"}, + {"ATmega164P", "m164p"}, + {"ATmega164PA", "m164pa"}, + {"ATmega165", "m165"}, + {"ATmega165A", "m165a"}, + {"ATmega165P", "m165p"}, + {"ATmega165PA", "m165pa"}, + {"ATmega168", "m168"}, + {"ATmega168A", "m168a"}, + {"ATmega168P", "m168p"}, + {"ATmega168PA", "m168pa"}, + {"ATmega168PB", "m168pb"}, + {"ATmega169", "m169"}, + {"ATmega169A", "m169a"}, + {"ATmega169P", "m169p"}, + {"ATmega169PA", "m169pa"}, + {"ATmega16A", "m16a"}, + {"ATmega16HVA", "m16hva"}, + {"ATmega16HVA2", "m16hva2"}, + {"ATmega16HVB", "m16hvb"}, + {"ATmega16M1", "m16m1"}, + {"ATmega16U2", "m16u2"}, + {"ATmega16U4", "m16u4"}, + {"ATmega2560", "m2560"}, + {"ATmega2561", "m2561"}, + {"ATmega2564RFR2", "m2564rfr2"}, + {"ATmega256RFA2", "m256rfa2"}, + {"ATmega256RFR2", "m256rfr2"}, + {"ATmega26HVG", "m26hvg"}, + {"ATmega32", "m32"}, + {"ATmega3208", "m3208"}, + {"ATmega3209", "m3209"}, + {"ATmega323", "m323"}, + {"ATmega324", "m324"}, + {"ATmega324A", "m324a"}, + {"ATmega324P", "m324p"}, + {"ATmega324PA", "m324pa"}, + {"ATmega324PB", "m324pb"}, + {"ATmega325", "m325"}, + {"ATmega3250", "m3250"}, + {"ATmega3250A", "m3250a"}, + {"ATmega3250P", "m3250p"}, + {"ATmega3250PA", "m3250pa"}, + {"ATmega325A", "m325a"}, + {"ATmega325P", "m325p"}, + {"ATmega325PA", "m325pa"}, + {"ATmega328", "m328"}, + {"ATmega328P", "m328p"}, + {"ATmega328PB", "m328pb"}, + {"ATmega329", "m329"}, + {"ATmega3290", "m3290"}, + {"ATmega3290A", "m3290a"}, + {"ATmega3290P", "m3290p"}, + {"ATmega3290PA", "m3290pa"}, + {"ATmega329A", "m329a"}, + {"ATmega329P", "m329p"}, + {"ATmega329PA", "m329pa"}, + {"ATmega32A", "m32a"}, + {"ATmega32C1", "m32c1"}, + {"ATmega32HVB", "m32hvb"}, + {"ATmega32M1", "m32m1"}, + {"ATmega32U2", "m32u2"}, + {"ATmega32U4", "m32u4"}, + {"ATmega32U6", "m32u6"}, + {"ATmega406", "m406"}, + {"ATmega48", "m48"}, + {"ATmega4808", "m4808"}, + {"ATmega4809", "m4809"}, + {"ATmega48A", "m48a"}, + {"ATmega48HVF", "m48hvf"}, + {"ATmega48P", "m48p"}, + {"ATmega48PA", "m48pa"}, + {"ATmega48PB", "m48pb"}, + {"ATmega4HVD", "m4hvd"}, + {"ATmega603", "m603"}, + {"ATmega64", "m64"}, + {"ATmega640", "m640"}, + {"ATmega644", "m644"}, + {"ATmega644A", "m644a"}, + {"ATmega644P", "m644p"}, + {"ATmega644PA", "m644pa"}, + {"ATmega644RFR2", "m644rfr2"}, + {"ATmega645", "m645"}, + {"ATmega6450", "m6450"}, + {"ATmega6450A", "m6450a"}, + {"ATmega6450P", "m6450p"}, + {"ATmega645A", "m645a"}, + {"ATmega645P", "m645p"}, + {"ATmega649", "m649"}, + {"ATmega6490", "m6490"}, + {"ATmega6490A", "m6490a"}, + {"ATmega6490P", "m6490p"}, + {"ATmega649A", "m649a"}, + {"ATmega649P", "m649p"}, + {"ATmega64A", "m64a"}, + {"ATmega64C1", "m64c1"}, + {"ATmega64HVE", "m256rfa2"}, + {"ATmega64HVE", "m64hve"}, + {"ATmega64HVE2", "m64hve2"}, + {"ATmega64M1", "m64m1"}, + {"ATmega64RFA2", "m64rfa2"}, + {"ATmega64RFR2", "m64rfr2"}, + {"ATmega8", "m8"}, + {"ATmega808", "m808"}, + {"ATmega809", "m809"}, + {"ATmega83", "m83"}, + {"ATmega8515", "m8515"}, + {"ATmega8535", "m8535"}, + {"ATmega88", "m88"}, + {"ATmega88A", "m88a"}, + {"ATmega88P", "m88p"}, + {"ATmega88PA", "m88pa"}, + {"ATmega88PB", "m88pb"}, + {"ATmega8A", "m8a"}, + {"ATmega8HVA", "m8hva"}, + {"ATmega8HVD", "m8hvd"}, + {"ATmega8U2", "m8u2"}, + {"ATtiny10", "tiny10"}, + {"ATtiny102", "tiny102"}, + {"ATtiny104", "tiny104"}, + {"ATtiny11", "tiny11"}, + {"ATtiny12", "tiny12"}, + {"ATtiny13", "tiny13"}, + {"ATtiny13A", "tiny13a"}, + {"ATtiny15", "tiny15"}, + {"ATtiny1604", "tiny1604"}, + {"ATtiny1606", "tiny1606"}, + {"ATtiny1607", "tiny1607"}, + {"ATtiny1614", "tiny1614"}, + {"ATtiny1616", "tiny1616"}, + {"ATtiny1617", "tiny1617"}, + {"ATtiny1634", "tiny1634"}, + {"ATtiny167", "tiny167"}, + {"ATtiny20", "tiny20"}, + {"ATtiny202", "tiny202"}, + {"ATtiny204", "tiny204"}, + {"ATtiny212", "tiny212"}, + {"ATtiny214", "tiny214"}, + {"ATtiny22", "tiny22"}, + {"ATtiny2313", "tiny2313"}, + {"ATtiny2313A", "tiny2313a"}, + {"ATtiny23U", "tiny23u"}, + {"ATtiny24", "tiny24"}, + {"ATtiny24A", "tiny24a"}, + {"ATtiny25", "tiny25"}, + {"ATtiny26", "tiny26"}, + {"ATtiny261", "tiny261"}, + {"ATtiny261A", "tiny261a"}, + {"ATtiny28", "tiny28"}, + {"ATtiny3214", "tiny3214"}, + {"ATtiny3216", "tiny3216"}, + {"ATtiny3217", "tiny3217"}, + {"ATtiny4", "tiny4"}, + {"ATtiny40", "tiny40"}, + {"ATtiny402", "tiny402"}, + {"ATtiny404", "tiny404"}, + {"ATtiny406", "tiny406"}, + {"ATtiny412", "tiny412"}, + {"ATtiny414", "tiny414"}, + {"ATtiny416", "tiny416"}, + {"ATtiny417", "tiny417"}, + {"ATtiny4313", "tiny4313"}, + {"ATtiny43U", "tiny43u"}, + {"ATtiny44", "tiny44"}, + {"ATtiny441", "tiny441"}, + {"ATtiny44A", "tiny44a"}, + {"ATtiny45", "tiny45"}, + {"ATtiny461", "tiny461"}, + {"ATtiny461A", "tiny461a"}, + {"ATtiny474", "tiny474"}, + {"ATtiny48", "tiny48"}, + {"ATtiny5", "tiny5"}, + {"ATtiny80", "tiny80"}, + {"ATtiny804", "tiny804"}, + {"ATtiny806", "tiny806"}, + {"ATtiny807", "tiny807"}, + {"ATtiny80_pre_2015", "tiny80_pre_2015"}, + {"ATtiny814", "tiny814"}, + {"ATtiny816", "tiny816"}, + {"ATtiny817", "tiny817"}, + {"ATtiny828", "tiny828"}, + {"ATtiny84", "tiny84"}, + {"ATtiny840", "tiny840"}, + {"ATtiny841", "tiny841"}, + {"ATtiny84A", "tiny84a"}, + {"ATtiny85", "tiny85"}, + {"ATtiny861", "tiny861"}, + {"ATtiny861A", "tiny861a"}, + {"ATtiny87", "tiny87"}, + {"ATtiny88", "tiny88"}, + {"ATtiny9", "tiny9"}, + {"ATxmega128A1", "xm128a1"}, + {"ATxmega128A1U", "xm128a1u"}, + {"ATxmega128A3", "xm128a3"}, + {"ATxmega128A3U", "xm128a3u"}, + {"ATxmega128A4", "xm128a4"}, + {"ATxmega128A4U", "xm128a4u"}, + {"ATxmega128B1", "xm128b1"}, + {"ATxmega128B3", "xm128b3"}, + {"ATxmega128C3", "xm128c3"}, + {"ATxmega128D3", "xm128d3"}, + {"ATxmega128D4", "xm128d4"}, + {"ATxmega16A4", "xm16a4"}, + {"ATxmega16A4U", "xm16a4u"}, + {"ATxmega16C4", "xm16c4"}, + {"ATxmega16D4", "xm16d4"}, + {"ATxmega16E5", "xm16e5"}, + {"ATxmega192A1", "xm192a1"}, + {"ATxmega192A3", "xm192a3"}, + {"ATxmega192A3U", "xm192a3u"}, + {"ATxmega192C3", "xm192c3"}, + {"ATxmega192D3", "xm192d3"}, + {"ATxmega256A1", "xm256a1"}, + {"ATxmega256A3", "xm256a3"}, + {"ATxmega256A3B", "xm256a3b"}, + {"ATxmega256A3BU", "xm256a3bu"}, + {"ATxmega256A3U", "xm256a3u"}, + {"ATxmega256B1", "xm256b1"}, + {"ATxmega256C3", "xm256c3"}, + {"ATxmega256D3", "xm256d3"}, + {"ATxmega32A4", "xm32a4"}, + {"ATxmega32A4U", "xm32a4u"}, + {"ATxmega32C3", "xm32c3"}, + {"ATxmega32C4", "xm32c4"}, + {"ATxmega32D3", "xm32d3"}, + {"ATxmega32D4", "xm32d4"}, + {"ATxmega32D4P", "xm32d4p"}, + {"ATxmega32E5", "xm32e5"}, + {"ATxmega32X1", "xm32x1"}, + {"ATxmega384A1", "xm384a1"}, + {"ATxmega384C3", "xm384c3"}, + {"ATxmega384D3", "xm384d3"}, + {"ATxmega64A1", "xm64a1"}, + {"ATxmega64A1U", "xm64a1u"}, + {"ATxmega64A3", "xm64a3"}, + {"ATxmega64A3U", "xm64a3u"}, + {"ATxmega64A4", "xm64a4"}, + {"ATxmega64A4U", "xm64a4u"}, + {"ATxmega64B1", "xm64b1"}, + {"ATxmega64B3", "xm64b3"}, + {"ATxmega64C3", "xm64c3"}, + {"ATxmega64D3", "xm64d3"}, + {"ATxmega64D4", "xm64d4"}, + {"ATxmega8E5", "xm8e5"}, + {"M3000", "m3000"}, + {"MaxBSE", "maxbse"}, +}; + +// Target page options. + +struct TargetPageOptions final +{ + enum MemoryModel { + TinyModel, + SmallModel, + LargeModel, + HugeModel + }; + + explicit TargetPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("driverFlags")}); + // Detect target MCU record. + const QString mcuValue = IarewUtils::flagValue( + flags, QStringLiteral("--cpu")).toLower(); + targetMcu = mcuStringFromFlagValue(mcuValue); + // Detect target memory model. + const QString modelValue = IarewUtils::flagValue( + flags, QStringLiteral("-m")); + if (modelValue == QLatin1Char('t')) + memoryModel = TargetPageOptions::TinyModel; + else if (modelValue == QLatin1Char('s')) + memoryModel = TargetPageOptions::SmallModel; + else if (modelValue == QLatin1Char('l')) + memoryModel = TargetPageOptions::LargeModel; + else if (modelValue == QLatin1Char('h')) + memoryModel = TargetPageOptions::HugeModel; + // Detect target EEPROM util size. + eepromUtilSize = IarewUtils::flagValue( + flags, QStringLiteral("--eeprom_size")).toInt(); + } + + static QString mcuStringFromFlagValue(const QString &mcuValue) + { + const auto targetBegin = std::cbegin(mcusDict); + const auto targetEnd = std::cend(mcusDict); + const auto targetIt = std::find_if(targetBegin, targetEnd, + [mcuValue]( + const TargetMcuEntry &entry) { + return entry.targetFlag == mcuValue.toLatin1(); + }); + if (targetIt != targetEnd) { + return QStringLiteral("%1\t%2") + .arg(QString::fromLatin1(targetIt->targetFlag), + QString::fromLatin1(targetIt->targetName)); + } + return {}; + } + + QString targetMcu; + MemoryModel memoryModel = TinyModel; + int eepromUtilSize = 0; +}; + +// System page options. + +struct SystemPageOptions final +{ + explicit SystemPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("driverLinkerFlags"), + QStringLiteral("defines")}); + cstackSize = IarewUtils::flagValue( + flags, QStringLiteral("_..X_CSTACK_SIZE")).toInt(); + rstackSize = IarewUtils::flagValue( + flags, QStringLiteral("_..X_RSTACK_SIZE")).toInt(); + } + + int cstackSize = 0; + int rstackSize = 0; +}; + +// Library options page options. + +struct LibraryOptionsPageOptions final +{ + enum PrintfFormatter { + PrintfAutoFormatter = 0, + PrintfFullFormatter = 1, + PrintfFullNoMultibytesFormatter = 2, + PrintfLargeFormatter = 3, + PrintfLargeNoMultibytesFormatter = 4, + PrintfSmallFormatter = 6, + PrintfSmallNoMultibytesFormatter = 7, + PrintfTinyFormatter = 8 + }; + + enum ScanfFormatter { + ScanfAutoFormatter = 0, + ScanfFullFormatter = 1, + ScanfFullNoMultibytesFormatter = 2, + ScanfLargeFormatter = 3, + ScanfLargeNoMultibytesFormatter = 4, + ScanfSmallFormatter = 6, + ScanfSmallNoMultibytesFormatter = 7 + }; + + explicit LibraryOptionsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + for (const QString &flag : flags) { + if (flag.endsWith(QLatin1String("_printf"), Qt::CaseInsensitive)) { + const QString prop = flag.split(QLatin1Char('=')).at(0).toLower(); + if (prop == QLatin1String("-e_printffull")) + printfFormatter = LibraryOptionsPageOptions::PrintfFullFormatter; + else if (prop == QLatin1String("-e_printffullnomb")) + printfFormatter = LibraryOptionsPageOptions::PrintfFullNoMultibytesFormatter; + else if (prop == QLatin1String("-e_printflarge")) + printfFormatter = LibraryOptionsPageOptions::PrintfLargeFormatter; + else if (prop == QLatin1String("-e_printflargenomb")) + printfFormatter = LibraryOptionsPageOptions::PrintfLargeNoMultibytesFormatter; + else if (prop == QLatin1String("-e_printfsmall")) + printfFormatter = LibraryOptionsPageOptions::PrintfSmallFormatter; + else if (prop == QLatin1String("-e_printfsmallnomb")) + printfFormatter = LibraryOptionsPageOptions::PrintfSmallNoMultibytesFormatter; + else if (prop == QLatin1String("-printftiny")) + printfFormatter = LibraryOptionsPageOptions::PrintfTinyFormatter; + } else if (flag.endsWith(QLatin1String("_scanf"), Qt::CaseInsensitive)) { + const QString prop = flag.split(QLatin1Char('=')).at(0).toLower(); + if (prop == QLatin1String("-e_scanffull")) + scanfFormatter = LibraryOptionsPageOptions::ScanfFullFormatter; + else if (prop == QLatin1String("-e_scanffullnomb")) + scanfFormatter = LibraryOptionsPageOptions::ScanfFullNoMultibytesFormatter; + else if (prop == QLatin1String("-e_scanflarge")) + scanfFormatter = LibraryOptionsPageOptions::ScanfLargeFormatter; + else if (prop == QLatin1String("-e_scanflargenomb")) + scanfFormatter = LibraryOptionsPageOptions::ScanfLargeNoMultibytesFormatter; + else if (prop == QLatin1String("-e_scanfsmall")) + scanfFormatter = LibraryOptionsPageOptions::ScanfSmallFormatter; + else if (prop == QLatin1String("-e_scanfsmallnomb")) + scanfFormatter = LibraryOptionsPageOptions::ScanfSmallNoMultibytesFormatter; + } + } + } + + PrintfFormatter printfFormatter = PrintfAutoFormatter; + ScanfFormatter scanfFormatter = ScanfAutoFormatter; +}; + +// Library configuration page options. + +struct LibraryConfigPageOptions final +{ + enum RuntimeLibrary { + NoLibrary, + NormalDlibLibrary, + FullDlibLibrary, + CustomDlibLibrary, + ClibLibrary, + CustomClibLibrary, + ThirdPartyLibrary + }; + + explicit LibraryConfigPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + + const QStringList libraryPaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("staticLibraries")}); + const auto libraryBegin = libraryPaths.cbegin(); + const auto libraryEnd = libraryPaths.cend(); + + if (flags.contains(QLatin1String("--dlib"))) { + const QString dlibToolkitPath = + IarewUtils::dlibToolkitRootPath(qbsProduct); + const QFileInfo configInfo(IarewUtils::flagValue( + flags, + QStringLiteral("--dlib_config"))); + const QString configFilePath = configInfo.absoluteFilePath(); + if (configFilePath.startsWith(dlibToolkitPath, + Qt::CaseInsensitive)) { + if (configFilePath.endsWith(QLatin1String("-n.h"), + Qt::CaseInsensitive)) { + libraryType = LibraryConfigPageOptions::NormalDlibLibrary; + } else if (configFilePath.endsWith(QLatin1String("-f.h"), + Qt::CaseInsensitive)) { + libraryType = LibraryConfigPageOptions::FullDlibLibrary; + } else { + libraryType = LibraryConfigPageOptions::CustomDlibLibrary; + } + + configPath = IarewUtils::toolkitRelativeFilePath( + baseDirectory, configFilePath); + + // Find dlib library inside of IAR toolkit directory. + const auto libraryIt = std::find_if(libraryBegin, libraryEnd, + [dlibToolkitPath]( + const QString &libraryPath) { + return libraryPath.startsWith(dlibToolkitPath); + }); + if (libraryIt != libraryEnd) { + // This means that dlib library is 'standard' (placed inside + // of IAR toolkit directory). + libraryPath = IarewUtils::toolkitRelativeFilePath( + baseDirectory, *libraryIt); + } + } else { + // This means that dlib library is 'custom' + // (but we don't know its path). + libraryType = LibraryConfigPageOptions::CustomDlibLibrary; + configPath = IarewUtils::projectRelativeFilePath( + baseDirectory, configFilePath); + } + } else if (flags.contains(QLatin1String("--clib"))) { + const QString clibToolkitPath = + IarewUtils::clibToolkitRootPath(qbsProduct); + // Find clib library inside of IAR toolkit directory. + const auto libraryIt = std::find_if(libraryBegin, libraryEnd, + [clibToolkitPath]( + const QString &libraryPath) { + return libraryPath.startsWith(clibToolkitPath); + }); + if (libraryIt != libraryEnd) { + // This means that clib library is 'standard' (placed inside + // of IAR toolkit directory). + libraryType = LibraryConfigPageOptions::ClibLibrary; + libraryPath = IarewUtils::toolkitRelativeFilePath( + baseDirectory, *libraryIt); + } else { + // This means that clib library is 'custom' + // (but we don't know its path). + libraryType = LibraryConfigPageOptions::CustomClibLibrary; + } + } else { + libraryType = LibraryConfigPageOptions::NoLibrary; + } + } + + RuntimeLibrary libraryType = NoLibrary; + QString configPath; + QString libraryPath; +}; + +// 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; +}; + +} // namespace + +// AvrGeneralSettingsGroup + +AvrGeneralSettingsGroup::AvrGeneralSettingsGroup( + 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); + buildSystemPage(qbsProduct); + buildLibraryOptionsPage(qbsProduct); + buildLibraryConfigPage(buildRootDirectory, qbsProduct); + buildOutputPage(buildRootDirectory, qbsProduct); +} + +void AvrGeneralSettingsGroup::buildTargetPage( + const ProductData &qbsProduct) +{ + const TargetPageOptions opts(qbsProduct); + // Add 'GenDeviceSelectMenu' item + // (Processor configuration chooser). + addOptionsGroup(QByteArrayLiteral("GenDeviceSelectMenu"), + {opts.targetMcu}); + // Add 'Variant Memory' item + // (Memory model: tiny/small/large/huge). + addOptionsGroup(QByteArrayLiteral("Variant Memory"), + {opts.memoryModel}); + // Add 'GGEepromUtilSize' item + // (Utilize inbuilt EEPROM size, in bytes). + addOptionsGroup(QByteArrayLiteral("GGEepromUtilSize"), + {opts.eepromUtilSize}); +} + +void AvrGeneralSettingsGroup::buildSystemPage( + const ProductData &qbsProduct) +{ + const SystemPageOptions opts (qbsProduct); + // Add 'SCCStackSize' item (Data stack + // - CSTACK size in bytes). + addOptionsGroup(QByteArrayLiteral("SCCStackSize"), + {opts.cstackSize}); + // Add 'SCRStackSize' item (Return address stack + // - RSTACK depth in bytes). + addOptionsGroup(QByteArrayLiteral("SCRStackSize"), + {opts.rstackSize}); +} + +void AvrGeneralSettingsGroup::buildLibraryOptionsPage( + const ProductData &qbsProduct) +{ + const LibraryOptionsPageOptions opts(qbsProduct); + // Add 'Output variant' item (Printf formatter). + addOptionsGroup(QByteArrayLiteral("Output variant"), + {opts.printfFormatter}); + // Add 'Input variant' item (Printf formatter). + addOptionsGroup(QByteArrayLiteral("Input variant"), + {opts.scanfFormatter}); +} + +void AvrGeneralSettingsGroup::buildLibraryConfigPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const LibraryConfigPageOptions opts(baseDirectory, qbsProduct); + // Add 'GRuntimeLibSelect' and 'GRuntimeLibSelectSlave' items + // (Link with runtime: none/dlib/clib/etc). + 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 AvrGeneralSettingsGroup::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}); +} + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/avr/avrgeneralsettingsgroup_v7.h b/src/plugins/generator/iarew/archs/avr/avrgeneralsettingsgroup_v7.h new file mode 100644 index 000000000..5411eeae8 --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrgeneralsettingsgroup_v7.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWAVRGENERALSETTINGSGROUP_V7_H +#define QBS_IAREWAVRGENERALSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +class AvrGeneralSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit AvrGeneralSettingsGroup(const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildTargetPage(const ProductData &qbsProduct); + void buildSystemPage(const ProductData &qbsProduct); + void buildLibraryOptionsPage(const ProductData &qbsProduct); + void buildLibraryConfigPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct); +}; + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWAVRGENERALSETTINGSGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/avr/avrlinkersettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/avr/avrlinkersettingsgroup_v7.cpp new file mode 100644 index 000000000..59ba515d9 --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrlinkersettingsgroup_v7.cpp @@ -0,0 +1,388 @@ +/**************************************************************************** +** +** 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 "avrlinkersettingsgroup_v7.h" + +#include "../../iarewutils.h" + +#include <QtCore/qdir.h> + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +constexpr int kLinkerArchiveVersion = 3; +constexpr int kLinkerDataVersion = 16; + +namespace { + +// Config page options. + +struct ConfigPageOptions final +{ + explicit ConfigPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + + entryPoint = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("entryPoint")); + + // 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)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + configFilePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + configFilePaths.push_back(path); + } + } + } + + // Enumerate all product linker config files + // (which are set trough '-f' option). + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + const QVariantList configPathValues = IarewUtils::flagValues( + flags, QStringLiteral("-f")); + for (const QVariant &configPathValue : configPathValues) { + const QString fullConfigPath = configPathValue.toString(); + if (fullConfigPath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } + } + + // Add libraries search paths. + const QStringList libraryPaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("libraryPaths")}); + for (const QString &libraryPath : libraryPaths) { + const QFileInfo libraryPathInfo(libraryPath); + const QString fullLibrarySearchPath = + libraryPathInfo.absoluteFilePath(); + if (fullLibrarySearchPath.startsWith(toolkitPath, + Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullLibrarySearchPath); + librarySearchPaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullLibrarySearchPath); + librarySearchPaths.push_back(path); + } + } + + // Add static libraries paths. + const QStringList staticLibrariesProps = + gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("staticLibraries")}); + for (const QString &staticLibrary : staticLibrariesProps) { + const QFileInfo staticLibraryInfo(staticLibrary); + if (staticLibraryInfo.isAbsolute()) { + const QString fullStaticLibraryPath = + staticLibraryInfo.absoluteFilePath(); + if (fullStaticLibraryPath.startsWith(toolkitPath, + Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullStaticLibraryPath); + staticLibraries.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullStaticLibraryPath); + staticLibraries.push_back(path); + } + } else { + staticLibraries.push_back(staticLibrary); + } + } + + // Add static libraries from product dependencies. + for (const ProductData &qbsProductDep : qbsProductDeps) { + const QString depBinaryPath = QLatin1String("$PROJ_DIR$/") + + gen::utils::targetBinaryPath(baseDirectory, + qbsProductDep); + staticLibraries.push_back(depBinaryPath); + } + } + + QVariantList configFilePaths; + QVariantList librarySearchPaths; + QVariantList staticLibraries; + QString entryPoint; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + outputFile = gen::utils::targetBinary(qbsProduct); + } + + QString outputFile; +}; + +// List page options. + +struct ListPageOptions final +{ + enum ListingAction { + NoListing, + GenerateListing + }; + + explicit ListPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + generateMap = gen::utils::cppBooleanModuleProperty( + qbsProps, QStringLiteral("generateLinkerMapFile")) + ? ListPageOptions::GenerateListing + : ListPageOptions::NoListing; + } + + ListingAction generateMap = NoListing; +}; + +// Define page options. + +struct DefinePageOptions final +{ + explicit DefinePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + // Enumerate all linker defines. + for (const QString &flag : flags) { + if (!flag.startsWith(QLatin1String("-D"))) + continue; + const auto symbol = flag.mid(2); + // Ignore system-defined macroses. + if (symbol.startsWith(QLatin1String("_..X_HEAP_SIZE")) + || symbol.startsWith(QLatin1String("_..X_TINY_HEAP_SIZE")) + || symbol.startsWith(QLatin1String("_..X_NEAR_HEAP_SIZE")) + || symbol.startsWith(QLatin1String("_..X_FAR_HEAP_SIZE")) + || symbol.startsWith(QLatin1String("_..X_HUGE_HEAP_SIZE")) + || symbol.startsWith(QLatin1String("_..X_CSTACK_SIZE")) + || symbol.startsWith(QLatin1String("_..X_RSTACK_SIZE")) + || symbol.startsWith(QLatin1String("_..X_FLASH_CODE_END")) + || symbol.startsWith(QLatin1String("_..X_FLASH_BASE")) + || symbol.startsWith(QLatin1String("_..X_CSTACK_BASE")) + || symbol.startsWith(QLatin1String("_..X_CSTACK_END")) + || symbol.startsWith(QLatin1String("_..X_RSTACK_BASE")) + || symbol.startsWith(QLatin1String("_..X_RSTACK_END")) + || symbol.startsWith(QLatin1String("_..X_EXT_SRAM_BASE")) + || symbol.startsWith(QLatin1String("_..X_EXT_SRAM_SIZE")) + || symbol.startsWith(QLatin1String("_..X_EXT_ROM_BASE")) + || symbol.startsWith(QLatin1String("_..X_EXT_ROM_SIZE")) + || symbol.startsWith(QLatin1String("_..X_EXT_NV_BASE")) + || symbol.startsWith(QLatin1String("_..X_EXT_NV_SIZE")) + || symbol.startsWith(QLatin1String("_..X_SRAM_BASE")) + || symbol.startsWith(QLatin1String("_..X_SRAM_SIZE")) + || symbol.startsWith(QLatin1String("_..X_RSTACK_BASE")) + || symbol.startsWith(QLatin1String("_..X_RSTACK_SIZE")) + ) { + continue; + } + defineSymbols.push_back(symbol); + } + } + + QVariantList defineSymbols; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString warningLevel = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("warningLevel")); + suppressAllWarnings = (warningLevel == QLatin1String("none")); + } + + int suppressAllWarnings = 0; +}; + +} // namespace + +// AvrLinkerSettingsGroup + +AvrLinkerSettingsGroup::AvrLinkerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + setName(QByteArrayLiteral("XLINK")); + setArchiveVersion(kLinkerArchiveVersion); + setDataVersion(kLinkerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildConfigPage(buildRootDirectory, qbsProduct, qbsProductDeps); + buildOutputPage(qbsProduct); + buildListPage(qbsProduct); + buildDefinePage(qbsProduct); + buildDiagnosticsPage(qbsProduct); + + // Should be called as latest stage! + buildExtraOptionsPage(qbsProduct); +} + +void AvrLinkerSettingsGroup::buildConfigPage( + const QString &baseDirectory, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + ConfigPageOptions opts(baseDirectory, qbsProduct, qbsProductDeps); + + if (opts.configFilePaths.count() > 0) { + // Note: IAR IDE does not allow to specify a multiple config files, + // although the IAR linker support it. So, we use followig 'trick': + // we take a first config file and to add it as usual to required items; + // and then an other remainders we forward to the "Extra options page". + const QVariant configPath = opts.configFilePaths.takeFirst(); + // Add 'XclOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("XclOverride"), + {1}); + // Add 'XclFile' item (Linke configuration file). + addOptionsGroup(QByteArrayLiteral("XclFile"), + {configPath}); + + // Add remainder configuration files to the "Extra options page". + if (!opts.configFilePaths.isEmpty()) { + for (QVariant &configPath : opts.configFilePaths) + configPath = QLatin1String("-f ") + configPath.toString(); + + m_extraOptions << opts.configFilePaths; + } + } + + if (opts.staticLibraries.count() > 0) + m_extraOptions << opts.staticLibraries; + + if (!opts.entryPoint.isEmpty()) { + // Add 'xcProgramEntryLabel' item (Entry symbol). + addOptionsGroup(QByteArrayLiteral("xcProgramEntryLabel"), + {opts.entryPoint}); + // Add 'xcOverrideProgramEntryLabel' item + // (Override default program entry). + addOptionsGroup(QByteArrayLiteral("xcOverrideProgramEntryLabel"), + {1}); + // Add 'xcProgramEntryLabelSelect' item. + addOptionsGroup(QByteArrayLiteral("xcProgramEntryLabelSelect"), + {0}); + } + + // Add 'XIncludes' item (Libraries search paths). + addOptionsGroup(QByteArrayLiteral("XIncludes"), + opts.librarySearchPaths); +} + +void AvrLinkerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'XOutOverride' item (Override default output file). + addOptionsGroup(QByteArrayLiteral("XOutOverride"), + {1}); + // Add 'OutputFile' item (Output file name). + addOptionsGroup(QByteArrayLiteral("OutputFile"), + {opts.outputFile}); +} + +void AvrLinkerSettingsGroup::buildListPage( + const ProductData &qbsProduct) +{ + const ListPageOptions opts(qbsProduct); + // Add 'XList' item (Generate linker listing). + addOptionsGroup(QByteArrayLiteral("XList"), + {opts.generateMap}); +} + +void AvrLinkerSettingsGroup::buildDefinePage( + const ProductData &qbsProduct) +{ + const DefinePageOptions opts(qbsProduct); + // Add 'XDefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("XDefines"), + opts.defineSymbols); +} + +void AvrLinkerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'SuppressAllWarn' item (Suppress all warnings). + addOptionsGroup(QByteArrayLiteral("SuppressAllWarn"), + {opts.suppressAllWarnings}); +} + +void AvrLinkerSettingsGroup::buildExtraOptionsPage(const ProductData &qbsProduct) +{ + Q_UNUSED(qbsProduct) + + if (!m_extraOptions.isEmpty()) { + // Add 'XExtraOptionsCheck' (Use command line options). + addOptionsGroup(QByteArrayLiteral("XExtraOptionsCheck"), + {1}); + // Add 'XExtraOptions' item (Command line options). + addOptionsGroup(QByteArrayLiteral("XExtraOptions"), + m_extraOptions); + } +} + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/avr/avrlinkersettingsgroup_v7.h b/src/plugins/generator/iarew/archs/avr/avrlinkersettingsgroup_v7.h new file mode 100644 index 000000000..5427937b7 --- /dev/null +++ b/src/plugins/generator/iarew/archs/avr/avrlinkersettingsgroup_v7.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWAVRLINKERSETTINGSGROUP_V7_H +#define QBS_IAREWAVRLINKERSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace avr { +namespace v7 { + +class AvrLinkerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit AvrLinkerSettingsGroup(const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildConfigPage(const QString &baseDirectory, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + void buildOutputPage(const ProductData &qbsProduct); + void buildListPage(const ProductData &qbsProduct); + void buildDefinePage(const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); + void buildExtraOptionsPage(const ProductData &qbsProduct); + + QVariantList m_extraOptions; +}; + +} // namespace v7 +} // namespace avr +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWAVRLINKERSETTINGSGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51archiversettingsgroup_v10.cpp b/src/plugins/generator/iarew/archs/mcs51/mcs51archiversettingsgroup_v10.cpp new file mode 100644 index 000000000..38264c653 --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51archiversettingsgroup_v10.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** 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 "mcs51archiversettingsgroup_v10.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +constexpr int kArchiverArchiveVersion = 2; +constexpr int kArchiverDataVersion = 1; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + outputFile = QLatin1String("$PROJ_DIR$/") + + gen::utils::targetBinaryPath(baseDirectory, qbsProduct); + } + + QString outputFile; +}; + +} // namespace + +// Mcs51ArchiverSettingsGroup + +Mcs51ArchiverSettingsGroup::Mcs51ArchiverSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("XAR")); + setArchiveVersion(kArchiverArchiveVersion); + setDataVersion(kArchiverDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + buildOutputPage(buildRootDirectory, qbsProduct); +} + +void Mcs51ArchiverSettingsGroup::buildOutputPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(baseDirectory, qbsProduct); + // Add 'XAROverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("XAROverride"), + {1}); + // Add 'XAROutput2' item (Output filename). + addOptionsGroup(QByteArrayLiteral("XAROutput2"), + {opts.outputFile}); +} + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51archiversettingsgroup_v10.h b/src/plugins/generator/iarew/archs/mcs51/mcs51archiversettingsgroup_v10.h new file mode 100644 index 000000000..21c66433d --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51archiversettingsgroup_v10.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMCS51ARCHIVERSETTINGSGROUP_V10_H +#define QBS_IAREWMCS51ARCHIVERSETTINGSGROUP_V10_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +class Mcs51ArchiverSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Mcs51ArchiverSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct); +}; + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMCS51ARCHIVERSETTINGSGROUP_V10_H diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51assemblersettingsgroup_v10.cpp b/src/plugins/generator/iarew/archs/mcs51/mcs51assemblersettingsgroup_v10.cpp new file mode 100644 index 000000000..a840b29c6 --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51assemblersettingsgroup_v10.cpp @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** 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 "mcs51assemblersettingsgroup_v10.h" + +//#include "../../iarewproperty.h" +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +constexpr int kAssemblerArchiveVersion = 2; +constexpr int kAssemblerDataVersion = 6; + +namespace { + +// Language page options. + +struct LanguagePageOptions final +{ + enum MacroQuoteCharacter { + AngleBracketsQuote, + RoundBracketsQuote, + SquareBracketsQuote, + FigureBracketsQuote + }; + + explicit LanguagePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("assemblerFlags")}); + enableSymbolsCaseSensitive = flags.contains(QLatin1String("-s+")); + enableMultibyteSupport = flags.contains(QLatin1String("-n")); + + if (flags.contains(QLatin1String("-M<>"))) + macroQuoteCharacter = LanguagePageOptions::AngleBracketsQuote; + else if (flags.contains(QLatin1String("-M()"))) + macroQuoteCharacter = LanguagePageOptions::RoundBracketsQuote; + else if (flags.contains(QLatin1String("-M[]"))) + macroQuoteCharacter = LanguagePageOptions::SquareBracketsQuote; + else if (flags.contains(QLatin1String("-M{}"))) + macroQuoteCharacter = LanguagePageOptions::FigureBracketsQuote; + } + + MacroQuoteCharacter macroQuoteCharacter = AngleBracketsQuote; + int enableSymbolsCaseSensitive = 0; + int enableMultibyteSupport = 0; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + debugInfo = gen::utils::debugInformation(qbsProduct); + } + + int debugInfo = 0; +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + for (const auto &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString warningLevel = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("warningLevel")); + if (warningLevel == QLatin1String("all")) { + enableWarnings = 0; + enableAllWarnings = 0; + } else if (warningLevel == QLatin1String("none")) { + enableWarnings = 1; + enableAllWarnings = 0; + } else { + enableWarnings = 0; + enableAllWarnings = 1; + } + } + + int enableWarnings = 0; + int enableAllWarnings = 0; +}; + +} // namespace + +// Mcs51AssemblerSettingsGroup + +Mcs51AssemblerSettingsGroup::Mcs51AssemblerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProject) + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("A8051")); + setArchiveVersion(kAssemblerArchiveVersion); + setDataVersion(kAssemblerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildLanguagePage(qbsProduct); + buildOutputPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); +} + +void Mcs51AssemblerSettingsGroup::buildLanguagePage( + const ProductData &qbsProduct) +{ + const LanguagePageOptions opts(qbsProduct); + // Add 'ACaseSensitivity' item (User symbols are case sensitive). + addOptionsGroup(QByteArrayLiteral("ACaseSensitivity"), + {opts.enableSymbolsCaseSensitive}); + // Add 'Asm multibyte support' item (Enable multibyte support). + addOptionsGroup(QByteArrayLiteral("Asm multibyte support"), + {opts.enableMultibyteSupport}); + // Add 'MacroChars' item (Macro quote characters: ()/[]/{}/<>). + addOptionsGroup(QByteArrayLiteral("MacroChars"), + {!opts.macroQuoteCharacter}, 0); +} + +void Mcs51AssemblerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'Debug' item (Generate debug information). + addOptionsGroup(QByteArrayLiteral("Debug"), + {opts.debugInfo}); +} + +void Mcs51AssemblerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'ADefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("ADefines"), + opts.defineSymbols); + // Add 'Include directories' item (Additional include directories). + addOptionsGroup(QByteArrayLiteral("Include directories"), + opts.includePaths); +} + +void Mcs51AssemblerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'AWarnEnable' item (Enable/disable warnings). + addOptionsGroup(QByteArrayLiteral("AWarnEnable"), + {opts.enableWarnings}); + // Add 'AWarnWhat' item (Enable/disable all warnings). + addOptionsGroup(QByteArrayLiteral("AWarnWhat"), + {opts.enableAllWarnings}); +} + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51assemblersettingsgroup_v10.h b/src/plugins/generator/iarew/archs/mcs51/mcs51assemblersettingsgroup_v10.h new file mode 100644 index 000000000..bb9f4b613 --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51assemblersettingsgroup_v10.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMCS51ASSEMBLERSETTINGSGROUP_V10_H +#define QBS_IAREWMCS51ASSEMBLERSETTINGSGROUP_V10_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +class Mcs51AssemblerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Mcs51AssemblerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildLanguagePage(const ProductData &qbsProduct); + void buildOutputPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); +}; + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMCS51ASSEMBLERSETTINGSGROUP_V10_H diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51buildconfigurationgroup_v10.cpp b/src/plugins/generator/iarew/archs/mcs51/mcs51buildconfigurationgroup_v10.cpp new file mode 100644 index 000000000..ba86bc54d --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51buildconfigurationgroup_v10.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 "mcs51archiversettingsgroup_v10.h" +#include "mcs51assemblersettingsgroup_v10.h" +#include "mcs51buildconfigurationgroup_v10.h" +#include "mcs51compilersettingsgroup_v10.h" +#include "mcs51generalsettingsgroup_v10.h" +#include "mcs51linkersettingsgroup_v10.h" + +#include "../../iarewtoolchainpropertygroup.h" +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +Mcs51BuildConfigurationGroup::Mcs51BuildConfigurationGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) + : gen::xml::PropertyGroup("configuration") +{ + // Append configuration name item. + const QString cfgName = gen::utils::buildConfigurationName(qbsProject); + appendProperty("name", cfgName); + + // Apend toolchain name group item. + appendChild<IarewToolchainPropertyGroup>("8051"); + + // Append debug info item. + const int debugBuild = gen::utils::debugInformation(qbsProduct); + appendProperty("debug", debugBuild); + + // Append settings group items. + appendChild<Mcs51ArchiverSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Mcs51AssemblerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Mcs51CompilerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Mcs51GeneralSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Mcs51LinkerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); +} + +bool Mcs51BuildConfigurationGroupFactory::canCreate( + gen::utils::Architecture arch, + const Version &version) const +{ + return arch == gen::utils::Architecture::Mcs51 + && version.majorVersion() == 10; +} + +std::unique_ptr<gen::xml::PropertyGroup> +Mcs51BuildConfigurationGroupFactory::create( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const +{ + const auto group = new Mcs51BuildConfigurationGroup( + qbsProject, qbsProduct, qbsProductDeps); + return std::unique_ptr<Mcs51BuildConfigurationGroup>(group); +} + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51buildconfigurationgroup_v10.h b/src/plugins/generator/iarew/archs/mcs51/mcs51buildconfigurationgroup_v10.h new file mode 100644 index 000000000..edd16d5d7 --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51buildconfigurationgroup_v10.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMCS51BUILDCONFIGURATIONGROUP_V10_H +#define QBS_IAREWMCS51BUILDCONFIGURATIONGROUP_V10_H + +#include <generators/xmlpropertygroup.h> + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +class Mcs51BuildConfigurationGroup final + : public gen::xml::PropertyGroup +{ +private: + explicit Mcs51BuildConfigurationGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + + friend class Mcs51BuildConfigurationGroupFactory; +}; + +class Mcs51BuildConfigurationGroupFactory final + : public gen::xml::PropertyGroupFactory +{ +public: + bool canCreate(gen::utils::Architecture arch, + const Version &version) const final; + + std::unique_ptr<gen::xml::PropertyGroup> create( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const final; +}; + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMCS51BUILDCONFIGURATIONGROUP_V10_H diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51compilersettingsgroup_v10.cpp b/src/plugins/generator/iarew/archs/mcs51/mcs51compilersettingsgroup_v10.cpp new file mode 100644 index 000000000..649350a98 --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51compilersettingsgroup_v10.cpp @@ -0,0 +1,476 @@ +/**************************************************************************** +** +** 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 "mcs51compilersettingsgroup_v10.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +constexpr int kCompilerArchiveVersion = 7; +constexpr int kCompilerDataVersion = 12; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + enum ModuleType { + ProgramModule, + LibraryModule + }; + + explicit OutputPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + moduleType = flags.contains(QLatin1String("--library_module")) + ? OutputPageOptions::LibraryModule + : OutputPageOptions::ProgramModule; + debugInfo = gen::utils::debugInformation(qbsProduct); + } + + int debugInfo = 0; + ModuleType moduleType = ProgramModule; +}; + +// Language one page options. + +struct LanguageOnePageOptions final +{ + enum LanguageExtension { + CLanguageExtension, + CxxLanguageExtension, + AutoLanguageExtension + }; + + enum CLanguageDialect { + C89LanguageDialect, + C99LanguageDialect + }; + + enum CxxLanguageDialect { + EmbeddedCPlusPlus, + ExtendedEmbeddedCPlusPlus + }; + + enum LanguageConformance { + AllowIarExtension, + RelaxedStandard, + StrictStandard + }; + + explicit LanguageOnePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + // File extension based by default. + languageExtension = LanguageOnePageOptions::AutoLanguageExtension; + // C language dialect. + const QStringList cLanguageVersion = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("cLanguageVersion")}); + cLanguageDialect = cLanguageVersion.contains(QLatin1String("c89")) + ? LanguageOnePageOptions::C89LanguageDialect + : LanguageOnePageOptions::C99LanguageDialect; + // C++ language dialect. + if (flags.contains(QLatin1String("--ec++"))) + cxxLanguageDialect = LanguageOnePageOptions::EmbeddedCPlusPlus; + else if (flags.contains(QLatin1String("--eec++"))) + cxxLanguageDialect = LanguageOnePageOptions::ExtendedEmbeddedCPlusPlus; + // Language conformance. + if (flags.contains(QLatin1String("-e"))) + languageConformance = LanguageOnePageOptions::AllowIarExtension; + else if (flags.contains(QLatin1String("--strict"))) + languageConformance = LanguageOnePageOptions::StrictStandard; + else + languageConformance = LanguageOnePageOptions::RelaxedStandard; + + allowVla = flags.contains(QLatin1String("--vla")); + useCppInlineSemantics = flags.contains( + QLatin1String("--use_c++_inline")); + requirePrototypes = flags.contains( + QLatin1String("--require_prototypes")); + destroyStaticObjects = !flags.contains( + QLatin1String("--no_static_destruction")); + } + + LanguageExtension languageExtension = AutoLanguageExtension; + CLanguageDialect cLanguageDialect = C89LanguageDialect; + CxxLanguageDialect cxxLanguageDialect = EmbeddedCPlusPlus; + LanguageConformance languageConformance = AllowIarExtension; + int allowVla = 0; + int useCppInlineSemantics = 0; + int requirePrototypes = 0; + int destroyStaticObjects = 0; +}; + +// Language two page options. + +struct LanguageTwoPageOptions final +{ + enum PlainCharacter { + SignedCharacter, + UnsignedCharacter + }; + + enum FloatingPointSemantic { + StrictSemantic, + RelaxedSemantic + }; + + explicit LanguageTwoPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + plainCharacter = flags.contains( + QLatin1String("--char_is_signed")) + ? LanguageTwoPageOptions::SignedCharacter + : LanguageTwoPageOptions::UnsignedCharacter; + floatingPointSemantic = flags.contains( + QLatin1String("--relaxed_fp")) + ? LanguageTwoPageOptions::RelaxedSemantic + : LanguageTwoPageOptions::StrictSemantic; + enableMultibyteSupport = flags.contains( + QLatin1String("--enable_multibytes")); + } + + PlainCharacter plainCharacter = SignedCharacter; + FloatingPointSemantic floatingPointSemantic = StrictSemantic; + int enableMultibyteSupport = 0; +}; + +// Optimizations page options. + +struct OptimizationsPageOptions final +{ + // Optimizations level radio-buttons with combo-box + // on "level" widget. + enum Strategy { + StrategyBalanced, + StrategySize, + StrategySpeed + }; + + enum Level { + LevelNone, + LevelLow, + LevelMedium, + LevelHigh + }; + + enum LevelSlave { + LevelSlave0, + LevelSlave1, + LevelSlave2, + LevelSlave3 + }; + + explicit OptimizationsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString optimization = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("optimization")); + if (optimization == QLatin1String("none")) { + optimizationStrategy = OptimizationsPageOptions::StrategyBalanced; + optimizationLevel = OptimizationsPageOptions::LevelNone; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave0; + } else if (optimization == QLatin1String("fast")) { + optimizationStrategy = OptimizationsPageOptions::StrategySpeed; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } else if (optimization == QLatin1String("small")) { + optimizationStrategy = OptimizationsPageOptions::StrategySize; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } + + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + enableCommonSubexpressionElimination = !flags.contains( + QLatin1String("--no_cse")); + enableLoopUnroll = !flags.contains(QLatin1String("--no_unroll")); + enableFunctionInlining = !flags.contains(QLatin1String("--no_inline")); + enableCodeMotion = !flags.contains(QLatin1String("--no_code_motion")); + enableTypeBasedAliasAnalysis = !flags.contains( + QLatin1String("--no_tbaa")); + enableCrossCall = !flags.contains(QLatin1String("--no_cross_call")); + disableRegisterBanks = flags.contains( + QLatin1String("--disable_register_banks")); + + disableSizeConstrains = flags.contains( + QLatin1String("--no_size_constraints")); + } + + Strategy optimizationStrategy = StrategyBalanced; + Level optimizationLevel = LevelNone; + LevelSlave optimizationLevelSlave = LevelSlave0; + // Seven bit-field flags on "enabled transformations" widget. + int enableCommonSubexpressionElimination = 0; // Common sub-expression elimination. + int enableLoopUnroll = 0; // Loop unrolling. + int enableFunctionInlining = 0; // Function inlining. + int enableCodeMotion = 0; // Code motion. + int enableTypeBasedAliasAnalysis = 0; // Type based alias analysis. + int enableCrossCall = 0; // Cross call optimization. + int disableRegisterBanks = 0; // Disabled register banks. + int disableSizeConstrains = 0; // No size constraints. +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + // TODO: Need to exclude the pre-defined maroses which are handled + // in 'General Options'. + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + const QString dlibToolkitPath = IarewUtils::dlibToolkitRootPath(qbsProduct); + for (const QString &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + // Exclude dlib config includes because it already handled in + // 'General Options->Library configuration page'. + if (includeFilePath.startsWith(dlibToolkitPath)) + continue; + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + warningsAsErrors = gen::utils::cppIntegerModuleProperty( + qbsProps, QStringLiteral("treatWarningsAsErrors")); + } + + int warningsAsErrors = 0; +}; + +// Code page options. + +struct CodePageOptions final +{ + explicit CodePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + paddingForRomMonitorBreakpoints = flags.contains( + QLatin1String("--rom_mon_bp_padding")); + excludeUbrofMessagesInOutput = flags.contains( + QLatin1String("--no_ubrof_messages")); + } + + int paddingForRomMonitorBreakpoints = 0; + int excludeUbrofMessagesInOutput = 0; +}; + +} // namespace + +// Mcs51CompilerSettingsGroup + +Mcs51CompilerSettingsGroup::Mcs51CompilerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProject) + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("ICC8051")); + setArchiveVersion(kCompilerArchiveVersion); + setDataVersion(kCompilerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildOutputPage(qbsProduct); + buildLanguageOnePage(qbsProduct); + buildLanguageTwoPage(qbsProduct); + buildOptimizationsPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); +} + +void Mcs51CompilerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'CCDebugInfo' item (Generate debug info). + addOptionsGroup(QByteArrayLiteral("CCDebugInfo"), + {opts.debugInfo}); + // Add 'CCOverrideModuleTypeDefault' item + // (Override default module type). + addOptionsGroup(QByteArrayLiteral("CCOverrideModuleTypeDefault"), + {1}); + // Add 'CCRadioModuleType' item (Module type: program/library). + addOptionsGroup(QByteArrayLiteral("CCRadioModuleType"), + {opts.moduleType}); +} + +void Mcs51CompilerSettingsGroup::buildLanguageOnePage( + const ProductData &qbsProduct) +{ + const LanguageOnePageOptions opts(qbsProduct); + // Add 'IccLang' item with 'auto-extension based' + // value (Language: C/C++/Auto). + addOptionsGroup(QByteArrayLiteral("IccLang"), + {opts.languageExtension}); + // Add 'IccCDialect' item (C dialect: c89/99/11). + addOptionsGroup(QByteArrayLiteral("IccCDialect"), + {opts.cLanguageDialect}); + // Add 'IccCppDialect' item (C++ dialect: embedded/extended). + addOptionsGroup(QByteArrayLiteral("IccCppDialect"), + {opts.cxxLanguageDialect}); + // Add 'CCExt' item (Language conformance: IAR/relaxed/strict). + addOptionsGroup(QByteArrayLiteral("LangConform"), + {opts.languageConformance}); + // Add 'IccAllowVLA' item (Allow VLA). + addOptionsGroup(QByteArrayLiteral("IccAllowVLA"), + {opts.allowVla}); + // Add 'IccCppInlineSemantics' item (C++ inline semantics). + addOptionsGroup(QByteArrayLiteral("IccCppInlineSemantics"), + {opts.useCppInlineSemantics}); + // Add 'CCRequirePrototypes' item (Require prototypes). + addOptionsGroup(QByteArrayLiteral("CCRequirePrototypes"), + {opts.requirePrototypes}); + // Add 'IccStaticDestr' item (Destroy static objects). + addOptionsGroup(QByteArrayLiteral("IccStaticDestr"), + {opts.destroyStaticObjects}); +} + +void Mcs51CompilerSettingsGroup::buildLanguageTwoPage( + const ProductData &qbsProduct) +{ + const LanguageTwoPageOptions opts(qbsProduct); + // Add 'CharIs' item (Plain char is: signed/unsigned). + addOptionsGroup(QByteArrayLiteral("CharIs"), + {opts.plainCharacter}); + // Add 'IccFloatSemantics' item + // (Floatic-point semantics: strict/relaxed conformance). + addOptionsGroup(QByteArrayLiteral("IccFloatSemantics"), + {opts.floatingPointSemantic}); + // Add 'CCMultibyteSupport' item (Enable multibyte support). + addOptionsGroup(QByteArrayLiteral("CCMultibyteSupport"), + {opts.enableMultibyteSupport}); +} + +void Mcs51CompilerSettingsGroup::buildOptimizationsPage( + const ProductData &qbsProduct) +{ + const OptimizationsPageOptions opts(qbsProduct); + // Add 'CCOptStrategy', 'CCOptLevel' and + // 'CCOptLevelSlave' items (Level). + addOptionsGroup(QByteArrayLiteral("CCOptStrategy"), + {opts.optimizationStrategy}); + addOptionsGroup(QByteArrayLiteral("CCOptLevel"), + {opts.optimizationLevel}); + addOptionsGroup(QByteArrayLiteral("CCOptLevelSlave"), + {opts.optimizationLevelSlave}); + // Add 'CCAllowList2' item (Enabled transformations: 7 check boxes). + const QString transformations = QStringLiteral("%1%2%3%4%5%6%7") + .arg(opts.enableCommonSubexpressionElimination) + .arg(opts.enableLoopUnroll) + .arg(opts.enableFunctionInlining) + .arg(opts.enableCodeMotion) + .arg(opts.enableTypeBasedAliasAnalysis) + .arg(opts.enableCrossCall) + .arg(opts.disableRegisterBanks); + addOptionsGroup(QByteArrayLiteral("CCAllowList2"), + {transformations}); + // Add 'NoSizeConstraints' item (No size constraints). + addOptionsGroup(QByteArrayLiteral("NoSizeConstraints"), + {opts.disableSizeConstrains}); +} + +void Mcs51CompilerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'CCDefines' item (Defines symbols). + addOptionsGroup(QByteArrayLiteral("CCDefines"), + opts.defineSymbols); + // Add 'CCIncludePath2' item (Additional include directories). + addOptionsGroup(QByteArrayLiteral("CCIncludePath2"), + opts.includePaths); +} + +void Mcs51CompilerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'CCDiagWarnAreErr' item (Treat all warnings as errors). + addOptionsGroup(QByteArrayLiteral("CCDiagWarnAreErr"), + {opts.warningsAsErrors}); +} + +void Mcs51CompilerSettingsGroup::buildCodePage( + const ProductData &qbsProduct) +{ + const CodePageOptions opts(qbsProduct); + // Add 'RomMonBpPadding' item (Padding for ROM-monitor breakpoints). + addOptionsGroup(QByteArrayLiteral("RomMonBpPadding"), + {opts.paddingForRomMonitorBreakpoints}); + // Add 'NoUBROFMessages' item (No UBROF messages in output files). + addOptionsGroup(QByteArrayLiteral("NoUBROFMessages"), + {opts.excludeUbrofMessagesInOutput}); +} + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51compilersettingsgroup_v10.h b/src/plugins/generator/iarew/archs/mcs51/mcs51compilersettingsgroup_v10.h new file mode 100644 index 000000000..e68a7628f --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51compilersettingsgroup_v10.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMCS51COMPILERSETTINGSGROUP_V10_H +#define QBS_IAREWMCS51COMPILERSETTINGSGROUP_V10_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +class Mcs51CompilerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Mcs51CompilerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const ProductData &qbsProduct); + void buildLanguageOnePage(const ProductData &qbsProduct); + void buildLanguageTwoPage(const ProductData &qbsProduct); + void buildOptimizationsPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); + void buildCodePage(const ProductData &qbsProduct); +}; + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMCS51COMPILERSETTINGSGROUP_V10_H diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51generalsettingsgroup_v10.cpp b/src/plugins/generator/iarew/archs/mcs51/mcs51generalsettingsgroup_v10.cpp new file mode 100644 index 000000000..43c160045 --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51generalsettingsgroup_v10.cpp @@ -0,0 +1,1014 @@ +/**************************************************************************** +** +** 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 "mcs51generalsettingsgroup_v10.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +constexpr int kGeneralArchiveVersion = 4; +constexpr int kGeneralDataVersion = 9; + +namespace { + +// Target page options. + +struct TargetPageOptions final +{ + enum CpuCore { + CorePlain = 1, + CoreExtended1, + CoreExtended2 + }; + + enum CodeModel { + CodeModelNear = 1, + CodeModelBanked, + CodeModelFar, + CodeModelBankedExtended2 + }; + + enum DataModel { + DataModelTiny = 0, + DataModelSmall, + DataModelLarge, + DataModelGeneric, + DataModelFarGeneric, + DataModelFar + }; + + enum ConstantsMemoryPlacement { + RamMemoryPlace = 0, + RomMemoryPlace, + CodeMemoryPlace + }; + + enum CallingConvention { + DataOverlayConvention = 0, + IDataOverlayConvention, + IDataReentrantConvention, + PDataReentrantConvention, + XDataReentrantConvention, + ExtendedStackReentrantConvention + }; + + explicit TargetPageOptions(const ProductData &qbsProduct) + { + chipInfoPath = detectChipInfoPath(qbsProduct); + + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + + // Should be parsed before the 'code_model' and + // 'data_model' options, as that options are depends on it. + const QString core = IarewUtils::flagValue( + flags, QStringLiteral("--core")) + .toLower(); + if (core == QLatin1String("plain")) { + cpuCore = TargetPageOptions::CorePlain; + } else if (core == QLatin1String("extended1")) { + cpuCore = TargetPageOptions::CoreExtended1; + } else if (core == QLatin1String("extended2")) { + cpuCore = TargetPageOptions::CoreExtended2; + } else { + // If the core variant is not set, then choose the + // default values (see the compiler datasheet for + // '--core' option). + cpuCore = TargetPageOptions::CorePlain; + } + + const QString cm = IarewUtils::flagValue( + flags, QStringLiteral("--code_model")) + .toLower(); + if (cm == QLatin1String("near")) { + codeModel = TargetPageOptions::CodeModelNear; + } else if (cm == QLatin1String("banked")) { + codeModel = TargetPageOptions::CodeModelBanked; + } else if (cm == QLatin1String("far")) { + codeModel = TargetPageOptions::CodeModelFar; + } else if (cm == QLatin1String("banked_ext2")) { + codeModel = TargetPageOptions::CodeModelBankedExtended2; + } else { + // If the code model is not set, then choose the + // default values (see the compiler datasheet for + // '--code_model' option). + if (cpuCore == TargetPageOptions::CorePlain) + codeModel = TargetPageOptions::CodeModelNear; + else if (cpuCore == TargetPageOptions::CoreExtended1) + codeModel = TargetPageOptions::CodeModelFar; + else if (cpuCore == TargetPageOptions::CoreExtended2) + codeModel = TargetPageOptions::CodeModelBankedExtended2; + } + + const QString dm = IarewUtils::flagValue( + flags, QStringLiteral("--data_model")).toLower(); + if (dm == QLatin1String("tiny")) { + dataModel = TargetPageOptions::DataModelTiny; + } else if (dm == QLatin1String("small")) { + dataModel = TargetPageOptions::DataModelSmall; + } else if (dm == QLatin1String("large")) { + dataModel = TargetPageOptions::DataModelLarge; + } else if (dm == QLatin1String("generic")) { + dataModel = TargetPageOptions::DataModelGeneric; + } else if (dm == QLatin1String("far_generic")) { + dataModel = TargetPageOptions::DataModelFarGeneric; + } else if (dm == QLatin1String("far")) { + dataModel = TargetPageOptions::DataModelFar; + } else { + // If the data model is not set, then choose the + // default values (see the compiler datasheet for + // '--data_model' option). + if (cpuCore == TargetPageOptions::CorePlain) + dataModel = TargetPageOptions::DataModelSmall; + else if (cpuCore == TargetPageOptions::CoreExtended1) + dataModel = TargetPageOptions::DataModelFar; + else if (cpuCore == TargetPageOptions::CoreExtended2) + dataModel = TargetPageOptions::DataModelLarge; + } + + useExtendedStack = flags.contains(QLatin1String("--extended_stack")); + + const int regsCount = IarewUtils::flagValue( + flags, QStringLiteral("--nr_virtual_regs")) + .toInt(); + enum { MinVRegsCount = 8, MaxVRegsCount = 32, VRegsOffset = 8 }; + // The registers index starts with 0: 0 - means 8 registers, + // 1 - means 9 registers and etc. Any invalid values we interpret + // as a default value in 8 registers. + virtualRegisters = (regsCount < MinVRegsCount || regsCount > MaxVRegsCount) + ? 0 : (regsCount - VRegsOffset); + + const QString constPlace = IarewUtils::flagValue( + flags, QStringLiteral("--place_constants")) + .toLower(); + if (constPlace == QLatin1String("data")) { + constPlacement = TargetPageOptions::RamMemoryPlace; + } else if (constPlace == QLatin1String("data_rom")) { + constPlacement = TargetPageOptions::RomMemoryPlace; + } else if (constPlace == QLatin1String("code")) { + constPlacement = TargetPageOptions::CodeMemoryPlace; + } else { + // If this option is not set, then choose the + // default value (see the compiler datasheet for + // '--place_constants' option). + constPlacement = TargetPageOptions::RamMemoryPlace; + } + + const QString cc = IarewUtils::flagValue( + flags, QStringLiteral("--calling_convention")).toLower(); + if (cc == QLatin1String("data_overlay")) { + callingConvention = TargetPageOptions::DataOverlayConvention; + } else if (cc == QLatin1String("idata_overlay")) { + callingConvention = TargetPageOptions::IDataOverlayConvention; + } else if (cc == QLatin1String("idata_reentrant")) { + callingConvention = TargetPageOptions::IDataReentrantConvention; + } else if (cc == QLatin1String("pdata_reentrant")) { + callingConvention = TargetPageOptions::PDataReentrantConvention; + } else if (cc == QLatin1String("xdata_reentrant")) { + callingConvention = TargetPageOptions::XDataReentrantConvention; + } else if (cc == QLatin1String("ext_stack_reentrant")) { + callingConvention = TargetPageOptions::ExtendedStackReentrantConvention; + } else { + // If this option is not set, then choose the + // default value (see the compiler datasheet for + // '--calling_convention' option). + callingConvention = TargetPageOptions::IDataReentrantConvention; + } + } + + // Trying to indirectly detect and build the chip config path, + // which uses to show a device name in "Device information" group box. + static QString detectChipInfoPath(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + + QVariantList configPaths; + + // Enumerate all product linker config files + // (which are set trough '-f' option). + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + configPaths << IarewUtils::flagValues(flags, QStringLiteral("-f")); + + // 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 auto configPath = qbsArtifact.filePath(); + // Skip duplicates. + if (configPaths.contains(configPath)) + continue; + configPaths << qbsArtifact.filePath(); + } + } + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + for (const QVariant &configPath : configPaths) { + const QString fullConfigPath = configPath.toString(); + // We interested only in a config paths shipped inside of a toolkit. + if (!fullConfigPath.startsWith(toolkitPath, Qt::CaseInsensitive)) + continue; + // Extract the chip name from the linker script name. + const int underscoreIndex = fullConfigPath.lastIndexOf(QLatin1Char('_')); + if (underscoreIndex == -1) + continue; + const int dotIndex = fullConfigPath.lastIndexOf(QLatin1Char('.')); + if (dotIndex == -1) + continue; + if (dotIndex <= underscoreIndex) + continue; + const QString chipName = fullConfigPath.mid( + underscoreIndex + 1, + dotIndex - underscoreIndex - 1); + // Construct full chip info path. + const QFileInfo fullChipInfoPath(QFileInfo(fullConfigPath).absolutePath() + + QLatin1Char('/') + chipName + + QLatin1String(".i51")); + if (fullChipInfoPath.exists()) + return fullChipInfoPath.absoluteFilePath(); + } + + return {}; + } + + QString chipInfoPath; + CpuCore cpuCore = CorePlain; + CodeModel codeModel = CodeModelNear; + DataModel dataModel = DataModelTiny; + int useExtendedStack = 0; + int virtualRegisters = 0; + ConstantsMemoryPlacement constPlacement = RamMemoryPlace; + CallingConvention callingConvention = DataOverlayConvention; +}; + +// System page options. + +struct StackHeapPageOptions final +{ + explicit StackHeapPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList defineSymbols = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("defines")}); + const QStringList linkerFlags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("driverLinkerFlags")}); + + idataStack = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_IDATA_STACK_SIZE")); + if (idataStack.isEmpty()) + idataStack = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_IDATA_STACK_SIZE")); + if (idataStack.isEmpty()) + idataStack = QLatin1String("0x40"); // Default IDATA stack size. + pdataStack = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_PDATA_STACK_SIZE")); + if (pdataStack.isEmpty()) + pdataStack = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_PDATA_STACK_SIZE")); + if (pdataStack.isEmpty()) + pdataStack = QLatin1String("0x80"); // Default PDATA stack size. + xdataStack = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_XDATA_STACK_SIZE")); + if (xdataStack.isEmpty()) + xdataStack = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_XDATA_STACK_SIZE")); + if (xdataStack.isEmpty()) + xdataStack = QLatin1String("0xEFF"); // Default XDATA stack size. + extendedStack = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_EXTENDED_STACK_SIZE")); + if (extendedStack.isEmpty()) + extendedStack = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_EXTENDED_STACK_SIZE")); + if (extendedStack.isEmpty()) + extendedStack = QLatin1String("0x3FF"); // Default EXTENDED stack size. + + xdataHeap = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_XDATA_HEAP_SIZE")); + if (xdataHeap.isEmpty()) + xdataHeap = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_XDATA_HEAP_SIZE")); + if (xdataHeap.isEmpty()) + xdataHeap = QLatin1String("0xFF"); // Default XDATA heap size. + farHeap = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_FAR_HEAP_SIZE")); + if (farHeap.isEmpty()) + farHeap = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_FAR_HEAP_SIZE")); + if (farHeap.isEmpty()) + farHeap = QLatin1String("0xFFF"); // Default FAR heap size. + far22Heap = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_FAR22_HEAP_SIZE")); + if (far22Heap.isEmpty()) + far22Heap = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_FAR22_HEAP_SIZE")); + if (far22Heap.isEmpty()) + far22Heap = QLatin1String("0xFFF"); // Default FAR22 heap size. + hugeHeap = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_HUGE_HEAP_SIZE")); + if (hugeHeap.isEmpty()) + hugeHeap = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_HUGE_HEAP_SIZE")); + if (hugeHeap.isEmpty()) + hugeHeap = QLatin1String("0xFFF"); // Default HUGE heap size. + + extStackAddress = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?ESP")); + if (extStackAddress.isEmpty()) + extStackAddress = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?ESP")); + if (extStackAddress.isEmpty()) + extStackAddress = QLatin1String("0x9B"); // Default extended stack pointer address. + extStackMask = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?ESP_MASK")); + if (extStackMask.isEmpty()) + extStackMask = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?ESP_MASK")); + if (extStackMask.isEmpty()) + extStackMask = QLatin1String("0x03"); // Default extended stack pointer mask. + } + + // Stack sizes. + QString idataStack; + QString pdataStack; + QString xdataStack; + QString extendedStack; + // Heap sizes. + QString xdataHeap; + QString farHeap; + QString far22Heap; + QString hugeHeap; + // Extended stack. + QString extStackAddress; + QString extStackMask; + int extStackOffset = 0; + int extStackStartAddress = 0; +}; + +// Data pointer page options. + +struct DptrPageOptions final +{ + enum DptrSize { + Dptr16, + Dptr24 + }; + + enum DptrVisibility { + DptrShadowed, + DptrSeparate + }; + + enum SwitchMethod { + DptrIncludeMethod, + DptrMaskMethod + }; + + explicit DptrPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + + const QString core = IarewUtils::flagValue( + flags, QStringLiteral("--core")); + + const QString dptr = IarewUtils::flagValue( + flags, QStringLiteral("--dptr")); + enum ValueIndex { SizeIndex, NumbersIndex, + VisibilityIndex, SwitchMethodIndex }; + const QStringList dptrparts = dptr.split(QLatin1Char(',')); + for (auto index = 0; index < dptrparts.count(); ++index) { + const QString part = dptrparts.at(index).toLower(); + switch (index) { + case SizeIndex: + if (part == QLatin1String("16")) { + dptrSize = DptrPageOptions::Dptr16; + } else if (part == QLatin1String("24")) { + dptrSize = DptrPageOptions::Dptr24; + } else { + // If this option is not set, then choose the + // default value (see the compiler datasheet for + // '--dptr' option). + if (core == QLatin1String("extended1")) + dptrSize = DptrPageOptions::Dptr24; + else + dptrSize = DptrPageOptions::Dptr16; + } + break; + case NumbersIndex: { + const int count = part.toInt(); + if (count < 1 || count > 8) { + // If this option is not set, then choose the + // default value (see the compiler datasheet for + // '--dptr' option). + if (core == QLatin1String("extended1")) + dptrsCountIndex = 1; // 2 DPTR's + else + dptrsCountIndex = 0; // 1 DPTR's + } else { + dptrsCountIndex = (count - 1); // DPTR's count - 1 + } + } + break; + case VisibilityIndex: + if (part == QLatin1String("shadowed")) + dptrVisibility = DptrPageOptions::DptrShadowed; + else if (part == QLatin1String("separate")) + dptrVisibility = DptrPageOptions::DptrSeparate; + else + // If this option is not set, then choose the + // default value (see the compiler datasheet for + // '--dptr' option). + dptrVisibility = DptrPageOptions::DptrSeparate; + break; + case SwitchMethodIndex: + if (part == QLatin1String("inc")) { + dptrSwitchMethod = DptrPageOptions::DptrIncludeMethod; + } else if (part.startsWith(QLatin1String("xor"))) { + dptrSwitchMethod = DptrPageOptions::DptrMaskMethod; + const int firstIndex = part.indexOf(QLatin1Char('(')); + const int lastIndex = part.indexOf(QLatin1Char(')')); + dptrMask = part.mid(firstIndex + 1, part.size() - lastIndex); + } else { + // If this option is not set, then choose the + // default value (see the compiler datasheet for + // '--dptr' option). + if (core == QLatin1String("extended1")) { + dptrSwitchMethod = DptrPageOptions::DptrIncludeMethod; + } else if (core == QLatin1String("plain")) { + dptrSwitchMethod = DptrPageOptions::DptrMaskMethod; + dptrMask = QLatin1String("0x01"); + } + } + break; + default: + break; + } + } + + const QStringList defineSymbols = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("defines")}); + const QStringList linkerFlags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("driverLinkerFlags")}); + + dptrPbank = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?PBANK")); + if (dptrPbank.isEmpty()) + dptrPbank = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?PBANK")); + if (dptrPbank.isEmpty()) + dptrPbank = QLatin1String("0x93"); // Default 8-15 regs address. + dptrPbankExt = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?PBANK_EXT")); + if (dptrPbankExt.isEmpty()) + dptrPbankExt = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?PBANK_EXT")); + + dpsAddress = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?DPS")); + if (dpsAddress.isEmpty()) + dpsAddress = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?DPS")); + dpcAddress = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?DPC")); + if (dpcAddress.isEmpty()) + dpcAddress = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?DPC")); + + for (auto index = 0; index < 8; ++index) { + if (index == 0) { + QString dpxAddress = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?DPX")); + if (dpxAddress.isEmpty()) + dpxAddress = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?DPX")); + if (!dpxAddress.isEmpty()) + dpxAddress.prepend(QLatin1String("-D?DPX=")); + if (!dptrAddresses.contains(dpxAddress)) + dptrAddresses.push_back(dpxAddress); + } else { + QString dplAddress = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?DPL%1").arg(index)); + if (dplAddress.isEmpty()) + dplAddress = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?DPL%1").arg(index)); + if (!dplAddress.isEmpty()) + dplAddress.prepend(QStringLiteral("-D?DPL%1=").arg(index)); + if (!dptrAddresses.contains(dplAddress)) + dptrAddresses.push_back(dplAddress); + + QString dphAddress = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?DPH%1").arg(index)); + if (dphAddress.isEmpty()) + dphAddress = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?DPH%1").arg(index)); + if (!dphAddress.isEmpty()) + dphAddress.prepend(QStringLiteral("-D?DPH%1=").arg(index)); + if (!dptrAddresses.contains(dphAddress)) + dptrAddresses.push_back(dphAddress); + + QString dpxAddress = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?DPX%1").arg(index)); + if (dpxAddress.isEmpty()) + dpxAddress = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?DPX%1").arg(index)); + if (!dpxAddress.isEmpty()) + dpxAddress.prepend(QStringLiteral("-D?DPX%1=").arg(index)); + if (!dptrAddresses.contains(dpxAddress)) + dptrAddresses.push_back(dpxAddress); + } + } + } + + int dptrsCountIndex = 0; + DptrSize dptrSize = Dptr16; + DptrVisibility dptrVisibility = DptrShadowed; + SwitchMethod dptrSwitchMethod = DptrIncludeMethod; + QString dptrMask; + QString dptrPbank; + QString dptrPbankExt; + QString dpsAddress; + QString dpcAddress; + QStringList dptrAddresses; +}; + +// Code bank page options. + +struct CodeBankPageOptions final +{ + explicit CodeBankPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList defineSymbols = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("defines")}); + const QStringList linkerFlags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("driverLinkerFlags")}); + + banksCount = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_NR_OF_BANKS")); + if (banksCount.isEmpty()) + banksCount = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_NR_OF_BANKS")); + if (banksCount.isEmpty()) + banksCount = QLatin1String("0x03"); + registerAddress = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?CBANK")); + if (registerAddress.isEmpty()) + registerAddress = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?CBANK")); + if (registerAddress.isEmpty()) + registerAddress = QLatin1String("0xF0"); + registerMask = IarewUtils::flagValue( + defineSymbols, QStringLiteral("?CBANK_MASK")); + if (registerMask.isEmpty()) + registerMask = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D?CBANK_MASK")); + if (registerMask.isEmpty()) + registerMask = QLatin1String("0xFF"); + bankStart = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_CODEBANK_START")); + if (bankStart.isEmpty()) + bankStart = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_CODEBANK_START")); + if (bankStart.isEmpty()) + bankStart = QLatin1String("0x8000"); + bankEnd = IarewUtils::flagValue( + defineSymbols, QStringLiteral("_CODEBANK_END")); + if (bankEnd.isEmpty()) + bankEnd = IarewUtils::flagValue( + linkerFlags, QStringLiteral("-D_CODEBANK_END")); + if (bankEnd.isEmpty()) + bankEnd = QLatin1String("0xFFFF"); + } + + QString banksCount; + QString registerAddress; + QString registerMask; + QString bankStart; + QString bankEnd; +}; + +// Library options page options. + +struct LibraryOptionsPageOptions final +{ + enum PrintfFormatter { + PrintfAutoFormatter = 0, + PrintfLargeFormatter = 3, + PrintfMediumFormatter = 5, + PrintfSmallFormatter = 6 + }; + + enum ScanfFormatter { + ScanfAutoFormatter = 0, + ScanfLargeFormatter = 3, + ScanfMediumFormatter = 5 + }; + + explicit LibraryOptionsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + for (const QString &flag : flags) { + if (flag.endsWith(QLatin1String("_formatted_write"), + Qt::CaseInsensitive)) { + const QString prop = flag.split( + QLatin1Char('=')).at(0).toLower(); + if (prop == QLatin1String("-e_large_write")) + printfFormatter = LibraryOptionsPageOptions::PrintfLargeFormatter; + else if (prop == QLatin1String("-e_medium_write")) + printfFormatter = LibraryOptionsPageOptions::PrintfMediumFormatter; + else if (prop == QLatin1String("-e_small_write")) + printfFormatter = LibraryOptionsPageOptions::PrintfSmallFormatter; + else + // If this option is not set, then choose the + // default value (see the compiler datasheet for + // '_formatted_write' option). + printfFormatter = LibraryOptionsPageOptions::PrintfMediumFormatter; + } else if (flag.endsWith(QLatin1String("_formatted_read"), + Qt::CaseInsensitive)) { + const QString prop = flag.split(QLatin1Char('=')) + .at(0).toLower(); + if (prop == QLatin1String("-e_large_read")) + scanfFormatter = LibraryOptionsPageOptions::ScanfLargeFormatter; + else if (prop == QLatin1String("-e_medium_read")) + scanfFormatter = LibraryOptionsPageOptions::ScanfMediumFormatter; + else + // If this option is not set, then choose the + // default value (see the compiler datasheet for + // '_formatted_read' option). + scanfFormatter = LibraryOptionsPageOptions::ScanfMediumFormatter; + } + } + } + + PrintfFormatter printfFormatter = PrintfAutoFormatter; + ScanfFormatter scanfFormatter = ScanfAutoFormatter; +}; + +// Library configuration page options. + +struct LibraryConfigPageOptions final +{ + enum RuntimeLibrary { + NoLibrary, + NormalDlibLibrary, + CustomDlibLibrary, + ClibLibrary, + CustomClibLibrary + }; + + explicit LibraryConfigPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + + const QStringList libraryPaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("staticLibraries")}); + const auto libraryBegin = libraryPaths.cbegin(); + const auto libraryEnd = libraryPaths.cend(); + + const QFileInfo dlibConfigInfo(IarewUtils::flagValue( + flags, QStringLiteral("--dlib_config"))); + const QString dlibConfigFilePath = dlibConfigInfo.absoluteFilePath(); + if (!dlibConfigFilePath.isEmpty()) { + const QString dlibToolkitPath = IarewUtils::dlibToolkitRootPath( + qbsProduct); + if (dlibConfigFilePath.startsWith(dlibToolkitPath, + Qt::CaseInsensitive)) { + libraryType = LibraryConfigPageOptions::NormalDlibLibrary; + configPath = IarewUtils::toolkitRelativeFilePath( + baseDirectory, dlibConfigFilePath); + + // Find dlib library inside of IAR toolkit directory. + const auto libraryIt = std::find_if(libraryBegin, libraryEnd, + [dlibToolkitPath]( + const QString &libraryPath) { + return libraryPath.startsWith(dlibToolkitPath); + }); + if (libraryIt != libraryEnd) { + // This means that dlib library is 'standard' (placed inside + // of IAR toolkit directory). + libraryPath = IarewUtils::toolkitRelativeFilePath( + baseDirectory, *libraryIt); + } + } else { + // This means that dlib library is 'custom' + // (but we don't know its path). + libraryType = LibraryConfigPageOptions::CustomDlibLibrary; + configPath = IarewUtils::projectRelativeFilePath( + baseDirectory, dlibConfigFilePath); + } + } else { + // Find clib library inside of IAR toolkit directory. + const QString clibToolkitPath = IarewUtils::clibToolkitRootPath( + qbsProduct); + const auto libraryIt = std::find_if(libraryBegin, libraryEnd, + [clibToolkitPath]( + const QString &libraryPath) { + return libraryPath.startsWith(clibToolkitPath); + }); + if (libraryIt != libraryEnd) { + // This means that clib library is 'standard' (placed inside + // of IAR toolkit directory). + libraryType = LibraryConfigPageOptions::ClibLibrary; + libraryPath = IarewUtils::toolkitRelativeFilePath( + baseDirectory, *libraryIt); + } else { + // This means that no any libraries are used . + libraryType = LibraryConfigPageOptions::NoLibrary; + } + } + } + + RuntimeLibrary libraryType = NoLibrary; + QString configPath; + QString libraryPath; +}; + +// 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; +}; + +} // namespace + +// Mcs51GeneralSettingsGroup + +Mcs51GeneralSettingsGroup::Mcs51GeneralSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProject) + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("General")); + setArchiveVersion(kGeneralArchiveVersion); + setDataVersion(kGeneralDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildTargetPage(qbsProduct); + buildStackHeapPage(qbsProduct); + buildDataPointerPage(qbsProduct); + buildCodeBankPage(qbsProduct); + buildLibraryOptionsPage(qbsProduct); + buildLibraryConfigPage(buildRootDirectory, qbsProduct); + buildOutputPage(buildRootDirectory, qbsProduct); +} + +void Mcs51GeneralSettingsGroup::buildTargetPage( + const ProductData &qbsProduct) +{ + const TargetPageOptions opts(qbsProduct); + // Add 'OGChipConfigPath' item (Device: <chip name>). + addOptionsGroup(QByteArrayLiteral("OGChipConfigPath"), + {opts.chipInfoPath}); + + // Add 'CPU Core' and 'CPU Core Slave' items + // (CPU core: plain/extended{1|2}). + addOptionsGroup(QByteArrayLiteral("CPU Core"), + {opts.cpuCore}); + addOptionsGroup(QByteArrayLiteral("CPU Core Slave"), + {opts.cpuCore}); + // Add 'Code Memory Model' and 'Code Memory Model slave' items + // (Code model: near/banked/far/banked extended). + addOptionsGroup(QByteArrayLiteral("Code Memory Model"), + {opts.codeModel}); + addOptionsGroup(QByteArrayLiteral("Code Memory Model slave"), + {opts.codeModel}); + // Add 'Data Memory Model' and 'Data Memory Model slave' items + // (Data model: tiny/small/large/generic/far). + addOptionsGroup(QByteArrayLiteral("Data Memory Model"), + {opts.dataModel}); + addOptionsGroup(QByteArrayLiteral("Data Memory Model slave"), + {opts.dataModel}); + // Add 'Use extended stack' and 'Use extended stack slave' items + // (Use extended stack). + addOptionsGroup(QByteArrayLiteral("Use extended stack"), + {opts.useExtendedStack}); + addOptionsGroup(QByteArrayLiteral("Use extended stack slave"), + {opts.useExtendedStack}); + // Add 'Workseg Size' item (Number of virtual registers: 8...32). + addOptionsGroup(QByteArrayLiteral("Workseg Size"), + {opts.virtualRegisters}); + // Add 'Constant Placement' item + // (Location of constants and strings: ram/rom/code memories). + addOptionsGroup(QByteArrayLiteral("Constant Placement"), + {opts.constPlacement}); + // Add 'Calling convention' item (Calling convention). + addOptionsGroup(QByteArrayLiteral("Calling convention"), + {opts.callingConvention}); +} + +void Mcs51GeneralSettingsGroup::buildStackHeapPage( + const ProductData &qbsProduct) +{ + const StackHeapPageOptions opts(qbsProduct); + // Add 'General Idata Stack Size' item (Stack size: IDATA). + addOptionsGroup(QByteArrayLiteral("General Idata Stack Size"), + {opts.idataStack}); + // Add 'General Pdata Stack Size' item (Stack size: PDATA). + addOptionsGroup(QByteArrayLiteral("General Pdata Stack Size"), + {opts.pdataStack}); + // Add 'General Xdata Stack Size' item (Stack size: XDATA). + addOptionsGroup(QByteArrayLiteral("General Xdata Stack Size"), + {opts.xdataStack}); + // Add 'General Ext Stack Size' item (Stack size: Extended). + addOptionsGroup(QByteArrayLiteral("General Ext Stack Size"), + {opts.extendedStack}); + + // Add 'General Xdata Heap Size' item (Heap size: XDATA). + addOptionsGroup(QByteArrayLiteral("General Xdata Heap Size"), + {opts.xdataHeap}); + // Add 'General Far Heap Size' item (Heap size: Far). + addOptionsGroup(QByteArrayLiteral("General Far Heap Size"), + {opts.farHeap}); + // Add 'General Far22 Heap Size' item (Heap size: Far22). + addOptionsGroup(QByteArrayLiteral("General Far22 Heap Size"), + {opts.far22Heap}); + // Add 'General Huge Heap Size' item (Heap size: Huge). + addOptionsGroup(QByteArrayLiteral("General Huge Heap Size"), + {opts.hugeHeap}); + + // Add 'Extended stack address' item + // (Extended stack pointer address). + addOptionsGroup(QByteArrayLiteral("Extended stack address"), + {opts.extStackAddress}); + // Add 'Extended stack mask' item (Extended stack pointer mask). + addOptionsGroup(QByteArrayLiteral("Extended stack mask"), + {opts.extStackMask}); + // Add 'Extended stack is offset' item + // (Extended stack pointer is an offset). + addOptionsGroup(QByteArrayLiteral("Extended stack is offset"), + {opts.extStackOffset}); +} + +void Mcs51GeneralSettingsGroup::buildDataPointerPage( + const ProductData &qbsProduct) +{ + const DptrPageOptions opts(qbsProduct); + // Add 'Nr of Datapointers' item (Number of DPTRs: 1...8). + addOptionsGroup(QByteArrayLiteral("Nr of Datapointers"), + {opts.dptrsCountIndex}); + // Add 'Datapointer Size' item (DPTR size: 16/24). + addOptionsGroup(QByteArrayLiteral("Datapointer Size"), + {opts.dptrSize}); + // Add 'Sfr Visibility' item (DPTR address: shadowed/separate). + addOptionsGroup(QByteArrayLiteral("Sfr Visibility"), + {opts.dptrVisibility}); + // Add 'Switch Method' item (Switch method: inc/mask). + addOptionsGroup(QByteArrayLiteral("Switch Method"), + {opts.dptrSwitchMethod}); + // Add 'Mask Value' item (Switch method mask). + addOptionsGroup(QByteArrayLiteral("Mask Value"), + {opts.dptrMask}); + // Add 'PDATA 8-15 register address' item (Page register + // address (for bits 8-15). + addOptionsGroup(QByteArrayLiteral("PDATA 8-15 register address"), + {opts.dptrPbank}); + // Add 'PDATA 16-31 register address' item (Page register + // address (for bits 16-31). + addOptionsGroup(QByteArrayLiteral("PDATA 16-31 register address"), + {opts.dptrPbankExt}); + // Add 'DPS Address' item (Selected DPTR register). + addOptionsGroup(QByteArrayLiteral("DPS Address"), + {opts.dpsAddress}); + // Add 'DPC Address' item (Separate DPTR control register). + addOptionsGroup(QByteArrayLiteral("DPC Address"), + {opts.dpcAddress}); + // Add 'DPTR Addresses' item (DPTR addresses: Low/High/Ext). + const QString dptrAddresses = opts.dptrAddresses.join(QLatin1Char(' ')); + addOptionsGroup(QByteArrayLiteral("DPTR Addresses"), + {dptrAddresses}); +} + +void Mcs51GeneralSettingsGroup::buildCodeBankPage( + const ProductData &qbsProduct) +{ + const CodeBankPageOptions opts(qbsProduct); + // Add 'CodeBankReg' item (Register address). + addOptionsGroup(QByteArrayLiteral("CodeBankReg"), + {opts.registerAddress}); + // Add 'CodeBankRegMask' item (Register mask). + addOptionsGroup(QByteArrayLiteral("CodeBankRegMask"), + {opts.registerMask}); + // Add 'CodeBankNrOfs' item (Number of banks). + addOptionsGroup(QByteArrayLiteral("CodeBankNrOfs"), + {opts.banksCount}); + // Add 'CodeBankStart' item (Bank start). + addOptionsGroup(QByteArrayLiteral("CodeBankStart"), + {opts.bankStart}); + // Add 'CodeBankSize' item (Bank end). + addOptionsGroup(QByteArrayLiteral("CodeBankSize"), + {opts.bankEnd}); +} + +void Mcs51GeneralSettingsGroup::buildLibraryOptionsPage( + const ProductData &qbsProduct) +{ + const LibraryOptionsPageOptions opts(qbsProduct); + // Add 'Output variant' item (Printf formatter). + addOptionsGroup(QByteArrayLiteral("Output variant"), + {opts.printfFormatter}); + // Add 'Input variant' item (Printf formatter). + addOptionsGroup(QByteArrayLiteral("Input variant"), + {opts.scanfFormatter}); +} + +void Mcs51GeneralSettingsGroup::buildLibraryConfigPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const LibraryConfigPageOptions opts(baseDirectory, qbsProduct); + // Add 'GRuntimeLibSelect2' and 'GRuntimeLibSelectSlave2' items + // (Link with runtime: none/dlib/clib/etc). + addOptionsGroup(QByteArrayLiteral("GRuntimeLibSelect2"), + {opts.libraryType}); + addOptionsGroup(QByteArrayLiteral("GRuntimeLibSelectSlave2"), + {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 Mcs51GeneralSettingsGroup::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}); +} + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51generalsettingsgroup_v10.h b/src/plugins/generator/iarew/archs/mcs51/mcs51generalsettingsgroup_v10.h new file mode 100644 index 000000000..1805a87af --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51generalsettingsgroup_v10.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMCS51GENERALSETTINGSGROUP_V10_H +#define QBS_IAREWMCS51GENERALSETTINGSGROUP_V10_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +class Mcs51GeneralSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Mcs51GeneralSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildTargetPage(const ProductData &qbsProduct); + void buildStackHeapPage(const ProductData &qbsProduct); + void buildDataPointerPage(const ProductData &qbsProduct); + void buildCodeBankPage(const ProductData &qbsProduct); + void buildLibraryOptionsPage(const ProductData &qbsProduct); + void buildLibraryConfigPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct); +}; + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMCS51GENERALSETTINGSGROUP_V10_H diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51linkersettingsgroup_v10.cpp b/src/plugins/generator/iarew/archs/mcs51/mcs51linkersettingsgroup_v10.cpp new file mode 100644 index 000000000..a88ac22e1 --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51linkersettingsgroup_v10.cpp @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** 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 "mcs51linkersettingsgroup_v10.h" + +#include "../../iarewutils.h" + +#include <QtCore/qdir.h> + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +constexpr int kLinkerArchiveVersion = 4; +constexpr int kLinkerDataVersion = 21; + +namespace { + +// Config page options. + +struct ConfigPageOptions final +{ + explicit ConfigPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + + entryPoint = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("entryPoint")); + + // 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)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + configFilePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + configFilePaths.push_back(path); + } + } + } + + // Enumerate all product linker config files + // (which are set trough '-f' option). + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + const QVariantList configPathValues = IarewUtils::flagValues( + flags, QStringLiteral("-f")); + for (const QVariant &configPathValue : configPathValues) { + const QString fullConfigPath = configPathValue.toString(); + if (fullConfigPath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } else { + const QString path =IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } + } + + // Add libraries search paths. + const QStringList libraryPaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("libraryPaths")}); + for (const QString &libraryPath : libraryPaths) { + const QFileInfo libraryPathInfo(libraryPath); + const QString fullLibrarySearchPath = libraryPathInfo.absoluteFilePath(); + if (fullLibrarySearchPath.startsWith(toolkitPath, + Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullLibrarySearchPath); + librarySearchPaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullLibrarySearchPath); + librarySearchPaths.push_back(path); + } + } + } + + QVariantList configFilePaths; + QVariantList librarySearchPaths; + QString entryPoint; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + outputFile = gen::utils::targetBinary(qbsProduct); + } + + QString outputFile; +}; + +// List page options. + +struct ListPageOptions final +{ + enum ListingAction { + NoListing, + GenerateListing + }; + + explicit ListPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + generateMap = gen::utils::cppBooleanModuleProperty( + qbsProps, QStringLiteral("generateLinkerMapFile")) + ? ListPageOptions::GenerateListing + : ListPageOptions::NoListing; + } + + ListingAction generateMap = NoListing; +}; + +// Define page options. + +struct DefinePageOptions final +{ + explicit DefinePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + // Enumerate all linker defines. + for (const QString &flag : flags) { + if (!flag.startsWith(QLatin1String("-D"))) + continue; + const QString symbol = flag.mid(2); + // Ignore system-defined macroses, because its already + // handled in "General Options" page. + if (symbol.startsWith(QLatin1Char('?')) + || symbol.startsWith(QLatin1Char('_')) + ) { + continue; + } + defineSymbols.push_back(symbol); + } + } + + QVariantList defineSymbols; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString warningLevel = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("warningLevel")); + suppressAllWarnings = (warningLevel == QLatin1String("none")); + } + + int suppressAllWarnings = 0; +}; + +} // namespace + +// Mcs51LinkerSettingsGroup + +Mcs51LinkerSettingsGroup::Mcs51LinkerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProject) + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("XLINK")); + setArchiveVersion(kLinkerArchiveVersion); + setDataVersion(kLinkerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildConfigPage(buildRootDirectory, qbsProduct); + buildOutputPage(qbsProduct); + buildListPage(qbsProduct); + buildDefinePage(qbsProduct); + buildDiagnosticsPage(qbsProduct); + + // Should be called as latest stage! + buildExtraOptionsPage(qbsProduct); +} + +void Mcs51LinkerSettingsGroup::buildConfigPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + ConfigPageOptions opts(baseDirectory, qbsProduct); + + if (opts.configFilePaths.count() > 0) { + // Note: IAR IDE does not allow to specify a multiple config files, + // although the IAR linker support it. So, we use followig 'trick': + // we take a first config file and to add it as usual to required items; + // and then an other remainders we forward to the "Extra options page". + const QVariant configPath = opts.configFilePaths.takeFirst(); + // Add 'XclOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("XclOverride"), + {1}); + // Add 'XclFile' item (Linke configuration file). + addOptionsGroup(QByteArrayLiteral("XclFile"), + {configPath}); + + // Add remainder configuration files to the "Extra options page". + if (!opts.configFilePaths.isEmpty()) { + for (QVariant &configPath : opts.configFilePaths) + configPath = QLatin1String("-f ") + configPath.toString(); + + m_extraOptions << opts.configFilePaths; + } + } + + // Add 'xcProgramEntryLabel' item (Entry symbol). + addOptionsGroup(QByteArrayLiteral("xcProgramEntryLabel"), + {opts.entryPoint}); + // Add 'xcOverrideProgramEntryLabel' item + // (Override default program entry). + addOptionsGroup(QByteArrayLiteral("xcOverrideProgramEntryLabel"), + {1}); + // Add 'xcProgramEntryLabelSelect' item. + addOptionsGroup(QByteArrayLiteral("xcProgramEntryLabelSelect"), + {0}); + + // Add 'XIncludes' item (Libraries search paths). + addOptionsGroup(QByteArrayLiteral("XIncludes"), + opts.librarySearchPaths); +} + +void Mcs51LinkerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'XOutOverride' item (Override default output file). + addOptionsGroup(QByteArrayLiteral("XOutOverride"), + {1}); + // Add 'OutputFile' item (Output file name). + addOptionsGroup(QByteArrayLiteral("OutputFile"), + {opts.outputFile}); +} + +void Mcs51LinkerSettingsGroup::buildListPage( + const ProductData &qbsProduct) +{ + const ListPageOptions opts(qbsProduct); + // Add 'XList' item (Generate linker listing). + addOptionsGroup(QByteArrayLiteral("XList"), + {opts.generateMap}); +} + +void Mcs51LinkerSettingsGroup::buildDefinePage( + const ProductData &qbsProduct) +{ + const DefinePageOptions opts(qbsProduct); + // Add 'XDefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("XDefines"), + opts.defineSymbols); +} + +void Mcs51LinkerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'SuppressAllWarn' item (Suppress all warnings). + addOptionsGroup(QByteArrayLiteral("SuppressAllWarn"), + {opts.suppressAllWarnings}); +} + +void Mcs51LinkerSettingsGroup::buildExtraOptionsPage( + const ProductData &qbsProduct) +{ + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + for (const QString &flag : flags) { + if (flag.startsWith(QLatin1String("-Z"))) + m_extraOptions.push_back(flag); + } + + if (!m_extraOptions.isEmpty()) { + // Add 'Linker Extra Options Check' (Use command line options). + addOptionsGroup(QByteArrayLiteral("Linker Extra Options Check"), + {1}); + // Add 'Linker Extra Options Edit' item (Command line options). + addOptionsGroup(QByteArrayLiteral("Linker Extra Options Edit"), + m_extraOptions); + } +} + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/mcs51/mcs51linkersettingsgroup_v10.h b/src/plugins/generator/iarew/archs/mcs51/mcs51linkersettingsgroup_v10.h new file mode 100644 index 000000000..fec80e5e6 --- /dev/null +++ b/src/plugins/generator/iarew/archs/mcs51/mcs51linkersettingsgroup_v10.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMCS51LINKERSETTINGSGROUP_V10_H +#define QBS_IAREWMCS51LINKERSETTINGSGROUP_V10_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace mcs51 { +namespace v10 { + +class Mcs51LinkerSettingsGroupPrivate; + +class Mcs51LinkerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Mcs51LinkerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildConfigPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildOutputPage(const ProductData &qbsProduct); + void buildListPage(const ProductData &qbsProduct); + void buildDefinePage(const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); + void buildExtraOptionsPage(const ProductData &qbsProduct); + + QVariantList m_extraOptions; +}; + +} // namespace v10 +} // namespace mcs51 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMCS51LINKERSETTINGSGROUP_V10_H diff --git a/src/plugins/generator/iarew/archs/msp430/msp430archiversettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/msp430/msp430archiversettingsgroup_v7.cpp new file mode 100644 index 000000000..1258412d8 --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430archiversettingsgroup_v7.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** 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 "msp430archiversettingsgroup_v7.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +constexpr int kArchiverArchiveVersion = 4; +constexpr int kArchiverDataVersion = 0; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + outputFile = QLatin1String("$PROJ_DIR$/") + + gen::utils::targetBinaryPath(baseDirectory, qbsProduct); + } + + QString outputFile; +}; + +} // namespace + +//Msp430ArchiverSettingsGroup + +Msp430ArchiverSettingsGroup::Msp430ArchiverSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("XAR")); + setArchiveVersion(kArchiverArchiveVersion); + setDataVersion(kArchiverDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + buildOutputPage(buildRootDirectory, qbsProduct); +} + +void Msp430ArchiverSettingsGroup::buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(baseDirectory, qbsProduct); + // Add 'XAROutOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("XAROutOverride"), + {1}); + // Add 'OutputFile' item (Output filename). + addOptionsGroup(QByteArrayLiteral("OutputFile"), + {opts.outputFile}); +} + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/msp430/msp430archiversettingsgroup_v7.h b/src/plugins/generator/iarew/archs/msp430/msp430archiversettingsgroup_v7.h new file mode 100644 index 000000000..9da8d3445 --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430archiversettingsgroup_v7.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMSP430ARCHIVERSETTINGSGROUP_V7_H +#define QBS_IAREWMSP430ARCHIVERSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +class Msp430ArchiverSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Msp430ArchiverSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct); +}; + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMSP430ARCHIVERSETTINGSGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/msp430/msp430assemblersettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/msp430/msp430assemblersettingsgroup_v7.cpp new file mode 100644 index 000000000..51108e63c --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430assemblersettingsgroup_v7.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** 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 "msp430assemblersettingsgroup_v7.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +constexpr int kAssemblerArchiveVersion = 5; +constexpr int kAssemblerDataVersion = 14; + +namespace { + +// Language page options. + +struct LanguagePageOptions final +{ + enum MacroQuoteCharacter { + AngleBracketsQuote, + RoundBracketsQuote, + SquareBracketsQuote, + FigureBracketsQuote + }; + + explicit LanguagePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("assemblerFlags")}); + enableSymbolsCaseSensitive = flags.contains( + QLatin1String("-s+")); + enableMultibyteSupport = flags.contains( + QLatin1String("-n")); + + if (flags.contains(QLatin1String("-M<>"))) + macroQuoteCharacter = LanguagePageOptions::AngleBracketsQuote; + else if (flags.contains(QLatin1String("-M()"))) + macroQuoteCharacter = LanguagePageOptions::RoundBracketsQuote; + else if (flags.contains(QLatin1String("-M[]"))) + macroQuoteCharacter = LanguagePageOptions::SquareBracketsQuote; + else if (flags.contains(QLatin1String("-M{}"))) + macroQuoteCharacter = LanguagePageOptions::FigureBracketsQuote; + } + + int enableSymbolsCaseSensitive = 1; + int enableMultibyteSupport = 0; + + MacroQuoteCharacter macroQuoteCharacter = AngleBracketsQuote; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + debugInfo = gen::utils::debugInformation(qbsProduct); + } + + int debugInfo = 0; +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + for (const auto &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString warningLevel = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("warningLevel")); + if (warningLevel == QLatin1String("all")) { + enableWarnings = 0; + enableAllWarnings = 0; + } else if (warningLevel == QLatin1String("none")) { + enableWarnings = 1; + enableAllWarnings = 0; + } else { + enableWarnings = 0; + enableAllWarnings = 1; + } + } + + int enableWarnings = 0; + int enableAllWarnings = 0; +}; + +} // namespace + +//Msp430AssemblerSettingsGroup + +Msp430AssemblerSettingsGroup::Msp430AssemblerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("A430")); + setArchiveVersion(kAssemblerArchiveVersion); + setDataVersion(kAssemblerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildLanguagePage(qbsProduct); + buildOutputPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); +} + +void Msp430AssemblerSettingsGroup::buildLanguagePage( + const ProductData &qbsProduct) +{ + const LanguagePageOptions opts(qbsProduct); + // Add 'ACaseSensitivity' item (User symbols are case sensitive). + addOptionsGroup(QByteArrayLiteral("ACaseSensitivity"), + {opts.enableSymbolsCaseSensitive}); + // Add 'AMultibyteSupport' item (Enable multibyte support). + addOptionsGroup(QByteArrayLiteral("AMultibyteSupport"), + {opts.enableMultibyteSupport}); + // Add 'MacroChars' item (Macro quote characters: ()/[]/{}/<>). + addOptionsGroup(QByteArrayLiteral("MacroChars"), + {opts.macroQuoteCharacter}); +} + +void Msp430AssemblerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'ADebug' item (Generate debug information). + addOptionsGroup(QByteArrayLiteral("ADebug"), + {opts.debugInfo}); +} + +void Msp430AssemblerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'ADefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("ADefines"), + opts.defineSymbols); + // Add 'AUserIncludes' item (Additional include directories). + addOptionsGroup(QByteArrayLiteral("AUserIncludes"), + opts.includePaths); +} + +void Msp430AssemblerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'AWarnEnable' item (Enable/disable warnings). + addOptionsGroup(QByteArrayLiteral("AWarnEnable"), + {opts.enableWarnings}); + // Add 'AWarnWhat' item (Enable/disable all warnings). + addOptionsGroup(QByteArrayLiteral("AWarnWhat"), + {opts.enableAllWarnings}); +} + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/msp430/msp430assemblersettingsgroup_v7.h b/src/plugins/generator/iarew/archs/msp430/msp430assemblersettingsgroup_v7.h new file mode 100644 index 000000000..97a59f4cd --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430assemblersettingsgroup_v7.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMSP430ASSEMBLERSETTINGSGROUP_V7_H +#define QBS_IAREWMSP430ASSEMBLERSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +class Msp430AssemblerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Msp430AssemblerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildLanguagePage(const ProductData &qbsProduct); + void buildOutputPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); +}; + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMSP430ASSEMBLERSETTINGSGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/msp430/msp430buildconfigurationgroup_v7.cpp b/src/plugins/generator/iarew/archs/msp430/msp430buildconfigurationgroup_v7.cpp new file mode 100644 index 000000000..bd80cdd7f --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430buildconfigurationgroup_v7.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 "msp430archiversettingsgroup_v7.h" +#include "msp430assemblersettingsgroup_v7.h" +#include "msp430buildconfigurationgroup_v7.h" +#include "msp430compilersettingsgroup_v7.h" +#include "msp430generalsettingsgroup_v7.h" +#include "msp430linkersettingsgroup_v7.h" + +#include "../../iarewtoolchainpropertygroup.h" +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +Msp430BuildConfigurationGroup::Msp430BuildConfigurationGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) + : gen::xml::PropertyGroup("configuration") +{ + // Append configuration name item. + const QString cfgName = gen::utils::buildConfigurationName(qbsProject); + appendProperty("name", cfgName); + + // Apend toolchain name group item. + appendChild<IarewToolchainPropertyGroup>("MSP430"); + + // Append debug info item. + const int debugBuild = gen::utils::debugInformation(qbsProduct); + appendProperty("debug", debugBuild); + + // Append settings group items. + appendChild<Msp430ArchiverSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Msp430AssemblerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Msp430CompilerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Msp430GeneralSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Msp430LinkerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); +} + +bool Msp430BuildConfigurationGroupFactory::canCreate( + gen::utils::Architecture arch, + const Version &version) const +{ + return arch == gen::utils::Architecture::Msp430 + && version.majorVersion() == 7; +} + +std::unique_ptr<gen::xml::PropertyGroup> +Msp430BuildConfigurationGroupFactory::create( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const +{ + const auto group = new Msp430BuildConfigurationGroup( + qbsProject, qbsProduct, qbsProductDeps); + return std::unique_ptr<Msp430BuildConfigurationGroup>(group); +} + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/msp430/msp430buildconfigurationgroup_v7.h b/src/plugins/generator/iarew/archs/msp430/msp430buildconfigurationgroup_v7.h new file mode 100644 index 000000000..ba0404c0b --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430buildconfigurationgroup_v7.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMSP430BUILDCONFIGURATIONGROUP_V7_H +#define QBS_IAREWMSP430BUILDCONFIGURATIONGROUP_V7_H + +#include <generators/generatorutils.h> +#include <generators/xmlpropertygroup.h> + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +class Msp430BuildConfigurationGroup final + : public gen::xml::PropertyGroup +{ +private: + explicit Msp430BuildConfigurationGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + + friend class Msp430BuildConfigurationGroupFactory; +}; + +class Msp430BuildConfigurationGroupFactory final + : public gen::xml::PropertyGroupFactory +{ +public: + bool canCreate(gen::utils::Architecture arch, + const Version &version) const final; + + std::unique_ptr<gen::xml::PropertyGroup> create( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const final; +}; + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMSP430BUILDCONFIGURATIONGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/msp430/msp430compilersettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/msp430/msp430compilersettingsgroup_v7.cpp new file mode 100644 index 000000000..5728578b9 --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430compilersettingsgroup_v7.cpp @@ -0,0 +1,486 @@ +/**************************************************************************** +** +** 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 "msp430compilersettingsgroup_v7.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +constexpr int kCompilerArchiveVersion = 4; +constexpr int kCompilerDataVersion = 38; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + debugInfo = gen::utils::debugInformation(qbsProduct); + } + + int debugInfo = 0; +}; + +// Language one page options. + +struct LanguageOnePageOptions final +{ + enum LanguageExtension { + CLanguageExtension, + CxxLanguageExtension, + AutoLanguageExtension + }; + + enum CLanguageDialect { + C89LanguageDialect, + C99LanguageDialect + }; + + enum CxxLanguageDialect { + EmbeddedCPlusPlus, + ExtendedEmbeddedCPlusPlus + }; + + enum LanguageConformance { + AllowIarExtension, + RelaxedStandard, + StrictStandard + }; + + explicit LanguageOnePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + // File extension based by default. + languageExtension = LanguageOnePageOptions::AutoLanguageExtension; + // C language dialect. + const QStringList cLanguageVersion = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("cLanguageVersion")}); + if (cLanguageVersion.contains(QLatin1String("c89"))) + cLanguageDialect = LanguageOnePageOptions::C89LanguageDialect; + else if (cLanguageVersion.contains(QLatin1String("c99"))) + cLanguageDialect = LanguageOnePageOptions::C99LanguageDialect; + // C++ language dialect. + if (flags.contains(QLatin1String("--ec++"))) + cxxLanguageDialect = LanguageOnePageOptions::EmbeddedCPlusPlus; + else if (flags.contains(QLatin1String("--eec++"))) + cxxLanguageDialect = LanguageOnePageOptions::ExtendedEmbeddedCPlusPlus; + // Language conformance. + if (flags.contains(QLatin1String("-e"))) + languageConformance = LanguageOnePageOptions::AllowIarExtension; + else if (flags.contains(QLatin1String("--strict"))) + languageConformance = LanguageOnePageOptions::StrictStandard; + else + languageConformance = LanguageOnePageOptions::RelaxedStandard; + + allowVla = flags.contains(QLatin1String("--vla")); + useCppInlineSemantics = flags.contains( + QLatin1String("--use_c++_inline")); + requirePrototypes = flags.contains( + QLatin1String("--require_prototypes")); + destroyStaticObjects = !flags.contains( + QLatin1String("--no_static_destruction")); + } + + LanguageExtension languageExtension = AutoLanguageExtension; + CLanguageDialect cLanguageDialect = C99LanguageDialect; + CxxLanguageDialect cxxLanguageDialect = EmbeddedCPlusPlus; + LanguageConformance languageConformance = AllowIarExtension; + int allowVla = 0; + int useCppInlineSemantics = 0; + int requirePrototypes = 0; + int destroyStaticObjects = 0; +}; + +// Language two page options. + +struct LanguageTwoPageOptions final +{ + enum PlainCharacter { + SignedCharacter, + UnsignedCharacter + }; + + enum FloatingPointSemantic { + StrictSemantic, + RelaxedSemantic + }; + + explicit LanguageTwoPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + plainCharacter = flags.contains(QLatin1String("--char_is_signed")) + ? LanguageTwoPageOptions::SignedCharacter + : LanguageTwoPageOptions::UnsignedCharacter; + floatingPointSemantic = flags.contains(QLatin1String("--relaxed_fp")) + ? LanguageTwoPageOptions::RelaxedSemantic + : LanguageTwoPageOptions::StrictSemantic; + enableMultibyteSupport = flags.contains( + QLatin1String("--enable_multibytes")); + guardCalls = flags.contains( + QLatin1String("--guard_calls")); + } + + PlainCharacter plainCharacter = UnsignedCharacter; + FloatingPointSemantic floatingPointSemantic = StrictSemantic; + int enableMultibyteSupport = 0; + int guardCalls = 0; +}; + +// Code page options. + +struct CodePageOptions final +{ + enum Utilization { + UtilizationNormalUse, + UtilizationRegVarVariables, + UtilizationNotUsed + }; + + explicit CodePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + // Detect R4 utilization. + if (flags.contains(QLatin1String("--lock_r4"))) + r4utilization = UtilizationNotUsed; + else if (flags.contains(QLatin1String("--regvar_r4"))) + r4utilization = UtilizationRegVarVariables; + // Detect R5 utilization. + if (flags.contains(QLatin1String("--lock_r5"))) + r5utilization = UtilizationNotUsed; + else if (flags.contains(QLatin1String("--regvar_r54"))) + r5utilization = UtilizationRegVarVariables; + // Detect reduce stack usage. + reduceStackUsage = flags.contains( + QLatin1String("--reduce_stack_usage")); + // Detect 20-bit context save on interrupt. + save20BitContextOnInterrupt = flags.contains( + QLatin1String("--save_reg20")); + } + + Utilization r4utilization = UtilizationNormalUse; + Utilization r5utilization = UtilizationNormalUse; + int reduceStackUsage = 0; + int save20BitContextOnInterrupt = 0; +}; + +// Optimizations page options. + +struct OptimizationsPageOptions final +{ + // Optimizations level radio-buttons with + // combo-box on "level" widget. + enum Strategy { + StrategyBalanced, + StrategySize, + StrategySpeed + }; + + enum Level { + LevelNone, + LevelLow, + LevelMedium, + LevelHigh + }; + + enum LevelSlave { + LevelSlave0, + LevelSlave1, + LevelSlave2, + LevelSlave3 + }; + + explicit OptimizationsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString optimization = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("optimization")); + if (optimization == QLatin1String("none")) { + optimizationStrategy = OptimizationsPageOptions::StrategyBalanced; + optimizationLevel = OptimizationsPageOptions::LevelNone; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave0; + } else if (optimization == QLatin1String("fast")) { + optimizationStrategy = OptimizationsPageOptions::StrategySpeed; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } else if (optimization == QLatin1String("small")) { + optimizationStrategy = OptimizationsPageOptions::StrategySize; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } + + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + + disableSizeConstraints = flags.contains( + QLatin1String("--no_size_constraints")); + + enableCommonSubexpressionElimination = !flags.contains( + QLatin1String("--no_cse")); + enableLoopUnroll = !flags.contains(QLatin1String("--no_unroll")); + enableFunctionInlining = !flags.contains(QLatin1String("--no_inline")); + enableCodeMotion = !flags.contains(QLatin1String("--no_code_motion")); + enableTypeBasedAliasAnalysis = !flags.contains( + QLatin1String("--no_tbaa")); + } + + Strategy optimizationStrategy = StrategyBalanced; + Level optimizationLevel = LevelNone; + LevelSlave optimizationLevelSlave = LevelSlave0; + // Separate "no size constraints" checkbox. + int disableSizeConstraints = 0; + + // Five bit-field flags on "enabled transformations" widget. + int enableCommonSubexpressionElimination = 0; // Common sub-expression elimination. + int enableLoopUnroll = 0; // Loop unrolling. + int enableFunctionInlining = 0; // Function inlining. + int enableCodeMotion = 0; // Code motion. + int enableTypeBasedAliasAnalysis = 0; // Type based alias analysis. +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + for (const QString &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + warningsAsErrors = gen::utils::cppIntegerModuleProperty( + qbsProps, QStringLiteral("treatWarningsAsErrors")); + } + + int warningsAsErrors = 0; +}; + +} // namespace + +//Msp430CompilerSettingsGroup + +Msp430CompilerSettingsGroup::Msp430CompilerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("ICC430")); + setArchiveVersion(kCompilerArchiveVersion); + setDataVersion(kCompilerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildOutputPage(qbsProduct); + buildLanguageOnePage(qbsProduct); + buildLanguageTwoPage(qbsProduct); + buildOptimizationsPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); +} + +void Msp430CompilerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'CCDebugInfo' item (Generate debug info). + addOptionsGroup(QByteArrayLiteral("CCDebugInfo"), + {opts.debugInfo}); +} + +void Msp430CompilerSettingsGroup::buildLanguageOnePage( + const ProductData &qbsProduct) +{ + const LanguageOnePageOptions opts(qbsProduct); + // Add 'IccLang' item with 'auto-extension based' + // value (Language: C/C++/Auto). + addOptionsGroup(QByteArrayLiteral("IccLang"), + {opts.languageExtension}); + // Add 'IccCDialect' item (C dialect: c89/99/11). + addOptionsGroup(QByteArrayLiteral("IccCDialect"), + {opts.cLanguageDialect}); + // Add 'IccCppDialect' item (C++ dialect: embedded/extended). + addOptionsGroup(QByteArrayLiteral("IccCppDialect"), + {opts.cxxLanguageDialect}); + // Add 'CCExt' item + // (Language conformance: IAR/relaxed/strict). + addOptionsGroup(QByteArrayLiteral("CCExt"), + {opts.languageConformance}); + // Add 'IccAllowVLA' item (Allow VLA). + addOptionsGroup(QByteArrayLiteral("IccAllowVLA"), + {opts.allowVla}); + // Add 'IccCppInlineSemantics' item (C++ inline semantics). + addOptionsGroup(QByteArrayLiteral("IccCppInlineSemantics"), + {opts.useCppInlineSemantics}); + // Add 'IccRequirePrototypes' item (Require prototypes). + addOptionsGroup(QByteArrayLiteral("CCRequirePrototypes"), + {opts.requirePrototypes}); + // Add 'IccStaticDestr' item (Destroy static objects). + addOptionsGroup(QByteArrayLiteral("IccStaticDestr"), + {opts.destroyStaticObjects}); +} + +void Msp430CompilerSettingsGroup::buildLanguageTwoPage( + const ProductData &qbsProduct) +{ + const LanguageTwoPageOptions opts(qbsProduct); + // Add 'IccCharIs' item (Plain char is: signed/unsigned). + addOptionsGroup(QByteArrayLiteral("CCCharIs"), + {opts.plainCharacter}); + // Add 'IccFloatSemantics' item (Floatic-point + // semantics: strict/relaxed conformance). + addOptionsGroup(QByteArrayLiteral("IccFloatSemantics"), + {opts.floatingPointSemantic}); + // Add 'IccMultibyteSupport' item (Enable multibyte support). + addOptionsGroup(QByteArrayLiteral("CCMultibyteSupport"), + {opts.enableMultibyteSupport}); + // Add 'CCGuardCalls' and 'OCGuardCallsSlave' item (Guard calls). + addOptionsGroup(QByteArrayLiteral("CCGuardCalls"), + {opts.guardCalls}); +} + +void Msp430CompilerSettingsGroup::buildCodePage( + const ProductData &qbsProduct) +{ + const CodePageOptions opts(qbsProduct); + // Add 'OCCR4Utilize' item + // (R4 utilization: normal/regvar/disabled). + addOptionsGroup(QByteArrayLiteral("OCCR4Utilize"), + {opts.r4utilization}); + // Add 'OCCR5Utilize' item + // (R5 utilization: normal/regvar/disabled). + addOptionsGroup(QByteArrayLiteral("OCCR5Utilize"), + {opts.r5utilization}); + // Add 'ReduceStack' item + // (Reduce stack usage). + addOptionsGroup(QByteArrayLiteral("ReduceStack"), + {opts.reduceStackUsage}); + // Add 'Save20bit' item + // (20-bit context save on interrupt). + addOptionsGroup(QByteArrayLiteral("Save20bit"), + {opts.save20BitContextOnInterrupt}); +} + +void Msp430CompilerSettingsGroup::buildOptimizationsPage( + const ProductData &qbsProduct) +{ + const OptimizationsPageOptions opts(qbsProduct); + // Add 'CCOptStrategy', 'CCOptLevel' and + // 'CCOptLevelSlave' items (Level). + addOptionsGroup(QByteArrayLiteral("CCOptStrategy"), + {opts.optimizationStrategy}); + addOptionsGroup(QByteArrayLiteral("CCOptLevel"), + {opts.optimizationLevel}); + addOptionsGroup(QByteArrayLiteral("CCOptLevelSlave"), + {opts.optimizationLevelSlave}); + + // Add 'CCOptimizationNoSizeConstraints' item (no size constraints). + addOptionsGroup(QByteArrayLiteral("CCOptimizationNoSizeConstraints"), + {opts.disableSizeConstraints}); + + // Add 'CCAllowList' item + // (Enabled transformations: 5 check boxes). + const QString bitflags = QStringLiteral("%1%2%3%4%5%6") + .arg(opts.enableCommonSubexpressionElimination) + .arg(opts.enableLoopUnroll) + .arg(opts.enableFunctionInlining) + .arg(opts.enableCodeMotion) + .arg(opts.enableTypeBasedAliasAnalysis); + addOptionsGroup(QByteArrayLiteral("CCAllowList"), + {bitflags}); +} + +void Msp430CompilerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'CCDefines' item (Defines symbols). + addOptionsGroup(QByteArrayLiteral("CCDefines"), + opts.defineSymbols); + // Add 'newCCIncludePaths' item + // (Additional include directories). + addOptionsGroup(QByteArrayLiteral("newCCIncludePaths"), + opts.includePaths); +} + +void Msp430CompilerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'CCDiagWarnAreErr' item (Treat all warnings as errors). + addOptionsGroup(QByteArrayLiteral("CCDiagWarnAreErr"), + {opts.warningsAsErrors}); +} + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/msp430/msp430compilersettingsgroup_v7.h b/src/plugins/generator/iarew/archs/msp430/msp430compilersettingsgroup_v7.h new file mode 100644 index 000000000..498100881 --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430compilersettingsgroup_v7.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMSP430COMPILERSETTINGSGROUP_V7_H +#define QBS_IAREWMSP430COMPILERSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +class Msp430CompilerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Msp430CompilerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const ProductData &qbsProduct); + void buildLanguageOnePage(const ProductData &qbsProduct); + void buildLanguageTwoPage(const ProductData &qbsProduct); + void buildCodePage(const ProductData &qbsProduct); + void buildOptimizationsPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); +}; + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMSP430COMPILERSETTINGSGROUP_V7_H 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 diff --git a/src/plugins/generator/iarew/archs/msp430/msp430generalsettingsgroup_v7.h b/src/plugins/generator/iarew/archs/msp430/msp430generalsettingsgroup_v7.h new file mode 100644 index 000000000..35e9e7b32 --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430generalsettingsgroup_v7.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMSP430GENERALSETTINGSGROUP_V7_H +#define QBS_IAREWMSP430GENERALSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +class Msp430GeneralSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Msp430GeneralSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildTargetPage(const ProductData &qbsProduct); + void buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildLibraryConfigPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildLibraryOptionsPage(const ProductData &qbsProduct); + void buildStackHeapPage(const ProductData &qbsProduct); +}; + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMSP430GENERALSETTINGSGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/msp430/msp430linkersettingsgroup_v7.cpp b/src/plugins/generator/iarew/archs/msp430/msp430linkersettingsgroup_v7.cpp new file mode 100644 index 000000000..b85edbb83 --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430linkersettingsgroup_v7.cpp @@ -0,0 +1,290 @@ +/**************************************************************************** +** +** 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 "msp430linkersettingsgroup_v7.h" + +#include "../../iarewutils.h" + +#include <QtCore/qdir.h> + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +constexpr int kLinkerArchiveVersion = 4; +constexpr int kLinkerDataVersion = 30; + +namespace { + +// Config page options. + +struct ConfigPageOptions final +{ + explicit ConfigPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + 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)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + configFilePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + configFilePaths.push_back(path); + } + } + } + + // Enumerate all product linker config files + // (which are set trough '-f' option). + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + const QVariantList configPathValues = IarewUtils::flagValues( + flags, QStringLiteral("-f")); + for (const QVariant &configPathValue : configPathValues) { + const QString fullConfigPath = configPathValue.toString(); + if (fullConfigPath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } + } + + // Library search paths. + librarySearchPaths = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("libraryPaths")}); + + // Entry point. + entryPoint = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("entryPoint")); + } + + QVariantList configFilePaths; + QVariantList librarySearchPaths; + QString entryPoint; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + outputFile = gen::utils::targetBinary(qbsProduct); + } + + QString outputFile; +}; + +// List page options. + +struct ListPageOptions final +{ + enum ListingAction { + NoListing, + GenerateListing + }; + + explicit ListPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + generateMap = gen::utils::cppBooleanModuleProperty( + qbsProps, QStringLiteral("generateLinkerMapFile")) + ? ListPageOptions::GenerateListing + : ListPageOptions::NoListing; + } + + ListingAction generateMap = NoListing; +}; + +// Define page options. + +struct DefinePageOptions final +{ + explicit DefinePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + // Enumerate all linker defines. + for (const QString &flag : flags) { + if (!flag.startsWith(QLatin1String("-D"))) + continue; + const QString symbol = flag.mid(2); + // Ignore system-defined macroses, because its already + // handled in "General Options" page. + if (symbol.startsWith(QLatin1Char('?')) + || symbol.startsWith(QLatin1Char('_')) + ) { + continue; + } + defineSymbols.push_back(symbol); + } + } + + QVariantList defineSymbols; +}; + +} // namespace + +//Msp430LinkerSettingsGroup + +Msp430LinkerSettingsGroup::Msp430LinkerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + setName(QByteArrayLiteral("XLINK")); + setArchiveVersion(kLinkerArchiveVersion); + setDataVersion(kLinkerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildConfigPage(buildRootDirectory, qbsProduct); + buildOutputPage(qbsProduct); + buildListPage(qbsProduct); + buildDefinePage(qbsProduct); + + // Should be called as latest stage! + buildExtraOptionsPage(qbsProduct); +} + +void Msp430LinkerSettingsGroup::buildConfigPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + ConfigPageOptions opts(baseDirectory, qbsProduct); + + if (opts.configFilePaths.count() > 0) { + // Note: IAR IDE does not allow to specify a multiple config files, + // although the IAR linker support it. So, we use followig 'trick': + // we take a first config file and to add it as usual to required items; + // and then an other remainders we forward to the "Extra options page". + const QVariant configPath = opts.configFilePaths.takeFirst(); + // Add 'XclOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("XclOverride"), + {1}); + // Add 'XclFile' item (Linke configuration file). + addOptionsGroup(QByteArrayLiteral("XclFile"), + {configPath}); + + // Add remainder configuration files to the "Extra options page". + if (!opts.configFilePaths.isEmpty()) { + for (QVariant &configPath : opts.configFilePaths) + configPath = QLatin1String("-f ") + configPath.toString(); + + m_extraOptions << opts.configFilePaths; + } + } + + // Add 'xcOverrideProgramEntryLabel' item + // (Override default program entry). + addOptionsGroup(QByteArrayLiteral("xcOverrideProgramEntryLabel"), + {1}); + // Add 'xcProgramEntryLabel' item (Entry point name). + addOptionsGroup(QByteArrayLiteral("xcProgramEntryLabel"), + {opts.entryPoint}); + + // Add 'XIncludes' item (Entry point name). + addOptionsGroup(QByteArrayLiteral("XIncludes"), + {opts.librarySearchPaths}); +} + +void Msp430LinkerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + + // Add 'XOutOverride' item (Output file name). + addOptionsGroup(QByteArrayLiteral("XOutOverride"), + {1}); + // Add 'OutputFile' item (Output file name). + addOptionsGroup(QByteArrayLiteral("OutputFile"), + {opts.outputFile}); +} + +void Msp430LinkerSettingsGroup::buildListPage( + const ProductData &qbsProduct) +{ + const ListPageOptions opts(qbsProduct); + // Add 'XList' item (Generate linker map file). + addOptionsGroup(QByteArrayLiteral("XList"), + {opts.generateMap}); +} + +void Msp430LinkerSettingsGroup::buildDefinePage( + const ProductData &qbsProduct) +{ + const DefinePageOptions opts(qbsProduct); + // Add 'XDefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("XDefines"), + opts.defineSymbols); +} + +void Msp430LinkerSettingsGroup::buildExtraOptionsPage( + const ProductData &qbsProduct) +{ + Q_UNUSED(qbsProduct) + + if (m_extraOptions.isEmpty()) + return; + + // Add 'XExtraOptionsCheck' (Use command line options). + addOptionsGroup(QByteArrayLiteral("XExtraOptionsCheck"), + {1}); + // Add 'XExtraOptions' item (Command line options). + addOptionsGroup(QByteArrayLiteral("XExtraOptions"), + m_extraOptions); +} + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/msp430/msp430linkersettingsgroup_v7.h b/src/plugins/generator/iarew/archs/msp430/msp430linkersettingsgroup_v7.h new file mode 100644 index 000000000..2b6f11514 --- /dev/null +++ b/src/plugins/generator/iarew/archs/msp430/msp430linkersettingsgroup_v7.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWMSP430LINKERSETTINGSGROUP_V7_H +#define QBS_IAREWMSP430LINKERSETTINGSGROUP_V7_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace msp430 { +namespace v7 { + +class Msp430LinkerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Msp430LinkerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildConfigPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildOutputPage(const ProductData &qbsProduct); + void buildListPage(const ProductData &qbsProduct); + void buildDefinePage(const ProductData &qbsProduct); + void buildExtraOptionsPage(const ProductData &qbsProduct); + + QVariantList m_extraOptions; +}; + +} // namespace v7 +} // namespace msp430 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWMSP430LINKERSETTINGSGROUP_V7_H diff --git a/src/plugins/generator/iarew/archs/stm8/stm8archiversettingsgroup_v3.cpp b/src/plugins/generator/iarew/archs/stm8/stm8archiversettingsgroup_v3.cpp new file mode 100644 index 000000000..b08b70bc5 --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8archiversettingsgroup_v3.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** 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 "stm8archiversettingsgroup_v3.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +constexpr int kArchiverArchiveVersion = 3; +constexpr int kArchiverDataVersion = 0; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + outputFile = QLatin1String("$PROJ_DIR$/") + + gen::utils::targetBinaryPath(baseDirectory, qbsProduct); + } + + QString outputFile; +}; + +} // namespace + +// Stm8ArchiverSettingsGroup + +Stm8ArchiverSettingsGroup::Stm8ArchiverSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("IARCHIVE")); + setArchiveVersion(kArchiverArchiveVersion); + setDataVersion(kArchiverDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + buildOutputPage(buildRootDirectory, qbsProduct); +} + +void Stm8ArchiverSettingsGroup::buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(baseDirectory, qbsProduct); + // Add 'IarchiveOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("IarchiveOverride"), + {1}); + // Add 'IarchiveOutput' item (Output filename). + addOptionsGroup(QByteArrayLiteral("IarchiveOutput"), + {opts.outputFile}); +} + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/stm8/stm8archiversettingsgroup_v3.h b/src/plugins/generator/iarew/archs/stm8/stm8archiversettingsgroup_v3.h new file mode 100644 index 000000000..754add3cb --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8archiversettingsgroup_v3.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWSTM8ARCHIVERSETTINGSGROUP_V3_H +#define QBS_IAREWSTM8ARCHIVERSETTINGSGROUP_V3_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +class Stm8ArchiverSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Stm8ArchiverSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct); +}; + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWSTM8ARCHIVERSETTINGSGROUP_V3_H diff --git a/src/plugins/generator/iarew/archs/stm8/stm8assemblersettingsgroup_v3.cpp b/src/plugins/generator/iarew/archs/stm8/stm8assemblersettingsgroup_v3.cpp new file mode 100644 index 000000000..396ee7db2 --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8assemblersettingsgroup_v3.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** 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 "stm8assemblersettingsgroup_v3.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +constexpr int kAssemblerArchiveVersion = 3; +constexpr int kAssemblerDataVersion = 2; + +namespace { + +// Language page options. + +struct LanguagePageOptions final +{ + enum MacroQuoteCharacter { + AngleBracketsQuote, + RoundBracketsQuote, + SquareBracketsQuote, + FigureBracketsQuote + }; + + explicit LanguagePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("assemblerFlags")}); + enableSymbolsCaseSensitive = !flags.contains( + QLatin1String("--case_insensitive")); + enableMultibyteSupport = flags.contains( + QLatin1String("--enable_multibytes")); + allowFirstColumnMnemonics = flags.contains( + QLatin1String("--mnem_first")); + allowFirstColumnDirectives = flags.contains( + QLatin1String("--dir_first")); + + if (flags.contains(QLatin1String("-M<>"))) + macroQuoteCharacter = LanguagePageOptions::AngleBracketsQuote; + else if (flags.contains(QLatin1String("-M()"))) + macroQuoteCharacter = LanguagePageOptions::RoundBracketsQuote; + else if (flags.contains(QLatin1String("-M[]"))) + macroQuoteCharacter = LanguagePageOptions::SquareBracketsQuote; + else if (flags.contains(QLatin1String("-M{}"))) + macroQuoteCharacter = LanguagePageOptions::FigureBracketsQuote; + } + + int enableSymbolsCaseSensitive = 1; + int enableMultibyteSupport = 0; + int allowFirstColumnMnemonics = 0; + int allowFirstColumnDirectives = 0; + + MacroQuoteCharacter macroQuoteCharacter = AngleBracketsQuote; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + debugInfo = gen::utils::debugInformation(qbsProduct); + } + + int debugInfo = 0; +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + for (const auto &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + warningsAsErrors = gen::utils::cppIntegerModuleProperty( + qbsProps, QStringLiteral("treatWarningsAsErrors")); + } + + int warningsAsErrors = 0; +}; + +} // namespace + +// Stm8AssemblerSettingsGroup + +Stm8AssemblerSettingsGroup::Stm8AssemblerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("ASTM8")); + setArchiveVersion(kAssemblerArchiveVersion); + setDataVersion(kAssemblerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildLanguagePage(qbsProduct); + buildOutputPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); +} + +void Stm8AssemblerSettingsGroup::buildLanguagePage( + const ProductData &qbsProduct) +{ + const LanguagePageOptions opts(qbsProduct); + // Add 'AsmCaseSensitivity' item (User symbols are case sensitive). + addOptionsGroup(QByteArrayLiteral("AsmCaseSensitivity"), + {opts.enableSymbolsCaseSensitive}); + // Add 'AsmMultibyteSupport' item (Enable multibyte support). + addOptionsGroup(QByteArrayLiteral("AsmMultibyteSupport"), + {opts.enableMultibyteSupport}); + // Add 'AsmAllowMnemonics' item (Allow mnemonics in first column). + addOptionsGroup(QByteArrayLiteral("AsmAllowMnemonics"), + {opts.allowFirstColumnMnemonics}); + // Add 'AsmAllowDirectives' item (Allow directives in first column). + addOptionsGroup(QByteArrayLiteral("AsmAllowDirectives"), + {opts.allowFirstColumnDirectives}); + + // Add 'AsmMacroChars' item (Macro quote characters: ()/[]/{}/<>). + addOptionsGroup(QByteArrayLiteral("AsmMacroChars"), + {opts.macroQuoteCharacter}); +} + +void Stm8AssemblerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'AsmDebugInfo' item (Generate debug information). + addOptionsGroup(QByteArrayLiteral("AsmDebugInfo"), + {opts.debugInfo}); +} + +void Stm8AssemblerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'AsmDefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("AsmDefines"), + opts.defineSymbols); + // Add 'AsmIncludePath' item (Additional include directories). + addOptionsGroup(QByteArrayLiteral("AsmIncludePath"), + opts.includePaths); +} + +void Stm8AssemblerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'AsmDiagnosticsWarningsAreErrors' item. + // (Treat all warnings as errors). + addOptionsGroup(QByteArrayLiteral("AsmDiagnosticsWarningsAreErrors"), + {opts.warningsAsErrors}); +} + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/stm8/stm8assemblersettingsgroup_v3.h b/src/plugins/generator/iarew/archs/stm8/stm8assemblersettingsgroup_v3.h new file mode 100644 index 000000000..4d7d0485b --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8assemblersettingsgroup_v3.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWSTM8ASSEMBLERSETTINGSGROUP_V3_H +#define QBS_IAREWSTM8ASSEMBLERSETTINGSGROUP_V3_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +class Stm8AssemblerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Stm8AssemblerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildLanguagePage(const ProductData &qbsProduct); + void buildOutputPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); +}; + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWSTM8ASSEMBLERSETTINGSGROUP_V3_H diff --git a/src/plugins/generator/iarew/archs/stm8/stm8buildconfigurationgroup_v3.cpp b/src/plugins/generator/iarew/archs/stm8/stm8buildconfigurationgroup_v3.cpp new file mode 100644 index 000000000..06167f919 --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8buildconfigurationgroup_v3.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 "stm8archiversettingsgroup_v3.h" +#include "stm8assemblersettingsgroup_v3.h" +#include "stm8buildconfigurationgroup_v3.h" +#include "stm8compilersettingsgroup_v3.h" +#include "stm8generalsettingsgroup_v3.h" +#include "stm8linkersettingsgroup_v3.h" + +#include "../../iarewtoolchainpropertygroup.h" +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +Stm8BuildConfigurationGroup::Stm8BuildConfigurationGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) + : gen::xml::PropertyGroup("configuration") +{ + // Append configuration name item. + const QString cfgName = gen::utils::buildConfigurationName(qbsProject); + appendProperty("name", cfgName); + + // Apend toolchain name group item. + appendChild<IarewToolchainPropertyGroup>("STM8"); + + // Append debug info item. + const int debugBuild = gen::utils::debugInformation(qbsProduct); + appendProperty("debug", debugBuild); + + // Append settings group items. + appendChild<Stm8ArchiverSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Stm8AssemblerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Stm8CompilerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Stm8GeneralSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); + appendChild<Stm8LinkerSettingsGroup>( + qbsProject, qbsProduct, qbsProductDeps); +} + +bool Stm8BuildConfigurationGroupFactory::canCreate( + gen::utils::Architecture arch, + const Version &version) const +{ + return arch == gen::utils::Architecture::Stm8 + && version.majorVersion() == 3; +} + +std::unique_ptr<gen::xml::PropertyGroup> +Stm8BuildConfigurationGroupFactory::create( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const +{ + const auto group = new Stm8BuildConfigurationGroup( + qbsProject, qbsProduct, qbsProductDeps); + return std::unique_ptr<Stm8BuildConfigurationGroup>(group); +} + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/stm8/stm8buildconfigurationgroup_v3.h b/src/plugins/generator/iarew/archs/stm8/stm8buildconfigurationgroup_v3.h new file mode 100644 index 000000000..c47819fef --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8buildconfigurationgroup_v3.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWSTM8BUILDCONFIGURATIONGROUP_V3_H +#define QBS_IAREWSTM8BUILDCONFIGURATIONGROUP_V3_H + +#include <generators/generatorutils.h> +#include <generators/xmlpropertygroup.h> + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +class Stm8BuildConfigurationGroup final + : public gen::xml::PropertyGroup +{ +private: + explicit Stm8BuildConfigurationGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + + friend class Stm8BuildConfigurationGroupFactory; +}; + +class Stm8BuildConfigurationGroupFactory final + : public gen::xml::PropertyGroupFactory +{ +public: + bool canCreate(gen::utils::Architecture arch, + const Version &version) const final; + + std::unique_ptr<gen::xml::PropertyGroup> create( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) const final; +}; + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWSTM8BUILDCONFIGURATIONGROUP_V3_H diff --git a/src/plugins/generator/iarew/archs/stm8/stm8compilersettingsgroup_v3.cpp b/src/plugins/generator/iarew/archs/stm8/stm8compilersettingsgroup_v3.cpp new file mode 100644 index 000000000..912d94bd0 --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8compilersettingsgroup_v3.cpp @@ -0,0 +1,442 @@ +/**************************************************************************** +** +** 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 "stm8compilersettingsgroup_v3.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +constexpr int kCompilerArchiveVersion = 3; +constexpr int kCompilerDataVersion = 9; + +namespace { + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + debugInfo = gen::utils::debugInformation(qbsProduct); + } + + int debugInfo = 0; +}; + +// Language one page options. + +struct LanguageOnePageOptions final +{ + enum LanguageExtension { + CLanguageExtension, + CxxLanguageExtension, + AutoLanguageExtension + }; + + enum CLanguageDialect { + C89LanguageDialect, + C99LanguageDialect + }; + + enum CxxLanguageDialect { + EmbeddedCPlusPlus, + ExtendedEmbeddedCPlusPlus + }; + + enum LanguageConformance { + AllowIarExtension, + RelaxedStandard, + StrictStandard + }; + + explicit LanguageOnePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + // File extension based by default. + languageExtension = LanguageOnePageOptions::AutoLanguageExtension; + // C language dialect. + const QStringList cLanguageVersion = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("cLanguageVersion")}); + if (cLanguageVersion.contains(QLatin1String("c89"))) + cLanguageDialect = LanguageOnePageOptions::C89LanguageDialect; + else if (cLanguageVersion.contains(QLatin1String("c99"))) + cLanguageDialect = LanguageOnePageOptions::C99LanguageDialect; + // C++ language dialect. + if (flags.contains(QLatin1String("--ec++"))) + cxxLanguageDialect = LanguageOnePageOptions::EmbeddedCPlusPlus; + else if (flags.contains(QLatin1String("--eec++"))) + cxxLanguageDialect = LanguageOnePageOptions::ExtendedEmbeddedCPlusPlus; + // Language conformance. + if (flags.contains(QLatin1String("-e"))) + languageConformance = LanguageOnePageOptions::AllowIarExtension; + else if (flags.contains(QLatin1String("--strict"))) + languageConformance = LanguageOnePageOptions::StrictStandard; + else + languageConformance = LanguageOnePageOptions::RelaxedStandard; + + allowVla = flags.contains(QLatin1String("--vla")); + useCppInlineSemantics = flags.contains( + QLatin1String("--use_c++_inline")); + requirePrototypes = flags.contains( + QLatin1String("--require_prototypes")); + destroyStaticObjects = !flags.contains( + QLatin1String("--no_static_destruction")); + } + + LanguageExtension languageExtension = AutoLanguageExtension; + CLanguageDialect cLanguageDialect = C99LanguageDialect; + CxxLanguageDialect cxxLanguageDialect = EmbeddedCPlusPlus; + LanguageConformance languageConformance = AllowIarExtension; + int allowVla = 0; + int useCppInlineSemantics = 0; + int requirePrototypes = 0; + int destroyStaticObjects = 0; +}; + +// Language two page options. + +struct LanguageTwoPageOptions final +{ + enum PlainCharacter { + SignedCharacter, + UnsignedCharacter + }; + + enum FloatingPointSemantic { + StrictSemantic, + RelaxedSemantic + }; + + explicit LanguageTwoPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + plainCharacter = flags.contains(QLatin1String("--char_is_signed")) + ? LanguageTwoPageOptions::SignedCharacter + : LanguageTwoPageOptions::UnsignedCharacter; + floatingPointSemantic = flags.contains(QLatin1String("--relaxed_fp")) + ? LanguageTwoPageOptions::RelaxedSemantic + : LanguageTwoPageOptions::StrictSemantic; + enableMultibyteSupport = flags.contains( + QLatin1String("--enable_multibytes")); + } + + PlainCharacter plainCharacter = UnsignedCharacter; + FloatingPointSemantic floatingPointSemantic = StrictSemantic; + int enableMultibyteSupport = 0; +}; + +// Optimizations page options. + +struct OptimizationsPageOptions final +{ + // Optimizations level radio-buttons with + // combo-box on "level" widget. + enum Strategy { + StrategyBalanced, + StrategySize, + StrategySpeed + }; + + enum Level { + LevelNone, + LevelLow, + LevelMedium, + LevelHigh + }; + + enum LevelSlave { + LevelSlave0, + LevelSlave1, + LevelSlave2, + LevelSlave3 + }; + + enum VRegsNumber { + VRegs12, + VRegs16 + }; + + explicit OptimizationsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString optimization = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("optimization")); + if (optimization == QLatin1String("none")) { + optimizationStrategy = OptimizationsPageOptions::StrategyBalanced; + optimizationLevel = OptimizationsPageOptions::LevelNone; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave0; + } else if (optimization == QLatin1String("fast")) { + optimizationStrategy = OptimizationsPageOptions::StrategySpeed; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } else if (optimization == QLatin1String("small")) { + optimizationStrategy = OptimizationsPageOptions::StrategySize; + optimizationLevel = OptimizationsPageOptions::LevelHigh; + optimizationLevelSlave = OptimizationsPageOptions::LevelSlave3; + } + + const QStringList flags = IarewUtils::cppModuleCompilerFlags(qbsProps); + + disableSizeConstraints = flags.contains( + QLatin1String("--no_size_constraints")); + + enableCommonSubexpressionElimination = !flags.contains( + QLatin1String("--no_cse")); + enableLoopUnroll = !flags.contains(QLatin1String("--no_unroll")); + enableFunctionInlining = !flags.contains(QLatin1String("--no_inline")); + enableCodeMotion = !flags.contains(QLatin1String("--no_code_motion")); + enableTypeBasedAliasAnalysis = !flags.contains( + QLatin1String("--no_tbaa")); + enableCrossCall = !flags.contains(QLatin1String("--no_cross_call")); + + const auto vregsCount = IarewUtils::flagValue( + flags, QStringLiteral("--vregs")).toInt(); + if (vregsCount == 12) + vregsNumber = VRegs12; + else if (vregsCount == 16) + vregsNumber = VRegs16; + } + + Strategy optimizationStrategy = StrategyBalanced; + Level optimizationLevel = LevelNone; + LevelSlave optimizationLevelSlave = LevelSlave0; + // Separate "no size constraints" checkbox. + int disableSizeConstraints = 0; + + // Six bit-field flags on "enabled transformations" widget. + int enableCommonSubexpressionElimination = 0; // Common sub-expression elimination. + int enableLoopUnroll = 0; // Loop unrolling. + int enableFunctionInlining = 0; // Function inlining. + int enableCodeMotion = 0; // Code motion. + int enableTypeBasedAliasAnalysis = 0; // Type based alias analysis. + int enableCrossCall = 0; // Cross call. + + VRegsNumber vregsNumber = VRegs16; +}; + +// Preprocessor page options. + +struct PreprocessorPageOptions final +{ + explicit PreprocessorPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + defineSymbols = gen::utils::cppVariantModuleProperties( + qbsProps, {QStringLiteral("defines")}); + + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + const QStringList fullIncludePaths = gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("includePaths"), + QStringLiteral("systemIncludePaths")}); + for (const QString &fullIncludePath : fullIncludePaths) { + const QFileInfo includeFileInfo(fullIncludePath); + const QString includeFilePath = includeFileInfo.absoluteFilePath(); + if (includeFilePath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, includeFilePath); + includePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, includeFilePath); + includePaths.push_back(path); + } + } + } + + QVariantList defineSymbols; + QVariantList includePaths; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + warningsAsErrors = gen::utils::cppIntegerModuleProperty( + qbsProps, QStringLiteral("treatWarningsAsErrors")); + } + + int warningsAsErrors = 0; +}; + +} // namespace + +// Stm8CompilerSettingsGroup + +Stm8CompilerSettingsGroup::Stm8CompilerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + Q_UNUSED(qbsProductDeps) + + setName(QByteArrayLiteral("ICCSTM8")); + setArchiveVersion(kCompilerArchiveVersion); + setDataVersion(kCompilerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildOutputPage(qbsProduct); + buildLanguageOnePage(qbsProduct); + buildLanguageTwoPage(qbsProduct); + buildOptimizationsPage(qbsProduct); + buildPreprocessorPage(buildRootDirectory, qbsProduct); + buildDiagnosticsPage(qbsProduct); +} + +void Stm8CompilerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + // Add 'IccGenerateDebugInfo' item (Generate debug info). + addOptionsGroup(QByteArrayLiteral("IccGenerateDebugInfo"), + {opts.debugInfo}); +} + +void Stm8CompilerSettingsGroup::buildLanguageOnePage( + const ProductData &qbsProduct) +{ + const LanguageOnePageOptions opts(qbsProduct); + // Add 'IccLang' item with 'auto-extension based' + // value (Language: C/C++/Auto). + addOptionsGroup(QByteArrayLiteral("IccLang"), + {opts.languageExtension}); + // Add 'IccCDialect' item (C dialect: c89/99/11). + addOptionsGroup(QByteArrayLiteral("IccCDialect"), + {opts.cLanguageDialect}); + // Add 'IccCppDialect' item (C++ dialect: embedded/extended). + addOptionsGroup(QByteArrayLiteral("IccCppDialect"), + {opts.cxxLanguageDialect}); + // Add 'IccLanguageConformance' item + // (Language conformance: IAR/relaxed/strict). + addOptionsGroup(QByteArrayLiteral("IccLanguageConformance"), + {opts.languageConformance}); + // Add 'IccAllowVLA' item (Allow VLA). + addOptionsGroup(QByteArrayLiteral("IccAllowVLA"), + {opts.allowVla}); + // Add 'IccCppInlineSemantics' item (C++ inline semantics). + addOptionsGroup(QByteArrayLiteral("IccCppInlineSemantics"), + {opts.useCppInlineSemantics}); + // Add 'IccRequirePrototypes' item (Require prototypes). + addOptionsGroup(QByteArrayLiteral("IccRequirePrototypes"), + {opts.requirePrototypes}); + // Add 'IccStaticDestr' item (Destroy static objects). + addOptionsGroup(QByteArrayLiteral("IccStaticDestr"), + {opts.destroyStaticObjects}); +} + +void Stm8CompilerSettingsGroup::buildLanguageTwoPage( + const ProductData &qbsProduct) +{ + const LanguageTwoPageOptions opts(qbsProduct); + // Add 'IccCharIs' item (Plain char is: signed/unsigned). + addOptionsGroup(QByteArrayLiteral("IccCharIs"), + {opts.plainCharacter}); + // Add 'IccFloatSemantics' item (Floatic-point + // semantics: strict/relaxed conformance). + addOptionsGroup(QByteArrayLiteral("IccFloatSemantics"), + {opts.floatingPointSemantic}); + // Add 'IccMultibyteSupport' item (Enable multibyte support). + addOptionsGroup(QByteArrayLiteral("IccMultibyteSupport"), + {opts.enableMultibyteSupport}); +} + +void Stm8CompilerSettingsGroup::buildOptimizationsPage( + const ProductData &qbsProduct) +{ + const OptimizationsPageOptions opts(qbsProduct); + // Add 'IccOptStrategy', 'IccOptLevel' and + // 'CCOptLevelSlave' items (Level). + addOptionsGroup(QByteArrayLiteral("IccOptStrategy"), + {opts.optimizationStrategy}); + addOptionsGroup(QByteArrayLiteral("IccOptLevel"), + {opts.optimizationLevel}); + addOptionsGroup(QByteArrayLiteral("IccOptLevelSlave"), + {opts.optimizationLevelSlave}); + + // Add 'IccOptNoSizeConstraints' iten (no size constraints). + addOptionsGroup(QByteArrayLiteral("IccOptNoSizeConstraints"), + {opts.disableSizeConstraints}); + + // Add 'IccOptAllowList' item + // (Enabled optimizations: 6 check boxes). + const QString bitflags = QStringLiteral("%1%2%3%4%5%6") + .arg(opts.enableCommonSubexpressionElimination) + .arg(opts.enableLoopUnroll) + .arg(opts.enableFunctionInlining) + .arg(opts.enableCodeMotion) + .arg(opts.enableTypeBasedAliasAnalysis) + .arg(opts.enableCrossCall); + addOptionsGroup(QByteArrayLiteral("IccOptAllowList"), + {bitflags}); + + // Add 'IccNoVregs' item + // (Number of virtual registers (12/16). + addOptionsGroup(QByteArrayLiteral("IccNoVregs"), + {opts.vregsNumber}); +} + +void Stm8CompilerSettingsGroup::buildPreprocessorPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const PreprocessorPageOptions opts(baseDirectory, qbsProduct); + // Add 'CCDefines' item (Defines symbols). + addOptionsGroup(QByteArrayLiteral("CCDefines"), + opts.defineSymbols); + // Add 'CCIncludePath2' item + // (Additional include directories). + addOptionsGroup(QByteArrayLiteral("CCIncludePath2"), + opts.includePaths); +} + +void Stm8CompilerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'CCDiagWarnAreErr' item (Treat all warnings as errors). + addOptionsGroup(QByteArrayLiteral("CCDiagWarnAreErr"), + {opts.warningsAsErrors}); +} + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/stm8/stm8compilersettingsgroup_v3.h b/src/plugins/generator/iarew/archs/stm8/stm8compilersettingsgroup_v3.h new file mode 100644 index 000000000..29bb5c2b3 --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8compilersettingsgroup_v3.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWSTM8COMPILERSETTINGSGROUP_V3_H +#define QBS_IAREWSTM8COMPILERSETTINGSGROUP_V3_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +class Stm8CompilerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Stm8CompilerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildOutputPage(const ProductData &qbsProduct); + void buildLanguageOnePage(const ProductData &qbsProduct); + void buildLanguageTwoPage(const ProductData &qbsProduct); + void buildOptimizationsPage(const ProductData &qbsProduct); + void buildPreprocessorPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); +}; + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWSTM8COMPILERSETTINGSGROUP_V3_H diff --git a/src/plugins/generator/iarew/archs/stm8/stm8generalsettingsgroup_v3.cpp b/src/plugins/generator/iarew/archs/stm8/stm8generalsettingsgroup_v3.cpp new file mode 100644 index 000000000..9477bc36e --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8generalsettingsgroup_v3.cpp @@ -0,0 +1,366 @@ +/**************************************************************************** +** +** 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 "stm8generalsettingsgroup_v3.h" + +#include "../../iarewutils.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +constexpr int kGeneralArchiveVersion = 4; +constexpr int kGeneralDataVersion = 2; + +namespace { + +// Target page options. + +struct TargetPageOptions final +{ + enum CodeModel { + SmallCodeModel, + MediumCodeModel, + LargeCodeModel + }; + + enum DataModel { + SmallDataModel, + MediumDataModel, + LargeDataModel + }; + + 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("medium")) + codeModel = TargetPageOptions::MediumCodeModel; + 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; + } + + CodeModel codeModel = MediumCodeModel; + DataModel dataModel = MediumDataModel; +}; + +// 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, + NormalLibrary, + FullLibrary, + CustomLibrary + }; + + 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::NormalLibrary; + } else if (configFilePath.endsWith(QLatin1String("f.h"), + Qt::CaseInsensitive)) { + libraryType = LibraryConfigPageOptions::FullLibrary; + } else { + libraryType = LibraryConfigPageOptions::CustomLibrary; + } + + configPath = IarewUtils::toolkitRelativeFilePath( + baseDirectory, configFilePath); + } else { + libraryType = LibraryConfigPageOptions::CustomLibrary; + + configPath = configFilePath; + } + } else { + libraryType = LibraryConfigPageOptions::NoLibrary; + } + } + + RuntimeLibrary libraryType = NoLibrary; + 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 != QLatin1String("--redirect")) + continue; + ++flagIt; + if (flagIt->startsWith(QLatin1String("_printf="), + Qt::CaseInsensitive)) { + const QString prop = flagIt->split( + QLatin1Char('=')).at(1).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->startsWith(QLatin1String("_scanf="), + Qt::CaseInsensitive)) { + const QString prop = flagIt->split( + QLatin1Char('=')).at(1).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); + const auto configDefs = IarewUtils::flagValues( + flags, QStringLiteral("--config_def")); + for (const auto &configDef : configDefs) { + const auto def = configDef.toString(); + if (def.startsWith(QLatin1String("_CSTACK_SIZE="))) { + stackSize = def.split(QLatin1Char('=')).at(1); + } else if (def.startsWith(QLatin1String("_HEAP_SIZE="))) { + heapSize = def.split(QLatin1Char('=')).at(1); + } + } + } + + QString stackSize; + QString heapSize; +}; + +} // namespace + +// Stm8GeneralSettingsGroup + +Stm8GeneralSettingsGroup::Stm8GeneralSettingsGroup( + 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 Stm8GeneralSettingsGroup::buildTargetPage( + const ProductData &qbsProduct) +{ + const TargetPageOptions opts(qbsProduct); + // Add 'GenCodeModel' item + // (Code model: small/medium/large). + addOptionsGroup(QByteArrayLiteral("GenCodeModel"), + {opts.codeModel}); + // Add 'GenDataModel' item + // (Data model: small/medium/large). + addOptionsGroup(QByteArrayLiteral("GenDataModel"), + {opts.dataModel}); +} + +void Stm8GeneralSettingsGroup::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 Stm8GeneralSettingsGroup::buildLibraryConfigPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + const LibraryConfigPageOptions opts(baseDirectory, qbsProduct); + // Add 'GenRuntimeLibSelect' and 'GenRuntimeLibSelectSlave' items + // (Link with runtime: none/normal/full/custom). + addOptionsGroup(QByteArrayLiteral("GenRuntimeLibSelect"), + {opts.libraryType}); + addOptionsGroup(QByteArrayLiteral("GenRuntimeLibSelectSlave"), + {opts.libraryType}); + // Add 'GenRTConfigPath' item (Runtime configuration file). + addOptionsGroup(QByteArrayLiteral("GenRTConfigPath"), + {opts.configPath}); +} + +void Stm8GeneralSettingsGroup::buildLibraryOptionsPage( + const ProductData &qbsProduct) +{ + const LibraryOptionsPageOptions opts(qbsProduct); + // Add 'GenLibOutFormatter' item (Printf formatter). + addOptionsGroup(QByteArrayLiteral("GenLibOutFormatter"), + {opts.printfFormatter}); + // Add 'GenLibInFormatter' item (Scanf formatter). + addOptionsGroup(QByteArrayLiteral("GenLibInFormatter"), + {opts.scanfFormatter}); +} + +void Stm8GeneralSettingsGroup::buildStackHeapPage( + const ProductData &qbsProduct) +{ + const StackHeapPageOptions opts(qbsProduct); + // Add 'GenStackSize' item (Stack size). + addOptionsGroup(QByteArrayLiteral("GenStackSize"), + {opts.stackSize}); + // Add 'GenHeapSize' item (Heap size). + addOptionsGroup(QByteArrayLiteral("GenHeapSize"), + {opts.heapSize}); +} + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/stm8/stm8generalsettingsgroup_v3.h b/src/plugins/generator/iarew/archs/stm8/stm8generalsettingsgroup_v3.h new file mode 100644 index 000000000..20def0fd5 --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8generalsettingsgroup_v3.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWSTM8GENERALSETTINGSGROUP_V3_H +#define QBS_IAREWSTM8GENERALSETTINGSGROUP_V3_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +class Stm8GeneralSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Stm8GeneralSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildTargetPage(const ProductData &qbsProduct); + void buildOutputPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildLibraryConfigPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildLibraryOptionsPage(const ProductData &qbsProduct); + void buildStackHeapPage(const ProductData &qbsProduct); +}; + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWSTM8GENERALSETTINGSGROUP_V3_H diff --git a/src/plugins/generator/iarew/archs/stm8/stm8linkersettingsgroup_v3.cpp b/src/plugins/generator/iarew/archs/stm8/stm8linkersettingsgroup_v3.cpp new file mode 100644 index 000000000..2d3780e4f --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8linkersettingsgroup_v3.cpp @@ -0,0 +1,411 @@ +/**************************************************************************** +** +** 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 "stm8linkersettingsgroup_v3.h" + +#include "../../iarewutils.h" + +#include <QtCore/qdir.h> + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +constexpr int kLinkerArchiveVersion = 5; +constexpr int kLinkerDataVersion = 4; + +namespace { + +// Config page options. + +struct ConfigPageOptions final +{ + explicit ConfigPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + 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)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + configFilePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + configFilePaths.push_back(path); + } + } + } + + // Enumerate all product linker config files + // (which are set trough '-config' option). + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + const QVariantList configPathValues = IarewUtils::flagValues( + flags, QStringLiteral("--config")); + for (const QVariant &configPathValue : configPathValues) { + const QString fullConfigPath = configPathValue.toString(); + if (fullConfigPath.startsWith(toolkitPath, Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullConfigPath); + if (!configFilePaths.contains(path)) + configFilePaths.push_back(path); + } + } + + // Enumerate all config definition symbols (except + // the CSTACK_SIZE and HEAP_SIZE which are handles + // on the general page). + configDefinitions = IarewUtils::flagValues( + flags, QStringLiteral("--config_def")); + configDefinitions.erase(std::remove_if( + configDefinitions.begin(), + configDefinitions.end(), + [](const auto &definition){ + const auto def = definition.toString(); + return def.startsWith(QLatin1String("_CSTACK_SIZE")) + || def.startsWith(QLatin1String("_HEAP_SIZE")); + }), configDefinitions.end()); + } + + QVariantList configFilePaths; + QVariantList configDefinitions; +}; + +struct LibraryPageOptions final +{ + explicit LibraryPageOptions(const QString &baseDirectory, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct); + + entryPoint = gen::utils::cppStringModuleProperty( + qbsProps, QStringLiteral("entryPoint")); + + // Add static libraries paths. + const QStringList staticLibrariesProps = + gen::utils::cppStringModuleProperties( + qbsProps, {QStringLiteral("staticLibraries")}); + for (const QString &staticLibrary : staticLibrariesProps) { + const QFileInfo staticLibraryInfo(staticLibrary); + if (staticLibraryInfo.isAbsolute()) { + const QString fullStaticLibraryPath = + staticLibraryInfo.absoluteFilePath(); + if (fullStaticLibraryPath.startsWith(toolkitPath, + Qt::CaseInsensitive)) { + const QString path = IarewUtils::toolkitRelativeFilePath( + toolkitPath, fullStaticLibraryPath); + staticLibraries.push_back(path); + } else { + const QString path = IarewUtils::projectRelativeFilePath( + baseDirectory, fullStaticLibraryPath); + staticLibraries.push_back(path); + } + } else { + staticLibraries.push_back(staticLibrary); + } + } + + // Add static libraries from product dependencies. + for (const ProductData &qbsProductDep : qbsProductDeps) { + const QString depBinaryPath = QLatin1String("$PROJ_DIR$/") + + gen::utils::targetBinaryPath(baseDirectory, + qbsProductDep); + staticLibraries.push_back(depBinaryPath); + } + } + + QString entryPoint; + QVariantList staticLibraries; +}; + +struct OptimizationsPageOptions final +{ + explicit OptimizationsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + + mergeDuplicateSections = flags.contains( + QLatin1String("--merge_duplicate_sections")); + } + + bool mergeDuplicateSections = 0; +}; + +// Output page options. + +struct OutputPageOptions final +{ + explicit OutputPageOptions(const ProductData &qbsProduct) + { + outputFile = gen::utils::targetBinary(qbsProduct); + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + + enableDebugInfo = !flags.contains(QLatin1String("--strip")); + } + + QString outputFile; + bool enableDebugInfo = 1; +}; + +// List page options. + +struct ListPageOptions final +{ + enum ListingAction { + NoListing, + GenerateListing + }; + + explicit ListPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + generateMap = gen::utils::cppBooleanModuleProperty( + qbsProps, QStringLiteral("generateLinkerMapFile")) + ? ListPageOptions::GenerateListing + : ListPageOptions::NoListing; + } + + ListingAction generateMap = NoListing; +}; + +// Define page options. + +struct DefinePageOptions final +{ + explicit DefinePageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + const QStringList flags = IarewUtils::cppModuleLinkerFlags(qbsProps); + + defineSymbols = IarewUtils::flagValues( + flags, QStringLiteral("--define_symbol")); + } + + QVariantList defineSymbols; +}; + +// Diagnostics page options. + +struct DiagnosticsPageOptions final +{ + explicit DiagnosticsPageOptions(const ProductData &qbsProduct) + { + const auto &qbsProps = qbsProduct.moduleProperties(); + warningsAsErrors = gen::utils::cppIntegerModuleProperty( + qbsProps, QStringLiteral("treatWarningsAsErrors")); + } + + int warningsAsErrors = 0; +}; + +} // namespace + +// Stm8LinkerSettingsGroup + +Stm8LinkerSettingsGroup::Stm8LinkerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + setName(QByteArrayLiteral("ILINK")); + setArchiveVersion(kLinkerArchiveVersion); + setDataVersion(kLinkerDataVersion); + setDataDebugInfo(gen::utils::debugInformation(qbsProduct)); + + const QString buildRootDirectory = gen::utils::buildRootPath(qbsProject); + + buildConfigPage(buildRootDirectory, qbsProduct); + buildLibraryPage(buildRootDirectory, qbsProduct, qbsProductDeps); + buildOptimizationsPage(qbsProduct); + buildOutputPage(qbsProduct); + buildListPage(qbsProduct); + buildDefinePage(qbsProduct); + buildDiagnosticsPage(qbsProduct); + + // Should be called as latest stage! + buildExtraOptionsPage(qbsProduct); +} + +void Stm8LinkerSettingsGroup::buildConfigPage( + const QString &baseDirectory, + const ProductData &qbsProduct) +{ + ConfigPageOptions opts(baseDirectory, qbsProduct); + + if (opts.configFilePaths.count() > 0) { + // Note: IAR IDE does not allow to specify a multiple config files, + // although the IAR linker support it. So, we use followig 'trick': + // we take a first config file and to add it as usual to required items; + // and then an other remainders we forward to the "Extra options page". + const QVariant configPath = opts.configFilePaths.takeFirst(); + // Add 'IlinkIcfOverride' item (Override default). + addOptionsGroup(QByteArrayLiteral("IlinkIcfOverride"), + {1}); + // Add 'IlinkIcfFile' item (Linke configuration file). + addOptionsGroup(QByteArrayLiteral("IlinkIcfFile"), + {configPath}); + + // Add remainder configuration files to the "Extra options page". + if (!opts.configFilePaths.isEmpty()) { + for (QVariant &configPath : opts.configFilePaths) + configPath = QLatin1String("--config ") + configPath.toString(); + + m_extraOptions << opts.configFilePaths; + } + } + + // Add 'IlinkConfigDefines' item (Configuration file + // symbol definitions). + addOptionsGroup(QByteArrayLiteral("IlinkConfigDefines"), + opts.configDefinitions); +} + +void Stm8LinkerSettingsGroup::buildLibraryPage( + const QString &baseDirectory, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps) +{ + LibraryPageOptions opts(baseDirectory, qbsProduct, qbsProductDeps); + + // Add 'IlinkOverrideProgramEntryLabel' item + // (Override default program entry). + addOptionsGroup(QByteArrayLiteral("IlinkOverrideProgramEntryLabel"), + {1}); + + if (opts.entryPoint.isEmpty()) { + // Add 'IlinkProgramEntryLabelSelect' item + // (Defined by application). + addOptionsGroup(QByteArrayLiteral("IlinkProgramEntryLabelSelect"), + {1}); + } else { + // Add 'IlinkProgramEntryLabel' item + // (Entry symbol). + addOptionsGroup(QByteArrayLiteral("IlinkProgramEntryLabel"), + {opts.entryPoint}); + } + + // Add 'IlinkAdditionalLibs' item (Additional libraries). + addOptionsGroup(QByteArrayLiteral("IlinkAdditionalLibs"), + {opts.staticLibraries}); +} + +void Stm8LinkerSettingsGroup::buildOptimizationsPage( + const ProductData &qbsProduct) +{ + OptimizationsPageOptions opts(qbsProduct); + + // Add 'IlinkOptMergeDuplSections' item + // (Merge duplicate sections). + addOptionsGroup(QByteArrayLiteral("IlinkOptMergeDuplSections"), + {opts.mergeDuplicateSections}); +} + +void Stm8LinkerSettingsGroup::buildOutputPage( + const ProductData &qbsProduct) +{ + const OutputPageOptions opts(qbsProduct); + + // Add 'IlinkOutputFile' item (Output file name). + addOptionsGroup(QByteArrayLiteral("IlinkOutputFile"), + {opts.outputFile}); + // Add 'IlinkDebugInfoEnable' item + // (Include debug information in output). + addOptionsGroup(QByteArrayLiteral("IlinkDebugInfoEnable"), + {opts.enableDebugInfo}); +} + +void Stm8LinkerSettingsGroup::buildListPage( + const ProductData &qbsProduct) +{ + const ListPageOptions opts(qbsProduct); + // Add 'IlinkMapFile' item (Generate linker map file). + addOptionsGroup(QByteArrayLiteral("IlinkMapFile"), + {opts.generateMap}); +} + +void Stm8LinkerSettingsGroup::buildDefinePage( + const ProductData &qbsProduct) +{ + const DefinePageOptions opts(qbsProduct); + // Add 'IlinkDefines' item (Defined symbols). + addOptionsGroup(QByteArrayLiteral("IlinkDefines"), + opts.defineSymbols); +} + +void Stm8LinkerSettingsGroup::buildDiagnosticsPage( + const ProductData &qbsProduct) +{ + const DiagnosticsPageOptions opts(qbsProduct); + // Add 'IlinkWarningsAreErrors' item (Treat all warnings as errors). + addOptionsGroup(QByteArrayLiteral("IlinkWarningsAreErrors"), + {opts.warningsAsErrors}); +} + +void Stm8LinkerSettingsGroup::buildExtraOptionsPage( + const ProductData &qbsProduct) +{ + Q_UNUSED(qbsProduct) + + if (m_extraOptions.isEmpty()) + return; + + // Add 'IlinkUseExtraOptions' (Use command line options). + addOptionsGroup(QByteArrayLiteral("IlinkUseExtraOptions"), + {1}); + // Add 'IlinkExtraOptions' item (Command line options). + addOptionsGroup(QByteArrayLiteral("IlinkExtraOptions"), + m_extraOptions); +} + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs diff --git a/src/plugins/generator/iarew/archs/stm8/stm8linkersettingsgroup_v3.h b/src/plugins/generator/iarew/archs/stm8/stm8linkersettingsgroup_v3.h new file mode 100644 index 000000000..b214ebe35 --- /dev/null +++ b/src/plugins/generator/iarew/archs/stm8/stm8linkersettingsgroup_v3.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#ifndef QBS_IAREWSTM8LINKERSETTINGSGROUP_V3_H +#define QBS_IAREWSTM8LINKERSETTINGSGROUP_V3_H + +#include "../../iarewsettingspropertygroup.h" + +namespace qbs { +namespace iarew { +namespace stm8 { +namespace v3 { + +class Stm8LinkerSettingsGroup final : public IarewSettingsPropertyGroup +{ +public: + explicit Stm8LinkerSettingsGroup( + const Project &qbsProject, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + +private: + void buildConfigPage(const QString &baseDirectory, + const ProductData &qbsProduct); + void buildLibraryPage(const QString &baseDirectory, + const ProductData &qbsProduct, + const std::vector<ProductData> &qbsProductDeps); + void buildOptimizationsPage(const ProductData &qbsProduct); + + + + void buildOutputPage(const ProductData &qbsProduct); + void buildListPage(const ProductData &qbsProduct); + void buildDefinePage(const ProductData &qbsProduct); + void buildDiagnosticsPage(const ProductData &qbsProduct); + void buildExtraOptionsPage(const ProductData &qbsProduct); + + QVariantList m_extraOptions; +}; + +} // namespace v3 +} // namespace stm8 +} // namespace iarew +} // namespace qbs + +#endif // QBS_IAREWSTM8LINKERSETTINGSGROUP_V3_H |