.github/workflows/ci.yaml #276
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
on: | |
schedule: | |
- cron: '0 8 * * *' | |
push: | |
pull_request: | |
jobs: | |
ci: | |
runs-on: ubuntu-24.04 | |
timeout-minutes: 70 | |
strategy: | |
fail-fast: false | |
matrix: | |
tree: | |
- torvalds | |
# rust-next | |
# next | |
arch: | |
- x86_64 | |
# arm64 | |
config: | |
- defconfig | |
- defconfig+debug | |
output: | |
- src | |
# subdir | |
# outside | |
env: | |
RUST_VERSION: nightly-2025-01-12 | |
steps: | |
# Setup: variables. | |
- run: echo "JOBS=-j$(($(nproc) + 1))" >> $GITHUB_ENV | |
- if: matrix.arch == 'x86_64' | |
run: | | |
echo 'MAKE_ARCH=ARCH=x86_64' >> $GITHUB_ENV | |
echo 'IMAGE_PATH=arch/x86/boot/bzImage' >> $GITHUB_ENV | |
echo 'QEMU_ARCH=x86_64' >> $GITHUB_ENV | |
echo 'QEMU_ARGS=-append console=ttyS0' >> $GITHUB_ENV | |
- if: matrix.arch == 'arm64' | |
run: | | |
echo 'MAKE_ARCH=ARCH=arm64' >> $GITHUB_ENV | |
echo 'MAKE_CROSS_COMPILE=CROSS_COMPILE=aarch64-linux-gnu-' >> $GITHUB_ENV | |
echo 'IMAGE_PATH=arch/arm64/boot/Image.gz' >> $GITHUB_ENV | |
echo 'QEMU_ARCH=aarch64' >> $GITHUB_ENV | |
echo 'QEMU_ARGS=-machine virt' >> $GITHUB_ENV | |
- if: matrix.output == 'src' | |
run: | | |
echo 'OUTPUT_DIR=linux/' >> $GITHUB_ENV | |
- if: matrix.output == 'subdir' | |
run: | | |
echo 'MAKE_OUTPUT=O=subdir' >> $GITHUB_ENV | |
echo 'OUTPUT_DIR=linux/subdir/' >> $GITHUB_ENV | |
- if: matrix.output == 'outside' | |
run: | | |
echo 'MAKE_OUTPUT=O=../outside' >> $GITHUB_ENV | |
echo 'OUTPUT_DIR=outside/' >> $GITHUB_ENV | |
- run: | | |
sudo apt-get -y update | |
sudo apt-get -y --no-install-recommends install bc file git make flex bison libelf-dev libssl-dev curl python3 llvm clang lld binutils qemu-system-x86 qemu-system-arm | |
- if: matrix.arch == 'arm64' | |
run: sudo apt-get -y --no-install-recommends install gcc-aarch64-linux-gnu libc6-dev-arm64-cross | |
# Setup: checkout Linux source tree. | |
- if: matrix.tree == 'torvalds' | |
run: git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux | |
- if: startsWith(matrix.tree, 'rust-') | |
run: git clone --depth 1 --branch ${{ matrix.tree }} https://github.com/Rust-for-Linux/linux.git linux | |
- if: matrix.tree == 'next' | |
run: git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git linux | |
- run: git -C linux show --no-patch | |
# Setup: checkout CI tree. | |
- uses: actions/checkout@v4 | |
with: | |
path: ci | |
- run: git -C linux apply ../ci/x86-boot-Use-std-gnu11-to-fix-build-with-GCC-15.patch | |
# Setup: `busybox`. | |
- run: | | |
git clone --depth 1 -b 1_30_1 https://git.busybox.net/busybox/ | |
mv ci/busybox.config busybox/.config | |
make -C busybox ${{ env.MAKE_CROSS_COMPILE }} ${{ env.JOBS }} busybox | |
# Setup: Rust. | |
- run: | | |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \ | |
-y \ | |
--no-modify-path \ | |
--default-toolchain $RUST_VERSION \ | |
--profile minimal \ | |
--component rust-src \ | |
--component rustfmt \ | |
--component clippy | |
echo "$HOME/.cargo/bin" >> $GITHUB_PATH | |
# Setup: `rustc_codegen_gcc`. | |
- run: | | |
sudo apt-get -y --no-install-recommends purge cpp gcc | |
curl --proto '=https' --tlsv1.2 -sSfLO https://github.com/rust-lang/gcc/releases/latest/download/gcc-15.deb | |
sudo dpkg -i gcc-15.deb | |
git clone --depth 1 https://github.com/rust-lang/rustc_codegen_gcc | |
echo "MAKE_KRUSTFLAGS=KRUSTFLAGS=-Zcodegen-backend=$(pwd)/rustc_codegen_gcc/target/release/librustc_codegen_gcc.so" >> $GITHUB_ENV | |
cd rustc_codegen_gcc | |
echo 'gcc-path = "/usr/lib"' > config.toml | |
#sed -i '/channel/d' rust-toolchain | |
export RUSTC_BOOTSTRAP=1 | |
./y.sh prepare --only-libcore | |
./y.sh build --sysroot --release | |
# Setup: `bindgen`. | |
- run: cargo install --locked --version 0.70.1 bindgen-cli | |
# Prepare build output folder. | |
- if: matrix.output != 'src' | |
run: | | |
mkdir ${{ env.OUTPUT_DIR }} | |
sed -i 's:linux/samples/rust/:${{ env.OUTPUT_DIR }}samples/rust/:' ci/qemu-initramfs.desc | |
# Make sure Rust is available. | |
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} rustavailable | |
# Configure kernel. | |
- run: cp ci/*.config linux/kernel/configs/ | |
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} defconfig rfl-${{ matrix.arch }}.config rfl-rust.config | |
- if: matrix.config == 'defconfig+debug' | |
run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} rfl-debug.config | |
# Dump kernel configuration before the build and save it. | |
- run: | | |
cat ${{ env.OUTPUT_DIR }}.config | |
cp ${{ env.OUTPUT_DIR }}.config config-before | |
# Build. | |
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} | |
# Check the kernel configuration did not change, just in case. | |
- run: diff -u config-before ${{ env.OUTPUT_DIR }}.config | |
# Make sure certain key configs were enabled. | |
- run: grep -F 'CONFIG_RUST=y' ${{ env.OUTPUT_DIR }}.config | |
# Report other data. | |
- run: | | |
ls -l \ | |
${{ env.OUTPUT_DIR }}samples/rust/*.o \ | |
${{ env.OUTPUT_DIR }}samples/rust/*.ko \ | |
${{ env.OUTPUT_DIR }}rust/*.o \ | |
${{ env.OUTPUT_DIR }}vmlinux \ | |
${{ env.OUTPUT_DIR }}${{ env.IMAGE_PATH }} | |
ci/size.sh \ | |
${{ env.OUTPUT_DIR }}samples/rust/*.o \ | |
${{ env.OUTPUT_DIR }}samples/rust/*.ko \ | |
${{ env.OUTPUT_DIR }}rust/*.o \ | |
${{ env.OUTPUT_DIR }}vmlinux | |
# Check `.comment` section. | |
- run: | | |
readelf --string-dump .comment ${{ env.OUTPUT_DIR }}rust/core.o | |
objcopy --dump-section .comment=comment ${{ env.OUTPUT_DIR }}rust/core.o | |
grep --text "^.rustc version .* with libgccjit" comment | |
grep --text 'libgccjit' comment | |
grep --text 'GCC: ' comment | |
# Prepare image. | |
- run: ${{ env.OUTPUT_DIR }}usr/gen_init_cpio ci/qemu-initramfs.desc > qemu-initramfs.img | |
# Run in QEMU. | |
- run: | | |
qemu-system-${{ env.QEMU_ARCH }} \ | |
${{ env.QEMU_ARGS }} \ | |
-kernel ${{ env.OUTPUT_DIR }}${{ env.IMAGE_PATH }} \ | |
-initrd qemu-initramfs.img \ | |
-smp 2 \ | |
-nographic \ | |
-vga none \ | |
-no-reboot \ | |
| sed 's:\r$::' \ | |
| tee qemu-stdout | |
# Check QEMU log output. | |
- run: | | |
grep '] rust_minimal: Rust minimal sample (init)$' qemu-stdout | |
grep '] rust_minimal: Am I built-in? false$' qemu-stdout | |
grep '] rust_minimal: My numbers are \[72, 108, 200]$' qemu-stdout | |
grep '] rust_minimal: Rust minimal sample (exit)$' qemu-stdout | |
- run: | | |
grep '] rust_print: Rust printing macros sample (init)$' qemu-stdout | |
grep '] rust_print: Emergency message (level 0) without args$' qemu-stdout | |
grep '] rust_print: Alert message (level 1) without args$' qemu-stdout | |
grep '] rust_print: Critical message (level 2) without args$' qemu-stdout | |
grep '] rust_print: Error message (level 3) without args$' qemu-stdout | |
grep '] rust_print: Warning message (level 4) without args$' qemu-stdout | |
grep '] rust_print: Notice message (level 5) without args$' qemu-stdout | |
grep '] rust_print: Info message (level 6) without args$' qemu-stdout | |
grep '] rust_print: A line that is continued without args$' qemu-stdout | |
grep '] rust_print: Emergency message (level 0) with args$' qemu-stdout | |
grep '] rust_print: Alert message (level 1) with args$' qemu-stdout | |
grep '] rust_print: Critical message (level 2) with args$' qemu-stdout | |
grep '] rust_print: Error message (level 3) with args$' qemu-stdout | |
grep '] rust_print: Warning message (level 4) with args$' qemu-stdout | |
grep '] rust_print: Notice message (level 5) with args$' qemu-stdout | |
grep '] rust_print: Info message (level 6) with args$' qemu-stdout | |
grep '] rust_print: A line that is continued with args$' qemu-stdout | |
- run: grep '] ok 1 rust_doctests_kernel$' qemu-stdout | |
- run: | | |
grep -i '\bpanic\b' qemu-stdout && exit 1 | |
grep -i '\boops\b' qemu-stdout && exit 1 | |
grep -i '\btaint\b' qemu-stdout && exit 1 | |
grep -i '\bfault\b' qemu-stdout && exit 1 | |
grep -i '\btrace\b' qemu-stdout && exit 1 | |
grep -i '\bcorrupted\b' qemu-stdout && exit 1 | |
grep -i '\bbug\b' qemu-stdout | | |
grep -Fv '" and report a bug' && | |
exit 1 | |
grep -i '\berror\b' qemu-stdout | | |
grep -Fv 'message (level 3)' | | |
grep -Fv 'regulatory.db' && | |
exit 1 | |
grep -i '\bwarning\b' qemu-stdout | | |
grep -Fv 'message (level 4)' && | |
exit 1 | |
exit 0 | |
# Re-build with Clippy. | |
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} CLIPPY=1 | |
# Generate Rust documentation. | |
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} rustdoc | |
# Check `#[test]`s. | |
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} rusttest | |
# Check formatting. | |
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} rustfmtcheck | |
# Test single targets. | |
- run: | | |
rm ${{ env.OUTPUT_DIR }}samples/rust/rust_minimal.o | |
make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} samples/rust/rust_minimal.o | |
file ${{ env.OUTPUT_DIR }}samples/rust/rust_minimal.o | grep -F 'ELF' | |
- run: | | |
make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} samples/rust/rust_minimal.rsi | |
grep -F '#![feature(prelude_import)]' ${{ env.OUTPUT_DIR }}samples/rust/rust_minimal.rsi | |
- run: | | |
make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} samples/rust/rust_minimal.s | |
grep -F '.text' ${{ env.OUTPUT_DIR }}samples/rust/rust_minimal.s | |
# Test Rust host programs. | |
- run: ${{ env.OUTPUT_DIR }}samples/rust/hostprogs/single | grep -F 'The number is 42.' |