Tools9 min read

CLI Reference

Complete reference for the bwslc command-line compiler.

Reading Time
9 min
Word Count
1,463
Sections
30
Try It Live

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 Playground

The 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

bash
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

OptionDescription
-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-spacePrint variant reflection JSON and exit
-checkRun diagnostics without writing output files
--stdinRead 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
-watchStay 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.

FlagDescription
-spvWrite generated SPIR-V files alongside requested artifacts
-metalGenerate Metal Shading Language output
-hlslGenerate HLSL output
-glslGenerate GLSL 450 output
-glesGenerate GLSL ES 300 output
-gles-directGenerate GLSL ES directly from BWSL IR
-wgslGenerate WGSL directly from BWSL IR (experimental; see below)
-webglAlias for -gles
-bindingsEmit resolved resource binding JSON
-errors-jsonPrint machine-readable diagnostics JSON
-ast-jsonPrint parsed AST JSON and exit
-allGenerate SPIR-V, Metal, HLSL, GLSL and GLSL ES, plus -bindings. Does not include WGSL; add -wgsl explicitly.

Debug Options

OptionDescription
-vVerbose output
-timingPrint timing information
-dump-irDump BWSL IR
-debug-namesKeep 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-validateSkip SPIR-V validation
-internalsWrite the IR dump and target internals (SPIR-V disassembly, or the WGSL source for WGSL-only builds) to <stem>.<stage>.internals.json
-h, --helpShow help

Examples

SPIR-V Only

bash
bwslc shader.bwsl

Use -spv when requesting other artifacts but still wanting SPIR-V files written:

bash
bwslc shader.bwsl -spv -metal

SPIR-V + Metal

bash
bwslc shader.bwsl -metal -spv

Multiple Output Formats

bash
bwslc shader.bwsl -metal -hlsl -gles

All Outputs

bash
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)

bash
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; -all never includes WGSL.
  • With -bindings, each stage gets a <stem>.<stage>.wgsl.bindings.json with 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

bash
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

bash
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

bash
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

bash
bwslc shader.bwsl -o dist/shaders -all

Batch Compile Files

bash
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

bash
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

bash
bwslc -manifest shaders.txt -check -errors-json

Manifest files contain one file or directory per line:

text
# 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

bash
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:

bash
bwslc shaders/ -modules modules/ -o dist/shaders -gles -watch -errors-json

Tune polling when needed:

bash
bwslc shaders/ -watch -watch-interval 100

Compile a Specific Pass

bash
bwslc shader.bwsl -pass MainPass

Compile a Specific Stage

bash
bwslc shader.bwsl -pass Simulate -stage compute

Add Module Search Paths

bash
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

bash
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

bash
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

bash
bwslc shader.bwsl -validation strict

Validation modes:

ModeBehavior
autoValidate when the SPIR-V validation tool is available; warn and continue if it is missing.
strictRequire validation and fail if the validation tool is missing or reports an error.
offSkip validation. -no-validate is an alias for this mode.

Emit Internal Debug Data

bash
bwslc shader.bwsl -internals -o build/shaders

Input Compatibility

Some modes intentionally stay single-input:

CombinationBehavior
--stdin with files, directories, or -manifestRejected
--stdin with -watchRejected
-ast-json with multiple inputsRejected
-dump-variant-space with multiple inputsRejected
-ast-json or -dump-variant-space with -watchRejected

Exit Codes

CodeMeaning
0Success, or -h
1Any 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.

OutputFile names
SPIR-Vshader.vert.spv, shader.frag.spv, shader.comp.spv
Metalshader.vert.metal, shader.frag.metal
HLSLshader.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 metadatashader.vert.json (or shader.gles.vert.json)
WGSLshader.vert.wgsl, plus shader.vert.wgsl.bindings.json with -bindings
Bindingsshader.bindings.json
Internalsshader.vert.internals.json

In batch mode, multiple explicit files write into the selected output directory. Directory inputs preserve relative subdirectories under -o.

See Also