aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/generator/iarew/archs
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2019-06-29 18:22:15 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2019-07-11 11:40:40 +0000
commit808d246607b768ea4dc02e3ef0b178e058d6575c (patch)
treeca19a3f75351ef7aad60241df81df82166451b72 /src/plugins/generator/iarew/archs
parent9ee200a92808286a8c48253cf51ee7eecaa1a8a8 (diff)
baremetal: Long live the IAR EW project generator for ARM
Right now it is possible to generate a native projects for the IAR Embedded Workbench IDE, e.g. using the following command: qbs generate -g iarew8 -d <path/to/build/directory> -f <path/to/qbs/project> profile:<your/qbs/profile> We need in a valid IAR EW QBS profile, from which the generator take a desired target architecture and other stuff. The IAR EW generator has a semi-intelligent logic, it parses a source QBS project and converts a compiler flags and other stuff to an appropriate configurations of the native IAR EW project. Currently it is supported only one 'iarew8' generator which allow to generate a projects for the IAR EW for ARM for all versions of 8 series. Tested with the IAR EW for ARM v8.20, v8.32, v8.40, using as the QBS bare-metal examples, and as other projects. Change-Id: I2aa24d5a635f1f5a0e645bec8c30053e960d90a3 Reviewed-by: Ivan Komissarov <ABBAPOH@gmail.com> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/plugins/generator/iarew/archs')
-rw-r--r--src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.cpp92
-rw-r--r--src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.h54
-rw-r--r--src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.cpp224
-rw-r--r--src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.h57
-rw-r--r--src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.cpp93
-rw-r--r--src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.h64
-rw-r--r--src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.cpp453
-rw-r--r--src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.h59
-rw-r--r--src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.cpp518
-rw-r--r--src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.h59
-rw-r--r--src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.cpp484
-rw-r--r--src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.h67
12 files changed, 2224 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..3bff5c43a
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 "../../iarewproperty.h"
+#include "../../iarewutils.h"
+
+namespace qbs {
+namespace v8 {
+
+constexpr int kArchiverArchiveVersion = 0;
+constexpr int kArchiverDataVersion = 0;
+
+namespace ArmArchiver {
+
+// Output page options.
+
+struct OutputPageOptions final
+{
+ explicit OutputPageOptions(const QString &baseDirectory,
+ const ProductData &qbsProduct)
+ {
+ outputFile = QLatin1String("$PROJ_DIR$/")
+ + IarewUtils::targetBinaryPath(baseDirectory, qbsProduct);
+ }
+
+ QString outputFile;
+};
+
+} // namespace ArmArchiver
+
+// 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(IarewUtils::debugInformation(qbsProduct));
+
+ const QString buildRootDirectory = IarewUtils::buildRootPath(qbsProject);
+ buildOutputPage(buildRootDirectory, qbsProduct);
+}
+
+void ArmArchiverSettingsGroup::buildOutputPage(
+ const QString &baseDirectory,
+ const ProductData &qbsProduct)
+{
+ const ArmArchiver::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 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..36ad3cc68
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armarchiversettingsgroup_v8.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** 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_ARMAARCHIVERSETTINGSGROUP_V8_H
+#define QBS_ARMAARCHIVERSETTINGSGROUP_V8_H
+
+#include "../../iarewsettingspropertygroup.h"
+
+namespace qbs {
+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 qbs
+
+#endif // QBS_ARMAARCHIVERSETTINGSGROUP_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..7c7f8e2bf
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** 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 "../../iarewproperty.h"
+#include "../../iarewutils.h"
+
+namespace qbs {
+namespace v8 {
+
+constexpr int kAssemblerArchiveVersion = 2;
+constexpr int kAssemblerDataVersion = 10;
+
+namespace ArmAssembler {
+
+// 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 = IarewUtils::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 = IarewUtils::cppVariantModuleProperties(
+ qbsProps, {QStringLiteral("defines")});
+
+ const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct);
+ const QStringList fullIncludePaths = IarewUtils::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 = IarewUtils::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 ArmAssembler
+
+// 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(IarewUtils::debugInformation(qbsProduct));
+
+ const QString buildRootDirectory = IarewUtils::buildRootPath(qbsProject);
+
+ buildLanguagePage(qbsProduct);
+ buildOutputPage(qbsProduct);
+ buildPreprocessorPage(buildRootDirectory, qbsProduct);
+ buildDiagnosticsPage(qbsProduct);
+}
+
+void ArmAssemblerSettingsGroup::buildLanguagePage(
+ const ProductData &qbsProduct)
+{
+ const ArmAssembler::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"),
+ {0}, {opts.macroQuoteCharacter});
+}
+void ArmAssemblerSettingsGroup::buildOutputPage(
+ const ProductData &qbsProduct)
+{
+ const ArmAssembler::OutputPageOptions opts(qbsProduct);
+ // Add 'ADebug' item (Generate debug information).
+ addOptionsGroup(QByteArrayLiteral("ADebug"),
+ {}, {opts.debugInfo});
+}
+
+void ArmAssemblerSettingsGroup::buildPreprocessorPage(
+ const QString &baseDirectory,
+ const ProductData &qbsProduct)
+{
+ const ArmAssembler::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 ArmAssembler::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 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..5db5ca454
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armassemblersettingsgroup_v8.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** 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_ARMASSEMBLERSETTINGSGROUP_V8_H
+#define QBS_ARMASSEMBLERSETTINGSGROUP_V8_H
+
+#include "../../iarewsettingspropertygroup.h"
+
+namespace qbs {
+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 qbs
+
+#endif // QBS_ARMASSEMBLERSETTINGSGROUP_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..ea55eaacb
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 v8 {
+
+ArmBuildConfigurationGroup::ArmBuildConfigurationGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps)
+ : IarewPropertyGroup("configuration")
+{
+ // Append configuration name item.
+ const QString cfgName = IarewUtils::buildConfigurationName(qbsProject);
+ appendProperty("name", cfgName);
+
+ // Apend toolchain name group item.
+ appendChild<IarewToolchainPropertyGroup>("ARM");
+
+ // Append debug info item.
+ const int debugBuild = IarewUtils::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(
+ IarewUtils::Architecture architecture,
+ const Version &version) const
+{
+ return architecture == IarewUtils::Architecture::ArmArchitecture
+ && version.majorVersion() == 8;
+}
+
+std::unique_ptr<IarewPropertyGroup> ArmBuildConfigurationGroupFactory::create(
+ const Project &qbsProject,
+ const 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 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..3d83a6370
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armbuildconfigurationgroup_v8.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_ARMBUILDCONFIGURATIONGROUP_V8_H
+#define QBS_ARMBUILDCONFIGURATIONGROUP_V8_H
+
+#include "../../iarewpropertygroup.h"
+
+namespace qbs {
+namespace v8 {
+
+class ArmBuildConfigurationGroup final : public IarewPropertyGroup
+{
+private:
+ explicit ArmBuildConfigurationGroup(const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps);
+
+ friend class ArmBuildConfigurationGroupFactory;
+};
+
+class ArmBuildConfigurationGroupFactory final : public IarewPropertyGroupFactory
+{
+public:
+ bool canCreate(IarewUtils::Architecture architecture,
+ const Version &version) const final;
+
+ std::unique_ptr<IarewPropertyGroup> create(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps) const final;
+};
+
+} // namespace v8
+} // namespace qbs
+
+#endif // QBS_ARMBUILDCONFIGURATIONGROUP_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..111f8003b
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.cpp
@@ -0,0 +1,453 @@
+/****************************************************************************
+**
+** 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 v8 {
+
+constexpr int kCompilerArchiveVersion = 2;
+constexpr int kCompilerDataVersion = 34;
+
+namespace ArmCompiler {
+
+// Output page options.
+
+struct OutputPageOptions final
+{
+ explicit OutputPageOptions(const ProductData &qbsProduct)
+ {
+ debugInfo = IarewUtils::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 = IarewUtils::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 = IarewUtils::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 = IarewUtils::cppVariantModuleProperties(
+ qbsProps, {QStringLiteral("defines")});
+
+ const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct);
+ const QStringList fullIncludePaths = IarewUtils::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 = IarewUtils::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 ArmCompiler
+
+// 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(IarewUtils::debugInformation(qbsProduct));
+
+ const QString buildRootDirectory = IarewUtils::buildRootPath(qbsProject);
+
+ buildOutputPage(qbsProduct);
+ buildLanguageOnePage(qbsProduct);
+ buildLanguageTwoPage(qbsProduct);
+ buildOptimizationsPage(qbsProduct);
+ buildPreprocessorPage(buildRootDirectory, qbsProduct);
+ buildDiagnosticsPage(qbsProduct);
+ buildCodePage(qbsProduct);
+}
+
+void ArmCompilerSettingsGroup::buildOutputPage(
+ const ProductData &qbsProduct)
+{
+ const ArmCompiler::OutputPageOptions opts(qbsProduct);
+ // Add 'CCDebugInfo' item (Generate debug info).
+ addOptionsGroup(QByteArrayLiteral("CCDebugInfo"),
+ {}, {opts.debugInfo});
+}
+
+void ArmCompilerSettingsGroup::buildLanguageOnePage(
+ const ProductData &qbsProduct)
+{
+ const ArmCompiler::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 ArmCompiler::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 ArmCompiler::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 ArmCompiler::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 ArmCompiler::DiagnosticsPageOptions opts(qbsProduct);
+ // Add 'CCDiagWarnAreErr' item (Treat all warnings as errors).
+ addOptionsGroup(QByteArrayLiteral("CCDiagWarnAreErr"),
+ {}, {opts.treatWarningsAsErrors});
+}
+
+void ArmCompilerSettingsGroup::buildCodePage(
+ const ProductData &qbsProduct)
+{
+ const ArmCompiler::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 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..6f2acbeaa
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armcompilersettingsgroup_v8.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_ARMCOMPILERSETTINGSGROUP_V8_H
+#define QBS_ARMCOMPILERSETTINGSGROUP_V8_H
+
+#include "../../iarewsettingspropertygroup.h"
+
+namespace qbs {
+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 qbs
+
+#endif // QBS_ARMCOMPILERSETTINGSGROUP_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..b7c919391
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.cpp
@@ -0,0 +1,518 @@
+/****************************************************************************
+**
+** 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 v8 {
+
+constexpr int kGeneralArchiveVersion = 3;
+constexpr int kGeneralDataVersion = 30;
+
+namespace ArmGeneral {
+
+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 };
+
+ 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 };
+
+ 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 = IarewUtils::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 = IarewUtils::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 = IarewUtils::binaryOutputDirectory(
+ baseDirectory, qbsProduct);
+ objectDirectory = IarewUtils::objectsOutputDirectory(
+ baseDirectory, qbsProduct);
+ listingDirectory = IarewUtils::listingOutputDirectory(
+ baseDirectory, qbsProduct);
+ }
+
+ IarewUtils::OutputBinaryType binaryType = IarewUtils::ApplicationOutputType;
+ QString binaryDirectory;
+ QString objectDirectory;
+ QString listingDirectory;
+};
+
+} // namespace ArmGeneral
+
+// 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(IarewUtils::debugInformation(qbsProduct));
+
+ const QString buildRootDirectory = IarewUtils::buildRootPath(qbsProject);
+
+ buildTargetPage(qbsProduct);
+ buildLibraryOptionsOnePage(qbsProduct);
+ buildLibraryOptionsTwoPage(qbsProduct);
+ buildLibraryConfigPage(buildRootDirectory, qbsProduct);
+ buildOutputPage(buildRootDirectory, qbsProduct);
+}
+
+void ArmGeneralSettingsGroup::buildTargetPage(
+ const ProductData &qbsProduct)
+{
+ const ArmGeneral::TargetPageOptions opts(qbsProduct);
+ // Add 'GBECoreSlave', 'CoreVariant', 'GFPUCoreSlave2' items
+ // (Processor variant chooser).
+ addOptionsGroup(QByteArrayLiteral("GBECoreSlave"),
+ {26}, {opts.targetCpu});
+ addOptionsGroup(QByteArrayLiteral("CoreVariant"),
+ {26}, {opts.targetCpu});
+ addOptionsGroup(QByteArrayLiteral("GFPUCoreSlave2"),
+ {26}, {opts.targetCpu});
+ // Add 'FPU2', 'NrRegs' item (Floating point settings chooser).
+ addOptionsGroup(QByteArrayLiteral("FPU2"),
+ {0}, {opts.targetFpu});
+ addOptionsGroup(QByteArrayLiteral("NrRegs"),
+ {0}, {opts.targetFpuRegs});
+ // Add 'GEndianMode' item (Endian mode chooser).
+ addOptionsGroup(QByteArrayLiteral("GEndianMode"),
+ {}, {opts.endianness});
+}
+
+void ArmGeneralSettingsGroup::buildLibraryOptionsOnePage(
+ const ProductData &qbsProduct)
+{
+ const ArmGeneral::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 ArmGeneral::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 ArmGeneral::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 ArmGeneral::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 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..7d4a444d4
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armgeneralsettingsgroup_v8.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_ARMGENERALSETTINGSGROUP_V8_H
+#define QBS_ARMGENERALSETTINGSGROUP_V8_H
+
+#include "../../iarewsettingspropertygroup.h"
+
+namespace qbs {
+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 qbs
+
+#endif // QBS_ARMGENERALSETTINGSGROUP_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..c567b4791
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.cpp
@@ -0,0 +1,484 @@
+/****************************************************************************
+**
+** 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 v8 {
+
+constexpr int kLinkerArchiveVersion = 0;
+constexpr int kLinkerDataVersion = 20;
+
+namespace ArmLinker {
+
+// 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 = IarewUtils::cppStringModuleProperty(
+ qbsProps, QStringLiteral("entryPoint"));
+
+ // Add libraries search paths.
+ const QString toolkitPath = IarewUtils::toolkitRootPath(qbsProduct);
+ const QStringList libraryPaths = IarewUtils::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 =
+ IarewUtils::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$/")
+ + IarewUtils::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 = IarewUtils::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 = IarewUtils::cppBooleanModuleProperty(
+ qbsProps, QStringLiteral("generateMapFile"))
+ ? 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 = IarewUtils::cppIntegerModuleProperty(
+ qbsProps, QStringLiteral("treatWarningsAsErrors"));
+ }
+
+ int treatWarningsAsErrors = 0;
+};
+
+} // namespace ArmLinker
+
+// ArmLinkerSettingsGroup
+
+ArmLinkerSettingsGroup::ArmLinkerSettingsGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps)
+{
+ setName(QByteArrayLiteral("ILINK"));
+ setArchiveVersion(kLinkerArchiveVersion);
+ setDataVersion(kLinkerDataVersion);
+ setDataDebugInfo(IarewUtils::debugInformation(qbsProduct));
+
+ const QString buildRootDirectory = IarewUtils::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)
+{
+ ArmLinker::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)
+{
+ ArmLinker::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 ArmLinker::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 ArmLinker::InputPageOptions opts(qbsProduct);
+ // Add 'IlinkKeepSymbols' item ().
+ addOptionsGroup(QByteArrayLiteral("IlinkKeepSymbols"),
+ {}, opts.keepSymbols);
+}
+
+void ArmLinkerSettingsGroup::buildListPage(
+ const ProductData &qbsProduct)
+{
+ const ArmLinker::ListPageOptions opts(qbsProduct);
+ // Add 'IlinkMapFile' item (Generate linker map file).
+ addOptionsGroup(QByteArrayLiteral("IlinkMapFile"),
+ {}, {opts.generateMap});
+}
+
+void ArmLinkerSettingsGroup::buildOptimizationsPage(
+ const ProductData &qbsProduct)
+{
+ const ArmLinker::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 ArmLinker::AdvancedPageOptions opts(qbsProduct);
+ // Add 'IlinkOptExceptionsAllow' item (Allow C++ exceptions).
+ addOptionsGroup(QByteArrayLiteral("IlinkOptExceptionsAllow"),
+ {}, {opts.allowExceptions});
+}
+
+void ArmLinkerSettingsGroup::buildDefinesPage(
+ const ProductData &qbsProduct)
+{
+ const ArmLinker::DefinesPageOptions opts(qbsProduct);
+ // Add 'IlinkDefines' item (Defined symbols).
+ addOptionsGroup(QByteArrayLiteral("IlinkDefines"),
+ {}, {opts.defineSymbols});
+}
+
+void ArmLinkerSettingsGroup::buildDiagnosticsPage(
+ const ProductData &qbsProduct)
+{
+ const ArmLinker::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 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..2dc0a92c4
--- /dev/null
+++ b/src/plugins/generator/iarew/archs/arm/armlinkersettingsgroup_v8.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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_ARMLINKERSETTINGSGROUP_V8_H
+#define QBS_ARMLINKERSETTINGSGROUP_V8_H
+
+#include "../../iarewsettingspropertygroup.h"
+
+namespace qbs {
+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 qbs
+
+#endif // QBS_ARMLINKERSETTINGSGROUP_V8_H