1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2026 Ethan Wu
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
//! Compiles, post-processes, and stages every artifact a `Consortium.toml` describes.
//!
//! `consortium-cfg` answers "what does this system look like, and is it valid?" and emits
//! generated source. This crate answers "now actually build it": four compilers, a
//! post-processing step remoteproc requires, and a staging tree a packaging recipe can
//! consume.
//!
//! It stops short of deployment. Nothing here writes to a live target filesystem — the
//! output is a local `dist/` tree plus an optional BitBake hand-off.
//!
//! # Layout
//!
//! | Module | Role |
//! | -------------- | ----------------------------------------------------------- |
//! | [`pipeline`] | The end-to-end `Consortium.toml` → `dist/` flow, stage by stage. |
//! | `compile` | One compiler per artifact kind, behind the [`Compiler`] trait. |
//! | [`progress`] | Reporting hooks the CLI uses to keep a step prompt visible. |
//!
//! # Fetch, then build offline
//!
//! [`pipeline::fetch`] resolves the same Cargo projects the build plan does and
//! downloads their dependencies (plus each target's `std` and the frontend's
//! packages) up front. A subsequent run with [`PipelineConfig::offline`] passes
//! `--offline` to every cargo invocation, so the build reads only local caches —
//! useful for air-gapped hosts, reproducible CI, and container images that should
//! not re-resolve the registry on each build.
//!
//! # Check without building
//!
//! [`pipeline::check`] is the pipeline's `cargo check`: it validates the manifest,
//! writes every endpoint's generated module, and runs `cargo check` in each Cargo
//! project with the same targets and injected environment a build uses — no
//! linking, objcopy, signing, HMI build, or staging.
//!
//! # The `Compiler` trait
//!
//! Firmware, the Linux application, the OP-TEE TA, and the HMI frontend are built by
//! very different toolchains, but callers drive them identically: each implementor owns
//! a `Configuration` carrying all its parameters, a typed `Error`, and an `Output`
//! (usually the path to the built artifact). See [`Compiler`].
//!
//! # Plan, then run
//!
//! [`pipeline::plan`] resolves every stage's inputs — paths, env vars, artifact
//! locations — **without running any build**, threading the data flow between stages.
//! [`pipeline::run`] plans, then executes.
//!
//! That split is what makes the pipeline debuggable: a wrong sysroot or a missing
//! firmware ELF surfaces as a planning failure naming the stage, rather than as a cargo
//! error several minutes into a cross-compile.
//!
//! # Compile-time configuration
//!
//! Memory layout lives in generated source, not the environment: controller firmware gets
//! its IPC region base and its `[dbg]` ring baked into generated `init()`, and the Linux
//! application reaches the same memory through its UIO devices. What still travels as
//! environment variables is what generated code cannot know: the on-target HMI asset
//! paths ([`HmiConfig`], read with `option_env!`), the TEE UUID, and the `CSTI_*`
//! build-host directories ([`CstiWorkspace`]). Numeric values are emitted as decimal
//! strings.
//!
//! # Firmware post-processing
//!
//! Linux remoteproc expects a coprocessor's vector table in a section named
//! `.isr_vectors`, but `cortex-m-rt` emits `.vector_table`. The pipeline renames it, and
//! keeps the debug/original artifacts alongside the deployable ELF.
//!
//! # Staging
//!
//! The assembled tree can contain `app/`, `firmware/`, `ta/`, `www/`, `dts/linux/`,
//! `kernel/`, `boot/`, and `systemd/`, plus a generated BitBake recipe. CLI flags can
//! stage that tree into a recipe's `files/` directory and invoke or dry-run BitBake —
//! the dry-run path exists for the split-machine flow, where `dist/` is produced on one
//! host and the Yocto build runs on another.
//!
//! Keep the planning, compilation, staging, and external BitBake hand-off boundaries
//! distinct when extending this crate; and prefer extending `consortium-cfg` lowering
//! first, then the pipeline.
// Trait
pub use Compiler;
pub use ;
// Deployment artifact rendering
pub use ;
// End-to-end pipeline
pub use ;
// Type-check without building
pub use ;
// Pre-build dependency download
pub use ;
// Compile-time environment-injection carriers
pub use ;
// Backward-compatible builders (String-error API)
pub use ApplicationBuilder;
pub use FirmwareBuilder;
pub use ;
// Typed compiler API
pub use ;
pub use ;
pub use ;
pub use ;