Expand description
§GDExtension loading file generation for Rust
This crate aims to provide a way to autogenerate a .gdextension file for using Rust to make a Godot GDExtension. It provides all the libraries pathfinding and a way to automatically link the default icons to the new defined classes based on the class they inherit from, and also a way to manually link a specific class with a custom icon. For more information, read the documentation, or the source code.
§Installation
To install this crate as a build dependency in your own crate, run: cargo add --build gdext-gen. If you instead want it added as a normal dependency run: cargo add gdext-gen.
§Usage
§build.rs call
To get all the functionality of this crate, in your build.rs file on the root of your crate (not your src/), write the following (parameters may vary depending on the features you’ve opt in or out of):
use gdext_gen::prelude::*;
fn main() {
// All your variable initialization and setup goes here.
generate_gdextension_file(base_dir, target_dir, gdextension_path, force_generation, configuration, windows_abi, icons_configuration, dependencies);
}The parameters of this function and how it works are documented in the docs. It should be kept in mind that this function returns an std::io::Result, so the following code could be used instead:
use std::io::Result;
use gdext_gen::prelude::*;
fn main() -> Result<()> {
// All your variable initialization and setup goes here.
generate_gdextension_file(base_dir, target_dir, gdextension_path, force_generation, configuration, windows_abi, icons_configuration, dependencies)?;
}To compile for Android, Web, MacOS or iOS please refer to the godot-rust book.
It’s worth noting that one can configure when the build script will be run, so it’s sensible to change it were one not to need it running at every source file change.
§Variable initialization
An example of variable initialization to have parity with the godot-rust example is the following (with all the primaty features enabled and checked_generation chosen):
use std::io::Result;
use gdext_gen::prelude::*;
fn main() -> Result<()> {
generate_gdextension_file(
BaseDirectory::ProjectFolder.into(),
Some("../rust/target".into()),
Some("../godot/rust.gdextension".into()),
true,
Some(Configuration::new(
EntrySymbol::GodotRustDefault,
Some((4, 1)),
None,
true,
false,
)),
Some(WindowsABI::MSVC),
Some(IconsConfig::new(
DefaultNodeIcon::NodeRust(NodeRust::Ferris, "rust".into()),
IconsCopyStrategy::new(true, true, "../godot/addons/rust".into(), false),
None,
IconsDirectories::new("addons".into(), "editor".into(), "rust".into(), BaseDirectory::ProjectFolder.into()),
)),
None,
)?;
Ok(())
}This results in a “rust.gdextension” file in “Project/godot”, which contains the following:
[configuration]
entry_symbol = "gdext_rust_init"
compatibility_minimum = 4.1
reloadable = true
[libraries]
"target.mode" = "res://../rust/target/mode/library.file"
"target.mode.architecture" = "res://../rust/target/target-triple/mode/library.file"
...
[icons]
YourStructName = "res://addons/rust/NodeRust.svg"
...Few lines of code for a customized automated .gdextension file, in conclusion.
§Variables short explanation
Based on the last example, the GDExtension is configured as follows:
BaseDirectory::ProjectFolderuses"res://"based paths.target_dir = "../rust/target": The target folder for the GDExtension crate is found at"res://../rust/target".gdextension_path = "../godot/rust.gdextension: Makes the file at"Project/godot/rust.gdextension"(if"rust"and"godot"are in a"Project"folder).truehere means the.gdextensionwill be rewritten even if the file already exists.EntrySymbol::GodotRustDefaultdefaults to"gdext_rust_init".minimum_compatibility-> 4.1 andreloatable = trueWindowsABI::MSVCusesMSVCas linker and environment when compiling forWindows.DefaultNodeIcon::NodeRust(NodeRust::Ferris, "rust")uses theNodeRustFerris.svgicon and finds it in the folder"res://{base_dir}/rust".- IconsCopyStrategy: true, copy the
NodeRust(and true) files in path"../godot/addons/rust"relative to your crate and if it’s there, don’t copy it again. - No custom nodes.
- The directories will be laid out as following:
- All icons will be found relative to
"res://addons". - The editor icons will be located in
"res://addons/editor". - The custom nodes will be located in
"res://addons/rust"
- All icons will be found relative to
- None: No dependencies.
§Features
icons- Allows the use of custom icons and the copying ofRust’s default icons for the generation of theiconssection of the.gdextensionfile.find_icons- Allows for the finding of the names of the custom implemented nodes and their subclasses using regex to automate theiconssection generation process.dependencies- Allows for the generation of thedependenciessection of the.gdextensionfile.checked_generation- Adds a parameter to the function call to allow for specifying whether the.gdextensionfile should always be copied or only when it doesn’t exist. This option is mutually exclusive withforced_generation. If none is chosen, it defaults to writing it only when it doesn’t exist.forced_generation- Ensures the.gdextensionfile is always written regardless of whether it exists or not. This option is mutually exclusive withchecked_generation. If none is chosen, it defaults to writing it only when it doesn’t exist.
§Limitations
The feature “find_icons” uses regex to do its work. It’s not a perfect way of finding the icons for each GDExtension custom node, but it always resets after each file, so one file’s contents failing can only affect itself. It does so by searching for lines that contain both "base" and "=", then trying to find the name of the base. Same with "struct". The only ways it could fail is if that exact appearance is in a comment or string, has comments in between or extends over more than a line. I believe these to be reasonable compromises, as searching for more than these would only make the code slower, and any reasonably formatted code would have "base =" in the same line and for "base = NameBase", or struct "NameStruct {" to appear on their own in a comment is hard enough, and the auto found icons can ALWAYS be overriden by custom icons that just happen to be the editor’s. In any case, if one thinks otherwise, here are other ways to implement this. 1: A pretty barebones Rust parser, 2: Preprocessing strings and comments in a file before doing the search, 3: Searching for the impl INameOfBase for StructName. If you experience problems due to this fact, due let us know, there may be a fix for it.
There is also an issue with structs that use generics, or structs that don’t follow the standard. These, may not be found at all, so it’s best to just add them as custom.
§Acknowledgements
- This crate is based on the
gdextension_filedocumentation fromGodot, and some snippets of the documentation (all written by paddy-exe) are taken as are from their documentation, so they are as accurate as possible. The copyright notices for those files can be found directly in their repository, and are licensed under theCC BY 3.0license. This applies to the doc comments on the serializable structs, so these are not relicensed under the licenses of this repository. The schema for the.gdextensionfile comes from theGodot Enginewhich is licensed under theMITlicense. - This crate is meant to work in tandem with
godot-rustto give the most painless use ofRustforGodot’sGDExtension, automating a helpful bunch of the work. It could be use on its own, just to generate the.gdextensionfile, but it works best with it. - The explanation on the
WindowsABI::LLVMdocumentation, taken from therustcdocumentation, which is licensed under theMITlicense.
§Asset licenses
- The default GDExt Rust node’s icons,
NodeRustSmall.svg,NodeRustLarge.svgandNodeRustFerris.svgare licensed under the CC BY 4.0 license, copyright by burritobandit28, so they is not relicensed under the licenses of this repository. They are derived from the following works: RustFerris, made by Karen Rustad Tölva and licensed under theCC0 1.0 Universallicense.Ferrisemoji, made by Dzuk and licensed under theCC BY-NC-SA 4.0license.Godotlogo, made by Andrea Calabró and licensed under theCC BY 4.0license.godot-rustFerris, licensed under theCC BY-NC-SA 4.0license, fromgodot-rust.
Modules§
- args
- Module with the structs and enums needed to call the main function of the library.
- features
- Module for the feature and compilation flags and their representations as
Godotgame andRust GDExtensiontargets. - gdext
- Module for the definition of the structs to be serialized to build the
.gdextensionfile, and the functions to generate the file. - prelude
Constants§
- NODES_
RUST 🔒icons - SVG representations of the default GDExtension Rust nodes.
- NODES_
RUST_ FILENAMES icons - Name of the NodeRust files.
Functions§
- generate_
gdextension_ file - Generates the
.gdextensionfile for the crate using all the necessary information.