See Also
Docs
Steps
- [[#define-you-gdextension-file|Define you
.gdextension
file]] - Build Your GDExtension in Terminal
- Copy the build targets into your Godot project
See also: Using a Build Script.
Define you .gdextension
file
Define your .gdextension file in TOML syntax.
Example .gdextension
file for SwiftGodot
[configuration]
entry_symbol = "swift_entry_point"
compatibility_minimum = 4.2
reloadable = true # specifies that the editor should reload the extension when the editor window loses and regains focus. See Godot issue #80284 for more details.
# Note: If Godot is crashing, you may want to try turning off or removing this `reloadable` setting.
[libraries]
macos.debug = "res://bin/libSimpleRunnerDriver.dylib"
[dependencies]
macos.debug = {"res://bin/libSwiftGodot.dylib" : ""} # Used to copy the library into the application when exporting the project
# The name of the file corresponds to the built version of the dynamic library
Build Your GDExtension in Terminal
See docs tutorial Section 3 step 4.
Run:
swift build --configuration debug
Copy the build targets into your Godot project
See docs tutorial Section 3 step 5 and 6.
How do we automate this?
There must be a way to automate this so that it is quicker, easier and less error prone. Perhaps we should use a makefile or a script? See Using a Build Script.
Using a Build Script
Here is an example build script1 which can be used to copy the build targets into your Godot project. And here is an explanation of how the script works.
#!/bin/sh
SWIFTBUILD="/usr/bin/xcrun swift build -c $1"
GODOT_BIN_PATH="./godot/bin/"
BUILD_OUTPUTDIR=""
DoBuild () {
local SPECIFIC_SWIFTBUILD="$SWIFTBUILD $1"
local SWIFTBUILD_GETOUTPUT="$SPECIFIC_SWIFTBUILD --show-bin-path"
BUILD_OUTPUTDIR=$($SWIFTBUILD_GETOUTPUT)
if $SWIFTBUILD; then
# Remove the generated files because their presence bothers VSCode
rm EntryPoint.generated.*
echo "Build successful"
else
exit
fi
}
CopyResult () {
local OUTPUTDIR=$1
mkdir -p "$GODOT_OUTPUT_PATH"
echo "Copy output to $GODOT_OUTPUT_PATH"
rsync --checksum "$OUTPUTDIR"/libSanctuaryDriver.dylib "$GODOT_OUTPUT_PATH"
rsync --checksum "$OUTPUTDIR"/libSwiftGodot.dylib "$GODOT_OUTPUT_PATH"
}
StandardOutputPath () {
local OUTPUTDIR=$1
if [[ "$OUTPUTDIR" =~ ([^/]+/+[^/]+)/*$ ]]; then
LAST_TWO_DIRECTORIES=$BASH_REMATCH
GODOT_OUTPUT_PATH="$GODOT_BIN_PATH$LAST_TWO_DIRECTORIES"
fi
}
case $2 in
mac)
if [ $1 == "debug" ]; then
DoBuild "--triple arm64-apple-macosx"
StandardOutputPath $BUILD_OUTPUTDIR
CopyResult $BUILD_OUTPUTDIR
fi
if [ $1 == "release" ]; then
UNIVERSAL_OUTPUTDIR="./.build/apple/Products/Release"
DoBuild "--triple arm64-apple-macosx"
ARM_OUTPUTDIR=$BUILD_OUTPUTDIR
DoBuild "--triple x86_64-apple-macosx"
INTEL_OUTPUTDIR=$BUILD_OUTPUTDIR
mkdir -p "$UNIVERSAL_OUTPUTDIR"
echo "Creating Universal binaries…"
lipo -create -output "$UNIVERSAL_OUTPUTDIR"/libSanctuaryDriver.dylib "$ARM_OUTPUTDIR"/libSanctuaryDriver.dylib "$INTEL_OUTPUTDIR"/libSanctuaryDriver.dylib
lipo -create -output "$UNIVERSAL_OUTPUTDIR"/libSwiftGodot.dylib "$ARM_OUTPUTDIR"/libSanctuaryDriver.dylib "$INTEL_OUTPUTDIR"/libSwiftGodot.dylib
GODOT_OUTPUT_PATH="$GODOT_BIN_PATH/universal-apple-macosx/release"
CopyResult $UNIVERSAL_OUTPUTDIR
fi
;;
*)
echo "Second argument much be platform - currently only 'mac' is supported."
;;
esac
And this is the .gdextension
file that the script was designed to work with.
[configuration]
entry_symbol = "swift_entry_point"
compatibility_minimum = 4.2
reloadable = false
[libraries]
macos.debug = "res://bin/arm64-apple-macosx/debug/libSanctuaryDriver.dylib"
macos.release = "res://bin/universal-apple-macosx/release/libSanctuaryDriver.dylib"
[dependencies]
macos.debug = {"res://bin/arm64-apple-macosx/debug/libSwiftGodot.dylib" : ""}
macos.release = {"res://bin/universal-apple-macosx/release/libSwiftGodot.dylib" : ""}
Further Exploration
How does our GDExtension set up affect hot reloading?
It would be nice to be able to use Hot Reloading in SwiftGodot. I need to do more research to find out if this is currently viable and what the limitations are.
Footnotes
-
Thanks to Chris Backas for sharing his script. ↩