This repository has no description
1#!/usr/bin/env bash
2# Build MLKit pose-detection static archives for all Kotlin/Native iOS targets
3# and stage them at build/mlkit-archives/<target>/lib<Pod>.a for cinterop to
4# embed into the library's klibs.
5#
6# Required env: MLKIT_STAGING_DIR, MLKIT_ARCHIVES_DIR
7# Optional env: MLKIT_TARGETS (space-separated; default "ios_arm64 ios_simulator_arm64 ios_x64")
8
9set -euo pipefail
10
11STAGING="${MLKIT_STAGING_DIR:?MLKIT_STAGING_DIR required}"
12ARCHIVES="${MLKIT_ARCHIVES_DIR:?MLKIT_ARCHIVES_DIR required}"
13TARGETS="${MLKIT_TARGETS:-ios_arm64 ios_simulator_arm64 ios_x64}"
14
15MLKIT_VERSION="1.0.0-beta16"
16IOS_DEPLOYMENT_TARGET="16.2"
17
18# Pods whose binaries we embed. Order matters for link-time resolution:
19# dependents before their deps.
20VENDORED_PODS=(
21 MLKitPoseDetectionAccurate
22 MLKitPoseDetectionCommon
23 MLKitVision
24 MLKitCommon
25 MLImage
26 MLKitXenoCommon
27)
28# Built-from-source pods. Their framework binary paths inside the build dir
29# don't always match the pod name, so we map explicitly.
30# Format: "<pod-name>:<output-framework-name>"
31SOURCE_PODS=(
32 "GTMSessionFetcher:GTMSessionFetcher"
33 "GoogleDataTransport:GoogleDataTransport"
34 "GoogleToolboxForMac:GoogleToolboxForMac"
35 "GoogleUtilities:GoogleUtilities"
36 "PromisesObjC:FBLPromises"
37 "nanopb:nanopb"
38)
39
40mkdir -p "$STAGING"
41mkdir -p "$ARCHIVES"
42cd "$STAGING"
43
44# Write a fresh Podfile for every run — ensures version changes propagate.
45cat > Podfile <<EOF
46platform :ios, '${IOS_DEPLOYMENT_TARGET}'
47use_frameworks! :linkage => :static
48
49install! 'cocoapods', :integrate_targets => false, :deterministic_uuids => false
50
51target 'MlkitSync' do
52 pod 'MLKitPoseDetectionAccurate', '${MLKIT_VERSION}'
53end
54EOF
55
56echo "==> pod install in $STAGING"
57if [ ! -d Pods ] || [ ! -f Podfile.lock ] || ! diff -q Podfile Podfile.lock.input 2>/dev/null; then
58 pod install --no-repo-update
59 cp Podfile Podfile.lock.input
60fi
61
62# Map a Kotlin target name to an (sdk, arch) tuple.
63target_to_sdk() {
64 case "$1" in
65 ios_arm64) echo "iphoneos arm64" ;;
66 ios_simulator_arm64) echo "iphonesimulator arm64" ;;
67 ios_x64) echo "iphonesimulator x86_64" ;;
68 *) echo "UNKNOWN UNKNOWN" ;;
69 esac
70}
71
72extract_slice() {
73 # $1 = input (fat or single-arch Mach-O)
74 # $2 = desired arch (arm64, x86_64)
75 # $3 = output path
76 local input="$1" arch="$2" output="$3"
77 mkdir -p "$(dirname "$output")"
78 # lipo -thin fails on already-thin; use -info to branch
79 if lipo -info "$input" 2>&1 | grep -q "Non-fat"; then
80 local existing_arch
81 existing_arch=$(lipo -info "$input" | sed -E 's/.*architecture: //')
82 if [ "$existing_arch" = "$arch" ]; then
83 cp "$input" "$output"
84 else
85 echo " skip: $input is $existing_arch, need $arch"
86 return 1
87 fi
88 else
89 lipo -thin "$arch" "$input" -output "$output" 2>/dev/null || {
90 echo " skip: no $arch slice in $input"
91 return 1
92 }
93 fi
94}
95
96for target in $TARGETS; do
97 read -r sdk arch <<< "$(target_to_sdk "$target")"
98 if [ "$sdk" = "UNKNOWN" ]; then
99 echo "skipping unknown target $target"
100 continue
101 fi
102
103 echo "==> Building source pods for $target ($sdk $arch)"
104 # Build only the source pods — vendored ones don't need building.
105 for entry in "${SOURCE_PODS[@]}"; do
106 pod_name="${entry%%:*}"
107 xcodebuild -project Pods/Pods.xcodeproj \
108 -target "$pod_name" \
109 -configuration Release \
110 -sdk "$sdk" \
111 -arch "$arch" \
112 ONLY_ACTIVE_ARCH=NO \
113 BUILD_LIBRARY_FOR_DISTRIBUTION=NO \
114 build 2>&1 | tail -3
115 done
116
117 out_dir="$ARCHIVES/$target"
118 rm -rf "$out_dir"
119 mkdir -p "$out_dir"
120
121 echo "==> Extracting $target archives to $out_dir"
122 # Vendored: pull the right slice from the fat .framework binary.
123 for pod in "${VENDORED_PODS[@]}"; do
124 fw_bin="Pods/$pod/Frameworks/$pod.framework/$pod"
125 if [ -f "$fw_bin" ]; then
126 extract_slice "$fw_bin" "$arch" "$out_dir/lib${pod}.a" || true
127 else
128 echo " miss: vendored $pod at $fw_bin"
129 fi
130 done
131 # Built-from-source: single-arch output at build/Release-<sdk>/<pod>/<fw>.framework/<fw>
132 for entry in "${SOURCE_PODS[@]}"; do
133 pod_name="${entry%%:*}"
134 fw_name="${entry##*:}"
135 built="build/Release-$sdk/$pod_name/$fw_name.framework/$fw_name"
136 if [ -f "$built" ]; then
137 extract_slice "$built" "$arch" "$out_dir/lib${fw_name}.a" || true
138 else
139 echo " miss: built $pod_name at $built"
140 fi
141 done
142
143 echo "==> $target: $(ls "$out_dir" | wc -l | tr -d ' ') archives"
144done
145
146echo "==> Done. Archives at $ARCHIVES"