Explorar el Código

DEF-3667: Added some extension details (#18)

Björn Ritzl hace 6 años
padre
commit
d31f05808e

+ 12 - 0
docs/en/en.json

@@ -423,6 +423,18 @@
                         "path": "/manuals/extensions",
                         "name": "Native extensions"
                     },
+                    {
+                        "path": "/manuals/extensions_details",
+                        "name": "Native extensions - Details"
+                    },
+                    {
+                        "path": "/manuals/extensions_best_practices",
+                        "name": "Native extensions - Best Practices"
+                    },
+                    {
+                        "path": "/manuals/extensions_build_variants",
+                        "name": "Native extensions - Build Variants"
+                    },
                     {
                         "path": "/manuals/iap",
                         "name": "In-app purchases"

+ 3 - 0
docs/en/manuals/extensions.md

@@ -47,6 +47,7 @@ Let's build a very simple extension. First, we create a new root folder *myexten
 ![Manifest](images/extensions/manifest.png)
 
 ```yaml
+# C++ symbol in your extension
 name: "MyExtension"
 ```
 
@@ -152,6 +153,8 @@ dmExtension::Result FinalizeMyExtension(dmExtension::Params* params)
 //
 // DM_DECLARE_EXTENSION(symbol, name, app_init, app_final, init, update, on_event, final)
 
+// MyExtension is the C++ symbol that holds all relevant extension data.
+// It must match the name field in the `ext.manifest`
 DM_DECLARE_EXTENSION(MyExtension, LIB_NAME, AppInitializeMyExtension, AppFinalizeMyExtension, InitializeMyExtension, 0, 0, FinalizeMyExtension)
 ```
 

+ 121 - 0
docs/en/manuals/extensions_best_practices.md

@@ -0,0 +1,121 @@
+# 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 document we list some ways we at Defold work with cross platform native code and API's.
+
+## 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` keywork 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!
+
+<legal note?>
+
+
+# Project structure
+
+When creating an extension, there are a few things that help out in developing it as well as maintaining it.
+
+## 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.
+
+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 myextension ~= nil then
+        myextension.do_something()
+    end
+
+## Folder structure
+
+Here is a folder structure that we use frequently for our extensions.
+
+    /root
+        /input
+        /main                            -- All the files for the actual example project
+            /...
+        /myextension                     -- The actual root folder of the extension
+            ext.manifest
+            /include                     -- External includes, used by other extensions
+            /libs
+                /<platform>              -- External libraries for all supported platforms
+            /src
+                myextension.cpp          -- The extension Lua api and the extension life cycle functions
+                                            Also contains generic implementations of your Lua api functions.
+                myextension_private.h    -- Your internal api that each platform will implement (I.e. `myextension_Init` etc)
+                myextension.mm           -- If native calls are needed for iOS/macOS. Implements `myextension_Init` etc for iOS/macOS
+                myextension_android.cpp  -- If JNI calls are needed for Android. Implements `myextension_Init` etc for Android
+                /java
+                    /<platform>          -- Any java files needed for Android
+            /res                         -- Any resources needed for a platform
+            /external
+                README.md                -- Notes/scripts on how to build or package any external libraries
+        /bundleres                       -- Resources that should be bundles for (see game.project and the [bundle_resources setting]([physics scale setting](/manuals/project-settings/#_project))
+            /<platform>
+        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:
+
+    <architecture>-<platform>
+
+The current list is:
+
+    arm64-ios,armv7-ios,arm64-android,armv7-android,x86_64-linux,x86_64-osx,x86_64-win32,x86-win32
+
+So for instance, put platform specific libraries under:
+
+    /libs
+        /arm64-ios
+                            /libFoo.a
+        /arm64-android
+                            /libFoo.a

+ 150 - 0
docs/en/manuals/extensions_build_variants.md

@@ -0,0 +1,150 @@
+# Native Extensions - Build Variants
+
+## Build Variants
+
+When you bundle a game, you need to choose what type of engine you wish to use.
+
+  * Debug
+  * Release
+  * Headless
+
+These different versions are also referred to as `Build variants`
+
+Note: When you choose `Build and run` you'll get the debug version.
+
+### Debug
+
+This type of executable still has the debugging feature left inside it, such as profiling, logging and hot reload. This variant is chosen during development of the game.
+
+### Release
+
+This variant has the debugging features disabled. This options is chosen when the game is ready to be released to the app store.
+
+### Headless
+
+This executable runs without any graphics and sound. It means that you can run the game unit/smoke tests on a CI server, or even have it as a game server in the cloud.
+
+## App Manifest
+
+Not only can you add native code to the engine with the Native Extensions feature, you can also remove standard parts of the engine. E.g. if you don't need a physics engine, you can remove that from the executable.
+
+We support this via a file called an `App Manifest` (.appmanifest). In such a file, you can configure what libraries or symbols to remove, or perhaps add compile flags
+
+This feature is still being developed and improved.
+
+### Combined context
+
+The app manifest actually has the same structure and syntax as the extension manifest. This allows us to merge the contexts for one platform together when finally building.
+
+And, Defold itself, has its own build manifest as the foundation (`build.yml`). For each extension that is built, the manifests are combined as follows:
+
+	manifest = merge(game.appmanifest, ext.manifest, build.yml)
+
+This is so the user can override the default behaviour of the engine and also each extension. And, for the final link stage, we merge the app manifest with the defold manifest:
+
+	manifest = merge(game.appmanifest, build.yml)
+
+### Editing
+
+Currently, the process can be done manually, but we recommend our users to use the [Manifestation](https://britzl.github.io/manifestation/) tool to create their app manifest. Eventually, the creation and modification of the app manifests will be done in the Editor.
+
+### Syntax
+
+Here is an example from the [Manifestation](https://britzl.github.io/manifestation/) tool for reference (Subject to change. Don't copy this file directly. Instead, use the online tool):
+
+	platforms:
+	    x86_64-osx:
+	        context:
+	            excludeLibs: []
+	            excludeSymbols: []
+	            libs: []
+	            linkFlags: []
+	    x86_64-linux:
+	        context:
+	            excludeLibs: []
+	            excludeSymbols: []
+	            libs: []
+	            linkFlags: []
+	    js-web:
+	        context:
+	            excludeLibs: []
+	            excludeJsLibs: []
+	            excludeSymbols: []
+	            libs: []
+	            linkFlags: []
+	    wasm-web:
+	        context:
+	            excludeLibs: []
+	            excludeJsLibs: []
+	            excludeSymbols: []
+	            libs: []
+	            linkFlags: []
+	    x86-win32:
+	        context:
+	            excludeLibs: []
+	            excludeSymbols: []
+	            libs: []
+	            linkFlags: []
+	    x86_64-win32:
+	        context:
+	            excludeLibs: []
+	            excludeSymbols: []
+	            libs: []
+	            linkFlags: []
+	    armv7-android:
+	        context:
+	            excludeLibs: []
+	            excludeJars: []
+	            excludeSymbols: []
+	            libs: []
+	            linkFlags: []
+	    armv7-ios:
+	        context:
+	            excludeLibs: []
+	            excludeSymbols: []
+	            libs: []
+	            linkFlags: []
+	    arm64-ios:
+	        context:
+	            excludeLibs: []
+	            excludeSymbols: []
+	            libs: []
+	            linkFlags: []
+
+
+#### White listing
+
+For all the keywords, we apply white listing filter. This is to avoid illegal path handling and accessing files outside of the build upload folder.
+
+#### linkFlags
+
+Here you can add flags to the specific platform compiler.
+
+#### libs
+
+This flag is only used if you wish to add a library that is part of the platform or Defold SDK. All libraries in your app's extensions are added automatically, and you shouldn't add those to this flag. Here's an example where the 3D physics is removed from the engine:
+
+    x86_64-linux:
+        context:
+            excludeLibs: ["physics","LinearMath","BulletDynamics","BulletCollision"]
+            excludeSymbols: []
+            libs: ["physics_2d"]
+            linkFlags: []
+
+#### Exclude flags
+
+These flags are used to remove things previously defined in the platform context. Here's an example of how to remove the Facebook extension from the engine (Note the `(.*)` which is a regexp to help remove the correct items).
+
+    armv7-android:
+        context:
+            excludeLibs: ["facebookext"]
+            excludeJars: ["(.*)/facebooksdk.jar","(.*)/facebook_android.jar"]
+            excludeSymbols: ["FacebookExt"]
+            libs: []
+            linkFlags: []
+
+#### Where's the list of all flags, libraries, symbols???
+
+We might put some of them here, but we also think our time is better spent completing the feature of moving the manifest configuration into the Editor, making it a seamless step for the user.
+
+In the meantime, we'll keep the [Manifestation](https://britzl.github.io/manifestation/) tool updated.

+ 66 - 0
docs/en/manuals/extensions_details.md

@@ -0,0 +1,66 @@
+
+# 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
+
+Clang - macOS, iOS, Win32
+GCC - Android, Linux
+
+*We're plan make both Android and Linux to use Clang as well*
+
+## SDK Versions
+
+* Android: NDK 10e, Build Tools 23.0.2, Api Level 14
+* iOS: iPhoneOS11.2.sdk
+* MacOS: MacOSX10.13.sdk
+* Windows: WindowsKits 8.1 + 10.0, Microsoft Visual Studio 14.0
+* Linux: Ubuntu 16.04, gcc 5.4.0, libssl-dev, uuid-dev, libxi-dev, libopenal-dev, libgl1-mesa-dev, libglw1-mesa-dev, freeglut3-dev
+* Html5: Emscripten 1.38.0,
+
+## C++ version + ABI compatibility
+
+* Linux: `GCC 5.4.0`
+* Android:`GCC 4.8`
+* Html5: `Emscripten 1.35.0`
+* Win32: `Microsoft Visual Studio 14.0` alt `clang-6.0`
+* iOS/MacOS: `apple-clang` alt `clang-6.0`
+
+For iOS/MacOS, we use `-miphoneos-version-min=6.0` and `-mmacosx-version-min=10.7` 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.
+
+# Defold SDK
+
+With each (biweekly) release of Defold, we release a new Defold SDK.
+With it, we ship the libraries of the engine, and also a build manifest file,
+which is identical in structure and syntax as the [extension](/manuals/extensions_build_variants) and [app](/manuals/extensions_build_variants) manifests.
+
+(This sdk is not yet public)
+

+ 1 - 1
docs/ko/manuals/project-settings.md

@@ -55,7 +55,7 @@ $ adb shell cat /mnt/sdcard/Android/data/com.defold.dmengine/files/log.txt
 이 프로젝트가 사용하는 프로젝트의 **Library URL:s** ([Defold dashboard](https://www.defold.com/dashboard/)에서 찾을 수 있음) 을 쉼표로 구분하여 나열합니다. 종속 프로젝트의 멤버여야 합니다.
 #### custom_resources (hidden setting)
 프로젝트에 포함될 쉼표로 구분된 리소스 목록입니다. 디렉토리가 지정되면 이 디렉토리의 모든 파일과 디렉토리들이 재귀적으로(recursively) 포함됩니다.
-#### bundle_resources (hidden setting)
+#### bundle_resources
 번들을 만들 때 결과 패키지에 그대로 복사해야하는 리소스 파일과 폴더를 포함하고 있는 디렉토리입니다. 이 디렉토리는 예를 들어 "/res" 같이 프로젝트 루트의 절대 경로(absolute path)로 지정됩니다. 이 리소스 디렉토리에는 platform 이나 architecure-platform 이라는 이름의 하위 폴더를 포함해야 합니다. 지원되는 플랫폼은 ios, android, osx 입니다. 지원되는 arc-platform 계열으로는 armv7-ios, arm64-ios, armv7-android, x86_64-osx 가 있습니다. 또한 common 이라는 이름의 하위 폴더에 모든 플랫폼의 공통적인 리소스 파일을 포함 시킬 수도 있습니다.
 
 ## Display