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