Skip to main content

Crate henad_build

Crate henad_build 

Source
Expand description

Build-script support for Henad model crates.

stamp_commit records the commit a crate was built from, a dirty flag and a hash of its sources, for henad::build_info! to read. ShaderBuild generates the Rust bindings of a crate’s WGSL shaders, from its build script. Each shader is composed with the shared modules it reaches through #import henad::<module>, whose text comes from henad-core’s SHARED_WGSL_MODULES. henad::include_shaders! then brings the two generated files into the crate, as the modules shader_bindings and binding_decls.

// build.rs
fn main() -> Result<(), Box<dyn std::error::Error>> {
    henad_build::stamp_commit();
    henad_build::ShaderBuild::discover("src")?.generate()?;
    Ok(())
}

A crate without shaders keeps the build script for its stamp, and drops the ShaderBuild line.

§Names

A shader’s path below the shader root becomes three Rust names. gpu_vote/step.wgsl gives the module shader_bindings::gpu_vote::step, the ShaderEntry variant GpuVoteStep and the binding constant binding_decls::bindings::GPU_VOTE_STEP. The constant is the path’s components upper-cased and joined by _, with the final .wgsl removed, so my_wgsl/step.wgsl gives MY_WGSL_STEP. Every component of a .wgsl file’s path is therefore a Rust identifier and not a keyword.

A file with a #define_import_path line is a module other shaders import, and never an entry point. An import resolves by file path alone. A module’s import path mirrors its path below the shader root, or below the directory of the file that imports it, as #define_import_path gpu_vote::state in gpu_vote/state.wgsl. The bindings refer to an imported module by the import path it resolved through, and to a quoted import by the stem of its file name, as #import "std.inc" gives the module std.

The root henad is reserved for the shared modules, regardless of case. A file named henad.wgsl or a directory named henad holding a .wgsl file would shadow them, and both are rejected. So is a .wgsl path whose first component is a name the generated bindings use at their root: wgpu, bytemuck, std, core, alloc, _root, ShaderEntry, layout_asserts or bytemuck_impls. An import is rejected too when its module path in the bindings starts with henad or one of those names.

Note that each struct’s layout assertion is named after the struct’s module path and name in upper snake case. gpu_vote::step::TallyParams and gpu_vote::step_tally::Params both give GPU_VOTE_STEP_TALLY_PARAMS_ASSERTS, and rustc reports the two inside the generated file. Rename one of the structs.

§Bindings

binding_decls::bindings holds each entry point’s @group(0) declarations, in @binding order, read from lines of one form: @group(0) @binding(N) var<...> name: Type;. A line holding @binding or @group in any other form fails the build. A compile-time assertion checks each list against the length of the layout wgsl_bindgen derives. A module declares no bindings, and a line holding @binding in a module fails the build too.

§Versions

henad-build pins wgsl_bindgen to 0.23.3 and fixes the code it generates. Cargo keeps one release per semver-compatible range in a lockfile. A build script that runs wgsl_bindgen itself therefore uses 0.23.3 as well. Use the same 0.x of henad and henad-build. include_shaders! fails the build when the shaders were composed against different shared WGSL than the linked henad provides.

Structs§

ShaderBuild
One crate’s shader-binding generation, run from its build script.

Enums§

ShaderBuildError
Reason a shader build fails.

Functions§

stamp_commit
Stamps the crate whose build script calls it with its commit, a dirty flag and a hash of its sources.