Plugin to generate gdextension files.#577
Draft
samdeane wants to merge 9 commits intomigueldeicaza:mainfrom
Draft
Plugin to generate gdextension files.#577samdeane wants to merge 9 commits intomigueldeicaza:mainfrom
samdeane wants to merge 9 commits intomigueldeicaza:mainfrom
Conversation
samdeane
commented
Oct 17, 2024
| .godot/ | ||
| .DS_Store | ||
| /.build | ||
| /.index-build |
Contributor
Author
There was a problem hiding this comment.
Swift's VSCode plugin has a background indexing option, which creates this folder.
Removed build plugin. Removed need for .gdswift files.
samdeane
commented
Oct 18, 2024
Contributor
Author
There was a problem hiding this comment.
I'm running swift-format locally, so the whitespace is a bit messed up.
The actual non-whitespace changes are minimal.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a proof-of-concept plugin which will generate a
.gdextensionfile for a GodotScript extension.See #130 for more details.
Motivation
Maintaining the
.gdextensionfile is a bit fiddly. The syntax is obscure and exactly which architectures to fill in for each platform isn't clear.Also, the current recommended approach of copying the built swift libraries into place inside the
bin/folder is repetitive and error-prone.It is relatively easy to recompile the library but forget to copy the new version into place. The solution is typically to automate this step, but that requires each user to build some extra tooling to perform this copy whenever they trigger a build.
The
.gdextensionformat supports using a relative or absolute path to a library, which can be outside the root folder of the Godot project. Doing this allows you to specify the actual build location once in the extension file. As long as recompiling the extension puts it into the same place, it will always be picked up next time you run.A plugin can solve this problem by writing the correct entries in the
.gdextensionfile for you. The exact entries it writes can be based on the platform you are building for. The entries can be written as paths relative to the Godot project root, allowing you to commit the file to source control as long as you can ensure that the libraries are built into the same relative location on each machine (which is quite achievable).Usage
To use this, cd to your extension root and run:
It will iterate through all library targets.
For each target, it looks for a file
<target-name>.gdextensionat the root of the package folder. If there isn't one, it makes one from a template.It then performs a debug build of that target, works out where the build artefacts are, and fills their location into the
.gdextensionfile.To use this extension file, you sym-link it into your Godot project's
bin/folder.Limitations
The generated/updated file has a fixed location currently, but it could be specified as a parameter.
We use the plugin host api to perform a build to work out the build location, which is slow. Ideally we could just do something like
swift build --show-bin-pathbut this requires actually shelling out, and it will only work for SPM.Using the Package API
will hopefully report the correct information for Xcode when invoked from there(update: I've just discovered that Xcode doesn't support the relevant part of the plugin host api anyway 🤦).
The
.gdextensionfile parser is crude. It preserves section order, but not key order, and it doesn't understand multi-line entries, comments, etc, etc. This would need improving, but that probably requires implementing a full parser that mirrors the one in config_file.cpp in the Godot source. We might be able to link into SwiftGodot and use the actual implementation of ConfigFile, but I'm not sure if that will work without additional context.Alternatives Considered
Build Plugin
A build plugin could create a
.gdextensionfile automatically. This would be preferable to a command plugin in that it would always be invoked as part of the build process, regardless of the IDE or build tool you were using (Xcode, VSCode, swift command line, etc). It would always know the build context (platform, architecture, configuration), and so could update the appropriate entries.To allow custom entries in the file, the plugin could take another file as input, using the same format, add in or rewrite keys pointing to the libraries, then write it out as a
.gdextensionfile.To use this you would add this line to your plugin target in your
Package.swift:And add an input file (say
YourPlugin.gdswift) to your sources. The plugin would process the input file, add in entries for the built libraries, and output it into the resource bundle of the built library.Limitations
I tried this approach, but there are problems.
The main one is that the sandboxing of build plugins is extreme. They can only create temporary files that become inputs to the build.
This means that the only way to locate the generated
.gdextensionfile is for it to be written into the resource bundle for the built library.This works fine, but is of limited use since telling Godot where to find the resource bundle is essentially the same problem as telling it where to find the compiled libraries.