TL;DR: I’m sharing a couple of build scripts to make it easier to run a custom build of the Godot Engine.

Motivation

I want to use the godot_voxel plugin, which is a module that must be compiled with Godot. There are several other modules that must be compiled this way.

This presents a technical risk, which the voxel project puts thusly:

Since you are pulling from two projects developped by different people, it’s probable that on occasion your build won’t compile, your project won’t open, or your Voxel Tools won’t work properly or even crash Godot. To minimize downtime, save your successful builds. Move them out of the build folder and rename them with the version number (e.g. godot-3.2+ee5ba3e.exe). This way, you can continue to use previously working builds until the Godot or Voxel developers fix whatever is broken. It is generally desired by all that code published to repositories will at least build, but stuff happens.

https://voxel-tools.readthedocs.io/en/latest/getting_the_module/

A good sytem is one that does not require me to be 100% well-behaved at all times: it should do this automatically.

The Build Scripts

Godot custom SCons dependency

Godot is configured to include a custom.py build script as part of its SCons build files if it exists. It’s even excluded in .gitignore by default. Unfortunately, I couldn’t find a way to configure a rule in this file that would execute after linking - no matter what I tried, my code would only be executed just before linking.

So I made a non-cross-platform batch script instead, that executes a cross-platform nushell script. I hope to unify them to de-stupify this.

Here’s the batch script:

@echo off
d:
cd d:\godot\godot
git pull
scons platform=windows
"C:\\Program Files\\nu\\bin\\nu.exe" "D:\\Godot\\custom_builds\\update_builds.nu"
pause

The above executes a nu script, but you could do otherwise.

Nushell Artifact Copying Script

let build_path = "D:\\Godot\\godot\\bin"
let storage_path = "D:\\Godot\\custom_builds"

let current_build_hash = (cd $build_path; git rev-parse --short HEAD)

if not ($"($storage_path)\\($current_build_hash)" | path exists) {
    mkdir $"($storage_path)\\($current_build_hash)"
}

if not ($"($storage_path)\\latest" | path exists) {
    mkdir $"($storage_path)\\latest"
}

ls | get name | each { |x|
    cp $x $"($storage_path)\\($current_build_hash)\\($x)"
    cp $x $"($storage_path)\\latest\\($x)"
}

echo $current_build_hash | save -f --raw $"($storage_path)\\latest\\build_hash.txt"

This will give a directory structure like the following.

D:/Godot/custom_builds> ls | get name                                                                        
╭───┬──────────────────╮
│ 0 │ 4df80b0e62       │
│ 1 │ e3e2528ba7       │
│ 2 │ latest           │
│ 3 │ update_builds.nu │
╰───┴──────────────────╯

Each will contain the build artifacts of Godot. The “latest” folder will also include a build_hash.txt containing the short git commit hash for the latest build. Here’s the contents of the “latest” folder:

D:/Godot/custom_builds> ls latest | get name                                                                        
╭───┬────────────────────────────────────────────────╮
│ 0 │ latest\build_hash.txt                          │
│ 1 │ latest\godot.windows.editor.x86_64.console.exe │
│ 2 │ latest\godot.windows.editor.x86_64.exe         │
│ 3 │ latest\godot.windows.editor.x86_64.exp         │
│ 4 │ latest\godot.windows.editor.x86_64.lib         │
╰───┴────────────────────────────────────────────────╯