Odin
The Odin rules build binaries, run test packages, validate source with
odin check -vet, execute a selected binary, publish artifacts, and generate
source files. Odin packages may depend on other Odin targets, resource targets,
and CMake libraries; the rule assembles the transitive sources, collection
flags, native link inputs, and managed tools needed by the sandboxed command.
Available goals
| Goal | Tool | Product module |
|---|---|---|
imp gen-lockfiles | Odin | //rules/odin/toolchain |
imp gen-lockfiles | odinfmt | //rules/odin/odinfmt/toolchain |
Set up the workspace
Import the compiler and formatter rules in imp.workspace.js, then load the
workflows you use. The rules provide pinned defaults:
import "//rules/odin";
import "//rules/odin/odinfmt";
import "//rules/workflows/fmt";
import "//rules/workflows/lint";
import "//rules/workflows/package";
import "//rules/workflows/run";
import "//rules/workflows/test";
Override a default only when needed, for example to select a managed linker. Keep that choice on the Odin toolchain so build, test, run, and lint resolve the same native environment.
This repository's workspace imports //rules/imp/mode: the default profile
keeps Odin's -debug build behavior, while imp build --profile release ...
uses Odin's -o:speed optimization mode.
Declare packages and tests
import { odinPackage, odinTestPackage } from "//rules/odin";
export const server = odinPackage({
path: ".",
output: "build/server",
});
export const server_tests = odinTestPackage({
path: ".",
deps: [server],
});
An odinPackage defaults to *.odin and excludes *_test.odin and
test_*.odin. An odinTestPackage includes test files and participates in the
test goal through odin test. Override srcs and exclude with globs
relative to path when a package uses another layout.
imp lint --fix is accepted goal-wide but has no effect for Odin packages:
odin check -vet has no autofix mode, so --fix just runs the same plain
lint.
Set output when a package needs a stable workspace-relative executable path.
package publishes the built result below dist/ according to the target
address. run executes one selected package and rejects ambiguous
multi-target selections.
imp build //apps/server:server
imp test //apps/server:server_tests
imp fmt --check //apps/server:server
imp lint //apps/server:server
imp run //apps/server:server
imp package //apps/server:serverCollections
Use workspace configuration for collection names shared by many packages:
export const odinConfig = {
collections: {
core: "src/core",
vendor: "third_party/odin",
},
};
The schema is a dynamic map<string, string>: collection names are not fixed
in advance, but every key and path is validated. Paths are workspace-relative.
Package-local collection entries belong on the target and override a workspace entry with the same name:
export const editor = odinPackage({
collections: {
generated: "generated/odin",
},
});
Local collections may also use collection target handles or { name, path }
entries when a plain name-to-path object is not sufficient. Collection
directories are included as declared sandbox inputs, not merely converted into
compiler flags.
Generate sources and BUILD files
odinGen() declares a generated file and records the generator command or
target as a dependency. The output path is appended as the command's final
argument. Exclude that output from any overlapping odinPackage() glob so one
file has one owner:
import { odinGen, odinPackage } from "//rules/odin";
export const bindings = odinGen({
srcs: ["schema.json"],
out: "generated/bindings.odin",
cmd: ["schema-to-odin", "schema.json"],
});
export const app = odinPackage({
exclude: ["generated/bindings.odin"],
deps: [bindings],
});
Separately, imp goal generate-build can create declarations for unowned
Odin sources. Opt in with odinConfig.buildGenerate: true; it is disabled by
default.
Configuration
| Option | Type | Default | Example | Required |
|---|---|---|---|---|
| buildGenerate | bool | false | — | no |
| collections | map<string, string> | {} | {"vendor":"//src/odin/vendor"} | no |
Example
export const odinConfig = {
buildGenerate: false,
collections: {},
};odinToolchain()
odinToolchain(version, opts = {})
Declare an Odin toolchain version and optionally set it as the default. matching lockfile entry (warns instead of failing). registering an "odin-linker" product. If omitted, Odin links with whatever ld the gcc toolchain's clang wrapper selects by default.
| Parameter | Type | Description |
|---|---|---|
| version | string | Odin release version (matches .odin-version). |
| [opts] | object | |
| [opts.default=false] | boolean | Set as the default toolchain. |
| [opts.unverified=false] | boolean | Allow downloading without a |
| [opts.linker] | object | Linker toolchain handle (e.g. moldToolchain()) |
Returns: object Target handle for this Odin toolchain.
Targets
odinGen
const odinGen
Declare an Odin source generation label. The generator command is run with the output path appended as the last argument. Generated files must be excluded from any odinPackage glob that covers the same directory — use the exclude option of odinPackage to enforce single ownership.
| Parameter | Type | Description |
|---|---|---|
| opts | object | |
| [opts.srcs=[]] | string[] | Glob patterns for input files (for incremental tracking). |
| opts.out | string | Output file path, relative to the declaring BUILD.js directory. |
| opts.cmd | string[] | Command to run; output path is appended as the final argument. |
| [opts.deps=[]] | Array | Additional dependencies. |
Returns: object Exported label handle.
odinPackage
const odinPackage
Declare an Odin package target. Sources are discovered lazily at build time via own_sources() / sources().
| Parameter | Type | Description |
|---|---|---|
| opts | object | |
| [opts.srcs=[]] | string[] | Glob patterns matched against paths relative to opts.path. |
| [opts.exclude=[]] | string[] | Glob patterns to exclude from matches. |
| [opts.path="."] | string | Workspace-relative package path. |
| [opts.collections=[]] | object[] | object |
| [opts.toolchain] | object | string |
| [opts.output] | string | Workspace-relative executable output path. |
| [opts.deps=[]] | Array | Odin package and resource package dependencies. |
Returns: object Exported label handle.
odinTestPackage
const odinTestPackage
Declare an Odin test package target. Test packages participate in the test goal and run odin test. Unlike odinPackage, they include test files by default.
| Parameter | Type | Description |
|---|---|---|
| opts | object | |
| [opts.srcs=[]] | string[] | Glob patterns matched against paths relative to opts.path. |
| [opts.exclude=[]] | string[] | Glob patterns to exclude from matches. |
| [opts.path="."] | string | Workspace-relative package path. |
| [opts.collections=[]] | object[] | object |
| [opts.toolchain] | object | string |
| [opts.deps=[]] | Array | Odin package and resource package dependencies. |
Returns: object Exported label handle.