fix(modules): graft to the directory Godot expects, and fetch submodules #13
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A build with godot_voxel enabled failed in the generated registration file:
Godot generates modules/register_module_types.gen.cpp from the directory name
it includes /register_types.h and callsunder modules/: for modules/
initialize__module. Zylann/godot_voxel is named for its repository but
declares initialize_voxel_module, so its catalog row has to graft it to
modules/voxel. The row's path was empty, so it went to modules/godot_voxel and
the engine compiled every source the module owns before failing on a symbol
that never mentions the directory that caused it.
The machinery for this was already right -- workspaceSpec derives the SCons
_enabled=yes together. Nothing recorded or checked which directorytoggle from the DestPath basename, so a correct path fixes the destination and
module_
a module expects, which is what made a one-field mistake cost a full compile.
Four changes:
internal/gdmodule reads the entry point a register_types.h declares. The
word boundary matters: uninitialize_x_module contains initialize_x_module.
graft() checks the header against the directory it just exported into, and
refuses with the path to set. It stays quiet about anything it cannot judge
-- no header, a macro-declared entry point, a destination the build already
rejects elsewhere -- so it can only ever fail a build that was going to fail.
Auto-populate reads the same header inside the crawl's existing mirror
borrow and returns suggested_path, which the admin page offers to apply. No
second lock and no extra fetch.
Registry.Export now fills gitlinks. git archive omits them, a mirror clone
does not fetch them, and the build container has no network, so a module
using submodules arrived incomplete and silently. Submodule URLs come from
upstream rather than from an administrator, so they are followed within
bounds: an allowlist of remote schemes, three levels of nesting, 64
submodules across the whole graft, safeJoin on every path, and a repository
repeated within one chain refused as a cycle. A gitlink pins an exact SHA,
so a warm mirror fetches nothing at all.
docs/architecture.md claimed submodules "work for free" under shelling out to
git. They do not, and it now says what actually happens.
Operationally, the live godot_voxel row still needs its path set to
modules/voxel; this stops the next such row from costing a build to find.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
A build with godot_voxel enabled failed in the generated registration file: modules/register_module_types.gen.cpp:155:9: error: 'initialize_godot_voxel_module' was not declared in this scope; did you mean 'initialize_voxel_module'? Godot generates modules/register_module_types.gen.cpp from the directory name under modules/: for modules/<dir> it includes <dir>/register_types.h and calls initialize_<dir>_module. Zylann/godot_voxel is named for its repository but declares initialize_voxel_module, so its catalog row has to graft it to modules/voxel. The row's path was empty, so it went to modules/godot_voxel and the engine compiled every source the module owns before failing on a symbol that never mentions the directory that caused it. The machinery for this was already right -- workspaceSpec derives the SCons toggle from the DestPath basename, so a correct path fixes the destination and module_<dir>_enabled=yes together. Nothing recorded or checked which directory a module expects, which is what made a one-field mistake cost a full compile. Four changes: - internal/gdmodule reads the entry point a register_types.h declares. The word boundary matters: uninitialize_x_module contains initialize_x_module. - graft() checks the header against the directory it just exported into, and refuses with the path to set. It stays quiet about anything it cannot judge -- no header, a macro-declared entry point, a destination the build already rejects elsewhere -- so it can only ever fail a build that was going to fail. - Auto-populate reads the same header inside the crawl's existing mirror borrow and returns suggested_path, which the admin page offers to apply. No second lock and no extra fetch. - Registry.Export now fills gitlinks. git archive omits them, a mirror clone does not fetch them, and the build container has no network, so a module using submodules arrived incomplete and silently. Submodule URLs come from upstream rather than from an administrator, so they are followed within bounds: an allowlist of remote schemes, three levels of nesting, 64 submodules across the whole graft, safeJoin on every path, and a repository repeated within one chain refused as a cycle. A gitlink pins an exact SHA, so a warm mirror fetches nothing at all. docs/architecture.md claimed submodules "work for free" under shelling out to git. They do not, and it now says what actually happens. Operationally, the live godot_voxel row still needs its path set to modules/voxel; this stops the next such row from costing a build to find. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>