1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# Test runner for nolibc tests 5 6set -e 7 8trap 'echo Aborting...' 'ERR' 9 10crosstool_version=13.2.0 11hostarch=x86_64 12nproc=$(( $(nproc) + 2)) 13cache_dir="${XDG_CACHE_HOME:-"$HOME"/.cache}" 14download_location="${cache_dir}/crosstools/" 15build_location="$(realpath "${cache_dir}"/nolibc-tests/)" 16perform_download=0 17test_mode=system 18werror=1 19llvm= 20archs="i386 x86_64 arm64 arm mips32le mips32be ppc ppc64 ppc64le riscv s390 loongarch" 21 22TEMP=$(getopt -o 'j:d:c:b:a:m:pelh' -n "$0" -- "$@") 23 24eval set -- "$TEMP" 25unset TEMP 26 27print_usage() { 28 cat <<EOF 29Run nolibc testsuite for multiple architectures with crosstools 30 31Usage: 32 $0 [options] <architectures> 33 34Known architectures: 35 ${archs} 36 37Options: 38 -j [N] Allow N jobs at once (default: ${nproc}) 39 -p Allow download of toolchains 40 -d [DIR] Download location for toolchains (default: ${download_location}) 41 -c [VERSION] Version of toolchains to use (default: ${crosstool_version}) 42 -a [ARCH] Host architecture of toolchains to use (default: ${hostarch}) 43 -b [DIR] Build location (default: ${build_location}) 44 -m [MODE] Test mode user/system (default: ${test_mode}) 45 -e Disable -Werror 46 -l Build with LLVM/clang 47EOF 48} 49 50while true; do 51 case "$1" in 52 '-j') 53 nproc="$2" 54 shift 2; continue ;; 55 '-p') 56 perform_download=1 57 shift; continue ;; 58 '-d') 59 download_location="$2" 60 shift 2; continue ;; 61 '-c') 62 crosstool_version="$2" 63 shift 2; continue ;; 64 '-a') 65 hostarch="$2" 66 shift 2; continue ;; 67 '-b') 68 build_location="$(realpath "$2")" 69 shift 2; continue ;; 70 '-m') 71 test_mode="$2" 72 shift 2; continue ;; 73 '-e') 74 werror=0 75 shift; continue ;; 76 '-l') 77 llvm=1 78 shift; continue ;; 79 '-h') 80 print_usage 81 exit 0 82 ;; 83 '--') 84 shift; break ;; 85 *) 86 echo 'Internal error!' >&2; exit 1 ;; 87 esac 88done 89 90if [[ -n "$*" ]]; then 91 archs="$*" 92fi 93 94crosstool_arch() { 95 case "$1" in 96 arm64) echo aarch64;; 97 ppc) echo powerpc;; 98 ppc64) echo powerpc64;; 99 ppc64le) echo powerpc64;; 100 riscv) echo riscv64;; 101 loongarch) echo loongarch64;; 102 mips*) echo mips;; 103 *) echo "$1";; 104 esac 105} 106 107crosstool_abi() { 108 case "$1" in 109 arm) echo linux-gnueabi;; 110 *) echo linux;; 111 esac 112} 113 114download_crosstool() { 115 arch="$(crosstool_arch "$1")" 116 abi="$(crosstool_abi "$1")" 117 118 archive_name="${hostarch}-gcc-${crosstool_version}-nolibc-${arch}-${abi}.tar.gz" 119 url="https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/${hostarch}/${crosstool_version}/${archive_name}" 120 archive="${download_location}${archive_name}" 121 stamp="${archive}.stamp" 122 123 [ -f "${stamp}" ] && return 124 125 echo "Downloading crosstools ${arch} ${crosstool_version}" 126 mkdir -p "${download_location}" 127 curl -o "${archive}" --fail --continue-at - "${url}" 128 tar -C "${download_location}" -xf "${archive}" 129 touch "${stamp}" 130} 131 132# capture command output, print it on failure 133# mimics chronic(1) from moreutils 134function swallow_output() { 135 if ! OUTPUT="$("$@" 2>&1)"; then 136 echo "$OUTPUT" 137 return 1 138 fi 139 return 0 140} 141 142test_arch() { 143 arch=$1 144 ct_arch=$(crosstool_arch "$arch") 145 ct_abi=$(crosstool_abi "$1") 146 cross_compile=$(realpath "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/${ct_arch}-${ct_abi}-") 147 build_dir="${build_location}/${arch}" 148 if [ "$werror" -ne 0 ]; then 149 CFLAGS_EXTRA="$CFLAGS_EXTRA -Werror" 150 fi 151 MAKE=(make -j"${nproc}" XARCH="${arch}" CROSS_COMPILE="${cross_compile}" LLVM="${llvm}" O="${build_dir}") 152 153 mkdir -p "$build_dir" 154 if [ "$test_mode" = "system" ] && [ ! -f "${build_dir}/.config" ]; then 155 swallow_output "${MAKE[@]}" defconfig 156 fi 157 case "$test_mode" in 158 'system') 159 test_target=run 160 ;; 161 'user') 162 test_target=run-user 163 ;; 164 *) 165 echo "Unknown mode $test_mode" 166 exit 1 167 esac 168 printf '%-15s' "$arch:" 169 swallow_output "${MAKE[@]}" CFLAGS_EXTRA="$CFLAGS_EXTRA" "$test_target" V=1 170 cp run.out run.out."${arch}" 171 "${MAKE[@]}" report | grep passed 172} 173 174if [ "$perform_download" -ne 0 ]; then 175 for arch in $archs; do 176 download_crosstool "$arch" 177 done 178fi 179 180for arch in $archs; do 181 test_arch "$arch" 182done 183