CLI Reference
Complete reference for the bwslc command-line compiler.
Turn the guide into code
Take the key idea from this page into the playground and validate it in a real shader instead of leaving it as theory.
Open PlaygroundThe bwslc command compiles .bwsl shader files to SPIR-V internally and can emit SPIR-V, Metal, HLSL, GLSL, and GLSL ES artifacts. An experimental WGSL backend generates WGSL directly.
Examples below use bwslc. In a source checkout, that binary is typically ./build/bwslc.
Basic Usage
bwslc <input.bwsl | directory> [more inputs...] [options]
Passing more than one input, a directory, or -manifest activates batch mode. Batch mode compiles every discovered unit and reports all failures together instead of stopping at the first failed file.
Options
Core Options
| Option | Description |
|---|---|
-o <dir> | Output directory (default: current directory) |
-manifest <file> | Read input files or directories from a manifest file |
-modules <dir> | Add a module search path (repeatable) |
-variant <k=v> | Specialize one named shader variant (repeatable) |
-dump-variant-space | Print variant reflection JSON and exit |
-check | Run diagnostics without writing output files |
--stdin | Read source from stdin instead of the input file |
--source-file <path> | Source path used for diagnostics/module resolution with --stdin |
-pass <name> | Compile a specific pass (default: all passes) |
-stage <name> | Compile a specific stage: vertex, fragment, or compute |
-watch | Stay resident and recompile changed source or imported module files |
-watch-interval <ms> | File polling interval for -watch (default: 250, minimum: 20) |
Output Format Flags
SPIR-V is generated internally for validation and cross-compilation. If no output format is requested, the CLI writes SPIR-V by default; when other formats are requested, use -spv to also write .spv sidecars. -wgsl is the exception: it generates WGSL from the compiler's IR, so a WGSL-only build skips SPIR-V entirely.
| Flag | Description |
|---|---|
-spv | Write generated SPIR-V files alongside requested artifacts |
-metal | Generate Metal Shading Language output |
-hlsl | Generate HLSL output |
-glsl | Generate GLSL 450 output |
-gles | Generate GLSL ES 300 output |
-gles-direct | Generate GLSL ES directly from BWSL IR |
-wgsl | Generate WGSL directly from BWSL IR (experimental; see below) |
-webgl | Alias for -gles |
-bindings | Emit resolved resource binding JSON |
-errors-json | Print machine-readable diagnostics JSON |
-ast-json | Print parsed AST JSON and exit |
-all | Generate SPIR-V, Metal, HLSL, GLSL and GLSL ES, plus -bindings. Does not include WGSL; add -wgsl explicitly. |
Debug Options
| Option | Description |
|---|---|
-v | Verbose output |
-timing | Print timing information |
-dump-ir | Dump BWSL IR |
-debug-names | Keep source names for locals, arrays, structs and members in SPIR-V and cross-compiled output. With -glsl/-gles, names reserved in GLSL get a _ suffix (vec4 becomes vec4_). |
-validation <auto|strict|off> | Choose SPIR-V validation behavior (default: auto) |
-no-validate | Skip SPIR-V validation |
-internals | Write the IR dump and target internals (SPIR-V disassembly, or the WGSL source for WGSL-only builds) to <stem>.<stage>.internals.json |
-h, --help | Show help |
Examples
SPIR-V Only
bwslc shader.bwsl
Use -spv when requesting other artifacts but still wanting SPIR-V files written:
bwslc shader.bwsl -spv -metal
SPIR-V + Metal
bwslc shader.bwsl -metal -spv
Multiple Output Formats
bwslc shader.bwsl -metal -hlsl -gles
All Outputs
bwslc shader.bwsl -all
-all writes the established targets and bindings.json. When a GLSL or GLSL ES target can't express something the shader uses (for example storage buffers in GLSL ES 3.00, or subgroup operations that need Vulkan semantics), -all skips that target with a warning instead of failing. A target you request explicitly must succeed.
WGSL (Experimental)
bwslc shader.bwsl -wgsl -bindings
The WGSL backend translates the compiler's IR straight to WGSL, without SPIR-V. It supports compute, vertex and fragment stages, structured control flow, std140 uniforms, storage buffers and sampled textures. Expect gaps: shaders that use features it doesn't cover yet fail with a WGSL: diagnostic.
- Add
-spv(or another target) to build SPIR-V as well;-allnever includes WGSL. - With
-bindings, each stage gets a<stem>.<stage>.wgsl.bindings.jsonwith WebGPU group/binding pairs. That layout differs from the SPIR-V one. See Bindings and Reflection. - The WASM build used by the playground does not include the WGSL backend.
Source-Declared Resources
bwslc shader.bwsl -all -bindings
Resources are declared in the shader with resources {} and selected per pass with use resources { ... }. The -bindings flag emits the resolved host binding metadata for those source-declared resources.
Specialize Shader Variants
bwslc shader.bwsl -variant skinning=true -variant lighting=Clustered -metal
Boolean variants accept true, false, 1, or 0. Enum variants accept either a bare member name or a qualified name such as LightingMode::Clustered.
Dump Variant Reflection
bwslc shader.bwsl -dump-variant-space
This prints JSON describing declared variants, implicit variants, legality rules, and the current selected values. See Shader Variants for the language-side model.
Custom Output Directory
bwslc shader.bwsl -o dist/shaders -all
Batch Compile Files
bwslc lighting.bwsl postfx.bwsl ui.bwsl -check
Every file is checked and the process exits nonzero if any file fails. Text output includes a batch summary; JSON mode emits one aggregate document with per-file diagnostics.
Batch Compile a Directory
bwslc shaders/ -o dist/shaders -metal -hlsl
Directory inputs are scanned recursively for .bwsl files. Outputs mirror the source subdirectories under -o, so files with the same stem in different folders do not overwrite each other.
Use a Manifest
bwslc -manifest shaders.txt -check -errors-json
Manifest files contain one file or directory per line:
# paths are relative to this manifest file
pipelines/
effects/bloom.bwsl
ui/hud.bwsl
Blank lines and # comments are ignored. Directory entries are scanned the same way as positional directory inputs, and overlapping entries are deduplicated.
Watch for Changes
bwslc shaders/ -modules modules/ -o dist/shaders -gles -watch
Watch mode performs an initial build, then recompiles changed units when a source file or imported module file changes. Directory and manifest inputs are rescanned on each polling tick, so added and removed .bwsl files are picked up without restarting the compiler.
Use -errors-json when an editor or engine hot-reload process wants one parseable JSON build report per rebuild:
bwslc shaders/ -modules modules/ -o dist/shaders -gles -watch -errors-json
Tune polling when needed:
bwslc shaders/ -watch -watch-interval 100
Compile a Specific Pass
bwslc shader.bwsl -pass MainPass
Compile a Specific Stage
bwslc shader.bwsl -pass Simulate -stage compute
Add Module Search Paths
bwslc shader.bwsl -modules ./modules -modules ./lib/shaders
Standard-library modules are embedded in the compiler, so imports such as import Math, import Debug, or import Sampling do not require a -modules path. Module search paths are still used for project modules. A disk module cannot override an embedded standard-library module name.
Emit JSON Diagnostics
bwslc shader.bwsl -errors-json
This prints schema-versioned diagnostic JSON with severities, phases, stable BWSL... error codes, source locations, token details, and source context when available. Use it for editor integrations, CI annotations, and build tools that should not parse human-readable compiler output.
See Diagnostics for the JSON schema and complete error-code table.
For batch inputs, -errors-json emits a single aggregate document with batch: true, summary counts, and a files array of normal per-file diagnostic documents. For watch mode, each rebuild emits one aggregate JSON document with watch: true and event: "build".
Emit AST JSON
bwslc shader.bwsl -ast-json
This parses the source and prints AST JSON for IDEs, code browsers, documentation tooling, and other structural integrations. The top-level object uses schema: "bwsl.ast.v3" and includes sourceFile, roots, modules, pipelines, nodeCounts and a referenceIndex of declarations and their references. The older root object is still present but deprecated.
See AST JSON for the full schema, including what changed from v2.
Control SPIR-V Validation
bwslc shader.bwsl -validation strict
Validation modes:
| Mode | Behavior |
|---|---|
auto | Validate when the SPIR-V validation tool is available; warn and continue if it is missing. |
strict | Require validation and fail if the validation tool is missing or reports an error. |
off | Skip validation. -no-validate is an alias for this mode. |
Emit Internal Debug Data
bwslc shader.bwsl -internals -o build/shaders
Input Compatibility
Some modes intentionally stay single-input:
| Combination | Behavior |
|---|---|
--stdin with files, directories, or -manifest | Rejected |
--stdin with -watch | Rejected |
-ast-json with multiple inputs | Rejected |
-dump-variant-space with multiple inputs | Rejected |
-ast-json or -dump-variant-space with -watch | Rejected |
Exit Codes
| Code | Meaning |
|---|---|
0 | Success, or -h |
1 | Any failure: invalid arguments, a compile error, a requested target that couldn't be generated, or any failed unit in a batch |
Warnings and notes do not change the exit code. In -watch mode the process stays running and reports each rebuild instead of exiting.
Output Notes
Each compiled pass emits one output per selected stage and target format into the chosen output directory. Graphics passes produce vertex and fragment outputs; compute passes produce compute outputs.
For single-pass shaders, stage outputs use the input basename directly. For multi-pass shaders, the pass name is appended to the stem, such as shader_MainPass.vert and shader_PostFX.frag.
| Output | File names |
|---|---|
| SPIR-V | shader.vert.spv, shader.frag.spv, shader.comp.spv |
| Metal | shader.vert.metal, shader.frag.metal |
| HLSL | shader.vert.hlsl, shader.frag.hlsl |
| GLSL or GLSL ES (one of them) | shader.vert, shader.frag, shader.comp |
GLSL and GLSL ES together (as with -all) | shader.glsl.vert and shader.gles.vert, and so on |
| WebGL stage metadata | shader.vert.json (or shader.gles.vert.json) |
| WGSL | shader.vert.wgsl, plus shader.vert.wgsl.bindings.json with -bindings |
| Bindings | shader.bindings.json |
| Internals | shader.vert.internals.json |
In batch mode, multiple explicit files write into the selected output directory. Directory inputs preserve relative subdirectories under -o.
See Also
- Shader Variants - Declaring and specializing shader variant space
- Diagnostics - Diagnostic JSON schema and error codes
- Installation - Building or locating the compiler
- Quick Start - Write your first shader
- Integration - Engine and build-system integration