Skip to content

bootstrapping rustc for a custom target no longers works since 1.48, assembles stages for build not host #81702

Open
@danc86

Description

@danc86

I'm working with Yocto's meta-rust layer, trying to build rustc 1.49. I'm building on a regular x86_64 Linux host, but we use a custom JSON target specification due to rust-lang/cargo#3349. So we have x86_64-unknown-linux-gnu (real Rust triple) cross-bootstrapping for x86_64-linux (custom target which is essentially the same as x86_64-unknown-linux-gnu but with a different name):

target = ["x86_64-linux"]
host = ["x86_64-linux"]
build = "x86_64-unknown-linux-gnu"

With rust 1.47, x.py build --stage 2 src/rustc gives us the desired bootstrapping behaviour:

Building stage0 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage0 std from stage0 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Building stage0 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage0 rustc from stage0 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Assembling stage1 compiler (x86_64-unknown-linux-gnu)
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage1 std from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Building stage1 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage1 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Assembling stage2 compiler (x86_64-unknown-linux-gnu)
Uplifting stage1 std (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage2 std from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Uplifting stage1 rustc (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage2 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> x86_64-linux)
Copying stage1 std from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-linux)
Uplifting stage1 std (x86_64-unknown-linux-gnu -> x86_64-linux)
Copying stage2 std from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-linux)
Building stage1 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-linux)
Copying stage1 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-linux)
Uplifting stage1 rustc (x86_64-unknown-linux-gnu -> x86_64-linux)
Copying stage2 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-linux)
Assembling stage2 compiler (x86_64-linux)
Uplifting stage1 std (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage2 std from stage1 (x86_64-unknown-linux-gnu -> x86_64-linux / x86_64-unknown-linux-gnu)
Uplifting stage1 rustc (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage2 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-linux / x86_64-unknown-linux-gnu)
Uplifting stage1 std (x86_64-unknown-linux-gnu -> x86_64-linux)
Copying stage2 std from stage1 (x86_64-unknown-linux-gnu -> x86_64-linux / x86_64-linux)
Uplifting stage1 rustc (x86_64-unknown-linux-gnu -> x86_64-linux)
Copying stage2 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-linux / x86_64-linux)

(Note that it also insisted on building a compiler for the build triple x86_64-unknown-linux-gnu as well as the host x86_64-linux, which is unnecessary but not harmful. It seems this has been addressed in bootstrap since 1.47.)

The end result with 1.47 above is that the build/x86_64-linux/stage2 directory contains an assembled rustc for the host x86_64-linux with libstd for x86_64-linux (and x86_64-unknown-linux-gnu).

However, with 1.48 and 1.49 the bootstrap behaviour has changed in a way that I still don't grok. When I run x.py build --stage 2 it seems both stage0 and stage1 are built for x86_64-unknown-linux-gnu. There is no stage1 built for the host x86_64-linux which is what I would expect.

Building stage0 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage0 std from stage0 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Building stage0 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage0 rustc from stage0 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Assembling stage1 compiler (x86_64-unknown-linux-gnu)
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage1 std from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Building stage1 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Copying stage1 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Assembling stage2 compiler (x86_64-unknown-linux-gnu)
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> x86_64-linux)
Copying stage1 std from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-linux)
Uplifting stage1 std (x86_64-unknown-linux-gnu -> x86_64-linux)
Copying stage2 std from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-linux)
Building stage1 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-linux)
Copying stage1 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-linux)
Assembling stage2 compiler (x86_64-linux)
Building rustdoc for stage2 (x86_64-linux)

As a result, this step: Uplifting stage1 std (x86_64-unknown-linux-gnu -> x86_64-linux) doesn't actually do what it says. The build/x86_64-linux/stage2 directory ends up containing a compiler, but its rustlib directory is empty:

$ find build/x86_64-linux/stage2
build/x86_64-linux/stage2/
build/x86_64-linux/stage2/lib
build/x86_64-linux/stage2/lib/rustlib
build/x86_64-linux/stage2/lib/rustlib/src
build/x86_64-linux/stage2/lib/rustlib/src/rust
build/x86_64-linux/stage2/lib/rustlib/x86_64-linux
build/x86_64-linux/stage2/lib/rustlib/x86_64-linux/lib
build/x86_64-linux/stage2/lib/rustlib/x86_64-linux/codegen-backends
build/x86_64-linux/stage2/lib/libstd-0689b0d4825be2a9.so
build/x86_64-linux/stage2/lib/libtest-c874a8d9a6c5eeb1.so
build/x86_64-linux/stage2/lib/libchalk_derive-882f59f2b68bc54d.so
build/x86_64-linux/stage2/lib/librustc_driver-3d1b959398c548de.so
build/x86_64-linux/stage2/lib/librustc_macros-47465b30dcf2dd0e.so
build/x86_64-linux/stage2/lib/libtracing_attributes-72e8112b29a353da.so
build/x86_64-linux/stage2/bin
build/x86_64-linux/stage2/bin/rustc
build/x86_64-linux/stage2/bin/rustdoc

That step seems to be copying into build/x86_64-unknown-linux-gnu/stage2 instead.

Complete build config and target spec for reference:
config.toml
x86_64-linux.json

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.O-yoctoTarget: a Linux distro that builds everything from source and patches our build extensivelyT-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