From a371b86d20ed6791806752a8516c55393663d2b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ritzl?= Date: Wed, 25 Sep 2024 08:16:16 +0200 Subject: [PATCH] Merged to extension pages --- docs/en/en.json | 4 - docs/en/manuals/extensions-best-practices.md | 120 ++++++++++--------- docs/en/manuals/extensions-details.md | 57 --------- 3 files changed, 62 insertions(+), 119 deletions(-) delete mode 100644 docs/en/manuals/extensions-details.md diff --git a/docs/en/en.json b/docs/en/en.json index 4091830a..494257e3 100644 --- a/docs/en/en.json +++ b/docs/en/en.json @@ -1531,10 +1531,6 @@ "path": "/manuals/extensions", "name": "Introduction" }, - { - "path": "/manuals/extensions-details", - "name": "Details" - }, { "path": "/manuals/extensions-defold-sdk", "name": "Defold SDK" diff --git a/docs/en/manuals/extensions-best-practices.md b/docs/en/manuals/extensions-best-practices.md index f40a7bb2..3a281f12 100644 --- a/docs/en/manuals/extensions-best-practices.md +++ b/docs/en/manuals/extensions-best-practices.md @@ -5,77 +5,30 @@ brief: This manual describes best practices when developing native extensions. # Best Practices -Writing cross platform code can be difficult, but there are some ways to make it easier to both develop and maintain. In this manual we list some ways we at Defold work with cross platform native code and APIs. - -## Defold code - -In the Defold engine we use C++ very sparingly. In fact, most code is very C-like. We avoid templates, except for a few container classes, due to the fact that templates both incurs a cost on compilation times as well as executable size. - -### C++ version - -The Defold source is built with the default C++ version of each compiler (See [Native Extensions - Best Practices](/manuals/extensions-best-practices/)). - -We avoid using the latest features or versions of C++. Mostly because we already have what we need to build a game engine. Keeping track of the latest features of C++ is a time consuming task, and to really master those features will require a lot of precious time. - -It also has the added benefit for our extension developers that we keep a stable ABI. Also worth pointing out is that using the latest C++ features may prevent the code from compiling on different platforms due to varying support. - -### Standard Template Libraries - STL - -Since the Defold engine doesn't use any STL code, except for some algorithms and math (std::sort, std::upper_bound etc), it may work for you to use STL in your extension. - -Again, bear in mind that ABI incompatibilites may hinder you when using your extension in conjunction with other extensions or 3rd party libraries. - -Avoiding the (heavily templated) STL libraries, also improves on our build times, and more importantly, the executable size. - -#### Strings - -In the Defold engine, we use `const char*` instead of `std::string`. - -`std::string` is a common pitfall when mixing different versions of C++ or compiler versions: you'll get an ABI mismatch. -For us, it's better to use `const char*` and a few helper functions. - -### Make functions hidden - -Use the `static` keyword on functions local to your compile unit if possible. This lets the compiler do some optimizations, and can both improve performance as well as reduce executable size. - -## 3rd party libraries - -When choosing a 3rd party library to use (regardless of language), we consider at least these things: - -* Functionality - Does it solve the particular problem you have? -* Performance - Does it infer a performance cost in the runtime? -* Library size - How much bigger will the final executable be? Is it acceptable? -* Dependencies - Does it require extra libraries? -* Support - What state is the library in? Does it have many open issues? Is it still maintained? -* License - Is it ok to use for this project? - - -## Open source dependencies - -Always make sure that you have access to your dependencies. E.g. if you depend on something on GitHub, there's nothing preventing that repository either being removed, or suddenly changes direction or ownership. You can mitigate this risk by forking the repository and using your fork instead of the upstream project. - -The code in that library will be injected into your game, so make sure the library does what it's supposed to do, and nothing more! +Writing cross platform code can be difficult, but there are some ways to make it easier to both develop and maintain such code. ## Project structure When creating an extension, there are a few things that help out in developing it as well as maintaining it. -### Lua api +### Lua API -There should only be one Lua api, and one implementation of it. This makes it a lot easier to behave the same for all platforms. +There should only be one Lua API, and one implementation of it. This makes it a lot easier to have the same behaviour for all platforms. -If the platform in question shouldn't support the extension, we recommend simply not registering a Lua module at all. -That way you can detect support by checking for nil: +If the platform in question shouldn't support the extension, it is recommended to simply not registering a Lua module at all. That way you can detect support by checking for nil: +```lua if myextension ~= nil then myextension.do_something() end +``` ### Folder structure -Here is a folder structure that we use frequently for our extensions. +The following folder structure is used frequently for extensions: +``` /root /input /main -- All the files for the actual example project @@ -100,14 +53,13 @@ Here is a folder structure that we use frequently for our extensions. / game.project game.appmanifest -- Any extra app configuration info - +``` Note that the `myextension.mm` and `myextension_android.cpp` are only needed if you are doing specific native calls for that platform. #### Platform folders -In certain places, we use the platform architecture as a folder name, to know what files to use when compiling/bundling the application. -These are of the form: +In certain places, the platform architecture is used as a folder name, to know what files to use when compiling/bundling the application. These are of the form: - @@ -122,3 +74,55 @@ So for instance, put platform specific libraries under: /libFoo.a /arm64-android /libFoo.a + + +## Writing native code + +In the Defold source C++ is used very sparingly. In fact, most code is very C-like. There is hardly any templates, except for a few container classes, due to the fact that templates both incurs a cost on compilation times as well as executable size. + +### C++ version + +The Defold source is built with the default C++ version of each compiler. The Defold source itself uses no C++ version higher than C++98. While it is possible to use a higher version to build an extension, a higher version might come with ABI changes. This might make it impossible to use one extension in conjunction with an extensions in the engine or from the [asset portal](/assets). + +The Defold source avoids using the latest features or versions of C++. Mostly because there is not need for new features when building a game engine, but also because keeping track of the latest features of C++ is a time consuming task, and to really master those features will require a lot of precious time. + +It also has the added benefit for extension developers that Defold maintains a stable ABI. Also worth pointing out is that using the latest C++ features may prevent the code from compiling on different platforms due to varying support. + +### No C++ Exceptions + +Defold does not make use of any exceptions in the engine. Exceptions are generally avoided in game engines, since the data is (mostly) known beforehand, during development. Removing the support for C++ exceptions decreases executable size and improves the runtime performance. + +### Standard Template Libraries - STL + +Since the Defold engine doesn't use any STL code, except for some algorithms and math (std::sort, std::upper_bound etc), it may work for you to use STL in your extension. + +Again, bear in mind that ABI incompatibilites may hinder you when using your extension in conjunction with other extensions or 3rd party libraries. + +Avoiding the (heavily templated) STL libraries, also improves on our build times, and more importantly, the executable size. + +#### Strings + +In the Defold engine `const char*` is used instead of `std::string`. The use `std::string` is a common pitfall when mixing different versions of C++ or compiler versions since it may resultin an ABI mismatch. Using `const char*` and a few helper functions will avoid this. + +### Make functions hidden + +Use the `static` keyword on functions local to your compile unit if possible. This lets the compiler do some optimizations, and can both improve performance as well as reduce executable size. + +## 3rd party libraries + +When choosing a 3rd party library to use (regardless of language), consider the following: + +* Functionality - Does it solve the particular problem you have? +* Performance - Does it infer a performance cost in the runtime? +* Library size - How much bigger will the final executable be? Is it acceptable? +* Dependencies - Does it require extra libraries? +* Support - What state is the library in? Does it have many open issues? Is it still maintained? +* License - Is it ok to use for this project? + + +## Open source dependencies + +Always make sure that you have access to your dependencies. E.g. if you depend on something on GitHub, there's nothing preventing that repository from either being removed, or suddenly change direction or ownership. You can mitigate this risk by forking the repository and using your fork instead of the upstream project. + +Remember that the code in the library will be injected into your game, so make sure the library does what it's supposed to do, and nothing more! + diff --git a/docs/en/manuals/extensions-details.md b/docs/en/manuals/extensions-details.md deleted file mode 100644 index 3d898c35..00000000 --- a/docs/en/manuals/extensions-details.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Native extensions - Details -brief: This manual describes some details about the build system used for native extensions. ---- - -# The Defold build setup - -Here we list some relevant build information, in order to make the integrations with your extensions as easy as possible. - -Here are some things to consider when you create an extension for the Defold engine. For more general guidelines on how to develop cross platform native code, and also extension/Lua apis, please refer to [Native Extensions - Best Practices](/manuals/extensions-best-practices) - -## C++ version - -In the engine itself we use no C++ version higher than C++98. While you may use a higher version to build your extension, bear in mind that a higher version might come with ABI changes. This might make it impossible to use your extension in conjunction with other extensions in the engine or on the asset store. - -When creating libraries (such as extensions), it's good to keep the lowest common denominator as a target. - -## Toolchain - -### SDK Versions - -For the most accurate list of versions, check the [build.py](./scripts/build.py). - -* Android: NDK r25b, Build Tools 33.0.1, Api Level 19 for armv7 and Api level 21 for arm64 -* iOS: iPhoneOS17.2.sdk -* macOS: MacOSX14.2.sdk -* Windows: WindowsKits 10.0, Microsoft Visual Studio 2022 -* Linux: Ubuntu 20.04, clang 17, locales, libssl-dev, openssl, libtool, autoconf, automake, build-essential, uuid-dev, libxi-dev, libopenal-dev, libgl1-mesa-dev, libglw1-mesa-dev, freeglut3-dev -* Html5: Emscripten 3.1.55 - -### C++ version + ABI compatibility - -* Linux: `clang 17` -* Android:`clang` using `NDK r25b` -* Html5: `Emscripten 3.1.55` -* Win32: `Microsoft Visual Studio 2012` (`clang 17` on build server) -* iOS/macOS: `apple-clang` (`clang 17` on build server) - -For iOS/macOS, we use `-miphoneos-version-min=11.0` and `-mmacosx-version-min=10.13` respectively. - -We don't specify a specific C++ version, so we use the default of each compiler. - -## Win32 + Clang - -A recent addition is to be able to build the Windows builds using clang. -This allows for faster builds on our servers, and also allows us to streamline our builds. - -## Static linkage - -The custom engine is built using static linkage. -The main reason is that on iOS version < 8, multiple executable binaries in an .ipa aren't allowed in the app store. - -## No C++ Exceptions - -We don't make use of any exceptions in the engine. -It isn't generally used in game engines, since the data is (mostly) known beforehand, during development. -Removing the support for C++ exceptions decreases executable size and improves the runtime performance.