@tokamakdev/platform-ios-simulator-x64 0.1.1-beta.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # The CLI runs the entrypoint from the pack root.
5
+ pack=$PWD
6
+ apple_tool=$pack/tools/tokamak-apple-signing
7
+ if [[ ! -x "$apple_tool" ]]; then
8
+ echo "Apple platform pack is missing its Apple helper: $apple_tool" >&2
9
+ exit 1
10
+ fi
11
+ if [[ $# -eq 1 && $1 == certs ]]; then
12
+ exec "$apple_tool" inventory
13
+ fi
14
+ if [[ $# -ne 3 || $1 != build ]]; then
15
+ echo "usage: entrypoint build INPUT OUTPUT | entrypoint certs" >&2
16
+ exit 2
17
+ fi
18
+
19
+ input=$2
20
+ output=$3
21
+ metadata=$input/metadata
22
+ app_slug=$(cat "$metadata/app-slug")
23
+ identifier=$(cat "$metadata/identifier")
24
+ platform=$(cat "$metadata/platform")
25
+ target=$(cat "$metadata/target")
26
+ project_dir=$(cat "$metadata/project-dir")
27
+ minimum=$(<"$pack/build/$platform-deployment-target")
28
+ output_parent=$(dirname "$output")
29
+ module_cache=$output_parent/.tokamak/module-cache
30
+ temporary=$(mktemp -d "${TMPDIR:-/tmp}/tokamak-apple.XXXXXX")
31
+ trap 'rm -rf "$temporary"' EXIT
32
+
33
+ case "$target" in
34
+ macos-arm64)
35
+ sdk=macosx
36
+ triple=arm64-apple-macos$minimum
37
+ ;;
38
+ macos-x64)
39
+ sdk=macosx
40
+ triple=x86_64-apple-macos$minimum
41
+ ;;
42
+ ios-arm64)
43
+ sdk=iphoneos
44
+ triple=arm64-apple-ios$minimum
45
+ ;;
46
+ ios-simulator-arm64)
47
+ sdk=iphonesimulator
48
+ triple=arm64-apple-ios$minimum-simulator
49
+ ;;
50
+ ios-simulator-x64)
51
+ sdk=iphonesimulator
52
+ triple=x86_64-apple-ios$minimum-simulator
53
+ ;;
54
+ *)
55
+ echo "unsupported Apple target: $target" >&2
56
+ exit 1
57
+ ;;
58
+ esac
59
+
60
+ bundle=$output
61
+ if [[ "$platform" == macos ]]; then
62
+ contents=$bundle/Contents
63
+ executable_dir=$contents/MacOS
64
+ resources_dir=$contents/Resources
65
+ app_dir=$resources_dir/app
66
+ icon=${TOKAMAK_MACOS_ICON:-}
67
+ app_files=("${TOKAMAK_MACOS_PLIST:-}" "${TOKAMAK_MACOS_ENTITLEMENTS:-}")
68
+ else
69
+ contents=$bundle
70
+ executable_dir=$bundle
71
+ resources_dir=$bundle
72
+ app_dir=$bundle/app
73
+ icon=${TOKAMAK_IOS_ICON:-}
74
+ app_files=("${TOKAMAK_IOS_PLIST:-}" "${TOKAMAK_IOS_ENTITLEMENTS:-}")
75
+ fi
76
+ if [[ -n "$icon" && ! ( -d "$icon" && "$icon" == *.[iI][cC][oO][nN] ) ]]; then
77
+ echo "$platform.icon must be an Icon Composer .icon package: $icon" >&2
78
+ exit 1
79
+ fi
80
+ icon_info_plist=$output_parent/.tokamak/$(basename "$output").icon-info.plist
81
+
82
+ write_plist() {
83
+ plist_args=(plist --input "$input" --output "$temporary/Info.plist")
84
+ if [[ -n "$icon" ]]; then
85
+ plist_args+=(--icon-info-plist "$icon_info_plist")
86
+ fi
87
+ "$apple_tool" "${plist_args[@]}"
88
+ cp "$temporary/Info.plist" "$contents/Info.plist"
89
+ }
90
+
91
+ sign_bundle() {
92
+ if [[ "$sdk" == iphonesimulator ]]; then
93
+ codesign --force --timestamp=none --sign - "$bundle"
94
+ return
95
+ fi
96
+ signing_args=(
97
+ sign
98
+ --platform "$platform"
99
+ --project "$project_dir"
100
+ --bundle "$bundle"
101
+ --bundle-id "$identifier"
102
+ )
103
+ if [[ "$platform" == ios && -f "$metadata/device-id" ]]; then
104
+ signing_args+=(--device-id "$(cat "$metadata/device-id")")
105
+ fi
106
+ "$apple_tool" "${signing_args[@]}"
107
+ }
108
+
109
+ # The bundle is reused while everything it is built from, apart from the
110
+ # Worker's environment and the signing settings, is unchanged.
111
+ bundle_key_file=$output_parent/.tokamak/$(basename "$output").input-key
112
+ key_files=("$input" "$pack")
113
+ for key_file in "$icon" "${app_files[@]}"; do
114
+ if [[ -n "$key_file" ]]; then
115
+ key_files+=("$key_file")
116
+ fi
117
+ done
118
+ bundle_key=$(
119
+ {
120
+ find -L "${key_files[@]}" -type f ! -path "$input/app/worker-environment.json" -print0 |
121
+ LC_ALL=C sort -z | xargs -0 shasum -a 256
122
+ env | LC_ALL=C sort | sed -n '/^TOKAMAK_/p' |
123
+ sed '/^TOKAMAK_IOS_TEAM_ID=/d; /^TOKAMAK_IOS_SIGNING_IDENTITY=/d; /^TOKAMAK_IOS_PROVISIONING_PROFILE=/d; /^TOKAMAK_MACOS_TEAM_ID=/d; /^TOKAMAK_IOS_BUILD_NUMBER=/d; /^TOKAMAK_MACOS_BUILD_NUMBER=/d'
124
+ printf '%s\n' "${DEVELOPER_DIR:-}" "$PATH"
125
+ xcodebuild -version
126
+ } | shasum -a 256 | cut -d ' ' -f 1
127
+ )
128
+ if [[ -d "$bundle" && -f "$bundle_key_file" && $(cat "$bundle_key_file") == "$bundle_key" && ( -z "$icon" || -f "$icon_info_plist" ) ]]; then
129
+ write_plist
130
+ cp "$input/app/worker-environment.json" "$app_dir/worker-environment.json"
131
+ sign_bundle
132
+ exit 0
133
+ fi
134
+
135
+ rm -f "$bundle_key_file" "$icon_info_plist"
136
+ rm -rf "$bundle"
137
+ mkdir -p "$executable_dir" "$app_dir" "$module_cache"
138
+ cp -R "$input/app/." "$app_dir/"
139
+
140
+ if [[ -n "$icon" ]]; then
141
+ if [[ "$platform" == macos ]]; then
142
+ icon_targets=(--target-device mac)
143
+ else
144
+ icon_targets=(--target-device iphone --target-device ipad)
145
+ fi
146
+ # actool names the app icon after its package.
147
+ cp -R "$icon" "$temporary/AppIcon.icon"
148
+ xcrun --sdk "$sdk" actool \
149
+ --compile "$resources_dir" \
150
+ --platform "$sdk" \
151
+ --minimum-deployment-target "$minimum" \
152
+ --app-icon AppIcon \
153
+ "${icon_targets[@]}" \
154
+ --output-partial-info-plist "$icon_info_plist" \
155
+ --output-format human-readable-text \
156
+ "$temporary/AppIcon.icon"
157
+ fi
158
+
159
+ shopt -s nullglob
160
+ swift_sources=()
161
+ for source in "$pack/native-shell"/*.swift; do
162
+ [[ -f "$source" ]] || continue
163
+ swift_sources+=("$source")
164
+ done
165
+
166
+ if [[ ! -f "$pack/native-shell/TokamakShell.swift" ]]; then
167
+ echo "Apple native shell source is missing: $pack/native-shell/TokamakShell.swift" >&2
168
+ exit 1
169
+ fi
170
+
171
+ # A plugin's class is a Swift type name, which the registry creates, and its
172
+ # sources are Swift.
173
+ swift_type='^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$'
174
+ registry=$temporary/TokamakPluginRegistry.swift
175
+ printf '%s\n\n%s\n%s\n' 'import Foundation' 'func tokamakPlugins(app: TokamakApp) -> [any TokamakPlugin] {' ' [' > "$registry"
176
+ for plugin in "$input/plugins"/*/; do
177
+ class=$(cat "$plugin/class" 2>/dev/null || true)
178
+ if [[ ! "$class" =~ $swift_type ]]; then
179
+ echo "plugin '$(basename "$plugin")' has invalid $platform class '$class'" >&2
180
+ exit 1
181
+ fi
182
+ printf ' %s(host: TokamakHost(app: app, plugin: "%s")),\n' "$class" "$(basename "$plugin")" >> "$registry"
183
+ for source in "$plugin/sources"/*; do
184
+ case "$source" in
185
+ *.swift) swift_sources+=("$source") ;;
186
+ *)
187
+ echo "Apple plugin source must be Swift: $source" >&2
188
+ exit 1
189
+ ;;
190
+ esac
191
+ done
192
+ done
193
+ printf '%s\n' ' ]' '}' >> "$registry"
194
+
195
+ # The executable exports only the entry points of the runtime parts the app
196
+ # links.
197
+ exported_symbols=$temporary/exported-symbols
198
+ sed 's/^/_/' "$metadata/exported-symbols" > "$exported_symbols"
199
+ swift_args=(
200
+ "${swift_sources[@]}"
201
+ "$registry"
202
+ -target "$triple"
203
+ -swift-version 5
204
+ -Osize
205
+ -whole-module-optimization
206
+ -module-cache-path "$module_cache"
207
+ -F "$pack/frameworks"
208
+ -framework TokamakRuntime
209
+ -framework CoreFoundation
210
+ -lc++
211
+ -lresolv
212
+ -Xlinker -dead_strip
213
+ -Xlinker -exported_symbols_list -Xlinker "$exported_symbols"
214
+ )
215
+
216
+ # Simulator builds embed their entitlements in __TEXT,__entitlements, where
217
+ # the simulator reads them.
218
+ if [[ "$sdk" == iphonesimulator ]]; then
219
+ simulator_entitlements=$temporary/simulator.entitlements
220
+ "$apple_tool" simulator-entitlements --identifier "$identifier" --output "$simulator_entitlements"
221
+ swift_args+=(-Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker "$simulator_entitlements")
222
+ fi
223
+
224
+ xcrun --sdk "$sdk" swiftc "${swift_args[@]}" -o "$executable_dir/$app_slug"
225
+ # Local symbols go; the exported entry points of linked parts stay.
226
+ xcrun --sdk "$sdk" strip -x "$executable_dir/$app_slug"
227
+
228
+ write_plist
229
+
230
+ # Plugins' resources go in the bundle's resources directory, where the system
231
+ # finds files such as notification sounds by name.
232
+ for resource in "$input/plugins"/*/resources/*; do
233
+ [[ -f "$resource" ]] || continue
234
+ name=${resource##*/}
235
+ name=${name#*-}
236
+ if [[ -e "$resources_dir/$name" ]]; then
237
+ echo "plugin resource '$name' would replace a file in the app bundle" >&2
238
+ exit 1
239
+ fi
240
+ cp "$resource" "$resources_dir/$name"
241
+ done
242
+
243
+ sign_bundle
244
+ mkdir -p "$(dirname "$bundle_key_file")"
245
+ printf '%s' "$bundle_key" > "$bundle_key_file"
@@ -0,0 +1,67 @@
1
+ #ifndef TOKAMAK_RUNTIME_H
2
+ #define TOKAMAK_RUNTIME_H
3
+
4
+ #include <stdbool.h>
5
+ #include <stddef.h>
6
+ #include <stdint.h>
7
+
8
+ enum {
9
+ TOKAMAK_DECISION_DEFAULT = 0,
10
+ TOKAMAK_DECISION_CANCEL = 1,
11
+ TOKAMAK_DECISION_USE = 2,
12
+ };
13
+
14
+ typedef struct {
15
+ uint8_t *data;
16
+ size_t len;
17
+ } TokamakBytes;
18
+
19
+ typedef struct {
20
+ TokamakBytes certificate;
21
+ TokamakBytes private_key;
22
+ } TokamakIdentity;
23
+
24
+ typedef void (*TokamakPluginRequest)(void *context, uint64_t id,
25
+ const char *plugin, const char *method,
26
+ const char *arguments);
27
+
28
+ typedef struct {
29
+ void *context;
30
+ TokamakPluginRequest call;
31
+ TokamakPluginRequest subscribe;
32
+ void (*unsubscribe)(void *context, uint64_t id);
33
+ } TokamakPluginHandler;
34
+
35
+ void *tokamak_runtime_start(const char *packaged_dir, const char *state_dir,
36
+ const char *storage_dir, const char *host,
37
+ bool foreground, TokamakPluginHandler plugins,
38
+ char *error, size_t error_len);
39
+ void *tokamak_runtime_start_development(const char *state_dir, const char *host,
40
+ const char *endpoint,
41
+ const char *session_token,
42
+ bool foreground,
43
+ TokamakPluginHandler plugins,
44
+ char *error, size_t error_len);
45
+ uint16_t tokamak_runtime_port(const void *runtime);
46
+ uint16_t tokamak_runtime_restore_gateway(const void *runtime, char *error,
47
+ size_t error_len);
48
+ void tokamak_runtime_stop(void *runtime);
49
+ bool tokamak_runtime_emit(const void *runtime, const char *name,
50
+ const char *event, uint64_t timeout_ms,
51
+ TokamakBytes *reply, char *error, size_t error_len);
52
+ bool tokamak_runtime_fetch(const void *runtime, const char *path,
53
+ uint64_t timeout_ms, TokamakBytes *body, char *error,
54
+ size_t error_len);
55
+ bool tokamak_runtime_set_foreground(const void *runtime, bool foreground);
56
+ bool tokamak_runtime_is_foreground(const void *runtime);
57
+ void tokamak_runtime_reply(const void *runtime, uint64_t id, const char *result);
58
+
59
+ int32_t tokamak_runtime_server_authority(const void *runtime, const char *host,
60
+ TokamakBytes *authority);
61
+ int32_t tokamak_runtime_client_identity(const void *runtime, const char *host,
62
+ size_t previous_failures,
63
+ TokamakIdentity *identity);
64
+ void tokamak_bytes_free(TokamakBytes bytes);
65
+ void tokamak_identity_free(TokamakIdentity identity);
66
+
67
+ #endif
@@ -0,0 +1,4 @@
1
+ framework module TokamakRuntime {
2
+ umbrella header "TokamakRuntime.h"
3
+ export *
4
+ }