From d374190955ce925e7ec3a3ccd8762f1a80152255 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 26 Oct 2025 03:50:03 -0400 Subject: [PATCH 1/6] ci: Update targets in verify-build Do a few things: * Update the list to reflect current target tiers. * Add some missing T2 targets (includes ohos and gnullvm). * Remove unneeded `dist = False` and minimum toolchain config. * Delete some `-none-` targets, which don't make use of libc. * Add a check for duplicates. * Re-group and sort the lists. --- ci/verify-build.py | 127 +++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 56 deletions(-) diff --git a/ci/verify-build.py b/ci/verify-build.py index 09d185658f7e..a5f14a0df363 100755 --- a/ci/verify-build.py +++ b/ci/verify-build.py @@ -77,81 +77,90 @@ def run_on(self) -> Os: FREEBSD_VERSIONS = [11, 12, 13, 14, 15] +# FIXME(ohos): CI fails with warnings TARGETS = [ - # linux - Target("aarch64-linux-android"), + # Tier 1 + Target("aarch64-apple-darwin"), + Target("aarch64-pc-windows-msvc"), Target("aarch64-unknown-linux-gnu"), + Target("i686-pc-windows-msvc"), + Target("i686-unknown-linux-gnu"), + Target("x86_64-pc-windows-gnu"), + Target("x86_64-pc-windows-msvc"), + Target("x86_64-unknown-linux-gnu"), + # + # Tier 2 with host tools + Target("aarch64-pc-windows-gnullvm", min_toolchain=Toolchain.STABLE), Target("aarch64-unknown-linux-musl"), - Target("arm-linux-androideabi"), + # Target("aarch64-unknown-linux-ohos"), Target("arm-unknown-linux-gnueabi"), Target("arm-unknown-linux-gnueabihf"), + Target("armv7-unknown-linux-gnueabihf"), + # Target("armv7-unknown-linux-ohos"), + Target("i686-pc-windows-gnu"), + Target("loongarch64-unknown-linux-gnu", min_toolchain=Toolchain.STABLE), + Target("loongarch64-unknown-linux-musl", min_toolchain=Toolchain.STABLE), + Target("powerpc-unknown-linux-gnu"), + Target("powerpc64-unknown-linux-gnu"), + Target("powerpc64le-unknown-linux-gnu"), + Target("powerpc64le-unknown-linux-musl", min_toolchain=Toolchain.STABLE), + Target("riscv64gc-unknown-linux-gnu"), + Target("s390x-unknown-linux-gnu"), + Target("sparcv9-sun-solaris"), + Target("x86_64-apple-darwin"), + Target("x86_64-pc-solaris"), + Target("x86_64-pc-windows-gnullvm", min_toolchain=Toolchain.STABLE), + Target("x86_64-unknown-freebsd"), + Target("x86_64-unknown-illumos"), + Target("x86_64-unknown-linux-musl"), + # Target("x86_64-unknown-linux-ohos"), + Target("x86_64-unknown-netbsd"), + # + # Tier 2 without host tools + Target("aarch64-apple-ios"), + Target("aarch64-linux-android"), + Target("aarch64-unknown-fuchsia", min_toolchain=Toolchain.STABLE), + Target("arm-linux-androideabi"), Target("arm-unknown-linux-musleabi"), Target("arm-unknown-linux-musleabihf"), + Target("armv5te-unknown-linux-gnueabi"), + Target("armv5te-unknown-linux-musleabi"), Target("armv7-linux-androideabi"), - Target("armv7-unknown-linux-gnueabihf"), Target("armv7-unknown-linux-musleabihf"), Target("i586-unknown-linux-gnu"), Target("i586-unknown-linux-musl"), Target("i686-linux-android"), Target("i686-unknown-freebsd"), - Target("i686-unknown-linux-gnu"), Target("i686-unknown-linux-musl"), - Target("powerpc-unknown-linux-gnu"), - Target("powerpc64-unknown-linux-gnu"), - Target("powerpc64le-unknown-linux-gnu"), - Target("s390x-unknown-linux-gnu"), Target("sparc64-unknown-linux-gnu"), - Target("sparcv9-sun-solaris"), Target("wasm32-unknown-emscripten"), Target("wasm32-unknown-unknown"), - # Target was renamed Target("wasm32-wasip1", min_toolchain=Toolchain.STABLE), Target("wasm32-wasip2", min_toolchain=Toolchain.STABLE), + Target("x86_64-fortanix-unknown-sgx"), Target("x86_64-linux-android"), - Target("x86_64-unknown-freebsd"), - Target("x86_64-unknown-linux-gnu"), - Target("x86_64-unknown-linux-musl"), - Target("x86_64-unknown-netbsd"), - # nightly linux - # FIXME(powerpc64le): powerpc64le-unknown-linux-musl is tier 2 since 1.85 and - # can be moved to rust_linux_targets once MSRV is increased - Target("aarch64-unknown-fuchsia", min_toolchain=Toolchain.NIGHTLY), - Target("armv5te-unknown-linux-gnueabi", min_toolchain=Toolchain.NIGHTLY), - Target("armv5te-unknown-linux-musleabi", min_toolchain=Toolchain.NIGHTLY), - Target("i686-pc-windows-gnu", min_toolchain=Toolchain.NIGHTLY), - Target("powerpc64le-unknown-linux-musl", min_toolchain=Toolchain.NIGHTLY), - Target("riscv64gc-unknown-linux-gnu", min_toolchain=Toolchain.NIGHTLY), - Target("x86_64-fortanix-unknown-sgx", min_toolchain=Toolchain.NIGHTLY), - Target("x86_64-pc-solaris", min_toolchain=Toolchain.NIGHTLY), - Target("x86_64-pc-windows-gnu", min_toolchain=Toolchain.NIGHTLY), - Target("x86_64-unknown-fuchsia", min_toolchain=Toolchain.NIGHTLY), - Target("x86_64-unknown-illumos", min_toolchain=Toolchain.NIGHTLY), - Target("x86_64-unknown-linux-gnux32", min_toolchain=Toolchain.NIGHTLY), - Target("x86_64-unknown-redox", min_toolchain=Toolchain.NIGHTLY), - # apple - Target("aarch64-apple-darwin"), - Target("aarch64-apple-ios"), - # windows - Target("x86_64-pc-windows-msvc"), - Target("x86_64-pc-windows-gnu"), - Target("i686-pc-windows-msvc"), - # linux nodist - # Targets which are not available via rustup and must be built with -Zbuild-std - # FIXME(hexagon): hexagon-unknown-linux-musl should be tested but currently has - # duplicate symbol errors from `compiler_builtins`. - Target("aarch64-pc-windows-msvc", dist=False), + Target("x86_64-unknown-fuchsia", min_toolchain=Toolchain.STABLE), + Target("x86_64-unknown-linux-gnux32"), + Target("x86_64-unknown-redox"), + # + # Libc has historically checked that a number of tier 3 targets build. Technically + # there is no need to do this given the target tier policy, but the cost is small + # and the saved churn from accidental breakage is significant, so we keep it around. Target("aarch64-unknown-freebsd", dist=False), Target("aarch64-unknown-hermit", dist=False), + Target("aarch64-unknown-illumos", dist=False), Target("aarch64-unknown-netbsd", dist=False), Target("aarch64-unknown-openbsd", dist=False), Target("aarch64-wrs-vxworks", dist=False), - Target("armebv7r-none-eabi", dist=False), Target("armebv7r-none-eabihf", dist=False), Target("armv7-wrs-vxworks-eabihf", dist=False), - Target("armv7r-none-eabi", dist=False), Target("armv7r-none-eabihf", dist=False), - Target("i686-pc-windows-msvc", dist=False), + Target("armv7s-apple-ios", dist=False), + Target("hexagon-unknown-linux-musl", dist=False), + Target("i386-apple-ios", dist=False), + Target("i686-apple-darwin", dist=False), Target("i686-unknown-haiku", dist=False), + Target("i686-unknown-hurd-gnu", dist=False), Target("i686-unknown-netbsd", dist=False), Target("i686-unknown-openbsd", dist=False), Target("i686-wrs-vxworks", dist=False), @@ -168,40 +177,35 @@ def run_on(self) -> Os: Target("powerpc-unknown-netbsd", dist=False), Target("powerpc-wrs-vxworks", dist=False), Target("powerpc-wrs-vxworks-spe", dist=False), + Target("powerpc64-ibm-aix", dist=False), Target("powerpc64-unknown-freebsd", dist=False), Target("powerpc64-wrs-vxworks", dist=False), + Target("riscv32-wrs-vxworks", dist=False), + Target("riscv32gc-unknown-linux-gnu", dist=False), Target("riscv32i-unknown-none-elf", dist=False), Target("riscv32imac-unknown-none-elf", dist=False), Target("riscv32imc-unknown-none-elf", dist=False), - Target("riscv32gc-unknown-linux-gnu", dist=False), - Target("riscv32-wrs-vxworks", dist=False), + Target("riscv64-wrs-vxworks", dist=False), + Target("riscv64a23-unknown-linux-gnu", dist=False), Target("riscv64gc-unknown-freebsd", dist=False), Target("riscv64gc-unknown-hermit", dist=False), Target("riscv64gc-unknown-linux-musl", dist=False), Target("riscv64gc-unknown-none-elf", dist=False), Target("riscv64imac-unknown-none-elf", dist=False), - Target("riscv64-wrs-vxworks", dist=False), Target("s390x-unknown-linux-musl", dist=False), Target("sparc-unknown-linux-gnu", dist=False), Target("sparc64-unknown-netbsd", dist=False), - Target("thumbv6m-none-eabi", dist=False), - Target("thumbv7em-none-eabi", dist=False), Target("thumbv7em-none-eabihf", dist=False), Target("thumbv7m-none-eabi", dist=False), Target("thumbv7neon-linux-androideabi", dist=False), Target("thumbv7neon-unknown-linux-gnueabihf", dist=False), Target("thumbv8m.main-none-eabi", dist=False), - Target("x86_64-pc-windows-msvc", dist=False), Target("x86_64-unknown-dragonfly", dist=False), Target("x86_64-unknown-haiku", dist=False), Target("x86_64-unknown-hermit", dist=False), Target("x86_64-unknown-l4re-uclibc", dist=False), Target("x86_64-unknown-openbsd", dist=False), Target("x86_64-wrs-vxworks", dist=False), - # apple nodist - Target("armv7s-apple-ios", dist=False), - Target("i686-apple-darwin", dist=False), - Target("i386-apple-ios", dist=False), ] @@ -230,6 +234,16 @@ def run(args: list[str], /, env: Optional[dict[str, str]] = None): sp.run(args, env=env, check=True) +def check_dup_targets(): + all = set() + duplicates = set() + for target in TARGETS: + if target.name in all: + duplicates.add(target.name) + all.add(target.name) + assert len(duplicates) == 0, f"duplicate targets: {duplicates}" + + def test_target(cfg: Cfg, target: Target): env = os.environ.copy() env.setdefault("RUSTFLAGS", "") @@ -315,6 +329,7 @@ def main(): cfg = Cfg(toolchain_name=args.toolchain) eprint(f"Config: {cfg}") eprint("Python version: ", sys.version) + check_dup_targets() if cfg.nightly(): # Needed for build-std From 484637cda3d634b0edfff35aa4c3c19735e70595 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 26 Oct 2025 04:09:25 -0400 Subject: [PATCH 2/6] ci: Always run verify-build on Linux Most of the targets are cross compiled anyway, and there isn't any advantage to running on native platforms. Start running everything on Linux which is the fastest and cheapest runner. As part of this, introduce a way to run only half of the target list from a single invocation. This is used to split the nightly job in two, each now only taking about as long as the stable job. --- .github/workflows/ci.yaml | 19 ++++++++++++++----- ci/verify-build.py | 38 +++++++++++++++----------------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a17d0e33ea28..46cdfdc521de 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -55,12 +55,18 @@ jobs: name: Verify build strategy: matrix: - toolchain: [stable, nightly, 1.63.0] - os: [ubuntu-24.04, macos-15, windows-2025] + toolchain: [stable, 1.63.0] include: + # Nightly has a lot of targets, so split it in half + - toolchain: nightly + half: 1 + - toolchain: nightly + half: 2 - toolchain: beta - os: ubuntu-24.04 - runs-on: ${{ matrix.os }} + only: '(aarch64|x86_64)' # just a spot check for beta + - toolchain: stable + - toolchain: 1.63.0 # msrv + runs-on: ubuntu-24.04 timeout-minutes: 25 env: TOOLCHAIN: ${{ matrix.toolchain }} @@ -92,7 +98,10 @@ jobs: perl -i -ne 'print unless /"ctest(-test)?",/ || /"libc-test",/' Cargo.toml fi - python3 ci/verify-build.py --toolchain "$TOOLCHAIN" + python3 ci/verify-build.py \ + --toolchain "$TOOLCHAIN" \ + ${{ matrix.only && format('--only "{0}"', matrix.only) }} \ + ${{ matrix.half && format('--half "{0}"', matrix.half) }} - name: Target size after job completion run: du -sh target | sort -k 2 diff --git a/ci/verify-build.py b/ci/verify-build.py index a5f14a0df363..f27fde35e50c 100755 --- a/ci/verify-build.py +++ b/ci/verify-build.py @@ -64,16 +64,6 @@ def __post_init__(self): # We will need to use build-std self.min_toolchain = Toolchain.NIGHTLY - def run_on(self) -> Os: - """MacOS CI runs all apple targets, Windows CI runs all Windows targets, - Linux CI handles everything else.""" - - if "apple" in self.name: - return Os.DARWIN - elif "windows" in self.name: - return Os.WINDOWS - return Os.LINUX - FREEBSD_VERSIONS = [11, 12, 13, 14, 15] @@ -324,6 +314,12 @@ def main(): p.add_argument("--toolchain", required=True, help="Rust toolchain") p.add_argument("--only", help="only targets matching this regex") p.add_argument("--skip", help="skip targets matching this regex") + p.add_argument( + "--half", + type=int, + choices=[1, 2], + help="specify 1 or 2 to run half of the targets", + ) args = p.parse_args() cfg = Cfg(toolchain_name=args.toolchain) @@ -346,30 +342,26 @@ def main(): targets = [t for t in targets if cfg.toolchain >= t.min_toolchain] eprint(f"Targets checkable with this toolchain: {len(targets)}") - # Targets get split among the diferent CI runners - targets = [t for t in targets if t.run_on() == cfg.os_] - eprint(f"Targets checked on this OS: {len(targets)}") - # Apply filtering if args.only: targets = [t for t in targets if re.match(args.only, t.name)] if args.skip: targets = [t for t in targets if not re.match(args.skip, t.name)] + # Allow splitting the targets in half for time improvements + if args.half == 1: + targets = targets[0::2] + elif args.half == 2: + targets = targets[1::2] + total = len(targets) eprint(f"Targets to run: {total}") assert total > 0, "some tests should be run" for i, target in enumerate(targets): - # HACK: We need to install the toolchain by name for most Windows toolchains, - # but not when cross compiling. - if cfg.os_ == Os.WINDOWS and "aarch64" not in target.name: - run( - ["sh", "./ci/install-rust.sh"], env=os.environ | {"TARGET": target.name} - ) - - eprint(f"::group::Target: {target.name} ({i}/{total})") - eprint(f"{ESC_CYAN}Checking target {target} ({i}/{total}){ESC_END}") + at = i + 1 + eprint(f"::group::Target: {target.name} ({at}/{total})") + eprint(f"{ESC_CYAN}Checking target {target} ({at}/{total}){ESC_END}") test_target(cfg, target) eprint("::endgroup::") From db92b911523f12ac4f3e13ee20b685c52419bf83 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 26 Oct 2025 04:46:55 -0400 Subject: [PATCH 3/6] ci: Print elapsed time as part of verify-build --- ci/verify-build.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/ci/verify-build.py b/ci/verify-build.py index f27fde35e50c..9c7e272bc8c9 100755 --- a/ci/verify-build.py +++ b/ci/verify-build.py @@ -1,14 +1,15 @@ #!/usr/bin/env python3 -import re -import os import argparse +import os +import platform +import re import subprocess as sp import sys -import platform -from typing import Optional -from enum import Enum, IntEnum +import time from dataclasses import dataclass, field +from enum import Enum, IntEnum +from typing import Optional ESC_CYAN = "\033[1;36m" @@ -235,6 +236,7 @@ def check_dup_targets(): def test_target(cfg: Cfg, target: Target): + start = time.time() env = os.environ.copy() env.setdefault("RUSTFLAGS", "") @@ -306,7 +308,8 @@ def test_target(cfg: Cfg, target: Target): else: eprint("Skipping semver checks") - eprint(f"Finished checking target {tname}") + elapsed = round(time.time() - start, 2) + eprint(f"Finished checking target {tname} in {elapsed} seconds") def main(): @@ -326,6 +329,7 @@ def main(): eprint(f"Config: {cfg}") eprint("Python version: ", sys.version) check_dup_targets() + start = time.time() if cfg.nightly(): # Needed for build-std @@ -365,5 +369,8 @@ def main(): test_target(cfg, target) eprint("::endgroup::") + elapsed = round(time.time() - start, 2) + eprint(f"Checked {total} targets in {elapsed} seconds") + main() From bf6078eedebe4d15b3112148a6a198f383a0c799 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 26 Oct 2025 04:54:02 -0400 Subject: [PATCH 4/6] ci: Launch create-artifacts.py with python We have occasional CI failures on Windows where the environment variables don't get set so the artifact upload fails. Looking at the logs, it doesn't even appear the create-artifact job ran (but there are no errors). The Windows runners sometimes have trouble launching python scripts via `./`, so switch to using the python3 executable in hopes that this helps. --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 46cdfdc521de..a717b805ffa4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -163,7 +163,7 @@ jobs: - name: Create CI artifacts id: create_artifacts if: always() - run: ./ci/create-artifacts.py + run: python3 ci/create-artifacts.py - uses: actions/upload-artifact@v4 if: always() && steps.create_artifacts.outcome == 'success' with: From 6bb706bda8d691772c6a227186166c9bbd7a3112 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 26 Oct 2025 04:59:58 -0400 Subject: [PATCH 5/6] aix: Resolve function comparison and `unnecessary_transmutes` warnings --- src/unix/aix/mod.rs | 2 ++ src/unix/aix/powerpc64.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/unix/aix/mod.rs b/src/unix/aix/mod.rs index c0983f6a2b16..51ef3768ac08 100644 --- a/src/unix/aix/mod.rs +++ b/src/unix/aix/mod.rs @@ -327,6 +327,8 @@ s! { pub cmsg_type: c_int, } + // FIXME(1.0): This should not implement `PartialEq` + #[allow(unpredictable_function_pointer_comparisons)] pub struct sigevent { pub sigev_value: crate::sigval, pub sigev_signo: c_int, diff --git a/src/unix/aix/powerpc64.rs b/src/unix/aix/powerpc64.rs index 1b62859ae163..f3a4419efb38 100644 --- a/src/unix/aix/powerpc64.rs +++ b/src/unix/aix/powerpc64.rs @@ -448,7 +448,7 @@ cfg_if! { impl hash::Hash for fpreg_t { fn hash(&self, state: &mut H) { - let d: u64 = unsafe { mem::transmute(self.d) }; + let d: u64 = self.d.to_bits(); d.hash(state); } } From 178948422b3002c9bd5a77495118e86d3dfa9fe7 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 26 Oct 2025 05:31:30 -0400 Subject: [PATCH 6/6] ci: For no-dist targets, do a check rather than a full build --- ci/verify-build.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ci/verify-build.py b/ci/verify-build.py index 9c7e272bc8c9..c5eb22dbd770 100755 --- a/ci/verify-build.py +++ b/ci/verify-build.py @@ -248,7 +248,15 @@ def test_target(cfg: Cfg, target: Target): assert target_bits in ["32", "64"] eprint(f"env {target_env}, os {target_os}, bits {target_bits}") - cmd = ["cargo", f"+{cfg.toolchain_name}", "build", "--target", tname] + # Usually we do a full build to make sure we don't run into any crashes or link + # problems. If we need to use build-std, though, only do a check to speed + # things up. + if target.dist: + action = "build" + else: + action = "check" + + cmd = ["cargo", f"+{cfg.toolchain_name}", action, "--target", tname] if not target.dist: # If we can't download a `core`, we need to build it