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=15.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= 20all_archs=( 21 i386 x86_64 x32 22 arm64 arm armthumb 23 mips32le mips32be mipsn32le mipsn32be mips64le mips64be 24 openrisc 25 ppc ppc64 ppc64le 26 riscv32 riscv64 27 s390x 28 loongarch 29 sparc32 sparc64 30 m68k 31 sh4 32 parisc32 33) 34archs="${all_archs[@]}" 35 36TEMP=$(getopt -o 'j:d:c:b:a:m:pelh' -n "$0" -- "$@") 37 38eval set -- "$TEMP" 39unset TEMP 40 41print_usage() { 42 cat <<EOF 43Run nolibc testsuite for multiple architectures with crosstools 44 45Usage: 46 $0 [options] <architectures> 47 48Known architectures: 49 ${archs} 50 51Options: 52 -j [N] Allow N jobs at once (default: ${nproc}) 53 -p Allow download of toolchains 54 -d [DIR] Download location for toolchains (default: ${download_location}) 55 -c [VERSION] Version of toolchains to use (default: ${crosstool_version}) 56 -a [ARCH] Host architecture of toolchains to use (default: ${hostarch}) 57 -b [DIR] Build location (default: ${build_location}) 58 -m [MODE] Test mode user/system (default: ${test_mode}) 59 -e Disable -Werror 60 -l Build with LLVM/clang 61EOF 62} 63 64while true; do 65 case "$1" in 66 '-j') 67 nproc="$2" 68 shift 2; continue ;; 69 '-p') 70 perform_download=1 71 shift; continue ;; 72 '-d') 73 download_location="$2" 74 shift 2; continue ;; 75 '-c') 76 crosstool_version="$2" 77 shift 2; continue ;; 78 '-a') 79 hostarch="$2" 80 shift 2; continue ;; 81 '-b') 82 build_location="$(realpath "$2")" 83 shift 2; continue ;; 84 '-m') 85 test_mode="$2" 86 shift 2; continue ;; 87 '-e') 88 werror=0 89 shift; continue ;; 90 '-l') 91 llvm=1 92 shift; continue ;; 93 '-h') 94 print_usage 95 exit 0 96 ;; 97 '--') 98 shift; break ;; 99 *) 100 echo 'Internal error!' >&2; exit 1 ;; 101 esac 102done 103 104if [[ -n "$*" ]]; then 105 archs="$*" 106fi 107 108crosstool_arch() { 109 case "$1" in 110 arm64) echo aarch64;; 111 armthumb) echo arm;; 112 openrisc) echo or1k;; 113 ppc) echo powerpc;; 114 ppc64) echo powerpc64;; 115 ppc64le) echo powerpc64;; 116 riscv) echo riscv64;; 117 loongarch) echo loongarch64;; 118 mips*) echo mips;; 119 s390*) echo s390;; 120 sparc*) echo sparc64;; 121 x32*) echo x86_64;; 122 parisc32) echo hppa;; 123 *) echo "$1";; 124 esac 125} 126 127crosstool_abi() { 128 case "$1" in 129 arm | armthumb) echo linux-gnueabi;; 130 *) echo linux;; 131 esac 132} 133 134download_crosstool() { 135 arch="$(crosstool_arch "$1")" 136 abi="$(crosstool_abi "$1")" 137 138 archive_name="${hostarch}-gcc-${crosstool_version}-nolibc-${arch}-${abi}.tar.gz" 139 url="https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/${hostarch}/${crosstool_version}/${archive_name}" 140 archive="${download_location}${archive_name}" 141 stamp="${archive}.stamp" 142 143 [ -f "${stamp}" ] && return 144 145 echo "Downloading crosstools ${arch} ${crosstool_version}" 146 mkdir -p "${download_location}" 147 curl -o "${archive}" --fail --continue-at - "${url}" 148 tar -C "${download_location}" -xf "${archive}" 149 touch "${stamp}" 150} 151 152# capture command output, print it on failure 153# mimics chronic(1) from moreutils 154function swallow_output() { 155 if ! OUTPUT="$("$@" 2>&1)"; then 156 echo "$OUTPUT" 157 return 1 158 fi 159 return 0 160} 161 162test_arch() { 163 arch=$1 164 ct_arch=$(crosstool_arch "$arch") 165 ct_abi=$(crosstool_abi "$1") 166 167 if [ ! -d "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/." ]; then 168 echo "No toolchain found in ${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}." 169 echo "Did you install the toolchains or set the correct arch ? Rerun with -h for help." 170 return 1 171 fi 172 173 cross_compile=$(realpath "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/${ct_arch}-${ct_abi}-") 174 build_dir="${build_location}/${arch}" 175 if [ "$werror" -ne 0 ]; then 176 CFLAGS_EXTRA="$CFLAGS_EXTRA -Werror -Wl,--fatal-warnings" 177 fi 178 MAKE=(make -f Makefile.nolibc -j"${nproc}" XARCH="${arch}" CROSS_COMPILE="${cross_compile}" LLVM="${llvm}" O="${build_dir}") 179 180 if [ "$arch" = "parisc32" ]; then 181 MAKE+=("CROSS32CC=${cross_compile}gcc") 182 fi 183 184 case "$test_mode" in 185 'system') 186 test_target=run 187 ;; 188 'user') 189 test_target=run-user 190 ;; 191 *) 192 echo "Unknown mode $test_mode" 193 exit 1 194 esac 195 printf '%-15s' "$arch:" 196 if [ "$arch" = "m68k" -o "$arch" = "sh4" -o "$arch" = "openrisc" -o "$arch" = "parisc32" ] && [ "$llvm" = "1" ]; then 197 echo "Unsupported configuration" 198 return 199 fi 200 if [ "$arch" = "x32" ] && [ "$test_mode" = "user" ]; then 201 echo "Unsupported configuration" 202 return 203 fi 204 205 mkdir -p "$build_dir" 206 swallow_output "${MAKE[@]}" defconfig 207 swallow_output "${MAKE[@]}" CFLAGS_EXTRA="$CFLAGS_EXTRA" "$test_target" V=1 208 cp run.out run.out."${arch}" 209 "${MAKE[@]}" report | grep passed 210} 211 212if [ "$perform_download" -ne 0 ]; then 213 for arch in $archs; do 214 download_crosstool "$arch" 215 done 216fi 217 218for arch in $archs; do 219 test_arch "$arch" 220done 221