mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-03 16:41:26 +01:00
116 lines
4.7 KiB
Bash
Executable File
116 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Build the iOS client as an unsigned .ipa for SideStore / AltStore.
|
|
#
|
|
# SideStore re-signs whatever it installs with the viewer's own Apple ID, so
|
|
# nothing here touches a certificate or a provisioning profile. Needs macOS with
|
|
# Xcode, XcodeGen and the aarch64-apple-ios Rust target.
|
|
set -euo pipefail
|
|
|
|
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
repo_root="$(cd -- "$script_dir/.." && pwd)"
|
|
ios_dir="$repo_root/ios"
|
|
generated="$ios_dir/build/generated"
|
|
target=aarch64-apple-ios
|
|
simulator=aarch64-apple-ios-sim
|
|
|
|
usage() {
|
|
echo "usage: $0 {rust|bindings|ipa|all|test}"
|
|
echo
|
|
echo " rust static libpstr_android.a for $target"
|
|
echo " bindings Swift bindings into ios/build/generated"
|
|
echo " ipa xcodegen + xcodebuild, then dist/proton-stream-<version>-ios.ipa"
|
|
echo " all all three, in that order"
|
|
echo " test the unit tests on a simulator ($simulator)"
|
|
}
|
|
|
|
die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; }
|
|
log() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
|
|
|
|
[[ "$(uname -s)" == Darwin ]] || die "the iOS build needs macOS and Xcode"
|
|
|
|
# Same guard as scripts/build.sh: without the sibling checkout the resolve fails
|
|
# a hundred lines deep in cargo output.
|
|
if grep -q '^\[patch\.crates-io\]' "$repo_root/Cargo.toml" && [[ ! -d "$repo_root/../proton-sdk-rs" ]]; then
|
|
die "Cargo.toml still carries [patch.crates-io] -> ../proton-sdk-rs, but that checkout is missing."
|
|
fi
|
|
|
|
version="$(awk '/^\[workspace.package\]/{found=1; next} found && /^\[/{exit} found && /^version = /{gsub(/[" ]/, "", $3); print $3; exit}' "$repo_root/Cargo.toml")"
|
|
[[ -n "$version" ]] || die "no [workspace.package] version in Cargo.toml"
|
|
|
|
build_rust() {
|
|
local triple="${1:-$target}"
|
|
log "cargo rustc -p pstr-android --target $triple (staticlib)"
|
|
# The crate stays `cdylib, rlib` for Android; the archive iOS links is asked
|
|
# for here instead of being built on every other platform too.
|
|
( cd "$repo_root" && IPHONEOS_DEPLOYMENT_TARGET=17.0 cargo rustc -p pstr-android --lib \
|
|
--release --locked --target "$triple" --crate-type staticlib )
|
|
}
|
|
|
|
generate_project() {
|
|
command -v xcodegen >/dev/null || die "xcodegen is required (brew install xcodegen)"
|
|
[[ -f "$generated/PstrBridge.swift" ]] || die "run '$0 bindings' first"
|
|
log "xcodegen ($version)"
|
|
( cd "$ios_dir" && PSTR_VERSION="$version" PSTR_BUILD="${PSTR_BUILD:-1}" xcodegen generate --quiet )
|
|
}
|
|
|
|
build_bindings() {
|
|
log "uniffi-bindgen --language swift"
|
|
# Library mode reads the interface out of a built library, and the host
|
|
# dylib is the one the bindgen binary can open.
|
|
( cd "$repo_root" && cargo build -p pstr-android --lib --locked )
|
|
rm -rf "$generated"
|
|
( cd "$repo_root" && cargo run -p pstr-android --features bindgen --bin uniffi-bindgen --locked -- \
|
|
generate --library target/debug/libpstr_android.dylib --language swift \
|
|
--no-format --out-dir "$generated" )
|
|
[[ -f "$generated/PstrBridge.swift" ]] || die "bindgen wrote no PstrBridge.swift"
|
|
}
|
|
|
|
build_ipa() {
|
|
[[ -f "$repo_root/target/$target/release/libpstr_android.a" ]] || die "run '$0 rust' first"
|
|
generate_project
|
|
|
|
log "xcodebuild (unsigned)"
|
|
xcodebuild -project "$ios_dir/ProtonStream.xcodeproj" -scheme ProtonStream \
|
|
-configuration Release -sdk iphoneos -destination 'generic/platform=iOS' \
|
|
-derivedDataPath "$ios_dir/build/DerivedData" \
|
|
CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= \
|
|
build
|
|
|
|
local app="$ios_dir/build/DerivedData/Build/Products/Release-iphoneos/ProtonStream.app"
|
|
[[ -d "$app" ]] || die "xcodebuild produced no ProtonStream.app"
|
|
local stage="$ios_dir/build/ipa"
|
|
rm -rf "$stage"
|
|
mkdir -p "$stage/Payload" "$repo_root/dist"
|
|
cp -R "$app" "$stage/Payload/"
|
|
local ipa="$repo_root/dist/proton-stream-$version-ios.ipa"
|
|
rm -f "$ipa"
|
|
( cd "$stage" && zip -qry "$ipa" Payload )
|
|
log "wrote $ipa"
|
|
}
|
|
|
|
run_tests() {
|
|
build_rust "$simulator"
|
|
[[ -f "$generated/PstrBridge.swift" ]] || build_bindings
|
|
generate_project
|
|
# Whichever iPhone this Xcode ships a simulator for: the names change with
|
|
# every release, and the tests do not care which one.
|
|
local device
|
|
device="$(xcrun simctl list devices available | grep -m1 -oE 'iPhone [^(]+' | sed 's/ *$//')"
|
|
[[ -n "$device" ]] || die "no iPhone simulator is installed"
|
|
log "xcodebuild test ($device)"
|
|
xcodebuild -project "$ios_dir/ProtonStream.xcodeproj" -scheme ProtonStream \
|
|
-destination "platform=iOS Simulator,name=$device" \
|
|
-derivedDataPath "$ios_dir/build/DerivedData" \
|
|
CODE_SIGNING_ALLOWED=NO \
|
|
test
|
|
}
|
|
|
|
case "${1:-}" in
|
|
rust) build_rust ;;
|
|
bindings) build_bindings ;;
|
|
ipa) build_ipa ;;
|
|
all) build_rust; build_bindings; build_ipa ;;
|
|
test) run_tests ;;
|
|
*) usage >&2; exit 2 ;;
|
|
esac
|