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 OpenHarmony targets #108792

Merged
merged 1 commit into from Mar 29, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
]
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Expand Up @@ -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;
Expand All @@ -239,6 +241,7 @@ pub fn target_machine_factory(
relax_elf_relocations,
use_init_array,
split_dwarf_file.as_ptr(),
force_emulated_tls,
)
};

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Expand Up @@ -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>(
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down
31 changes: 31 additions & 0 deletions compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs
@@ -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
@@ -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
Expand Up @@ -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>]>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1954,6 +1960,7 @@ impl Default for TargetOptions {
entry_name: "main".into(),
entry_abi: Conv::C,
supports_xray: false,
force_emulated_tls: false,
}
}
}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion library/std/Cargo.toml
Expand Up @@ -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" }
Expand Down
5 changes: 4 additions & 1 deletion library/std/src/sys/unix/os.rs
Expand Up @@ -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;
}

Expand Down
16 changes: 16 additions & 0 deletions library/unwind/src/lib.rs
Expand Up @@ -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")] {
Expand Down
2 changes: 2 additions & 0 deletions src/bootstrap/lib.rs
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/llvm.rs
Expand Up @@ -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"]),
Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions src/doc/rustc/src/platform-support.md
Expand Up @@ -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
Expand All @@ -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
Expand Down
128 changes: 128 additions & 0 deletions src/doc/rustc/src/platform-support/openharmony.md
@@ -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.