consortium_builder/compile/mod.rs
1// Copyright 2026 Ethan Wu
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// SPDX-License-Identifier: Apache-2.0
16
17//! One compiler per artifact kind, behind a single trait.
18//!
19//! A Consortium build produces four very differently-built things:
20//!
21//! | Module | Artifact | Built with |
22//! | --------------- | ------------------------- | ------------------------------ |
23//! | `firmware` | coprocessor ELF | `cargo` for a bare-metal target |
24//! | `application` | Linux executable | `cargo`, usually cross-compiled |
25//! | `optee` | signed OP-TEE TA | the OP-TEE TA dev kit |
26//! | `web` | HMI frontend bundle | `vp` / `npm` / `bun` |
27//!
28//! [`Compiler`] is what makes them uniform: each implementor owns its `Configuration`
29//! (all build parameters), a typed `Error`, and an `Output`. Its methods take the config
30//! rather than `&self`, so every implementor has the same `.build(cfg)` /
31//! `.output_path(&cfg)` shape and the pipeline needs no per-kind special casing.
32//!
33//! `env` holds the carriers for compile-time environment injection; `deploy` renders
34//! the deployment artifacts (currently a systemd unit).
35
36pub mod application;
37pub mod deploy;
38pub mod env;
39pub mod firmware;
40pub mod optee;
41pub(crate) mod utils;
42pub mod web;
43
44use std::path::PathBuf;
45
46/// Unified async compilation trait for firmware, application, and OP-TEE targets.
47///
48/// Each implementor owns its `Configuration` type (carries all build parameters),
49/// a typed `Error`, and an `Output` (usually `PathBuf` to the built artifact).
50///
51/// The trait methods are free functions (take `config` by value or reference) so
52/// callers can use any implementor with the same `.build(cfg)` / `.output_path(&cfg)` UX.
53pub trait Compiler: Sized {
54 /// All build parameters for this compiler.
55 type Configuration;
56
57 /// Typed error returned from build operations.
58 type Error: std::error::Error + Send + Sync + 'static;
59
60 /// The primary artifact produced (usually `PathBuf`).
61 type Output;
62
63 /// Run the full build and return the path to the primary artifact.
64 fn build(
65 config: Self::Configuration,
66 ) -> impl std::future::Future<Output = Result<Self::Output, Self::Error>> + Send;
67
68 /// Return the expected output path without building.
69 fn output_path(
70 config: &Self::Configuration,
71 ) -> impl std::future::Future<Output = Result<PathBuf, Self::Error>> + Send;
72}