aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2019-07-18 17:18:59 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2019-07-30 11:59:46 +0000
commit1ce230bfda1f9c2dc69bbdfb63a7586d0e7770a4 (patch)
tree9daad27f4742bd63b7f4be29665c018f9405ac84
parentef1c11855ee974a26ffb83892d2e4d40731fbff7 (diff)
baremetal: Long live the KEIL UV project generator for 8051
Right now it is possible to generate a native projects for the KEIL UVision IDE, e.g. using the following command: qbs generate -g keiluv5 -d <path/to/build/directory> -f <path/to/qbs/project> profile:<your/qbs/profile> We need in a valid KEIL QBS profile, from which the generator take a desired target architecture and other stuff. The KEIL UV 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 KEIL UVsion project. Currently it is supported only one 'keiluv5' generator which allow to generate a projects for the KEIL UVision v5 for 8051 architecture. Tested with the KEIL UVision v5.23 for 8051, using as the QBS bare-metal examples, and as other projects. Change-Id: I248f1d220d9c9bcae9cb07d5bfbabbb85f9c39c9 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--src/plugins/generator/generator.pro6
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51buildtargetgroup_v5.cpp108
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51buildtargetgroup_v5.h69
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51commonpropertygroup_v5.cpp52
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51commonpropertygroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51debugoptiongroup_v5.cpp52
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51debugoptiongroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51dlloptiongroup_v5.cpp52
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51dlloptiongroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetassemblergroup_v5.cpp143
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetassemblergroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetcommonoptionsgroup_v5.cpp137
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetcommonoptionsgroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetcompilergroup_v5.cpp281
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetcompilergroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetgroup_v5.cpp58
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetgroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetlinkergroup_v5.cpp240
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetlinkergroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetmiscgroup_v5.cpp104
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51targetmiscgroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51utilitiesgroup_v5.cpp52
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51utilitiesgroup_v5.h54
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51utils.cpp83
-rw-r--r--src/plugins/generator/keiluv/archs/mcs51/mcs51utils.h67
-rw-r--r--src/plugins/generator/keiluv/ikeiluvnodevisitor.h65
-rw-r--r--src/plugins/generator/keiluv/keiluv.pro68
-rw-r--r--src/plugins/generator/keiluv/keiluv.qbs67
-rw-r--r--src/plugins/generator/keiluv/keiluvfilesgroupspropertygroup.cpp194
-rw-r--r--src/plugins/generator/keiluv/keiluvfilesgroupspropertygroup.h51
-rw-r--r--src/plugins/generator/keiluv/keiluvgenerator.cpp157
-rw-r--r--src/plugins/generator/keiluv/keiluvgenerator.h71
-rw-r--r--src/plugins/generator/keiluv/keiluvgeneratorplugin.cpp67
-rw-r--r--src/plugins/generator/keiluv/keiluvproject.cpp119
-rw-r--r--src/plugins/generator/keiluv/keiluvproject.h59
-rw-r--r--src/plugins/generator/keiluv/keiluvprojectwriter.cpp97
-rw-r--r--src/plugins/generator/keiluv/keiluvprojectwriter.h64
-rw-r--r--src/plugins/generator/keiluv/keiluvproperty.cpp52
-rw-r--r--src/plugins/generator/keiluv/keiluvproperty.h82
-rw-r--r--src/plugins/generator/keiluv/keiluvpropertygroup.cpp64
-rw-r--r--src/plugins/generator/keiluv/keiluvpropertygroup.h71
-rw-r--r--src/plugins/generator/keiluv/keiluvutils.cpp253
-rw-r--r--src/plugins/generator/keiluv/keiluvutils.h109
-rw-r--r--src/plugins/generator/keiluv/keiluvversioninfo.cpp105
-rw-r--r--src/plugins/generator/keiluv/keiluvversioninfo.h76
-rw-r--r--src/plugins/generator/keiluv/keiluvworkspace.cpp80
-rw-r--r--src/plugins/generator/keiluv/keiluvworkspace.h63
-rw-r--r--src/plugins/generator/keiluv/keiluvworkspacewriter.cpp97
-rw-r--r--src/plugins/generator/keiluv/keiluvworkspacewriter.h64
-rw-r--r--src/plugins/plugins.qbs1
50 files changed, 4239 insertions, 1 deletions
diff --git a/src/plugins/generator/generator.pro b/src/plugins/generator/generator.pro
index 3fa39468b..4a3861321 100644
--- a/src/plugins/generator/generator.pro
+++ b/src/plugins/generator/generator.pro
@@ -1,2 +1,6 @@
TEMPLATE = subdirs
-SUBDIRS = clangcompilationdb makefilegenerator visualstudio iarew
+SUBDIRS += clangcompilationdb
+SUBDIRS += makefilegenerator
+SUBDIRS += visualstudio
+SUBDIRS += iarew
+SUBDIRS += keiluv
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51buildtargetgroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51buildtargetgroup_v5.cpp
new file mode 100644
index 000000000..e9af55743
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51buildtargetgroup_v5.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** 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 "mcs51buildtargetgroup_v5.h"
+#include "mcs51commonpropertygroup_v5.h"
+#include "mcs51debugoptiongroup_v5.h"
+#include "mcs51dlloptiongroup_v5.h"
+#include "mcs51targetcommonoptionsgroup_v5.h"
+#include "mcs51targetgroup_v5.h"
+#include "mcs51utilitiesgroup_v5.h"
+#include "mcs51utils.h"
+
+#include "../../keiluvfilesgroupspropertygroup.h"
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+Mcs51BuildTargetGroup::Mcs51BuildTargetGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps)
+ : KeiluvPropertyGroup("Target")
+{
+ // Append target name item (it is a build configuration name).
+ const QString targetName = qbs::KeiluvUtils::buildConfigurationName(
+ qbsProject);
+ appendProperty(QByteArrayLiteral("TargetName"), targetName);
+ // Append toolset number group item.
+ appendChild<KeiluvProperty>(QByteArrayLiteral("ToolsetNumber"),
+ QByteArrayLiteral("0x0"));
+ // Append toolset name group item.
+ appendChild<KeiluvProperty>(QByteArrayLiteral("ToolsetName"),
+ QByteArrayLiteral("MCS-51"));
+
+ // Append target option group item.
+ const auto targetOptionGroup = appendChild<KeiluvPropertyGroup>(
+ QByteArrayLiteral("TargetOption"));
+
+ targetOptionGroup->appendChild<Mcs51TargetCommonOptionsGroup>(
+ qbsProject, qbsProduct);
+ targetOptionGroup->appendChild<Mcs51CommonPropertyGroup>(
+ qbsProject, qbsProduct);
+ targetOptionGroup->appendChild<Mcs51DllOptionGroup>(
+ qbsProject, qbsProduct);
+ targetOptionGroup->appendChild<Mcs51DebugOptionGroup>(
+ qbsProject, qbsProduct);
+ targetOptionGroup->appendChild<Mcs51UtilitiesGroup>(
+ qbsProject, qbsProduct);
+ targetOptionGroup->appendChild<Mcs51TargetGroup>(
+ qbsProject, qbsProduct);
+
+ // Append files group.
+ appendChild<KeiluvFilesGroupsPropertyGroup>(qbsProject, qbsProduct,
+ qbsProductDeps);
+}
+
+bool Mcs51BuildTargetGroupFactory::canCreate(
+ qbs::KeiluvUtils::Architecture architecture,
+ const Version &version) const
+{
+ return architecture == qbs::KeiluvUtils::Architecture::Mcs51Architecture
+ && version.majorVersion() == KeiluvConstants::kUVisionVersion;
+}
+
+std::unique_ptr<KeiluvPropertyGroup> Mcs51BuildTargetGroupFactory::create(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps) const
+{
+ const auto group = new Mcs51BuildTargetGroup(
+ qbsProject, qbsProduct, qbsProductDeps);
+ return std::unique_ptr<Mcs51BuildTargetGroup>(group);
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51buildtargetgroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51buildtargetgroup_v5.h
new file mode 100644
index 000000000..3f11c489e
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51buildtargetgroup_v5.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** 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_KEILUVMCS51BUILDTARGETGROUP_V5_H
+#define QBS_KEILUVMCS51BUILDTARGETGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51BuildTargetGroup final : public KeiluvPropertyGroup
+{
+private:
+ explicit Mcs51BuildTargetGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps);
+
+ friend class Mcs51BuildTargetGroupFactory;
+};
+
+class Mcs51BuildTargetGroupFactory final : public KeiluvPropertyGroupFactory
+{
+public:
+ bool canCreate(KeiluvUtils::Architecture architecture,
+ const Version &version) const final;
+
+ std::unique_ptr<KeiluvPropertyGroup> create(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps) const final;
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51BUILDTARGETGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51commonpropertygroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51commonpropertygroup_v5.cpp
new file mode 100644
index 000000000..32760df23
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51commonpropertygroup_v5.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 "mcs51commonpropertygroup_v5.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+Mcs51CommonPropertyGroup::Mcs51CommonPropertyGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("CommonProperty")
+{
+ Q_UNUSED(qbsProject)
+ Q_UNUSED(qbsProduct)
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51commonpropertygroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51commonpropertygroup_v5.h
new file mode 100644
index 000000000..185d498d0
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51commonpropertygroup_v5.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_KEILUVMCS51COMMONPROPERTYGROUP_V5_H
+#define QBS_KEILUVMCS51COMMONPROPERTYGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51CommonPropertyGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51CommonPropertyGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_MCS51COMMONPROPERTYGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51debugoptiongroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51debugoptiongroup_v5.cpp
new file mode 100644
index 000000000..5f2494f8f
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51debugoptiongroup_v5.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 "mcs51debugoptiongroup_v5.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+Mcs51DebugOptionGroup::Mcs51DebugOptionGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("DebugOption")
+{
+ Q_UNUSED(qbsProject)
+ Q_UNUSED(qbsProduct)
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51debugoptiongroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51debugoptiongroup_v5.h
new file mode 100644
index 000000000..e19f1edf8
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51debugoptiongroup_v5.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_KEILUVMCS51DEBUGOPTIONGROUP_V5_H
+#define QBS_KEILUVMCS51DEBUGOPTIONGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51DebugOptionGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51DebugOptionGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51DEBUGOPTIONGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51dlloptiongroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51dlloptiongroup_v5.cpp
new file mode 100644
index 000000000..26639b9bf
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51dlloptiongroup_v5.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 "mcs51dlloptiongroup_v5.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+Mcs51DllOptionGroup::Mcs51DllOptionGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("DllOption")
+{
+ Q_UNUSED(qbsProject)
+ Q_UNUSED(qbsProduct)
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51dlloptiongroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51dlloptiongroup_v5.h
new file mode 100644
index 000000000..5144dfd72
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51dlloptiongroup_v5.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_KEILUVMCS51DLLOPTIONGROUP_V5_H
+#define QBS_KEILUVMCS51DLLOPTIONGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51DllOptionGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51DllOptionGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51DLLOPTIONGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetassemblergroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetassemblergroup_v5.cpp
new file mode 100644
index 000000000..00120a56d
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetassemblergroup_v5.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** 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 "mcs51targetassemblergroup_v5.h"
+#include "mcs51utils.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+namespace {
+
+struct AssemblerPageOptions final
+{
+ explicit AssemblerPageOptions(const Project &qbsProject,
+ const ProductData &qbsProduct)
+ {
+ Q_UNUSED(qbsProject)
+
+ const auto &qbsProps = qbsProduct.moduleProperties();
+ const auto flags = qbs::KeiluvUtils::cppModuleAssemblerFlags(qbsProps);
+
+ // Don't use standard macro.
+ if (flags.contains(QLatin1String("NOMACRO"), Qt::CaseInsensitive))
+ useStandardMacroProcessor = false;
+
+ // Use MPL.
+ if (flags.contains(QLatin1String("MPL"), Qt::CaseInsensitive))
+ useMacroProcessingLanguage = true;
+
+ // Define 8051 SFR names.
+ if (flags.contains(QLatin1String("NOMOD51"), Qt::CaseInsensitive))
+ suppressSfrNames = true;
+
+ // Define symbols.
+ defineSymbols = qbs::KeiluvUtils::defines(qbsProps);
+ // Include paths.
+ includePaths = qbs::KeiluvUtils::includes(qbsProps);
+
+ // Interpret other assembler flags as a misc controls (exclude only
+ // that flags which are was already handled).
+ for (const auto &flag : flags) {
+ if (flag.compare(QLatin1String("NOMACRO"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("MACRO"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("NOMPL"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("MPL"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("NOMOD51"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("MOD51"),
+ Qt::CaseInsensitive) == 0
+ ) {
+ continue;
+ }
+ miscControls.push_back(flag);
+ }
+ }
+
+ int useStandardMacroProcessor = true;
+ int useMacroProcessingLanguage = false;
+ int suppressSfrNames = false;
+ QStringList defineSymbols;
+ QStringList includePaths;
+ QStringList miscControls;
+};
+
+} // namespace
+
+Mcs51TargetAssemblerGroup::Mcs51TargetAssemblerGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("Ax51")
+{
+ const AssemblerPageOptions opts(qbsProject, qbsProduct);
+
+ // Add 'Macro processor (Standard)'
+ appendProperty(QByteArrayLiteral("UseStandard"),
+ opts.useStandardMacroProcessor);
+ // Add 'Macro processor (MPL)'
+ appendProperty(QByteArrayLiteral("UseMpl"),
+ opts.useMacroProcessingLanguage);
+ // Add 'Define 8051 SFR names'
+ appendProperty(QByteArrayLiteral("UseMod51"),
+ opts.suppressSfrNames);
+
+ // Add other various controls.
+ // Note: A sub-items order makes sense!
+ const auto variousControlsGroup = appendChild<KeiluvPropertyGroup>(
+ QByteArrayLiteral("VariousControls"));
+ // Add 'Misc Controls' item.
+ variousControlsGroup->appendMultiLineProperty(
+ QByteArrayLiteral("MiscControls"),
+ opts.miscControls, QLatin1Char(' '));
+ // Add 'Define' item.
+ variousControlsGroup->appendMultiLineProperty(
+ QByteArrayLiteral("Define"),
+ opts.defineSymbols);
+ // Add an empty 'Undefine' item.
+ variousControlsGroup->appendProperty(
+ QByteArrayLiteral("Undefine"), {});
+ // Add 'Include Paths' item.
+ variousControlsGroup->appendMultiLineProperty(
+ QByteArrayLiteral("IncludePath"),
+ opts.includePaths, QLatin1Char(';'));
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetassemblergroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetassemblergroup_v5.h
new file mode 100644
index 000000000..8a183c30b
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetassemblergroup_v5.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_KEILUVMCS51TARGETASSEMBLERGROUP_V3
+#define QBS_KEILUVMCS51TARGETASSEMBLERGROUP_V3
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51TargetAssemblerGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51TargetAssemblerGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51TARGETASSEMBLERGROUP_V3
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcommonoptionsgroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcommonoptionsgroup_v5.cpp
new file mode 100644
index 000000000..00d15d34b
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcommonoptionsgroup_v5.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** 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 "mcs51targetcommonoptionsgroup_v5.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+namespace {
+
+struct CommonPageOptions final
+{
+ explicit CommonPageOptions(const Project &qbsProject,
+ const ProductData &qbsProduct)
+ {
+ Q_UNUSED(qbsProject)
+
+ const auto &qbsProps = qbsProduct.moduleProperties();
+ const auto flags = KeiluvUtils::cppModuleCompilerFlags(qbsProps);
+
+ // Browse information.
+ if (flags.contains(QLatin1String("BROWSE"), Qt::CaseInsensitive))
+ browseInfo = true;
+
+ // Debug information.
+ debugInfo = KeiluvUtils::debugInformation(qbsProduct);
+
+ // Output parameters.
+ executableName = KeiluvUtils::targetBinary(qbsProduct);
+ // Fix output binary name if it is a library. Because
+ // the IDE appends an additional suffix (.LIB) to end
+ // of an output library name.
+ if (executableName.endsWith(QLatin1String(".lib")))
+ executableName = qbsProduct.targetName();
+
+
+ const QString baseDirectory = KeiluvUtils::buildRootPath(qbsProject);
+ objectDirectory = KeiluvUtils::objectsOutputDirectory(
+ baseDirectory, qbsProduct);
+ listingDirectory = KeiluvUtils::listingOutputDirectory(
+ baseDirectory, qbsProduct);
+
+ // Target type.
+ targetType = KeiluvUtils::outputBinaryType(qbsProduct);
+ }
+
+ int browseInfo = false;
+ int debugInfo = false;
+ QString executableName;
+ QString objectDirectory;
+ QString listingDirectory;
+ KeiluvUtils::OutputBinaryType targetType =
+ KeiluvUtils::ApplicationOutputType;
+};
+
+} // namespace
+
+Mcs51TargetCommonOptionsGroup::Mcs51TargetCommonOptionsGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("TargetCommonOption")
+{
+ const CommonPageOptions opts(qbsProject, qbsProduct);
+
+ // Add 'Generic 8051 device' items,
+ // because we can't detect a target device
+ // form the present command lines.
+ appendProperty(QByteArrayLiteral("Device"),
+ QByteArrayLiteral("8051 (all Variants)"));
+ appendProperty(QByteArrayLiteral("Vendor"),
+ QByteArrayLiteral("Generic"));
+ appendProperty(QByteArrayLiteral("DeviceId"),
+ QByteArrayLiteral("2994"));
+
+ // Add 'Debug Information' item.
+ appendProperty(QByteArrayLiteral("DebugInformation"),
+ opts.debugInfo);
+ // Add 'Browse Information' item.
+ appendProperty(QByteArrayLiteral("BrowseInformation"),
+ opts.browseInfo);
+
+ // Add 'Name of Executable'.
+ appendProperty(QByteArrayLiteral("OutputName"),
+ opts.executableName);
+ // Add 'Output objects directory'.
+ appendProperty(QByteArrayLiteral("OutputDirectory"),
+ opts.objectDirectory);
+ // Add 'Output listing directory'.
+ appendProperty(QByteArrayLiteral("ListingPath"),
+ opts.listingDirectory);
+
+ // Add 'Create Executable/Library' item.
+ const int isExecutable = (opts.targetType
+ == KeiluvUtils::ApplicationOutputType);
+ const int isLibrary = (opts.targetType
+ == KeiluvUtils::LibraryOutputType);
+ appendProperty(QByteArrayLiteral("CreateExecutable"),
+ isExecutable);
+ appendProperty(QByteArrayLiteral("CreateLib"),
+ isLibrary);
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcommonoptionsgroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcommonoptionsgroup_v5.h
new file mode 100644
index 000000000..7535b3373
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcommonoptionsgroup_v5.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_KEILUVMCS51TARGETCOMMONOPTIONSGROUP_V5_H
+#define QBS_KEILUVMCS51TARGETCOMMONOPTIONSGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51TargetCommonOptionsGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51TargetCommonOptionsGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51TARGETCOMMONOPTIONSGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcompilergroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcompilergroup_v5.cpp
new file mode 100644
index 000000000..76a246508
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcompilergroup_v5.cpp
@@ -0,0 +1,281 @@
+/****************************************************************************
+**
+** 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 "mcs51targetcompilergroup_v5.h"
+#include "mcs51utils.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+namespace {
+
+struct CompilerPageOptions final
+{
+ enum WarningLevel {
+ WarningLevelNone = 0,
+ WarningLevelOne,
+ WarningLevelTwo
+ };
+
+ enum OptimizationLevel {
+ ConstantFoldingOptimizationLevel = 0,
+ DeadCodeEliminationOptimizationLevel,
+ DataOverlayingOptimizationLevel,
+ PeepholeOptimizationLevel,
+ RegisterVariablesOptimizationLevel,
+ CommonSubexpressionEliminationOptimizationLevel,
+ LoopRotationOptimizationLevel,
+ ExtendedIndexAccessOptimizationLevel,
+ ReuseCommonEntryCodeOptimizationLevel,
+ CommonBlockSubroutinesOptimizationLevel,
+ RearrangeCodeOptimizationLevel,
+ ReuseCommonExitCodeOptimizationLevel
+ };
+
+ enum OptimizationEmphasis {
+ FavorSizeOptimizationEmphasis = 0,
+ FavorSpeedOptimizationEmphasis
+ };
+
+ enum FloatFuzzyBits {
+ NoFloatFuzzyBits = 0,
+ OneFloatFuzzyBit,
+ TwoFloatFuzzyBits,
+ ThreeFloatFuzzyBits,
+ FourFloatFuzzyBits,
+ FiveFloatFuzzyBits,
+ SixFloatFuzzyBits,
+ SevenFloatFuzzyBits
+ };
+
+ explicit CompilerPageOptions(const Project &qbsProject,
+ const ProductData &qbsProduct)
+ {
+ Q_UNUSED(qbsProject)
+
+ const auto &qbsProps = qbsProduct.moduleProperties();
+ const auto flags = qbs::KeiluvUtils::cppModuleCompilerFlags(qbsProps);
+
+ // Warnings.
+ const QString level = qbs::KeiluvUtils::cppStringModuleProperty(
+ qbsProps, QStringLiteral("warningLevel"));
+ if (level == QLatin1String("none")) {
+ warningLevel = WarningLevelNone;
+ } else if (level == QLatin1String("all")) {
+ warningLevel = WarningLevelTwo;
+ } else {
+ // In this case take it directly from the compiler command line,
+ // e.g. parse the line in a form: 'WARNINGLEVEL (2)'
+ const auto warnValue = KeiluvUtils::flagValue(
+ flags, QStringLiteral("WARNINGLEVEL"));
+ bool ok = false;
+ const auto level = warnValue.toInt(&ok);
+ if (ok && qbs::KeiluvUtils::inBounds(
+ level, int(WarningLevelNone),int(WarningLevelTwo))) {
+ warningLevel = static_cast<WarningLevel>(level);
+ }
+ }
+
+ // Optimizations.
+ const QString optimization = qbs::KeiluvUtils::cppStringModuleProperty(
+ qbsProps, QStringLiteral("optimization"));
+ if (optimization == QLatin1String("fast")) {
+ optimizationEmphasis = FavorSpeedOptimizationEmphasis;
+ } else if (level == QLatin1String("small")) {
+ optimizationEmphasis = FavorSizeOptimizationEmphasis;
+ } else if (level == QLatin1String("small")) {
+ // Don't supported by C51 compiler.
+ } else {
+ // In this case take it directly from the compiler command line,
+ // e.g. parse the line in a form: 'OPTIMIZE (8, SPEED)'
+ const auto optValue = KeiluvUtils::flagValue(
+ flags, QStringLiteral("OPTIMIZE"));
+ const auto parts = KeiluvUtils::flagValueParts(optValue);
+ for (const auto &part : parts) {
+ bool ok = false;
+ const auto level = part.toInt(&ok);
+ if (ok && (level >= ConstantFoldingOptimizationLevel)
+ && (level <= ReuseCommonExitCodeOptimizationLevel)) {
+ optimizationLevel = static_cast<OptimizationLevel>(level);
+ } else if (part.compare(QLatin1String("SIZE"),
+ Qt::CaseInsensitive) == 0) {
+ optimizationEmphasis = FavorSizeOptimizationEmphasis;
+ } else if (part.compare(QLatin1String("SPEED"),
+ Qt::CaseInsensitive) == 0) {
+ optimizationEmphasis = FavorSpeedOptimizationEmphasis;
+ }
+ }
+ }
+
+ // Don't use absolute register accesses.
+ if (flags.contains(QLatin1String("NOAREGS"), Qt::CaseInsensitive))
+ dontuseAbsoluteRegsAccess = true;
+
+ // Enable ANSI integer promotion rules.
+ if (flags.contains(QLatin1String("NOINTPROMOTE"), Qt::CaseInsensitive))
+ enableIntegerPromotionRules = false;
+
+ // Keep variables in order.
+ if (flags.contains(QLatin1String("ORDER"), Qt::CaseInsensitive))
+ keepVariablesInOrder = true;
+
+ // Don't use interrupt vector.
+ if (flags.contains(QLatin1String("NOINTVECTOR"), Qt::CaseInsensitive))
+ useInterruptVector = false;
+
+ // Interrupt vector address.
+ interruptVectorAddress = KeiluvUtils::flagValue(
+ flags, QStringLiteral("INTVECTOR"));
+
+ // Float fuzzy bits count.
+ const auto bitsValue = KeiluvUtils::flagValue(
+ flags, QStringLiteral("FLOATFUZZY"));
+ bool ok = false;
+ const auto bits = bitsValue.toInt(&ok);
+ if (ok && qbs::KeiluvUtils::inBounds(
+ bits, int(NoFloatFuzzyBits), int(SevenFloatFuzzyBits))) {
+ floatFuzzyBits = static_cast<FloatFuzzyBits>(bits);
+ }
+
+ // Define symbols.
+ defineSymbols = qbs::KeiluvUtils::defines(qbsProps);
+ // Include paths.
+ includePaths = qbs::KeiluvUtils::includes(qbsProps);
+
+ // Interpret other compiler flags as a misc controls (exclude only
+ // that flags which are was already handled).
+ for (const auto &flag : flags) {
+ if (flag.startsWith(QLatin1String("WARNINGLEVEL"),
+ Qt::CaseInsensitive)
+ || flag.startsWith(QLatin1String("OPTIMIZE"),
+ Qt::CaseInsensitive)
+ || flag.startsWith(QLatin1String("FLOATFUZZY"),
+ Qt::CaseInsensitive)
+ || flag.compare(QLatin1String("NOAREGS"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("AREGS"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("NOINTPROMOTE"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("INTPROMOTE"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("NOINTVECTOR"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("INTVECTOR"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("ORDER"),
+ Qt::CaseInsensitive) == 0
+ || flag.compare(QLatin1String("BROSWE"),
+ Qt::CaseInsensitive) == 0
+ ) {
+ continue;
+ }
+ miscControls.push_back(flag);
+ }
+ }
+
+ WarningLevel warningLevel = WarningLevelTwo;
+ OptimizationLevel optimizationLevel = ReuseCommonEntryCodeOptimizationLevel;
+ OptimizationEmphasis optimizationEmphasis = FavorSpeedOptimizationEmphasis;
+ FloatFuzzyBits floatFuzzyBits = ThreeFloatFuzzyBits;
+ int dontuseAbsoluteRegsAccess = false;
+ int enableIntegerPromotionRules = true;
+ int keepVariablesInOrder = false;
+ int useInterruptVector = true;
+ QString interruptVectorAddress;
+ QStringList defineSymbols;
+ QStringList includePaths;
+ QStringList miscControls;
+};
+
+} // namespace
+
+Mcs51TargetCompilerGroup::Mcs51TargetCompilerGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("C51")
+{
+ const CompilerPageOptions opts(qbsProject, qbsProduct);
+
+ // Add 'Code Optimization' options.
+ appendProperty(QByteArrayLiteral("Optimize"),
+ opts.optimizationLevel);
+ appendProperty(QByteArrayLiteral("SizeSpeed"),
+ opts.optimizationEmphasis);
+ // Add 'Warnings' options.
+ appendProperty(QByteArrayLiteral("WarningLevel"),
+ opts.warningLevel);
+ // Add 'Don't use absolute register access' item.
+ appendProperty(QByteArrayLiteral("uAregs"),
+ opts.dontuseAbsoluteRegsAccess);
+ // Add 'Enable integer promotion rules' item.
+ appendProperty(QByteArrayLiteral("IntegerPromotion"),
+ opts.enableIntegerPromotionRules);
+ // Add 'Keep variables in order' item.
+ appendProperty(QByteArrayLiteral("VariablesInOrder"),
+ opts.keepVariablesInOrder);
+ // Add 'Use interrupt vector' item.
+ appendProperty(QByteArrayLiteral("UseInterruptVector"),
+ opts.useInterruptVector);
+ appendProperty(QByteArrayLiteral("InterruptVectorAddress"),
+ opts.interruptVectorAddress);
+ // Add 'Float fuzzy bits' item.
+ appendProperty(QByteArrayLiteral("Fuzzy"),
+ opts.floatFuzzyBits);
+
+ // Add other various controls.
+ // Note: A sub-items order makes sense!
+ const auto variousControlsGroup = appendChild<KeiluvPropertyGroup>(
+ QByteArrayLiteral("VariousControls"));
+ // Add 'Misc Controls' item.
+ variousControlsGroup->appendMultiLineProperty(
+ QByteArrayLiteral("MiscControls"),
+ opts.miscControls, QLatin1Char(' '));
+ // Add 'Define' item.
+ variousControlsGroup->appendMultiLineProperty(
+ QByteArrayLiteral("Define"),
+ opts.defineSymbols);
+ // Add an empty 'Undefine' item.
+ variousControlsGroup->appendProperty(
+ QByteArrayLiteral("Undefine"), {});
+ // Add 'Include Paths' item.
+ variousControlsGroup->appendMultiLineProperty(
+ QByteArrayLiteral("IncludePath"),
+ opts.includePaths, QLatin1Char(';'));
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcompilergroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcompilergroup_v5.h
new file mode 100644
index 000000000..801f79ee6
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetcompilergroup_v5.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_KEILUVMCS51TARGETCOMPILERGROUP_V5_H
+#define QBS_KEILUVMCS51TARGETCOMPILERGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51TargetCompilerGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51TargetCompilerGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51TARGETCOMPILERGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetgroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetgroup_v5.cpp
new file mode 100644
index 000000000..ec583aa29
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetgroup_v5.cpp
@@ -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.
+**
+****************************************************************************/
+
+#include "mcs51targetassemblergroup_v5.h"
+#include "mcs51targetcompilergroup_v5.h"
+#include "mcs51targetgroup_v5.h"
+#include "mcs51targetlinkergroup_v5.h"
+#include "mcs51targetmiscgroup_v5.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+Mcs51TargetGroup::Mcs51TargetGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("Target51")
+{
+ appendChild<Mcs51TargetMiscGroup>(qbsProject, qbsProduct);
+ appendChild<Mcs51TargetCompilerGroup>(qbsProject, qbsProduct);
+ appendChild<Mcs51TargetAssemblerGroup>(qbsProject, qbsProduct);
+ appendChild<Mcs51TargetLinkerGroup>(qbsProject, qbsProduct);
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetgroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetgroup_v5.h
new file mode 100644
index 000000000..989e50991
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetgroup_v5.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_KEILUVMCS51TARGETGROUP_V5_H
+#define QBS_KEILUVMCS51TARGETGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51TargetGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51TargetGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51TARGETGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetlinkergroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetlinkergroup_v5.cpp
new file mode 100644
index 000000000..6e5f807a5
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetlinkergroup_v5.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** 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 "mcs51targetlinkergroup_v5.h"
+#include "mcs51utils.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+namespace {
+
+struct LinkerPageOptions final
+{
+ explicit LinkerPageOptions(const Project &qbsProject,
+ const ProductData &qbsProduct)
+ {
+ Q_UNUSED(qbsProject)
+
+ const auto &qbsProps = qbsProduct.moduleProperties();
+ const auto flags = qbs::KeiluvUtils::cppModuleLinkerFlags(qbsProps);
+
+ // Handle all 'BIT' memory flags.
+ parseMemory(flags, QStringLiteral("BIT"),
+ bitAddresses, bitSegments);
+ // Handle all 'CODE' memory flags.
+ parseMemory(flags, QStringLiteral("CODE"),
+ codeAddresses, codeSegments);
+ // Handle all 'DATA' memory flags.
+ parseMemory(flags, QStringLiteral("DATA"),
+ dataAddresses, dataSegments);
+ // Handle all 'IDATA' memory flags.
+ parseMemory(flags, QStringLiteral("IDATA"),
+ idataAddresses, idataSegments);
+ // Handle all 'PDATA' memory flags.
+ parseMemory(flags, QStringLiteral("PDATA"),
+ pdataAddresses, pdataSegments);
+ // Handle all 'XDATA' memory flags.
+ parseMemory(flags, QStringLiteral("XDATA"),
+ xdataAddresses, xdataSegments);
+
+ // Enumerate all flags in a form like:
+ // 'PRECEDE(foo, bar) PRECEDE(baz)'.
+ const auto precedeValues = KeiluvUtils::flagValues(
+ flags, QStringLiteral("PRECEDE"));
+ for (const auto &precedeValue : precedeValues) {
+ const auto parts = KeiluvUtils::flagValueParts(precedeValue);
+ precedeSegments.reserve(precedeSegments.size() + parts.count());
+ std::copy(parts.cbegin(), parts.cend(),
+ std::back_inserter(precedeSegments));
+ }
+
+ // Enumerate all flags in a form like:
+ // 'STACK(foo, bar) STACK(baz)'.
+ const auto stackValues = KeiluvUtils::flagValues(
+ flags, QStringLiteral("STACK"));
+ for (const auto &stackValue : stackValues) {
+ const auto parts = KeiluvUtils::flagValueParts(stackValue);
+ stackSegments.reserve(stackSegments.size() + parts.count());
+ std::copy(parts.cbegin(), parts.cend(),
+ std::back_inserter(stackSegments));
+ }
+
+ // Interpret other linker flags as a misc controls (exclude only
+ // that flags which are was already handled).
+ for (const auto &flag : flags) {
+ if (flag.startsWith(QLatin1String("BIT"),
+ Qt::CaseInsensitive)
+ || flag.startsWith(QLatin1String("CODE"),
+ Qt::CaseInsensitive)
+ || flag.startsWith(QLatin1String("DATA"),
+ Qt::CaseInsensitive)
+ || flag.startsWith(QLatin1String("IDATA"),
+ Qt::CaseInsensitive)
+ || flag.startsWith(QLatin1String("PDATA"),
+ Qt::CaseInsensitive)
+ || flag.startsWith(QLatin1String("XDATA"),
+ Qt::CaseInsensitive)
+ || flag.startsWith(QLatin1String("PRECEDE"),
+ Qt::CaseInsensitive)
+ || flag.startsWith(QLatin1String("STACK"),
+ Qt::CaseInsensitive)
+ ) {
+ continue;
+ }
+ miscControls.push_back(flag);
+ }
+ }
+
+ static void parseMemory(const QStringList &flags,
+ const QString &flagKey,
+ QStringList &destAddresses,
+ QStringList &destSegments)
+ {
+ // Handle all flags in a form like:
+ // 'FLAGKEY(0x00-0x20, 30, foo, bar(0x40)) FLAGKEY(baz)'.
+ const auto values = KeiluvUtils::flagValues(flags, flagKey);
+ for (const auto &value : values) {
+ const auto parts = KeiluvUtils::flagValueParts(value);
+ for (const auto &part : parts) {
+ if (part.contains(QLatin1Char('-'))) {
+ // Seems, it is an address range.
+ destAddresses.push_back(part);
+ } else {
+ // Check on address (specified in decimal
+ // or hexadecimal form).
+ bool ok = false;
+ part.toInt(&ok, 16);
+ if (!ok)
+ part.toInt(&ok, 10);
+ if (ok) {
+ // Seems, it is just a single address.
+ destAddresses.push_back(part);
+ } else {
+ // Seems it is a segment name.
+ destSegments.push_back(part);
+ }
+ }
+ }
+ }
+ }
+
+ QStringList bitAddresses;
+ QStringList bitSegments;
+ QStringList codeAddresses;
+ QStringList codeSegments;
+ QStringList dataAddresses;
+ QStringList dataSegments;
+ QStringList idataAddresses;
+ QStringList idataSegments;
+ QStringList pdataAddresses;
+ QStringList pdataSegments;
+ QStringList xdataAddresses;
+ QStringList xdataSegments;
+
+ QStringList precedeSegments;
+ QStringList stackSegments;
+
+ QStringList miscControls;
+};
+
+} // namespace
+
+Mcs51TargetLinkerGroup::Mcs51TargetLinkerGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("Lx51")
+{
+ const LinkerPageOptions opts(qbsProject, qbsProduct);
+
+ // Add 'Misc Controls' item.
+ appendMultiLineProperty(QByteArrayLiteral("MiscControls"),
+ opts.miscControls, QLatin1Char(' '));
+
+ // Add 'Use Memory Layout from Target Dialog' item.
+ // Note: we always disable it, as we expect that
+ // the layout will be specified from the linker's
+ // command line.
+ appendProperty(QByteArrayLiteral("UseMemoryFromTarget"),
+ 0);
+
+ // Add 'Bit Range' item.
+ appendMultiLineProperty(QByteArrayLiteral("BitBaseAddress"),
+ opts.bitAddresses);
+ // Add 'Code Range' item.
+ appendMultiLineProperty(QByteArrayLiteral("CodeBaseAddress"),
+ opts.codeAddresses);
+ // Add 'Data Range' item.
+ appendMultiLineProperty(QByteArrayLiteral("DataBaseAddress"),
+ opts.dataAddresses);
+ // Add 'IData Range' item.
+ appendMultiLineProperty(QByteArrayLiteral("IDataBaseAddress"),
+ opts.idataAddresses);
+ // Add 'PData Range' item.
+ appendMultiLineProperty(QByteArrayLiteral("PDataBaseAddress"),
+ opts.pdataAddresses);
+ // Add 'XData Range' item.
+ appendMultiLineProperty(QByteArrayLiteral("XDataBaseAddress"),
+ opts.xdataAddresses);
+
+ // Add 'Bit Segment' item.
+ appendMultiLineProperty(QByteArrayLiteral("BitSegmentName"),
+ opts.bitSegments);
+ // Add 'Code Segment' item.
+ appendMultiLineProperty(QByteArrayLiteral("CodeSegmentName"),
+ opts.codeSegments);
+ // Add 'Data Segment' item.
+ appendMultiLineProperty(QByteArrayLiteral("DataSegmentName"),
+ opts.dataSegments);
+ // Add 'IData Segment' item.
+ appendMultiLineProperty(QByteArrayLiteral("IDataSegmentName"),
+ opts.idataSegments);
+
+ // Note: PData has not segments!
+
+ // Add 'XData Segment' item.
+ appendMultiLineProperty(QByteArrayLiteral("XDataSegmentName"),
+ opts.xdataSegments);
+ // Add 'Precede' item.
+ appendMultiLineProperty(QByteArrayLiteral("Precede"),
+ opts.precedeSegments);
+ // Add 'Stack' item.
+ appendMultiLineProperty(QByteArrayLiteral("Stack"),
+ opts.stackSegments);
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetlinkergroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetlinkergroup_v5.h
new file mode 100644
index 000000000..d9bbcea4b
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetlinkergroup_v5.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_KEILUVMCS51TARGETLINKERGROUP_V5_H
+#define QBS_KEILUVMCS51TARGETLINKERGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51TargetLinkerGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51TargetLinkerGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51TARGETLINKERGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetmiscgroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetmiscgroup_v5.cpp
new file mode 100644
index 000000000..193330864
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetmiscgroup_v5.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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 "mcs51targetmiscgroup_v5.h"
+#include "mcs51utils.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+namespace {
+
+struct MiscPageOptions final
+{
+ enum MemoryModel {
+ SmallMemoryModel = 0,
+ CompactMemoryModel,
+ LargeMemoryModel
+ };
+
+ enum CodeRomSize {
+ SmallCodeRomSize = 0,
+ CompactCodeRomSize,
+ LargeCodeRomSize
+ };
+
+ explicit MiscPageOptions(const Project &qbsProject,
+ const ProductData &qbsProduct)
+ {
+ Q_UNUSED(qbsProject)
+
+ const auto &qbsProps = qbsProduct.moduleProperties();
+ const auto flags = qbs::KeiluvUtils::cppModuleCompilerFlags(qbsProps);
+
+ // Memory model.
+ if (flags.contains(QLatin1String("COMPACT"), Qt::CaseInsensitive))
+ memoryModel = CompactMemoryModel;
+ else if (flags.contains(QLatin1String("LARGE"), Qt::CaseInsensitive))
+ memoryModel = LargeMemoryModel;
+
+ // Code ROM size.
+ const auto sizeValue = KeiluvUtils::flagValue(
+ flags, QStringLiteral("ROM"));
+ if (sizeValue == QLatin1String("SMALL"))
+ coderomSize = SmallCodeRomSize;
+ else if (sizeValue == QLatin1String("COMPACT"))
+ coderomSize = CompactCodeRomSize;
+ }
+
+ MemoryModel memoryModel = SmallMemoryModel;
+ CodeRomSize coderomSize = LargeCodeRomSize;
+};
+
+} // namespace
+
+Mcs51TargetMiscGroup::Mcs51TargetMiscGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("Target51Misc")
+{
+ const MiscPageOptions opts(qbsProject, qbsProduct);
+
+ // Add 'Memory Model' options item.
+ appendProperty(QByteArrayLiteral("MemoryModel"),
+ opts.memoryModel);
+ // Add 'ROM Size' options item.
+ appendProperty(QByteArrayLiteral("RomSize"),
+ opts.coderomSize);
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51targetmiscgroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetmiscgroup_v5.h
new file mode 100644
index 000000000..e1dfd4a56
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51targetmiscgroup_v5.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_KEILUVMCS51TARGETMISCGROUP_V5_H
+#define QBS_KEILUVMCS51TARGETMISCGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51TargetMiscGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51TargetMiscGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51TARGETMISCGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51utilitiesgroup_v5.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51utilitiesgroup_v5.cpp
new file mode 100644
index 000000000..380876e51
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51utilitiesgroup_v5.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 "mcs51utilitiesgroup_v5.h"
+
+#include "../../keiluvutils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+Mcs51UtilitiesGroup::Mcs51UtilitiesGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct)
+ : KeiluvPropertyGroup("Utilities")
+{
+ Q_UNUSED(qbsProject)
+ Q_UNUSED(qbsProduct)
+}
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51utilitiesgroup_v5.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51utilitiesgroup_v5.h
new file mode 100644
index 000000000..4345bd981
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51utilitiesgroup_v5.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_KEILUVMCS51UTILITIESGROUP_V5_H
+#define QBS_KEILUVMCS51UTILITIESGROUP_V5_H
+
+#include "../../keiluvpropertygroup.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+namespace v5 {
+
+class Mcs51UtilitiesGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit Mcs51UtilitiesGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct);
+};
+
+} // namespace v5
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51UTILITIESGROUP_V5_H
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51utils.cpp b/src/plugins/generator/keiluv/archs/mcs51/mcs51utils.cpp
new file mode 100644
index 000000000..698f0df78
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51utils.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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 "mcs51utils.h"
+
+namespace qbs {
+namespace keiluv {
+namespace mcs51 {
+
+namespace KeiluvUtils {
+
+static QString extractValue(const QString &flag)
+{
+ const auto openBracketIndex = flag.indexOf(QLatin1Char('('));
+ const auto closeBracketIndex = flag.indexOf(QLatin1Char(')'));
+ const auto n = closeBracketIndex - openBracketIndex - 1;
+ return flag.mid(openBracketIndex + 1, n);
+}
+
+QStringList flagValues(const QStringList &flags, const QString &flagKey)
+{
+ QStringList values;
+ for (const auto &flag : flags) {
+ if (!flag.startsWith(flagKey, Qt::CaseInsensitive))
+ continue;
+ const auto value = extractValue(flag);
+ values.push_back(value);
+ }
+ return values;
+}
+
+QString flagValue(const QStringList &flags, const QString &flagKey)
+{
+ const auto flagEnd = flags.cend();
+ const auto flagIt = std::find_if(flags.cbegin(), flagEnd,
+ [flagKey](const auto &flag) {
+ return flag.startsWith(flagKey, Qt::CaseInsensitive);
+ });
+ if (flagIt == flagEnd)
+ return {}; // Flag key not found.
+ return extractValue(*flagIt);
+}
+
+QStringList flagValueParts(const QString &flagValue, const QLatin1Char &sep)
+{
+ auto parts = flagValue.split(sep);
+ std::transform(parts.begin(), parts.end(), parts.begin(),
+ [](const auto &part) { return part.trimmed(); });
+ return parts;
+}
+
+} // namespace KeiluvUtils
+
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/archs/mcs51/mcs51utils.h b/src/plugins/generator/keiluv/archs/mcs51/mcs51utils.h
new file mode 100644
index 000000000..f6ed7e4eb
--- /dev/null
+++ b/src/plugins/generator/keiluv/archs/mcs51/mcs51utils.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_KEILUVMCS51UTILS_H
+#define QBS_KEILUVMCS51UTILS_H
+
+#include <QtCore/qstringlist.h>
+
+namespace qbs {
+
+namespace keiluv {
+namespace mcs51 {
+
+namespace KeiluvUtils {
+
+QStringList flagValues(const QStringList &flags, const QString &flagKey);
+
+QString flagValue(const QStringList &flags, const QString &flagKey);
+
+QStringList flagValueParts(const QString &flagValue,
+ const QLatin1Char &sep = QLatin1Char(','));
+
+} // namespace KeiluvUtils
+
+namespace v5 {
+
+namespace KeiluvConstants {
+
+constexpr int kUVisionVersion = 5;
+
+} // namespace KeiluvConstants
+
+} // namespace v5
+
+} // namespace mcs51
+} // namespace keiluv
+} // namespace qbs
+
+#endif // QBS_KEILUVMCS51UTILS_H
+
diff --git a/src/plugins/generator/keiluv/ikeiluvnodevisitor.h b/src/plugins/generator/keiluv/ikeiluvnodevisitor.h
new file mode 100644
index 000000000..8ba14d11f
--- /dev/null
+++ b/src/plugins/generator/keiluv/ikeiluvnodevisitor.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_IKEILUVNODEVISITOR_H
+#define QBS_IKEILUVNODEVISITOR_H
+
+#include <QtCore/qxmlstream.h>
+
+#include <memory>
+
+namespace qbs {
+
+class KeiluvProject;
+class KeiluvProperty;
+class KeiluvPropertyGroup;
+class KeiluvWorkspace;
+
+class IKeiluvNodeVisitor
+{
+public:
+ virtual ~IKeiluvNodeVisitor() {}
+
+ virtual void visitStart(const KeiluvWorkspace *workspace) { Q_UNUSED(workspace) }
+ virtual void visitEnd(const KeiluvWorkspace *workspace) { Q_UNUSED(workspace) }
+
+ virtual void visitStart(const KeiluvProject *project) { Q_UNUSED(project) }
+ virtual void visitEnd(const KeiluvProject *project) { Q_UNUSED(project) }
+
+ virtual void visitStart(const KeiluvProperty *property) = 0;
+ virtual void visitEnd(const KeiluvProperty *property) = 0;
+
+ virtual void visitStart(const KeiluvPropertyGroup *propertyGroup) = 0;
+ virtual void visitEnd(const KeiluvPropertyGroup *propertyGroup) = 0;
+};
+
+} // namespace qbs
+
+#endif // QBS_IKEILUVNODEVISITOR_H
diff --git a/src/plugins/generator/keiluv/keiluv.pro b/src/plugins/generator/keiluv/keiluv.pro
new file mode 100644
index 000000000..99bf44d54
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluv.pro
@@ -0,0 +1,68 @@
+include(../../plugins.pri)
+include(../../../shared/json/json.pri)
+
+TARGET = keiluvgenerator
+
+QT = core
+
+# Plugin file.
+
+SOURCES += \
+ $$PWD/keiluvgeneratorplugin.cpp \
+
+# Common files.
+
+HEADERS += \
+ $$PWD/ikeiluvnodevisitor.h \
+ $$PWD/keiluvfilesgroupspropertygroup.h \
+ $$PWD/keiluvgenerator.h \
+ $$PWD/keiluvproject.h \
+ $$PWD/keiluvprojectwriter.h \
+ $$PWD/keiluvproperty.h \
+ $$PWD/keiluvpropertygroup.h \
+ $$PWD/keiluvutils.h \
+ $$PWD/keiluvversioninfo.h \
+ $$PWD/keiluvworkspace.h \
+ $$PWD/keiluvworkspacewriter.h \
+
+SOURCES += \
+ $$PWD/keiluvfilesgroupspropertygroup.cpp \
+ $$PWD/keiluvgenerator.cpp \
+ $$PWD/keiluvproject.cpp \
+ $$PWD/keiluvprojectwriter.cpp \
+ $$PWD/keiluvproperty.cpp \
+ $$PWD/keiluvpropertygroup.cpp \
+ $$PWD/keiluvutils.cpp \
+ $$PWD/keiluvversioninfo.cpp \
+ $$PWD/keiluvworkspace.cpp \
+ $$PWD/keiluvworkspacewriter.cpp \
+
+# For MCS51 architecture.
+
+HEADERS += \
+ $$PWD/archs/mcs51/mcs51buildtargetgroup_v5.h \
+ $$PWD/archs/mcs51/mcs51commonpropertygroup_v5.h \
+ $$PWD/archs/mcs51/mcs51debugoptiongroup_v5.h \
+ $$PWD/archs/mcs51/mcs51dlloptiongroup_v5.h \
+ $$PWD/archs/mcs51/mcs51targetassemblergroup_v5.h \
+ $$PWD/archs/mcs51/mcs51targetcommonoptionsgroup_v5.h \
+ $$PWD/archs/mcs51/mcs51targetcompilergroup_v5.h \
+ $$PWD/archs/mcs51/mcs51targetgroup_v5.h \
+ $$PWD/archs/mcs51/mcs51targetlinkergroup_v5.h \
+ $$PWD/archs/mcs51/mcs51targetmiscgroup_v5.h \
+ $$PWD/archs/mcs51/mcs51utilitiesgroup_v5.h \
+ $$PWD/archs/mcs51/mcs51utils.h \
+
+SOURCES += \
+ $$PWD/archs/mcs51/mcs51buildtargetgroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51commonpropertygroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51debugoptiongroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51dlloptiongroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51targetassemblergroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51targetcommonoptionsgroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51targetcompilergroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51targetgroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51targetlinkergroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51targetmiscgroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51utilitiesgroup_v5.cpp \
+ $$PWD/archs/mcs51/mcs51utils.cpp \
diff --git a/src/plugins/generator/keiluv/keiluv.qbs b/src/plugins/generator/keiluv/keiluv.qbs
new file mode 100644
index 000000000..5734f0538
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluv.qbs
@@ -0,0 +1,67 @@
+import qbs
+import "../../qbsplugin.qbs" as QbsPlugin
+
+QbsPlugin {
+ Depends { name: "qbsjson" }
+
+ name: "keiluvgenerator"
+
+ files: ["keiluvgeneratorplugin.cpp"]
+
+ Group {
+ name: "KEIL UV generator common"
+ files: [
+ "ikeiluvnodevisitor.h",
+ "keiluvfilesgroupspropertygroup.cpp",
+ "keiluvfilesgroupspropertygroup.h",
+ "keiluvgenerator.cpp",
+ "keiluvgenerator.h",
+ "keiluvproject.cpp",
+ "keiluvproject.h",
+ "keiluvprojectwriter.cpp",
+ "keiluvprojectwriter.h",
+ "keiluvproperty.cpp",
+ "keiluvproperty.h",
+ "keiluvpropertygroup.cpp",
+ "keiluvpropertygroup.h",
+ "keiluvutils.cpp",
+ "keiluvutils.h",
+ "keiluvversioninfo.cpp",
+ "keiluvversioninfo.h",
+ "keiluvworkspace.cpp",
+ "keiluvworkspace.h",
+ "keiluvworkspacewriter.cpp",
+ "keiluvworkspacewriter.h",
+ ]
+ }
+ Group {
+ name: "KEIL UV generator for MCS51"
+ prefix: "archs/mcs51/"
+ files: [
+ "mcs51buildtargetgroup_v5.cpp",
+ "mcs51buildtargetgroup_v5.h",
+ "mcs51commonpropertygroup_v5.cpp",
+ "mcs51commonpropertygroup_v5.h",
+ "mcs51debugoptiongroup_v5.cpp",
+ "mcs51debugoptiongroup_v5.h",
+ "mcs51dlloptiongroup_v5.cpp",
+ "mcs51dlloptiongroup_v5.h",
+ "mcs51targetassemblergroup_v5.cpp",
+ "mcs51targetassemblergroup_v5.h",
+ "mcs51targetcommonoptionsgroup_v5.cpp",
+ "mcs51targetcommonoptionsgroup_v5.h",
+ "mcs51targetcompilergroup_v5.cpp",
+ "mcs51targetcompilergroup_v5.h",
+ "mcs51targetgroup_v5.cpp",
+ "mcs51targetgroup_v5.h",
+ "mcs51targetlinkergroup_v5.cpp",
+ "mcs51targetlinkergroup_v5.h",
+ "mcs51targetmiscgroup_v5.cpp",
+ "mcs51targetmiscgroup_v5.h",
+ "mcs51utilitiesgroup_v5.cpp",
+ "mcs51utilitiesgroup_v5.h",
+ "mcs51utils.cpp",
+ "mcs51utils.h",
+ ]
+ }
+}
diff --git a/src/plugins/generator/keiluv/keiluvfilesgroupspropertygroup.cpp b/src/plugins/generator/keiluv/keiluvfilesgroupspropertygroup.cpp
new file mode 100644
index 000000000..137cabe3d
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvfilesgroupspropertygroup.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** 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 "keiluvfilesgroupspropertygroup.h"
+
+#include <generators/generatordata.h>
+
+#include <tools/stringconstants.h>
+
+namespace qbs {
+
+class KeiluvFilePropertyGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit KeiluvFilePropertyGroup(
+ const QString &fullFilePath,
+ const QString &baseDirectory)
+ : KeiluvPropertyGroup("File")
+ {
+ const QFileInfo fileInfo(fullFilePath);
+ const auto fileName = fileInfo.fileName();
+ const auto fileType = encodeFileType(fileInfo.suffix());
+ const auto filePath = KeiluvUtils::relativeFilePath(
+ baseDirectory, fileInfo.absoluteFilePath());
+
+ appendChild<KeiluvProperty>(QByteArrayLiteral("FileName"),
+ fileName);
+ appendChild<KeiluvProperty>(QByteArrayLiteral("FileType"),
+ fileType);
+ appendChild<KeiluvProperty>(QByteArrayLiteral("FilePath"),
+ filePath);
+ }
+
+private:
+ enum FileType {
+ UnknownFileType = 0,
+ CSourceFileType = 1,
+ AssemblerFileType = 2,
+ LibraryFileType = 4,
+ TextFileType = 5,
+ CppSourceFileType = 8,
+ };
+
+ static FileType encodeFileType(const QString &fileSuffix)
+ {
+ if (fileSuffix.compare(QLatin1String("c"),
+ Qt::CaseInsensitive) == 0) {
+ return CSourceFileType;
+ } else if (fileSuffix.compare(QLatin1String("cpp"),
+ Qt::CaseInsensitive) == 0) {
+ return CppSourceFileType;
+ } else if (fileSuffix.compare(QLatin1String("s"),
+ Qt::CaseInsensitive) == 0
+ || fileSuffix.compare(QLatin1String("a51"),
+ Qt::CaseInsensitive) == 0) {
+ return AssemblerFileType;
+ } else if (fileSuffix.compare(QLatin1String("lib"),
+ Qt::CaseInsensitive) == 0) {
+ return LibraryFileType;
+ } else {
+ // All header files, text files and include files
+ // interpretes as a text file types.
+ return TextFileType;
+ }
+ }
+};
+
+class KeiluvFilesPropertyGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit KeiluvFilesPropertyGroup(
+ const QList<ArtifactData> &sourceArtifacts,
+ const QString &baseDirectory)
+ : KeiluvPropertyGroup("Files")
+ {
+ for (const auto &artifact : sourceArtifacts)
+ appendChild<KeiluvFilePropertyGroup>(artifact.filePath(),
+ baseDirectory);
+ }
+
+ explicit KeiluvFilesPropertyGroup(
+ const QStringList &filePaths,
+ const QString &baseDirectory)
+ : KeiluvPropertyGroup("Files")
+ {
+ for (const auto &filePath : filePaths)
+ appendChild<KeiluvFilePropertyGroup>(filePath,
+ baseDirectory);
+ }
+};
+
+class KeiluvFileGroupPropertyGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit KeiluvFileGroupPropertyGroup(
+ const QString &groupName,
+ const QList<ArtifactData> &sourceArtifacts,
+ const QString &baseDirectory)
+ : KeiluvPropertyGroup("Group")
+ {
+ appendChild<KeiluvProperty>(QByteArrayLiteral("GroupName"),
+ groupName);
+
+ appendChild<KeiluvFilesPropertyGroup>(sourceArtifacts,
+ baseDirectory);
+ }
+
+ explicit KeiluvFileGroupPropertyGroup(
+ const QString &groupName,
+ const QStringList &filePaths,
+ const QString &baseDirectory)
+ : KeiluvPropertyGroup("Group")
+ {
+ appendChild<KeiluvProperty>(QByteArrayLiteral("GroupName"),
+ groupName);
+
+ appendChild<KeiluvFilesPropertyGroup>(filePaths,
+ baseDirectory);
+ }
+};
+
+KeiluvFilesGroupsPropertyGroup::KeiluvFilesGroupsPropertyGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps)
+ : KeiluvPropertyGroup(QByteArrayLiteral("Groups"))
+{
+ const auto baseDirectory = KeiluvUtils::buildRootPath(qbsProject);
+
+ // Build source items.
+ const auto groups = qbsProduct.groups();
+ for (const auto &group : groups) {
+ // Ignore disabled groups (e.g. when its condition property is false).
+ if (!group.isEnabled())
+ continue;
+ auto sourceArtifacts = group.sourceArtifacts();
+ // Remove the linker script artifacts.
+ sourceArtifacts.erase(std::remove_if(sourceArtifacts.begin(),
+ sourceArtifacts.end(),
+ [](const auto &artifact){
+ const auto tags = artifact.fileTags();
+ return tags.contains(QLatin1String("linkerscript"));
+ }), sourceArtifacts.end());
+
+ if (sourceArtifacts.isEmpty())
+ continue;
+ appendChild<KeiluvFileGroupPropertyGroup>(
+ group.name(), sourceArtifacts, baseDirectory);
+ }
+
+ // Build local static library items.
+ const auto &qbsProps = qbsProduct.moduleProperties();
+ const auto staticLibs = KeiluvUtils::staticLibraries(qbsProps);
+ if (!staticLibs.isEmpty()) {
+ appendChild<KeiluvFileGroupPropertyGroup>(
+ QStringLiteral("Static Libs"), staticLibs, baseDirectory);
+ }
+
+ // Build dependency library items.
+ const auto deps = KeiluvUtils::dependencies(qbsProductDeps);
+ if (!deps.isEmpty()) {
+ appendChild<KeiluvFileGroupPropertyGroup>(
+ QStringLiteral("Dependencies"), deps, baseDirectory);
+ }
+}
+
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvfilesgroupspropertygroup.h b/src/plugins/generator/keiluv/keiluvfilesgroupspropertygroup.h
new file mode 100644
index 000000000..6ae335875
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvfilesgroupspropertygroup.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** 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_KEILUVFILESGROUPSPROPERTYGROUP_H
+#define QBS_KEILUVFILESGROUPSPROPERTYGROUP_H
+
+#include "keiluvpropertygroup.h"
+
+#include <generators/generatordata.h>
+
+namespace qbs {
+
+class KeiluvFilesGroupsPropertyGroup final : public KeiluvPropertyGroup
+{
+public:
+ explicit KeiluvFilesGroupsPropertyGroup(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps);
+};
+
+} // namespace qbs
+
+#endif // QBS_KEILUVFILESGROUPSPROPERTYGROUP_H
diff --git a/src/plugins/generator/keiluv/keiluvgenerator.cpp b/src/plugins/generator/keiluv/keiluvgenerator.cpp
new file mode 100644
index 000000000..570f7693e
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvgenerator.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** 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 "keiluvgenerator.h"
+#include "keiluvproject.h"
+#include "keiluvprojectwriter.h"
+#include "keiluvworkspace.h"
+#include "keiluvworkspacewriter.h"
+
+#include <generators/generatableprojectiterator.h>
+
+#include <logging/logger.h>
+#include <logging/translator.h>
+
+#include <tools/filesaver.h>
+
+namespace qbs {
+
+static QString targetFilePath(const QString &baseName,
+ const QString &baseBuildDirectory)
+{
+ return QDir(baseBuildDirectory).absoluteFilePath(
+ baseName + QStringLiteral(".uvproj"));
+}
+
+static QString targetFilePath(const GeneratableProductData &product,
+ const QString &baseBuildDirectory)
+{
+ return targetFilePath(product.name(), baseBuildDirectory);
+}
+
+static void writeProjectFiles(const std::map<QString,
+ std::shared_ptr<KeiluvProject>> &projects,
+ const Internal::Logger &logger)
+{
+ for (const auto &item : projects) {
+ const QString projectFilePath = item.first;
+ Internal::FileSaver file(projectFilePath.toStdString());
+ if (!file.open())
+ throw ErrorInfo(Internal::Tr::tr("Cannot open %s for writing")
+ .arg(projectFilePath));
+
+ std::shared_ptr<KeiluvProject> project = item.second;
+ KeiluvProjectWriter writer(file.device());
+ if (!(writer.write(project.get()) && file.commit()))
+ throw ErrorInfo(Internal::Tr::tr("Failed to generate %1")
+ .arg(projectFilePath));
+
+ logger.qbsInfo() << Internal::Tr::tr("Generated %1").arg(
+ QFileInfo(projectFilePath).fileName());
+ }
+}
+
+static void writeWorkspace(const std::shared_ptr<KeiluvWorkspace> &wokspace,
+ const QString &workspaceFilePath,
+ const Internal::Logger &logger)
+{
+ Internal::FileSaver file(workspaceFilePath.toStdString());
+ if (!file.open())
+ throw ErrorInfo(Internal::Tr::tr("Cannot open %s for writing")
+ .arg(workspaceFilePath));
+
+ KeiluvWorkspaceWriter writer(file.device());
+ if (!(writer.write(wokspace.get()) && file.commit()))
+ throw ErrorInfo(Internal::Tr::tr("Failed to generate %1")
+ .arg(workspaceFilePath));
+
+ logger.qbsInfo() << Internal::Tr::tr("Generated %1").arg(
+ QFileInfo(workspaceFilePath).fileName());
+}
+
+KeiluvGenerator::KeiluvGenerator(const KeiluvVersionInfo &versionInfo)
+ : m_versionInfo(versionInfo)
+{
+}
+
+QString KeiluvGenerator::generatorName() const
+{
+ return QStringLiteral("keiluv%1").arg(m_versionInfo.marketingVersion());
+}
+
+void KeiluvGenerator::reset()
+{
+ m_workspace.reset();
+ m_workspaceFilePath.clear();
+ m_projects.clear();
+}
+
+void KeiluvGenerator::generate()
+{
+ GeneratableProjectIterator it(project());
+ it.accept(this);
+
+ writeProjectFiles(m_projects, logger());
+ writeWorkspace(m_workspace, m_workspaceFilePath, logger());
+
+ reset();
+}
+
+void KeiluvGenerator::visitProject(const GeneratableProject &project)
+{
+ const QDir buildDir = project.baseBuildDirectory();
+
+ m_workspaceFilePath = buildDir.absoluteFilePath(
+ project.name() + QStringLiteral(".uvmpw"));
+ m_workspace = std::make_shared<KeiluvWorkspace>(m_workspaceFilePath);
+}
+
+void KeiluvGenerator::visitProjectData(const GeneratableProject &project,
+ const GeneratableProjectData &projectData)
+{
+ Q_UNUSED(project)
+ Q_UNUSED(projectData)
+}
+
+void KeiluvGenerator::visitProduct(const GeneratableProject &project,
+ const GeneratableProjectData &projectData,
+ const GeneratableProductData &productData)
+{
+ Q_UNUSED(projectData);
+ const QString projectFilePath = targetFilePath(
+ productData, project.baseBuildDirectory().absolutePath());
+ const auto targetProject = std::make_shared<KeiluvProject>(project, productData,
+ m_versionInfo);
+
+ m_projects.insert({projectFilePath, targetProject});
+ m_workspace->addProjectPath(projectFilePath);
+}
+
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvgenerator.h b/src/plugins/generator/keiluv/keiluvgenerator.h
new file mode 100644
index 000000000..769519562
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvgenerator.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_KEILUVGENERATOR_H
+#define QBS_KEILUVGENERATOR_H
+
+#include "keiluvversioninfo.h"
+
+#include <generators/generator.h>
+#include <generators/igeneratableprojectvisitor.h>
+
+namespace qbs {
+
+class KeiluvProject;
+class KeiluvWorkspace;
+
+class KeiluvGenerator final : public ProjectGenerator,
+ private IGeneratableProjectVisitor
+{
+public:
+ explicit KeiluvGenerator(const KeiluvVersionInfo &versionInfo);
+
+ QString generatorName() const final;
+ void generate() final;
+
+private:
+ void reset();
+
+ void visitProject(const GeneratableProject &project) final;
+ void visitProjectData(const GeneratableProject &project,
+ const GeneratableProjectData &projectData) final;
+ void visitProduct(const GeneratableProject &project,
+ const GeneratableProjectData &projectData,
+ const GeneratableProductData &productData) final;
+
+ const KeiluvVersionInfo m_versionInfo;
+ std::shared_ptr<KeiluvWorkspace> m_workspace;
+ QString m_workspaceFilePath;
+ std::map<QString, std::shared_ptr<KeiluvProject>> m_projects;
+};
+
+} // namespace qbs
+
+#endif // QBS_KEILUVGENERATOR_H
diff --git a/src/plugins/generator/keiluv/keiluvgeneratorplugin.cpp b/src/plugins/generator/keiluv/keiluvgeneratorplugin.cpp
new file mode 100644
index 000000000..33e552936
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvgeneratorplugin.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "keiluvgenerator.h"
+#include "keiluvversioninfo.h"
+
+#include <tools/projectgeneratormanager.h>
+#include <tools/qbspluginmanager.h>
+
+static void QbsKeiluvGeneratorPluginLoad()
+{
+ for (const auto &info : qbs::KeiluvVersionInfo::knownVersions()) {
+ qbs::ProjectGeneratorManager::registerGenerator(
+ std::make_shared<qbs::KeiluvGenerator>(info));
+ }
+}
+
+static void QbsKeiluvGeneratorPluginUnload()
+{
+}
+
+#ifndef GENERATOR_EXPORT
+#if defined(WIN32) || defined(_WIN32)
+#define GENERATOR_EXPORT __declspec(dllexport)
+#else
+#define GENERATOR_EXPORT __attribute__((visibility("default")))
+#endif
+#endif
+
+QBS_REGISTER_STATIC_PLUGIN(extern "C" GENERATOR_EXPORT, QbsKeiluvGeneratorPlugin,
+ QbsKeiluvGeneratorPluginLoad, QbsKeiluvGeneratorPluginUnload)
diff --git a/src/plugins/generator/keiluv/keiluvproject.cpp b/src/plugins/generator/keiluv/keiluvproject.cpp
new file mode 100644
index 000000000..d9e256bdb
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvproject.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** 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 "ikeiluvnodevisitor.h"
+#include "keiluvproject.h"
+#include "keiluvutils.h"
+#include "keiluvversioninfo.h"
+
+#include "archs/mcs51/mcs51buildtargetgroup_v5.h"
+#include "archs/mcs51/mcs51utils.h"
+
+#include <logging/translator.h>
+
+namespace qbs {
+
+static QString keilProjectSchema(const KeiluvVersionInfo &info)
+{
+ const auto v = info.marketingVersion();
+ switch (v) {
+ case keiluv::mcs51::v5::KeiluvConstants::kUVisionVersion:
+ return QStringLiteral("1.1");
+ default:
+ return {};
+ }
+}
+
+KeiluvProject::KeiluvProject(const GeneratableProject &genProject,
+ const GeneratableProductData &genProduct,
+ const KeiluvVersionInfo &versionInfo)
+{
+ Q_ASSERT(genProject.projects.size() == genProject.commandLines.size());
+ Q_ASSERT(genProject.projects.size() == genProduct.data.size());
+
+ // Create available configuration group factories.
+ m_factories.push_back(std::make_unique<
+ keiluv::mcs51::v5::Mcs51BuildTargetGroupFactory>());
+
+ // Construct schema version item (depends on a project version).
+ const auto schema = keilProjectSchema(versionInfo);
+ appendChild<KeiluvProperty>(QByteArrayLiteral("SchemaVersion"),
+ schema);
+
+ // Construct targets group.
+ const auto targetsGroup = appendChild<KeiluvPropertyGroup>(
+ QByteArrayLiteral("Targets"));
+
+ // Construct all build target items.
+ const int configsCount = std::max(genProject.projects.size(),
+ genProduct.data.size());
+ for (auto configIndex = 0; configIndex < configsCount; ++configIndex) {
+ const Project qbsProject = genProject.projects.values().at(configIndex);
+ const ProductData qbsProduct = genProduct.data.values().at(configIndex);
+ const QString confName = KeiluvUtils::buildConfigurationName(qbsProject);
+ const std::vector<ProductData> qbsProductDeps = KeiluvUtils::dependenciesOf
+ (qbsProduct, genProject, confName);
+
+ const auto arch = KeiluvUtils::architecture(qbsProject);
+ if (arch == KeiluvUtils::Architecture::UnknownArchitecture)
+ throw ErrorInfo(Internal::Tr::tr("Target architecture is not set,"
+ " please use the 'profile' option"));
+
+ // Construct the build target item, which are depend from
+ // the architecture and the version.
+ const auto factoryEnd = m_factories.cend();
+ const auto factoryIt = std::find_if(m_factories.cbegin(), factoryEnd,
+ [arch, versionInfo](const auto &factory) {
+ return factory->canCreate(arch, versionInfo.version());
+ });
+ if (factoryIt == factoryEnd) {
+ throw ErrorInfo(Internal::Tr::tr("Incompatible target architecture '%1'"
+ " for KEIL UV version %2")
+ .arg(KeiluvUtils::architectureName(arch))
+ .arg(versionInfo.marketingVersion()));
+ }
+
+ auto targetGroup = (*factoryIt)->create(
+ qbsProject, qbsProduct, qbsProductDeps);
+ targetsGroup->appendChild(std::move(targetGroup));
+ }
+}
+
+void KeiluvProject::accept(IKeiluvNodeVisitor *visitor) const
+{
+ visitor->visitStart(this);
+
+ for (const auto &child : children())
+ child->accept(visitor);
+
+ visitor->visitEnd(this);
+}
+
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvproject.h b/src/plugins/generator/keiluv/keiluvproject.h
new file mode 100644
index 000000000..fc9893da5
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvproject.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_KEILUVPROJECT_H
+#define QBS_KEILUVPROJECT_H
+
+#include "keiluvproperty.h"
+#include "keiluvpropertygroup.h"
+
+#include <generators/generatordata.h>
+
+#include <memory>
+
+namespace qbs {
+
+class KeiluvVersionInfo;
+
+class KeiluvProject final : public KeiluvProperty
+{
+public:
+ explicit KeiluvProject(const GeneratableProject &genProject,
+ const GeneratableProductData &genProduct,
+ const KeiluvVersionInfo &versionInfo);
+ void accept(IKeiluvNodeVisitor *visitor) const final;
+
+private:
+ std::vector<std::unique_ptr<KeiluvPropertyGroupFactory>> m_factories;
+};
+
+} // namespace qbs
+
+#endif // QBS_KEILUVPROJECT_H
diff --git a/src/plugins/generator/keiluv/keiluvprojectwriter.cpp b/src/plugins/generator/keiluv/keiluvprojectwriter.cpp
new file mode 100644
index 000000000..7f63b4714
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvprojectwriter.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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 "keiluvproject.h"
+#include "keiluvprojectwriter.h"
+#include "keiluvproperty.h"
+#include "keiluvpropertygroup.h"
+
+#include <ostream>
+
+namespace qbs {
+
+KeiluvProjectWriter::KeiluvProjectWriter(std::ostream *device)
+ : m_device(device)
+{
+ m_writer.reset(new QXmlStreamWriter(&m_buffer));
+ m_writer->setAutoFormatting(true);
+}
+
+bool KeiluvProjectWriter::write(const KeiluvProject *project)
+{
+ m_buffer.clear();
+ m_writer->writeStartDocument();
+ project->accept(this);
+ m_writer->writeEndDocument();
+ if (m_writer->hasError())
+ return false;
+ m_device->write(&*std::begin(m_buffer), m_buffer.size());
+ return m_device->good();
+}
+
+void KeiluvProjectWriter::visitStart(const KeiluvProject *project)
+{
+ Q_UNUSED(project)
+ m_writer->writeStartElement(QStringLiteral("Project"));
+ m_writer->writeAttribute(QStringLiteral("xmlns:xsi"),
+ QStringLiteral("http://www.w3.org/2001/XMLSchema-instance"));
+ m_writer->writeAttribute(QStringLiteral("xsi:noNamespaceSchemaLocation"),
+ QStringLiteral("project_proj.xsd"));
+}
+
+void KeiluvProjectWriter::visitEnd(const KeiluvProject *project)
+{
+ Q_UNUSED(project)
+ m_writer->writeEndElement();
+}
+
+void KeiluvProjectWriter::visitStart(const KeiluvProperty *property)
+{
+ const QString stringValue = property->value().toString();
+ m_writer->writeTextElement(QString::fromUtf8(property->name()), stringValue);
+}
+
+void KeiluvProjectWriter::visitEnd(const KeiluvProperty *property)
+{
+ Q_UNUSED(property)
+}
+
+void KeiluvProjectWriter::visitStart(const KeiluvPropertyGroup *propertyGroup)
+{
+ m_writer->writeStartElement(QString::fromUtf8(propertyGroup->name()));
+}
+
+void KeiluvProjectWriter::visitEnd(const KeiluvPropertyGroup *propertyGroup)
+{
+ Q_UNUSED(propertyGroup)
+ m_writer->writeEndElement();
+}
+
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvprojectwriter.h b/src/plugins/generator/keiluv/keiluvprojectwriter.h
new file mode 100644
index 000000000..ad807e29e
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvprojectwriter.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_KEILUVPROJECTWRITER_H
+#define QBS_KEILUVPROJECTWRITER_H
+
+#include "ikeiluvnodevisitor.h"
+
+namespace qbs {
+
+class KeiluvProject;
+
+class KeiluvProjectWriter final : public IKeiluvNodeVisitor
+{
+ Q_DISABLE_COPY(KeiluvProjectWriter)
+public:
+ explicit KeiluvProjectWriter(std::ostream *device);
+ bool write(const KeiluvProject *project);
+
+private:
+ void visitStart(const KeiluvProject *project) final;
+ void visitEnd(const KeiluvProject *project) final;
+
+ void visitStart(const KeiluvProperty *property) final;
+ void visitEnd(const KeiluvProperty *property) final;
+
+ void visitStart(const KeiluvPropertyGroup *propertyGroup) final;
+ void visitEnd(const KeiluvPropertyGroup *propertyGroup) final;
+
+ std::ostream *m_device = nullptr;
+ QByteArray m_buffer;
+ std::unique_ptr<QXmlStreamWriter> m_writer;
+};
+
+} // namespace qbs
+
+#endif // QBS_KEILUVPROJECTWRITER_H
diff --git a/src/plugins/generator/keiluv/keiluvproperty.cpp b/src/plugins/generator/keiluv/keiluvproperty.cpp
new file mode 100644
index 000000000..057ebe1f6
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvproperty.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 "ikeiluvnodevisitor.h"
+#include "keiluvproperty.h"
+
+namespace qbs {
+
+KeiluvProperty::KeiluvProperty(QByteArray name, QVariant value)
+{
+ setName(std::move(name));
+ setValue(std::move(value));
+}
+
+void KeiluvProperty::accept(IKeiluvNodeVisitor *visitor) const
+{
+ visitor->visitStart(this);
+
+ for (const auto &child : children())
+ child->accept(visitor);
+
+ visitor->visitEnd(this);
+}
+
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvproperty.h b/src/plugins/generator/keiluv/keiluvproperty.h
new file mode 100644
index 000000000..a385c1314
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvproperty.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** 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_KEILUVPROPERTY_H
+#define QBS_KEILUVPROPERTY_H
+
+#include <QtCore/qvariant.h>
+
+#include <memory>
+
+namespace qbs {
+
+class IKeiluvNodeVisitor;
+
+class KeiluvProperty
+{
+ Q_DISABLE_COPY(KeiluvProperty)
+public:
+ KeiluvProperty() = default;
+ explicit KeiluvProperty(QByteArray name, QVariant value);
+ virtual ~KeiluvProperty() = default;
+
+ QByteArray name() const { return m_name; }
+ void setName(QByteArray name) { m_name = std::move(name); }
+
+ QVariant value() const { return m_value; }
+ void setValue(QVariant value) { m_value = std::move(value); }
+
+ template<class T>
+ T *appendChild(std::unique_ptr<T> child) {
+ const auto p = child.get();
+ m_children.push_back(std::move(child));
+ return p;
+ }
+
+ template<class T, class... Args>
+ T *appendChild(Args&&... args) {
+ return appendChild(std::make_unique<T>(std::forward<Args>(args)...));
+ }
+
+ virtual void accept(IKeiluvNodeVisitor *visitor) const;
+
+protected:
+ const std::vector<std::unique_ptr<KeiluvProperty>> &children() const
+ { return m_children; }
+
+private:
+ QByteArray m_name;
+ QVariant m_value;
+ std::vector<std::unique_ptr<KeiluvProperty>> m_children;
+};
+
+} // namespace qbs
+
+#endif // QBS_KEILUVPROPERTY_H
diff --git a/src/plugins/generator/keiluv/keiluvpropertygroup.cpp b/src/plugins/generator/keiluv/keiluvpropertygroup.cpp
new file mode 100644
index 000000000..9aeaa576d
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvpropertygroup.cpp
@@ -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.
+**
+****************************************************************************/
+
+#include "ikeiluvnodevisitor.h"
+#include "keiluvproperty.h"
+#include "keiluvpropertygroup.h"
+
+namespace qbs {
+
+KeiluvPropertyGroup::KeiluvPropertyGroup(QByteArray name)
+{
+ setName(std::move(name));
+}
+
+void KeiluvPropertyGroup::appendProperty(QByteArray name, QVariant value)
+{
+ appendChild<KeiluvProperty>(std::move(name), std::move(value));
+}
+
+void KeiluvPropertyGroup::appendMultiLineProperty(
+ QByteArray key, QStringList values, QChar sep)
+{
+ const auto line = values.join(std::move(sep));
+ appendProperty(std::move(key), QVariant::fromValue(line));
+}
+
+void KeiluvPropertyGroup::accept(IKeiluvNodeVisitor *visitor) const
+{
+ visitor->visitStart(this);
+
+ for (const auto &child : children())
+ child->accept(visitor);
+
+ visitor->visitEnd(this);
+}
+
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvpropertygroup.h b/src/plugins/generator/keiluv/keiluvpropertygroup.h
new file mode 100644
index 000000000..bb5d608c4
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvpropertygroup.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_KEILUVPROPERTYGROUP_H
+#define QBS_KEILUVPROPERTYGROUP_H
+
+#include "keiluvproperty.h"
+#include "keiluvversioninfo.h"
+
+#include <memory>
+
+namespace qbs {
+
+class ProductData;
+class Project;
+
+class KeiluvPropertyGroup : public KeiluvProperty
+{
+public:
+ explicit KeiluvPropertyGroup(QByteArray name);
+
+ void appendProperty(QByteArray name, QVariant value);
+ void appendMultiLineProperty(QByteArray key, QStringList values,
+ QChar sep = QLatin1Char(','));
+
+ void accept(IKeiluvNodeVisitor *visitor) const final;
+};
+
+class KeiluvPropertyGroupFactory
+{
+public:
+ virtual ~KeiluvPropertyGroupFactory() = default;
+ virtual bool canCreate(KeiluvUtils::Architecture architecture,
+ const Version &version) const = 0;
+
+ virtual std::unique_ptr<KeiluvPropertyGroup> create(
+ const Project &qbsProject,
+ const ProductData &qbsProduct,
+ const std::vector<ProductData> &qbsProductDeps) const = 0;
+};
+
+} // namespace qbs
+
+#endif // QBS_KEILUVPROPERTYGROUP_H
diff --git a/src/plugins/generator/keiluv/keiluvutils.cpp b/src/plugins/generator/keiluv/keiluvutils.cpp
new file mode 100644
index 000000000..51382dc36
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvutils.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** 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 "keiluvutils.h"
+
+namespace qbs {
+namespace KeiluvUtils {
+
+OutputBinaryType outputBinaryType(const ProductData &qbsProduct)
+{
+ const auto qbsProductType = qbsProduct.type();
+ if (qbsProductType.contains(QLatin1String("application")))
+ return ApplicationOutputType;
+ if (qbsProductType.contains(QLatin1String("staticlibrary")))
+ return LibraryOutputType;
+ return ApplicationOutputType;
+}
+
+QString architectureName(Architecture arch)
+{
+ switch (arch) {
+ case Architecture::Mcs51Architecture:
+ return QStringLiteral("mcs51");
+ default:
+ return QStringLiteral("unknown");
+ }
+}
+
+Architecture architecture(const Project &qbsProject)
+{
+ const auto qbsArch = qbsProject.projectConfiguration()
+ .value(Internal::StringConstants::qbsModule()).toMap()
+ .value(QStringLiteral("architecture")).toString();
+
+ if (qbsArch == QLatin1String("mcs51"))
+ return Architecture::Mcs51Architecture;
+ return Architecture::UnknownArchitecture;
+}
+
+QString buildConfigurationName(const Project &qbsProject)
+{
+ return qbsProject.projectConfiguration()
+ .value(Internal::StringConstants::qbsModule()).toMap()
+ .value(QStringLiteral("configurationName")).toString();
+}
+
+int debugInformation(const ProductData &qbsProduct)
+{
+ return qbsProduct.moduleProperties().getModuleProperty(
+ Internal::StringConstants::qbsModule(),
+ QStringLiteral("debugInformation"))
+ .toInt();
+}
+
+QString binaryOutputDirectory(const QString &baseDirectory,
+ const ProductData &qbsProduct)
+{
+ const auto path = QDir(baseDirectory).relativeFilePath(
+ qbsProduct.buildDirectory()) + QLatin1String("/bin");
+ return QDir::toNativeSeparators(path);
+}
+
+QString objectsOutputDirectory(const QString &baseDirectory,
+ const ProductData &qbsProduct)
+{
+ const auto path = QDir(baseDirectory).relativeFilePath(
+ qbsProduct.buildDirectory()) + QLatin1String("/obj");
+ return QDir::toNativeSeparators(path);
+}
+
+QString listingOutputDirectory(const QString &baseDirectory,
+ const ProductData &qbsProduct)
+{
+ const auto path = QDir(baseDirectory).relativeFilePath(
+ qbsProduct.buildDirectory()) + QLatin1String("/lst");
+ return QDir::toNativeSeparators(path);
+}
+
+QString targetBinary(const ProductData &qbsProduct)
+{
+ const auto type = qbsProduct.type();
+ if (type.contains(QLatin1String("application"))) {
+ return QFileInfo(qbsProduct.targetExecutable()).fileName();
+ } else if (type.contains(QLatin1String("staticlibrary"))) {
+ const auto artifacts = qbsProduct.targetArtifacts();
+ for (const auto &artifact : artifacts) {
+ if (artifact.fileTags().contains(QLatin1String("staticlibrary")))
+ return QFileInfo(artifact.filePath()).fileName();
+ }
+ }
+
+ return {};
+}
+
+std::vector<ProductData> dependenciesOf(const ProductData &qbsProduct,
+ const GeneratableProject &genProject,
+ const QString configurationName)
+{
+ std::vector<ProductData> result;
+ const auto depsNames = qbsProduct.dependencies();
+ for (const auto &product : qAsConst(genProject.products)) {
+ const auto pt = product.type();
+ if (!pt.contains(QLatin1String("staticlibrary")))
+ continue;
+ const auto pn = product.name();
+ if (!depsNames.contains(pn))
+ continue;
+ result.push_back(product.data.value(configurationName));
+ }
+ return result;
+}
+
+QString toolkitRootPath(const ProductData &qbsProduct)
+{
+ QDir dir(qbsProduct.moduleProperties()
+ .getModuleProperty(Internal::StringConstants::cppModule(),
+ QStringLiteral("toolchainInstallPath"))
+ .toString());
+ dir.cdUp();
+ const auto path = dir.absolutePath();
+ return QDir::toNativeSeparators(path);
+}
+
+QString buildRootPath(const Project &qbsProject)
+{
+ QDir dir(qbsProject.projectData().buildDirectory());
+ dir.cdUp();
+ const auto path = dir.absolutePath();
+ return QDir::toNativeSeparators(path);
+}
+
+QString relativeFilePath(const QString &baseDirectory,
+ const QString &fullFilePath)
+{
+ const auto path = QDir(baseDirectory).relativeFilePath(fullFilePath);
+ return QDir::toNativeSeparators(path);
+}
+
+QString cppStringModuleProperty(const PropertyMap &qbsProps,
+ const QString &propertyName)
+{
+ return qbsProps.getModuleProperty(Internal::StringConstants::cppModule(),
+ propertyName).toString().trimmed();
+}
+
+QStringList cppStringModuleProperties(const PropertyMap &qbsProps,
+ const QStringList &propertyNames)
+{
+ QStringList properties;
+ for (const auto &propertyName : propertyNames) {
+ properties << qbsProps.getModuleProperty(
+ Internal::StringConstants::cppModule(),
+ propertyName).toStringList();
+ }
+ std::transform(properties.begin(), properties.end(), properties.begin(),
+ [](const auto &property) {
+ return property.trimmed();
+ });
+ return properties;
+}
+
+QStringList cppModuleCompilerFlags(const PropertyMap &qbsProps)
+{
+ return cppStringModuleProperties(
+ qbsProps, {QStringLiteral("driverFlags"), QStringLiteral("cFlags"),
+ QStringLiteral("cppFlags"), QStringLiteral("cxxFlags"),
+ QStringLiteral("commonCompilerFlags")});
+}
+
+QStringList cppModuleAssemblerFlags(const PropertyMap &qbsProps)
+{
+ return cppStringModuleProperties(
+ qbsProps, {QStringLiteral("assemblerFlags")});
+}
+
+QStringList cppModuleLinkerFlags(const PropertyMap &qbsProps)
+{
+ return cppStringModuleProperties(
+ qbsProps, {QStringLiteral("driverLinkerFlags")});
+}
+
+QStringList includes(const PropertyMap &qbsProps)
+{
+ auto paths = qbs::KeiluvUtils::cppStringModuleProperties(
+ qbsProps, {QStringLiteral("includePaths"),
+ QStringLiteral("systemIncludePaths")});
+ // Transform include path separators to native.
+ std::transform(paths.begin(), paths.end(), paths.begin(),
+ [](const auto &path) {
+ return QDir::toNativeSeparators(path);
+ });
+ return paths;
+}
+
+QStringList defines(const PropertyMap &qbsProps)
+{
+ return qbs::KeiluvUtils::cppStringModuleProperties(
+ qbsProps, {QStringLiteral("defines")});
+}
+
+QStringList staticLibraries(const PropertyMap &qbsProps)
+{
+ auto libs = qbs::KeiluvUtils::cppStringModuleProperties(
+ qbsProps, {QStringLiteral("staticLibraries")});
+ // Transform library path separators to native.
+ std::transform(libs.begin(), libs.end(), libs.begin(),
+ [](const auto &path) {
+ return QDir::toNativeSeparators(path);
+ });
+ return libs;
+}
+
+QStringList dependencies(const std::vector<ProductData> &qbsProductDeps)
+{
+ QStringList deps;
+ for (const ProductData &qbsProductDep : qbsProductDeps) {
+ const auto path = qbsProductDep.buildDirectory()
+ + QLatin1String("/obj/")
+ + qbs::KeiluvUtils::targetBinary(qbsProductDep);
+ deps.push_back(QDir::toNativeSeparators(path));
+ }
+ return deps;
+}
+
+} // namespace KeiluvUtils
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvutils.h b/src/plugins/generator/keiluv/keiluvutils.h
new file mode 100644
index 000000000..a1de6c543
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvutils.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** 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_KEILUVUTILS_H
+#define QBS_KEILUVUTILS_H
+
+#include <qbs.h>
+
+#include <tools/stringconstants.h>
+
+namespace qbs {
+namespace KeiluvUtils {
+
+enum class Architecture {
+ Mcs51Architecture,
+ UnknownArchitecture
+};
+
+enum OutputBinaryType {
+ ApplicationOutputType,
+ LibraryOutputType
+};
+
+template <typename T>
+bool inBounds(const T &value, const T &low, const T &high)
+{
+ return !(value < low) && !(high < value);
+}
+
+OutputBinaryType outputBinaryType(const ProductData &qbsProduct);
+
+QString architectureName(Architecture arch);
+
+Architecture architecture(const Project &qbsProject);
+
+QString buildConfigurationName(const Project &qbsProject);
+
+int debugInformation(const ProductData &qbsProduct);
+
+QString binaryOutputDirectory(const QString &baseDirectory,
+ const ProductData &qbsProduct);
+
+QString objectsOutputDirectory(const QString &baseDirectory,
+ const ProductData &qbsProduct);
+
+QString listingOutputDirectory(const QString &baseDirectory,
+ const ProductData &qbsProduct);
+
+QString targetBinary(const ProductData &qbsProduct);
+
+std::vector<ProductData> dependenciesOf(const ProductData &qbsProduct,
+ const GeneratableProject &genProject,
+ const QString configurationName);
+
+QString toolkitRootPath(const ProductData &qbsProduct);
+
+QString buildRootPath(const Project &qbsProject);
+
+QString relativeFilePath(const QString &baseDirectory,
+ const QString &fullFilePath);
+
+QString cppStringModuleProperty(const PropertyMap &qbsProps,
+ const QString &propertyName);
+
+QStringList cppStringModuleProperties(const PropertyMap &qbsProps,
+ const QStringList &propertyNames);
+
+QStringList cppModuleCompilerFlags(const PropertyMap &qbsProps);
+
+QStringList cppModuleAssemblerFlags(const PropertyMap &qbsProps);
+
+QStringList cppModuleLinkerFlags(const PropertyMap &qbsProps);
+
+QStringList includes(const PropertyMap &qbsProps);
+QStringList defines(const PropertyMap &qbsProps);
+QStringList staticLibraries(const PropertyMap &qbsProps);
+QStringList dependencies(const std::vector<ProductData> &qbsProductDeps);
+
+} // namespace KeiluvUtils
+} // namespace qbs
+
+#endif // QBS_KEILUVUTILS_H
diff --git a/src/plugins/generator/keiluv/keiluvversioninfo.cpp b/src/plugins/generator/keiluv/keiluvversioninfo.cpp
new file mode 100644
index 000000000..9d9723307
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvversioninfo.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "keiluvversioninfo.h"
+
+#include "archs/mcs51/mcs51utils.h"
+
+#include <tools/qbsassert.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qglobal.h>
+
+namespace qbs {
+
+KeiluvVersionInfo::KeiluvVersionInfo(
+ const Version &version,
+ const std::set<KeiluvUtils::Architecture> &archs)
+ : m_version(version), m_archs(archs)
+{
+}
+
+std::set<KeiluvVersionInfo> KeiluvVersionInfo::knownVersions()
+{
+ static const std::set<KeiluvVersionInfo> known = {
+ {Version(keiluv::mcs51::v5::KeiluvConstants::kUVisionVersion),
+ {KeiluvUtils::Architecture::Mcs51Architecture}},
+ };
+ return known;
+}
+
+bool KeiluvVersionInfo::operator<(const KeiluvVersionInfo &other) const
+{
+ return m_version < other.m_version;
+}
+
+bool KeiluvVersionInfo::operator==(const KeiluvVersionInfo &other) const
+{
+ return m_version == other.m_version
+ && m_archs == other.m_archs;
+}
+
+Version KeiluvVersionInfo::version() const
+{
+ return m_version;
+}
+
+int KeiluvVersionInfo::marketingVersion() const
+{
+ const auto mv = m_version.majorVersion();
+ for (const KeiluvVersionInfo &known : knownVersions()) {
+ if (known.version().majorVersion() == mv)
+ return mv;
+ }
+ qWarning() << QStringLiteral("Unrecognized KEIL UV version: ")
+ << m_version.toString();
+ return 0;
+}
+
+bool KeiluvVersionInfo::containsArchitecture(KeiluvUtils::Architecture arch) const
+{
+ return m_archs.find(arch) != m_archs.cend();
+}
+
+quint32 qHash(const KeiluvVersionInfo &info)
+{
+ return qHash(info.version().toString());
+}
+
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvversioninfo.h b/src/plugins/generator/keiluv/keiluvversioninfo.h
new file mode 100644
index 000000000..5bec6ac6e
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvversioninfo.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBS_KEILUVVERSIONINFO_H
+#define QBS_KEILUVVERSIONINFO_H
+
+#include "keiluvutils.h"
+
+#include <tools/version.h>
+
+#include <set>
+
+namespace qbs {
+
+class KeiluvVersionInfo final
+{
+public:
+ KeiluvVersionInfo(const Version &version,
+ const std::set<KeiluvUtils::Architecture> &archs);
+
+ static std::set<KeiluvVersionInfo> knownVersions();
+
+ bool operator<(const KeiluvVersionInfo &other) const;
+ bool operator==(const KeiluvVersionInfo &other) const;
+
+ Version version() const;
+ int marketingVersion() const;
+
+ bool containsArchitecture(KeiluvUtils::Architecture arch) const;
+
+private:
+ Version m_version;
+ std::set<KeiluvUtils::Architecture> m_archs;
+};
+
+quint32 qHash(const KeiluvVersionInfo &info);
+
+} // namespace qbs
+
+#endif // QBS_KEILUVVERSIONINFO_H
diff --git a/src/plugins/generator/keiluv/keiluvworkspace.cpp b/src/plugins/generator/keiluv/keiluvworkspace.cpp
new file mode 100644
index 000000000..948929ee0
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvworkspace.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ikeiluvnodevisitor.h"
+#include "keiluvproperty.h"
+#include "keiluvpropertygroup.h"
+#include "keiluvworkspace.h"
+
+namespace qbs {
+
+KeiluvWorkspace::KeiluvWorkspace(const QString &workspacePath)
+{
+ m_baseDirectory = QFileInfo(workspacePath).absoluteDir();
+
+ // Construct schema version item.
+ appendChild<KeiluvProperty>(QByteArrayLiteral("SchemaVersion"),
+ QStringLiteral("1.0"));
+
+ // Construct workspace name item.
+ appendChild<KeiluvProperty>(QByteArrayLiteral("WorkspaceName"),
+ QStringLiteral("WorkSpace"));
+}
+
+void KeiluvWorkspace::addProjectPath(const QString &projectFilePath)
+{
+ const QString relativeProjectPath =
+ m_baseDirectory.relativeFilePath(projectFilePath);
+
+ const auto projectGroup = appendChild<KeiluvPropertyGroup>(
+ QByteArrayLiteral("project"));
+ projectGroup->appendProperty("PathAndName", relativeProjectPath);
+}
+
+void KeiluvWorkspace::accept(IKeiluvNodeVisitor *visitor) const
+{
+ visitor->visitStart(this);
+
+ for (const auto &child : children())
+ child->accept(visitor);
+
+ visitor->visitEnd(this);
+}
+
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvworkspace.h b/src/plugins/generator/keiluv/keiluvworkspace.h
new file mode 100644
index 000000000..09950efd7
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvworkspace.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBS_KEILUVWORKSPACE_H
+#define QBS_KEILUVWORKSPACE_H
+
+#include "keiluvproperty.h"
+
+#include <QtCore/qdir.h>
+
+namespace qbs {
+
+class KeiluvWorkspace final : public KeiluvProperty
+{
+public:
+ explicit KeiluvWorkspace(const QString &workspacePath);
+ void addProjectPath(const QString &projectPath);
+
+ void accept(IKeiluvNodeVisitor *visitor) const final;
+
+private:
+ QDir m_baseDirectory;
+};
+
+} // namespace qbs
+
+#endif // QBS_KEILUVWORKSPACE_H
diff --git a/src/plugins/generator/keiluv/keiluvworkspacewriter.cpp b/src/plugins/generator/keiluv/keiluvworkspacewriter.cpp
new file mode 100644
index 000000000..e646a1122
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvworkspacewriter.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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 "keiluvproperty.h"
+#include "keiluvpropertygroup.h"
+#include "keiluvworkspace.h"
+#include "keiluvworkspacewriter.h"
+
+#include <ostream>
+
+namespace qbs {
+
+KeiluvWorkspaceWriter::KeiluvWorkspaceWriter(std::ostream *device)
+ : m_device(device)
+{
+ m_writer.reset(new QXmlStreamWriter(&m_buffer));
+ m_writer->setAutoFormatting(true);
+}
+
+bool KeiluvWorkspaceWriter::write(const KeiluvWorkspace *workspace)
+{
+ m_buffer.clear();
+ m_writer->writeStartDocument();
+ workspace->accept(this);
+ m_writer->writeEndDocument();
+ if (m_writer->hasError())
+ return false;
+ m_device->write(&*std::begin(m_buffer), m_buffer.size());
+ return m_device->good();
+}
+
+void KeiluvWorkspaceWriter::visitStart(const KeiluvWorkspace *workspace)
+{
+ Q_UNUSED(workspace)
+ m_writer->writeStartElement(QStringLiteral("ProjectWorkspace"));
+ m_writer->writeAttribute(QStringLiteral("xmlns:xsi"),
+ QStringLiteral("http://www.w3.org/2001/XMLSchema-instance"));
+ m_writer->writeAttribute(QStringLiteral("xsi:noNamespaceSchemaLocation"),
+ QStringLiteral("project_mpw.xsd"));
+}
+
+void KeiluvWorkspaceWriter::visitEnd(const KeiluvWorkspace *workspace)
+{
+ Q_UNUSED(workspace)
+ m_writer->writeEndElement();
+}
+
+void KeiluvWorkspaceWriter::visitStart(const KeiluvProperty *property)
+{
+ const QString stringValue = property->value().toString();
+ m_writer->writeTextElement(QString::fromLatin1(property->name()), stringValue);
+}
+
+void KeiluvWorkspaceWriter::visitEnd(const KeiluvProperty *property)
+{
+ Q_UNUSED(property)
+}
+
+void KeiluvWorkspaceWriter::visitStart(const KeiluvPropertyGroup *propertyGroup)
+{
+ m_writer->writeStartElement(QString::fromLatin1(propertyGroup->name()));
+}
+
+void KeiluvWorkspaceWriter::visitEnd(const KeiluvPropertyGroup *propertyGroup)
+{
+ Q_UNUSED(propertyGroup)
+ m_writer->writeEndElement();
+}
+
+} // namespace qbs
diff --git a/src/plugins/generator/keiluv/keiluvworkspacewriter.h b/src/plugins/generator/keiluv/keiluvworkspacewriter.h
new file mode 100644
index 000000000..4b4f2dde0
--- /dev/null
+++ b/src/plugins/generator/keiluv/keiluvworkspacewriter.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_KEILUVWORKSPACEWRITER_H
+#define QBS_KEILUVWORKSPACEWRITER_H
+
+#include "ikeiluvnodevisitor.h"
+
+namespace qbs {
+
+class KeiluvWorkspace;
+
+class KeiluvWorkspaceWriter final : public IKeiluvNodeVisitor
+{
+ Q_DISABLE_COPY(KeiluvWorkspaceWriter)
+public:
+ explicit KeiluvWorkspaceWriter(std::ostream *device);
+ bool write(const KeiluvWorkspace *workspace);
+
+private:
+ void visitStart(const KeiluvWorkspace *workspace) final;
+ void visitEnd(const KeiluvWorkspace *workspace) final;
+
+ void visitStart(const KeiluvProperty *property) final;
+ void visitEnd(const KeiluvProperty *property) final;
+
+ void visitStart(const KeiluvPropertyGroup *propertyGroup) final;
+ void visitEnd(const KeiluvPropertyGroup *propertyGroup) final;
+
+ std::ostream *m_device = nullptr;
+ QByteArray m_buffer;
+ std::unique_ptr<QXmlStreamWriter> m_writer;
+};
+
+} // namespace qbs
+
+#endif // QBS_KEILUVWORKSPACEWRITER_H
diff --git a/src/plugins/plugins.qbs b/src/plugins/plugins.qbs
index e1b7437cb..ee101f60e 100644
--- a/src/plugins/plugins.qbs
+++ b/src/plugins/plugins.qbs
@@ -7,6 +7,7 @@ Project {
"generator/makefilegenerator/makefilegenerator.qbs",
"generator/visualstudio/visualstudio.qbs",
"generator/iarew/iarew.qbs",
+ "generator/keiluv/keiluv.qbs",
"scanner/cpp/cpp.qbs",
"scanner/qt/qt.qbs"
]