changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > infra / check.sh

changeset 232: 8b62bc1ae25c
parent: b1a96e0e3add
child: 7c6e3bbfe8cd
author: Richard Westhaver <ellis@rwest.io>
date: Sun, 26 May 2024 21:11:52 +0000
permissions: -rwxr-xr-x
description: more porting over to skelfile
1 #!/usr/bin/env sh
2 set -eu
3 main() {
4  need_cmd uname
5  need_cmd mktemp
6  need_cmd chmod
7  need_cmd mkdir
8  need_cmd rm
9  need_cmd rmdir
10  need_cmd tar
11  need_cmd zstd
12  need_cmd hg
13  need_cmd git
14  # need_cmd clang
15  need_cmd grep
16  need_cmd awk
17  need_cmd head
18  need_cmd tail
19  host_config_file=$(cat /proc/sys/kernel/hostname).sxp
20  rm -f $host_config_file
21  check_mem
22  local _mem_total="$RETVAL"
23  check_disk
24  check_mod kvm
25  get_architecture || return 1
26  local _arch="$RETVAL"
27  assert_nz "$_arch" "arch"
28  _write ";; -*- mode:skel -*-"
29  _write ":arch \"$_arch\""
30  kernel_version
31  local _kernel_version="$RETVAL"
32  _write ":kernel \"$_kernel_version\""
33  check_cpus
34  local _num_cpus="$RETVAL"
35  _write ":cpus $_num_cpus"
36  _write ":mem $_mem_total"
37  case "$_arch" in
38  *windows*)
39  _write ":ext \"exe\""
40  ;;
41  *)
42  _write ":ext nil"
43  esac
44  print_env
45 }
46 
47 say() {
48  printf '%s\n' "$1"
49 }
50 
51 say_var() {
52  say "$1=$(eval echo "\$$1" 2> /dev/null)"
53 }
54 
55 _write() {
56  say "$1" >> $host_config_file
57 }
58 
59 err() {
60  say "$1" >&2
61  exit 1
62 }
63 
64 assert_nz() {
65  if [ -z "$1" ]; then err "assert_nz $2"; fi
66 }
67 
68 check_cmd() {
69  command -v "$1" > /dev/null 2>&1
70 }
71 
72 need_cmd() {
73  if ! check_cmd "$1"; then
74  err "need '$1' (command not found)"
75  fi
76 }
77 
78 ensure() {
79  if ! "$@"; then err "command failed: $*"; fi
80 }
81 
82 check_proc() {
83  # Check for /proc by looking for the /proc/self/exe link
84  # This is only run on Linux
85  if ! test -L /proc/self/exe ; then
86  err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
87  fi
88 }
89 
90 get_bitness() {
91  # Architecture detection without dependencies beyond coreutils.
92  # ELF files start out "\x7fELF", and the following byte is
93  # 0x01 for 32-bit and
94  # 0x02 for 64-bit.
95  # The printf builtin on some shells like dash only supports octal
96  # escape sequences, so we use those.
97  local _current_exe_head
98  _current_exe_head=$(head -c 5 /proc/self/exe )
99  if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
100  echo 32
101  elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
102  echo 64
103  else
104  err "unknown platform bitness"
105  fi
106 }
107 
108 is_host_amd64_elf() {
109  # ELF e_machine detection without dependencies beyond coreutils.
110  # Two-byte field at offset 0x12 indicates the CPU,
111  # but we're interested in it being 0x3E to indicate amd64, or not that.
112  local _current_exe_machine
113  _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
114  [ "$_current_exe_machine" = "$(printf '\076')" ]
115 }
116 
117 get_endianness() {
118  local cputype=$1
119  local suffix_eb=$2
120  local suffix_el=$3
121 
122  # detect endianness without od/hexdump, like get_bitness() does.
123  local _current_exe_endianness
124  _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
125  if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then
126  echo "${cputype}${suffix_el}"
127  elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then
128  echo "${cputype}${suffix_eb}"
129  else
130  err "unknown platform endianness"
131  fi
132 }
133 
134 get_architecture() {
135  local _ostype _cputype _bitness _arch _clibtype
136  _ostype="$(uname -s)"
137  _cputype="$(uname -m)"
138  _clibtype="gnu"
139 
140  if [ "$_ostype" = Linux ]; then
141  if [ "$(uname -o)" = Android ]; then
142  _ostype=Android
143  fi
144  if ldd --version 2>&1 | grep -q 'musl'; then
145  _clibtype="musl"
146  fi
147  fi
148 
149  if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then
150  # Darwin `uname -m` lies
151  if sysctl hw.optional.x86_64 | grep -q ': 1'; then
152  _cputype=x86_64
153  fi
154  fi
155 
156  if [ "$_ostype" = SunOS ]; then
157  # Both Solaris and illumos presently announce as "SunOS" in "uname -s"
158  # so use "uname -o" to disambiguate. We use the full path to the
159  # system uname in case the user has coreutils uname first in PATH,
160  # which has historically sometimes printed the wrong value here.
161  if [ "$(/usr/bin/uname -o)" = illumos ]; then
162  _ostype=illumos
163  fi
164 
165  # illumos systems have multi-arch userlands, and "uname -m" reports the
166  # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
167  # systems. Check for the native (widest) instruction set on the
168  # running kernel:
169  if [ "$_cputype" = i86pc ]; then
170  _cputype="$(isainfo -n)"
171  fi
172  fi
173 
174  case "$_ostype" in
175 
176  Android)
177  _ostype=linux-android
178  ;;
179 
180  Linux)
181  check_proc
182  _ostype=unknown-linux-$_clibtype
183  _bitness=$(get_bitness)
184  ;;
185 
186  FreeBSD)
187  _ostype=unknown-freebsd
188  ;;
189 
190  NetBSD)
191  _ostype=unknown-netbsd
192  ;;
193 
194  DragonFly)
195  _ostype=unknown-dragonfly
196  ;;
197 
198  Darwin)
199  _ostype=apple-darwin
200  ;;
201 
202  illumos)
203  _ostype=unknown-illumos
204  ;;
205 
206  MINGW* | MSYS* | CYGWIN* | Windows_NT)
207  _ostype=pc-windows-gnu
208  ;;
209 
210  *)
211  err "unrecognized OS type: $_ostype"
212  ;;
213 
214  esac
215 
216  case "$_cputype" in
217 
218  i386 | i486 | i686 | i786 | x86)
219  _cputype=i686
220  ;;
221 
222  xscale | arm)
223  _cputype=arm
224  if [ "$_ostype" = "linux-android" ]; then
225  _ostype=linux-androideabi
226  fi
227  ;;
228 
229  armv6l)
230  _cputype=arm
231  if [ "$_ostype" = "linux-android" ]; then
232  _ostype=linux-androideabi
233  else
234  _ostype="${_ostype}eabihf"
235  fi
236  ;;
237 
238  armv7l | armv8l)
239  _cputype=armv7
240  if [ "$_ostype" = "linux-android" ]; then
241  _ostype=linux-androideabi
242  else
243  _ostype="${_ostype}eabihf"
244  fi
245  ;;
246 
247  aarch64 | arm64)
248  _cputype=aarch64
249  ;;
250 
251  x86_64 | x86-64 | x64 | amd64)
252  _cputype=x86_64
253  ;;
254 
255  mips)
256  _cputype=$(get_endianness mips '' el)
257  ;;
258 
259  mips64)
260  if [ "$_bitness" -eq 64 ]; then
261  # only n64 ABI is supported for now
262  _ostype="${_ostype}abi64"
263  _cputype=$(get_endianness mips64 '' el)
264  fi
265  ;;
266 
267  ppc)
268  _cputype=powerpc
269  ;;
270 
271  ppc64)
272  _cputype=powerpc64
273  ;;
274 
275  ppc64le)
276  _cputype=powerpc64le
277  ;;
278 
279  s390x)
280  _cputype=s390x
281  ;;
282  riscv64)
283  _cputype=riscv64gc
284  ;;
285  loongarch64)
286  _cputype=loongarch64
287  ;;
288  *)
289  err "unknown CPU type: $_cputype"
290 
291  esac
292 
293  # Detect 64-bit linux with 32-bit userland
294  if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then
295  case $_cputype in
296  x86_64)
297  if [ -n "${CPUTYPE:-}" ]; then
298  _cputype="$CPUTYPE"
299  else {
300  # 32-bit executable for amd64 = x32
301  if is_host_amd64_elf; then {
302  echo "This host is running an x32 userland; as it stands, x32 support is poor," 1>&2
303  echo "and there isn't a native toolchain -- you will have to install" 1>&2
304  echo "multiarch compatibility with i686 and/or amd64, then select one" 1>&2
305  echo "by re-running this script with the CPUTYPE environment variable" 1>&2
306  echo "set to i686 or x86_64, respectively." 1>&2
307  exit 1
308  }; else
309  _cputype=i686
310  fi
311  }; fi
312  ;;
313  mips64)
314  _cputype=$(get_endianness mips '' el)
315  ;;
316  powerpc64)
317  _cputype=powerpc
318  ;;
319  aarch64)
320  _cputype=armv7
321  if [ "$_ostype" = "linux-android" ]; then
322  _ostype=linux-androideabi
323  else
324  _ostype="${_ostype}eabihf"
325  fi
326  ;;
327  riscv64gc)
328  err "riscv64 with 32-bit userland unsupported"
329  ;;
330  esac
331  fi
332 
333  if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then
334  if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then
335  # At least one processor does not have NEON.
336  _cputype=arm
337  fi
338  fi
339 
340  _arch="${_cputype}-${_ostype}"
341 
342  RETVAL="$_arch"
343 }
344 
345 mem_total () {
346  local _mem_total
347  _mem_total=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
348  RETVAL="$_mem_total"
349 }
350 
351 check_mem () {
352  mem_total
353  local _mem_total="$RETVAL"
354  local _mem_min=8388608 # 8Gb in kB
355  if [ "$_mem_total" -lt "$_mem_min" ]; then
356  err "not enough memory: $_mem_total < $_mem_min";
357  fi
358 }
359 
360 disk_free () {
361  local _disk_free
362  _disk_free=$(df . | tail -n1 | awk '{print $4}')
363  RETVAL="${_disk_free}"
364 }
365 
366 check_disk () {
367  disk_free
368  local _disk_free="$RETVAL"
369  local _disk_min=33554432 # in bytes
370  if [ "$_disk_free" -lt "$_disk_min" ]; then
371  err "not enough disk space: $_disk_free < $_disk_min"
372  fi
373 }
374 
375 kernel_version () {
376  local _kernel_version
377  _kernel_version=$(uname -r)
378  RETVAL="$_kernel_version"
379 }
380 
381 check_mod () {
382  if ! lsmod | grep -wq "$1"; then
383  err "kernel module $1 isn't loaded"
384  fi
385 }
386 
387 num_cpus () {
388  local _num_cpus
389  _num_cpus=$(grep -c '^processor' /proc/cpuinfo 2>/dev/null)
390  RETVAL="$_num_cpus"
391  # sysctl -n hw.ncpu # nproc --all
392 }
393 
394 check_cpus () {
395  num_cpus
396  local _num_cpus="$RETVAL"
397  local _min_cpus=8
398  if [ "$_num_cpus" -lt "$_min_cpus" ]; then
399  err "not enough cpu threads ($_num_cpus < $_min_cpus)"
400  fi
401 }
402 
403 print_env () {
404  say_var STASH
405  say_var STORE
406  say_var DIST
407  say_var PACKY_URL
408  say_var VC_URL
409  say_var INSTALL_PREFIX
410  say_var CC
411  say_var AR
412  say_var HG
413  say_var GIT
414  say_var LISP
415  say_var RUST
416  say_var LD
417  say_var SHELL
418  say_var DEV
419  say_var DEV_HOME
420  say_var ID
421  say_var WORKER
422  say_var WORKER_ID
423  say_var WORKER_HOME
424  say_var CARGO_HOME
425  say_var RUSTUP_HOME
426 }
427 
428 main "$@" || exit 1