Skip to content

Allow creating GDExtension plugins from inside the Godot editor#90979

Open
aaronfranke wants to merge 1 commit intogodotengine:masterfrom
aaronfranke:create-gdextension
Open

Allow creating GDExtension plugins from inside the Godot editor#90979
aaronfranke wants to merge 1 commit intogodotengine:masterfrom
aaronfranke:create-gdextension

Conversation

@aaronfranke
Copy link
Copy Markdown
Member

@aaronfranke aaronfranke commented Apr 21, 2024

This PR implements godotengine/godot-proposals#3367 and godotengine/godot-proposals#9306 (not exactly as the proposals describe, but solves the same problem).

The status quo for GDExtension development is really unfortunate. For the most part the only easy way to get started is to edit the GDExtension template project, or copy-paste an existing GDExtension project and use it as a template. If you don't do this, you'd need to follow the documentation, which is a massive behemoth that manually explains to the user how to create each file from scratch, and it would take a user hours to follow this guide.

Really, I believe it should be as simple as making a GDScript plugin:

  • Click a button to open a wizard to make an extension.
  • Give your extension a name.
  • Select a language from the dropdown menu.
  • Click Create.

This is what this PR implements. Just go into Project Settings -> GDExtension:

Screenshot 2024-05-27 at 12 02 11 AM

Next, click Create GDExtension, type in a base name, click "Create", and then it will create and compile an extension.

Screenshot 2024-05-27 at 1 30 48 AM

The library name and path are optional. If you do not specify these, they will be determined automatically.

The dialog includes hover tooltips if you hover over the boxes, which explain what each field is and what the values you write in it should be.

The language system is designed to be completely language-agnostic. The dialogs have no clue about the existence of C++ or SCons. All of the C++ and SCons specific code is isolated in one class, and in the future we can allow editor plugins to extend this. It's not exposed as of this PR in case we want to iterate on the internal code first, but we can expose it whenever, preferably in a future PR to avoid this one becoming too big.

As mentioned by proposal godotengine/godot-proposals#3367, this sets up the build system with a build command (scons), the .gitignore files, the .gdextension file, the type registration boilerplate, and it even git clones godot-cpp. By default, it will also initiate scons to compile the extension, but this does take awhile, so you can skip this step by unchecking the "Compile now?" box.

Note that this PR does not include setting up system-level dependencies, such as installing a C++ compiler, installing Git, installing SCons, etc. This varies widely by operating system and it would be a slippery slope to try and have that. This PR is purely focused on the files that go in your project, not the system-wide dependencies. This PR does not try to detect a C++ compiler, but it will warn the user if either Git or SCons is not found on their system.

When you create a GDExtension plugin with this PR, one example node is provided called ExampleNode. Like the Blender default cube, this is expected to be replaced by users as soon as possible. However, its existence is useful to both new and experienced users, since it serves 2 functions: 1) As a reference for how to make a node type, including the code, registration, docs, icon, etc, and 2) A minimal test to check if your GDExtension plugin works (don't see it in the editor? It's not working).

Assuming you have the system-wide dependencies installed, and you leave the "Compile now?" checkbox enabled, and you wait for it to finish, the extension immediately works. No fuss, the example node is just there.

Screenshot 2024-05-27 at 1 27 30 AM

Assuming it was compiled, it will show up in a list of GDExtensions. This list will contain every loaded GDExtension, regardless of whether it was been created by the create dialog. It gets this list from GDExtensionManager, so it will not include any non-compiled or otherwise broken extensions.

Screenshot 2024-05-27 at 12 08 11 AM

If you change the code, you just need to run scons in either the extension folder or the project root. A future idea would be to detect this in projects and provide a "Build" button in the editor UI like we already do for C#, but that is technically separate from what this PR does.

The files look like this:

Screenshot 2024-04-21 at 4 25 19 AM

The SConstruct at the project root is extremely barebones, it is only one line to call into another SConstruct. It is designed to be simple enough so that more GDExtension plugins can be added to the same Godot project with no manual work. The _ensure_file_contains helper function in this PR completely handles the merging of more calls into this file. You can just make 2 plugins back-to-back with no conflicts. If you want to have 20 GDExtension plugins, this PR will let you do that just fine, with one call to scons in the root folder able to compile all of them at once.

This PR provides 2 options for making a GDExtension plugin: "C++ with SCons, GDExtension only" or "C++ with SCons, GDExtension and engine module". The former creates a standalone GDExtension C++ plugin, with the only files stored in the root of the project being a .gitignore and barebones SConstruct.

The engine module option provides a few more files like SCsub and config.py, provides lots of #ifdef directives to support both GDExtensions and modules, and places most of the C++ code in the root of the folder, which is more suitable for making a Godot engine module. This way if users want to target both GDExtension and modules with one codebase, they can do this as easily as selecting it from the dropdown. This option turns the project's root folder into a module, so only one module is allowed per project.

Screenshot 2024-05-27 at 12 10 59 AM

When in this mode, you can either compile for GDExtension the same as with the "only" option, or you can copy-paste the entire Godot project into the engine modules folder, naming the folder the same as the addon folder name, and it works.

The source files are designed to handle the extension+module case, but are automatically simplified by this PR's project generator when making a non-module extension, including by looking at the #if preprocessor directives to determine which lines of code to exclude. "Yo dawg, I heard you like preprocessors, so I preprocessed your preprocessor directives so there are fewer preprocessor directives to direct your preprocessor."

@deralmas
Copy link
Copy Markdown
Member

Wow, this looks great! I wonder, does this also resolve godotengine/godot-proposals#9306 ? It looks like the same problem IMO.

@Naros
Copy link
Copy Markdown
Contributor

Naros commented Apr 21, 2024

This looks great, but I also definitely think its worthwhile to consider support for other build systems beyond scons. There has been a tremendous amount of work put into the cmake build in godot-cpp, and I think its at least worthwhile for supporting that build system if someone picks "GDExtension C++ only".

@Lazy-Rabbit-2001
Copy link
Copy Markdown
Contributor

Lazy-Rabbit-2001 commented Apr 22, 2024

This looks wonderful as I've been annoying with handling the preparation of making GDExtension manually for days.
However, I think there could be an option to decide if godot-cpp is global or not, as some devs may use the same godot-cpp to avoid repeated compilations on this folder because of their parallel development on multiple GDExtensions.
For example, according to current status of pr, a dev may produce two GDExtensions like this:

addons

exm_a

src

godot_cpp

exm_b

src

godot_cpp

See? There are two godot_cpp-s in seperate projects, but the dev may hope to use only one for these two GDExtensions, like this:

addons

_bin

godot_cpp

exm_a

src

...

exm_b

src

...

As the direct placement of folder godot_cpp may bring ambiguity and vagueness to devs, it's better to place it in a single common folder named _bin or something else clear that resonates with the devs.

@aaronfranke
Copy link
Copy Markdown
Member Author

@Naros The big question I have is what would this feature look like? Should cmake be included as one of the supported options out of the box? Should it be plugable? If so how? I guess plugins should add more options to the dropdown menu, so we would have "GDExtension C++ only (scons)" and "GDExtension C++ only (cmake)"? Or is it worth refactoring this menu to have a more generalized "GDExtension" option and a second dropdown for "C++ SCons", "C++ CMake", etc?

@Lazy-Rabbit-2001 I agree, but there are some technical challenges when trying to make the plugins share godot-cpp. When I try to do this, and both call into the same SConstruct, it is unable to compile from the top-level SConstruct:

scons: warning: Two different environments were specified for target gen/src/variant/utility_functions.cpp,
        but they appear to have the same action: scons_generate_bindings(target, source, env)
File "/Users/aaronfranke/workspace/projects/gdextension-test/addons/godot-cpp/tools/godotcpp.py", line 463, in _godot_cpp

scons: *** Two environments with different actions were specified for the same target: src/godot.macos.template_debug.universal.o

I would need some help from the build system gurus to make this work.

Comment thread editor/plugins/gdextension/cpp_template/addon/library_name.gdextension Outdated
Comment thread editor/plugins/gdextension/cpp_template/addon/library_name.gdextension Outdated
@dsnopek
Copy link
Copy Markdown
Contributor

dsnopek commented Apr 23, 2024

Thanks for taking this on! It looks really cool :-)

I did a quick test of the PR, and the "Compile on" checkbox didn't seem to work for me. It detected scons and git, but it encountered an error when trying to run it:

scons: Reading SConscript files ...
Auto-detected 32 CPU cores available for build parallelism. Using 31 cores by default. You can override it with the -j argument.
Building for architecture x86_64 on platform linux
KeyError: 'arch_suffix':
  File "/home/dsnopek/Sync/Projects/games/gdext-creation-test/SConstruct", line 4:
    SConscript("addons/zap/SConstruct")
  File "/usr/lib/python3/dist-packages/SCons/Script/SConscript.py", line 661:
    return method(*args, **kw)
  File "/usr/lib/python3/dist-packages/SCons/Script/SConscript.py", line 598:
    return _SConscript(self.fs, *files, **subst_kw)
  File "/usr/lib/python3/dist-packages/SCons/Script/SConscript.py", line 287:
    exec(compile(scriptdata, scriptname, 'exec'), call_stack[-1].globals)
  File "/home/dsnopek/Sync/Projects/games/gdext-creation-test/addons/zap/SConstruct", line 35:
    env["arch_suffix"],
  File "/usr/lib/python3/dist-packages/SCons/Environment.py", line 405:
    return self._dict[key]

If I change the SConstruct to remove the env["arch_suffix"] part, then it builds fine when running scons manually. After that, the ExampleNode class appears and I can add it to my scene!

It looks like this creates a plugin.cfg file, which leads to an entry on the "Plugins" tab in "Project Settings". However, GDExtensions aren't plugins in this sense, and enabling/disabling the created plugin there will actually have no effect. We do plan to eventually add the ability to enable/disable GDExtensions in "Project Settings", but work hasn't started on that yet.

However, GDExtensions are quite different from plugins in many ways. It may make sense for GDExtensions to have their own tab distinct from "Plugins"? And, if so, then the UI here should probably be disentangled from the "Create New Plugin" form and process.

Anyway, this is a great start!

@Naros
Copy link
Copy Markdown
Contributor

Naros commented Apr 23, 2024

The big question I have is what would this feature look like? Should cmake be included as one of the supported options out of the box? Should it be plugable? If so how? I guess plugins should add more options to the dropdown menu, so we would have "GDExtension C++ only (scons)" and "GDExtension C++ only (cmake)"? Or is it worth refactoring this menu to have a more generalized "GDExtension" option and a second dropdown for "C++ SCons", "C++ CMake", etc?

So first, I think David is right, we should completely separate GDExtension from GDScript plug-ins here, 💯 . An independent UI has several benefits:

  • Avoids confusing GDScript plug-in creators with C++ / GDExtension noise.
  • Allows creating a screen tailored for GDExtension and its toolings.

On the GDExtension create dialog, I could imagine this being a bit similar to Project Settings with a tree on the left, and a panel on the right where we display context-specific options based on the choice on the left. The left panel tree might look like this:

- General 
- Build, Execution, and Deployment
  - Toolchains
    - Custom compiler
  - CMake
  - Meson
  - Scons
  - ...
- Plugins
  - ... 

The General tab allows you to define basic data about the extension, its name, a custom entry point name, the base path for where the compiled binaries should be copied, i.e. res:\\addons\<addon-name>\bin being the default. Additionally, this is where the user can define the minimum compatibility, hot-reload, etc.

Under the Build tab, we'd have sections for each supported build system that would be output for the user. These tabs could include specific options that can be customized for that specific build system. For example, here's what I could imagine being the case for CMAKE:

image

The Plugins section is really some future scope I would say, but could be where the build files get customized, additional classes added, or some other customizations are done that can be tailored to an organization's needs.


And circling back to Limbo's idea of a shared godot-cpp, this got me thinking about whether the C++ code should really reside in the project folder itself or would it make sense to reside in something like user://, with top-level paths like:

  • user://godot-cpp (shared godot-cpp)
  • user://gdextension/<extension-name>

I'm just not sure I like the idea of embedding the C++ code into the Godot project, but I'm not 100% sold either way. But now I do question if some of these settings belong configurable in the Project Settings and not in the "Create Extension" dialog 🤔

@HeadClot
Copy link
Copy Markdown

HeadClot commented May 20, 2024

Bit of a question about this Draft PR will this trigger a compile after the GDExtention is created or do will we have to do that manually?

@aaronfranke
Copy link
Copy Markdown
Member Author

aaronfranke commented May 20, 2024

@HeadClot It attempts a compile for you, but this may fail if Git, SCons, or a C++ compiler/linker/etc are missing.

@HeadClot
Copy link
Copy Markdown

@HeadClot It attempts a compile for you, but this may fail if Git, SCons, or a C++ compiler/linker/etc are missing.

Got it thank you for the info :)

@dsnopek
Copy link
Copy Markdown
Contributor

dsnopek commented May 23, 2024

Decide how we want this to work for non-C++ languages (currently the code is not designed to be plugable).

I think it probably makes sense to make this pluggable via an editor plugin, similar to the EditorExtensionSourceCodePlugin proposed in godotengine/godot-proposals#9806 (or even just being additional methods on that same plugin - keeping everything related to managing GDExtension source together makes sense).

Also, it could make sense to include the C++ support in a godotcpp module? That way, we can disable the module on certain platforms (for example, web) or folks could make custom builds of Godot that don't include this additional integration with C++ (if, for example, they wanted an editor build that focused on a different GDExtension language).

@aaronfranke aaronfranke force-pushed the create-gdextension branch 4 times, most recently from 3199f9a to 6d83772 Compare May 27, 2024 09:21
@aaronfranke aaronfranke marked this pull request as ready for review May 27, 2024 09:31
@aaronfranke aaronfranke requested review from a team as code owners May 27, 2024 09:31
@aaronfranke
Copy link
Copy Markdown
Member Author

aaronfranke commented May 27, 2024

I overhauled the entire UI frontend of this PR. Instead of using the same dialog as GDScript plugins, now there is an entirely separate tab with 2 dialogs for creating and editing GDExtensions.

I have updated the OP, please read that for a summary of how the workflow looks like. In addition to what's in the OP, here is a short description of what the classes are:

  • ProjectSettingsGDExtension: Lists GDExtensions as a tab in Project Settings. Allows opening the dialogs.
  • GDExtensionCreateDialog: Dialog for creating new GDExtensions. Uses classes that extend GDExtensionCreatorBase to do the heavy lifting. Which one the dialog uses depends on which is selected in the dropdown.
  • GDExtensionConfigDialog: Dialog for configuring/editing GDExtensions.
  • GDExtensionCreatorBase: Base class for GDExtension creator classes, the classes which are able to take in a few parameters and generate a GDExtension for some language. In the future when we expose the ability for users to add custom classes for new languages or build systems, they would extend this class.
  • CppSconsGDExtensionCreator: Extends GDExtensionCreatorBase, used for generating GDExtensions C++ with SCons. This is the only class that knows about C++ and SCons, the other classes are language-agnostic.

If I change the SConstruct to remove the env["arch_suffix"] part, then it builds fine when running scons manually.

This should be fixed now. It will now add arch_suffix if it's missing.

It looks like this creates a plugin.cfg file, which leads to an entry on the "Plugins" tab in "Project Settings".

This is gone now.

And circling back to Limbo's idea of a shared godot-cpp, this got me thinking about whether the C++ code should really reside in the project folder itself or would it make sense to reside in

The create dialog now allows specifying any path. You can use res://gdextension/my_extension if you want, or even use a top-level folder using res://my_extension.

@aaronfranke aaronfranke force-pushed the create-gdextension branch from 6d83772 to 8f4b938 Compare May 29, 2024 23:37
@KoBeWi
Copy link
Copy Markdown
Member

KoBeWi commented Jun 4, 2024

EDIT:
The solution might be adding a new tab called Addons, which would have sub-tabs Plugins and GDExtension (similar to how Localization has sub-tabs.

  • When creating extension and typing a name, there is a noticeable delay between each letter (at least in debug build), likely caused by field updating. There could be some debouncing applied here.
godot.windows.editor.dev.x86_64_WmCRfH6YBH.mp4

EDIT:
The dialog also checks for git and scons, which might be another thing slowing it down. This should be cached, e.g. when opening the dialog.

  • While performing initial compilation the editor is completely unresponsive. The compilation should run in an independent process, to not stall the editor. You could display indeterminate progress bar, or if you are ambitious, you can show compilation progress and output in real time, using the new execute_with_pipe() method.

  • After compiling finishes, the new GDExtension does not appear in the list until you click the window. Seems like editor ends unfocused somehow and clicking it refreshes the list or something. (might need further testing)

  • The layout for editing extension is awkward.
    image
    You could add some text to the checkbox (e.g. On or Enabled) and align it to the right.

Despite these minor problems, the extension is created correctly and is usable out-of-the-box, which is very nice.

@fire
Copy link
Copy Markdown
Member

fire commented Jul 31, 2025

Try adding:

#!/usr/bin/env python
from misc.utility.scons_hints import *

to the top.

@aaronfranke
Copy link
Copy Markdown
Member Author

aaronfranke commented Aug 23, 2025

@fire When I add that, it fails when running the scons command:

scons: Reading SConscript files ...
ModuleNotFoundError: No module named 'misc':
  File "/Users/aaronfranke/workspace/projects/gdext_test/SConstruct", line 2:
    from misc.utility.scons_hints import *

@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented Sep 9, 2025

That topmost import only works in the context of the Godot repo root, which has a file at that location. We should ideally move away from using the SCons global methods entirely, as that would remove the need for such workarounds

@dsnamel-dev
Copy link
Copy Markdown

What is preventing this from being merged? This has already been open for more then 1 year

@llama-nl
Copy link
Copy Markdown

Does this feature available for Android Editor

@Calinou
Copy link
Copy Markdown
Member

Calinou commented Nov 10, 2025

Does this feature available for Android Editor

It's possible for the Android editor to create the file structure, but not compile the GDExtension as you can't call a C++ compiler toolchain (outside of Termux). You would need dedicated code to be able to interface with Termux for this to be possible in the first place.

@aaronfranke
Copy link
Copy Markdown
Member Author

Updated the PR to account for godotengine/godot-cpp#1451, #107415, and others, distinguishing threads/nothreads for the web platform in the .gdextension file.

@that404nerd
Copy link
Copy Markdown

Will this support CMake? I have CMake as the build tool rather than scons. Will it support that? Thanks! Looking forward for the PR to be merged

@aaronfranke
Copy link
Copy Markdown
Member Author

@that404nerd That could be added in the future, but this PR is focused on SCons.

@that404nerd
Copy link
Copy Markdown

@that404nerd That could be added in the future, but this PR is focused on SCons.

Thanks for the quick reply! Do you think this PR will be merged soon? Like probably by the end of this month or could it take more time? Thanks again!

@aaronfranke
Copy link
Copy Markdown
Member Author

@that404nerd That depends on how interested people are in reviewing. This PR is a big change with big impact, so it ideally should be reviewed by many people before it is merged.

You are welcome to review yourself if you want to, and encourage others to review as well. If you leave an approval, you need to state what you did (including testing, looking over the code, etc) and what specifically you approve of (the UX flow, the feature scope, the implementation details, the code style, etc). Reviews from non-members will show up as a gray checkmark instead of a green checkmark, but more effort from the community is always welcome.

@DexterFstone
Copy link
Copy Markdown
Contributor

When trying to create a new GDExtension, the output shows a few errors:

Godot Engine v4.6.dev.custom_build (c) 2007-present Juan Linietsky, Ariel Manzur & Godot Contributors.
--- Debug adapter server started on port 6006 ---
--- GDScript language server started on port 6005 ---
  ERROR: Couldn't read OBJ file 'res://example_node.windows.template_debug.x86_64.obj', it seems to be binary, corrupted, or empty.
  ERROR: editor\import\3d\resource_importer_obj.cpp:690 - Condition "meshes.size() != 1" is true. Returning: ERR_BUG
  ERROR: Error importing 'res://example_node.windows.template_debug.x86_64.obj'.
  ERROR: Couldn't read OBJ file 'res://register_types.windows.template_debug.x86_64.obj', it seems to be binary, corrupted, or empty.
  ERROR: editor\import\3d\resource_importer_obj.cpp:690 - Condition "meshes.size() != 1" is true. Returning: ERR_BUG
  ERROR: Error importing 'res://register_types.windows.template_debug.x86_64.obj'.

@Jordyfel
Copy link
Copy Markdown
Contributor

Took the PR for a spin, found no issues in functionality.

The start and end column from similar tables were recently removed because they don't look good in the modern theme.
image

</description>
<tutorials>
<link title="GDExtension overview">$DOCS_URL/tutorials/scripting/gdextension/what_is_gdextension.html</link>
<link title="GDExtension example in C++">$DOCS_URL/tutorials/scripting/gdextension/gdextension_cpp_example.html</link>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link is outdated, the structure of the docs has changed since.

@Naros
Copy link
Copy Markdown
Contributor

Naros commented Feb 2, 2026

@aaronfranke I skimmed through the discussion and may have overlooked this; if so, I apologize. But I am concerned about the dual maintenance of the templates in this PR with the godot-cpp-template.

If these diverge, it could raise questions about best practices or opinionated approaches.

So are there plans to pick one or the other as the source of truth on how a GDExtension should be structured, or will there simply be dual maintenance to keep them both synchronized?

@aaronfranke
Copy link
Copy Markdown
Member Author

@Naros I do not personally see a problem with having both exist. They are not exactly the same, and attempting to "deduplicate" these would cause some problems: if Godot cloned that repo, then creating a GDExtension would require an Internet connection, and the code in the Godot editor to manipulate it would be dependent on the repo having specific contents. If a change is useful for both, it can be made for both.

If it was determined that it is important to only have one of them, I would delete godot-cpp-template in favor of this PR, because 1) When creating a GDExtension you're going to want it to be customized with the name of your extension written everywhere, and it would be annoying for every user to have to do that process manually, and 2) Users should be able to create a GDExtension easily without going to a repo in their web browser and following instructions that involve cloning a repo and using a terminal, ideally it should be as simple to get started with GDExtension C++ as it already is to get started with C# in Godot.

@Jordyfel
Copy link
Copy Markdown
Contributor

Jordyfel commented Feb 2, 2026

Plugin editor:
image

GDExtension editor:
image

This misalignment in table style trees was recently-fixed in #114862, it seems it introduced a new "TreeTable" style variation that would fix this.

Copy link
Copy Markdown
Contributor

@Jordyfel Jordyfel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested and approving UX (aside from above comment) and the feature, did not review the code.

I'm not sure about the practicality of the extension + module option, as I haven't worked with engine modules.

@that404nerd
Copy link
Copy Markdown

Alright, So I tested this feature on my machine and the core feature works just fine. But I do want to address a couple of issues with this PR:

  • The first one is my opinion and I'm open to any suggestions
    Why is the actual gdextension folder is placed in the addons folder? It would make a lot of sense to instead include the godot-cpp in the addons folder and the actual extension in the root folder. There are many ways to do this but this makes a lot of sense.
    Also if there's an existing addons folder it would be better to check for general naming conventions before creating a duplicate folder with different casing (like Addons/ if addons/ already exists).

  • The second one is, what about clang support? Currently, this works fine if you are using VSCode, but if you use any other editor that uses clang lsp like say VSCodium (because the official extension doesn't work and instead clangd is required) otherwise the editor will be full of include errors like this:

image

The same applies to vim/neovim. Well, since the build system that's provided by default is scons, I think there should be an option right when you are creating the extension to ask for compile_commands.json support or something in that way.

  • And it's also really annoying to have object files (.os or .o files) generated right next to the .cpp files. It would be better if the scons script has a way to avoid that. I do wanna mention that I'm no scons expert so I have no idea how to do this.

I will add anymore issues as I keep experimenting with this. Definitely a must have feature. Thanks and have a nice day!

@aaronfranke
Copy link
Copy Markdown
Member Author

aaronfranke commented Apr 3, 2026

@that404nerd I'll respond to each of your points individually:

Why is the actual gdextension folder is placed in the addons folder?

This is the default, but you can fully control where it goes by typing in res://somepath. If the desired path contains res:// then it won't try to prefix what you type with res://addons/. The root of the project can also be done if you select the module option, but for the GDExtension files, I really think you don't want these directly in the project root.

creating a duplicate folder with different casing (like Addons/ if addons/ already exists).

This is not supported, only addons/ is valid for addons in a Godot project, doing otherwise will cause portability concerns across platforms. More generally, I recommend using only lowercase letters in folder and file names.

The second one is, what about clang support?

The code in this PR tries to not be biased towards any particular compiler or tool too much, but that said, further enhancements to improve usability across editors would be welcome, especially if it's just minor config additions.

Given how long this PR has been waiting, I would prefer this be done in follow-up PRs submitted by users like yourself, especially because we want to hear from users what tools are desired to support and we want to have such implementations tested by users of those tools.

And it's also really annoying to have object files (.os or .o files) generated right next to the .cpp files.

The main Godot repo recently changed the location of compilation artifacts, we could do the same for GDExtensions generated by this system, if anyone would like to contribute that.

@that404nerd
Copy link
Copy Markdown

@that404nerd I'll respond to each of your points individually:

Why is the actual gdextension folder is placed in the addons folder?

This is the default, but you can fully control where it goes by typing in res://somepath. If the desired path contains res:// then it won't try to prefix what you type with res://addons/. The root of the project can also be done if you select the module option, but for the GDExtension files, I really think you don't want these directly in the project root.

creating a duplicate folder with different casing (like Addons/ if addons/ already exists).

This is not supported, only addons/ is valid for addons in a Godot project, doing otherwise will cause portability concerns across platforms. More generally, I recommend using only lowercase letters in folder and file names.

The second one is, what about clang support?

The code in this PR tries to not be biased towards any particular compiler or tool too much, but that said, further enhancements to improve usability across editors would be welcome, especially if it's just minor config additions.

Given how long this PR has been waiting, I would prefer this be done in follow-up PRs submitted by users like yourself, especially because we want to hear from users what tools are desired to support and we want to have such implementations tested by users of those tools.

And it's also really annoying to have object files (.os or .o files) generated right next to the .cpp files.

The main Godot repo recently changed the location of compilation artifacts, we could do the same for GDExtensions generated by this system, if anyone would like to contribute that.

Thanks for responding. As you mentioned, I think I'll wait for this PR to be merged and also I didn't look at the path of the gdextension creation so yea I thought that was permanent but looking forward for this to be merged. A question, will this PR be merged before the release of 4.7?

Copy link
Copy Markdown
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally on Windows 11 24H2 + MSVC 2022, it works as expected. No additional setup was required to get it to work compared to what I already had to build Godot from source.

Code looks good to me.

Some feedback:

  • The #ifdef GODOT_PRINT_STRING_HPP guards can be removed now that the associated PR has been merged.

    • I added #define GODOT_PRINT_STRING_HPP, ran scons, ran the project and the string appeared in the Output panel when I called print_hello() on ExampleNode.
  • The default .gitignore seems to work well. I ran git init && git add ; && git commit -m "Initial commit" and no extraneous files like binaries or caches were committed to version control:

$ git commit -m "Initial commit"
[master (root-commit) 2216da5] Initial commit
 25 files changed, 395 insertions(+)
 create mode 100644 .editorconfig
 create mode 100644 .gitattributes
 create mode 100644 .gitignore
 create mode 100644 SConstruct
 create mode 100644 addons/example_ext/.gitignore
 create mode 100644 addons/example_ext/SConstruct
 create mode 100644 addons/example_ext/doc_classes/ExampleNode.xml
 create mode 100644 addons/example_ext/example_ext.gdextension
 create mode 100644 addons/example_ext/example_ext.gdextension.uid
 create mode 100644 addons/example_ext/icons/ExampleNode.svg
 create mode 100644 addons/example_ext/icons/ExampleNode.svg.import
 create mode 100644 addons/example_ext/src/.gdignore
 create mode 100644 addons/example_ext/src/example_ext_defines.h
 create mode 100644 addons/example_ext/src/example_node.cpp
 create mode 100644 addons/example_ext/src/example_node.h
 create mode 160000 addons/example_ext/src/godot-cpp
 create mode 100644 addons/example_ext/src/initialize_gdextension.cpp
 create mode 100644 addons/example_ext/src/register_types.cpp
 create mode 100644 addons/example_ext/src/register_types.h
 create mode 100644 example_node.gd
 create mode 100644 example_node.gd.uid
 create mode 100644 icon.svg
 create mode 100644 icon.svg.import
 create mode 100644 node_2d.tscn
 create mode 100644 project.godot

(The top-level .gitignore is the one created by the project manager with no changes made to it.)

@Calinou
Copy link
Copy Markdown
Member

Calinou commented Apr 17, 2026

A question, will this PR be merged before the release of 4.7?

4.7 is in feature freeze since Wednesday, so I'm afraid not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.