-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.sh
executable file
·255 lines (243 loc) · 12.1 KB
/
main.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
x() {
local cmd="$1"
shift
(
set -x
"${cmd}" "$@"
)
}
retry() {
for i in {1..5}; do
if "$@"; then
return 0
else
sleep "${i}"
fi
done
"$@"
}
bail() {
echo "::error::$*"
exit 1
}
warn() {
echo "::warning::$*"
}
export DEBIAN_FRONTEND=noninteractive
export RUSTUP_MAX_RETRIES="${RUSTUP_MAX_RETRIES:-10}"
if [[ $# -gt 0 ]]; then
bail "invalid argument '$1'"
fi
target="${INPUT_TARGET:?}"
runner="${INPUT_RUNNER:-}"
target_lower="${target//-/_}"
target_lower="${target_lower//./_}"
target_upper="$(tr '[:lower:]' '[:upper:]' <<<"${target_lower}")"
host=$(rustc -Vv | grep host | sed 's/host: //')
rustc_version=$(rustc -Vv | grep 'release: ' | sed 's/release: //')
rustup_target_list=$(rustup target list)
# Refs: https://github.com/multiarch/qemu-user-static.
register_binfmt() {
local url=https://raw.githubusercontent.com/qemu/qemu/44f28df24767cf9dca1ddc9b23157737c4cbb645/scripts/qemu-binfmt-conf.sh
retry curl --proto '=https' --tlsv1.2 -fsSL --retry 10 --retry-connrefused -o __qemu-binfmt-conf.sh "${url}"
chmod +x ./__qemu-binfmt-conf.sh
if [ ! -d /proc/sys/fs/binfmt_misc ]; then
bail "kernel does not support binfmt"
fi
if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
sudo mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
fi
sudo ./__qemu-binfmt-conf.sh --qemu-path /usr/bin --persistent yes
rm ./__qemu-binfmt-conf.sh
}
case "${host}" in
x86_64-unknown-linux-gnu)
apt_packages=()
case "${target}" in
x86_64-unknown-linux-gnu) ;;
*-linux-gnu*)
# https://github.com/taiki-e/rust-cross-toolchain/blob/main/docker/linux-gnu.sh
case "${target}" in
aarch64_be-unknown-linux-gnu)
# (tier3) Toolchains for aarch64_be-linux-gnu is not available in APT.
# https://github.com/taiki-e/rust-cross-toolchain/blob/590d6cb4d3a72c26c5096f2ad3033980298cd4aa/docker/linux-gnu.sh#L40
bail "target '${target}' not yet supported; consider using aarch64-unknown-linux-gnu for testing aarch64"
;;
arm-unknown-linux-gnueabihf)
# (tier2) Ubuntu's gcc-arm-linux-gnueabihf enables armv7 by default
# https://github.com/taiki-e/rust-cross-toolchain/blob/590d6cb4d3a72c26c5096f2ad3033980298cd4aa/docker/linux-gnu.sh#L55
bail "target '${target}' not yet supported; consider using armv7-unknown-linux-gnueabihf for testing armhf"
;;
riscv32gc-unknown-linux-gnu)
# (tier3) Toolchains for riscv32-linux-gnu is not available in APT.
# https://github.com/taiki-e/rust-cross-toolchain/blob/590d6cb4d3a72c26c5096f2ad3033980298cd4aa/docker/linux-gnu.sh#L69
# Suggest riscv64 because instructions available on riscv32 are also available on riscv64,
# so testing in riscv64 may cover riscv32-related code.
bail "target '${target}' not yet supported; consider using riscv64gc-unknown-linux-gnu for testing RISC-V"
;;
sparc-unknown-linux-gnu)
# (tier3) Setup is tricky, and fails to build test.
# https://github.com/taiki-e/rust-cross-toolchain/blob/590d6cb4d3a72c26c5096f2ad3033980298cd4aa/docker/linux-gnu.Dockerfile#L44
# https://github.com/taiki-e/rust-cross-toolchain/blob/590d6cb4d3a72c26c5096f2ad3033980298cd4aa/docker/test/test.sh#L241
bail "target '${target}' not yet supported"
;;
esac
case "${target}" in
arm*hf | thumbv7neon-*) cc_target=arm-linux-gnueabihf ;;
arm*) cc_target=arm-linux-gnueabi ;;
riscv32gc-* | riscv64gc-*) cc_target="${target/gc-unknown/}" ;;
sparc-*)
cc_target=sparc-linux-gnu
apt_target=sparc64-linux-gnu
multilib=1
;;
*) cc_target="${target/-unknown/}" ;;
esac
apt_target="${apt_target:-"${cc_target/i586/i686}"}"
# TODO: can we reduce the setup time by providing an option to skip installing packages for C++?
apt_packages+=("g++-${multilib:+multilib-}${apt_target/_/-}")
# https://github.com/taiki-e/rust-cross-toolchain/blob/main/docker/test/entrypoint.sh
echo "CARGO_TARGET_${target_upper}_LINKER=${apt_target}-gcc" >>"${GITHUB_ENV}"
echo "CC_${target_lower}=${apt_target}-gcc" >>"${GITHUB_ENV}"
echo "CXX_${target_lower}=${apt_target}-g++" >>"${GITHUB_ENV}"
echo "AR_${target_lower}=${apt_target}-ar" >>"${GITHUB_ENV}"
echo "STRIP=${apt_target}-strip" >>"${GITHUB_ENV}"
echo "OBJDUMP=${apt_target}-objdump" >>"${GITHUB_ENV}"
;;
*) bail "unsupported target '${target}'" ;;
esac
case "${target}" in
*-unknown-linux-*)
use_qemu=''
case "${runner}" in
'')
case "${target}" in
# On x86, qemu-user is not used by default.
x86_64-* | i*86-*) ;;
*) use_qemu='1' ;;
esac
;;
qemu-user) use_qemu='1' ;;
*) bail "unrecognized runner '${runner}'" ;;
esac
if [[ -n "${use_qemu}" ]]; then
# https://github.com/taiki-e/rust-cross-toolchain/blob/590d6cb4d3a72c26c5096f2ad3033980298cd4aa/docker/test/entrypoint.sh#L251
# We basically set the newer and more powerful CPU as the
# default QEMU_CPU so that we can test more CPU features.
# In some contexts, we want to test for a specific CPU,
# so respect user-set QEMU_CPU.
case "${target}" in
aarch64-* | aarch64_be-*)
qemu_arch="${target%%-*}"
qemu_cpu=a64fx
;;
arm* | thumbv7neon-*)
qemu_arch=arm
case "${target}" in
# ARMv6: https://en.wikipedia.org/wiki/ARM11
arm-* | armv6-*) qemu_cpu=arm11mpcore ;;
# ARMv4: https://en.wikipedia.org/wiki/StrongARM
armv4t-*) qemu_cpu=sa1110 ;;
# ARMv5TE
armv5te-*) qemu_cpu=arm1026 ;;
# ARMv7-A+NEONv2
armv7-* | thumbv7neon-*) qemu_cpu=cortex-a15 ;;
*) bail "unrecognized target '${target}'" ;;
esac
;;
i*86-*) qemu_arch=i386 ;;
hexagon-*) qemu_arch=hexagon ;;
m68k-*) qemu_arch=m68k ;;
mips-* | mipsel-*) qemu_arch="${target%%-*}" ;;
mips64-* | mips64el-*)
qemu_arch="${target%%-*}"
# As of qemu 6.1, only Loongson-3A4000 supports MSA instructions with mips64r5.
qemu_cpu=Loongson-3A4000
;;
mipsisa32r6-* | mipsisa32r6el-*)
qemu_arch="${target%%-*}"
qemu_arch="${qemu_arch/isa32r6/}"
qemu_cpu=mips32r6-generic
;;
mipsisa64r6-* | mipsisa64r6el-*)
qemu_arch="${target%%-*}"
qemu_arch="${qemu_arch/isa64r6/64}"
qemu_cpu=I6400
;;
powerpc-*spe)
qemu_arch=ppc
qemu_cpu=e500v2
;;
powerpc-*)
qemu_arch=ppc
qemu_cpu=Vger
;;
powerpc64-*)
qemu_arch=ppc64
qemu_cpu=power10
;;
powerpc64le-*)
qemu_arch=ppc64le
qemu_cpu=power10
;;
riscv32gc-* | riscv64gc-*) qemu_arch="${target%%gc-*}" ;;
s390x-*) qemu_arch=s390x ;;
sparc-*) qemu_arch=sparc32plus ;;
sparc64-*) qemu_arch=sparc64 ;;
x86_64-*)
qemu_arch=x86_64
# qemu does not seem to support emulating x86_64 CPU features on x86_64 hosts.
# > qemu-x86_64: warning: TCG doesn't support requested feature
#
# A way that works well for emulating x86_64 CPU features on x86_64 hosts is to use Intel SDE.
# https://www.intel.com/content/www/us/en/developer/articles/tool/software-development-emulator.html
# It is not OSS, but it is licensed under Intel Simplified Software License and redistribution is allowed.
# https://www.intel.com/content/www/us/en/developer/articles/license/pre-release-license-agreement-for-software-development-emulator.html
# https://www.intel.com/content/www/us/en/developer/articles/license/onemkl-license-faq.html
;;
*) bail "unrecognized target '${target}'" ;;
esac
echo "CARGO_TARGET_${target_upper}_RUNNER=qemu-${qemu_arch}" >>"${GITHUB_ENV}"
if [[ -n "${qemu_cpu:-}" ]] && [[ -z "${QEMU_CPU:-}" ]]; then
echo "QEMU_CPU=${qemu_cpu}" >>"${GITHUB_ENV}"
fi
case "${target}" in
*-linux-gnu*) qemu_ld_prefix="/usr/${apt_target}" ;;
esac
if [[ -n "${qemu_ld_prefix:-}" ]] && [[ -z "${QEMU_LD_PREFIX:-}" ]]; then
echo "QEMU_LD_PREFIX=${qemu_ld_prefix}" >>"${GITHUB_ENV}"
fi
# https://github.com/taiki-e/dockerfiles/pkgs/container/qemu-user
docker create --name qemu-user ghcr.io/taiki-e/qemu-user
mkdir -p .setup-cross-toolchain
docker cp qemu-user:/usr/bin .setup-cross-toolchain/qemu
docker rm -f qemu-user >/dev/null
sudo mv .setup-cross-toolchain/qemu/qemu-* /usr/bin/
rm -rf ./.setup-cross-toolchain
x qemu-${qemu_arch} --version
register_binfmt
fi
;;
esac
retry sudo apt-get -o Acquire::Retries=10 -qq update
retry sudo apt-get -o Acquire::Retries=10 -qq -o Dpkg::Use-Pty=0 install -y --no-install-recommends \
"${apt_packages[@]}"
;;
*) bail "unsupported host '${host}'" ;;
esac
if grep <<<"${rustup_target_list}" -Eq "^${target}( |$)"; then
retry rustup target add "${target}" &>/dev/null
else
# for -Z build-std
retry rustup component add rust-src &>/dev/null
echo "BUILD_STD=-Z build-std" >>"${GITHUB_ENV}"
fi
echo "CARGO_BUILD_TARGET=${target}" >>"${GITHUB_ENV}"
if [[ "${rustc_version}" == *"nightly"* ]] || [[ "${rustc_version}" == *"dev"* ]]; then
if cargo -Z help | grep -Eq '-Z doctest-xcompile\b'; then
echo "DOCTEST_XCOMPILE=-Z doctest-xcompile" >>"${GITHUB_ENV}"
fi
fi