[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.
This commit is contained in:
Dylan McKay 2020-07-26 23:58:37 +12:00
parent c4b6d9411f
commit d785f9ba76
4 changed files with 41 additions and 18 deletions

View File

@ -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()
},
})
}

View File

@ -0,0 +1,5 @@
use crate::spec::TargetResult;
pub fn target() -> TargetResult {
super::avr_gnu_base::target("atmega328".to_owned())
}

View File

@ -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(),
})
}

View File

@ -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),