106 lines
3.6 KiB
Bash
Executable file
106 lines
3.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
|
|
# See LICENSE.md for license information.
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
# The macOS port's C compiler (make/macos.mk; the installer builds SDL with
|
|
# it too): zig cc once for each architecture in MACOS_ARCHS -- by default
|
|
# Apple silicon and Intel -- with the results joined into one universal file
|
|
# by llvm-lipo, as Apple's own clang does when given two -arch flags. It
|
|
# takes what a C compiler takes: with -c it makes a universal object, else a
|
|
# universal program. The first architecture's run is exactly the call it was
|
|
# given, so its dependency file (-MMD) comes out as a plain compiler's; the
|
|
# other runs leave theirs out. With one architecture, or with no -o (a
|
|
# preprocessing run), it is zig cc for the first architecture alone.
|
|
#
|
|
# Programs run on macOS MACOS_MIN or newer: Ventura, which every Apple
|
|
# silicon Mac runs and the Intel ones from 2017 on.
|
|
#
|
|
# From the environment (toolchains/config.mk, which make exports): ZIG and
|
|
# its cache folders, MACOS_SDK and MACOS_LIPO.
|
|
#
|
|
# Usage: cc.sh COMPILER-ARGUMENTS...
|
|
# cc.sh --minimum prints MACOS_MIN (for an Info.plist)
|
|
|
|
set -euo pipefail
|
|
|
|
MACOS_MIN=13.0
|
|
read -r -a archs <<< "${MACOS_ARCHS:-aarch64 x86_64}"
|
|
|
|
if [[ "${1:-}" == --minimum ]]; then
|
|
printf '%s\n' "$MACOS_MIN"
|
|
exit 0
|
|
fi
|
|
if [[ -z "${ZIG:-}" || -z "${MACOS_SDK:-}" || -z "${MACOS_LIPO:-}" ]]; then
|
|
echo "$0: ZIG, MACOS_SDK or MACOS_LIPO is not set; run ./install.sh install toolchain:macos" >&2
|
|
exit 1
|
|
fi
|
|
|
|
out=""
|
|
compile=0
|
|
preprocess=0
|
|
prev=""
|
|
for arg in "$@"; do
|
|
if [[ "$prev" == -o ]]; then
|
|
out="$arg"
|
|
fi
|
|
case "$arg" in
|
|
-c) compile=1 ;;
|
|
-E) preprocess=1 ;;
|
|
esac
|
|
prev="$arg"
|
|
done
|
|
|
|
# zig brings the C library's headers and libSystem's stubs; the SDK the
|
|
# rest, after them (so the caller's own come first): its other headers, its
|
|
# frameworks, and, for a link, the stub libraries beside them. zig cc
|
|
# builds for UBSan unless told not to, and would then want its runtime; and
|
|
# it warns, as no other port's compiler does, at __DATE__ and __TIME__ (a
|
|
# build that uses them cannot be reproduced), which -Werror would make fatal.
|
|
flags=(-fno-sanitize=undefined -Wno-date-time -idirafter "$MACOS_SDK/usr/include" -F"$MACOS_SDK/System/Library/Frameworks")
|
|
if [[ $compile -eq 0 && $preprocess -eq 0 ]]; then
|
|
flags+=(-L"$MACOS_SDK/usr/lib")
|
|
fi
|
|
|
|
# zig refuses a target with a version for a run that only preprocesses (a
|
|
# build system asking what the compiler defines), and the version makes no
|
|
# difference to that.
|
|
target() {
|
|
if [[ $preprocess -eq 1 ]]; then
|
|
printf '%s-macos\n' "$1"
|
|
else
|
|
printf '%s-macos.%s\n' "$1" "$MACOS_MIN"
|
|
fi
|
|
}
|
|
|
|
if [[ ${#archs[@]} -eq 1 || -z "$out" ]]; then
|
|
exec "$ZIG" cc -target "$(target "${archs[0]}")" "$@" "${flags[@]}"
|
|
fi
|
|
|
|
slices=()
|
|
trap 'rm -f "${slices[@]}"' EXIT
|
|
for arch in "${archs[@]}"; do
|
|
slice="$out.$arch"
|
|
slices+=("$slice")
|
|
if [[ ${#slices[@]} -eq 1 ]]; then
|
|
"$ZIG" cc -target "$(target "$arch")" "$@" "${flags[@]}"
|
|
mv -f "$out" "$slice"
|
|
continue
|
|
fi
|
|
args=()
|
|
skip=0
|
|
for arg in "$@"; do
|
|
if [[ $skip -eq 1 ]]; then
|
|
skip=0
|
|
continue
|
|
fi
|
|
case "$arg" in
|
|
-o) args+=(-o "$slice"); skip=1 ;;
|
|
-MD|-MMD|-MP) ;;
|
|
-MF|-MT|-MQ) skip=1 ;;
|
|
*) args+=("$arg") ;;
|
|
esac
|
|
done
|
|
"$ZIG" cc -target "$(target "$arch")" "${args[@]}" "${flags[@]}"
|
|
done
|
|
"$MACOS_LIPO" -create "${slices[@]}" -output "$out"
|