Bootstrapping Rust via stage file

From Gentoo Wiki
Jump to:navigation Jump to:search

This article covers bootstraping Rust for a LLVM profile using a (non-LLVM) Stage 3 file.


Precondition

On LLVM-based systems using musl, packages may break if dev-lang/rust-bin is the active Rust installation, and it is therefore masked (bug #912154). Emerge dev-lang/rust requires a Rust installation, which leads to a circular dependency that cannot be resolved.

Verify that the profile is a musl/llvm profile:

root #eselect profile list
Available profile symlink targets:
  [46]  default/linux/arm64/23.0/musl/llvm (exp) *

Setting up a Build-Environment

Getting a Stage File

Choose a Stage 3 file that matches the architecture and profile, but does not use LLVM: e.g.

  • default/linux/arm64/23.0/musl/llvm -> default/linux/arm64/23.0/musl
  • default/linux/amd64/23.0/musl/llvm -> default/linux/amd64/23.0/musl
  • ...

Before downloading the stage file, the current directory should be set to the location where the environment shall be set up:

user $mkdir ~/gentoo-rootfs
user $cd ~/gentoo-rootfs

Once downloaded, extract the stage file:

user $fakeroot tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner

Entering the Environment

One thing still remains to be done before entering the new environment and that is copying over the DNS information in /etc/resolv.conf.

user $cp --dereference /etc/resolv.conf ./etc

Option 1: via Chroot

As described in the Chrooting section in the handbook.

Option 2: via Podman

user $podman run -it --rootfs $(pwd) /bin/bash

Configuring Portage

Install a snapshot of the Gentoo ebuild repository

root #emerge-webrsync

Veryfing the Profile

Verify that the profile is a musl, non-llvm profile:

root #eselect profile list
Available profile symlink targets:
  [45]  default/linux/arm64/23.0/musl (dev) *

Building Rust

Building Rust with stdlibc++

First a working setup with rust and llvm is built.

root #emerge --ask llvm-core/clang llvm-core/llvm llvm-runtimes/compiler-rt llvm-runtimes/libunwind llvm-core/lld dev-lang/rust

Building Rust with libc++

Then switch the toolchain to default-libcxx.

Select the corresponding llvm profile

root #eselect profile list
  [45]  default/linux/arm64/23.0/musl (dev) *
  [46]  default/linux/arm64/23.0/musl/llvm (exp)
root #profile set 46
!!! Warning: Profile default/linux/arm64/23.0/musl/llvm is experimental

Emerge llvm-core/clang-runtime

The USE-flags default-compiler-rt, default-libcxx, default-lld and llvm-libunwind are set by the profile.

root #emerge --ask llvm-core/clang-runtime
[ebuild   R    ] llvm-runtimes/libunwind USE="static-libs*"
[ebuild  N     ] llvm-runtimes/libcxxabi USE="(clang) static-libs -test -verify-sig"
[ebuild  N     ] llvm-runtimes/libcxx    USE="(clang) (libcxxabi) static-libs -test -verify-sig"
[ebuild   R    ] llvm-core/clang-runtime USE="(default-compiler-rt*) (default-libcxx*) (default-lld*) libcxx* (llvm-libunwind*) -sanitize*" 
Note
If there is no profile or switching profile is not possible, follow Bootstrapping the LLVM toolchain

Confirm working default-libcxx

user $cat > test.cpp <<'EOF'
#include <iostream>
int main() { std::cout << "LLVM profile OK\n"; }
EOF
user $clang++ test.cpp
user $ldd ./a.out | grep -E 'libc\+\+|libstdc\+\+'
       libc++.so.1 => /lib/libc++.so.1 (0xffff95926000)
       libc++abi.so.1 => /lib/libc++abi.so.1 (0xffff958d5000)
Warning
If you see libstdc++.so.6 the toolchain is still using stdlibc++

Rebuild the toolchain

root #emerge --ask llvm-core/clang llvm-core/llvm llvm-runtimes/libcxx llvm-runtimes/libcxxabi llvm-runtimes/compiler-rt llvm-runtimes/compiler-rt-sanitizers llvm-runtimes/libunwind llvm-core/lld

Rebuild Rust & create a binary package

Emerge Rust with the new toolchain and USE-flags and build a binary package:

root #emerge --ask --buildpkg dev-lang/rust
[ebuild   R    ] dev-lang/rust USE="(llvm-libunwind*)"

Installing Rust

Leave the build environment

root #exit

Backup the hosts package cache

root #[ -d /var/cache/binpkgs ] && mv /var/cache/binpkgs /var/cache/binpkgs-tmp

Copy the build environment package cache to the host

root #cp -r ./var/cache/binpkgs /var/cache/binpkgs

Install Rust

root #emerge --ask --usepkgonly dev-lang/rust

Remove the cache

root #rm -r /var/cache/binpkgs

Restore the hosts package cache

root #[ -d /var/cache/binpkgs-tmp ] && mv /var/cache/binpkgs-tmp /var/cache/binpkgs

Optional: Rebuilding with custom USE-flags

Once installed, rebuild Rust with the desired USE-flags.

See Also