diff options
Diffstat (limited to '.github/workflows/ci.yaml')
-rw-r--r-- | .github/workflows/ci.yaml | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000000..81ad91542d6b --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,420 @@ +on: + pull_request: {} + schedule: + - cron: '30 5,17 * * *' + push: + +jobs: + ci: + runs-on: ubuntu-20.04 + container: ghcr.io/rust-for-linux/ci:Rust-1.62.0-2 + timeout-minutes: 25 + + strategy: + matrix: + arch: [arm, arm64, ppc64le, riscv64, x86_64] + toolchain: [gcc, clang, llvm] + config: [debug, release] + output: [src] # [src, build] + sysroot: [common] # [common, custom] + lto: [none] # [none, thin] + + exclude: + # arm 32-bit gcc not yet supported + - arch: arm + toolchain: gcc + # arm (clang/LLVM,release) issue since Rust 1.56 + - arch: arm + toolchain: clang + config: release + - arch: arm + toolchain: llvm + config: release + # riscv64 debug (see #500 and #502). + - arch: riscv64 + config: debug + # Exclude `LLVM=1` where not supported. + - arch: ppc64le + toolchain: llvm + - arch: riscv64 + toolchain: llvm + + # A few independent combinations to avoid exploding the matrix: + # - The other option for `output`. + # - Whether to use a custom sysroot. + # - Explicitly enabling `lto` on platforms which support LTO. + include: + - arch: arm64 + toolchain: gcc + config: debug + output: build + sysroot: custom + lto: none + + - arch: arm64 + toolchain: llvm + config: debug + output: build + sysroot: custom + lto: thin + + - arch: arm64 + toolchain: llvm + config: release + output: build + sysroot: custom + lto: thin + + - arch: ppc64le + toolchain: clang + config: release + output: build + sysroot: common + lto: none + + - arch: x86_64 + toolchain: llvm + config: debug + output: build + sysroot: custom + lto: none + + - arch: x86_64 + toolchain: llvm + config: debug + output: src + sysroot: common + lto: thin + + - arch: x86_64 + toolchain: llvm + config: release + output: src + sysroot: common + lto: thin + + steps: + # Setup: checkout + - uses: actions/checkout@v2 + + # Setup: Store matrix name + - run: echo 'MATRIX_NAME=${{ matrix.arch }}-${{ matrix.toolchain }}-${{ matrix.config }}' >> $GITHUB_ENV + + # Setup: Github cache + - uses: actions/cache@v2 + with: + path: /root/.ccache + key: ${{ env.MATRIX_NAME }}-ccache-${{ github.run_id }} + restore-keys: | + ${{ env.MATRIX_NAME }}-ccache- + + # Setup: variables + - if: matrix.arch == 'x86_64' + run: | + echo 'IMAGE_PATH=arch/x86/boot/bzImage' >> $GITHUB_ENV + echo 'QEMU_ARCH=x86_64' >> $GITHUB_ENV + echo 'QEMU_MACHINE=pc' >> $GITHUB_ENV + echo 'QEMU_CPU=Cascadelake-Server' >> $GITHUB_ENV + echo 'QEMU_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_MACHINE=virt' >> $GITHUB_ENV + echo 'QEMU_CPU=cortex-a72' >> $GITHUB_ENV + - if: matrix.arch == 'ppc64le' + run: | + echo 'MAKE_ARCH=ARCH=powerpc' >> $GITHUB_ENV + echo 'MAKE_CROSS_COMPILE=CROSS_COMPILE=powerpc64le-linux-gnu-' >> $GITHUB_ENV + echo 'MAKE_LLVM_IAS=LLVM_IAS=0' >> $GITHUB_ENV + echo 'IMAGE_PATH=vmlinux' >> $GITHUB_ENV + echo 'QEMU_ARCH=ppc64' >> $GITHUB_ENV + echo 'QEMU_MACHINE=pseries' >> $GITHUB_ENV + echo 'QEMU_CPU=POWER9' >> $GITHUB_ENV + - if: matrix.arch == 'arm' + run: | + echo 'MAKE_ARCH=ARCH=arm' >> $GITHUB_ENV + echo 'MAKE_CROSS_COMPILE=CROSS_COMPILE=arm-linux-gnueabi-' >> $GITHUB_ENV + echo 'IMAGE_PATH=arch/arm/boot/zImage' >> $GITHUB_ENV + echo 'QEMU_ARCH=arm' >> $GITHUB_ENV + echo 'QEMU_MACHINE=virt' >> $GITHUB_ENV + echo 'QEMU_CPU=cortex-a7' >> $GITHUB_ENV + - if: matrix.arch == 'riscv64' + run: | + echo 'MAKE_ARCH=ARCH=riscv' >> $GITHUB_ENV + echo 'MAKE_CROSS_COMPILE=CROSS_COMPILE=riscv64-linux-gnu-' >> $GITHUB_ENV + echo 'IMAGE_PATH=arch/riscv/boot/Image' >> $GITHUB_ENV + echo 'QEMU_ARCH=riscv64' >> $GITHUB_ENV + echo 'QEMU_MACHINE=virt' >> $GITHUB_ENV + echo 'QEMU_CPU=rv64' >> $GITHUB_ENV + echo 'QEMU_ARGS=-bios /usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.elf' >> $GITHUB_ENV + + - if: matrix.toolchain == 'clang' + run: echo 'MAKE_TOOLCHAIN=CC=clang' >> $GITHUB_ENV + - if: matrix.toolchain == 'llvm' + run: echo 'MAKE_TOOLCHAIN=LLVM=1' >> $GITHUB_ENV + + # if arch is supported and ThinLTO is enabled, enable LLVM's integrated assembler + - if: matrix.arch == 'arm64' && matrix.toolchain == 'llvm' && matrix.lto == 'thin' + run: echo 'MAKE_LLVM_IAS=LLVM_IAS=1' >> $GITHUB_ENV + - if: matrix.arch == 'x86_64' && matrix.toolchain == 'llvm' && matrix.lto == 'thin' + run: echo 'MAKE_LLVM_IAS=LLVM_IAS=1' >> $GITHUB_ENV + + - if: matrix.output == 'build' + run: | + echo 'MAKE_OUTPUT=O=build' >> $GITHUB_ENV + echo 'BUILD_DIR=build/' >> $GITHUB_ENV + + # Setup: Rust + # + # `rustc` via `rustup` needs to find the `settings.xml` file, + # but GitHub overrides `$HOME` for containers. Undo it, even + # if it makes GitHub show some Docker warnings. + # See https://github.com/actions/runner/issues/863. + # + # Note that the commands need to be in their own `run` to have + # `$HOME` visible for the second one. + - run: echo 'HOME=/root' >> $GITHUB_ENV + - run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH + + - if: matrix.sysroot == 'custom' + run: | + echo 'RUSTC_SYSROOT=--sysroot=$HOME/sysroot' >> $GITHUB_ENV + echo "MAKE_SYSROOT=KRUSTFLAGS=--sysroot=$HOME/sysroot" >> $GITHUB_ENV + + # Setup: rustc native libs + - if: matrix.sysroot == 'custom' + run: | + mkdir $(rustc ${{ env.RUSTC_SYSROOT }} --print sysroot) + ln -s $(rustc --print sysroot)/lib $(rustc ${{ env.RUSTC_SYSROOT }} --print sysroot)/lib + + # Setup: ccache + - run: | + echo '/usr/lib/ccache:$PATH' >> $GITHUB_PATH + + # Setup: Check existing ccache + - run: ccache -s + + # Setup: module parameters test + - run: | + cp samples/rust/rust_module_parameters.rs samples/rust/rust_module_parameters_builtin_default.rs + cp samples/rust/rust_module_parameters.rs samples/rust/rust_module_parameters_builtin_custom.rs + cp samples/rust/rust_module_parameters.rs samples/rust/rust_module_parameters_loadable_default.rs + cp samples/rust/rust_module_parameters.rs samples/rust/rust_module_parameters_loadable_custom.rs + + sed -i 's:rust_module_parameters:rust_module_parameters_builtin_default:g' samples/rust/rust_module_parameters_builtin_default.rs + sed -i 's:rust_module_parameters:rust_module_parameters_builtin_custom:g' samples/rust/rust_module_parameters_builtin_custom.rs + sed -i 's:rust_module_parameters:rust_module_parameters_loadable_default:g' samples/rust/rust_module_parameters_loadable_default.rs + sed -i 's:rust_module_parameters:rust_module_parameters_loadable_custom:g' samples/rust/rust_module_parameters_loadable_custom.rs + + echo 'obj-y += rust_module_parameters_builtin_default.o' >> samples/rust/Makefile + echo 'obj-y += rust_module_parameters_builtin_custom.o' >> samples/rust/Makefile + echo 'obj-m += rust_module_parameters_loadable_default.o' >> samples/rust/Makefile + echo 'obj-m += rust_module_parameters_loadable_custom.o' >> samples/rust/Makefile + + # Build + - if: matrix.lto == 'none' + run: mv .github/workflows/kernel-${{ matrix.arch }}-${{ matrix.config }}.config .config + - if: matrix.lto == 'thin' + run: mv .github/workflows/kernel-${{ matrix.arch }}-${{ matrix.config }}-thinlto.config .config + + - if: matrix.output == 'build' + run: | + mkdir ${{ env.BUILD_DIR }} + mv .config ${{ env.BUILD_DIR }}.config + sed -i 's:samples/rust/:${{ env.BUILD_DIR }}samples/rust/:' .github/workflows/qemu-initramfs.desc + + - run: make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_LLVM_IAS }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 + + # Print the final config used + - run: cat ${{ env.BUILD_DIR }}.config + + # Make sure `CONFIG_WERROR` was enabled + - run: grep -F 'CONFIG_WERROR=y' ${{ env.BUILD_DIR }}.config + + # Prepare image + - run: | + mv $HOME/busybox-${{ matrix.arch }} busybox + ${{ env.BUILD_DIR }}usr/gen_init_cpio .github/workflows/qemu-initramfs.desc > qemu-initramfs.img + + # Run + - run: | + qemu-system-${{ env.QEMU_ARCH }} \ + ${{ env.QEMU_ARGS }} \ + -kernel ${{ env.BUILD_DIR }}${{ env.IMAGE_PATH }} \ + -initrd qemu-initramfs.img \ + -M ${{ env.QEMU_MACHINE }} \ + -cpu ${{ env.QEMU_CPU }} \ + -smp 2 \ + -nographic \ + -vga none \ + -no-reboot \ + -append '${{ env.QEMU_APPEND }} \ + rust_module_parameters_builtin_custom.my_bool=n \ + rust_module_parameters_builtin_custom.my_i32=345543 \ + rust_module_parameters_builtin_custom.my_str=🦀mod \ + rust_module_parameters_builtin_custom.my_usize=84 \ + rust_module_parameters_builtin_custom.my_array=1,2,3 \ + ' \ + | sed 's:\r$::' \ + | tee qemu-stdout.log + + # The kernel should not be generating any warnings + - run: | + ! grep -v 'at mm/debug_vm_pgtable.c:' qemu-stdout.log | grep '] WARNING:' + + # Check + - run: | + grep '] ok 1 - rust_kernel_doctests$' qemu-stdout.log + + - run: | + grep '] rust_minimal: Rust minimal sample (init)$' qemu-stdout.log + grep '] rust_minimal: Am I built-in? false$' qemu-stdout.log + grep '] rust_minimal: My numbers are \[72, 108, 200]$' qemu-stdout.log + grep '] rust_minimal: Rust minimal sample (exit)$' qemu-stdout.log + + - run: | + grep '] rust_print: Rust printing macros sample (init)$' qemu-stdout.log + + grep '] rust_print: Emergency message (level 0) without args$' qemu-stdout.log + grep '] rust_print: Alert message (level 1) without args$' qemu-stdout.log + grep '] rust_print: Critical message (level 2) without args$' qemu-stdout.log + grep '] rust_print: Error message (level 3) without args$' qemu-stdout.log + grep '] rust_print: Warning message (level 4) without args$' qemu-stdout.log + grep '] rust_print: Notice message (level 5) without args$' qemu-stdout.log + grep '] rust_print: Info message (level 6) without args$' qemu-stdout.log + grep '] rust_print: A line that is continued without args$' qemu-stdout.log + + grep '] rust_print: Emergency message (level 0) with args$' qemu-stdout.log + grep '] rust_print: Alert message (level 1) with args$' qemu-stdout.log + grep '] rust_print: Critical message (level 2) with args$' qemu-stdout.log + grep '] rust_print: Error message (level 3) with args$' qemu-stdout.log + grep '] rust_print: Warning message (level 4) with args$' qemu-stdout.log + grep '] rust_print: Notice message (level 5) with args$' qemu-stdout.log + grep '] rust_print: Info message (level 6) with args$' qemu-stdout.log + grep '] rust_print: A line that is continued with args$' qemu-stdout.log + + grep '] rust_print: Rust printing macros sample (exit)$' qemu-stdout.log + + - run: | + grep '] rust_module_parameters_builtin_default: Rust module parameters sample (init)' qemu-stdout.log + grep '] rust_module_parameters_builtin_default: my_bool: true$' qemu-stdout.log + grep '] rust_module_parameters_builtin_default: my_i32: 42$' qemu-stdout.log + grep '] rust_module_parameters_builtin_default: my_str: default str val$' qemu-stdout.log + grep '] rust_module_parameters_builtin_default: my_usize: 42$' qemu-stdout.log + grep '] rust_module_parameters_builtin_default: my_array: \[0, 1]$' qemu-stdout.log + + grep '] rust_module_parameters_builtin_custom: Rust module parameters sample (init)$' qemu-stdout.log + grep '] rust_module_parameters_builtin_custom: my_bool: false$' qemu-stdout.log + grep '] rust_module_parameters_builtin_custom: my_i32: 345543$' qemu-stdout.log + grep '] rust_module_parameters_builtin_custom: my_str: 🦀mod$' qemu-stdout.log + grep '] rust_module_parameters_builtin_custom: my_usize: 84$' qemu-stdout.log + grep '] rust_module_parameters_builtin_custom: my_array: \[1, 2, 3]$' qemu-stdout.log + + grep '] rust_module_parameters_loadable_default: Rust module parameters sample (init)$' qemu-stdout.log + grep '] rust_module_parameters_loadable_default: my_bool: true$' qemu-stdout.log + grep '] rust_module_parameters_loadable_default: my_i32: 42$' qemu-stdout.log + grep '] rust_module_parameters_loadable_default: my_str: default str val$' qemu-stdout.log + grep '] rust_module_parameters_loadable_default: my_usize: 42$' qemu-stdout.log + grep '] rust_module_parameters_loadable_default: my_array: \[0, 1]$' qemu-stdout.log + grep '] rust_module_parameters_loadable_default: Rust module parameters sample (exit)$' qemu-stdout.log + + grep '] rust_module_parameters_loadable_custom: Rust module parameters sample (init)$' qemu-stdout.log + grep '] rust_module_parameters_loadable_custom: my_bool: false$' qemu-stdout.log + grep '] rust_module_parameters_loadable_custom: my_i32: 345543$' qemu-stdout.log + grep '] rust_module_parameters_loadable_custom: my_str: 🦀mod$' qemu-stdout.log + grep '] rust_module_parameters_loadable_custom: my_usize: 84$' qemu-stdout.log + grep '] rust_module_parameters_loadable_custom: my_array: \[1, 2, 3]$' qemu-stdout.log + grep '] rust_module_parameters_loadable_custom: Rust module parameters sample (exit)$' qemu-stdout.log + + grep '] rust_module_parameters: Rust module parameters sample (init)$' qemu-stdout.log + grep '] rust_module_parameters: my_bool: true$' qemu-stdout.log + grep '] rust_module_parameters: my_i32: 42$' qemu-stdout.log + grep '] rust_module_parameters: my_str: default str val$' qemu-stdout.log + grep '] rust_module_parameters: my_usize: 42$' qemu-stdout.log + grep '] rust_module_parameters: my_array: \[0, 1]$' qemu-stdout.log + grep '] rust_module_parameters: Rust module parameters sample (exit)$' qemu-stdout.log + + - run: | + grep '] rust_sync: Rust synchronisation primitives sample (init)$' qemu-stdout.log + grep '] rust_sync: Value: 10$' qemu-stdout.log + grep '] rust_sync: Rust synchronisation primitives sample (exit)$' qemu-stdout.log + + - run: | + grep '] rust_chrdev: Rust character device sample (init)$' qemu-stdout.log + grep '] rust_chrdev: Rust character device sample (exit)$' qemu-stdout.log + + - run: | + grep '] rust_miscdev: Rust miscellaneous device sample (init)$' qemu-stdout.log + grep '] rust_miscdev: Rust miscellaneous device sample (exit)$' qemu-stdout.log + + - run: | + grep '] rust_stack_probing: Rust stack probing sample (init)$' qemu-stdout.log + grep '] rust_stack_probing: Large array has length: 514$' qemu-stdout.log + grep '] rust_stack_probing: Rust stack probing sample (exit)$' qemu-stdout.log + + - run: | + grep '] rust_semaphore: Rust semaphore sample (init)$' qemu-stdout.log + grep '] rust_semaphore: Rust semaphore sample (exit)$' qemu-stdout.log + + - run: | + grep '] rust_semaphore_c: Rust semaphore sample (in C, for comparison) (init)$' qemu-stdout.log + grep '] rust_semaphore_c: Rust semaphore sample (in C, for comparison) (exit)$' qemu-stdout.log + + - run: | + grep '] rust_selftests: Rust self tests (init)$' qemu-stdout.log + grep '] rust_selftests: All tests passed. Congratulations!$' qemu-stdout.log + grep '] rust_selftests: Rust self tests (exit)$' qemu-stdout.log + + # Report + - run: | + cat ${{ env.BUILD_DIR }}.config + + ls -l \ + ${{ env.BUILD_DIR }}samples/rust/*.o \ + ${{ env.BUILD_DIR }}samples/rust/*.ko \ + ${{ env.BUILD_DIR }}drivers/android/rust_binder.o \ + ${{ env.BUILD_DIR }}rust/*.o \ + ${{ env.BUILD_DIR }}vmlinux \ + ${{ env.BUILD_DIR }}${{ env.IMAGE_PATH }} + + .github/workflows/size.sh \ + ${{ env.BUILD_DIR }}samples/rust/*.o \ + ${{ env.BUILD_DIR }}samples/rust/*.ko \ + ${{ env.BUILD_DIR }}drivers/android/rust_binder.o \ + ${{ env.BUILD_DIR }}rust/*.o \ + ${{ env.BUILD_DIR }}vmlinux + + # Clippy + - run: make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_LLVM_IAS }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 CLIPPY=1 + + # Docs + - run: make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_LLVM_IAS }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 rustdoc + + # Tests + - run: make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_LLVM_IAS }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 rusttest + + # Formatting + - run: make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_LLVM_IAS }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 rustfmtcheck + + # Single targets + - run: | + rm ${{ env.BUILD_DIR }}samples/rust/rust_minimal.o + + make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_LLVM_IAS }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 samples/rust/rust_minimal.o + make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_LLVM_IAS }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 samples/rust/rust_minimal.rsi + make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_LLVM_IAS }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 samples/rust/rust_minimal.s + make ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_LLVM_IAS }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_SYSROOT }} -j3 samples/rust/rust_minimal.ll + + file ${{ env.BUILD_DIR }}samples/rust/rust_minimal.o | grep -F 'ELF' + grep -F '#![feature(prelude_import)]' ${{ env.BUILD_DIR }}samples/rust/rust_minimal.rsi + grep -F '.text' ${{ env.BUILD_DIR }}samples/rust/rust_minimal.s + grep -F '; ModuleID' ${{ env.BUILD_DIR }}samples/rust/rust_minimal.ll + + # Rust host programs + - run: ${{ env.BUILD_DIR }}samples/rust/hostprogs/single | grep -F 'The number is 42.' + + # View changes to ccache + - run: ccache -s |