Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -154,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:
Expand Down
194 changes: 108 additions & 86 deletions ci/verify-build.py
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -64,94 +65,93 @@ 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]

# 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),
Expand All @@ -168,40 +168,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),
]


Expand Down Expand Up @@ -230,7 +225,18 @@ 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):
start = time.time()
env = os.environ.copy()
env.setdefault("RUSTFLAGS", "")

Expand All @@ -242,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
Expand Down Expand Up @@ -302,19 +316,28 @@ 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():
p = argparse.ArgumentParser()
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)
eprint(f"Config: {cfg}")
eprint("Python version: ", sys.version)
check_dup_targets()
start = time.time()

if cfg.nightly():
# Needed for build-std
Expand All @@ -331,32 +354,31 @@ 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::")

elapsed = round(time.time() - start, 2)
eprint(f"Checked {total} targets in {elapsed} seconds")


main()
2 changes: 2 additions & 0 deletions src/unix/aix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/unix/aix/powerpc64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ cfg_if! {

impl hash::Hash for fpreg_t {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
let d: u64 = unsafe { mem::transmute(self.d) };
let d: u64 = self.d.to_bits();
d.hash(state);
}
}
Expand Down