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