Skip to content
This repository was archived by the owner on Jun 1, 2026. It is now read-only.

Commit fe875d7

Browse files
committed
Refactor Gemstone iOS library build
1 parent 76948e4 commit fe875d7

17 files changed

Lines changed: 234 additions & 820 deletions

File tree

‎.github/workflows/ci-stone-ios.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ jobs:
3434
- name: Install iOS targets
3535
run: just install-ios-targets
3636

37+
- name: Install XcodeGen
38+
run: brew install xcodegen
39+
3740
- name: Build iOS
3841
run: just build-ios
3942

‎gemstone/.gitignore‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,10 @@ xcuserdata/
55
jniLibs/
66
.kotlin/
77
gradle-daemon-jvm.properties
8+
tests/ios/GemTest/GemTest.xcodeproj/
9+
tests/ios/GemTest/GemTest/Info.plist
10+
tests/ios/GemTest/GemTestTests/Info.plist
11+
tests/ios/Packages/Gemstone/.build/
12+
tests/ios/Packages/Gemstone/.swiftpm/
13+
tests/ios/Packages/Gemstone/Sources/Gemstone/Gemstone.swift
14+
tests/ios/Packages/Gemstone/Sources/GemstoneFFI/include/GemstoneFFI.h

‎gemstone/README.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ Gemstone is the essential cross platform library used by Gem Wallet clients (mai
44

55
## Build
66

7-
iOS
7+
iOS example
88

99
```bash
10+
just generate-ios-project
1011
just build-ios
12+
just test-ios
1113
```
1214

15+
`just generate-ios-project` creates the local Swift package sources and regenerates `GemTest.xcodeproj` with XcodeGen. The generated Xcode project builds and links the native Gemstone static library during the Xcode build.
16+
1317
Android
1418

1519
```bash

‎gemstone/justfile‎

Lines changed: 20 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ test:
1212
cargo test --lib
1313

1414
export ANDROID_HOME := env("ANDROID_HOME", "~/Library/Android/sdk")
15-
export HOST_ARCH := arch()
1615

1716
install-ndk:
1817
#!/usr/bin/env bash
@@ -24,16 +23,23 @@ install-ndk:
2423
2524
install-ios-targets:
2625
#!/usr/bin/env bash
27-
rustup target add aarch64-apple-ios-sim aarch64-apple-ios aarch64-apple-ios-macabi aarch64-apple-darwin
28-
if [ ${HOST_ARCH} == "x86_64" ]; then \
29-
rustup target add x86_64-apple-ios; \
30-
fi
26+
rustup target add aarch64-apple-ios-sim aarch64-apple-ios
3127
3228
install-android-targets:
3329
rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi
3430
cargo install cargo-ndk@4.1.2
3531

36-
test-ios:
32+
build-ios: generate-ios-project
33+
#!/usr/bin/env bash
34+
set -o pipefail
35+
DEVICE_ID=$(xcrun simctl list devices available | grep iPhone | head -1 | sed 's/.*(\([A-F0-9-]*\)).*/\1/')
36+
echo "Using Simulator: $DEVICE_ID"
37+
xcodebuild -project tests/ios/GemTest/GemTest.xcodeproj \
38+
-scheme GemTest \
39+
-destination "platform=iOS Simulator,id=$DEVICE_ID,arch=arm64" \
40+
build | xcbeautify
41+
42+
test-ios: generate-ios-project
3743
#!/usr/bin/env bash
3844
set -o pipefail
3945
DEVICE_ID=$(xcrun simctl list devices available | grep iPhone | head -1 | sed 's/.*(\([A-F0-9-]*\)).*/\1/')
@@ -44,7 +50,6 @@ test-ios:
4450
test | xcbeautify
4551
4652
export LIB_NAME := "gemstone"
47-
export FW_NAME := "Gemstone"
4853
export STATIC_LIB_NAME := "lib" + LIB_NAME + ".a"
4954
export DY_LIB_NAME := if os() == "macos" { "libgemstone.dylib" } else { "libgemstone.so" }
5055

@@ -56,24 +61,10 @@ export TARGET_DIR := "../target"
5661
export GEN_SWIFT_FOLDER := "generated/swift"
5762
export GEN_KOTLIN_FOLDER := "generated/kotlin"
5863
export ANDROID_MODULE_FOLDER := "android/gemstone/src/main/java"
64+
export IOS_PROJECT_FOLDER := "tests/ios/GemTest"
65+
export IOS_PACKAGE_FOLDER := "tests/ios/Packages/Gemstone"
5966

60-
export TARGET_XC_FW_FOLDER := "target/spm"
61-
export FW_FFI_NAME := FW_NAME + "FFI"
62-
export FW_FFI_FILE := FW_FFI_NAME + ".framework"
63-
export XC_FW_FFI_NAME := FW_FFI_NAME + ".xcframework"
64-
export DEPLOYMENT_TARGET := env("IPHONEOS_DEPLOYMENT_TARGET", "17.0")
6567
export LIB_OUTPUT_PATH := TARGET_DIR + "/" + BUILD_MODE_TARGET + "/" + DY_LIB_NAME
66-
build-ios: build-targets bindgen-swift assemble-frameworks xcframework cp-xcframework-source
67-
68-
build-targets:
69-
#!/usr/bin/env bash
70-
echo "Host: ${HOST_ARCH}, iOS deployment target ${DEPLOYMENT_TARGET}, BUILD_MODE_TARGET: ${BUILD_MODE_TARGET}"
71-
if [ ${HOST_ARCH} == "x86_64" ]; then \
72-
IPHONEOS_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET} cargo build --target x86_64-apple-ios ${BUILD_FLAG}; \
73-
else \
74-
IPHONEOS_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET} cargo build --target aarch64-apple-ios-sim --target aarch64-apple-ios ${BUILD_FLAG}; \
75-
env -u IPHONEOS_DEPLOYMENT_TARGET cargo build --target aarch64-apple-ios-macabi --target aarch64-apple-darwin ${BUILD_FLAG}; \
76-
fi
7768

7869
bindgen-swift:
7970
#!/usr/bin/env bash
@@ -89,56 +80,14 @@ bindgen-swift:
8980
fi; \
9081
cargo run ${BUILD_FLAG} -p uniffi-bindgen -- generate --library --language swift --crate ${LIB_NAME} -o ${GEN_SWIFT_FOLDER} "${LIB_OUTPUT_PATH}"
9182
92-
assemble-frameworks:
83+
prepare-ios-package: bindgen-swift
9384
#!/usr/bin/env bash
94-
MODULE_MAP=$(
95-
cat << EOF
96-
// This file was autogenerated by some hot garbage in the uniffi crate.
97-
framework module ${FW_FFI_NAME} {
98-
header "${FW_FFI_NAME}.h"
99-
export *
100-
}
101-
EOF
102-
)
103-
cd ${TARGET_DIR} && find . -type d -name ${FW_FFI_FILE} | xargs rm -rf
104-
targets=(aarch64-apple-ios-sim aarch64-apple-ios aarch64-apple-ios-macabi aarch64-apple-darwin)
105-
if [ ${HOST_ARCH} == "x86_64" ]; then
106-
targets=(x86_64-apple-ios)
107-
fi
108-
for target in ${targets[@]}; do \
109-
pushd ${TARGET_DIR}/${target}/${BUILD_MODE_TARGET} > /dev/null && \
110-
mkdir -p ${FW_FFI_FILE} && \
111-
cd ${FW_FFI_FILE} && \
112-
mkdir Headers Modules && \
113-
echo "$MODULE_MAP" > ./Modules/module.modulemap && \
114-
cp ../../../../${LIB_NAME}/${GEN_SWIFT_FOLDER}/${FW_FFI_NAME}.h ./Headers && \
115-
cp ../${STATIC_LIB_NAME} ./${FW_FFI_NAME} && \
116-
cp ../../../../${LIB_NAME}/src/Info.plist ./; \
117-
popd > /dev/null; \
118-
done
119-
120-
xcframework:
121-
#!/usr/bin/env bash
122-
rm -rf ${TARGET_XC_FW_FOLDER}/Sources/${XC_FW_FFI_NAME}
123-
mkdir -p ${TARGET_XC_FW_FOLDER}/Sources
124-
if [ ${HOST_ARCH} == "x86_64" ]; then \
125-
xcodebuild -create-xcframework \
126-
-framework ${TARGET_DIR}/x86_64-apple-ios/${BUILD_MODE_TARGET}/${FW_FFI_FILE} \
127-
-output ${TARGET_XC_FW_FOLDER}/Sources/${XC_FW_FFI_NAME}; \
128-
else \
129-
xcodebuild -create-xcframework \
130-
-framework ${TARGET_DIR}/aarch64-apple-ios/${BUILD_MODE_TARGET}/${FW_FFI_FILE} \
131-
-framework ${TARGET_DIR}/aarch64-apple-ios-sim/${BUILD_MODE_TARGET}/${FW_FFI_FILE} \
132-
-framework ${TARGET_DIR}/aarch64-apple-ios-macabi/${BUILD_MODE_TARGET}/${FW_FFI_FILE} \
133-
-framework ${TARGET_DIR}/aarch64-apple-darwin/${BUILD_MODE_TARGET}/${FW_FFI_FILE} \
134-
-output ${TARGET_XC_FW_FOLDER}/Sources/${XC_FW_FFI_NAME}; \
135-
fi
85+
mkdir -p ${IOS_PACKAGE_FOLDER}/Sources/Gemstone ${IOS_PACKAGE_FOLDER}/Sources/GemstoneFFI/include
86+
cp ${GEN_SWIFT_FOLDER}/gemstone.swift ${IOS_PACKAGE_FOLDER}/Sources/Gemstone/Gemstone.swift
87+
cp ${GEN_SWIFT_FOLDER}/GemstoneFFI.h ${IOS_PACKAGE_FOLDER}/Sources/GemstoneFFI/include/GemstoneFFI.h
13688
137-
cp-xcframework-source:
138-
#!/usr/bin/env bash
139-
mkdir -p ${TARGET_XC_FW_FOLDER}/Sources/${FW_NAME}
140-
cp src/Package.swift ${TARGET_XC_FW_FOLDER}
141-
cp ${GEN_SWIFT_FOLDER}/${FW_NAME}.swift ${TARGET_XC_FW_FOLDER}/Sources/${FW_NAME}
89+
generate-ios-project: prepare-ios-package
90+
xcodegen generate --spec ${IOS_PROJECT_FOLDER}/project.yml --project ${IOS_PROJECT_FOLDER}
14291

14392
bindgen-kotlin:
14493
#!/usr/bin/env bash

‎gemstone/scripts/build-ios-lib.sh‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Build the Gemstone Rust static library for the active Xcode destination.
4+
5+
set -euo pipefail
6+
7+
export PATH="$HOME/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
8+
9+
SCRIPT_DIR=$(dirname "$(realpath "$0")")
10+
GEMSTONE_DIR="$SCRIPT_DIR/.."
11+
TARGET_DIR="$GEMSTONE_DIR/../target"
12+
13+
if [ -z "${BUILT_PRODUCTS_DIR:-}" ] || [ -z "${PLATFORM_NAME:-}" ] || [ -z "${CONFIGURATION:-}" ]; then
14+
echo "error: build-ios-lib.sh must run from an Xcode build environment" >&2
15+
exit 1
16+
fi
17+
18+
profile="debug"
19+
build_flag=""
20+
requested_arch="${ARCHS:-${CURRENT_ARCH:-$(uname -m)}}"
21+
22+
if [ "$CONFIGURATION" = "Release" ]; then
23+
profile="release"
24+
build_flag="--release"
25+
fi
26+
27+
if [ -z "$requested_arch" ] || [ "$requested_arch" = "undefined_arch" ]; then
28+
requested_arch="$(uname -m)"
29+
fi
30+
31+
if [ "$requested_arch" != "arm64" ]; then
32+
echo "error: Intel Macs are not supported for iOS Gemstone builds." >&2
33+
exit 1
34+
fi
35+
36+
case "$PLATFORM_NAME" in
37+
iphoneos) rust_target="aarch64-apple-ios" ;;
38+
iphonesimulator) rust_target="aarch64-apple-ios-sim" ;;
39+
*)
40+
echo "error: unsupported Gemstone platform: $PLATFORM_NAME" >&2
41+
exit 1
42+
;;
43+
esac
44+
45+
mkdir -p "$BUILT_PRODUCTS_DIR"
46+
47+
echo "note: Building Gemstone Rust library for $rust_target ($profile)"
48+
env -u MACOSX_DEPLOYMENT_TARGET -u TVOS_DEPLOYMENT_TARGET -u WATCHOS_DEPLOYMENT_TARGET -u XROS_DEPLOYMENT_TARGET \
49+
IPHONEOS_DEPLOYMENT_TARGET="${IPHONEOS_DEPLOYMENT_TARGET:-17.0}" \
50+
cargo build --manifest-path "$GEMSTONE_DIR/Cargo.toml" --target "$rust_target" --lib ${build_flag}
51+
52+
cp "$TARGET_DIR/$rust_target/$profile/libgemstone.a" "$BUILT_PRODUCTS_DIR/libgemstone.a"
53+
echo "note: Gemstone Rust library ready at $BUILT_PRODUCTS_DIR/libgemstone.a"

‎gemstone/src/Info.plist‎

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)