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