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 Cargo.lock

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

1 change: 1 addition & 0 deletions crates/fbuild-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ tempfile = { workspace = true }
filetime = { workspace = true }
fbuild-test-support = { path = "../fbuild-test-support" }
tar = { workspace = true }
object = { workspace = true }
7 changes: 6 additions & 1 deletion crates/fbuild-build/src/apollo3/orchestrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ impl BuildOrchestrator for Apollo3Orchestrator {
// 1-2. Parse config, load board, setup build dirs, resolve src dir, collect flags
let mut ctx = pipeline::BuildContext::new(params)?;

// 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)?;
Expand Down Expand Up @@ -182,7 +186,8 @@ impl BuildOrchestrator for Apollo3Orchestrator {
params.profile,
params.verbose,
)
.with_build_unflags(ctx.build_unflags.clone());
.with_build_unflags(ctx.build_unflags.clone())
.with_eh_frame_policy(eh_frame_policy);

// 8. Create linker
let linker_script = framework.get_linker_script();
Expand Down
39 changes: 39 additions & 0 deletions crates/fbuild-build/src/avr/avr_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use fbuild_core::{BuildProfile, Result};

use super::mcu_config::AvrMcuConfig;
use crate::compiler::{CompileResult, Compiler, CompilerBase};
use crate::eh_frame_policy::EhFramePolicy;

/// AVR-specific compiler using avr-gcc and avr-g++.
pub struct AvrCompiler {
Expand All @@ -22,6 +23,10 @@ pub struct AvrCompiler {
/// PlatformIO `build_unflags` to strip from the effective compile
/// line. See FastLED/fbuild#37.
build_unflags: Vec<String>,
/// Whether to strip eh_frame unwinding tables. Default `Preserve` so existing
/// callers see no behavior change; orchestrators set this via
/// [`Self::with_eh_frame_policy`]. See FastLED/fbuild#244.
eh_frame_policy: EhFramePolicy,
}

impl AvrCompiler {
Expand Down Expand Up @@ -51,6 +56,7 @@ impl AvrCompiler {
profile,
temp_dir: fbuild_core::response_file::windows_temp_dir(),
build_unflags: Vec::new(),
eh_frame_policy: EhFramePolicy::default(),
}
}

Expand All @@ -61,6 +67,13 @@ impl AvrCompiler {
self
}

/// Attach the eh_frame strip/preserve policy decided by the orchestrator.
/// Default `Preserve` keeps existing behavior. See FastLED/fbuild#244.
pub fn with_eh_frame_policy(mut self, policy: EhFramePolicy) -> Self {
self.eh_frame_policy = policy;
self
}

/// Build the common AVR compiler flags.
fn common_flags(&self) -> Vec<String> {
let mut flags = vec![format!("-mmcu={}", self.base.mcu)];
Expand All @@ -73,6 +86,14 @@ impl AvrCompiler {

flags.extend(self.base.build_define_flags());
flags.extend(self.base.build_include_flags());

if matches!(self.eh_frame_policy, EhFramePolicy::Strip) {
flags.extend(
crate::eh_frame_policy::STRIP_FLAGS
.iter()
.map(|s| s.to_string()),
);
}
flags
}
}
Expand Down Expand Up @@ -198,4 +219,22 @@ mod tests {
assert!(flags.contains(&"-std=gnu++11".to_string()));
assert!(flags.contains(&"-fno-exceptions".to_string()));
}

/// FastLED/fbuild#244: default policy must not leak STRIP_FLAGS.
#[test]
fn cpp_flags_preserve_eh_frame_by_default() {
let compiler = test_compiler();
let flags = compiler.cpp_flags();
assert!(!flags.iter().any(|f| f == "-fno-asynchronous-unwind-tables"));
assert!(!flags.iter().any(|f| f == "-fno-unwind-tables"));
}

/// FastLED/fbuild#244: Strip policy must inject both unwind-table flags.
#[test]
fn cpp_flags_strip_eh_frame_when_policy_set() {
let compiler = test_compiler().with_eh_frame_policy(EhFramePolicy::Strip);
let flags = compiler.cpp_flags();
assert!(flags.iter().any(|f| f == "-fno-asynchronous-unwind-tables"));
assert!(flags.iter().any(|f| f == "-fno-unwind-tables"));
}
}
13 changes: 12 additions & 1 deletion crates/fbuild-build/src/avr/orchestrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ struct AvrFingerprintMetadata {
platform: String,
max_flash: Option<u64>,
max_ram: Option<u64>,
eh_frame_policy: &'static str,
}

fn profile_label(profile: fbuild_core::BuildProfile) -> &'static str {
Expand Down Expand Up @@ -90,6 +91,11 @@ impl BuildOrchestrator for AvrOrchestrator {
// the shared `perf` timer.
let mut ctx = pipeline::BuildContext::new_with_perf(params, Some(&mut perf))?;

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

Comment thread
coderabbitai[bot] marked this conversation as resolved.
// 3. Ensure toolchain
let (toolchain, toolchain_dir) = {
let _g = perf.phase("toolchain-ensure");
Expand Down Expand Up @@ -138,6 +144,10 @@ impl BuildOrchestrator for AvrOrchestrator {
platform: "atmelavr".to_string(),
max_flash: ctx.board.max_flash,
max_ram: ctx.board.max_ram,
eh_frame_policy: match eh_frame_policy {
crate::eh_frame_policy::EhFramePolicy::Strip => "strip",
crate::eh_frame_policy::EhFramePolicy::Preserve => "preserve",
},
})?;
let (fast_elf, [fast_hex], fast_compile_db) =
expected_fast_path_artifacts(build_dir, &params.project_dir, ["firmware.hex"]);
Expand Down Expand Up @@ -224,7 +234,8 @@ impl BuildOrchestrator for AvrOrchestrator {
params.profile,
params.verbose,
)
.with_build_unflags(ctx.build_unflags.clone());
.with_build_unflags(ctx.build_unflags.clone())
.with_eh_frame_policy(eh_frame_policy);

// 7. Create linker
let linker = AvrLinker::new(
Expand Down
Loading
Loading