Skip to content

Add OpenHarmony targets #108792

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

Merged
merged 1 commit into from
Mar 29, 2023
Merged
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
8 changes: 4 additions & 4 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -868,9 +868,9 @@ dependencies = [

[[package]]
name = "compiler_builtins"
version = "0.1.87"
version = "0.1.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f867ce54c09855ccd135ad4a50c777182a0c7af5ff20a8f537617bd648b10d50"
checksum = "9fc9c2080d347a2c316518840ac9194644a9993dfa1e9778ef38979a339f5d8b"
dependencies = [
"cc",
"rustc-std-workspace-core",
@@ -2879,9 +2879,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"

[[package]]
name = "libc"
version = "0.2.139"
version = "0.2.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
dependencies = [
"rustc-std-workspace-core",
]
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
@@ -214,6 +214,8 @@ pub fn target_machine_factory(

let path_mapping = sess.source_map().path_mapping().clone();

let force_emulated_tls = sess.target.force_emulated_tls;

Arc::new(move |config: TargetMachineFactoryConfig| {
let split_dwarf_file =
path_mapping.map_prefix(config.split_dwarf_file.unwrap_or_default()).0;
@@ -239,6 +241,7 @@ pub fn target_machine_factory(
relax_elf_relocations,
use_init_array,
split_dwarf_file.as_ptr(),
force_emulated_tls,
)
};

1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
@@ -2257,6 +2257,7 @@ extern "C" {
RelaxELFRelocations: bool,
UseInitArray: bool,
SplitDwarfFile: *const c_char,
ForceEmulatedTls: bool,
) -> Option<&'static mut TargetMachine>;
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
pub fn LLVMRustAddLibraryInfo<'a>(
7 changes: 6 additions & 1 deletion compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
@@ -368,7 +368,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
bool EmitStackSizeSection,
bool RelaxELFRelocations,
bool UseInitArray,
const char *SplitDwarfFile) {
const char *SplitDwarfFile,
bool ForceEmulatedTls) {

auto OptLevel = fromRust(RustOptLevel);
auto RM = fromRust(RustReloc);
@@ -400,6 +401,10 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
}
Options.RelaxELFRelocations = RelaxELFRelocations;
Options.UseInitArray = UseInitArray;
if (ForceEmulatedTls) {
Options.ExplicitEmulatedTLS = true;
Options.EmulatedTLS = true;
}

if (TrapUnreachable) {
// Tell LLVM to codegen `unreachable` into an explicit trap instruction.
31 changes: 31 additions & 0 deletions compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::spec::{Target, TargetOptions};

use super::SanitizerSet;

pub fn target() -> Target {
let mut base = super::linux_musl_base::opts();
base.env = "ohos".into();
base.crt_static_default = false;
base.max_atomic_width = Some(128);

Target {
// LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
llvm_target: "aarch64-unknown-linux-musl".into(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
arch: "aarch64".into(),
options: TargetOptions {
features: "+reserve-x18".into(),
mcount: "\u{1}_mcount".into(),
force_emulated_tls: true,
supported_sanitizers: SanitizerSet::ADDRESS
| SanitizerSet::CFI
| SanitizerSet::LEAK
| SanitizerSet::MEMORY
| SanitizerSet::MEMTAG
| SanitizerSet::THREAD
| SanitizerSet::HWADDRESS,
..base
},
}
}
27 changes: 27 additions & 0 deletions compiler/rustc_target/src/spec/armv7_unknown_linux_ohos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::spec::{Target, TargetOptions};

// This target is for OpenHarmony on ARMv7 Linux with thumb-mode, but no NEON or
// hardfloat.

pub fn target() -> Target {
// Most of these settings are copied from the armv7_unknown_linux_musleabi
// target.
Target {
// LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
llvm_target: "armv7-unknown-linux-gnueabi".into(),
pointer_width: 32,
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
arch: "arm".into(),

options: TargetOptions {
abi: "eabi".into(),
features: "+v7,+thumb2,+soft-float,-neon".into(),
max_atomic_width: Some(64),
env: "ohos".into(),
crt_static_default: false,
mcount: "\u{1}mcount".into(),
force_emulated_tls: true,
..super::linux_musl_base::opts()
},
}
}
9 changes: 9 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
@@ -1261,6 +1261,9 @@ supported_targets! {

("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx_710),
("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710),

("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos),
("armv7-unknown-linux-ohos", armv7_unknown_linux_ohos),
}

/// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]>
@@ -1734,6 +1737,9 @@ pub struct TargetOptions {

/// Whether the target supports XRay instrumentation.
pub supports_xray: bool,

/// Forces the use of emulated TLS (__emutls_get_address)
pub force_emulated_tls: bool,
}

/// Add arguments for the given flavor and also for its "twin" flavors
@@ -1954,6 +1960,7 @@ impl Default for TargetOptions {
entry_name: "main".into(),
entry_abi: Conv::C,
supports_xray: false,
force_emulated_tls: false,
}
}
}
@@ -2605,6 +2612,7 @@ impl Target {
key!(entry_name);
key!(entry_abi, Conv)?;
key!(supports_xray, bool);
key!(force_emulated_tls, bool);

if base.is_builtin {
// This can cause unfortunate ICEs later down the line.
@@ -2859,6 +2867,7 @@ impl ToJson for Target {
target_option_val!(entry_name);
target_option_val!(entry_abi);
target_option_val!(supports_xray);
target_option_val!(force_emulated_tls);

if let Some(abi) = self.default_adjusted_cabi {
d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json());
2 changes: 1 addition & 1 deletion library/std/Cargo.toml
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core" }
libc = { version = "0.2.139", default-features = false, features = ['rustc-dep-of-std'] }
libc = { version = "0.2.140", default-features = false, features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.87" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }
5 changes: 4 additions & 1 deletion library/std/src/sys/unix/os.rs
Original file line number Diff line number Diff line change
@@ -115,7 +115,10 @@ pub fn set_errno(e: i32) {
/// Gets a detailed string description for the given error number.
pub fn error_string(errno: i32) -> String {
extern "C" {
#[cfg_attr(any(target_os = "linux", target_env = "newlib"), link_name = "__xpg_strerror_r")]
#[cfg_attr(
all(any(target_os = "linux", target_env = "newlib"), not(target_env = "ohos")),
link_name = "__xpg_strerror_r"
)]
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int;
}

16 changes: 16 additions & 0 deletions library/unwind/src/lib.rs
Original file line number Diff line number Diff line change
@@ -54,6 +54,22 @@ cfg_if::cfg_if! {
}
}

// This is the same as musl except that we default to using the system libunwind
// instead of libgcc.
#[cfg(target_env = "ohos")]
cfg_if::cfg_if! {
if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] {
compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time");
} else if #[cfg(feature = "llvm-libunwind")] {
#[link(name = "unwind", kind = "static", modifiers = "-bundle")]
extern "C" {}
} else {
#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
extern "C" {}
}
}

#[cfg(target_os = "android")]
cfg_if::cfg_if! {
if #[cfg(feature = "llvm-libunwind")] {
2 changes: 2 additions & 0 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
@@ -149,6 +149,8 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
// Needed to avoid the need to copy windows.lib into the sysroot.
(Some(Mode::Rustc), "windows_raw_dylib", None),
(Some(Mode::ToolRustc), "windows_raw_dylib", None),
// #[cfg(bootstrap)] ohos
(Some(Mode::Std), "target_env", Some(&["ohos"])),
];

/// A structure representing a Rust compiler.
3 changes: 3 additions & 0 deletions src/bootstrap/llvm.rs
Original file line number Diff line number Diff line change
@@ -1008,6 +1008,9 @@ fn supported_sanitizers(
"aarch64-unknown-linux-gnu" => {
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"])
}
"aarch64-unknown-linux-ohos" => {
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"])
}
"x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
"x86_64-unknown-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]),
"x86_64-apple-ios" => darwin_libs("iossim", &["asan", "tsan"]),
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@
- [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
- [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
- [\*-android and \*-androideabi](platform-support/android.md)
- [\*-linux-ohos](platform-support/openharmony.md)
- [\*-unknown-fuchsia](platform-support/fuchsia.md)
- [\*-kmc-solid_\*](platform-support/kmc-solid.md)
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
2 changes: 2 additions & 0 deletions src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
@@ -218,6 +218,7 @@ target | std | host | notes
[`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3
[`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon
[`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
[`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARM64 OpenHarmony |
[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS |
`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
`aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore
@@ -240,6 +241,7 @@ target | std | host | notes
[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
`armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8
[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ? | | ARM Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARMv7 OpenHarmony |
[`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7 Linux with uClibc, softfloat
[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux with uClibc, hardfloat
`armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
128 changes: 128 additions & 0 deletions src/doc/rustc/src/platform-support/openharmony.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# `*-linux-ohos*`

**Tier: 3**

Targets for the [OpenHarmony](https://gitee.com/openharmony/docs/) operating
system.

## Target maintainers

- Amanieu d'Antras ([@Amanieu](https://github.com/Amanieu))

## Setup

The OpenHarmony SDK doesn't currently support Rust compilation directly, so
some setup is required.

First, you must obtain the OpenHarmony SDK from [this page](https://gitee.com/openharmony/docs/tree/master/en/release-notes).
Select the version of OpenHarmony you are developing for and download the "Public SDK package for the standard system".

Create the following shell scripts that wrap Clang from the OpenHarmony SDK:

`aarch64-unknown-linux-ohos-clang.sh`

```sh
#!/bin/sh
exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \
-target aarch64-linux-ohos \
--sysroot=/path/to/ohos-sdk/linux/native/sysroot \
-D__MUSL__ \
"$@"
```

`aarch64-unknown-linux-ohos-clang++.sh`

```sh
#!/bin/sh
exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \
-target aarch64-linux-ohos \
--sysroot=/path/to/ohos-sdk/linux/native/sysroot \
-D__MUSL__ \
"$@"
```

`armv7-unknown-linux-ohos-clang.sh`

```sh
#!/bin/sh
exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \
-target arm-linux-ohos \
--sysroot=/path/to/ohos-sdk/linux/native/sysroot \
-D__MUSL__ \
-march=armv7-a \
-mfloat-abi=softfp \
-mtune=generic-armv7-a \
-mthumb \
"$@"
```

`armv7-unknown-linux-ohos-clang++.sh`

```sh
#!/bin/sh
exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \
-target arm-linux-ohos \
--sysroot=/path/to/ohos-sdk/linux/native/sysroot \
-D__MUSL__ \
-march=armv7-a \
-mfloat-abi=softfp \
-mtune=generic-armv7-a \
-mthumb \
"$@"
```

Future versions of the OpenHarmony SDK will avoid the need for this process.

## Building the target

To build a rust toolchain, create a `config.toml` with the following contents:

```toml
profile = "compiler"
changelog-seen = 2

[build]
sanitizers = true
profiler = true

[target.aarch64-unknown-linux-ohos]
cc = "/path/to/aarch64-unknown-linux-ohos-clang.sh"
cxx = "/path/to/aarch64-unknown-linux-ohos-clang++.sh"
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib"
linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh"

[target.armv7-unknown-linux-ohos]
cc = "/path/to/armv7-unknown-linux-ohos-clang.sh"
cxx = "/path/to/armv7-unknown-linux-ohos-clang++.sh"
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib"
linker = "/path/to/armv7-unknown-linux-ohos-clang.sh"
```

## Building Rust programs

Rust does not yet ship pre-compiled artifacts for this target. To compile for
this target, you will either need to build Rust with the target enabled (see
"Building the target" above), or build your own copy of `core` by using
`build-std` or similar.

You will need to configure the linker to use in `~/.cargo/config`:
```toml
[target.aarch64-unknown-linux-ohos]
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh"

[target.armv7-unknown-linux-ohos]
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
linker = "/path/to/armv7-unknown-linux-ohos-clang.sh"
```

## Testing

Running the Rust testsuite is possible, but currently difficult due to the way
the OpenHarmony emulator is set up (no networking).

## Cross-compilation toolchains and C code

You can use the shell scripts above to compile C code for the target.