diff options
Diffstat (limited to 'examples')
25 files changed, 1277 insertions, 27 deletions
diff --git a/examples/app-and-lib/app/app.qbs b/examples/app-and-lib/app/app.qbs index dcb9e7af2..1cdb95c39 100644 --- a/examples/app-and-lib/app/app.qbs +++ b/examples/app-and-lib/app/app.qbs @@ -53,5 +53,6 @@ Application { files : [ "main.cpp" ] Depends { name: "cpp" } Depends { name: "mylib" } + install: true } diff --git a/examples/cocoa-touch-application/cocoa-touch-application.qbs b/examples/cocoa-touch-application/cocoa-touch-application.qbs index ec199d4a5..c837cacf1 100644 --- a/examples/cocoa-touch-application/cocoa-touch-application.qbs +++ b/examples/cocoa-touch-application/cocoa-touch-application.qbs @@ -64,6 +64,11 @@ CppApplication { cpp.automaticReferenceCounting: true cpp.frameworks: [ "UIKit", "Foundation", "CoreGraphics" ] + // sample code signing settings: + // codesign.enableCodeSigning: true + // codesign.provisioningProfile: "my provisioning profile name" + // codesign.signingIdentity: "Apple Development: My Team Name" + Group { prefix: "CocoaTouchApplication/" files: [ diff --git a/examples/code-generator/code-generator.qbs b/examples/code-generator/code-generator.qbs index 4d664c0ec..fdb0e1aac 100644 --- a/examples/code-generator/code-generator.qbs +++ b/examples/code-generator/code-generator.qbs @@ -62,7 +62,7 @@ Project { // Generate and build a hello-world application. CppApplication { - condition: qbs.targetOS === qbs.hostOS + condition: qbs.targetPlatform === qbs.hostPlatform name: "hello-world" Depends { name: "hwgen" } Rule { diff --git a/examples/examples.qbs b/examples/examples.qbs index d457b8a88..fa8ed0f5c 100644 --- a/examples/examples.qbs +++ b/examples/examples.qbs @@ -48,24 +48,6 @@ ** ****************************************************************************/ -Project { - references: [ - "app-and-lib/app-and-lib.qbs", - "cocoa-application/cocoa-application.qbs", - "cocoa-touch-application/cocoa-touch-application.qbs", - "code-generator/code-generator.qbs", - "collidingmice/collidingmice.qbs", - "compiled-qml/compiled-qml.qbs", - "grpc/grpc.qbs", - "helloworld-complex/helloworld-complex.qbs", - "helloworld-minimal/helloworld-minimal.qbs", - "helloworld-qt/helloworld-qt.qbs", - "install-bundle/install-bundle.qbs", - // these examples are broken because of the bug in the protobuf modules - // "protobuf/addressbook_cpp/addressbook_cpp.qbs", - // "protobuf/addressbook_objc/addressbook_objc.qbs", - "baremetal/baremetal.qbs", - "rule/rule.qbs", - "rpaths/rpaths.qbs", - ] +Product { + files: "**/*" } diff --git a/examples/exporters/exporters.qbs b/examples/exporters/exporters.qbs new file mode 100644 index 000000000..bae62e17c --- /dev/null +++ b/examples/exporters/exporters.qbs @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +Project { + references: [ + "lib_a/lib_a.qbs", + "lib_b/lib_b.qbs" + ] + qbsSearchPaths: "qbs" +} + diff --git a/examples/exporters/lib_a/lib_a.cpp b/examples/exporters/lib_a/lib_a.cpp new file mode 100644 index 000000000..e3e7f17d9 --- /dev/null +++ b/examples/exporters/lib_a/lib_a.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "lib_a.h" + +const char *bla() +{ + return "Hello World!"; +} diff --git a/examples/exporters/lib_a/lib_a.h b/examples/exporters/lib_a/lib_a.h new file mode 100644 index 000000000..f583421b9 --- /dev/null +++ b/examples/exporters/lib_a/lib_a.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LIB_A_H +#define LIB_A_H + +const char *bla(); + +#endif // LIB_A_H diff --git a/examples/exporters/lib_a/lib_a.qbs b/examples/exporters/lib_a/lib_a.qbs new file mode 100644 index 000000000..fedbb7074 --- /dev/null +++ b/examples/exporters/lib_a/lib_a.qbs @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +MyLibrary { + name: "lib_a" + files: ["lib_a.cpp"] + + Group { + name: "API headers" + files: ["lib_a.h"] + qbs.install: true + qbs.installDir: headersInstallDir + } + Export { + Depends { name: "cpp" } + cpp.dynamicLibraries: "z" + cpp.libraryPaths: "/opt/local/lib" + } +} + diff --git a/examples/exporters/lib_b/lib_b.cpp b/examples/exporters/lib_b/lib_b.cpp new file mode 100644 index 000000000..b29dc57b6 --- /dev/null +++ b/examples/exporters/lib_b/lib_b.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "lib_b.h" + +#include <lib_a.h> + +#include <cstdio> + +int foo() +{ + std::puts(bla()); + return 2; +} diff --git a/examples/exporters/lib_b/lib_b.h b/examples/exporters/lib_b/lib_b.h new file mode 100644 index 000000000..a3d3e3aee --- /dev/null +++ b/examples/exporters/lib_b/lib_b.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LIB_B_H +#define LIB_B_H + +int foo(); + +#endif // LIB_B_H diff --git a/examples/exporters/lib_b/lib_b.qbs b/examples/exporters/lib_b/lib_b.qbs new file mode 100644 index 000000000..0c680f3e0 --- /dev/null +++ b/examples/exporters/lib_b/lib_b.qbs @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +MyLibrary { + Depends { name: "lib_a" } + name: "lib_b" + files: ["lib_b.cpp"] + Group { + name: "API headers" + files: ["lib_b.h"] + qbs.install: true + qbs.installDir: headersInstallDir + } + Export { + Depends { name: 'lib_a' } + } +} diff --git a/examples/exporters/qbs/imports/MyLibrary.qbs b/examples/exporters/qbs/imports/MyLibrary.qbs new file mode 100644 index 000000000..4607776b3 --- /dev/null +++ b/examples/exporters/qbs/imports/MyLibrary.qbs @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import qbs.FileInfo + +StaticLibrary { + Depends { name: 'cpp' } + + property string headersInstallDir: "include" + + Export { + Depends { name: "cpp" } + cpp.includePaths: [exportingProduct.sourceDirectory] + prefixMapping: [{ + prefix: exportingProduct.sourceDirectory, + replacement: FileInfo.joinPaths(exportingProduct.qbs.installPrefix, + exportingProduct.headersInstallDir) + }] + } + install: true + + Depends { name: "Exporter.qbs" } + + Group { + fileTagsFilter: "Exporter.qbs.module" + qbs.install: install + qbs.installDir: FileInfo.joinPaths(installDir, "qbs", "modules", product.name) + } + + Depends { name: "Exporter.pkgconfig" } + Exporter.pkgconfig.versionEntry: "1.0" + + Group { + fileTagsFilter: ["Exporter.pkgconfig.pc"] + qbs.install: install + qbs.installDir: FileInfo.joinPaths(installDir, "pkgconfig") + } + + Depends { name: "Exporter.cmake" } + Group { + fileTagsFilter: ["Exporter.cmake.package"] + qbs.install: install + qbs.installDir: FileInfo.joinPaths(installDir, "cmake", product.name) + } + + Depends { name: 'bundle' } + bundle.isBundle: false +} + diff --git a/examples/flatbuffers/.clang-format b/examples/flatbuffers/.clang-format new file mode 100644 index 000000000..47a38a93f --- /dev/null +++ b/examples/flatbuffers/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: Never diff --git a/examples/flatbuffers/monster-c/conanfile.txt b/examples/flatbuffers/monster-c/conanfile.txt new file mode 100644 index 000000000..613119ec2 --- /dev/null +++ b/examples/flatbuffers/monster-c/conanfile.txt @@ -0,0 +1,6 @@ +[requires] +flatcc/0.6.1 +[tool_requires] +flatcc/0.6.1 +[generators] +QbsDeps diff --git a/examples/flatbuffers/monster-c/monster-c.qbs b/examples/flatbuffers/monster-c/monster-c.qbs new file mode 100644 index 000000000..e6abe749e --- /dev/null +++ b/examples/flatbuffers/monster-c/monster-c.qbs @@ -0,0 +1,12 @@ +CppApplication { + Depends { name: "flatbuf.c"; required: false } + + name: "monster_c" + consoleApplication: true + condition: flatbuf.c.present && qbs.targetPlatform === qbs.hostPlatform + + files: [ + "monster.c", + "../shared/monster.fbs" + ] +} diff --git a/examples/flatbuffers/monster-c/monster.c b/examples/flatbuffers/monster-c/monster.c new file mode 100644 index 000000000..6bf49d628 --- /dev/null +++ b/examples/flatbuffers/monster-c/monster.c @@ -0,0 +1,367 @@ +/* + * Copyright 2019 dvidelabs. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Example on how to build a Monster FlatBuffer. + + +// Note: while some older C89 compilers are supported when +// -DFLATCC_PORTABLE is defined, this particular sample is known not to +// not work with MSVC 2010 (MSVC 2013 is OK) due to inline variable +// declarations. These are easily move to the start of code blocks, but +// since we follow the step-wise tutorial, it isn't really practical +// in this case. The comment style is technically also in violation of C89. + + +#include "monster_builder.h" +// <string.h> and <assert.h> already included. + +// Convenient namespace macro to manage long namespace prefix. +// The ns macro makes it possible to write `ns(Monster_create(...))` +// instead of `MyGame_Sample_Monster_create(...)` +#undef ns +#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema. + +// A helper to simplify creating vectors from C-arrays. +#define c_vec_len(V) (sizeof(V)/sizeof((V)[0])) + +// This allows us to verify result in optimized builds. +#define test_assert(x) do { if (!(x)) { assert(0); return -1; }} while (0) + +// Bottom-up approach where we create child objects and store these +// in temporary references before a parent object is created with +// these references. +int create_monster_bottom_up(flatcc_builder_t *B, int flexible) +{ + flatbuffers_string_ref_t weapon_one_name = flatbuffers_string_create_str(B, "Sword"); + uint16_t weapon_one_damage = 3; + + flatbuffers_string_ref_t weapon_two_name = flatbuffers_string_create_str(B, "Axe"); + uint16_t weapon_two_damage = 5; + + // Use the `MyGame_Sample_Weapon_create` shortcut to create Weapons + // with all the fields set. + // + // In the C-API, verbs (here create) always follow the type name + // (here Weapon), prefixed by the namespace (here MyGame_Sample_): + // MyGame_Sample_Weapon_create(...), or ns(Weapone_create(...)). + ns(Weapon_ref_t) sword = ns(Weapon_create(B, weapon_one_name, weapon_one_damage)); + ns(Weapon_ref_t) axe = ns(Weapon_create(B, weapon_two_name, weapon_two_damage)); + + // Serialize a name for our monster, called "Orc". + // The _str suffix indicates the source is an ascii-z string. + flatbuffers_string_ref_t name = flatbuffers_string_create_str(B, "Orc"); + + // Create a `vector` representing the inventory of the Orc. Each number + // could correspond to an item that can be claimed after he is slain. + uint8_t treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + flatbuffers_uint8_vec_ref_t inventory; + // `c_vec_len` is the convenience macro we defined earlier. + inventory = flatbuffers_uint8_vec_create(B, treasure, c_vec_len(treasure)); + + // Here we use a top-down approach locally to build a Weapons vector + // in-place instead of creating a temporary external vector to use + // as argument like we did with the `inventory` earlier on, but the + // overall approach is still bottom-up. + ns(Weapon_vec_start(B)); + ns(Weapon_vec_push(B, sword)); + ns(Weapon_vec_push(B, axe)); + ns(Weapon_vec_ref_t) weapons = ns(Weapon_vec_end(B)); + + + // Create a `Vec3`, representing the Orc's position in 3-D space. + ns(Vec3_t) pos = { 1.0f, 2.0f, 3.0f }; + + + // Set his hit points to 300 and his mana to 150. + uint16_t hp = 300; + // The default value is 150, so we will never store this field. + uint16_t mana = 150; + + // Create the equipment union. In the C++ language API this is given + // as two arguments to the create call, or as two separate add + // operations for the type and the table reference. Here we create + // a single union value that carries both the type and reference. + ns(Equipment_union_ref_t) equipped = ns(Equipment_as_Weapon(axe)); + + if (!flexible) { + // Finally, create the monster using the `Monster_create` helper function + // to set all fields. + // + // Note that the Equipment union only take up one argument in C, where + // C++ takes a type and an object argument. + ns(Monster_create_as_root(B, &pos, mana, hp, name, inventory, ns(Color_Red), + weapons, equipped)); + + // Unlike C++ we do not use a Finish call. Instead we use the + // `create_as_root` action which has better type safety and + // simplicity. + // + // However, we can also express this as: + // + // ns(Monster_ref_t) orc = ns(Monster_create(B, ...)); + // flatcc_builder_buffer_create(orc); + // + // In this approach the function should return the orc and + // let a calling function handle the flatcc_buffer_create call + // for a more composable setup that is also able to create child + // monsters. In general, `flatcc_builder` calls are best isolated + // in a containing driver function. + + } else { + + // A more flexible approach where we mix bottom-up and top-down + // style. We still create child objects first, but then create + // a top-down style monster object that we can manipulate in more + // detail. + + // It is important to pair `start_as_root` with `end_as_root`. + ns(Monster_start_as_root(B)); + ns(Monster_pos_create(B, 1.0f, 2.0f, 3.0f)); + // or alternatively + //ns(Monster_pos_add(&pos); + + ns(Monster_hp_add(B, hp)); + // Notice that `Monser_name_add` adds a string reference unlike the + // add_str and add_strn variants. + ns(Monster_name_add(B, name)); + ns(Monster_inventory_add(B, inventory)); + ns(Monster_color_add(B, ns(Color_Red))); + ns(Monster_weapons_add(B, weapons)); + ns(Monster_equipped_add(B, equipped)); + // Complete the monster object and make it the buffer root object. + ns(Monster_end_as_root(B)); + + // We could also drop the `as_root` suffix from Monster_start/end(B) + // and add the table as buffer root later: + // + // ns(Monster_ref_t) orc = ns(Monster_start(B)); + // ... + // ns(Monster_ref_t) orc = ns(Monster_end(B)); + // flatcc_builder_buffer_create(orc); + // + // It is best to keep the `flatcc_builder` calls in a containing + // driver function for modularity. + } + return 0; +} + +// Alternative top-down approach where parent objects are created before +// their children. We only need to save one reference because the `axe` +// object is used in two places effectively making the buffer object +// graph a DAG. +int create_monster_top_down(flatcc_builder_t *B) +{ + uint8_t treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + size_t treasure_count = c_vec_len(treasure); + ns(Weapon_ref_t) axe; + + // NOTE: if we use end_as_root, we MUST also start as root. + ns(Monster_start_as_root(B)); + ns(Monster_pos_create(B, 1.0f, 2.0f, 3.0f)); + ns(Monster_hp_add(B, 300)); + //ns(Monster_mana_add(B, 150)); + // We use create_str instead of add because we have no existing string reference. + ns(Monster_name_create_str(B, "Orc")); + // Again we use create because we no existing vector object, only a C-array. + ns(Monster_inventory_create(B, treasure, treasure_count)); + ns(Monster_color_add(B, ns(Color_Red))); + if (1) { + ns(Monster_weapons_start(B)); + ns(Monster_weapons_push_create(B, flatbuffers_string_create_str(B, "Sword"), 3)); + // We reuse the axe object later. Note that we dereference a pointer + // because push always returns a short-term pointer to the stored element. + // We could also have created the axe object first and simply pushed it. + axe = *ns(Monster_weapons_push_create(B, flatbuffers_string_create_str(B, "Axe"), 5)); + ns(Monster_weapons_end(B)); + } else { + // We can have more control with the table elements added to a vector: + // + ns(Monster_weapons_start(B)); + ns(Monster_weapons_push_start(B)); + ns(Weapon_name_create_str(B, "Sword")); + ns(Weapon_damage_add(B, 3)); + ns(Monster_weapons_push_end(B)); + ns(Monster_weapons_push_start(B)); + ns(Weapon_name_create_str(B, "Axe")); + ns(Weapon_damage_add(B, 5)); + axe = *ns(Monster_weapons_push_end(B)); + ns(Monster_weapons_end(B)); + } + // Unions can get their type by using a type-specific add/create/start method. + ns(Monster_equipped_Weapon_add(B, axe)); + + ns(Monster_end_as_root(B)); + return 0; +} + +// This isn't strictly needed because the builder already included the reader, +// but we would need it if our reader were in a separate file. +#include "monster_reader.h" + +#undef ns +#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema. + +int access_monster_buffer(const void *buffer) +{ + // Note that we use the `table_t` suffix when reading a table object + // as opposed to the `ref_t` suffix used during the construction of + // the buffer. + ns(Monster_table_t) monster = ns(Monster_as_root(buffer)); + + // Note: root object pointers are NOT the same as the `buffer` pointer. + + // Make sure the buffer is accessible. + test_assert(monster != 0); + + uint16_t hp = ns(Monster_hp(monster)); + uint16_t mana = ns(Monster_mana(monster)); + // This is just a const char *, but it also supports a fast length operation. + flatbuffers_string_t name = ns(Monster_name(monster)); + size_t name_len = flatbuffers_string_len(name); + + test_assert(hp == 300); + // Since 150 is the default, we are reading a value that wasn't stored. + test_assert(mana == 150); + test_assert(0 == strcmp(name, "Orc")); + test_assert(name_len == strlen("Orc")); + + int hp_present = ns(Monster_hp_is_present(monster)); // 1 + int mana_present = ns(Monster_mana_is_present(monster)); // 0 + test_assert(hp_present); + test_assert(!mana_present); + + ns(Vec3_struct_t) pos = ns(Monster_pos(monster)); + // Make sure pos has been set. + test_assert(pos != 0); + float x = ns(Vec3_x(pos)); + float y = ns(Vec3_y(pos)); + float z = ns(Vec3_z(pos)); + + // The literal `f` suffix is important because double literals does + // not always map cleanly to 32-bit represention even with only a few digits: + // `1.0 == 1.0f`, but `3.2 != 3.2f`. + test_assert(x == 1.0f); + test_assert(y == 2.0f); + test_assert(z == 3.0f); + + // We can also read the position into a C-struct. We have to copy + // because we generally do not know if the native endian format + // matches the one stored in the buffer (pe: protocol endian). + ns(Vec3_t) pos_vec; + // `pe` indicates endian conversion from protocol to native. + ns(Vec3_copy_from_pe(&pos_vec, pos)); + test_assert(pos_vec.x == 1.0f); + test_assert(pos_vec.y == 2.0f); + test_assert(pos_vec.z == 3.0f); + + // This is a const uint8_t *, but it shouldn't be accessed directly + // to ensure proper endian conversion. However, uint8 (ubyte) are + // not sensitive endianness, so we *could* have accessed it directly. + // The compiler likely optimizes this so that it doesn't matter. + flatbuffers_uint8_vec_t inv = ns(Monster_inventory(monster)); + size_t inv_len = flatbuffers_uint8_vec_len(inv); + // Make sure the inventory has been set. + test_assert(inv != 0); + // If `inv` were absent, the length would 0, so the above test is redundant. + test_assert(inv_len == 10); + // Index 0 is the first, index 2 is the third. + // NOTE: C++ uses the `Get` terminology for vector elemetns, C use `at`. + uint8_t third_item = flatbuffers_uint8_vec_at(inv, 2); + test_assert(third_item == 2); + + ns(Weapon_vec_t) weapons = ns(Monster_weapons(monster)); + size_t weapons_len = ns(Weapon_vec_len(weapons)); + test_assert(weapons_len == 2); + // We can use `const char *` instead of `flatbuffers_string_t`. + const char *second_weapon_name = ns(Weapon_name(ns(Weapon_vec_at(weapons, 1)))); + uint16_t second_weapon_damage = ns(Weapon_damage(ns(Weapon_vec_at(weapons, 1)))); + test_assert(second_weapon_name != 0 && strcmp(second_weapon_name, "Axe") == 0); + test_assert(second_weapon_damage == 5); + + // Access union type field. + if (ns(Monster_equipped_type(monster)) == ns(Equipment_Weapon)) { + // Cast to appropriate type: + // C does not require the cast to Weapon_table_t, but C++ does. + ns(Weapon_table_t) weapon = (ns(Weapon_table_t)) ns(Monster_equipped(monster)); + const char *weapon_name = ns(Weapon_name(weapon)); + uint16_t weapon_damage = ns(Weapon_damage(weapon)); + + test_assert(0 == strcmp(weapon_name, "Axe")); + test_assert(weapon_damage == 5); + } + return 0; +} + +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + // Create a `FlatBufferBuilder`, which will be used to create our + // monsters' FlatBuffers. + flatcc_builder_t builder; + void *buf; + size_t size; + + // Silence warnings. + (void)argc; + (void)argv; + + // Initialize the builder object. + flatcc_builder_init(&builder); + test_assert(0 == create_monster_bottom_up(&builder, 0)); + + // Allocate and extract a readable buffer from internal builder heap. + // The returned buffer must be deallocated using `free`. + // NOTE: Finalizing the buffer does NOT change the builder, it + // just creates a snapshot of the builder content. + // NOTE2: finalize_buffer uses malloc while finalize_aligned_buffer + // uses a portable aligned allocation method. Often the malloc + // version is sufficient, but won't work for all schema on all + // systems. If the buffer is written to disk or network, but not + // accessed in memory, `finalize_buffer` is also sufficient. + buf = flatcc_builder_finalize_aligned_buffer(&builder, &size); + //buf = flatcc_builder_finalize_buffer(&builder, &size); + + // We now have a FlatBuffer we can store on disk or send over a network. + // ** file/network code goes here :) ** + // Instead, we're going to access it right away (as if we just received it). + //access_monster_buffer(buf); + + // prior to v0.5.0, use `aligned_free` + flatcc_builder_aligned_free(buf); + //free(buf); + // + // The builder object can optionally be reused after a reset which + // is faster than creating a new builder. Subsequent use might + // entirely avoid temporary allocations until finalizing the buffer. + flatcc_builder_reset(&builder); + test_assert(0 == create_monster_bottom_up(&builder, 1)); + buf = flatcc_builder_finalize_aligned_buffer(&builder, &size); + access_monster_buffer(buf); + flatcc_builder_aligned_free(buf); + flatcc_builder_reset(&builder); + create_monster_top_down(&builder); + buf = flatcc_builder_finalize_buffer(&builder, &size); + test_assert(0 == access_monster_buffer(buf)); + free(buf); + // Eventually the builder must be cleaned up: + flatcc_builder_clear(&builder); + + printf("The FlatBuffer was successfully created and accessed!\n"); + + return 0; +} + diff --git a/examples/flatbuffers/monster-cpp/conanfile.txt b/examples/flatbuffers/monster-cpp/conanfile.txt new file mode 100644 index 000000000..188da5897 --- /dev/null +++ b/examples/flatbuffers/monster-cpp/conanfile.txt @@ -0,0 +1,6 @@ +[requires] +flatbuffers/24.3.25 +[tool_requires] +flatbuffers/24.3.25 +[generators] +QbsDeps diff --git a/examples/flatbuffers/monster-cpp/monster-cpp.qbs b/examples/flatbuffers/monster-cpp/monster-cpp.qbs new file mode 100644 index 000000000..fdcc3fcfd --- /dev/null +++ b/examples/flatbuffers/monster-cpp/monster-cpp.qbs @@ -0,0 +1,12 @@ +CppApplication { + Depends { name: "flatbuf.cpp"; required: false } + + name: "monster_cpp" + consoleApplication: true + condition: flatbuf.cpp.present && qbs.targetPlatform === qbs.hostPlatform + + files: [ + "monster.cpp", + "../shared/monster.fbs" + ] +} diff --git a/examples/flatbuffers/monster-cpp/monster.cpp b/examples/flatbuffers/monster-cpp/monster.cpp new file mode 100644 index 000000000..d2348c820 --- /dev/null +++ b/examples/flatbuffers/monster-cpp/monster.cpp @@ -0,0 +1,104 @@ +/* + * Copyright 2015 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h". + +using namespace MyGame::Sample; + +// Example how to use FlatBuffers to create and read binary buffers. + +int main(int /*argc*/, const char * /*argv*/ []) { + // Build up a serialized buffer algorithmically: + flatbuffers::FlatBufferBuilder builder; + + // First, lets serialize some weapons for the Monster: A 'sword' and an 'axe'. + auto weapon_one_name = builder.CreateString("Sword"); + short weapon_one_damage = 3; + + auto weapon_two_name = builder.CreateString("Axe"); + short weapon_two_damage = 5; + + // Use the `CreateWeapon` shortcut to create Weapons with all fields set. + auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage); + auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage); + + // Create a FlatBuffer's `vector` from the `std::vector`. + std::vector<flatbuffers::Offset<Weapon>> weapons_vector; + weapons_vector.push_back(sword); + weapons_vector.push_back(axe); + auto weapons = builder.CreateVector(weapons_vector); + + // Second, serialize the rest of the objects needed by the Monster. + auto position = Vec3(1.0f, 2.0f, 3.0f); + + auto name = builder.CreateString("MyMonster"); + + unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + auto inventory = builder.CreateVector(inv_data, 10); + + // Shortcut for creating monster with all fields set: + auto orc = CreateMonster(builder, &position, 150, 80, name, inventory, + Color_Red, weapons, Equipment_Weapon, axe.Union()); + + builder.Finish(orc); // Serialize the root of the object. + + // We now have a FlatBuffer we can store on disk or send over a network. + + // ** file/network code goes here :) ** + // access builder.GetBufferPointer() for builder.GetSize() bytes + + // Instead, we're going to access it right away (as if we just received it). + + // Get access to the root: + auto monster = GetMonster(builder.GetBufferPointer()); + + // Get and test some scalar types from the FlatBuffer. + assert(monster->hp() == 80); + assert(monster->mana() == 150); // default + assert(monster->name()->str() == "MyMonster"); + + // Get and test a field of the FlatBuffer's `struct`. + auto pos = monster->pos(); + assert(pos); + assert(pos->z() == 3.0f); + (void)pos; + + // Get a test an element from the `inventory` FlatBuffer's `vector`. + auto inv = monster->inventory(); + assert(inv); + assert(inv->Get(9) == 9); + (void)inv; + + // Get and test the `weapons` FlatBuffers's `vector`. + std::string expected_weapon_names[] = { "Sword", "Axe" }; + short expected_weapon_damages[] = { 3, 5 }; + auto weps = monster->weapons(); + for (unsigned int i = 0; i < weps->size(); i++) { + assert(weps->Get(i)->name()->str() == expected_weapon_names[i]); + assert(weps->Get(i)->damage() == expected_weapon_damages[i]); + } + (void)expected_weapon_names; + (void)expected_weapon_damages; + + // Get and test the `Equipment` union (`equipped` field). + assert(monster->equipped_type() == Equipment_Weapon); + auto equipped = static_cast<const Weapon *>(monster->equipped()); + assert(equipped->name()->str() == "Axe"); + assert(equipped->damage() == 5); + (void)equipped; + + printf("The FlatBuffer was successfully created and verified!\n"); +} diff --git a/examples/flatbuffers/shared/monster.fbs b/examples/flatbuffers/shared/monster.fbs new file mode 100644 index 000000000..247b81771 --- /dev/null +++ b/examples/flatbuffers/shared/monster.fbs @@ -0,0 +1,32 @@ +// Example IDL file for our monster's schema. + +namespace MyGame.Sample; + +enum Color:byte { Red = 0, Green, Blue = 2 } + +union Equipment { Weapon } // Optionally add more tables. + +struct Vec3 { + x:float; + y:float; + z:float; +} + +table Monster { + pos:Vec3; + mana:short = 150; + hp:short = 100; + name:string; + friendly:bool = false (deprecated); + inventory:[ubyte]; + color:Color = Blue; + weapons:[Weapon]; + equipped:Equipment; +} + +table Weapon { + name:string; + damage:short; +} + +root_type Monster; diff --git a/examples/grpc/grpc.qbs b/examples/grpc/grpc.qbs index c4f146ec0..b6d169508 100644 --- a/examples/grpc/grpc.qbs +++ b/examples/grpc/grpc.qbs @@ -32,15 +32,16 @@ import qbs.Utilities Project { condition: Utilities.versionCompare(qbs.version, "1.14") >= 0 + qbsModuleProviders: "qbspkgconfig" Application { Depends { name: "cpp" } Depends { name: "protobuf.cpp"; required: false } - condition: protobuf.cpp.present && qbs.targetOS === qbs.hostOS + condition: protobuf.cpp.present && qbs.targetPlatform === qbs.hostPlatform protobuf.cpp.useGrpc: true consoleApplication: true cpp.cxxLanguageVersion: "c++17" - cpp.minimumMacosVersion: "10.8" + cpp.minimumMacosVersion: "10.15" name: "client" files: "client.cpp" Properties { @@ -56,11 +57,11 @@ Project { Application { Depends { name: "cpp" } Depends { name: "protobuf.cpp"; required: false } - condition: protobuf.cpp.present && qbs.targetOS === qbs.hostOS + condition: protobuf.cpp.present && qbs.targetPlatform === qbs.hostPlatform protobuf.cpp.useGrpc: true consoleApplication: true cpp.cxxLanguageVersion: "c++17" - cpp.minimumMacosVersion: "10.8" + cpp.minimumMacosVersion: "10.15" name: "server" files: "server.cpp" Properties { diff --git a/examples/protobuf/addressbook_conan/addressbook_conan.qbs b/examples/protobuf/addressbook_conan/addressbook_conan.qbs new file mode 100644 index 000000000..c496d14bd --- /dev/null +++ b/examples/protobuf/addressbook_conan/addressbook_conan.qbs @@ -0,0 +1,20 @@ +//![0] + +import qbs.Host + +CppApplication { + consoleApplication: true + condition: protobuf.cpp.present && qbs.targetPlatform === Host.platform() + + Depends { name: "cpp" } + cpp.minimumMacosVersion: "11.0" + + Depends { name: "protobuf.cpp"; required: false } + + files: [ + "../shared/addressbook.proto", + "main.cpp", + ] + qbsModuleProviders: "conan" +} +//![0] diff --git a/examples/protobuf/addressbook_conan/conanfile.txt b/examples/protobuf/addressbook_conan/conanfile.txt new file mode 100644 index 000000000..e7d849b1a --- /dev/null +++ b/examples/protobuf/addressbook_conan/conanfile.txt @@ -0,0 +1,6 @@ +[requires] +protobuf/3.21.12 +[tool_requires] +protobuf/3.21.12 +[generators] +QbsDeps diff --git a/examples/protobuf/addressbook_conan/main.cpp b/examples/protobuf/addressbook_conan/main.cpp new file mode 100644 index 000000000..76e1e0d74 --- /dev/null +++ b/examples/protobuf/addressbook_conan/main.cpp @@ -0,0 +1,180 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <ctime> +#include <fstream> +#include <iostream> +#include <string> + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#include <google/protobuf/util/time_util.h> +#pragma GCC diagnostic pop +#else +#include <google/protobuf/util/time_util.h> +#endif // __GNUC__ + +#include "addressbook.pb.h" + +using google::protobuf::util::TimeUtil; + +int printUsage(char *argv0) +{ + std::cerr << "Usage: " << argv0 << "add|list ADDRESS_BOOK_FILE" << std::endl; + return -1; +} + +std::string readString(const std::string &promt) +{ + std::string result; + std::cout << promt; + std::getline(std::cin, result); + return result; +} + +// This function fills in a Person message based on user input. +void promptForAddress(tutorial::Person *person) +{ + std::cout << "Enter person ID number: "; + int id; + std::cin >> id; + person->set_id(id); + std::cin.ignore(256, '\n'); + + *person->mutable_name() = readString("Enter name: "); + + const auto email = readString("Enter email address (blank for none): "); + if (!email.empty()) + person->set_email(email); + + while (true) { + const auto number = readString("Enter a phone number (or leave blank to finish): "); + if (number.empty()) + break; + + tutorial::Person::PhoneNumber *phone_number = person->add_phones(); + phone_number->set_number(number); + + const auto type = readString("Is this a mobile, home, or work phone? "); + if (type == "mobile") + phone_number->set_type(tutorial::Person::MOBILE); + else if (type == "home") + phone_number->set_type(tutorial::Person::HOME); + else if (type == "work") + phone_number->set_type(tutorial::Person::WORK); + else + std::cout << "Unknown phone type. Using default." << std::endl; + } + *person->mutable_last_updated() = TimeUtil::SecondsToTimestamp(time(NULL)); +} + +// Iterates though all people in the AddressBook and prints info about them. +void listPeople(const tutorial::AddressBook &address_book) +{ + for (int i = 0; i < address_book.people_size(); i++) { + const tutorial::Person &person = address_book.people(i); + + std::cout << "Person ID: " << person.id() << std::endl; + std::cout << " Name: " << person.name() << std::endl; + if (!person.email().empty()) { + std::cout << " E-mail address: " << person.email() << std::endl; + } + + for (int j = 0; j < person.phones_size(); j++) { + const tutorial::Person::PhoneNumber &phone_number = person.phones(j); + + switch (phone_number.type()) { + case tutorial::Person::MOBILE: + std::cout << " Mobile phone #: "; + break; + case tutorial::Person::HOME: + std::cout << " Home phone #: "; + break; + case tutorial::Person::WORK: + std::cout << " Work phone #: "; + break; + default: + std::cout << " Unknown phone #: "; + break; + } + std::cout << phone_number.number() << std::endl; + } + if (person.has_last_updated()) { + std::cout << " Updated: " << TimeUtil::ToString(person.last_updated()) << std::endl; + } + } +} + +int main(int argc, char *argv[]) +{ + // Verify that the version of the library that we linked against is + // compatible with the version of the headers we compiled against. + GOOGLE_PROTOBUF_VERIFY_VERSION; + + if (argc != 3) + return printUsage(argv[0]); + + tutorial::AddressBook address_book; + + // Read the existing address book. + std::fstream input(argv[2], std::ios::in | std::ios::binary); + if (!input) { + std::cout << argv[2] << ": File not found." << std::endl; + } else if (!address_book.ParseFromIstream(&input)) { + std::cerr << "Failed to parse address book." << std::endl; + return -1; + } + + const std::string mode(argv[1]); + if (mode == "add") { + // Add an address. + promptForAddress(address_book.add_people()); + + if (!input) + std::cout << "Creating a new file." << std::endl; + + // Write the new address book back to disk. + std::fstream output(argv[2], std::ios::out | std::ios::trunc | std::ios::binary); + if (!address_book.SerializeToOstream(&output)) { + std::cerr << "Failed to write address book." << std::endl; + return -1; + } + } else if (mode == "list") { + listPeople(address_book); + } else { + return printUsage(argv[0]); + } + + // Optional: Delete all global objects allocated by libprotobuf. + google::protobuf::ShutdownProtobufLibrary(); + + return 0; +} diff --git a/examples/protobuf/addressbook_cpp/addressbook_cpp.qbs b/examples/protobuf/addressbook_cpp/addressbook_cpp.qbs index 667b30223..5a3b27652 100644 --- a/examples/protobuf/addressbook_cpp/addressbook_cpp.qbs +++ b/examples/protobuf/addressbook_cpp/addressbook_cpp.qbs @@ -5,8 +5,7 @@ CppApplication { condition: protobuf.cpp.present && qbs.targetPlatform === Host.platform() Depends { name: "cpp" } - cpp.cxxLanguageVersion: "c++11" - cpp.minimumMacosVersion: "10.8" + cpp.minimumMacosVersion: "10.15" Depends { name: "protobuf.cpp"; required: false } @@ -15,4 +14,5 @@ CppApplication { "main.cpp", "README.md", ] + qbsModuleProviders: "qbspkgconfig" } |