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