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