{
    "archive_path": "archive/1790676378.953906",
    "base_url": "blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html",
    "basename": "Using-Any-Cpp-Library-In-Godot.html",
    "bookmarked_date": "2026-09-29 10:06",
    "canonical": {
        "archive_org_path": "https://web.archive.org/web/blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html",
        "dom_path": "output.html",
        "favicon_path": "favicon.ico",
        "git_path": "git/",
        "google_favicon_path": "https://www.google.com/s2/favicons?domain=blog.conan.io",
        "headers_path": "headers.json",
        "htmltotext_path": "htmltotext.txt",
        "index_path": "index.html",
        "media_path": "media/",
        "mercury_path": "mercury/content.html",
        "pdf_path": "output.pdf",
        "readability_path": "readability/content.html",
        "screenshot_path": "screenshot.png",
        "singlefile_path": "singlefile.html",
        "warc_path": "warc/",
        "wget_path": "blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html"
    },
    "domain": "blog.conan.io",
    "extension": "html",
    "hash": "1939ZP45MVXJYV2DP9Z5",
    "history": {
        "archive_org": [],
        "dom": [],
        "favicon": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://www.google.com/s2/favicons?domain=blog.conan.io"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-29T10:09:29.677841+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1790676378.953906",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-29T10:09:29.159049+00:00",
                "status": "succeeded"
            }
        ],
        "git": [],
        "headers": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--head",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-29T10:09:30.002302+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1790676378.953906",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-29T10:09:29.684710+00:00",
                "status": "succeeded"
            }
        ],
        "htmltotext": [],
        "media": [],
        "mercury": [
            {
                "cmd": [
                    "/app/node_modules/@postlight/parser/cli.js",
                    "https://blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html"
                ],
                "cmd_version": "1.0.0",
                "end_ts": "2026-09-29T10:09:40.585749+00:00",
                "index_texts": null,
                "output": "mercury",
                "pwd": "/data/archive/1790676378.953906",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-29T10:09:37.274834+00:00",
                "status": "succeeded"
            }
        ],
        "pdf": [],
        "readability": [
            {
                "cmd": [
                    "/app/node_modules/readability-extractor/readability-extractor",
                    "/tmp/tmpqxwenynu",
                    "https://blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-09-29T10:09:37.264948+00:00",
                "index_texts": [
                    "Godot has become one of the most popular game\nengines of the last few years. It is free, open source under the MIT license,\nand small enough to download and start using in minutes. Most Godot games are\nwritten in GDScript, the engine\u2019s own scripting language.\n\nSooner or later, though, many projects need something that already exists as\na C or C++ library: a simulation library, a database, a networking protocol,\na machine learning runtime. GDScript cannot call native code, but Godot can\nload it through GDExtension, and godot-cpp, the official C++\nbindings, lets you expose that code as regular engine classes. Writing the\nC++ code is the easy part. The hard part is the build: godot-cpp has to match\nyour Godot version, and every library you add has to be compiled for each\nplatform you ship to.\n\nIn this post we give a short tour of Godot, explain how C++ extensions work,\nand show how to bring C++ libraries into a Godot game with Conan and\ngodot-cpp 10, now available in ConanCenter. As an example we\nwill use flecs, an Entity\nComponent System library, to simulate 100,000 particles inside a Godot scene.\n\n\n    \n        \n        Download the video\n    \n    \n        100,000 particles simulated with flecs inside a Godot scene, fleeing from the mouse cursor\n    \n\n\nA Quick Introduction to Godot\n\nGodot is a general purpose engine for 2D and 3D games. Everything in a Godot\nproject is built from two concepts:\n\n\n  Nodes are the basic building blocks. Each node has a type (Sprite2D,\nCamera3D, AudioStreamPlayer, Timer\u2026), a set of properties you can\nedit in the Inspector, and callbacks such as _ready() or _process() that\nthe engine calls during the game loop.\n  Scenes are trees of nodes saved to disk as .tscn files. A scene can be\na character, a menu or a whole level, and scenes can be instanced inside\nother scenes.\n\n\nBehavior is usually added by attaching a script to a node. GDScript is a\nPython-like language designed for the engine, and it is great for gameplay\nlogic because changes show up immediately without a compile step.\n\nWhat makes Godot interesting for C++ developers is that the engine itself is\nwritten in C++, and it can load extensions written in C++ without being\nrecompiled. A class that comes from one of these extensions becomes a regular\nengine class: it shows up in the editor next to the built-in nodes, with its\nproperties in the Inspector, and GDScript can use it like any other node. The\nnext section explains how these extensions work.\n\nExtending Godot with C++\n\nThere are two ways to add C++ code to Godot:\n\n\n  Engine\nmodules\nare compiled into the engine itself. They have full access to the\ninternals, but you need to build and ship your own copy of Godot, including\nthe editor and export templates for every platform.\n  GDExtension\nloads a shared library (.dll, .so, .dylib, or .wasm on the web) into\nan official, unmodified Godot build at runtime. The engine talks to the\nlibrary through a stable C interface.\n\n\nGDExtension is the recommended approach for most projects, and it is how many\npopular plugins are distributed today. Because the C interface is verbose to\nuse directly, the Godot team maintains\ngodot-cpp, a C++ library that\nwraps it with an API very close to the one used inside the engine. It provides\na C++ class for every engine class, such as Node2D, Sprite2D or Input.\n\nYour own classes are regular C++ code that derives from those classes. A node\nwritten with godot-cpp looks like this:\n\n#include <godot_cpp/classes/node2d.hpp>\n\nnamespace godot {\n\nclass MyNode : public Node2D {\n    GDCLASS(MyNode, Node2D)\n\nprotected:\n    static void _bind_methods() {}\n\npublic:\n    void _process(double p_delta) override {\n        // runs every frame\n    }\n};\n\n} // namespace godot\n\n\nSince version 10.0, a single godot-cpp release works with any Godot version\nfrom 4.3 onwards. You pick one with the api_version build option, and\ngodot-cpp generates its C++ classes from the API of that version. An\nextension built for Godot 4.3 also works in newer versions, but not in older\nones, so you usually pick the oldest Godot version you want to support.\n\nBuild targets and feature tags\n\nThere is one more concept you need to know before building anything.\ngodot-cpp is compiled for one of three targets, named after the Godot\nbuilds that load the library:\n\n\n  template_debug: the default. Enables debug checks through the\nDEBUG_ENABLED definition. This library is loaded by the editor and by\ndebug exports.\n  template_release: for release exports, with the debug checks removed.\n  editor: for libraries that are only loaded by the editor.\n\n\nWhich library Godot loads is decided at runtime by a small .gdextension\nfile. It maps feature tags to library paths. The debug tag matches the\neditor and debug exports, and the release tag matches release exports:\n\n[configuration]\nentry_symbol = \"gdexample_library_init\"\ncompatibility_minimum = \"4.7\"\n\n[libraries]\nmacos.debug = \"res://bin/libgdexample.template_debug.dylib\"\nmacos.release = \"res://bin/libgdexample.template_release.dylib\"\nlinux.debug = \"res://bin/libgdexample.template_debug.so\"\nlinux.release = \"res://bin/libgdexample.template_release.so\"\nwindows.debug = \"res://bin/libgdexample.template_debug.dll\"\nwindows.release = \"res://bin/libgdexample.template_release.dll\"\n\n\nThe usual workflow\n\nThe Godot\ndocumentation\nrecommends adding godot-cpp to your repository as a git submodule and\nbuilding it together with your library using SCons. That works well for a\nfirst extension, but every project ends up compiling its own godot-cpp for\neach target, platform and architecture, and any third party library you\nwrap, such as a physics engine or a machine learning runtime, has to be\nvendored and built with matching flags for every platform Godot exports to.\n\nBoth are exactly the kind of problem Conan was built to solve.\n\nManaging the Dependencies with Conan\n\nWith the godot-cpp recipe in ConanCenter, godot-cpp becomes a regular\npackage. The two parameters discussed above are Conan options:\n\n\n  api_version: the Godot API version the bindings target, from 4.3 to\n4.7 (the default).\n  target: template_debug (the default), template_release or editor.\n\n\nEach combination is built once and then reused by every project that needs\nit, instead of being compiled inside each extension.\n\nYour GDExtension becomes just another C++ project with dependencies. Any of\nthe more than 1,900 libraries in ConanCenter, or\none you package yourself with a Conan\nrecipe, can be\nadded next to godot-cpp, and Conan builds all of them consistently for every\nplatform you target.\n\nA Practical Example: A Swarm of 100,000 Particles\n\nTo show how this works in practice, we will write a GDExtension that\nregisters a new Swarm node. It simulates 100,000 particles that flee from\nthe mouse cursor and bounce off the window edges, and draws all of them in a\nGodot scene.\n\nThe simulation runs on flecs, an\nEntity Component System (ECS) library for C and C++. In an ECS, entities\nare plain ids, components are plain data structs attached to them, and\nsystems are functions that run over every entity that has a given set of\ncomponents. Components of the same type are stored together in memory, which\nmakes iterating over large numbers of entities very fast. That is why ECS is\na popular choice for simulations, crowds or bullet hell games. It is also\nthe kind of work where native code pays off, since updating this many\nentities every frame is much faster in C++ than in GDScript.\n\nYou can find the complete example in the Conan examples2\nrepository:\n\n$ git clone https://github.com/conan-io/examples2.git\n$ cd examples2/examples/libraries/godot-cpp/gdextension\n\n\nThe src folder contains the extension code, and demo is a regular Godot\nproject that loads it.\n\nDeclaring the dependencies\n\nThe conanfile.py requires godot-cpp and flecs from ConanCenter:\n\nfrom conan import ConanFile\nfrom conan.tools.cmake import CMake, CMakeToolchain, cmake_layout\n\n\nclass GDExtensionExample(ConanFile):\n    package_type = \"shared-library\"\n    settings = \"os\", \"compiler\", \"build_type\", \"arch\"\n    generators = \"CMakeDeps\"\n\n    def requirements(self):\n        self.requires(\"godot-cpp/10.0.0\")\n        self.requires(\"flecs/4.1.6\")\n\n    def layout(self):\n        cmake_layout(self)\n\n    def generate(self):\n        tc = CMakeToolchain(self)\n        # Godot picks the library to load by its build \"target\", so we name\n        # the output after the target godot-cpp was built with\n        tc.cache_variables[\"GODOTCPP_TARGET\"] = str(self.dependencies[\"godot-cpp\"].options.target)\n        tc.generate()\n\n    def build(self):\n        cmake = CMake(self)\n        cmake.configure()\n        cmake.build()\n\n\nThe only Godot specific detail is in generate(). We read the target\noption of the godot-cpp dependency and pass it to CMake, so the name of the\nlibrary always matches the godot-cpp binary it was linked against.\n\nThe CMakeLists.txt\n\ncmake_minimum_required(VERSION 3.15)\nproject(gdexample LANGUAGES CXX)\n\nfind_package(godot-cpp REQUIRED CONFIG)\nfind_package(flecs REQUIRED CONFIG)\n\nadd_library(gdexample SHARED\n    src/register_types.cpp\n    src/swarm.cpp\n)\ntarget_link_libraries(gdexample PRIVATE godot-cpp flecs::flecs_static)\n\n# Output as demo/bin/libgdexample.<target>.<ext>, the path the\n# demo/bin/gdexample.gdextension file points Godot to. The generator\n# expression prevents multi-config generators from adding a Release/ subfolder\nset_target_properties(gdexample PROPERTIES\n    OUTPUT_NAME \"gdexample.${GODOTCPP_TARGET}\"\n    PREFIX \"lib\"\n    LIBRARY_OUTPUT_DIRECTORY \"$<1:${CMAKE_SOURCE_DIR}/demo/bin>\"\n    RUNTIME_OUTPUT_DIRECTORY \"$<1:${CMAKE_SOURCE_DIR}/demo/bin>\"\n)\n\n\nThis is a completely standard CMake project. The extension is a shared\nlibrary that links godot-cpp and flecs statically, so there is a single\nlibrary file to ship. We write it straight into demo/bin so Godot finds it\nwithout an extra copy step.\n\nWriting the node\n\nThe Swarm class derives from Node2D and owns the flecs world. The\ncomponents of each particle are plain structs. The GDCLASS macro adds the\nboilerplate that Godot\u2019s class system needs, and _bind_methods() declares\nwhat Godot can see, in this case the count and flee_radius properties.\nOnce the class is registered, they appear in the Inspector and can be used\nfrom GDScript. This is a simplified view of the class:\n\nstruct Position { float x, y; };\nstruct Velocity { float x, y; };\n\nclass Swarm : public Node2D {\n    GDCLASS(Swarm, Node2D)\n\n    int count = 100000;\n    double flee_radius = 150.0;\n    flecs::world world;\n    ...\n\nprotected:\n    static void _bind_methods() {\n        ClassDB::bind_method(D_METHOD(\"set_count\", \"count\"), &Swarm::set_count);\n        ClassDB::bind_method(D_METHOD(\"get_count\"), &Swarm::get_count);\n        ADD_PROPERTY(PropertyInfo(Variant::INT, \"count\"), \"set_count\", \"get_count\");\n        // ... and the same for flee_radius\n    }\n    ...\n};\n\n\nThe rest of the node connects both worlds. _ready() creates one flecs\nentity per particle and a flecs system that updates them. It also sets up a\nMultiMesh,\nwhich draws many instances of the same mesh in a single draw call, because\none Godot node per particle would be far too heavy for 100,000 of them.\n\nEvery frame, _process() hands the mouse position to flecs, runs the systems\nwith world.progress(), and copies the resulting positions back into the\nMultiMesh. Again, this is a simplified view, and the full code is in the\nrepository:\n\nvoid Swarm::_ready() {\n    // One entity per particle, with a Position and a Velocity component\n    for (int i = 0; i < count; i++) {\n        world.entity().set<Position>({ ... }).set<Velocity>({ ... });\n    }\n\n    // A system that runs for every entity with both components\n    world.system<Position, Velocity>(\"Move\").each([this](flecs::iter &it, size_t, Position &p, Velocity &v) {\n        // flee from the mouse, move, and bounce off the window edges\n    });\n\n    // A MultiMeshInstance2D child node that draws all the particles\n    ...\n}\n\nvoid Swarm::_process(double p_delta) {\n    mouse = get_local_mouse_position();\n    world.progress(static_cast<float>(p_delta));\n\n    // Copy the position of every entity into the MultiMesh buffer\n    render_query.each([&](const Position &p, const Velocity &v) { ... });\n    multimesh->set_buffer(buffer);\n}\n\n\nRegistering the extension\n\nFinally, register_types.cpp registers the class when Godot loads the\nlibrary:\n\nvoid initialize_gdexample_module(ModuleInitializationLevel p_level) {\n    if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {\n        return;\n    }\n    GDREGISTER_RUNTIME_CLASS(Swarm);\n}\n\n\nWe register Swarm with GDREGISTER_RUNTIME_CLASS. By default, the code of\na GDExtension class also runs inside the editor, so _ready() and\n_process() would start the simulation while you are editing the scene. A\nruntime class is only a placeholder in the editor: you can add it to a\nscene and set its properties, but its code only runs when the game is\nrunning.\n\nThe same file defines gdexample_library_init(), the entry point named in\nthe .gdextension file. It is a few lines of boilerplate that look the same\nin every extension.\n\nBuilding and running\n\nWith everything in place, building the extension is a single command:\n\n$ conan build . --build=missing\n...\n[100%] Linking CXX shared library .../demo/bin/libgdexample.template_debug.dylib\n[100%] Built target gdexample\n\n\nConan resolves godot-cpp and flecs, downloads precompiled binaries from\nConanCenter when they exist for your configuration, builds the rest from\nsource, generates the CMake integration and finally builds the extension.\n\n\n  Note: godot-cpp requires C++17. If your default profile uses an older\nstandard, which is the case for MSVC, add -s compiler.cppstd=17 to the\ncommand.\n\n\nNow start Godot 4.7, click \u201cImport\u201d in the Project Manager, and select\ndemo/project.godot. When the project opens, Godot reads\nbin/gdexample.gdextension, loads the library, and Swarm becomes available\nlike any built-in node. You can find it in the \u201cCreate New Node\u201d dialog,\nunder Node2D:\n\n\n    \n\n\nThe main scene of the demo already contains a Swarm node. Selecting it\nshows count and flee_radius in the Inspector, the two properties we bound\nin _bind_methods():\n\n\n    \n\n\nPress Play to run the scene, and move the mouse over the window to push the\nparticles around. Then stop it, change count or flee_radius in the\nInspector, and play it again to see how the swarm behaves with more particles\nor a wider flee radius.\n\nConclusion\n\nGDExtension and godot-cpp let you write engine classes in C++, and Conan\ntakes care of building godot-cpp and any other C++ library your extension\nneeds. This is also a big advantage when you distribute the extension:\nbuilding it for every platform you ship to only takes changing the settings\nof the build.\n\n\n  Note for Linux: By default, the extension links libstdc++ dynamically,\nso the target system must provide a version at least as new as the one used\nto build it. For broad compatibility, build the extension and its\ndependencies against a toolchain and system libraries compatible with the\noldest distribution you intend to support. Alternatively, link libstdc++\nstatically and hide its symbols with a linker version script.\n\n\nTry the complete\nexample\nand check the godot-cpp documentation\nto learn more about writing extensions. If you have any feedback or run into\nany issues, please let us know in the Conan GitHub\nrepository.\n\nHappy game development!\n\nThis post was written with AI assistance and reviewed by humans."
                ],
                "output": "readability",
                "pwd": "/data/archive/1790676378.953906",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-29T10:09:35.295167+00:00",
                "status": "succeeded"
            }
        ],
        "screenshot": [],
        "singlefile": [],
        "title": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-09-29T10:09:35.288370+00:00",
                "index_texts": null,
                "output": "Using any C++ library in Godot",
                "pwd": "/data/archive/1790676378.953906",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-29T10:09:35.260099+00:00",
                "status": "succeeded"
            }
        ],
        "wget": [
            {
                "cmd": [
                    "wget",
                    "--no-verbose",
                    "--adjust-extension",
                    "--convert-links",
                    "--force-directories",
                    "--span-hosts",
                    "--no-parent",
                    "-e",
                    "robots=off",
                    "--reject=js,mjs,woff,woff2,ttf,otf,eot,mp4,m4v,mov,webm,ogv,mkv,avi,flv",
                    "--timeout=120",
                    "--restrict-file-names=windows",
                    "--page-requisites",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) wget/GNU Wget 1.21.3",
                    "--compression=auto",
                    "--timestamping",
                    "https://blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html"
                ],
                "cmd_version": "GNU Wget 1.21.3",
                "end_ts": "2026-09-29T10:09:35.251628+00:00",
                "index_texts": null,
                "output": "blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html",
                "pwd": "/data/archive/1790676378.953906",
                "schema": "ArchiveResult",
                "start_ts": "2026-09-29T10:09:30.010403+00:00",
                "status": "succeeded"
            }
        ]
    },
    "icons": null,
    "is_archived": true,
    "is_static": false,
    "latest": {
        "archive_org": null,
        "dom": null,
        "favicon": "favicon.ico",
        "git": null,
        "media": null,
        "pdf": null,
        "screenshot": null,
        "singlefile": null,
        "title": "Using any C++ library in Godot",
        "warc": null,
        "wget": "blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html"
    },
    "link_dir": "/data/archive/1790676378.953906",
    "newest_archive_date": "2026-09-29T10:09:37.274834+00:00",
    "num_failures": 0,
    "num_outputs": 6,
    "oldest_archive_date": "2026-09-29T10:09:29.159049+00:00",
    "path": "/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html",
    "schema": "Link",
    "scheme": "https",
    "snapshot_id": "c5c20dd4-996e-4412-bb1c-295f0678c5d2",
    "sources": [
        "/data/sources/1790676378-import.txt"
    ],
    "tags": null,
    "tags_str": "",
    "timestamp": "1790676378.953906",
    "title": "Using any C++ library in Godot",
    "updated": "2026-09-29T10:09:29.158605+00:00",
    "updated_date": "2026-09-29 10:09",
    "url": "https://blog.conan.io/cpp/conan/gamedev/godot/cmake/2026/09/29/Using-Any-Cpp-Library-In-Godot.html"
}