nishikaze 0.1.2

Zephyr build system companion.
Documentation
nishikaze-0.1.2 has been yanked.

Nishikaze - The West Wind

crates.io docs.rs pre-commit codecov

A CLI companion that orchestrates the whole lifecycle of Zephyr-based projects using a declarative config.

Index

Why?

Because Zephyr's west sucks, that's why. Even though at first glance this meta tool looks exactly like west, you have the option to configure your project declaratively. I admit, when building a simple Zephyr app, you can just use pure CMake + ninja/make and configure everything in CMake. However, when building a multi-image app using sysbuild (e.g. updatehub OTA + mcuboot + app image) then you're stuck with passing a mile of args into west as you cannot configure it declaratively and cannot externally modify mcuboot's CMake config.

Features

  1. Manage the whole lifecycle of a Zephyr app - config, build, flash, sim runs
  2. Declarative config through kaze.toml
  3. Automatic project dir navigation (can be run from both project root or build dir)

Installation

Install using cargo:

cargo install nishikaze

Usage

Usage: kaze [OPTIONS] <COMMAND>

Commands:
  init      Initializes project with kaze.toml
  boards    Lists available boards
  runners   Lists available runners
  profiles  Lists profiles configured in kaze.toml
  clean     Cleans build dir
  conf      Configure project
  build     Build binary
  run       Run simulation
  flash     Flash binary
  help      Print this message or the help of the given subcommand(s)

Options:
  -c, --clean              Pre-clean the active build dir
  -a, --all                Run command for all configured profiles (overrides --profile/default)
  -p, --profile <PROFILE>  Select project profile defined in kaze.toml
  -b, --board <BOARD>      Zephyr OS board/target
  -r, --runner <RUNNER>    Zephyr OS runner
      --project <PROJECT>  Explicit project root
  -v, --verbose...         Logging verbosity
  -d, --dry-run            Dry run
  -h, --help               Print help
  -V, --version            Print version

Kaze config

πŸ”” Note: Under construction. This doc section contains some features that are not yet implemented.

kaze.toml is a declarative config located at the project root.

File discovery

kaze locates the project by:

  1. if --project <path> is given, use it
  2. else traverse upward from cwd until kaze.toml is found
  3. if run from a build directory, traverse upward to find the owning project root

Configuration layers and precedence

Resolved configuration is produced by merging layers in this order:

  1. Defaults
  2. User config (optional): ~/.config/kaze/config.toml
  3. Project config: <project>/kaze.toml
  4. Environment variables: KAZE_*
  5. CLI flags (--profile, --board, --runner, etc.)

Within the project config:

  • global values apply first
  • active profile values override global values
  • CLI overrides override both

Top-level schema overview

Recommended top-level tables:

  • [project] β€” defaults and profile selection
  • [zephyr] β€” workspace and base paths
  • [build] β€” build directory rules
  • [args] β€” extra args per phase (global)
  • [profile.<name>] β€” per-profile board/runner + per-profile args

[project]

Key Type Default Summary
board string (none) Default Zephyr board
runner string (none) Default Zephyr runner
default_profile string (none) Default profile name
name string (optional) Display name for the project (optional)

[profile.<name>]

Each profile is a partial override of the global project config.

Key Type Summary
board string Profile board
runner string Profile runner
args table Per-phase args for the profile

Example:

[profile.sim]
board = "native_sim"

[profile.prod]
board = "nucleo_f767zi"
runner = "openocd"

Profile selection rules

When profiles are defined:

  1. if --all set β†’ all profiles selected
  2. else if --profile set β†’ that profile selected
  3. else if default_profile set β†’ selected
  4. else β†’ first profile in config file order (or lexicographic if order isn’t preserved)

When profiles are not defined:

  • profile selection is ignored and build is profile-less.

[zephyr]

Key Type Default Summary
workspace string auto-detect Zephyr workspace root
base string ${zephyr_ws}/zephyr Zephyr base directory

Auto-detection order (when not set):

  1. ZEPHYR_BASE environment variable
  2. find .west/ by traversing upward; if found, treat its parent as workspace
  3. (optional) fallback helpers can be added later

[build]

Key Type Default Summary
root string "build" Root build output directory
layout string enum "auto" Build layout mode: auto, profiles, single
link_compile_commands bool true When profiles enabled, create root build/compile_commands.json symlink

Build output layout

  • Profile-less mode: ./<build.root>/
  • Profiles mode: ./<build.root>/<profile>/

If profiles mode and link_compile_commands=true:

  • ./<build.root>/compile_commands.json is a symlink to the selected default/first profile’s compile_commands.json

[args] and per-profile args

Args are configurable for phases:

  • conf (CMake configure)
  • build (Ninja)
  • flash (west flash / runner invocation)
  • run (simulator binary or fallback command)

Value forms:

  • string β†’ treated as a single argument string (split behavior is implementation-defined; recommended to use arrays)
  • array of strings β†’ preferred, exact args list

Example:

[args]
conf  = ["-DHG_TEST=ON"]
build = ["-j", "0"]
flash = ["--hex-file", "path/to/other.hex"]
run   = ["-flash_mount=../../seed/sd"]

[profile.sim.args]
run = ["-flash=../../seed/flash.bin", "-wait_uart"]

Arg merge order

For a given phase:

  1. global [args.<phase>]
  2. profile [profile.<name>.args.<phase>]
  3. CLI passthrough args after --

Minimal examples

1) Simple project (profile-less)

[project]
board = "nucleo_f767zi"
runner = "openocd"

2) Project with profiles

[project]
runner = "openocd"
default_profile = "sim"

[profile.sim]
board = "native_sim"

[profile.prod]
board = "nucleo_f767zi"

Similar projects

License

This project is licensed under either of:

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed under the Apache-2.0 and MIT license, without any additional terms or conditions.

Development

Only requires just to bootstrap all tools and configuration.

cargo install just
just init # setup repo, install hooks and all required tools

To run:

just run

To test:

just test

Before committing work:

just pre-commit

To see all available commands:

just list