Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .intentionally-empty-file.o
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
placeholder
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/fbuild-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ zccache = { git = "https://github.com/zackees/zccache", rev = "73d3f84542deb16f7
[dev-dependencies]
filetime = { workspace = true }
fbuild-test-support = { path = "../fbuild-test-support" }
async-trait = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "sync"] }
7 changes: 4 additions & 3 deletions crates/fbuild-build/src/apollo3/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Apollo3 platform build support (Ambiq Micro Apollo3 / SparkFun Artemis).
//! Apollo3 platform build support (Ambiq Micro Apollo3 / SparkFun Artemis).

pub mod mcu_config;
pub mod orchestrator;
Expand All @@ -8,15 +8,16 @@ pub use orchestrator::Apollo3Orchestrator;
/// Apollo3 platform support.
pub struct Apollo3PlatformSupport;

#[async_trait::async_trait]
impl crate::PlatformSupport for Apollo3PlatformSupport {
fn create_orchestrator(&self) -> Box<dyn crate::BuildOrchestrator> {
orchestrator::create()
}

fn install_deps(&self, project_dir: &std::path::Path) -> fbuild_core::Result<()> {
async fn install_deps(&self, project_dir: &std::path::Path) -> fbuild_core::Result<()> {
use fbuild_packages::Package;
let tc = fbuild_packages::toolchain::ArmGcc8Toolchain::new(project_dir);
Package::ensure_installed(&tc)?;
Package::ensure_installed(&tc).await?;
tracing::info!("ARM GCC 8 toolchain installed");
Ok(())
}
Expand Down
15 changes: 9 additions & 6 deletions crates/fbuild-build/src/apollo3/orchestrator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Apollo3 build orchestrator wires together config, packages, compiler, linker.
//! Apollo3 build orchestrator — wires together config, packages, compiler, linker.
//!
//! Build phases:
//! 1. Parse platformio.ini
Expand All @@ -25,36 +25,38 @@ use crate::{BuildOrchestrator, BuildParams, BuildResult, SourceScanner};
/// Apollo3 platform build orchestrator.
pub struct Apollo3Orchestrator;

#[async_trait::async_trait]
impl BuildOrchestrator for Apollo3Orchestrator {
fn platform(&self) -> Platform {
Platform::Apollo3
}

fn build(&self, params: &BuildParams) -> Result<BuildResult> {
async fn build(&self, params: &BuildParams) -> Result<BuildResult> {
let start = Instant::now();

// 1-2. Parse config, load board, setup build dirs, resolve src dir, collect flags
let mut ctx = pipeline::BuildContext::new(params)?;
let mut ctx = pipeline::BuildContext::new(params).await?;

// Compute eh_frame strip policy once per build (FastLED/fbuild#244).
let eh_frame_policy =
crate::eh_frame_policy_compute::compute_eh_frame_policy(&ctx, params.profile, None);

// 3. Ensure ARM GCC 8 toolchain (Apollo3/mbed-os requires GCC 8)
let toolchain = fbuild_packages::toolchain::ArmGcc8Toolchain::new(&params.project_dir);
let toolchain_dir = fbuild_packages::Package::ensure_installed(&toolchain)?;
let toolchain_dir = fbuild_packages::Package::ensure_installed(&toolchain).await?;
tracing::info!("arm-gcc8 toolchain at {}", toolchain_dir.display());

use fbuild_packages::Toolchain;
pipeline::log_toolchain_version(
&toolchain.get_gcc_path(),
"arm-none-eabi-gcc",
&mut ctx.build_log,
);
)
.await;

// 4. Ensure Apollo3 cores (SparkFun Arduino Apollo3 core)
let framework = fbuild_packages::library::Apollo3Cores::new(&params.project_dir);
let framework_dir = fbuild_packages::Package::ensure_installed(&framework)?;
let framework_dir = fbuild_packages::Package::ensure_installed(&framework).await?;
tracing::info!("Apollo3 cores at {}", framework_dir.display());

// 5. Scan sources (core + variant)
Expand Down Expand Up @@ -270,6 +272,7 @@ impl BuildOrchestrator for Apollo3Orchestrator {
"APOLLO3",
start,
)
.await
}
}

Expand Down
4 changes: 3 additions & 1 deletion crates/fbuild-build/src/avr/avr_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ impl AvrCompiler {
}
}

#[async_trait::async_trait]
impl Compiler for AvrCompiler {
fn compile_one(
async fn compile_one(
&self,
compiler_path: &Path,
source: &Path,
Expand All @@ -119,6 +120,7 @@ impl Compiler for AvrCompiler {
None,
&[],
)
.await
}

fn build_unflags(&self) -> &[String] {
Expand Down
18 changes: 11 additions & 7 deletions crates/fbuild-build/src/avr/avr_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,13 @@ impl AvrLinker {
}
}

#[async_trait::async_trait]
impl Linker for AvrLinker {
fn archive(&self, objects: &[PathBuf], output: &Path) -> Result<()> {
crate::linker::LinkerBase::archive(&self.ar_path, objects, output, "avr-ar")
async fn archive(&self, objects: &[PathBuf], output: &Path) -> Result<()> {
crate::linker::LinkerBase::archive(&self.ar_path, objects, output, "avr-ar").await
}

fn link(
async fn link(
&self,
objects: &[PathBuf],
archives: &[PathBuf],
Expand Down Expand Up @@ -171,7 +172,8 @@ impl Linker for AvrLinker {
&raw_objects,
&framework_archive,
"avr-gcc-ar",
)?;
)
.await?;
linker_archives.push(framework_archive);
}
linker_archives.extend(existing_archives);
Expand All @@ -184,7 +186,7 @@ impl Linker for AvrLinker {
}

let args_ref: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
let result = run_command(&args_ref, None, None, None)?;
let result = run_command(&args_ref, None, None, None).await?;

if !result.success() {
return Err(fbuild_core::FbuildError::BuildFailed(format!(
Expand All @@ -196,7 +198,7 @@ impl Linker for AvrLinker {
Ok(elf_path)
}

fn convert_firmware(&self, elf_path: &Path, output_dir: &Path) -> Result<PathBuf> {
async fn convert_firmware(&self, elf_path: &Path, output_dir: &Path) -> Result<PathBuf> {
crate::linker::LinkerBase::objcopy_firmware(
&self.objcopy_path,
elf_path,
Expand All @@ -205,6 +207,7 @@ impl Linker for AvrLinker {
&self.mcu_config.objcopy.remove_sections,
"avr-objcopy",
)
.await
}

fn size_tool_path(&self) -> &Path {
Expand All @@ -223,14 +226,15 @@ impl Linker for AvrLinker {
Some(&self.gcc_path)
}

fn report_size(&self, elf_path: &Path) -> Result<SizeInfo> {
async fn report_size(&self, elf_path: &Path) -> Result<SizeInfo> {
crate::linker::LinkerBase::report_size(
&self.size_path,
elf_path,
self.max_flash,
self.max_ram,
"avr-size",
)
.await
}
}

Expand Down
7 changes: 4 additions & 3 deletions crates/fbuild-build/src/avr/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! AVR platform build support (Arduino Uno, Mega, Nano, etc.)
//! AVR platform build support (Arduino Uno, Mega, Nano, etc.)

pub mod avr_compiler;
pub mod avr_linker;
Expand All @@ -12,15 +12,16 @@ pub use orchestrator::AvrOrchestrator;
/// AVR platform support (AtmelAvr + AtmelMegaAvr).
pub struct AvrPlatformSupport;

#[async_trait::async_trait]
impl crate::PlatformSupport for AvrPlatformSupport {
fn create_orchestrator(&self) -> Box<dyn crate::BuildOrchestrator> {
orchestrator::create()
}

fn install_deps(&self, project_dir: &std::path::Path) -> fbuild_core::Result<()> {
async fn install_deps(&self, project_dir: &std::path::Path) -> fbuild_core::Result<()> {
use fbuild_packages::Package;
let tc = fbuild_packages::toolchain::AvrToolchain::new(project_dir);
Package::ensure_installed(&tc)?;
Package::ensure_installed(&tc).await?;
tracing::info!("AVR toolchain installed");
Ok(())
}
Expand Down
32 changes: 18 additions & 14 deletions crates/fbuild-build/src/avr/orchestrator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! AVR build orchestrator wires together config, packages, compiler, linker.
//! AVR build orchestrator — wires together config, packages, compiler, linker.
//!
//! Build phases:
//! 1. Parse platformio.ini
Expand Down Expand Up @@ -38,7 +38,7 @@ pub struct AvrOrchestrator;
/// Any field that can change the produced firmware belongs here;
/// a change flips the hash and forces a full rebuild. Keep this in
/// sync with what [`AvrCompiler`] / [`AvrLinker`] actually read off
/// of `BoardConfig` extra fields only cost a tiny amount of CPU,
/// of `BoardConfig` — extra fields only cost a tiny amount of CPU,
/// but missing fields silently let stale artifacts get reused.
#[derive(Debug, Serialize)]
struct AvrFingerprintMetadata {
Expand Down Expand Up @@ -67,17 +67,18 @@ fn profile_label(profile: fbuild_core::BuildProfile) -> &'static str {
}
}

#[async_trait::async_trait]
impl BuildOrchestrator for AvrOrchestrator {
fn platform(&self) -> Platform {
Platform::AtmelAvr
}

fn build(&self, params: &BuildParams) -> Result<BuildResult> {
async fn build(&self, params: &BuildParams) -> Result<BuildResult> {
let start = Instant::now();
// Env-gated per-phase timer (FBUILD_PERF_LOG=1); zero-overhead when unset.
let mut perf = crate::perf_log::PerfTimer::new("avr-orchestrator");

// Wrapper-binary discovery removed in FastLED/fbuild#800 every
// Wrapper-binary discovery removed in FastLED/fbuild#800 — every
// compile dispatches through the embedded zccache service. The
// `compiler_cache: Option<PathBuf>` slot is retained as a dead
// pass-through for the per-platform compiler API until a future
Expand All @@ -88,7 +89,7 @@ impl BuildOrchestrator for AvrOrchestrator {
// collect flags. `new_with_perf` records its own sub-phases
// (config-parse, board-load, build-dirs, flag-collect) into
// the shared `perf` timer.
let mut ctx = pipeline::BuildContext::new_with_perf(params, Some(&mut perf))?;
let mut ctx = pipeline::BuildContext::new_with_perf(params, Some(&mut perf)).await?;

// Compute eh_frame strip policy once per build (FastLED/fbuild#244).
// No sdkconfig on AVR.
Expand All @@ -99,13 +100,14 @@ impl BuildOrchestrator for AvrOrchestrator {
let (toolchain, toolchain_dir) = {
let _g = perf.phase("toolchain-ensure");
let toolchain = fbuild_packages::toolchain::AvrToolchain::new(&params.project_dir);
let toolchain_dir = fbuild_packages::Package::ensure_installed(&toolchain)?;
let toolchain_dir = fbuild_packages::Package::ensure_installed(&toolchain).await?;
(toolchain, toolchain_dir)
};
tracing::info!("avr-gcc toolchain at {}", toolchain_dir.display());

use fbuild_packages::Toolchain as _;
pipeline::log_toolchain_version(&toolchain.get_gcc_path(), "avr-gcc", &mut ctx.build_log);
pipeline::log_toolchain_version(&toolchain.get_gcc_path(), "avr-gcc", &mut ctx.build_log)
.await;

// 4. Ensure Arduino core
let (_framework_dir, core_dir, variant_dir) = {
Expand All @@ -115,7 +117,8 @@ impl BuildOrchestrator for AvrOrchestrator {
&ctx.board.core,
&ctx.board.variant,
ctx.board.platform(),
)?
)
.await?
};

// 4.5. Warm-build fast path.
Expand Down Expand Up @@ -211,7 +214,7 @@ impl BuildOrchestrator for AvrOrchestrator {

// 6. Build include dirs + compiler
let defines = ctx.board.get_defines();
// Use the resolved core_dir/variant_dir directly board.get_include_paths()
// Use the resolved core_dir/variant_dir directly — board.get_include_paths()
// uses the raw board core name which may differ from the actual directory
// (e.g. MiniCore's core dir is "MCUdude_corefiles", not "MiniCore").
let mut include_dirs = vec![core_dir.clone(), variant_dir.clone()];
Expand All @@ -236,7 +239,7 @@ impl BuildOrchestrator for AvrOrchestrator {
.with_build_unflags(ctx.build_unflags.clone())
.with_eh_frame_policy(eh_frame_policy);

// 7. Create linker pass gcc-ar so framework .o inputs can be
// 7. Create linker — pass gcc-ar so framework .o inputs can be
// archived into libframework.a with the LTO bytecode plugin index
// intact (preserves `-fuse-linker-plugin`). See FastLED/fbuild#304.
let linker = AvrLinker::new(
Expand Down Expand Up @@ -286,11 +289,12 @@ impl BuildOrchestrator for AvrOrchestrator {
TargetArchitecture::Avr,
"AVR",
start,
)?;
)
.await?;

// 10. Persist fingerprint so the next warm invocation can hit the
// fast path. Skip this for compile-db-only / symbol-analysis runs
// they don't produce the full artifact set the fast path
// — they don't produce the full artifact set the fast path
// requires.
if build_result.success
&& !params.compiledb_only
Expand Down Expand Up @@ -325,7 +329,7 @@ pub fn create() -> Box<dyn BuildOrchestrator> {
/// to `"arduino_megaavr"` so they get `ArduinoCore-megaavr` (which contains the
/// megaAVR variants like `nona4809`) instead of `ArduinoCore-avr`.
/// Returns (framework_root, core_dir, variant_dir).
fn ensure_avr_framework(
async fn ensure_avr_framework(
project_dir: &Path,
core_name: &str,
variant_name: &str,
Expand All @@ -343,7 +347,7 @@ fn ensure_avr_framework(
};

let framework = fbuild_packages::library::AvrFramework::for_core(lookup_key, project_dir)?;
let framework_dir = framework.ensure_installed()?;
let framework_dir = framework.ensure_installed().await?;
tracing::info!(
"AVR framework for core '{}' (lookup '{}') at {}",
core_name,
Expand Down
4 changes: 3 additions & 1 deletion crates/fbuild-build/src/ch32v/ch32v_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ fn framework_suppression_flags() -> &'static [&'static str] {
&["-w"]
}

#[async_trait::async_trait]
impl Compiler for Ch32vCompiler {
fn compile_one(
async fn compile_one(
&self,
compiler_path: &Path,
source: &Path,
Expand Down Expand Up @@ -166,6 +167,7 @@ impl Compiler for Ch32vCompiler {
None,
&[],
)
.await
}

fn gcc_path(&self) -> &Path {
Expand Down
Loading
Loading