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
80 changes: 70 additions & 10 deletions crates/fbuild-build/src/avr/avr_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,19 @@ impl AvrLinker {
}
}

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

fn link(
impl AvrLinker {
/// Build the argv that will be passed to `avr-gcc` for the link step.
///
/// Factored out so it can be unit-tested without invoking the toolchain
/// (see #305 — assert that `-Wl,-Map=` is present).
fn build_link_args(
&self,
objects: &[PathBuf],
archives: &[PathBuf],
output_dir: &Path,
elf_path: &Path,
extra: &LinkExtraArgs,
) -> Result<PathBuf> {
std::fs::create_dir_all(output_dir)?;
let elf_path = output_dir.join("firmware.elf");

) -> Vec<String> {
let mut args: Vec<String> = vec![
self.gcc_path.to_string_lossy().to_string(),
format!("-mmcu={}", self.mcu),
Expand All @@ -85,6 +83,10 @@ impl Linker for AvrLinker {

args.extend(["-o".to_string(), elf_path.to_string_lossy().to_string()]);

// Always emit a linker map next to firmware.elf for debugging (#305).
let map_path = output_dir.join("firmware.map");
args.push(format!("-Wl,-Map={}", map_path.to_string_lossy()));

// Sketch objects first
for obj in objects {
args.push(obj.to_string_lossy().to_string());
Expand All @@ -102,7 +104,29 @@ impl Linker for AvrLinker {
args.extend(extra.libs.iter().cloned());
args.push("-Wl,--end-group".to_string());

args
}
}

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

fn link(
&self,
objects: &[PathBuf],
archives: &[PathBuf],
output_dir: &Path,
extra: &LinkExtraArgs,
) -> Result<PathBuf> {
std::fs::create_dir_all(output_dir)?;
let elf_path = output_dir.join("firmware.elf");

let args = self.build_link_args(objects, archives, output_dir, &elf_path, extra);

if self.verbose {
eprintln!("link: {}", args.join(" "));
tracing::info!("link: {}", args.join(" "));
}

Expand Down Expand Up @@ -168,4 +192,40 @@ mod tests {
assert_eq!(linker.max_flash, Some(32256));
assert_eq!(linker.max_ram, Some(2048));
}

/// #305: every per-platform linker must emit a `firmware.map` next to
/// `firmware.elf`. Assert the generated argv contains a `-Wl,-Map=` token.
#[test]
fn test_avr_link_args_contain_map_flag() {
let linker = AvrLinker::new(
PathBuf::from("/bin/avr-gcc"),
PathBuf::from("/bin/avr-ar"),
PathBuf::from("/bin/avr-objcopy"),
PathBuf::from("/bin/avr-size"),
"atmega328p",
get_avr_config().unwrap(),
BuildProfile::Release,
Some(32256),
Some(2048),
false,
);

let tmp = tempfile::TempDir::new().unwrap();
let output_dir = tmp.path();
let elf_path = output_dir.join("firmware.elf");
let extra = LinkExtraArgs::default();
let args = linker.build_link_args(&[], &[], output_dir, &elf_path, &extra);

let map_flag = args
.iter()
.find(|a| a.starts_with("-Wl,-Map="))
.expect("link args must contain -Wl,-Map= for firmware.map emission");
let expected_map = output_dir.join("firmware.map");
assert!(
map_flag.contains(&*expected_map.to_string_lossy()),
"expected map flag to reference {}, got {}",
expected_map.display(),
map_flag
);
}
}
5 changes: 5 additions & 0 deletions crates/fbuild-build/src/ch32v/ch32v_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ impl Linker for Ch32vLinker {
elf_path.to_string_lossy().to_string(),
]);

// Always emit a linker map next to firmware.elf for debugging (#305).
let map_path = output_dir.join("firmware.map");
args.push(format!("-Wl,-Map={}", map_path.to_string_lossy()));

// Sketch objects first
for obj in objects {
args.push(obj.to_string_lossy().to_string());
Expand All @@ -101,6 +105,7 @@ impl Linker for Ch32vLinker {
args.extend(extra.libs.iter().cloned());

if self.verbose {
eprintln!("link: {}", args.join(" "));
tracing::info!("link: {}", args.join(" "));
}

Expand Down
5 changes: 5 additions & 0 deletions crates/fbuild-build/src/esp8266/esp8266_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ impl Linker for Esp8266Linker {

args.extend(["-o".to_string(), elf_path.to_string_lossy().to_string()]);

// Always emit a linker map next to firmware.elf for debugging (#305).
let map_path = output_dir.join("firmware.map");
args.push(format!("-Wl,-Map={}", map_path.to_string_lossy()));

// Sketch objects first
for obj in objects {
args.push(obj.to_string_lossy().to_string());
Expand All @@ -216,6 +220,7 @@ impl Linker for Esp8266Linker {
args.push("-Wl,--end-group".to_string());

if self.verbose {
eprintln!("link: {}", args.join(" "));
tracing::info!("link: {}", args.join(" "));
}

Expand Down
5 changes: 5 additions & 0 deletions crates/fbuild-build/src/generic_arm/arm_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ impl Linker for ArmLinker {
elf_path.to_string_lossy().to_string(),
]);

// Always emit a linker map next to firmware.elf for debugging (#305).
let map_path = output_dir.join("firmware.map");
args.push(format!("-Wl,-Map={}", map_path.to_string_lossy()));

// Sketch objects first
for obj in objects {
args.push(obj.to_string_lossy().to_string());
Expand All @@ -101,6 +105,7 @@ impl Linker for ArmLinker {
args.extend(extra.libs.iter().cloned());

if self.verbose {
eprintln!("link: {}", args.join(" "));
tracing::info!("link: {}", args.join(" "));
}

Expand Down
5 changes: 5 additions & 0 deletions crates/fbuild-build/src/nrf52/nrf52_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ impl Linker for Nrf52Linker {
elf_path.to_string_lossy().to_string(),
]);

// Always emit a linker map next to firmware.elf for debugging (#305).
let map_path = output_dir.join("firmware.map");
args.push(format!("-Wl,-Map={}", map_path.to_string_lossy()));

// Sketch objects first
for obj in objects {
args.push(obj.to_string_lossy().to_string());
Expand All @@ -109,6 +113,7 @@ impl Linker for Nrf52Linker {
args.extend(extra.libs.iter().cloned());

if self.verbose {
eprintln!("link: {}", args.join(" "));
tracing::info!("link: {}", args.join(" "));
}

Expand Down
5 changes: 5 additions & 0 deletions crates/fbuild-build/src/renesas/renesas_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ impl Linker for RenesasLinker {
elf_path.to_string_lossy().to_string(),
]);

// Always emit a linker map next to firmware.elf for debugging (#305).
let map_path = output_dir.join("firmware.map");
args.push(format!("-Wl,-Map={}", map_path.to_string_lossy()));

// Sketch objects first
for obj in objects {
args.push(obj.to_string_lossy().to_string());
Expand All @@ -114,6 +118,7 @@ impl Linker for RenesasLinker {
args.extend(extra.libs.iter().cloned());

if self.verbose {
eprintln!("link: {}", args.join(" "));
tracing::info!("link: {}", args.join(" "));
}

Expand Down
5 changes: 5 additions & 0 deletions crates/fbuild-build/src/sam/sam_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ impl Linker for SamLinker {
elf_path.to_string_lossy().to_string(),
]);

// Always emit a linker map next to firmware.elf for debugging (#305).
let map_path = output_dir.join("firmware.map");
args.push(format!("-Wl,-Map={}", map_path.to_string_lossy()));

// Sketch objects first
for obj in objects {
args.push(obj.to_string_lossy().to_string());
Expand Down Expand Up @@ -130,6 +134,7 @@ impl Linker for SamLinker {
args.extend(extra.libs.iter().cloned());

if self.verbose {
eprintln!("link: {}", args.join(" "));
tracing::info!("link: {}", args.join(" "));
}

Expand Down
5 changes: 5 additions & 0 deletions crates/fbuild-build/src/silabs/silabs_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ impl Linker for SilabsLinker {
elf_path.to_string_lossy().to_string(),
]);

// Always emit a linker map next to firmware.elf for debugging (#305).
let map_path = output_dir.join("firmware.map");
args.push(format!("-Wl,-Map={}", map_path.to_string_lossy()));

// Sketch objects first
for obj in objects {
args.push(obj.to_string_lossy().to_string());
Expand All @@ -117,6 +121,7 @@ impl Linker for SilabsLinker {
args.push("-Wl,--end-group".to_string());

if self.verbose {
eprintln!("link: {}", args.join(" "));
tracing::info!("link: {}", args.join(" "));
}

Expand Down
5 changes: 5 additions & 0 deletions crates/fbuild-build/src/teensy/teensy_linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ impl Linker for TeensyLinker {
args.extend(self.linker_scripts.to_args());
args.extend(["-o".to_string(), elf_path.to_string_lossy().to_string()]);

// Always emit a linker map next to firmware.elf for debugging (#305).
let map_path = output_dir.join("firmware.map");
args.push(format!("-Wl,-Map={}", map_path.to_string_lossy()));

// Sketch objects first
for obj in objects {
args.push(obj.to_string_lossy().to_string());
Expand All @@ -98,6 +102,7 @@ impl Linker for TeensyLinker {
args.extend(extra.libs.iter().cloned());

if self.verbose {
eprintln!("link: {}", args.join(" "));
tracing::info!("link: {}", args.join(" "));
}

Expand Down
Loading