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