Skip to content

Unable to build cross target's libstd on Rust 1.89 #145587

@RyanSquared

Description

@RyanSquared

Summary

In previous versions of Rust, I could build libstd for x86_64-unknown-linux-gnu on a x86_64-unknown-linux-musl machine by using ./x.py build --stage 0 library --target x86_64-unknown-linux-gnu. After upgrading to Rust 1.89, stage 0 libstd no longer works, and stage 1 results in the compiler being unable to find the host libstd and core.

Command used

	./configure \
		--build="${ARCH}-unknown-linux-musl" \
		--host="${ARCH}-unknown-linux-musl" \
		--target="${ARCH}-unknown-linux-gnu" \
		--prefix="/usr" \
		--llvm-root="/usr" \
		--llvm-libunwind="system" \
		--sysconfdir="/rootfs/etc" \
		--libdir="/opt/cross/lib/${ARCH}-linux-gnu" \
		--enable-local-rust \
		--enable-clang \
		--enable-lld \
		--disable-docs \
		--enable-llvm-link-shared \
		--enable-option-checking \
		--enable-locked-deps \
		--enable-vendor \
		--dist-compression-formats=gz \
		--release-channel="stable" \
		--set="install.prefix=/rootfs"
	python3 x.py build --stage 1 --target ${ARCH}-unknown-linux-gnu library

Source: https://codeberg.org/stagex/stagex/src/branch/main/packages/core/cross-x86_64-gnu-rust/Containerfile#L63

Expected behaviour

libstd should be built without error.

Actual behaviour

The compiler fails on the step going from stage0 to stage1, saying it's missing core and std for the host machine.

Bootstrap configuration (bootstrap.toml)

# Use different pre-set defaults than the global defaults.
#
# See `src/bootstrap/defaults` for more information.
# Note that this has no default value (x.py uses the defaults in `bootstrap.example.toml`).
profile = 'dist'

[llvm]

# Whether to build LLVM as a dynamically linked library (as opposed to statically linked).
# Under the hood, this passes `--shared` to llvm-config.
# NOTE: To avoid performing LTO multiple times, we suggest setting this to `true` when `thin-lto` is enabled.
link-shared = true

# Whether to build the clang compiler.
clang = true

[gcc]
# Download GCC from CI instead of building it locally.
# Note that this will attempt to download GCC even if there are local
# modifications to the `src/gcc` submodule.
# Currently, this is only supported for the `x86_64-unknown-linux-gnu` target.
#download-ci-gcc = false

[build]

# Build triple for the pre-compiled snapshot compiler. If `rustc` is set, this must match its host
# triple (see `rustc --version --verbose`; cross-compiling the rust build system itself is NOT
# supported). If `rustc` is unset, this must be a platform with pre-compiled host tools
# (https://doc.rust-lang.org/nightly/rustc/platform-support.html). The current platform must be
# able to run binaries of this build triple.
#
# If `rustc` is present in path, this defaults to the host it was compiled for.
# Otherwise, `x.py` will try to infer it from the output of `uname`.
# If `uname` is not found in PATH, we assume this is `x86_64-pc-windows-msvc`.
# This may be changed in the future.
build = 'x86_64-unknown-linux-musl'

# Which triples to produce a compiler toolchain for. Each of these triples will be bootstrapped from
# the build triple themselves. In other words, this is the list of triples for which to build a
# compiler that can RUN on that triple.
#
# Defaults to just the `build` triple.
host = ['x86_64-unknown-linux-musl']

# Which triples to build libraries (core/alloc/std/test/proc_macro) for. Each of these triples will
# be bootstrapped from the build triple themselves. In other words, this is the list of triples for
# which to build a library that can CROSS-COMPILE to that triple.
#
# Defaults to `host`. If you set this explicitly, you likely want to add all
# host triples to this list as well in order for those host toolchains to be
# able to compile programs for their native target.
target = ['x86_64-unknown-linux-gnu']

# Instead of downloading the src/stage0 version of Cargo specified, use
# this Cargo binary instead to build all Rust code
# If you set this, you likely want to set `rustc` as well.
cargo = '/usr/bin/cargo'

# Instead of downloading the src/stage0 version of the compiler
# specified, use this rustc binary instead as the stage0 snapshot compiler.
# If you set this, you likely want to set `cargo` as well.
rustc = '/usr/bin/rustc'

# Whether to build documentation by default. If false, rustdoc and
# friends will still be compiled but they will not be used to generate any
# documentation.
#
# You can still build documentation when this is disabled by explicitly passing paths,
# e.g. `x doc library`.
docs = false

# Force Cargo to check that Cargo.lock describes the precise dependency
# set that all the Cargo.toml files create, instead of updating it.
locked-deps = true

# Indicate whether the vendored sources are used for Rust dependencies or not.
#
# Vendoring requires additional setup. We recommend using the pre-generated source tarballs if you
# want to use vendoring. See https://forge.rust-lang.org/infra/other-installation-methods.html#source-code.
vendor = true

# Arguments passed to the `./configure` script, used during distcheck. You
# probably won't fill this in but rather it's filled in by the `./configure`
# script. Useful for debugging.
configure-args = ['--build=x86_64-unknown-linux-musl', '--host=x86_64-unknown-linux-musl', '--target=x86_64-unknown-linux-gnu', '--prefix=/usr', '--llvm-root=/usr', '--llvm-libunwind=system', '--sysconfdir=/rootfs/etc', '--libdir=/opt/cross/lib/x86_64-linux-gnu', '--enable-local-rust', '--enable-clang', '--enable-lld', '--disable-docs', '--enable-llvm-link-shared', '--enablon-checking', '--enable-locked-deps', '--enable-vendor', '--dist-compression-formats=gz', '--release-channel=stable', '--set=install.prefix=/rootfs']

[install]

# Where to install the generated toolchain. Must be an absolute path.
prefix = '/rootfs'

# Where to install system configuration files.
# If this is a relative path, it will get installed in `prefix` above
sysconfdir = '/rootfs/etc'

# Where to install libraries in `prefix` above
libdir = '/opt/cross/lib/x86_64-linux-gnu'

[rust]

# The "channel" for the Rust build to produce. The stable/beta channels only
# allow using stable features, whereas the nightly and dev channels allow using
# nightly features.
#
# You can set the channel to "auto-detect" to load the channel name from `src/ci/channel`.
#
# If using tarball sources, default value is "auto-detect", otherwise, it's "dev".
channel = 'stable'

# Indicates whether LLD will be compiled and made available in the sysroot for rustc to execute, and
# whether to set it as rustc's default linker on `x86_64-unknown-linux-gnu`. This will also only be
# when *not* building an external LLVM (so only when using `download-ci-llvm` or building LLVM from
# the in-tree source): setting `llvm-config` in the `[target.x86_64-unknown-linux-gnu]` section will
# make this default to false.
lld = true

# Global default for llvm-libunwind for all targets. See the target-specific
# documentation for llvm-libunwind below. Note that the target-specific
# option will override this if set.
llvm-libunwind = 'system'

[target.x86_64-unknown-linux-musl]

# Path to the `llvm-config` binary of the installation of a custom LLVM to link
# against. Note that if this is specified we don't compile LLVM at all for this
# target.
llvm-config = '/usr/bin/llvm-config'

[target.x86_64-unknown-linux-gnu]

[dist]

# List of compression formats to use when generating dist tarballs. The list of
# formats is provided to rust-installer, which must support all of them.
#
# This list must be non-empty.
compression-formats = ['gz']

Operating system

stagex (Linux, x86_64-linux-musl) 2025.08.0-dev (https://codeberg.org/stagex/stagex)

HEAD

2948388+

Additional context

We build our main Rust with a patch to disable implicit static on musl: https://codeberg.org/stagex/stagex/src/branch/main/packages/core/rust/no-default-static.patch.

We do not build the cross-compiled libstd with the patch, as it's only musl-specific.

Build Log

14.37    Compiling build_helper v0.1.0 (/rustc-1.89.0-src/src/build_helper)
44.52     Finished `dev` profile [unoptimized] target(s) in 0.00s
44.89 Warning: LLD is enabled when using external llvm-config. LLD will not be built and copied to the sysroot.
44.89 WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.
44.89 NOTE: to silence this warning, add `change-id = 142379` or `change-id = "ignore"` at the top of `bootstrap.toml`
58.28 Building compiler artifacts (stage0 -> stage1, x86_64-unknown-linux-musl)
59.83    Compiling proc-macro2 v1.0.95
59.83    Compiling unicode-ident v1.0.18
59.83    Compiling cfg-if v1.0.1
59.83    Compiling libc v0.2.174
59.83    Compiling memchr v2.7.5
59.83    Compiling shlex v1.3.0
59.83    Compiling stable_deref_trait v1.2.0
59.83    Compiling smallvec v1.15.1
59.83    Compiling allocator-api2 v0.2.21
59.83    Compiling once_cell v1.21.3
59.84    Compiling equivalent v1.0.2
59.84    Compiling bitflags v2.9.1
59.84    Compiling foldhash v0.1.5
59.84    Compiling getrandom v0.3.3
59.84    Compiling autocfg v1.4.0
59.84    Compiling version_check v0.9.5
59.84    Compiling parking_lot_core v0.9.11
59.84    Compiling typenum v1.18.0
59.84    Compiling scopeguard v1.2.0
59.84    Compiling log v0.4.27
59.84    Compiling pin-project-lite v0.2.16
59.84    Compiling crossbeam-utils v0.8.21
59.84    Compiling rustix v1.0.7
59.84    Compiling linux-raw-sys v0.9.4
59.84    Compiling rustc-stable-hash v0.1.2
59.84    Compiling rustc_macros v0.0.0 (/rustc-1.89.0-src/compiler/rustc_macros)
59.84    Compiling zerocopy v0.8.25
59.84    Compiling proc-macro-hack v0.5.20+deprecated
59.84    Compiling rustc-hash v2.1.1
59.84    Compiling fastrand v2.3.0
59.84    Compiling rustc-hash v1.1.0
59.84    Compiling thin-vec v0.2.14
59.85    Compiling either v1.15.0
59.86    Compiling arrayvec v0.7.6
59.88    Compiling rustc_graphviz v0.0.0 (/rustc-1.89.0-src/compiler/rustc_graphviz)
59.88    Compiling unicode-width v0.2.1
59.88    Compiling cpufeatures v0.2.17
59.88    Compiling arrayref v0.3.9
59.88    Compiling itoa v1.0.15
59.88    Compiling constant_time_eq v0.3.1
59.89    Compiling scoped-tls v1.0.1
59.92    Compiling thiserror v2.0.12
59.93    Compiling serde v1.0.219
59.93    Compiling writeable v0.5.5
59.94    Compiling icu_locid_transform_data v1.5.1
59.98    Compiling rustc-literal-escaper v0.0.2
59.99    Compiling litemap v0.7.5
60.00    Compiling serde_json v1.0.140
60.10 error[E0463]: can't find crate for `core`
60.10   |
60.10   = note: the `x86_64-unknown-linux-musl` target may not be installed
60.10   = help: consider downloading the target with `rustup target add x86_64-unknown-linux-musl`
60.10   = help: consider building the standard library from source with `cargo build -Zbuild-std`
60.10
60.10 error[E0463]: can't find crate for `std`
60.10   |
60.10   = note: the `x86_64-unknown-linux-musl` target may not be installed
60.10   = help: consider downloading the target with `rustup target add x86_64-unknown-linux-musl`
60.10   = help: consider building the standard library from source with `cargo build -Zbuild-std`
60.10
60.10 For more information about this error, try `rustc --explain E0463`.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-crossArea: Cross compilationC-bugCategory: This is a bug.T-bootstrapRelevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions