1
#!/bin/bash
2
+
3
+set -e -x
4
+
5
if [[ "$1" == "--dont-install" ]]; then
6
echo "Skipping Go installation as per --dont-install flag"
7
else
8
# install go > 1.24:
9
brew install go
10
export PATH=$PATH:~/go/bin
8
- go install golang.org/x/mobile/cmd/gomobile@latest
9
- gomobile init
11
fi
12
12
-# build mwebd:
13
-git clone https://github.com/ltcmweb/mwebd
14
-cd mwebd
15
-git reset --hard f75cb9edef07d03360ee2d33e6edae4243a890b1
16
-gomobile bind -target=ios .
17
-mv -fn ./Mwebd.xcframework ../../../cw_mweb/ios/
18
-# cleanup:
19
-cd ..
20
-rm -rf mwebd
\ No newline at end of file
13
+BASE_DIR="$(pwd)"
14
+MWEB_GO_DIR="${BASE_DIR}/../../cw_mweb/go"
15
+IOS_OUTPUT_DIR="${BASE_DIR}/../../cw_mweb/ios"
16
+TMP_DIR="${BASE_DIR}/tmp_mweb_frameworks"
17
+FRAMEWORK_NAME="Mwebd"
18
+
19
+rm -rf "$TMP_DIR"
20
+mkdir -p "$TMP_DIR"
21
+
22
+mkdir -p "$IOS_OUTPUT_DIR"
23
+
24
+write_info_plist() {
25
+ local framework_bundle="$1"
26
+ local framework_name="$2"
27
+ local target="$3"
28
+ local arch="$4"
29
+ local plist_path="${framework_bundle}/Info.plist"
30
+
31
+ local platform min_os_version dtplatformname dtsdkname
32
+
33
+ if [[ "$target" == "ios-simulator" ]]; then
34
+ platform="iPhoneSimulator"
35
+ dtplatformname="iphonesimulator"
36
+ dtsdkname="iphonesimulator17.4"
37
+ min_os_version="12.0"
38
+ elif [[ "$target" == "ios" ]]; then
39
+ platform="iPhoneOS"
40
+ dtplatformname="iphoneos"
41
+ dtsdkname="iphoneos17.4"
42
+ min_os_version="12.0"
43
+ else
44
+ echo "Unknown target: $target"
45
+ exit 1
46
+ fi
47
+
48
+ cat > "$plist_path" <<EOF
49
+<?xml version="1.0" encoding="UTF-8"?>
50
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
51
+<plist version="1.0">
52
+<dict>
53
+ <key>BuildMachineOSBuild</key>
54
+ <string>23F79</string>
55
+ <key>CFBundleDevelopmentRegion</key>
56
+ <string>en</string>
57
+ <key>CFBundleExecutable</key>
58
+ <string>${framework_name}</string>
59
+ <key>CFBundleIdentifier</key>
60
+ <string>com.cakewallet.${framework_name}</string>
61
+ <key>CFBundleInfoDictionaryVersion</key>
62
+ <string>6.0</string>
63
+ <key>CFBundleName</key>
64
+ <string>${framework_name}</string>
65
+ <key>CFBundlePackageType</key>
66
+ <string>FMWK</string>
67
+ <key>CFBundleShortVersionString</key>
68
+ <string>1.0</string>
69
+ <key>CFBundleVersion</key>
70
+ <string>1</string>
71
+ <key>CFBundleSupportedPlatforms</key>
72
+ <array>
73
+ <string>${platform}</string>
74
+ </array>
75
+ <key>DTCompiler</key>
76
+ <string>com.apple.compilers.llvm.clang.1_0</string>
77
+ <key>DTPlatformName</key>
78
+ <string>${dtplatformname}</string>
79
+ <key>DTPlatformVersion</key>
80
+ <string>17.4</string>
81
+ <key>DTSDKBuild</key>
82
+ <string>21E213</string>
83
+ <key>DTSDKName</key>
84
+ <string>${dtsdkname}</string>
85
+ <key>DTSDKVersion</key>
86
+ <string>17.4</string>
87
+ <key>DTXcode</key>
88
+ <string>1530</string>
89
+ <key>DTXcodeBuild</key>
90
+ <string>15E204a</string>
91
+ <key>MinimumOSVersion</key>
92
+ <string>${min_os_version}</string>
93
+ <key>UIDeviceFamily</key>
94
+ <array>
95
+ <integer>1</integer>
96
+ <integer>2</integer>
97
+ </array>
98
+</dict>
99
+</plist>
100
+EOF
101
+}
102
+
103
+build_go_library() {
104
+ local goos="$1"
105
+ local goarch="$2"
106
+ local cc_target="$3"
107
+ local sdk="$4"
108
+ local output_file="$5"
109
+
110
+ echo "Building Go library for ${goos}/${goarch} with target ${cc_target}..."
111
+
112
+ cd "$MWEB_GO_DIR"
113
+
114
+ export GOOS="$goos"
115
+ export GOARCH="$goarch"
116
+ export CGO_ENABLED=1
117
+ export CGO_CFLAGS="-fembed-bitcode"
118
+
119
+ if [[ "$sdk" == "iphoneos" ]]; then
120
+ export CC="$(xcrun -f clang) -target $cc_target -mios-version-min=12 --sysroot $(xcrun --sdk iphoneos --show-sdk-path)"
121
+ else
122
+ export CC="$(xcrun -f clang) -target $cc_target -mios-simulator-version-min=12 --sysroot $(xcrun --sdk iphonesimulator --show-sdk-path)"
123
+ fi
124
+
125
+ go build -buildmode=c-archive -trimpath -o "$output_file" mweb.go
126
+
127
+ echo "Built: $output_file"
128
+ cd - > /dev/null
129
+}
130
+
131
+create_framework() {
132
+ local archive_path="$1"
133
+ local framework_name="$2"
134
+ local target="$3"
135
+ local out_dir="$4"
136
+ local arch="$5"
137
+
138
+ echo "Creating ${framework_name}.framework for target ${target} (${arch}) in ${out_dir}..."
139
+
140
+ local framework_bundle="${out_dir}/${framework_name}.framework"
141
+
142
+ rm -rf "$framework_bundle"
143
+ mkdir -p "$framework_bundle"
144
+
145
+ if [[ ! -f "$archive_path" ]]; then
146
+ echo "Error: Input archive not found: $archive_path"
147
+ exit 1
148
+ fi
149
+
150
+ local temp_dir="${TMP_DIR}/temp_${arch}"
151
+ mkdir -p "$temp_dir"
152
+
153
+ pushd "$temp_dir"
154
+ ar x "$archive_path"
155
+
156
+ if [[ "$target" == "ios" ]]; then
157
+ xcrun -sdk iphoneos clang -dynamiclib -arch "${arch}" -mios-version-min=12 \
158
+ -install_name "@rpath/${framework_name}.framework/${framework_name}" \
159
+ -framework CoreFoundation -framework Security -lresolv \
160
+ -o "${framework_bundle}/${framework_name}" ./*.o
161
+ else
162
+ xcrun -sdk iphonesimulator clang -dynamiclib -arch "${arch}" -mios-simulator-version-min=12 \
163
+ -install_name "@rpath/${framework_name}.framework/${framework_name}" \
164
+ -framework CoreFoundation -framework Security -lresolv \
165
+ -o "${framework_bundle}/${framework_name}" ./*.o
166
+ fi
167
+ popd
168
+
169
+ echo "Created binary: ${framework_bundle}/${framework_name}"
170
+
171
+ write_info_plist "$framework_bundle" "$framework_name" "$target" "$arch"
172
+
173
+ mkdir -p "${framework_bundle}/Headers"
174
+ local header_file="${archive_path%.a}.h"
175
+ if [[ -f "$header_file" ]]; then
176
+ cp "$header_file" "${framework_bundle}/Headers/${framework_name}.h"
177
+ echo "Copied header: ${framework_bundle}/Headers/${framework_name}.h"
178
+ fi
179
+
180
+ echo "Framework created: ${framework_bundle}"
181
+}
182
+
183
+create_xcframework() {
184
+ local framework_name="$1"
185
+ local xcframework_output="$2"
186
+ shift 2
187
+ local frameworks=("$@")
188
+
189
+ echo "Creating ${xcframework_output} by bundling:"
190
+ for fw in "${frameworks[@]}"; do
191
+ echo " Framework: ${fw}"
192
+ done
193
+
194
+ local xcodebuild_args=()
195
+ for fw in "${frameworks[@]}"; do
196
+ xcodebuild_args+=("-framework" "$fw")
197
+ done
198
+
199
+ rm -rf "$xcframework_output"
200
+ xcodebuild -create-xcframework "${xcodebuild_args[@]}" -output "$xcframework_output"
201
+
202
+ echo "Created XCFramework: ${xcframework_output}"
203
+}
204
+
205
+echo "Building MWEB XCFramework for iOS..."
206
+
207
+IOS_DEVICE_OUT="${TMP_DIR}/ios_device"
208
+IOS_SIMULATOR_ARM64_OUT="${TMP_DIR}/ios_simulator_arm64"
209
+IOS_SIMULATOR_X86_64_OUT="${TMP_DIR}/ios_simulator_x86_64"
210
+
211
+mkdir -p "$IOS_DEVICE_OUT" "$IOS_SIMULATOR_ARM64_OUT" "$IOS_SIMULATOR_X86_64_OUT"
212
+
213
+IOS_DEVICE_ARCHIVE="${TMP_DIR}/${FRAMEWORK_NAME}_device.a"
214
+IOS_SIMULATOR_ARM64_ARCHIVE="${TMP_DIR}/${FRAMEWORK_NAME}_sim_arm64.a"
215
+IOS_SIMULATOR_X86_64_ARCHIVE="${TMP_DIR}/${FRAMEWORK_NAME}_sim_x86_64.a"
216
+
217
+build_go_library "ios" "arm64" "aarch64-apple-ios" "iphoneos" "$IOS_DEVICE_ARCHIVE"
218
+build_go_library "ios" "arm64" "aarch64-apple-ios-simulator" "iphonesimulator" "$IOS_SIMULATOR_ARM64_ARCHIVE"
219
+build_go_library "ios" "amd64" "x86_64-apple-ios-simulator" "iphonesimulator" "$IOS_SIMULATOR_X86_64_ARCHIVE"
220
+
221
+create_framework "$IOS_DEVICE_ARCHIVE" "$FRAMEWORK_NAME" "ios" "$IOS_DEVICE_OUT" "arm64"
222
+create_framework "$IOS_SIMULATOR_ARM64_ARCHIVE" "$FRAMEWORK_NAME" "ios-simulator" "$IOS_SIMULATOR_ARM64_OUT" "arm64"
223
+create_framework "$IOS_SIMULATOR_X86_64_ARCHIVE" "$FRAMEWORK_NAME" "ios-simulator" "$IOS_SIMULATOR_X86_64_OUT" "x86_64"
224
+
225
+IOS_SIMULATOR_UNIVERSAL_OUT="${TMP_DIR}/ios_simulator_universal"
226
+mkdir -p "$IOS_SIMULATOR_UNIVERSAL_OUT"
227
+
228
+SIMULATOR_UNIVERSAL_FRAMEWORK="${IOS_SIMULATOR_UNIVERSAL_OUT}/${FRAMEWORK_NAME}.framework"
229
+mkdir -p "$SIMULATOR_UNIVERSAL_FRAMEWORK"
230
+
231
+lipo -create \
232
+ "${IOS_SIMULATOR_ARM64_OUT}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" \
233
+ "${IOS_SIMULATOR_X86_64_OUT}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" \
234
+ -output "${SIMULATOR_UNIVERSAL_FRAMEWORK}/${FRAMEWORK_NAME}"
235
+
236
+echo "Created universal simulator binary: ${SIMULATOR_UNIVERSAL_FRAMEWORK}/${FRAMEWORK_NAME}"
237
+
238
+cp -r "${IOS_SIMULATOR_ARM64_OUT}/${FRAMEWORK_NAME}.framework/Info.plist" "${SIMULATOR_UNIVERSAL_FRAMEWORK}/"
239
+cp -r "${IOS_SIMULATOR_ARM64_OUT}/${FRAMEWORK_NAME}.framework/Headers" "${SIMULATOR_UNIVERSAL_FRAMEWORK}/"
240
+
241
+IOS_DEVICE_FRAMEWORK="${IOS_DEVICE_OUT}/${FRAMEWORK_NAME}.framework"
242
+IOS_SIMULATOR_FRAMEWORK="${SIMULATOR_UNIVERSAL_FRAMEWORK}"
243
+
244
+IOS_XCFRAMEWORK="${IOS_OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework"
245
+create_xcframework "$FRAMEWORK_NAME" "$IOS_XCFRAMEWORK" "$IOS_DEVICE_FRAMEWORK" "$IOS_SIMULATOR_FRAMEWORK"
246
+
247
+echo ""
248
+echo "XCFramework created successfully:"
249
+echo " iOS XCFramework: ${IOS_XCFRAMEWORK}"
250
+echo ""
251
+
252
+FFIGEN_CONFIG="${BASE_DIR}/../../cw_mweb/ffigen_config.yaml"
253
+if [[ -f "$FFIGEN_CONFIG" ]]; then
254
+ echo "Updating ffigen configuration..."
255
+ sed -i.bak "s|android/src/main/jniLibs/arm64-v8a/mweb.h|ios/${FRAMEWORK_NAME}.xcframework/ios-arm64/${FRAMEWORK_NAME}.framework/Headers/${FRAMEWORK_NAME}.h|g" "$FFIGEN_CONFIG"
256
+ mv "$FFIGEN_CONFIG.bak" "$FFIGEN_CONFIG"
257
+ echo "Updated ffigen config to use XCFramework header"
258
+fi
259
+
260
+cd "${BASE_DIR}/../../cw_mweb"
261
+echo "Generating Dart FFI bindings..."
262
+dart run ffigen --config ffigen_config.yaml
263
+
264
+echo "Build completed successfully!"
265
+
266
+rm -rf "$TMP_DIR"
267
+echo "Temporary files cleaned up."
\ No newline at end of file