Skip to content

Commit 2b9cece

Browse files
committed
Initial commit
Signed-off-by: Miguel Ojeda <[email protected]>
0 parents  commit 2b9cece

10 files changed

+882
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
on:
2+
schedule:
3+
- cron: '0 8 * * *'
4+
push:
5+
6+
jobs:
7+
ci:
8+
runs-on: ubuntu-22.04
9+
container: ghcr.io/rust-for-linux/ci
10+
11+
timeout-minutes: 70
12+
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
tree:
17+
- rust-next
18+
# rust-fixes
19+
# rust-dev
20+
21+
# next
22+
23+
# stable/linux-6.7.y
24+
# stable-rc/linux-6.7.y
25+
26+
# stable/linux-6.6.y
27+
# stable-rc/linux-6.6.y
28+
29+
# stable/linux-6.1.y
30+
# stable-rc/linux-6.1.y
31+
32+
arch:
33+
- x86_64
34+
# arm64
35+
36+
toolchain:
37+
# llvm
38+
- rustc_codegen_gcc
39+
40+
config:
41+
- defconfig
42+
- defconfig+debug
43+
44+
output:
45+
- src
46+
# subdir
47+
# outside
48+
49+
include:
50+
# # `arch: arm64` (with `rust-dev`).
51+
# - tree: rust-dev
52+
# arch: arm64
53+
# toolchain: rustc_codegen_gcc
54+
# config: defconfig
55+
# output: src
56+
#
57+
# # `arch: arm64` (with `rust-dev` + `defconfig+debug`).
58+
# - tree: rust-dev
59+
# arch: arm64
60+
# toolchain: rustc_codegen_gcc
61+
# config: defconfig+debug
62+
# output: src
63+
64+
# `output: subdir`.
65+
- tree: rust-next
66+
arch: x86_64
67+
toolchain: rustc_codegen_gcc
68+
config: defconfig
69+
output: subdir
70+
71+
# `output: outside`.
72+
- tree: rust-next
73+
arch: x86_64
74+
toolchain: rustc_codegen_gcc
75+
config: defconfig
76+
output: outside
77+
78+
exclude:
79+
# Rust 1.71.1 (in Linux 6.6) had a bug: it generated `.eh_frame` with debug assertions enabled.
80+
- tree: stable/linux-6.6.y
81+
config: defconfig+debug
82+
83+
# Rust 1.71.1 (in Linux 6.6) had a bug: it generated `.eh_frame` with debug assertions enabled.
84+
- tree: stable-rc/linux-6.6.y
85+
config: defconfig+debug
86+
87+
steps:
88+
# Setup: variables.
89+
- run: echo "JOBS=-j$(($(nproc) + 1))" >> $GITHUB_ENV
90+
91+
- if: matrix.arch == 'x86_64'
92+
run: |
93+
echo 'MAKE_ARCH=ARCH=x86_64' >> $GITHUB_ENV
94+
echo 'IMAGE_PATH=arch/x86/boot/bzImage' >> $GITHUB_ENV
95+
echo 'QEMU_ARCH=x86_64' >> $GITHUB_ENV
96+
echo 'QEMU_ARGS=-append console=ttyS0' >> $GITHUB_ENV
97+
- if: matrix.arch == 'arm64'
98+
run: |
99+
echo 'MAKE_ARCH=ARCH=arm64' >> $GITHUB_ENV
100+
echo 'MAKE_CROSS_COMPILE=CROSS_COMPILE=aarch64-linux-gnu-' >> $GITHUB_ENV
101+
echo 'IMAGE_PATH=arch/arm64/boot/Image.gz' >> $GITHUB_ENV
102+
echo 'QEMU_ARCH=aarch64' >> $GITHUB_ENV
103+
echo 'QEMU_ARGS=-machine virt' >> $GITHUB_ENV
104+
105+
- if: matrix.toolchain == 'llvm'
106+
run: echo 'MAKE_TOOLCHAIN=LLVM=1' >> $GITHUB_ENV
107+
108+
- if: matrix.output == 'src'
109+
run: |
110+
echo 'OUTPUT_DIR=linux/' >> $GITHUB_ENV
111+
- if: matrix.output == 'subdir'
112+
run: |
113+
echo 'MAKE_OUTPUT=O=subdir' >> $GITHUB_ENV
114+
echo 'OUTPUT_DIR=linux/subdir/' >> $GITHUB_ENV
115+
- if: matrix.output == 'outside'
116+
run: |
117+
echo 'MAKE_OUTPUT=O=/outside' >> $GITHUB_ENV
118+
echo 'OUTPUT_DIR=/outside/' >> $GITHUB_ENV
119+
120+
# Setup: checkout Linux source tree.
121+
- if: startsWith(matrix.tree, 'rust-')
122+
run: git clone --depth 1 --branch ${{ matrix.tree }} https://github.com/Rust-for-Linux/linux.git linux
123+
- if: startsWith(matrix.tree, 'next')
124+
run: git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git linux
125+
- if: startsWith(matrix.tree, 'stable/')
126+
run: git clone --depth 1 --branch $(echo ${{ matrix.tree }} | cut -d/ -f2-) https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git linux
127+
- if: startsWith(matrix.tree, 'stable-rc/')
128+
run: git clone --depth 1 --branch $(echo ${{ matrix.tree }} | cut -d/ -f2-) https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux
129+
130+
- run: git -C linux show --no-patch
131+
132+
# Setup: checkout CI tree.
133+
- uses: actions/checkout@v4
134+
with:
135+
path: ci
136+
137+
# Setup: Rust.
138+
- run: |
139+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \
140+
-y \
141+
--no-modify-path \
142+
--default-toolchain $(linux/scripts/min-tool-version.sh rustc) \
143+
--profile minimal \
144+
--component rust-src \
145+
--component rustfmt \
146+
--component clippy
147+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
148+
149+
# Setup: `rustc_codegen_gcc`.
150+
- if: matrix.toolchain == 'rustc_codegen_gcc'
151+
run: |
152+
apt-get -y --no-install-recommends purge cpp gcc
153+
curl --proto '=https' --tlsv1.2 -sSfLO https://github.com/antoyo/gcc/releases/download/master/gcc-13.deb
154+
dpkg -i gcc-13.deb
155+
156+
git clone --depth 1 --branch $(linux/scripts/min-tool-version.sh rustc) https://github.com/rust-lang/rust.git rust-repo
157+
# FIXME: 1.75.0 only: avoid `.eh_frame` error.
158+
git config --global user.email "[email protected]"
159+
git config --global user.name "Your Name"
160+
git -C rust-repo am ../ci/0001-Do-not-emit-.eh_frame-section-when-using-Cpanic-abor.patch
161+
162+
echo "MAKE_KRUSTFLAGS=KRUSTFLAGS=-Zcodegen-backend=$(pwd)/rust-repo/compiler/rustc_codegen_gcc/target/release/librustc_codegen_gcc.so" >> $GITHUB_ENV
163+
164+
cd rust-repo/compiler/rustc_codegen_gcc
165+
echo /usr/lib > gcc_path
166+
sed -i '/channel/d' rust-toolchain
167+
export RUSTC_BOOTSTRAP=1
168+
./y.sh prepare --only-libcore
169+
./y.sh build --release --features master
170+
171+
# Setup: `bindgen`.
172+
#
173+
# The `bindgen` package name is only used for 6.1 LTS.
174+
- run: |
175+
cargo install --locked --version $(linux/scripts/min-tool-version.sh bindgen) bindgen-cli ||
176+
cargo install --locked --version $(linux/scripts/min-tool-version.sh bindgen) bindgen
177+
178+
# Setup: `busybox`.
179+
- run: cp /root/busybox-${{ matrix.arch }} /root/busybox
180+
181+
# Prepare build output folder.
182+
- if: matrix.output != 'src'
183+
run: |
184+
mkdir ${{ env.OUTPUT_DIR }}
185+
sed -i 's:linux/samples/rust/:${{ env.OUTPUT_DIR }}samples/rust/:' ci/qemu-initramfs.desc
186+
187+
# Make sure Rust is available.
188+
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} rustavailable
189+
190+
# Configure kernel.
191+
- run: cp ci/*.config linux/kernel/configs/
192+
193+
- 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
194+
195+
- if: matrix.config == 'defconfig+debug'
196+
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
197+
198+
# Dump kernel configuration before the build and save it.
199+
- run: |
200+
cat ${{ env.OUTPUT_DIR }}.config
201+
cp ${{ env.OUTPUT_DIR }}.config config-before
202+
203+
# Build.
204+
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }}
205+
206+
# Check the kernel configuration did not change, just in case.
207+
- run: diff -u config-before ${{ env.OUTPUT_DIR }}.config
208+
209+
# Make sure certain key configs were enabled.
210+
- run: |
211+
grep -F 'CONFIG_RUST=y' ${{ env.OUTPUT_DIR }}.config
212+
grep -F 'CONFIG_WERROR=y' ${{ env.OUTPUT_DIR }}.config
213+
214+
# Prepare image.
215+
- run: ${{ env.OUTPUT_DIR }}usr/gen_init_cpio ci/qemu-initramfs.desc > qemu-initramfs.img
216+
217+
# Run in QEMU.
218+
- run: |
219+
qemu-system-${{ env.QEMU_ARCH }} \
220+
${{ env.QEMU_ARGS }} \
221+
-kernel ${{ env.OUTPUT_DIR }}${{ env.IMAGE_PATH }} \
222+
-initrd qemu-initramfs.img \
223+
-smp 2 \
224+
-nographic \
225+
-vga none \
226+
-no-reboot \
227+
| sed 's:\r$::' \
228+
| tee qemu-stdout
229+
230+
# Report other data.
231+
- run: |
232+
ls -l
233+
234+
ls -l \
235+
${{ env.OUTPUT_DIR }}samples/rust/*.o \
236+
${{ env.OUTPUT_DIR }}samples/rust/*.ko \
237+
${{ env.OUTPUT_DIR }}rust/*.o \
238+
${{ env.OUTPUT_DIR }}vmlinux \
239+
${{ env.OUTPUT_DIR }}${{ env.IMAGE_PATH }}
240+
241+
ci/size.sh \
242+
${{ env.OUTPUT_DIR }}samples/rust/*.o \
243+
${{ env.OUTPUT_DIR }}samples/rust/*.ko \
244+
${{ env.OUTPUT_DIR }}rust/*.o \
245+
${{ env.OUTPUT_DIR }}vmlinux
246+
247+
# Check `.comment` section.
248+
- if: matrix.toolchain == 'llvm'
249+
run: |
250+
if [ $(linux/scripts/min-tool-version.sh rustc | cut -d'.' -f2) -ge 73 ]; then
251+
llvm-readelf --string-dump .comment ${{ env.OUTPUT_DIR }}rust/core.o
252+
llvm-objcopy --dump-section .comment=comment ${{ env.OUTPUT_DIR }}rust/core.o
253+
grep --text "^.rustc version $(linux/scripts/min-tool-version.sh rustc)" comment
254+
else
255+
echo 'Skipping since `rustc` < 1.73.0.'
256+
fi
257+
- if: matrix.toolchain == 'rustc_codegen_gcc'
258+
run: |
259+
llvm-readelf --string-dump .comment ${{ env.OUTPUT_DIR }}rust/core.o
260+
llvm-objcopy --dump-section .comment=comment ${{ env.OUTPUT_DIR }}rust/core.o
261+
# TODO: starting with Rust 1.76.0, we should check for the improved `.comment` section.
262+
grep --text '^.GCC: ' comment
263+
264+
# Check QEMU log output.
265+
- run: |
266+
grep '] rust_minimal: Rust minimal sample (init)$' qemu-stdout
267+
grep '] rust_minimal: Am I built-in? false$' qemu-stdout
268+
grep '] rust_minimal: My numbers are \[72, 108, 200]$' qemu-stdout
269+
grep '] rust_minimal: Rust minimal sample (exit)$' qemu-stdout
270+
271+
# Linux 6.1 does not have `rust_print`.
272+
- if: ${{ ! contains(matrix.tree, '6.1') }}
273+
run: |
274+
grep '] rust_print: Rust printing macros sample (init)$' qemu-stdout
275+
276+
grep '] rust_print: Emergency message (level 0) without args$' qemu-stdout
277+
grep '] rust_print: Alert message (level 1) without args$' qemu-stdout
278+
grep '] rust_print: Critical message (level 2) without args$' qemu-stdout
279+
grep '] rust_print: Error message (level 3) without args$' qemu-stdout
280+
grep '] rust_print: Warning message (level 4) without args$' qemu-stdout
281+
grep '] rust_print: Notice message (level 5) without args$' qemu-stdout
282+
grep '] rust_print: Info message (level 6) without args$' qemu-stdout
283+
grep '] rust_print: A line that is continued without args$' qemu-stdout
284+
285+
grep '] rust_print: Emergency message (level 0) with args$' qemu-stdout
286+
grep '] rust_print: Alert message (level 1) with args$' qemu-stdout
287+
grep '] rust_print: Critical message (level 2) with args$' qemu-stdout
288+
grep '] rust_print: Error message (level 3) with args$' qemu-stdout
289+
grep '] rust_print: Warning message (level 4) with args$' qemu-stdout
290+
grep '] rust_print: Notice message (level 5) with args$' qemu-stdout
291+
grep '] rust_print: Info message (level 6) with args$' qemu-stdout
292+
grep '] rust_print: A line that is continued with args$' qemu-stdout
293+
294+
# Linux 6.1 does not have KUnit `rustdoc` tests.
295+
- if: ${{ matrix.config == 'defconfig+debug' && ! contains(matrix.tree, '6.1') }}
296+
run: grep '] ok 1 rust_doctests_kernel$' qemu-stdout
297+
298+
- run: |
299+
grep -i '\bpanic\b' qemu-stdout && exit 1
300+
grep -i '\boops\b' qemu-stdout && exit 1
301+
grep -i '\btaint\b' qemu-stdout && exit 1
302+
grep -i '\bfault\b' qemu-stdout && exit 1
303+
grep -i '\btrace\b' qemu-stdout && exit 1
304+
grep -i '\bcorrupted\b' qemu-stdout && exit 1
305+
306+
grep -i '\bbug\b' qemu-stdout |
307+
grep -Fv '" and report a bug' &&
308+
exit 1
309+
310+
grep -i '\berror\b' qemu-stdout |
311+
grep -Fv 'message (level 3)' |
312+
grep -Fv 'regulatory.db' &&
313+
exit 1
314+
315+
grep -i '\bwarning\b' qemu-stdout |
316+
grep -Fv 'message (level 4)' &&
317+
exit 1
318+
319+
exit 0
320+
321+
# Re-build with Clippy.
322+
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} CLIPPY=1
323+
324+
# Generate Rust documentation.
325+
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} rustdoc
326+
327+
# Check `#[test]`s.
328+
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} rusttest
329+
330+
# Check formatting.
331+
- run: make -C linux ${{ env.MAKE_ARCH }} ${{ env.MAKE_CROSS_COMPILE }} ${{ env.MAKE_TOOLCHAIN }} ${{ env.MAKE_OUTPUT }} ${{ env.MAKE_KRUSTFLAGS }} ${{ env.JOBS }} rustfmtcheck
332+
333+
# Test single targets.
334+
- run: |
335+
rm ${{ env.OUTPUT_DIR }}samples/rust/rust_minimal.o
336+
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
337+
file ${{ env.OUTPUT_DIR }}samples/rust/rust_minimal.o | grep -F 'ELF'
338+
339+
# Rust 1.71.1 (in Linux 6.6) had a bug: it does not generate dependency files.
340+
- if: ${{ ! contains(matrix.tree, '6.6') }}
341+
run: |
342+
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
343+
grep -F '#![feature(prelude_import)]' ${{ env.OUTPUT_DIR }}samples/rust/rust_minimal.rsi
344+
345+
- run: |
346+
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
347+
grep -F '.text' ${{ env.OUTPUT_DIR }}samples/rust/rust_minimal.s
348+
349+
- if: matrix.toolchain == 'llvm'
350+
run: |
351+
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.ll
352+
grep -F '; ModuleID' ${{ env.OUTPUT_DIR }}samples/rust/rust_minimal.ll
353+
354+
# Test Rust host programs.
355+
- run: ${{ env.OUTPUT_DIR }}samples/rust/hostprogs/single | grep -F 'The number is 42.'

0 commit comments

Comments
 (0)