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

GoalToolProduct module
imp gen-lockfilesOdin//rules/odin/toolchain
imp gen-lockfilesodinfmt//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:server

Collections

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

OptionTypeDefaultExampleRequired
buildGenerateboolfalseno
collectionsmap<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.

ParameterTypeDescription
versionstringOdin release version (matches .odin-version).
[opts]object
[opts.default=false]booleanSet as the default toolchain.
[opts.unverified=false]booleanAllow downloading without a
[opts.linker]objectLinker 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.

ParameterTypeDescription
optsobject
[opts.srcs=[]]string[]Glob patterns for input files (for incremental tracking).
opts.outstringOutput file path, relative to the declaring BUILD.js directory.
opts.cmdstring[]Command to run; output path is appended as the final argument.
[opts.deps=[]]ArrayAdditional 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().

ParameterTypeDescription
optsobject
[opts.srcs=[]]string[]Glob patterns matched against paths relative to opts.path.
[opts.exclude=[]]string[]Glob patterns to exclude from matches.
[opts.path="."]stringWorkspace-relative package path.
[opts.collections=[]]object[]object
[opts.toolchain]objectstring
[opts.output]stringWorkspace-relative executable output path.
[opts.deps=[]]ArrayOdin 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.

ParameterTypeDescription
optsobject
[opts.srcs=[]]string[]Glob patterns matched against paths relative to opts.path.
[opts.exclude=[]]string[]Glob patterns to exclude from matches.
[opts.path="."]stringWorkspace-relative package path.
[opts.collections=[]]object[]object
[opts.toolchain]objectstring
[opts.deps=[]]ArrayOdin package and resource package dependencies.

Returns: object Exported label handle.