├── .gdignore ├── bin ├── linux │ └── .gitkeep ├── macos │ └── .gitkeep ├── android │ └── .gitkeep └── windows │ └── .gitkeep ├── demo ├── bin │ ├── linux │ │ └── .gitkeep │ ├── macos │ │ └── .gitkeep │ ├── android │ │ └── .gitkeep │ ├── windows │ │ └── .gitkeep │ └── example.gdextension ├── example.gd ├── example.tscn ├── project.godot ├── icon.svg.import └── icon.svg ├── .gitattributes ├── .gitmodules ├── .vscode └── extensions.json ├── src ├── register_types.h ├── example_class.cpp ├── example_class.h └── register_types.cpp ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── bug_report.yml └── workflows │ ├── ci.yml │ └── make_build.yml ├── doc_classes └── ExampleClass.xml ├── .gitignore ├── LICENSE.md ├── methods.py ├── SConstruct ├── CMakeLists.txt ├── README.md └── .clang-format /.gdignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/linux/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/macos/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/android/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/windows/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/bin/linux/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/bin/macos/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/bin/android/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/bin/windows/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize EOL for all files that Git considers text files. 2 | * text=auto eol=lf 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "godot-cpp"] 2 | path = godot-cpp 3 | url = https://github.com/godotengine/godot-cpp.git 4 | branch = 4.3 5 | -------------------------------------------------------------------------------- /demo/example.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | 4 | func _ready() -> void: 5 | var example := ExampleClass.new() 6 | example.print_type(example) 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ms-vscode.cpptools-extension-pack", 4 | "ms-python.python" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/register_types.h: -------------------------------------------------------------------------------- 1 | #ifndef EXAMPLE_REGISTER_TYPES_H 2 | #define EXAMPLE_REGISTER_TYPES_H 3 | 4 | void initialize_gdextension_types(); 5 | void uninitialize_gdextension_types(); 6 | 7 | #endif // EXAMPLE_REGISTER_TYPES_H -------------------------------------------------------------------------------- /demo/example.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://dh0oj81pufivs"] 2 | 3 | [ext_resource type="Script" path="res://example.gd" id="1_jdh55"] 4 | 5 | [node name="Node" type="Node"] 6 | script = ExtResource("1_jdh55") 7 | -------------------------------------------------------------------------------- /src/example_class.cpp: -------------------------------------------------------------------------------- 1 | #include "example_class.h" 2 | 3 | void ExampleClass::_bind_methods() { 4 | godot::ClassDB::bind_method(D_METHOD("print_type", "variant"), &ExampleClass::print_type); 5 | } 6 | 7 | void ExampleClass::print_type(const Variant &p_variant) const { 8 | print_line(vformat("Type: %d", p_variant.get_type())); 9 | } 10 | -------------------------------------------------------------------------------- /demo/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="godot cpp template" 14 | config/features=PackedStringArray("4.1", "Forward Plus") 15 | config/icon="res://icon.svg" 16 | -------------------------------------------------------------------------------- /src/example_class.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "godot_cpp/classes/ref_counted.hpp" 4 | #include "godot_cpp/classes/wrapped.hpp" 5 | #include "godot_cpp/variant/variant.hpp" 6 | 7 | using namespace godot; 8 | 9 | class ExampleClass : public RefCounted { 10 | GDCLASS(ExampleClass, RefCounted) 11 | 12 | protected: 13 | static void _bind_methods(); 14 | 15 | public: 16 | ExampleClass() = default; 17 | ~ExampleClass() override = default; 18 | 19 | void print_type(const Variant &p_variant) const; 20 | }; 21 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = tab 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [{*.gradle,AndroidManifest.xml}] 11 | indent_style = space 12 | indent_size = 4 13 | 14 | [{*.py,SConstruct,SCsub}] 15 | indent_style = space 16 | indent_size = 4 17 | 18 | # YAML requires indentation with spaces instead of tabs. 19 | [*.{yml,yaml}] 20 | indent_style = space 21 | indent_size = 2 22 | 23 | [{*.cmake,CMakeLists.txt}] 24 | indent_style = space 25 | ij_continuation_indent_size = 4 26 | ij_cmake_force_commands_case = 1 27 | 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | 3 | contact_links: 4 | - name: Godot proposals 5 | url: https://github.com/godotengine/godot-proposals 6 | about: Please submit feature proposals on the Godot proposals repository, not here. 7 | 8 | - name: Godot documentation repository 9 | url: https://github.com/godotengine/godot-docs 10 | about: Please report issues with documentation on the Godot documentation repository, not here. 11 | 12 | - name: Godot community channels 13 | url: https://godotengine.org/community 14 | about: Please ask for technical support on one of the other community channels, not here. 15 | -------------------------------------------------------------------------------- /doc_classes/ExampleClass.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Example class. 5 | 6 | 7 | An example class. 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Print the type of the variant. 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /demo/icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dbx66sovxd1" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Godot auto generated files 2 | *.gen.* 3 | .godot/ 4 | 5 | # Ignore library files but not the gdextension file 6 | demo/bin/* 7 | !demo/bin/android 8 | demo/bin/android/* 9 | !demo/bin/android/.gitkeep 10 | !demo/bin/linux 11 | demo/bin/linux/* 12 | !demo/bin/linux/.gitkeep 13 | !demo/bin/macos 14 | demo/bin/macos/* 15 | !demo/bin/macos/.gitkeep 16 | !demo/bin/windows 17 | demo/bin/windows/* 18 | !demo/bin/windows/.gitkeep 19 | !demo/bin/*.gdextension 20 | .sconsign*.dblite 21 | 22 | # Ignore custom.py 23 | custom.py 24 | 25 | # Ignore generated compile_commands.json 26 | compile_commands.json 27 | 28 | # Ignore files generated for documentation 29 | /src/gen 30 | 31 | # Binaries 32 | *.o 33 | *.os 34 | *.so 35 | *.obj 36 | *.bc 37 | *.pyc 38 | *.dblite 39 | *.pdb 40 | *.lib 41 | *.config 42 | *.creator 43 | *.creator.user 44 | *.files 45 | *.includes 46 | *.idb 47 | *.exp 48 | 49 | # Other stuff 50 | *.log 51 | 52 | # VSCode 53 | .vscode/* 54 | !.vscode/extensions.json 55 | .DS_Store 56 | 57 | # Jetbrains 58 | .idea/ 59 | 60 | # Cmake 61 | cmake-build* 62 | CMakeUserPresets.json -------------------------------------------------------------------------------- /src/register_types.cpp: -------------------------------------------------------------------------------- 1 | #include "register_types.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "example_class.h" 9 | 10 | using namespace godot; 11 | 12 | void initialize_gdextension_types(ModuleInitializationLevel p_level) 13 | { 14 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { 15 | return; 16 | } 17 | GDREGISTER_CLASS(ExampleClass); 18 | } 19 | 20 | void uninitialize_gdextension_types(ModuleInitializationLevel p_level) { 21 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { 22 | return; 23 | } 24 | } 25 | 26 | extern "C" 27 | { 28 | // Initialization 29 | GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) 30 | { 31 | GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); 32 | init_obj.register_initializer(initialize_gdextension_types); 33 | init_obj.register_terminator(uninitialize_gdextension_types); 34 | init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE); 35 | 36 | return init_obj.init(); 37 | } 38 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Report a bug with the godot-cpp template 3 | body: 4 | 5 | - type: markdown 6 | attributes: 7 | value: | 8 | - Write a descriptive issue title above. 9 | - Search [open](https://github.com/godotengine/godot-cpp-template/issues) and [closed](https://github.com/godotengine/godot-cpp-template/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. 10 | - type: input 11 | attributes: 12 | label: Godot version 13 | description: > 14 | Specify the Git commit hash of your Godot build. 15 | placeholder: v4.0.stable.official [92bee43ad] 16 | validations: 17 | required: true 18 | 19 | - type: input 20 | attributes: 21 | label: godot-cpp version 22 | description: > 23 | Specify the Git commit hash of the godot-cpp submodule in your project. You can run `git status` inside the folder to check it. 24 | placeholder: v4.0.stable.official [9d1c396c5] 25 | validations: 26 | required: true 27 | 28 | - type: input 29 | attributes: 30 | label: System information 31 | description: | 32 | Specify the OS version. 33 | placeholder: Windows 10 34 | validations: 35 | required: true 36 | 37 | - type: textarea 38 | attributes: 39 | label: Issue description 40 | description: | 41 | Describe your issue briefly. What doesn't work, and how do you expect it to work instead? 42 | You can include images or videos with drag and drop, and format code blocks or logs with ``` tags. 43 | validations: 44 | required: true -------------------------------------------------------------------------------- /methods.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from enum import Enum 4 | 5 | # Colors are disabled in non-TTY environments such as pipes. This means 6 | # that if output is redirected to a file, it won't contain color codes. 7 | # Colors are always enabled on continuous integration. 8 | _colorize = bool(sys.stdout.isatty() or os.environ.get("CI")) 9 | 10 | 11 | class ANSI(Enum): 12 | """ 13 | Enum class for adding ansi colorcodes directly into strings. 14 | Automatically converts values to strings representing their 15 | internal value, or an empty string in a non-colorized scope. 16 | """ 17 | 18 | RESET = "\x1b[0m" 19 | 20 | BOLD = "\x1b[1m" 21 | ITALIC = "\x1b[3m" 22 | UNDERLINE = "\x1b[4m" 23 | STRIKETHROUGH = "\x1b[9m" 24 | REGULAR = "\x1b[22;23;24;29m" 25 | 26 | BLACK = "\x1b[30m" 27 | RED = "\x1b[31m" 28 | GREEN = "\x1b[32m" 29 | YELLOW = "\x1b[33m" 30 | BLUE = "\x1b[34m" 31 | MAGENTA = "\x1b[35m" 32 | CYAN = "\x1b[36m" 33 | WHITE = "\x1b[37m" 34 | 35 | PURPLE = "\x1b[38;5;93m" 36 | PINK = "\x1b[38;5;206m" 37 | ORANGE = "\x1b[38;5;214m" 38 | GRAY = "\x1b[38;5;244m" 39 | 40 | def __str__(self) -> str: 41 | global _colorize 42 | return str(self.value) if _colorize else "" 43 | 44 | 45 | def print_warning(*values: object) -> None: 46 | """Prints a warning message with formatting.""" 47 | print(f"{ANSI.YELLOW}{ANSI.BOLD}WARNING:{ANSI.REGULAR}", *values, ANSI.RESET, file=sys.stderr) 48 | 49 | 50 | def print_error(*values: object) -> None: 51 | """Prints an error message with formatting.""" 52 | print(f"{ANSI.RED}{ANSI.BOLD}ERROR:{ANSI.REGULAR}", *values, ANSI.RESET, file=sys.stderr) 53 | -------------------------------------------------------------------------------- /SConstruct: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | from methods import print_error 6 | 7 | 8 | libname = "EXTENSION-NAME" 9 | projectdir = "demo" 10 | 11 | localEnv = Environment(tools=["default"], PLATFORM="") 12 | 13 | # Build profiles can be used to decrease compile times. 14 | # You can either specify "disabled_classes", OR 15 | # explicitly specify "enabled_classes" which disables all other classes. 16 | # Modify the example file as needed and uncomment the line below or 17 | # manually specify the build_profile parameter when running SCons. 18 | 19 | # localEnv["build_profile"] = "build_profile.json" 20 | 21 | customs = ["custom.py"] 22 | customs = [os.path.abspath(path) for path in customs] 23 | 24 | opts = Variables(customs, ARGUMENTS) 25 | opts.Update(localEnv) 26 | 27 | Help(opts.GenerateHelpText(localEnv)) 28 | 29 | env = localEnv.Clone() 30 | 31 | if not (os.path.isdir("godot-cpp") and os.listdir("godot-cpp")): 32 | print_error("""godot-cpp is not available within this folder, as Git submodules haven't been initialized. 33 | Run the following command to download godot-cpp: 34 | 35 | git submodule update --init --recursive""") 36 | sys.exit(1) 37 | 38 | env = SConscript("godot-cpp/SConstruct", {"env": env, "customs": customs}) 39 | 40 | env.Append(CPPPATH=["src/"]) 41 | sources = Glob("src/*.cpp") 42 | 43 | if env["target"] in ["editor", "template_debug"]: 44 | try: 45 | doc_data = env.GodotCPPDocData("src/gen/doc_data.gen.cpp", source=Glob("doc_classes/*.xml")) 46 | sources.append(doc_data) 47 | except AttributeError: 48 | print("Not including class reference as we're targeting a pre-4.3 baseline.") 49 | 50 | # .dev doesn't inhibit compatibility, so we don't need to key it. 51 | # .universal just means "compatible with all relevant arches" so we don't need to key it. 52 | suffix = env['suffix'].replace(".dev", "").replace(".universal", "") 53 | 54 | lib_filename = "{}{}{}{}".format(env.subst('$SHLIBPREFIX'), libname, suffix, env.subst('$SHLIBSUFFIX')) 55 | 56 | library = env.SharedLibrary( 57 | "bin/{}/{}".format(env['platform'], lib_filename), 58 | source=sources, 59 | ) 60 | 61 | copy = env.Install("{}/bin/{}/".format(projectdir, env["platform"]), library) 62 | 63 | default_args = [library, copy] 64 | Default(*default_args) 65 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Using the same minimum as the godot-cpp project 2 | cmake_minimum_required(VERSION 3.17) 3 | 4 | # Silence unused variable warning when specified from toolchain 5 | if(CMAKE_C_COMPILER) 6 | endif() 7 | 8 | set(LIBNAME "EXTENSION-NAME" CACHE STRING "The name of the library") 9 | set(GODOT_PROJECT_DIR "demo" CACHE STRING "The directory of a Godot project folder") 10 | 11 | # Make sure all the dependencies are satisfied 12 | find_package(Python3 3.4 REQUIRED) 13 | find_program(GIT git REQUIRED) 14 | 15 | # Ensure godot-cpp submodule has been updated 16 | if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/godot-cpp/src") 17 | message(NOTICE "godot-cpp bindings source not found") 18 | message(NOTICE "initializing/updating the godot-cpp submodule...") 19 | 20 | # update the c++ bindings submodule to populate it with the necessary source for the library 21 | execute_process( 22 | COMMAND git submodule update --init godot-cpp 23 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} 24 | COMMAND_ERROR_IS_FATAL ANY 25 | ) 26 | endif() 27 | add_subdirectory(godot-cpp SYSTEM) 28 | 29 | # Add godot-cpp's module path and include the exported functions. 30 | # This is made available for documentation generation 31 | set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${godot-cpp_SOURCE_DIR}/cmake") 32 | include(GodotCPPModule) 33 | 34 | # The godot-cpp target has some of useful properties attached that can be retrieved like so. 35 | get_target_property(GODOTCPP_SUFFIX godot::cpp GODOTCPP_SUFFIX) 36 | get_target_property(GODOTCPP_PLATFORM godot::cpp GODOTCPP_PLATFORM) 37 | 38 | # Now we can specify our own project which will inherit any global cmake properties or variables that have been defined. 39 | project(godot-cpp-template 40 | VERSION 1.0 41 | DESCRIPTION "This repository serves as a quickstart template for GDExtension development with Godot 4.0+." 42 | HOMEPAGE_URL "https://github.com/enetheru/godot-cpp-template/tree/main" 43 | LANGUAGES CXX 44 | ) 45 | 46 | add_library(${LIBNAME} SHARED) 47 | 48 | target_sources(${LIBNAME} 49 | PRIVATE 50 | src/register_types.cpp 51 | src/register_types.h 52 | src/example_class.cpp 53 | src/example_class.h 54 | ) 55 | 56 | # Fetch a list of the xml files to use for documentation and add to our target 57 | file(GLOB_RECURSE DOC_XML LIST_DIRECTORIES NO CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/doc_classes/*.xml") 58 | 59 | # conditionally add doc data to compile output 60 | if(DOC_XML) 61 | if(GODOTCPP_TARGET MATCHES "editor|template_debug") 62 | target_doc_sources(${LIBNAME} ${DOC_XML}) 63 | endif() 64 | endif() 65 | 66 | target_link_libraries(${LIBNAME} PRIVATE godot-cpp) 67 | 68 | # Require at least C++17 for this target 69 | set_property(TARGET ${LIBNAME} PROPERTY CXX_STANDARD 17) 70 | 71 | set_target_properties(${LIBNAME} 72 | PROPERTIES 73 | # The generator expression here prevents msvc from adding a Debug or Release subdir. 74 | RUNTIME_OUTPUT_DIRECTORY "$<1:${PROJECT_SOURCE_DIR}/bin/${GODOTCPP_PLATFORM}>" 75 | 76 | PREFIX "" 77 | OUTPUT_NAME "${LIBNAME}${GODOTCPP_SUFFIX}" 78 | ) 79 | 80 | set(GODOT_PROJECT_BINARY_DIR "${PROJECT_SOURCE_DIR}/${GODOT_PROJECT_DIR}/bin/${GODOTCPP_PLATFORM}") 81 | 82 | add_custom_command(TARGET ${LIBNAME} POST_BUILD 83 | COMMAND ${CMAKE_COMMAND} -E copy "$" "${GODOT_PROJECT_BINARY_DIR}/$" 84 | ) 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # godot-cpp template 2 | This repository serves as a quickstart template for GDExtension development with Godot 4.0+. 3 | 4 | ## Contents 5 | * Preconfigured source files for C++ development of the GDExtension ([src/](./src/)) 6 | * An empty Godot project in [demo/](./demo), to test the GDExtension 7 | * godot-cpp as a submodule (`godot-cpp/`) 8 | * GitHub Issues template ([.github/ISSUE_TEMPLATE.yml](./.github/ISSUE_TEMPLATE.yml)) 9 | * GitHub CI/CD workflows to publish your library packages when creating a release ([.github/workflows/builds.yml](./.github/workflows/builds.yml)) 10 | * An SConstruct file with various functions, such as boilerplate for [Adding documentation](https://docs.godotengine.org/en/stable/tutorials/scripting/cpp/gdextension_docs_system.html) 11 | 12 | ## Usage - Template 13 | 14 | To use this template, log in to GitHub and click the green "Use this template" button at the top of the repository page. This will let you create a copy of this repository with a clean git history. 15 | 16 | To get started with your new GDExtension, do the following: 17 | 18 | * clone your repository to your local computer 19 | * initialize the godot-cpp git submodule via `git submodule update --init` 20 | * change the name of the compiled library file inside the [SConstruct](./SConstruct) file by modifying the `libname` string. 21 | * change the paths of the to be loaded library name inside the [demo/bin/example.gdextension](./demo/bin/example.gdextension) file, by replacing `EXTENSION-NAME` with the name you chose for `libname`. 22 | * change the `entry_symbol` string inside [demo/bin/example.gdextension](./demo/bin/example.gdextension) file. 23 | * rename the `example_library_init` function in [src/register_types.cpp](./src/register_types.cpp) to the same name you chose for `entry_symbol`. 24 | * change the name of the `demo/bin/example.gdextension` file 25 | 26 | Now, you can build the project with the following command: 27 | 28 | ```shell 29 | scons 30 | ``` 31 | 32 | If the build command worked, you can test it with the [demo](./demo) project. Import it into Godot, open it, and launch the main scene. You should see it print the following line in the console: 33 | 34 | ``` 35 | Type: 24 36 | ``` 37 | 38 | ### Configuring an IDE 39 | You can develop your own extension with any text editor and by invoking scons on the command line, but if you want to work with an IDE (Integrated Development Environment), you can use a compilation database file called `compile_commands.json`. Most IDEs should automatically identify this file, and self-configure appropriately. 40 | To generate the database file, you can run one of the following commands in the project root directory: 41 | ```shell 42 | # Generate compile_commands.json while compiling 43 | scons compiledb=yes 44 | 45 | # Generate compile_commands.json without compiling 46 | scons compiledb=yes compile_commands.json 47 | ``` 48 | 49 | ## Usage - Actions 50 | 51 | This repository comes with continuous integration (CI) through a GitHub action that tests building the GDExtension. 52 | It triggers automatically for each pushed change. You can find and edit it in [builds.yml](.github/workflows/ci.yml). 53 | 54 | There is also a workflow ([make_build.yml](.github/workflows/make_build.yml)) that builds the GDExtension for all supported platforms that you can use to create releases. 55 | You can trigger this workflow manually from the `Actions` tab on GitHub. 56 | After it is complete, you can find the file `godot-cpp-template.zip` in the `Artifacts` section of the workflow run. 57 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # For syntax, see https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax 2 | # This workflow is automatically triggered for every push and pull request, to verify that everything still builds. 3 | 4 | name: Continuous Integration 5 | on: 6 | workflow_call: 7 | push: 8 | pull_request: 9 | merge_group: 10 | 11 | jobs: 12 | build: 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | # Test a few selected combinations of parameters ("test case matrix"). 17 | # While it would be nice to test all needed combinations, in practice this would a waste of CI usage time. 18 | # By building just with a few combinations, we only need a few runners, 19 | # while still achieving adequate coverage. 20 | # To make a full build with all combinations, use the make_build.yml workflow instead. 21 | include: 22 | - target: { platform: linux, arch: x86_64, os: ubuntu-22.04 } 23 | target-type: template_debug 24 | float-precision: double 25 | - target: { platform: windows, arch: x86_64, os: windows-latest } 26 | target-type: template_release 27 | float-precision: single 28 | - target: { platform: macos, arch: universal, os: macos-latest } 29 | target-type: template_debug 30 | float-precision: single 31 | - target: { platform: android, arch: arm64, os: ubuntu-22.04 } 32 | target-type: template_debug 33 | float-precision: single 34 | - target: { platform: web, arch: wasm32, os: ubuntu-22.04 } 35 | target-type: template_release 36 | float-precision: double 37 | 38 | runs-on: ${{ matrix.target.os }} 39 | steps: 40 | # Clone this repository 41 | - name: Checkout 42 | uses: actions/checkout@v4 43 | with: 44 | submodules: true 45 | 46 | # Lint 47 | #- name: Setup clang-format 48 | # shell: bash 49 | # run: | 50 | # python -m pip install clang-format 51 | #- name: Run clang-format 52 | # shell: bash 53 | # run: | 54 | # clang-format src/** --dry-run --Werror 55 | 56 | # Add linux x86_32 toolchain 57 | - name: Install multilib support 58 | if: ${{ matrix.target.platform == 'linux' && matrix.target.arch == 'x86_32' }} 59 | run: | 60 | sudo apt-get update && sudo apt-get install -y gcc-multilib g++-multilib 61 | 62 | # Setup dependencies 63 | - name: Setup godot-cpp 64 | uses: ./godot-cpp/.github/actions/setup-godot-cpp 65 | with: 66 | platform: ${{ matrix.target.platform }} 67 | em-version: 3.1.62 68 | 69 | # Build GDExtension (with caches) 70 | 71 | - name: Restore .scons_cache 72 | uses: ./godot-cpp/.github/actions/godot-cache-restore 73 | with: 74 | scons-cache: ${{ github.workspace }}/.scons-cache/ 75 | cache-name: ${{ matrix.target.platform }}_${{ matrix.target.arch }}_${{ matrix.float-precision }}_${{ matrix.target-type }} 76 | 77 | - name: Build GDExtension Debug Build 78 | shell: sh 79 | env: 80 | SCONS_CACHE: ${{ github.workspace }}/.scons-cache/ 81 | run: | 82 | scons target=${{ matrix.target-type }} platform=${{ matrix.target.platform }} arch=${{ matrix.target.arch }} precision=${{ matrix.float-precision }} 83 | 84 | - name: Save .scons_cache 85 | uses: ./godot-cpp/.github/actions/godot-cache-save 86 | with: 87 | scons-cache: ${{ github.workspace }}/.scons-cache/ 88 | cache-name: ${{ matrix.target.platform }}_${{ matrix.target.arch }}_${{ matrix.float-precision }}_${{ matrix.target-type }} 89 | -------------------------------------------------------------------------------- /demo/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /demo/bin/example.gdextension: -------------------------------------------------------------------------------- 1 | [configuration] 2 | 3 | entry_symbol = "example_library_init" 4 | compatibility_minimum = "4.1" 5 | 6 | [libraries] 7 | ; Relative paths ensure that our GDExtension can be placed anywhere in the project directory. 8 | macos.single.debug = "./macos/libEXTENSION-NAME.macos.template_debug.dylib" 9 | macos.double.debug = "./macos/libEXTENSION-NAME.macos.template_debug.double.dylib" 10 | macos.single.release = "./macos/libEXTENSION-NAME.macos.template_release.dylib" 11 | macos.double.release = "./macos/libEXTENSION-NAME.macos.template_release.double.dylib" 12 | 13 | ios.arm64.single.debug = "./ios/libEXTENSION-NAME.ios.template_debug.arm64.dylib" 14 | ios.arm64.double.debug = "./ios/libEXTENSION-NAME.ios.template_debug.arm64.double.dylib" 15 | ios.arm64.single.release = "./ios/libEXTENSION-NAME.ios.template_release.arm64.dylib" 16 | ios.arm64.double.release = "./ios/libEXTENSION-NAME.ios.template_release.arm64.double.dylib" 17 | 18 | windows.x86_32.single.debug = "./windows/EXTENSION-NAME.windows.template_debug.x86_32.dll" 19 | windows.x86_32.double.debug = "./windows/EXTENSION-NAME.windows.template_debug.x86_32.double.dll" 20 | windows.x86_32.single.release = "./windows/EXTENSION-NAME.windows.template_release.x86_32.dll" 21 | windows.x86_32.double.release = "./windows/EXTENSION-NAME.windows.template_release.x86_32.double.dll" 22 | 23 | windows.x86_64.single.debug = "./windows/EXTENSION-NAME.windows.template_debug.x86_64.dll" 24 | windows.x86_64.double.debug = "./windows/EXTENSION-NAME.windows.template_debug.x86_64.double.dll" 25 | windows.x86_64.single.release = "./windows/EXTENSION-NAME.windows.template_release.x86_64.dll" 26 | windows.x86_64.double.release = "./windows/EXTENSION-NAME.windows.template_release.x86_64.double.dll" 27 | 28 | linux.x86_64.single.debug = "./linux/libEXTENSION-NAME.linux.template_debug.x86_64.so" 29 | linux.x86_64.double.debug = "./linux/libEXTENSION-NAME.linux.template_debug.x86_64.double.so" 30 | linux.x86_64.single.release = "./linux/libEXTENSION-NAME.linux.template_release.x86_64.so" 31 | linux.x86_64.double.release = "./linux/libEXTENSION-NAME.linux.template_release.x86_64.double.so" 32 | 33 | linux.arm64.single.debug = "./linux/libEXTENSION-NAME.linux.template_debug.arm64.so" 34 | linux.arm64.double.debug = "./linux/libEXTENSION-NAME.linux.template_debug.arm64.double.so" 35 | linux.arm64.single.release = "./linux/libEXTENSION-NAME.linux.template_release.arm64.so" 36 | linux.arm64.double.release = "./linux/libEXTENSION-NAME.linux.template_release.arm64.double.so" 37 | 38 | linux.rv64.single.debug = "./linux/libEXTENSION-NAME.linux.template_debug.rv64.so" 39 | linux.rv64.double.debug = "./linux/libEXTENSION-NAME.linux.template_debug.rv64.double.so" 40 | linux.rv64.single.release = "./linux/libEXTENSION-NAME.linux.template_release.rv64.so" 41 | linux.rv64.double.release = "./linux/libEXTENSION-NAME.linux.template_release.rv64.double.so" 42 | 43 | android.x86_64.single.debug = "./android/libEXTENSION-NAME.android.template_debug.x86_64.so" 44 | android.x86_64.double.debug = "./android/libEXTENSION-NAME.android.template_debug.x86_64.double.so" 45 | android.x86_64.single.release = "./android/libEXTENSION-NAME.android.template_release.x86_64.so" 46 | android.x86_64.double.release = "./android/libEXTENSION-NAME.android.template_release.x86_64.double.so" 47 | 48 | android.arm64.single.debug = "./android/libEXTENSION-NAME.android.template_debug.arm64.so" 49 | android.arm64.double.debug = "./android/libEXTENSION-NAME.android.template_debug.arm64.double.so" 50 | android.arm64.single.release = "./android/libEXTENSION-NAME.android.template_release.arm64.so" 51 | android.arm64.double.release = "./android/libEXTENSION-NAME.android.template_release.arm64.double.so" 52 | 53 | web.wasm32.single.debug = "./web/libEXTENSION-NAME.web.template_debug.wasm32.nothreads.wasm" 54 | web.wasm32.double.debug = "./web/libEXTENSION-NAME.web.template_debug.wasm32.double.nothreads.wasm" 55 | web.wasm32.single.release = "./web/libEXTENSION-NAME.web.template_release.wasm32.nothreads.wasm" 56 | web.wasm32.double.release = "./web/libEXTENSION-NAME.web.template_release.wasm32.double.nothreads.wasm" 57 | -------------------------------------------------------------------------------- /.github/workflows/make_build.yml: -------------------------------------------------------------------------------- 1 | # For syntax, see https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax 2 | # This workflow is triggered manually on the "Actions" tab on GitHub, and can be used to create releases. 3 | 4 | name: Make a GDExtension build for all supported platforms 5 | on: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | # A build is made for every possible combination of parameters 14 | # You can add or remove entries from the arrays of each parameter to customize which builds you want to run. 15 | # See https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow 16 | target: 17 | [ 18 | { platform: linux, arch: x86_64, os: ubuntu-22.04 }, 19 | { platform: linux, arch: x86_32, os: ubuntu-22.04 }, 20 | { platform: linux, arch: arm64, os: ubuntu-22.04-arm }, 21 | { platform: linux, arch: arm32, os: ubuntu-22.04-arm }, 22 | { platform: windows, arch: x86_64, os: windows-latest }, 23 | { platform: windows, arch: x86_32, os: windows-latest }, 24 | { platform: windows, arch: arm64, os: windows-latest }, 25 | { platform: macos, arch: universal, os: macos-latest }, 26 | { platform: android, arch: x86_64, os: ubuntu-22.04 }, 27 | { platform: android, arch: x86_32, os: ubuntu-22.04 }, 28 | { platform: android, arch: arm64, os: ubuntu-22.04 }, 29 | { platform: android, arch: arm32, os: ubuntu-22.04 }, 30 | { platform: ios, arch: arm64, os: macos-latest }, 31 | { platform: web, arch: wasm32, os: ubuntu-22.04 }, 32 | ] 33 | target-type: [template_debug, template_release] 34 | float-precision: [single] 35 | 36 | runs-on: ${{ matrix.target.os }} 37 | steps: 38 | # Clone this repository 39 | - name: Checkout 40 | uses: actions/checkout@v4 41 | with: 42 | submodules: true 43 | 44 | # Add linux x86_32 toolchain 45 | - name: Install multilib support 46 | if: ${{ matrix.target.platform == 'linux' && matrix.target.arch == 'x86_32' }} 47 | run: | 48 | sudo apt-get update && sudo apt-get install -y gcc-multilib g++-multilib 49 | 50 | # Setup dependencies 51 | - name: Setup godot-cpp 52 | uses: ./godot-cpp/.github/actions/setup-godot-cpp 53 | with: 54 | platform: ${{ matrix.target.platform }} 55 | em-version: 3.1.62 56 | 57 | # Build GDExtension (with caches) 58 | 59 | - name: Restore .scons_cache 60 | uses: ./godot-cpp/.github/actions/godot-cache-restore 61 | with: 62 | scons-cache: ${{ github.workspace }}/.scons-cache/ 63 | cache-name: ${{ matrix.target.platform }}_${{ matrix.target.arch }}_${{ matrix.float-precision }}_${{ matrix.target-type }} 64 | 65 | - name: Build GDExtension Debug Build 66 | shell: sh 67 | env: 68 | SCONS_CACHE: ${{ github.workspace }}/.scons-cache/ 69 | run: | 70 | scons target=${{ matrix.target-type }} platform=${{ matrix.target.platform }} arch=${{ matrix.target.arch }} precision=${{ matrix.float-precision }} 71 | 72 | - name: Save .scons_cache 73 | uses: ./godot-cpp/.github/actions/godot-cache-save 74 | with: 75 | scons-cache: ${{ github.workspace }}/.scons-cache/ 76 | cache-name: ${{ matrix.target.platform }}_${{ matrix.target.arch }}_${{ matrix.float-precision }}_${{ matrix.target-type }} 77 | 78 | # Clean up compilation files 79 | - name: Windows - Delete compilation files 80 | if: ${{ matrix.target.platform == 'windows' }} 81 | shell: pwsh 82 | run: | 83 | Remove-Item bin/* -Include *.exp,*.lib,*.pdb -Force 84 | 85 | # Upload the build 86 | - name: Upload Artifact 87 | uses: actions/upload-artifact@v4 88 | with: 89 | name: godot-cpp-template-${{ matrix.target.platform }}-${{ matrix.target.arch }}-${{ matrix.float-precision }}-${{ matrix.target-type }} 90 | path: | 91 | ${{ github.workspace }}/bin/** 92 | 93 | # Merges all the build artifacts together into a single godot-cpp-template artifact. 94 | # If you comment out this step, all the builds will be uploaded individually. 95 | merge: 96 | runs-on: ubuntu-22.04 97 | needs: build 98 | steps: 99 | - name: Merge Artifacts 100 | uses: actions/upload-artifact/merge@v4 101 | with: 102 | name: godot-cpp-template 103 | pattern: godot-cpp-template-* 104 | delete-merged: true 105 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | # Commented out parameters are those with the same value as base LLVM style. 2 | # We can uncomment them if we want to change their value, or enforce the 3 | # chosen value in case the base style changes (last sync: Clang 14.0). 4 | --- 5 | ### General config, applies to all languages ### 6 | BasedOnStyle: LLVM 7 | AccessModifierOffset: -4 8 | AlignAfterOpenBracket: DontAlign 9 | # AlignArrayOfStructures: None 10 | # AlignConsecutiveMacros: None 11 | # AlignConsecutiveAssignments: None 12 | # AlignConsecutiveBitFields: None 13 | # AlignConsecutiveDeclarations: None 14 | # AlignEscapedNewlines: Right 15 | AlignOperands: DontAlign 16 | AlignTrailingComments: false 17 | # AllowAllArgumentsOnNextLine: true 18 | AllowAllParametersOfDeclarationOnNextLine: false 19 | # AllowShortEnumsOnASingleLine: true 20 | # AllowShortBlocksOnASingleLine: Never 21 | # AllowShortCaseLabelsOnASingleLine: false 22 | # AllowShortFunctionsOnASingleLine: All 23 | # AllowShortLambdasOnASingleLine: All 24 | # AllowShortIfStatementsOnASingleLine: Never 25 | # AllowShortLoopsOnASingleLine: false 26 | # AlwaysBreakAfterDefinitionReturnType: None 27 | # AlwaysBreakAfterReturnType: None 28 | # AlwaysBreakBeforeMultilineStrings: false 29 | # AlwaysBreakTemplateDeclarations: MultiLine 30 | # AttributeMacros: 31 | # - __capability 32 | # BinPackArguments: true 33 | # BinPackParameters: true 34 | # BraceWrapping: 35 | # AfterCaseLabel: false 36 | # AfterClass: false 37 | # AfterControlStatement: Never 38 | # AfterEnum: false 39 | # AfterFunction: false 40 | # AfterNamespace: false 41 | # AfterObjCDeclaration: false 42 | # AfterStruct: false 43 | # AfterUnion: false 44 | # AfterExternBlock: false 45 | # BeforeCatch: false 46 | # BeforeElse: false 47 | # BeforeLambdaBody: false 48 | # BeforeWhile: false 49 | # IndentBraces: false 50 | # SplitEmptyFunction: true 51 | # SplitEmptyRecord: true 52 | # SplitEmptyNamespace: true 53 | # BreakBeforeBinaryOperators: None 54 | # BreakBeforeConceptDeclarations: true 55 | # BreakBeforeBraces: Attach 56 | # BreakBeforeInheritanceComma: false 57 | # BreakInheritanceList: BeforeColon 58 | # BreakBeforeTernaryOperators: true 59 | # BreakConstructorInitializersBeforeComma: false 60 | BreakConstructorInitializers: AfterColon 61 | # BreakStringLiterals: true 62 | ColumnLimit: 0 63 | # CommentPragmas: '^ IWYU pragma:' 64 | # QualifierAlignment: Leave 65 | # CompactNamespaces: false 66 | ConstructorInitializerIndentWidth: 8 67 | ContinuationIndentWidth: 8 68 | Cpp11BracedListStyle: false 69 | # DeriveLineEnding: true 70 | # DerivePointerAlignment: false 71 | # DisableFormat: false 72 | # EmptyLineAfterAccessModifier: Never 73 | # EmptyLineBeforeAccessModifier: LogicalBlock 74 | # ExperimentalAutoDetectBinPacking: false 75 | # PackConstructorInitializers: BinPack 76 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 77 | # AllowAllConstructorInitializersOnNextLine: true 78 | # FixNamespaceComments: true 79 | # ForEachMacros: 80 | # - foreach 81 | # - Q_FOREACH 82 | # - BOOST_FOREACH 83 | # IfMacros: 84 | # - KJ_IF_MAYBE 85 | # IncludeBlocks: Preserve 86 | IncludeCategories: 87 | - Regex: '".*"' 88 | Priority: 1 89 | - Regex: '^<.*\.h>' 90 | Priority: 2 91 | - Regex: '^<.*' 92 | Priority: 3 93 | # IncludeIsMainRegex: '(Test)?$' 94 | # IncludeIsMainSourceRegex: '' 95 | # IndentAccessModifiers: false 96 | IndentCaseLabels: true 97 | # IndentCaseBlocks: false 98 | # IndentGotoLabels: true 99 | # IndentPPDirectives: None 100 | # IndentExternBlock: AfterExternBlock 101 | # IndentRequires: false 102 | IndentWidth: 4 103 | # IndentWrappedFunctionNames: false 104 | # InsertTrailingCommas: None 105 | # JavaScriptQuotes: Leave 106 | # JavaScriptWrapImports: true 107 | KeepEmptyLinesAtTheStartOfBlocks: false 108 | # LambdaBodyIndentation: Signature 109 | # MacroBlockBegin: '' 110 | # MacroBlockEnd: '' 111 | # MaxEmptyLinesToKeep: 1 112 | # NamespaceIndentation: None 113 | # PenaltyBreakAssignment: 2 114 | # PenaltyBreakBeforeFirstCallParameter: 19 115 | # PenaltyBreakComment: 300 116 | # PenaltyBreakFirstLessLess: 120 117 | # PenaltyBreakOpenParenthesis: 0 118 | # PenaltyBreakString: 1000 119 | # PenaltyBreakTemplateDeclaration: 10 120 | # PenaltyExcessCharacter: 1000000 121 | # PenaltyReturnTypeOnItsOwnLine: 60 122 | # PenaltyIndentedWhitespace: 0 123 | # PointerAlignment: Right 124 | # PPIndentWidth: -1 125 | # ReferenceAlignment: Pointer 126 | # ReflowComments: true 127 | # RemoveBracesLLVM: false 128 | # SeparateDefinitionBlocks: Leave 129 | # ShortNamespaceLines: 1 130 | # SortIncludes: CaseSensitive 131 | # SortJavaStaticImport: Before 132 | # SortUsingDeclarations: true 133 | # SpaceAfterCStyleCast: false 134 | # SpaceAfterLogicalNot: false 135 | # SpaceAfterTemplateKeyword: true 136 | # SpaceBeforeAssignmentOperators: true 137 | # SpaceBeforeCaseColon: false 138 | # SpaceBeforeCpp11BracedList: false 139 | # SpaceBeforeCtorInitializerColon: true 140 | # SpaceBeforeInheritanceColon: true 141 | # SpaceBeforeParens: ControlStatements 142 | # SpaceBeforeParensOptions: 143 | # AfterControlStatements: true 144 | # AfterForeachMacros: true 145 | # AfterFunctionDefinitionName: false 146 | # AfterFunctionDeclarationName: false 147 | # AfterIfMacros: true 148 | # AfterOverloadedOperator: false 149 | # BeforeNonEmptyParentheses: false 150 | # SpaceAroundPointerQualifiers: Default 151 | # SpaceBeforeRangeBasedForLoopColon: true 152 | # SpaceInEmptyBlock: false 153 | # SpaceInEmptyParentheses: false 154 | # SpacesBeforeTrailingComments: 1 155 | # SpacesInAngles: Never 156 | # SpacesInConditionalStatement: false 157 | # SpacesInContainerLiterals: true 158 | # SpacesInCStyleCastParentheses: false 159 | ## Godot TODO: We'll want to use a min of 1, but we need to see how to fix 160 | ## our comment capitalization at the same time. 161 | SpacesInLineCommentPrefix: 162 | Minimum: 0 163 | Maximum: -1 164 | # SpacesInParentheses: false 165 | # SpacesInSquareBrackets: false 166 | # SpaceBeforeSquareBrackets: false 167 | # BitFieldColonSpacing: Both 168 | # StatementAttributeLikeMacros: 169 | # - Q_EMIT 170 | # StatementMacros: 171 | # - Q_UNUSED 172 | # - QT_REQUIRE_VERSION 173 | TabWidth: 4 174 | # UseCRLF: false 175 | UseTab: Always 176 | # WhitespaceSensitiveMacros: 177 | # - STRINGIZE 178 | # - PP_STRINGIZE 179 | # - BOOST_PP_STRINGIZE 180 | # - NS_SWIFT_NAME 181 | # - CF_SWIFT_NAME 182 | --- 183 | ### C++ specific config ### 184 | Language: Cpp 185 | Standard: c++17 186 | --- 187 | ### ObjC specific config ### 188 | Language: ObjC 189 | # ObjCBinPackProtocolList: Auto 190 | ObjCBlockIndentWidth: 4 191 | # ObjCBreakBeforeNestedBlockParam: true 192 | # ObjCSpaceAfterProperty: false 193 | # ObjCSpaceBeforeProtocolList: true 194 | --- 195 | ### Java specific config ### 196 | Language: Java 197 | # BreakAfterJavaFieldAnnotations: false 198 | JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax'] 199 | ... 200 | --------------------------------------------------------------------------------