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 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 *) echo "$1";; 119 esac 120} 121 122crosstool_abi() { 123 case "$1" in 124 arm | armthumb) echo linux-gnueabi;; 125 *) echo linux;; 126 esac 127} 128 129download_crosstool() { 130 arch="$(crosstool_arch "$1")" 131 abi="$(crosstool_abi "$1")" 132 133 archive_name="${hostarch}-gcc-${crosstool_version}-nolibc-${arch}-${abi}.tar.gz" 134 url="https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/${hostarch}/${crosstool_version}/${archive_name}" 135 archive="${download_location}${archive_name}" 136 stamp="${archive}.stamp" 137 138 [ -f "${stamp}" ] && return 139 140 echo "Downloading crosstools ${arch} ${crosstool_version}" 141 mkdir -p "${download_location}" 142 curl -o "${archive}" --fail --continue-at - "${url}" 143 tar -C "${download_location}" -xf "${archive}" 144 touch "${stamp}" 145} 146 147# capture command output, print it on failure 148# mimics chronic(1) from moreutils 149function swallow_output() { 150 if ! OUTPUT="$("$@" 2>&1)"; then 151 echo "$OUTPUT" 152 return 1 153 fi 154 return 0 155} 156 157test_arch() { 158 arch=$1 159 ct_arch=$(crosstool_arch "$arch") 160 ct_abi=$(crosstool_abi "$1") 161 162 if [ ! -d "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/." ]; then 163 echo "No toolchain found in ${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}." 164 echo "Did you install the toolchains or set the correct arch ? Rerun with -h for help." 165 return 1 166 fi 167 168 cross_compile=$(realpath "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/${ct_arch}-${ct_abi}-") 169 build_dir="${build_location}/${arch}" 170 if [ "$werror" -ne 0 ]; then 171 CFLAGS_EXTRA="$CFLAGS_EXTRA -Werror" 172 fi 173 MAKE=(make -f Makefile.nolibc -j"${nproc}" XARCH="${arch}" CROSS_COMPILE="${cross_compile}" LLVM="${llvm}" O="${build_dir}") 174 175 case "$test_mode" in 176 'system') 177 test_target=run 178 ;; 179 'user') 180 test_target=run-user 181 ;; 182 *) 183 echo "Unknown mode $test_mode" 184 exit 1 185 esac 186 printf '%-15s' "$arch:" 187 if [ "$arch" = "s390" ] && ([ "$llvm" = "1" ] || [ "$test_mode" = "user" ]); then 188 echo "Unsupported configuration" 189 return 190 fi 191 if [ "$arch" = "m68k" -o "$arch" = "sh4" ] && [ "$llvm" = "1" ]; then 192 echo "Unsupported configuration" 193 return 194 fi 195 196 mkdir -p "$build_dir" 197 swallow_output "${MAKE[@]}" defconfig 198 swallow_output "${MAKE[@]}" CFLAGS_EXTRA="$CFLAGS_EXTRA" "$test_target" V=1 199 cp run.out run.out."${arch}" 200 "${MAKE[@]}" report | grep passed 201} 202 203if [ "$perform_download" -ne 0 ]; then 204 for arch in $archs; do 205 download_crosstool "$arch" 206 done 207fi 208 209for arch in $archs; do 210 test_arch "$arch" 211done 212