mty build¶
Compile a Mighty source file to a runnable artifact (slice 8).
Synopsis¶
Description¶
mty build runs the same parse → lower → typeck → borrowck →
MtyIR pipeline as mty run, then hands the program to the
configured backend. Two backends ship in v0.1:
- native (default) — Cranelift via
mty-codegen-cranelift. Produces a host-format object (.o) and links it into an executable via the platform linker. - wasm32-wasi / wasm32-web —
mty-codegen-wasm. Emits a core Wasm module (.wasm).
Per A46, LLVM is not the default native backend in v0.1; it's a scaffold behind a feature flag.
Arguments¶
| Flag | Description |
|---|---|
<PATH> |
Path to a .mty source file. |
--debug |
Build in debug mode (default). Smaller compile time, no optimization, debug info emitted (DWARF on native; name + .wasm.map on wasm). |
--release |
Build in release mode. Cranelift opt_level = speed. Debug info stripped. |
--target <TARGET> |
One of native (default), wasm32-wasi, wasm32-web. |
--out-dir <DIR> |
Output directory. Default target/. |
--no-component |
Wasm targets only: emit a bare core wasm module instead of a Component Model component. Useful for runtimes that don't yet support the Component Model, or for debugging the lowering. Default = Component Model output (v0.2 wave-2, closes A47). |
Output¶
Native target: writes <DIR>/<name> (or <name>.exe on Windows).
Intermediate object preserved at <DIR>/<name>.o.
Wasm target: writes <DIR>/<name>.wasm. No linker step.
By default the emitted bytes are a Component Model component
(preamble \0asm\x0d\x00\x01\x00). With --no-component, a bare
core wasm module is written instead (preamble
\0asm\x01\x00\x00\x00).
WasmArtifact::wit_text carries the generated WIT contract in
both modes — downstream tools can read it from the artifact
metadata.
The binary's name is derived from the source file's stem
(examples/01_hello.mty → 01_hello).
Linker discovery (A52)¶
For native builds, the discovery order is:
$MTY_LINKERenv var, if set and non-empty (legacy$STARDUST_LINKERis still honoured with a one-shot deprecation warning).clang(clang.exeon Windows).gcc(gcc.exe).cc(cc.exe).
The MSYS/Git-Bash /usr/bin/link.exe shim is skipped because
it's a hardlink helper, not a linker.
If no linker is found, mty build still succeeds for the object
file. The exit message is:
If a linker is found and returns a non-zero status, mty build
reports a build error instead of treating the run as object-only
success. The error includes the emitted object path and linker stderr,
which lets CI and agent workflows separate "install a linker" from
"fix unresolved symbols or bad link arguments."
You can then invoke the linker yourself:
Environment variables¶
| Variable | Purpose |
|---|---|
MTY_LINKER |
Override linker discovery. Absolute path or bare name on PATH (clang, gcc, link.exe, lld-link). |
MTY_LINKER_FLAVOR |
Force the arg-rewrite flavor regardless of basename. Values: gnu (default) or msvc (rewrites -lfoo→foo.lib, -L<p>→/LIBPATH:<p>, --gc-sections→/OPT:REF). Use when MTY_LINKER points at a custom wrapper that the basename heuristic can't classify. |
STARDUST_LINKER |
Legacy spelling of MTY_LINKER. Honoured with a one-shot deprecation warning. |
MACOSX_DEPLOYMENT_TARGET |
Set the LC_BUILD_VERSION minimum macOS version baked into the produced Mach-O object. Defaults to 11.0.0. |
MTY_MACOSX_SDK_VERSION |
Override the LC_BUILD_VERSION SDK field. Defaults to 14.0.0. |
Manifest link knobs ([build])¶
mighty.toml carries an optional [build] block whose link-related
keys are wired into every native build of the package. Use these for
project-wide knobs ("link libm everywhere"); use [[extern_lib]] for
per-library shape (a vendored static archive with its own
link_args_* matrix).
[build]
# Each name becomes -l<name> (rewritten to <name>.lib on MSVC linkers).
native-libs = ["m", "pthread"]
# Each path becomes -L<path> (rewritten to /LIBPATH:<path> on MSVC).
link-search = ["/opt/whatever/lib"]
# macOS-only. Becomes `-framework <Name>`. Silently dropped on other
# hosts (and dropped by the MSVC rewriter — no Windows analogue).
frameworks = ["Cocoa", "Foundation"]
# Raw linker arguments. Cross-platform shapes are translated by the
# MSVC rewriter:
# --gc-sections → /OPT:REF
# -Wl,-rpath,/x → dropped (MSVC has no rpath)
# Anything unrecognised passes through unchanged — escape hatch for
# linker-specific flags that lack a portable spelling.
link-args = ["--gc-sections"]
These args are appended after the per-[[extern_lib]] argv, so a
vendored static archive can shadow a [build] native-libs entry that
contributes the same symbol.
Examples¶
# Default: native debug build → target/01_hello (or .exe)
mty build examples/01_hello.mty
# Native release build with a custom out dir:
mty build --release --out-dir dist/ src/main.mty
# Wasm WASI build → Component Model component (v0.2 default):
mty build --target wasm32-wasi examples/01_hello.mty
# Wasmtime requires the component-model flag:
wasmtime --wasm component-model target/01_hello.wasm
# Bare core wasm module (skip component wrapper):
mty build --no-component --target wasm32-wasi examples/01_hello.mty
wasmtime target/01_hello.wasm # works without --wasm component-model
# Browser-targeted Wasm → Component Model, transpile via jco:
mty build --target wasm32-web src/widget.mty
jco transpile target/widget.wasm -o dist/widget # emits ESM glue + .wasm core
# then load dist/widget/widget.js as a module in your page
Debug info¶
--debug builds embed debug info into the artifact (the flag is on by
default; pass --release to strip):
- Native objects carry standard DWARF v4 sections (
.debug_info,.debug_abbrev,.debug_line,.debug_str). Uselldb,gdb, orobjdump --dwarf=infoto inspect. - Wasm modules gain a
namecustom section (function names) plus asourceMappingURLcustom section pointing at the sidecar<binary>.wasm.map(source-map v3 JSON). DevTools / Chrome load the sidecar automatically; the Component Model wrapper preserves both custom sections.
See docs/internals/debug-info.md for
the v0.2 coverage matrix, format details, and known limitations
(coarse line table, no .debug_loc location lists yet).
mty build --debug examples/01_hello.mty
objdump --dwarf=info target/01_hello.o # native DWARF
mty build --debug --target wasm32-wasi examples/01_hello.mty
ls target/01_hello.wasm target/01_hello.wasm.map
Wasm runtime compatibility¶
| Runtime | Component default | --no-component core module |
|---|---|---|
wasmtime --wasm component-model |
✅ | n/a |
wasmtime (plain) |
❌ — need flag | ✅ |
wasmer ≥ 4.3 |
✅ | ✅ |
wasmer < 4.3 |
❌ | ✅ |
Browser via jco transpile |
✅ | n/a (use component) |
wasm-tools component validate |
✅ | n/a (it's not a component) |
Exit codes¶
| Code | Meaning |
|---|---|
| 0 | Build succeeded; artifact written. |
| 1 | Frontend error (parse / typeck / borrowck). Diagnostics already rendered. |
| 2 | Backend or CLI error (unknown target, codegen rejection, link failure). Error message printed to stderr. |
Backend coverage matrix¶
The slice-8 native and wasm backends cover a deliberately narrow
MtyIR subset. Programs the backend can't lower trigger
CodegenError::Unsupported(reason). For mty run this falls
back to the interpreter transparently; for mty build it
surfaces as exit 2 with a build error: ... message.
See SLICE8.md for the per-example matrix and the v0.2 backlog.
See also¶
mty run— JIT-compile and execute in one stepmty check— type / borrow check without loweringmty dump— emit AST / CST / HIR / MtyIR for inspection- Codegen internals: Cranelift
- Codegen internals: Wasm
- Codegen internals: LLVM scaffold