1
Fork 0

Create a generic AVR target: avr-none

This commit removes the `avr-unknown-gnu-atmega328` target and replaces
it with a more generic `avr-none` variant that must be specialized with
the `-C target-cpu` flag (e.g. `-C target-cpu=atmega328p`).
This commit is contained in:
Patryk Wychowaniec 2024-10-13 14:58:44 +02:00
parent ed49386d3a
commit 78ddabf31d
No known key found for this signature in database
GPG key ID: F62547D075E09767
19 changed files with 156 additions and 60 deletions

View file

@ -1990,6 +1990,7 @@ fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor)
if let Some(args) = sess.target.pre_link_args.get(&flavor) {
cmd.verbatim_args(args.iter().map(Deref::deref));
}
cmd.verbatim_args(&sess.opts.unstable_opts.pre_link_args);
}

View file

@ -153,6 +153,7 @@ pub(crate) fn get_linker<'a>(
hinted_static: None,
is_ld: cc == Cc::No,
is_gnu: flavor.is_gnu(),
uses_lld: flavor.uses_lld(),
}) as Box<dyn Linker>,
LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
@ -361,6 +362,7 @@ struct GccLinker<'a> {
// Link as ld
is_ld: bool,
is_gnu: bool,
uses_lld: bool,
}
impl<'a> GccLinker<'a> {
@ -552,6 +554,7 @@ impl<'a> Linker for GccLinker<'a> {
self.link_args(&["--entry", "_initialize"]);
}
}
// VxWorks compiler driver introduced `--static-crt` flag specifically for rustc,
// it switches linking for libc and similar system libraries to static without using
// any `#[link]` attributes in the `libc` crate, see #72782 for details.
@ -567,6 +570,15 @@ impl<'a> Linker for GccLinker<'a> {
{
self.cc_arg("--static-crt");
}
// avr-none doesn't have default ISA, users must specify which specific
// CPU (well, microcontroller) they are targetting using `-Ctarget-cpu`.
//
// Currently this makes sense only when using avr-gcc as a linker, since
// it brings a couple of hand-written important intrinsics from libgcc.
if self.sess.target.arch == "avr" && !self.uses_lld {
self.verbatim_arg(format!("-mmcu={}", self.target_cpu));
}
}
fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, as_needed: bool) {

View file

@ -1,45 +1,5 @@
use object::elf;
use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions};
/// A base target for AVR devices using the GNU toolchain.
///
/// Requires GNU avr-gcc and avr-binutils on the host system.
/// FIXME: Remove the second parameter when const string concatenation is possible.
pub(crate) fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
Target {
arch: "avr".into(),
metadata: crate::spec::TargetMetadata {
description: None,
tier: None,
host_tools: None,
std: None,
},
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(),
llvm_target: "avr-unknown-unknown".into(),
pointer_width: 16,
options: TargetOptions {
env: "gnu".into(),
c_int_width: "16".into(),
cpu: target_cpu.into(),
exe_suffix: ".elf".into(),
linker: Some("avr-gcc".into()),
eh_frame_header: false,
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]),
late_link_args: TargetOptions::link_args(
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&["-lgcc"],
),
max_atomic_width: Some(16),
atomic_cas: false,
relocation_model: RelocModel::Static,
..TargetOptions::default()
},
}
}
/// Resolve the value of the EF_AVR_ARCH field for AVR ELF files, given the
/// name of the target CPU / MCU.
///

View file

@ -1,7 +1,7 @@
pub(crate) mod aix;
pub(crate) mod android;
pub(crate) mod apple;
pub(crate) mod avr_gnu;
pub(crate) mod avr;
pub(crate) mod bpf;
pub(crate) mod cygwin;
pub(crate) mod dragonfly;

View file

@ -60,7 +60,7 @@ pub mod crt_objects;
mod base;
mod json;
pub use base::avr_gnu::ef_avr_arch;
pub use base::avr::ef_avr_arch;
/// Linker is called through a C/C++ compiler.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@ -1797,7 +1797,7 @@ supported_targets! {
("riscv64gc-unknown-fuchsia", riscv64gc_unknown_fuchsia),
("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia),
("avr-unknown-gnu-atmega328", avr_unknown_gnu_atmega328),
("avr-none", avr_none),
("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc),
@ -3062,7 +3062,10 @@ impl Target {
&self.post_link_args,
] {
for (&flavor, flavor_args) in args {
check!(!flavor_args.is_empty(), "linker flavor args must not be empty");
check!(
!flavor_args.is_empty() || self.arch == "avr",
"linker flavor args must not be empty"
);
// Check that flavors mentioned in link args are compatible with the default flavor.
match self.linker_flavor {
LinkerFlavor::Gnu(..) => {

View file

@ -0,0 +1,32 @@
use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions};
pub(crate) fn target() -> Target {
Target {
arch: "avr".into(),
metadata: crate::spec::TargetMetadata {
description: None,
tier: None,
host_tools: None,
std: None,
},
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(),
llvm_target: "avr-unknown-unknown".into(),
pointer_width: 16,
options: TargetOptions {
c_int_width: "16".into(),
exe_suffix: ".elf".into(),
linker: Some("avr-gcc".into()),
eh_frame_header: false,
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[]),
late_link_args: TargetOptions::link_args(
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&["-lgcc"],
),
max_atomic_width: Some(16),
atomic_cas: false,
relocation_model: RelocModel::Static,
need_explicit_cpu: true,
..TargetOptions::default()
},
}
}

View file

@ -1,5 +0,0 @@
use crate::spec::{Target, base};
pub(crate) fn target() -> Target {
base::avr_gnu::target("atmega328", "-mmcu=atmega328")
}