One cannot easily build the RustDoc for a number of crates in the repo. For one thing, much of our code cannot be built without an explicitly set Cortex-M target, so one must pass --target <pick your favorite supported cortex-m toolchain> in order to document any crate which depends on userlib. However, that alone is not sufficient if a crate either has a build script which uses the Hubris app.toml config, or depends on a crate which does. For example:
eliza@theseus ~/Code/oxide/hubris $ cargo doc --open -p ereports --target thumbv7em-none-eabihf --no-deps
Compiling task-sensor-api v0.1.0 (/home/eliza/Code/oxide/hubris/task/sensor-api)
error: failed to run custom build command for `task-sensor-api v0.1.0 (/home/eliza/Code/oxide/hubris/task/sensor-api)`
Caused by:
process didn't exit successfully: `/home/eliza/Code/oxide/hubris/target/debug/build/task-sensor-api-06a98560f4251f57/build-script-build` (exit status: 101)
--- stdout
cargo:rerun-if-changed=../../idl/sensor.idol
cargo::rerun-if-env-changed=HUBRIS_APP_CONFIG
--- stderr
thread 'main' panicked at build/i2c/src/lib.rs:523:17:
malformed config.i2c: app.toml missing global config section [config]
stack backtrace:
0: __rustc::rust_begin_unwind
at /rustc/0d9592026226f5a667a0da60c13b955e0b486a07/library/std/src/panicking.rs:697:5
1: core::panicking::panic_fmt
at /rustc/0d9592026226f5a667a0da60c13b955e0b486a07/library/core/src/panicking.rs:75:14
2: build_i2c::ConfigGenerator::new
at /home/eliza/Code/oxide/hubris/build/i2c/src/lib.rs:523:17
3: build_i2c::codegen
at /home/eliza/Code/oxide/hubris/build/i2c/src/lib.rs:1720:17
4: build_script_build::main
at ./build.rs:37:5
5: core::ops::function::FnOnce::call_once
at /home/eliza/.rustup/toolchains/nightly-2025-07-20-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:253:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
eliza@theseus ~/Code/oxide/hubris $
Note that, in this case, the ereports crate only needs a Hubris app via a transitive dependency on task-sensor-api --- it does not have a build script of its own:
eliza@theseus ~/Code/oxide/hubris $ tree lib/ereports
lib/ereports
├── Cargo.toml
└── src
├── cpu.rs
├── lib.rs
└── pwr.rs
2 directories, 4 files
eliza@theseus ~/Code/oxide/hubris $ cat lib/ereports/Cargo.toml
[package]
name = "ereports"
version = "0.1.0"
edition = "2024"
[dependencies]
microcbor = { path = "../microcbor" }
fixedstr = { path = "../fixedstr", features = ["microcbor"] }
drv-cpu-power-state = { path = "../../drv/cpu-power-state", features = ["microcbor"] }
drv-i2c-devices = { path = "../../drv/i2c-devices" }
counters = { path = "../counters", features = ["derive"], optional = true }
ringbuf = { path = "../ringbuf", features = ["counters"], optional = true }
task-packrat-api = { path = "../../task/packrat-api", optional = true, features = ["microcbor"]}
paste = { workspace = true, optional = true }
static-cell = { path = "../static-cell", optional = true }
[features]
ereporter-macro = ["task-packrat-api", "paste", "static-cell", "counters", "ringbuf"]
default = ["ereporter-macro"]
[lints]
workspace = true
# This section is here to discourage RLS/rust-analyzer from doing test builds,
# since test builds don't work for cross compilation, and this crate dependencies
# on `userlib` (transitively, via `drv-i2c-devices`), which won't build on non-ARM
# targets.
[lib]
test = false
doctest = false
bench = false
eliza@theseus ~/Code/oxide/hubris $
I think it would be nice if we had a cargo xtask doc or something which wrapped a RustDoc invocation in the context of a Hubris build. I would expect the CLI for this to basically just be:
$ cargo xtask doc <CFG> [RUSTDOC_ARGS]...
where <CFG> is the path to a Hubris app.toml and [RUSTDOC_ARGS]... is any number of additional arguments which are passed through to RustDoc (i.e. so that you can say things like -p ereports --open --no-deps or whatever else you'd like).
If we anticipate the need to pass additional flags to the xtask itself, we could instead use the [-- <RUSTDOC_ARGS>...] syntax to disambiguate between xtask doc flags and cargo doc flags, similarly to xtask humility and friends, but I really struggle to imagine additional RustDoc-specific args we'd need to pass here. All the xtask needs to do is invoke cargo doc in the context of a Hubris build so that build scripts can run.
One cannot easily build the RustDoc for a number of crates in the repo. For one thing, much of our code cannot be built without an explicitly set Cortex-M target, so one must pass
--target <pick your favorite supported cortex-m toolchain>in order to document any crate which depends onuserlib. However, that alone is not sufficient if a crate either has a build script which uses the Hubrisapp.tomlconfig, or depends on a crate which does. For example:Note that, in this case, the
ereportscrate only needs a Hubris app via a transitive dependency ontask-sensor-api--- it does not have a build script of its own:I think it would be nice if we had a
cargo xtask docor something which wrapped a RustDoc invocation in the context of a Hubris build. I would expect the CLI for this to basically just be:$ cargo xtask doc <CFG> [RUSTDOC_ARGS]...where
<CFG>is the path to a Hubris app.toml and[RUSTDOC_ARGS]...is any number of additional arguments which are passed through to RustDoc (i.e. so that you can say things like-p ereports --open --no-depsor whatever else you'd like).If we anticipate the need to pass additional flags to the
xtaskitself, we could instead use the[-- <RUSTDOC_ARGS>...]syntax to disambiguate betweenxtask docflags andcargo docflags, similarly toxtask humilityand friends, but I really struggle to imagine additional RustDoc-specific args we'd need to pass here. All the xtask needs to do is invokecargo docin the context of a Hubris build so that build scripts can run.