@@ -316,10 +316,30 @@ get_architecture() {
316
316
fi
317
317
fi
318
318
319
- if [ " $_ostype " = Darwin ] && [ " $_cputype " = i386 ]; then
320
- # Darwin `uname -m` lies
321
- if sysctl hw.optional.x86_64 | grep -q ' : 1' ; then
322
- _cputype=x86_64
319
+ if [ " $_ostype " = Darwin ]; then
320
+ # Darwin `uname -m` can lie due to Rosetta shenanigans. If you manage to
321
+ # invoke a native shell binary and then a native uname binary, you can
322
+ # get the real answer, but that's hard to ensure, so instead we use
323
+ # `sysctl` (which doesn't lie) to check for the actual architecture.
324
+ if [ " $_cputype " = i386 ]; then
325
+ # Handling i386 compatibility mode in older macOS versions (<10.15)
326
+ # running on x86_64-based Macs.
327
+ # Starting from 10.15, macOS explicitly bans all i386 binaries from running.
328
+ # See: <https://support.apple.com/en-us/HT208436>
329
+
330
+ # Avoid `sysctl: unknown oid` stderr output and/or non-zero exit code.
331
+ if sysctl hw.optional.x86_64 2> /dev/null || true | grep -q ' : 1' ; then
332
+ _cputype=x86_64
333
+ fi
334
+ elif [ " $_cputype " = x86_64 ]; then
335
+ # Handling x86-64 compatibility mode (a.k.a. Rosetta 2)
336
+ # in newer macOS versions (>=11) running on arm64-based Macs.
337
+ # Rosetta 2 is built exclusively for x86-64 and cannot run i386 binaries.
338
+
339
+ # Avoid `sysctl: unknown oid` stderr output and/or non-zero exit code.
340
+ if sysctl hw.optional.arm64 2> /dev/null || true | grep -q ' : 1' ; then
341
+ _cputype=arm64
342
+ fi
323
343
fi
324
344
fi
325
345
0 commit comments