Skip to content

Commit

Permalink
Provide prebuilt std for gnullvm targets
Browse files Browse the repository at this point in the history
  • Loading branch information
mati865 committed Mar 9, 2024
1 parent 1e4f9e3 commit 14b18e9
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 12 deletions.
11 changes: 10 additions & 1 deletion src/ci/docker/host-x86_64/dist-various-1/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ RUN ./install-riscv64-none-elf.sh
COPY host-x86_64/dist-various-1/install-riscv32-none-elf.sh /build
RUN ./install-riscv32-none-elf.sh

COPY host-x86_64/dist-various-1/install-llvm-mingw.sh /build
RUN ./install-llvm-mingw.sh

# Suppress some warnings in the openwrt toolchains we downloaded
ENV STAGING_DIR=/tmp

Expand Down Expand Up @@ -110,6 +113,9 @@ ENV TARGETS=$TARGETS,armv7r-none-eabi
ENV TARGETS=$TARGETS,armv7r-none-eabihf
ENV TARGETS=$TARGETS,thumbv7neon-unknown-linux-gnueabihf
ENV TARGETS=$TARGETS,armv7a-none-eabi
ENV TARGETS=$TARGETS,aarch64-pc-windows-gnullvm
ENV TARGETS=$TARGETS,i686-pc-windows-gnullvm
ENV TARGETS=$TARGETS,x86_64-pc-windows-gnullvm

ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft" \
CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm" \
Expand Down Expand Up @@ -139,7 +145,10 @@ ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft
CC_riscv64imac_unknown_none_elf=riscv64-unknown-elf-gcc \
CFLAGS_riscv64imac_unknown_none_elf=-march=rv64imac -mabi=lp64 \
CC_riscv64gc_unknown_none_elf=riscv64-unknown-elf-gcc \
CFLAGS_riscv64gc_unknown_none_elf=-march=rv64gc -mabi=lp64
CFLAGS_riscv64gc_unknown_none_elf=-march=rv64gc -mabi=lp64 \
CC_aarch64_pc_windows_gnullvm=aarch64-w64-mingw32-clang \
CC_i686_pc_windows_gnullvm=i686-w64-mingw32-clang \
CC_x86_64_pc_windows_gnullvm=x86_64-w64-mingw32-clang

ENV RUST_CONFIGURE_ARGS \
--musl-root-armv5te=/musl-armv5te \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

set -ex

archive=llvm-mingw-20231128-ucrt-ubuntu-20.04-x86_64.tar.xz
curl -L https://github.com/mstorsjo/llvm-mingw/releases/download/20231128/${archive} | \
tar --extract --lzma --strip 1 --directory /usr/local
36 changes: 25 additions & 11 deletions src/doc/rustc/src/platform-support/pc-windows-gnullvm.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# \*-pc-windows-gnullvm

**Tier: 3**
**Tier: 2 (without host tools)**

Windows targets similar to `*-pc-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of GCC/Binutils.

Expand All @@ -12,38 +12,52 @@ Target triples available so far:
## Target maintainers

- [@mati865](https://github.com/mati865)
- [@thomcc](https://github.com/thomcc)

## Requirements

The easiest way to obtain these targets is cross-compilation but native build from `x86_64-pc-windows-gnu` is possible with few hacks which I don't recommend.
The easiest way to obtain these targets is cross-compilation, but native build from `x86_64-pc-windows-gnu` is possible with few hacks which I don't recommend.
Std support is expected to be on pair with `*-pc-windows-gnu`.

Binaries for this target should be at least on pair with `*-pc-windows-gnu` in terms of requirements and functionality.

Those targets follow Windows calling convention for `extern "C"`.

Like with any other Windows target created binaries are in PE format.
Like with any other Windows target, created binaries are in PE format.

## Building the target

For cross-compilation I recommend using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain, one change that seems necessary beside configuring cross compilers is disabling experimental `m86k` target. Otherwise LLVM build fails with `multiple definition ...` errors.
Native bootstrapping builds require rather fragile hacks until host artifacts are available so I won't describe them here.
These targets can be easily cross-compiled
using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain or [MSYS2 CLANG*](https://www.msys2.org/docs/environments/) environments.
Just fill `[target.*]` sections for both build and resulting compiler and set installation prefix in `config.toml`.
Then run `./x.py install`.
In my case I had ran `./x.py install --host x86_64-pc-windows-gnullvm --target x86_64-pc-windows-gnullvm` inside MSYS2 MINGW64 shell
so `x86_64-pc-windows-gnu` was my build toolchain.

Native bootstrapping is doable in two ways:
- cross-compile gnullvm host toolchain and use it as build toolchain for the next build,
- copy libunwind libraries and rename them to mimic libgcc like here: https://github.com/msys2/MINGW-packages/blob/68e640756df2df6df6afa60f025e3f936e7b977c/mingw-w64-rust/PKGBUILD#L108-L109, stage0 compiler will be mostly broken but good enough to build the next stage.

The second option might stop working anytime, so it's not recommended.

## 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.
Rust does ship a pre-compiled std library for those targets.
That means one can easily cross-compile for those targets from other hosts if C proper toolchain is installed.

Alternatively full toolchain can be built as described in the previous section.

## Testing

Created binaries work fine on Windows or Wine using native hardware. Testing AArch64 on x86_64 is problematic though and requires spending some time with QEMU.
Once these targets bootstrap themselves on native hardware they should pass Rust testsuite.
Most of x86_64 testsuite does pass when cross-compiling,
with exception for `rustdoc` and `ui-fulldeps` that fail with and error regarding a missing library,
they do pass in native builds though.
The only failing test is std's `process::tests::test_proc_thread_attributes` for unknown reason.

## Cross-compilation toolchains and C code

Compatible C code can be built with Clang's `aarch64-pc-windows-gnu`, `i686-pc-windows-gnullvm` and `x86_64-pc-windows-gnu` targets as long as LLVM based C toolchains are used.
Compatible C code can be built with Clang's `aarch64-pc-windows-gnu`, `i686-pc-windows-gnullvm` and `x86_64-pc-windows-gnu` targets as long as LLVM-based C toolchains are used.
Those include:
- [llvm-mingw](https://github.com/mstorsjo/llvm-mingw)
- [MSYS2 with CLANG* environment](https://www.msys2.org/docs/environments)
1 change: 1 addition & 0 deletions tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//@ only-gnu
//@ only-windows
//@ needs-dlltool
//@ ignore-llvm
//@ compile-flags: --crate-type lib --emit link
//@ normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL"
//@ normalize-stderr-test: "[^ ]*/foo.def" -> "$$DEF_FILE"
Expand Down
1 change: 1 addition & 0 deletions tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

//@ only-gnu
//@ only-windows
//@ ignore-llvm
//@ compile-flags: --crate-type lib --emit link -Cdlltool=does_not_exit.exe
#[link(name = "foo", kind = "raw-dylib")]
extern "C" {
Expand Down

0 comments on commit 14b18e9

Please sign in to comment.