From d785f9ba76be199a47652f5841260a42390f611b Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Sun, 26 Jul 2020 23:58:37 +1200 Subject: [PATCH] [AVR] Replace broken 'avr-unknown-unknown' target with 'avr-unknown-gnu-atmega328' target The `avr-unknown-unknown` target has never worked correctly, always trying to invoke the host linker and failing. It aimed to be a mirror of AVR-GCC's default handling of the `avr-unknown-unknown' triple (assume bare minimum chip features, silently skip linking runtime libraries, etc). This behaviour is broken-by-default as it will cause a miscompiled executable when flashed. This patch improves the AVR builtin target specifications to instead expose only a 'avr-unknown-gnu-atmega328' target. This target system is `gnu`, as it uses the AVR-GCC frontend along with avr-binutils. The target triple ABI is 'atmega328'. In the future, it should be possible to replace the dependency on AVR-GCC and binutils by using the in-progress AVR LLD and compiler-rt support. Perhaps at that point it would make sense to add an 'avr-unknown-unknown-atmega328' target as a better default when implemented. There is no current intention to add in-tree AVR target specifications for other AVR microcontrollers - this one can serve as a reference implementation for other devices via `rustc --print target-spec-json avr-unknown-gnu-atmega328p`. There should be no users of the existing 'avr-unknown-unknown' Rust target as a custom target specification JSON has always been recommended, and the avr-unknown-unknown target could never pass the linking step anyway. --- src/librustc_target/spec/avr_gnu_base.rs | 34 +++++++++++++++++++ .../spec/avr_unknown_gnu_atmega328.rs | 5 +++ .../spec/avr_unknown_unknown.rs | 17 ---------- src/librustc_target/spec/mod.rs | 3 +- 4 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 src/librustc_target/spec/avr_gnu_base.rs create mode 100644 src/librustc_target/spec/avr_unknown_gnu_atmega328.rs delete mode 100644 src/librustc_target/spec/avr_unknown_unknown.rs diff --git a/src/librustc_target/spec/avr_gnu_base.rs b/src/librustc_target/spec/avr_gnu_base.rs new file mode 100644 index 00000000000..5fcaaaacbee --- /dev/null +++ b/src/librustc_target/spec/avr_gnu_base.rs @@ -0,0 +1,34 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +/// A base target for AVR devices using the GNU toolchain. +/// +/// Requires GNU avr-gcc and avr-binutils on the host system. +pub fn target(target_cpu: String) -> TargetResult { + Ok(Target { + arch: "avr".to_string(), + data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".to_string(), + llvm_target: "avr-unknown-unknown".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "16".to_string(), + linker_flavor: LinkerFlavor::Gcc, + target_os: "unknown".to_string(), + target_env: "".to_string(), + target_vendor: "unknown".to_string(), + target_c_int_width: 16.to_string(), + options: TargetOptions { + cpu: target_cpu.clone(), + exe_suffix: ".elf".to_string(), + linker: Some("avr-gcc".to_owned()), + pre_link_args: vec![( + LinkerFlavor::Gcc, + vec!["-Os".to_owned(), format!("-mmcu={}", target_cpu)], + )] + .into_iter() + .collect(), + late_link_args: vec![(LinkerFlavor::Gcc, vec!["-lc".to_owned(), "-lgcc".to_owned()])] + .into_iter() + .collect(), + ..super::freestanding_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/avr_unknown_gnu_atmega328.rs b/src/librustc_target/spec/avr_unknown_gnu_atmega328.rs new file mode 100644 index 00000000000..5d22598b57b --- /dev/null +++ b/src/librustc_target/spec/avr_unknown_gnu_atmega328.rs @@ -0,0 +1,5 @@ +use crate::spec::TargetResult; + +pub fn target() -> TargetResult { + super::avr_gnu_base::target("atmega328".to_owned()) +} diff --git a/src/librustc_target/spec/avr_unknown_unknown.rs b/src/librustc_target/spec/avr_unknown_unknown.rs deleted file mode 100644 index f90a8def0aa..00000000000 --- a/src/librustc_target/spec/avr_unknown_unknown.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::spec::{LinkerFlavor, Target, TargetResult}; - -pub fn target() -> TargetResult { - Ok(Target { - llvm_target: "avr-unknown-unknown".to_string(), - target_endian: "little".to_string(), - target_pointer_width: "16".to_string(), - data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".to_string(), - arch: "avr".to_string(), - linker_flavor: LinkerFlavor::Gcc, - target_os: "unknown".to_string(), - target_env: "".to_string(), - target_vendor: "unknown".to_string(), - target_c_int_width: 16.to_string(), - options: super::freestanding_base::opts(), - }) -} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index fa29ff3f8d8..b16351c063a 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -51,6 +51,7 @@ mod android_base; mod apple_base; mod apple_sdk_base; mod arm_base; +mod avr_gnu_base; mod cloudabi_base; mod dragonfly_base; mod freebsd_base; @@ -581,7 +582,7 @@ supported_targets! { ("aarch64-fuchsia", aarch64_fuchsia), ("x86_64-fuchsia", x86_64_fuchsia), - ("avr-unknown-unknown", avr_unknown_unknown), + ("avr-unknown-gnu-atmega328", avr_unknown_gnu_atmega328), ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc),