Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new tier-3 target: armv7-unknown-linux-uclibceabihf #88952

Merged
merged 3 commits into from
Oct 10, 2021
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
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1879,9 +1879,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"

[[package]]
name = "libc"
version = "0.2.99"
version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
dependencies = [
"rustc-std-workspace-core",
]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
// should use dllimport for functions.
if cx.use_dll_storage_attrs
&& tcx.is_dllimport_foreign_item(instance_def_id)
&& tcx.sess.target.env != "gnu"
&& !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc")
{
llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3009,7 +3009,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
};

let target = &self.tcx.sess.target;
let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl");
let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc");
let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
let linux_s390x_gnu_like =
target.os == "linux" && target.arch == "s390x" && target_env_gnu_like;
Expand Down Expand Up @@ -3107,7 +3107,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
if arg.layout.is_zst() {
// For some forsaken reason, x86_64-pc-windows-gnu
// doesn't ignore zero-sized struct arguments.
// The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl}.
// The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc}.
if is_return
|| rust_abi
|| (!win_x64_gnu
Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::spec::{Target, TargetOptions};
Mark-Simulacrum marked this conversation as resolved.
Show resolved Hide resolved

// This target is for uclibc Linux on ARMv7 without NEON or
// thumb-mode. See the thumbv7neon variant for enabling both.

pub fn target() -> Target {
let base = super::linux_uclibc_base::opts();
Target {
llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
nagisa marked this conversation as resolved.
Show resolved Hide resolved
pointer_width: 32,
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),

options: TargetOptions {
// Info about features at https://wiki.debian.org/ArmHardFloatPort
skrap marked this conversation as resolved.
Show resolved Hide resolved
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
cpu: "generic".to_string(),
max_atomic_width: Some(64),
mcount: "_mcount".to_string(),
abi: "eabihf".to_string(),
..base
},
}
}
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,8 @@ supported_targets! {
("bpfel-unknown-none", bpfel_unknown_none),

("armv6k-nintendo-3ds", armv6k_nintendo_3ds),

("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf),
}

/// Warnings encountered when parsing the target `json`.
Expand Down
2 changes: 1 addition & 1 deletion library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core" }
libc = { version = "0.2.99", default-features = false, features = ['rustc-dep-of-std'] }
libc = { version = "0.2.103", default-features = false, features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.44" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ cfg_if::cfg_if! {
#[link(name = "zircon")]
#[link(name = "fdio")]
extern "C" {}
} else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] {
#[link(name = "dl")]
extern "C" {}
}
}

Expand Down
3 changes: 2 additions & 1 deletion library/std/src/sys/unix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,8 @@ pub mod guard {
Some(stackaddr - guardsize..stackaddr)
} else if cfg!(all(target_os = "linux", target_env = "musl")) {
Some(stackaddr - guardsize..stackaddr)
} else if cfg!(all(target_os = "linux", target_env = "gnu")) {
} else if cfg!(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))
nagisa marked this conversation as resolved.
Show resolved Hide resolved
{
// glibc used to include the guard area within the stack, as noted in the BUGS
// section of `man pthread_attr_getguardsize`. This has been corrected starting
// with glibc 2.27, and in some distro backports, so the guard is now placed at the
Expand Down
4 changes: 2 additions & 2 deletions library/unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ cfg_if::cfg_if! {
// don't want to duplicate it here.
#[cfg(all(
target_os = "linux",
target_env = "gnu",
any(target_env = "gnu", target_env = "uclibc"),
not(feature = "llvm-libunwind"),
not(feature = "system-llvm-libunwind")
))]
Expand All @@ -72,7 +72,7 @@ extern "C" {}

#[cfg(all(
target_os = "linux",
target_env = "gnu",
any(target_env = "gnu", target_env = "uclibc"),
not(feature = "llvm-libunwind"),
feature = "system-llvm-libunwind"
))]
Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ target | std | host | notes
`armv6-unknown-netbsd-eabihf` | ? | |
`armv6k-nintendo-3ds` | * | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
`armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8
`armv7-unknown-linux-uclibceabihf` | ✓ | ? | ARMv7 Linux uClibc
`armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
`armv7-unknown-netbsd-eabihf` | ✓ | ✓ |
`armv7-wrs-vxworks-eabihf` | ? | |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# armv7-unknown-linux-uclibceabihf

**Tier: 3**

This tier supports the ARMv7 processor running a Linux kernel and uClibc-ng standard library. It provides full support for rust and the rust standard library.

## Designated Developers

* [@skrap](https://github.com/skrap)

## Requirements

This target is cross compiled, and requires a cross toolchain. You can find suitable pre-built toolchains at [bootlin](https://toolchains.bootlin.com/) or build one yourself via [buildroot](https://buildroot.org).

## Building

### Get a C toolchain

Compiling rust for this target has been tested on `x86_64` linux hosts. Other host types have not been tested, but may work, if you can find a suitable cross compilation toolchain for them.

If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2020.08-1.tar.bz2), and unpack it into a directory.

### Configure rust

The target can be built by enabling it for a `rustc` build, by placing the following in `config.toml`:

```toml
[build]
target = ["armv7-unknown-linux-uclibceabihf"]
stage = 2

[target.armv7-unknown-linux-uclibceabihf]
# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN
cc = "/TOOLCHAIN_PATH/bin/arm-buildroot-linux-uclibcgnueabihf-gcc"
```

### Build

```sh
# in rust dir
./x.py build --stage 2
```

## Building and Running Rust Programs

To test cross-compiled binaries on a `x86_64` system, you can use the `qemu-arm` [userspace emulation](https://qemu-project.gitlab.io/qemu/user/main.html) program. This avoids having a full emulated ARM system by doing dynamic binary translation and dynamic system call translation. It lets you run ARM programs directly on your `x86_64` kernel. It's very convenient!

To use:

* Install `qemu-arm` according to your distro.
* Link your built toolchain via:
* `rustup toolchain link stage2 ${RUST}/build/x86_64-unknown-linux-gnu/stage2`
* Create a test program

```sh
cargo new hello_world
cd hello_world
```

* Build and run

```sh
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_RUNNER="qemu-arm -L ${TOOLCHAIN}/arm-buildroot-linux-uclibcgnueabihf/sysroot/" \
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_LINKER=${TOOLCHAIN}/bin/arm-buildroot-linux-uclibcgnueabihf-gcc \
cargo +stage2 run --target armv7-unknown-linux-uclibceabihf
```