module Lapis::Docs::A_GETTING_STARTED::B_COMPILATION

Overview

Building Lapis from Source

Comprehensive guide to compiling the complete Lapis engine toolchain from source, understanding the three compilation tiers, runtime DLL dependencies, Windows shadow loading, and in-editor hot-reloading.

Executive Summary & Key Topics

Topic Method / Anchor Description
The Three Compilation Tiers .topic_00_compilation_tiers Overview of the native C++ bridge, Crystal game library, and Godot engine.
The Golden Build Rule: make all .topic_01_the_golden_build_rule Always use make all to compile, link, synchronize, and test all targets safely.
Windows Shadow DLL File-Lock Avoidance .topic_02_windows_shadow_loading Mechanics of runtime shadow DLL cloning to allow background recompilation while Godot is open.
Automatic Shadow DLL Cleanup .topic_03_shadow_cleanup_lifecycle Lifecycle cleanup of temporary shadow DLLs on startup, during reload, and on engine shutdown.
Runtime DLL Dependencies .topic_04_runtime_dependencies Required platform shared libraries for Crystal garbage collection and regular expressions.

Related Guides & Source References

Defined in:

libgodot/docs/a_getting_started/b_compilation.cr

Class Method Summary

Class Method Detail

def self.topic_00_compilation_tiers : Nil #

The Three Compilation Tiers: Overview of the native C++ bridge, Crystal game library, and Godot engine.

Key Topics & Information

  • Tier 1: C++ GDExtension Loader Bridge (bin/crystal_bridge.dll)
  • Tier 2: Crystal Game & Addon Libraries (bin/game.dll, bin/plugin.dll)
  • Tier 3: Standalone Executable Host (bin/game.exe) or Godot Editor (godot.exe)

def self.topic_01_the_golden_build_rule : Nil #

The Golden Build Rule: make all: Always use make all to compile, link, synchronize, and test all targets safely.

Whenever compiling or rebuilding in the Lapis workspace, developers and agents must run:

make all

Or for release-optimized compilation:

make all RELEASE=1

Why Partial Builds are Prohibited:

Running partial targets in isolation (e.g. make bridge or make game_dll) fails to synchronize runtime dependencies and GDExtension manifests across consumer projects (examples/, template/, performance/).

make all guarantees the following sequential steps:

  1. Verifies runtime directory layout (dirs).
  2. Validates and stages runtime DLLs (gc.dll, pcre2-8.dll, iconv-2.dll, libgodot.dll).
  3. Compiles src/bridge/crystal_bridge.cpp into bin/crystal_bridge.dll with debug symbols.
  4. Compiles the native editor plugin bin/plugin.dll.
  5. Generates project node bindings and compiles the root game library bin/game.dll.
  6. Compiles the standalone runner bin/game.exe.
  7. Compiles all example showcase games in examples/.
  8. Compiles the starter templates (template/, template-addon/).
  9. Synchronizes all output binaries across all 22 target folders.
  10. Executes the multi-tier test suite.

def self.topic_02_windows_shadow_loading : Nil #

Windows Shadow DLL File-Lock Avoidance: Mechanics of runtime shadow DLL cloning to allow background recompilation while Godot is open.

On Windows, opening a dynamic library with LoadLibraryA acquires an exclusive operating system file lock on disk. If the Godot Editor is running, the Crystal compiler cannot overwrite bin/game.dll, triggering Windows Error 32 (Sharing Violation).

How Lapis Solves This:

In src/bridge/module_loader.hpp, the loader bridge never locks bin/game.dll directly during development:

  1. When the editor boots or reloads, the bridge creates a timestamped shadow copy: bin/game.dll_loaded_<PID>_<TIMESTAMP>.dll
  2. It copies companion debug symbols (.pdb) alongside the shadow copy so radare2 retains line-level debugging.
  3. The bridge passes the shadow copy to LoadLibraryExA.
  4. bin/game.dll remains completely unlocked on disk!
  5. The developer can rebuild game.dll freely in the background while the Godot Editor stays open.
  6. Pressing F5 in the Godot Editor triggers an instant hot-reload.

def self.topic_03_shadow_cleanup_lifecycle : Nil #

Automatic Shadow DLL Cleanup: Lifecycle cleanup of temporary shadow DLLs on startup, during reload, and on engine shutdown.

To prevent disk bloat from accumulated shadow copies over long development sessions, Lapis implements automatic multi-directory sweeping:

  1. On Engine Startup (load_crystal_game_library): cleanup_old_shadow_dlls scans bridge_dir, candidate output directories, and root bin/, immediately unlinking any shadow files whose host processes have exited.
  2. On Runtime Reload: Prior shadow files from earlier reloads whose locks were released are deleted automatically.
  3. On Engine Shutdown (unload_crystal_game_library): The bridge sweeps all scanned directories.
  4. Manual Storage Reclamation: Run lapis clean --shadows at any time to prune all stale shadow files across your workstation without touching compiled game binaries.

def self.topic_04_runtime_dependencies : Nil #

Runtime DLL Dependencies: Required platform shared libraries for Crystal garbage collection and regular expressions.

Every Lapis target directory requires the following shared libraries alongside crystal_bridge.dll and game.dll:

Shared Library Purpose Source
gc.dll Boehm-Demers-Weiser Garbage Collector Crystal distribution (bin/)
pcre2-8.dll Perl-Compatible Regular Expressions v2 Crystal distribution (bin/)
iconv-2.dll Character encoding conversion library Crystal distribution (bin/)
libgodot.dll Standalone Godot engine core dynamic library Workspace bin/

Run make deps or lapis deps at any time to verify and stage these libraries automatically.