| #!/bin/bash -eu |
| |
| # This requires: |
| # * Native and cross GNU toolchain (gcc, gcc-$toolsarch) |
| # * LLVM toolchain (clang, lld) |
| # * QEMU user-space static binaries (qemu-user-static) |
| # * rsync |
| # * patchelf |
| |
| build_gnu() { |
| echo "I: Using $("$toolsarch-gcc" --version | head -1)" |
| echo "I: Using $("$toolsarch-ld" --version | head -1)" |
| |
| mkdir -p "build/gnu-$toolsarch" |
| echo "I: Generating kernel UAPI headers for ARCH=$kernelarch" |
| make -C ../linux "ARCH=$kernelarch" \ |
| "INSTALL_HDR_PATH=$PWD/build/gnu-$toolsarch/linux" headers_install \ |
| || return |
| echo "I: Building with ARCH=$arch CROSS_COMPILE=$toolsarch- ${makeflags[*]}" |
| make -C "build/gnu-$toolsarch" -f "$PWD/../klibc/Makefile" -j"$nproc" \ |
| "ARCH=$arch" "CROSS_COMPILE=$toolsarch-" "KBUILD_SRC=$PWD/../klibc" \ |
| "${makeflags[@]}" all test \ |
| || return |
| } |
| |
| build_llvm() { |
| echo "I: Using $(clang --version | head -1)" |
| echo "I: Using $(ld.lld --version | head -1)" |
| |
| mkdir -p "build/llvm-$toolsarch" |
| echo "I: Generating kernel UAPI headers for ARCH=$kernelarch" |
| make -C ../linux "ARCH=$kernelarch" \ |
| "INSTALL_HDR_PATH=$PWD/build/llvm-$toolsarch/linux" headers_install \ |
| || return |
| echo "I: Building with ARCH=$arch CROSS_COMPILE=$toolsarch- CC='clang -target $toolsarch' HOSTCC=clang LD=ld.lld ${makeflags[*]}" |
| make -C "build/llvm-$toolsarch" -f "$PWD/../klibc/Makefile" -j"$nproc" \ |
| "ARCH=$arch" "CROSS_COMPILE=$toolsarch-" "KBUILD_SRC=$PWD/../klibc" \ |
| "CC=clang -target $toolsarch" "HOSTCC=clang" "LD=ld.lld" \ |
| "${makeflags[@]}" all test \ |
| || return |
| } |
| |
| clean() { |
| echo "I: Cleaning" |
| (cd ../klibc && git clean -d -f -x) |
| rm -rf "build/$tools-$toolsarch" |
| } |
| |
| run_built() { |
| # XXX We assume build architecture is x86_64 |
| case "$arch" in |
| i386 | x86_64) |
| "$@" |
| ;; |
| *) |
| "qemu-$qemuarch-static" -- "$@" |
| ;; |
| esac |
| } |
| |
| patch_interp() { |
| patchelf --set-interpreter "$PWD/build/$tools-$toolsarch/usr/klibc/klibc.so" \ |
| "$@" |
| } |
| |
| run_test_program() { |
| local flavour="$1" |
| local progname="$2" |
| shift 2 |
| local logname="test-$tools-$toolsarch-$flavour-$progname.log" |
| local err=0 |
| |
| case "$flavour" in |
| static) |
| run_built "build/$tools-$toolsarch/usr/klibc/tests/$progname" > "$logname" \ |
| || err=$? |
| ;; |
| shared) |
| patch_interp "build/$tools-$toolsarch/usr/klibc/tests/$progname.shared" |
| run_built "build/$tools-$toolsarch/usr/klibc/tests/$progname.shared" > "$logname" \ |
| || err=$? |
| ;; |
| esac |
| |
| if [ "$err" -eq 0 ]; then |
| if grep -qw ERROR "$logname"; then |
| echo "E: $progname: Error found in output" |
| return 1 |
| fi |
| while [ $# -ge 1 ]; do |
| if ! grep -qF -- "$1" "$logname"; then |
| echo "E: $progname: Expected text '$1' not found in output" |
| return 1 |
| fi |
| shift |
| done |
| echo "I: $progname: pass" |
| else |
| echo "E: $progname: fail" |
| return 1 |
| fi |
| } |
| |
| run_shell_static() { |
| local command="$1" |
| |
| if run_built "build/$tools-$toolsarch/usr/dash/static/sh" -c "$command"; then |
| echo "I: shell '$command': pass" |
| else |
| echo "E: shell '$command': fail" |
| return 1 |
| fi |
| } |
| |
| run_shell_shared() { |
| local command="$1" |
| |
| patch_interp "build/$tools-$toolsarch/usr/dash/shared/sh" |
| if run_built "build/$tools-$toolsarch/usr/dash/shared/sh" -c "$command"; then |
| echo "I: shell '$command': pass" |
| else |
| echo "E: shell '$command': fail" |
| return 1 |
| fi |
| } |
| |
| run_tests_flavour() { |
| local flavour="$1" |
| local err=0 |
| |
| run_test_program "$flavour" microhello || err=1 |
| run_test_program "$flavour" minihello || err=1 |
| run_test_program "$flavour" hello || err=1 |
| run_test_program "$flavour" environ 'Verifying envp == environ... ok' \ |
| || err=1 |
| run_test_program "$flavour" fcntl || err=1 |
| run_test_program "$flavour" malloctest || err=1 |
| run_test_program "$flavour" malloctest2 || err=1 |
| run_test_program "$flavour" opentest "Line 1 = $(head -1 /etc/passwd)" \ |
| || err=1 |
| run_test_program "$flavour" pipetest || err=1 |
| run_test_program "$flavour" select || err=1 |
| run_test_program "$flavour" setjmptest \ |
| "calling longjmp with 256... setjmp returned 256" || err=1 |
| run_test_program "$flavour" sigint "Signal received OK" || err=1 |
| run_test_program "$flavour" socket || err=1 |
| run_test_program "$flavour" sscanf || err=1 |
| run_test_program "$flavour" stdio "Hello, World!" \ |
| "Hello again - and some more - and some more" || err=1 |
| run_test_program "$flavour" strlcpycat || err=1 |
| run_test_program "$flavour" vfork || err=1 |
| |
| return $err |
| } |
| |
| run_tests() { |
| local err=0 |
| |
| run_tests_flavour static || err=1 |
| run_shell_static "exit" || err=1 |
| run_shell_static "build/$tools-$toolsarch/usr/utils/static/true; exit" || err=1 |
| |
| run_tests_flavour shared || err=1 |
| run_shell_shared "exit" || err=1 |
| patch_interp "build/$tools-$toolsarch/usr/utils/shared/true" |
| run_shell_shared "build/$tools-$toolsarch/usr/utils/shared/true; exit" || err=1 |
| |
| return $err |
| } |
| |
| process() { |
| arch="$1" |
| kernelarch="$2" |
| tools="$3" |
| toolsarch="$4" |
| qemuarch="$5" |
| shift 5 |
| makeflags=("$@") |
| |
| case "$qemuarch" in |
| *:*) |
| export QEMU_CPU="${qemuarch#*:}" |
| qemuarch="${qemuarch%:*}" |
| ;; |
| *) |
| unset QEMU_CPU |
| ;; |
| esac |
| |
| echo "I: Architecture $arch/$tools-$toolsarch: begin" |
| if clean && build_$tools && run_tests; then |
| echo "I: Architecture $arch/$tools-$toolsarch: pass" |
| clean || true |
| else |
| echo "E: Architecture $arch/$tools-$toolsarch: fail" |
| fi |
| } |
| |
| echo "I: $0 started at $(date)" |
| echo "I: Using klibc $(GIT_DIR=../klibc/.git git describe)" |
| echo "I: Using Linux $(make -C ../linux -s kernelversion)" |
| |
| nproc="$(nproc || echo 1)" |
| echo "I: Using concurrency of $nproc" |
| |
| # klibc kernel tools tools arch QEMU make flags |
| process alpha alpha gnu alpha-linux-gnu alpha |
| # arm OABI is no longer supported in Debian. |
| #process arm arm gnu arm-linux-gnu arm |
| process arm arm gnu arm-linux-gnueabi arm CONFIG_AEABI=y |
| process arm arm gnu arm-linux-gnueabihf arm CONFIG_AEABI=y CPU_ARCH=armv7-a CPU_TUNE=cortex-a8 CONFIG_KLIBC_THUMB=y |
| process arm arm llvm arm-linux-gnueabihf arm CONFIG_AEABI=y CPU_ARCH=armv7-a CPU_TUNE=cortex-a8 CONFIG_KLIBC_THUMB=y |
| process arm64 arm64 gnu aarch64-linux-gnu aarch64 |
| process arm64 arm64 llvm aarch64-linux-gnu aarch64 |
| process i386 x86 gnu i686-linux-gnu i386 |
| process i386 x86 llvm i686-linux-gnu i386 |
| # ia64 cross-compiler is currently missing in Debian, as is QEMU support. |
| #process ia64 ia64 gnu ia64-linux-gnu ??? |
| process m68k m68k gnu m68k-linux-gnu m68k |
| process mips mips gnu mips-linux-gnu mips |
| process mips mips llvm mips-linux-gnu mips |
| process mips64 mips gnu mips64-linux-gnuabi64 mips64 |
| process mips64 mips llvm mips64-linux-gnuabi64 mips64 |
| process mips mips gnu mipsel-linux-gnu mipsel |
| process mips mips llvm mipsel-linux-gnu mipsel |
| process mips64 mips gnu mips64el-linux-gnuabi64 mips64el |
| process mips64 mips llvm mips64el-linux-gnuabi64 mips64el |
| process parisc parisc gnu hppa-linux-gnu hppa |
| process ppc powerpc gnu powerpc-linux-gnu ppc |
| process ppc powerpc llvm powerpc-linux-gnu ppc |
| process ppc64 powerpc gnu powerpc64-linux-gnu ppc64 |
| process ppc64 powerpc llvm powerpc64-linux-gnu ppc64 |
| process ppc64 powerpc gnu powerpc64le-linux-gnu ppc64le |
| process ppc64 powerpc llvm powerpc64le-linux-gnu ppc64le |
| process riscv64 riscv gnu riscv64-linux-gnu riscv64 |
| process riscv64 riscv llvm riscv64-linux-gnu riscv64 |
| # 32-bit s390 is no longer supported in Debian. |
| #process s390 s390 gnu s390-linux-gnu s390 |
| process s390x s390 gnu s390x-linux-gnu s390x |
| process s390x s390 llvm s390x-linux-gnu s390x |
| process sh sh gnu sh4-linux-gnu sh4 |
| process sparc sparc gnu sparc64-linux-gnu sparc32plus LD="sparc64-linux-gnu-ld -m elf32_sparc" |
| process sparc64 sparc gnu sparc64-linux-gnu sparc64 |
| process sparc64 sparc llvm sparc64-linux-gnu sparc64 |
| process x86_64 x86 gnu x86_64-linux-gnu x86_64 |
| process x86_64 x86 llvm x86_64-linux-gnu x86_64 |
| |
| echo "I: $0 finished at $(date)" |