This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
export PATH
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 --output ABSOLUTE_DIR --target-dir ABSOLUTE_DIR" >&2
|
||||
@@ -26,10 +28,41 @@ done
|
||||
|
||||
test -n "$output" || usage
|
||||
test -n "$target_dir" || usage
|
||||
case "$output:$target_dir" in
|
||||
/*:/*) ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
ROOT=$(CDPATH= cd -P -- "$(dirname "$0")/../.." && pwd -P)
|
||||
CORE="$ROOT/core"
|
||||
|
||||
resolve_new_path() {
|
||||
requested=$1
|
||||
label=$2
|
||||
case "$requested" in
|
||||
/*) ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
if test -e "$requested" || test -L "$requested"; then
|
||||
echo "$label must not exist: $requested" >&2
|
||||
exit 2
|
||||
fi
|
||||
parent=$(dirname -- "$requested")
|
||||
name=$(basename -- "$requested")
|
||||
case "$name" in
|
||||
''|.|..) usage ;;
|
||||
esac
|
||||
physical_parent=$(CDPATH= cd -P -- "$parent" 2>/dev/null && pwd -P) || {
|
||||
echo "$label parent must already exist: $parent" >&2
|
||||
exit 2
|
||||
}
|
||||
candidate="$physical_parent/$name"
|
||||
case "$candidate" in
|
||||
"$ROOT"|"$ROOT"/*)
|
||||
echo "$label must be outside the repository: $requested" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
printf '%s\n' "$candidate"
|
||||
}
|
||||
|
||||
output=$(resolve_new_path "$output" output)
|
||||
target_dir=$(resolve_new_path "$target_dir" "target directory")
|
||||
case "$output/:$target_dir/" in
|
||||
"$target_dir/"*:*|*:"$output/"*)
|
||||
echo "output and target directory must be separate" >&2
|
||||
@@ -37,55 +70,164 @@ case "$output/:$target_dir/" in
|
||||
;;
|
||||
esac
|
||||
|
||||
ROOT=$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)
|
||||
case "$output" in
|
||||
"$ROOT"|"$ROOT"/*)
|
||||
echo "output must be outside the repository" >&2
|
||||
mkdir "$output"
|
||||
if ! mkdir "$target_dir"; then
|
||||
rmdir "$output"
|
||||
exit 2
|
||||
fi
|
||||
output=$(CDPATH= cd -P -- "$output" && pwd -P)
|
||||
target_dir=$(CDPATH= cd -P -- "$target_dir" && pwd -P)
|
||||
for reserved_path in "$output" "$target_dir"; do
|
||||
case "$reserved_path" in
|
||||
"$ROOT"|"$ROOT"/*)
|
||||
echo "reserved packaging path resolved inside the repository: $reserved_path" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
case "$output/:$target_dir/" in
|
||||
"$target_dir/"*:*|*:"$output/"*)
|
||||
echo "reserved output and target directory must be separate" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
case "$target_dir" in
|
||||
"$ROOT"|"$ROOT"/*)
|
||||
echo "target directory must be outside the repository" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
test ! -e "$output" || {
|
||||
echo "output already exists: $output" >&2
|
||||
exit 2
|
||||
}
|
||||
test ! -e "$target_dir" || {
|
||||
echo "target directory already exists: $target_dir" >&2
|
||||
exit 2
|
||||
}
|
||||
test "$(uname -s)" = Darwin || {
|
||||
|
||||
test "$(/usr/bin/uname -s)" = Darwin || {
|
||||
echo "XCFramework packaging requires macOS" >&2
|
||||
exit 2
|
||||
}
|
||||
test "$(/usr/bin/uname -m)" = arm64 || {
|
||||
echo "XCFramework packaging requires an arm64 host" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
source_epoch=$(git -C "$ROOT" show -s --format=%ct HEAD)
|
||||
export CARGO_INCREMENTAL=0
|
||||
export CARGO_TARGET_DIR="$target_dir"
|
||||
export MACOSX_DEPLOYMENT_TARGET=14.0
|
||||
export RUSTFLAGS="--remap-path-prefix=$ROOT=."
|
||||
export SOURCE_DATE_EPOCH="$source_epoch"
|
||||
export ZERO_AR_DATE=1
|
||||
user_record=$(/usr/bin/dscacheutil -q user -a name "$(/usr/bin/id -un)")
|
||||
trusted_home=$(printf '%s\n' "$user_record" | awk '$1 == "dir:" { print $2; exit }')
|
||||
rustup="$trusted_home/.cargo/bin/rustup"
|
||||
test -x "$rustup" || {
|
||||
echo "rustup not found at trusted user path" >&2
|
||||
exit 2
|
||||
}
|
||||
cargo_bin=$(/usr/bin/env -i \
|
||||
HOME="$trusted_home" \
|
||||
PATH="$PATH" \
|
||||
RUSTUP_HOME="$trusted_home/.rustup" \
|
||||
"$rustup" which --toolchain 1.97.1 cargo)
|
||||
rustc_bin=$(/usr/bin/env -i \
|
||||
HOME="$trusted_home" \
|
||||
PATH="$PATH" \
|
||||
RUSTUP_HOME="$trusted_home/.rustup" \
|
||||
"$rustup" which --toolchain 1.97.1 rustc)
|
||||
rustc_version=$(/usr/bin/env -i HOME="$trusted_home" PATH="$PATH" "$rustc_bin" --version)
|
||||
cargo_version=$(/usr/bin/env -i HOME="$trusted_home" PATH="$PATH" "$cargo_bin" --version)
|
||||
test "$rustc_version" = 'rustc 1.97.1 (8bab26f4f 2026-07-14)' || {
|
||||
echo "unexpected rustc identity: $rustc_version" >&2
|
||||
exit 2
|
||||
}
|
||||
test "$cargo_version" = 'cargo 1.97.1 (c980f4866 2026-06-30)' || {
|
||||
echo "unexpected cargo identity: $cargo_version" >&2
|
||||
exit 2
|
||||
}
|
||||
xcodebuild=$(/usr/bin/env -i PATH="$PATH" /usr/bin/xcrun --find xcodebuild)
|
||||
xcode_version=$(/usr/bin/env -i HOME="$trusted_home" PATH="$PATH" "$xcodebuild" -version)
|
||||
test "$xcode_version" = 'Xcode 26.6
|
||||
Build version 17F113' || {
|
||||
echo "unexpected Xcode identity: $xcode_version" >&2
|
||||
exit 2
|
||||
}
|
||||
clang=$(/usr/bin/env -i PATH="$PATH" /usr/bin/xcrun --find clang)
|
||||
ar=$(/usr/bin/env -i PATH="$PATH" /usr/bin/xcrun --find ar)
|
||||
clang_identity=$(/usr/bin/env -i HOME="$trusted_home" PATH="$PATH" "$clang" --version)
|
||||
clang_version=$(printf '%s\n' "$clang_identity" | sed -n '1p')
|
||||
sdk=$(/usr/bin/env -i PATH="$PATH" /usr/bin/xcrun --sdk macosx --show-sdk-path)
|
||||
|
||||
cargo build \
|
||||
--manifest-path "$ROOT/core/Cargo.toml" \
|
||||
--target aarch64-apple-darwin \
|
||||
--release \
|
||||
--locked
|
||||
config_dir=$CORE
|
||||
while :; do
|
||||
if test -e "$config_dir/.cargo/config" || test -e "$config_dir/.cargo/config.toml"; then
|
||||
echo "Cargo config is not permitted in the packaging path: $config_dir/.cargo" >&2
|
||||
exit 2
|
||||
fi
|
||||
test "$config_dir" = / && break
|
||||
config_dir=$(dirname "$config_dir")
|
||||
done
|
||||
|
||||
source_commit=$(/usr/bin/env -i HOME="$trusted_home" PATH="$PATH" \
|
||||
/usr/bin/git -C "$ROOT" rev-parse HEAD)
|
||||
source_epoch=$(/usr/bin/env -i HOME="$trusted_home" PATH="$PATH" \
|
||||
/usr/bin/git -C "$ROOT" show -s --format=%ct HEAD)
|
||||
rustflags="--remap-path-prefix=$ROOT=. --remap-path-prefix=$target_dir=/cargo-target"
|
||||
cflags="-fdebug-prefix-map=$ROOT=. -ffile-prefix-map=$ROOT=. -fdebug-prefix-map=$target_dir=/cargo-target -ffile-prefix-map=$target_dir=/cargo-target"
|
||||
cargo_home="$target_dir/cargo-home"
|
||||
build_tmp="$target_dir/tmp"
|
||||
mkdir "$cargo_home" "$build_tmp"
|
||||
for cache in registry git; do
|
||||
if test -e "$trusted_home/.cargo/$cache"; then
|
||||
ln -s "$trusted_home/.cargo/$cache" "$cargo_home/$cache"
|
||||
fi
|
||||
done
|
||||
(
|
||||
cd "$CORE"
|
||||
/usr/bin/env -i \
|
||||
AR="$ar" \
|
||||
AR_aarch64_apple_darwin="$ar" \
|
||||
CARGO_HOME="$cargo_home" \
|
||||
CARGO_INCREMENTAL=0 \
|
||||
CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 \
|
||||
CARGO_PROFILE_RELEASE_INCREMENTAL=false \
|
||||
CARGO_PROFILE_RELEASE_LTO=fat \
|
||||
CARGO_PROFILE_RELEASE_PANIC=abort \
|
||||
CARGO_TARGET_AARCH64_APPLE_DARWIN_LINKER="$clang" \
|
||||
CARGO_TARGET_DIR="$target_dir" \
|
||||
CC="$clang" \
|
||||
CC_aarch64_apple_darwin="$clang" \
|
||||
CFLAGS="$cflags" \
|
||||
CFLAGS_aarch64_apple_darwin="$cflags" \
|
||||
HOME="$trusted_home" \
|
||||
MACOSX_DEPLOYMENT_TARGET=14.0 \
|
||||
PATH="$PATH" \
|
||||
RUSTC="$rustc_bin" \
|
||||
RUSTFLAGS="$rustflags" \
|
||||
SDKROOT="$sdk" \
|
||||
SOURCE_DATE_EPOCH="$source_epoch" \
|
||||
TMPDIR="$build_tmp" \
|
||||
ZERO_AR_DATE=1 \
|
||||
"$cargo_bin" build \
|
||||
--target aarch64-apple-darwin \
|
||||
--release \
|
||||
--frozen
|
||||
)
|
||||
|
||||
headers="$target_dir/xcframework-headers"
|
||||
mkdir -p "$headers" "$output"
|
||||
cp "$ROOT/core/include/versevdi_core.h" "$headers/"
|
||||
cp "$ROOT/core/include/module.modulemap" "$headers/"
|
||||
|
||||
xcodebuild -create-xcframework \
|
||||
/usr/bin/env -i \
|
||||
HOME="$trusted_home" \
|
||||
PATH="$PATH" \
|
||||
TMPDIR="$build_tmp" \
|
||||
"$xcodebuild" -create-xcframework \
|
||||
-library "$target_dir/aarch64-apple-darwin/release/libversevdi_core.a" \
|
||||
-headers "$headers" \
|
||||
-output "$output/VerseVDICore.xcframework"
|
||||
|
||||
timestamp=$(date -r "$source_epoch" +%Y%m%d%H%M.%S)
|
||||
find "$output/VerseVDICore.xcframework" -exec touch -h -t "$timestamp" {} +
|
||||
|
||||
{
|
||||
printf 'rustc=%s\n' "$rustc_version"
|
||||
printf 'cargo=%s\n' "$cargo_version"
|
||||
printf 'cargo_path=%s\n' "$cargo_bin"
|
||||
printf 'rustc_path=%s\n' "$rustc_bin"
|
||||
printf 'xcode=%s\n' "$xcode_version"
|
||||
printf 'clang=%s\n' "$clang_version"
|
||||
printf 'sdk=%s\n' "$sdk"
|
||||
printf 'cargo_config=isolated-home-and-no-project-config\n'
|
||||
printf 'target=aarch64-apple-darwin\n'
|
||||
printf 'deployment_target=14.0\n'
|
||||
printf 'source_commit=%s\n' "$source_commit"
|
||||
printf 'source_epoch=%s\n' "$source_epoch"
|
||||
printf 'rustflags=--remap-path-prefix=<repository>=. --remap-path-prefix=<target>=/cargo-target\n'
|
||||
printf 'cflags=-fdebug-prefix-map/-ffile-prefix-map for <repository> and <target>\n'
|
||||
} >"$output/build-environment.txt"
|
||||
touch -t "$timestamp" "$output/build-environment.txt" "$output"
|
||||
|
||||
Reference in New Issue
Block a user