peachsim 0.1.2220 → 0.1.2222
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.
- package/cli/commands/compat.ts +4 -4
- package/cli/commands/inspect.ts +4 -4
- package/cli/commands/report-issue.ts +1 -1
- package/cli/runtime-compat.ts +7 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/bundle-channel.cjs +475 -381
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/config.mjs +1 -1
- package/dist-lib/detox/index.cjs +3 -2
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +472 -379
- package/dist-lib/expo-swift-metadata.cjs +1 -1
- package/dist-lib/expo-swift-metadata.mjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +695 -574
- package/dist-lib/host/fetch-proxy-handler.cjs +10 -7
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +8232 -7815
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +8146 -7737
- package/dist-lib/native-app-identity-project.cjs +331 -13
- package/dist-lib/native-app-identity-project.mjs +331 -13
- package/dist-lib/native-app-identity.cjs +16 -3
- package/dist-lib/native-app-identity.mjs +16 -3
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/pdfium-raster.cjs +1 -1
- package/dist-lib/pdfium-raster.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/public-origins-lib-esm.json +25 -24
- package/dist-lib/public-origins-lib.json +99 -96
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/reap-browser.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +532 -420
- package/dist-lib/swift-compile.cjs +84 -49
- package/dist-lib/swift-compile.mjs +84 -49
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift-toolchain.cjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +158 -69
- package/dist-lib/vite.cjs +2930 -2800
- package/dist-lib/worklet-executable.cjs +1 -1
- package/dist-lib/worklet-executable.mjs +1 -1
- package/dist-types/packages/peach-engine/src/cli-companion.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/cli-host-terser.d.ts +7 -0
- package/dist-types/packages/peach-engine/src/engine/glass-material.d.ts +1 -1
- package/dist-types/packages/peach-engine/src/engine/liquid-glass.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/engine/native-layout.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/engine/node.d.ts +5 -0
- package/dist-types/packages/peach-engine/src/engine/scene-table.d.ts +8 -1
- package/dist-types/packages/peach-engine/src/engine/types.d.ts +3 -0
- package/dist-types/packages/peach-engine/src/engine/yoga-layout.d.ts +1 -1
- package/dist-types/packages/peach-engine/src/remote-stream/cloud-display.d.ts +2 -2
- package/dist-types/packages/peach-engine/src/render-worker/compositor-protocol.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/render-worker/shell-tree-wire.d.ts +1 -2
- package/dist-types/packages/peach-kit/src/internal.d.ts +1 -0
- package/dist-types/packages/peach-kit/src/ios-tint.d.ts +1 -0
- package/dist-types/packages/peach-kit/src/transitions/screen-transition-math.d.ts +25 -0
- package/kotlin/sdk.tar.gz +0 -0
- package/package.json +1 -1
- package/runtime-companion.json +1 -1
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNAnimation.h +4 -4
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNCameraController.h +1 -1
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNConstraint.h +5 -5
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNGeometry.h +1 -1
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNLevelOfDetail.h +1 -1
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNParametricGeometry.h +9 -9
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNParticleSystem.h +1 -1
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNPhysicsBehavior.h +7 -7
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNRenderer.h +1 -1
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNShadable.h +1 -1
- package/sdk/ios/System/Library/Frameworks/SceneKit.framework/Headers/SCNTechnique.h +1 -1
- package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/NSLayoutConstraint.h +1 -8
- package/sdk/ios/System/Library/Frameworks/UIKit.framework/Modules/module.modulemap +1 -0
- package/sdk/ios/System/Library/Frameworks/UIKitTypes.framework/Headers/UIKitTypes.h +1 -0
- package/sdk/ios/System/Library/Frameworks/UIKitTypes.framework/Headers/UILayoutPriority.h +11 -0
- package/src/cli-runtime.ts +1 -0
- package/src/expo-native-workspace.ts +14 -10
- package/src/expo-workspace-exclusion.ts +10 -7
- package/src/react-native-autolinking.ts +2 -1
- package/src/runtime-delivery.ts +7 -0
- package/src/swift-compile.ts +90 -54
- package/src/swift-coverage/xcode-assets.ts +4 -2
- package/src/swift-host.ts +53 -14
- package/src/swift-objc-import.ts +4 -0
- package/src/wasm-optimize.ts +5 -1
- package/src/xcode-project.ts +26 -5
- package/src/xcode-target-members.ts +25 -3
|
@@ -7,7 +7,7 @@ import path from 'node:path'
|
|
|
7
7
|
import { promisify } from 'node:util'
|
|
8
8
|
import { detectPackageManager } from '../cli/commands/detect'
|
|
9
9
|
import { teamMachineInstalled } from './admitted-mac-build'
|
|
10
|
-
import { workspaceExclusion } from './expo-workspace-exclusion'
|
|
10
|
+
import { workspaceExclusion, type WorkspaceExclusion } from './expo-workspace-exclusion'
|
|
11
11
|
import { cacheDir } from './home-paths'
|
|
12
12
|
import { failedOutputLine } from './native-failure-output'
|
|
13
13
|
import { requireNativeGit } from './native-git'
|
|
@@ -49,7 +49,7 @@ export function reactNativePodsEnvironment() {
|
|
|
49
49
|
function workspacePackageManager(
|
|
50
50
|
root: string,
|
|
51
51
|
declared: unknown,
|
|
52
|
-
excluded:
|
|
52
|
+
excluded: WorkspaceExclusion,
|
|
53
53
|
): string {
|
|
54
54
|
const manager = typeof declared === 'string' ? declared : detectPackageManager(root)
|
|
55
55
|
const locks = [
|
|
@@ -116,7 +116,7 @@ export async function verifyExpoWorkspaceCopy(app: string, work: string) {
|
|
|
116
116
|
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
117
117
|
const file = path.join(directory, entry.name)
|
|
118
118
|
const relative = path.relative(root, file)
|
|
119
|
-
if (excluded(relative)) continue
|
|
119
|
+
if (excluded(relative, entry.isDirectory())) continue
|
|
120
120
|
const copy = path.join(work, relative)
|
|
121
121
|
if (entry.isDirectory()) walk(file)
|
|
122
122
|
else if (entry.isSymbolicLink()) {
|
|
@@ -212,7 +212,7 @@ async function hashWorkspaceInputs(
|
|
|
212
212
|
hash: string
|
|
213
213
|
// the subset of inputs that decides the prepared workspace
|
|
214
214
|
nativeHash: string
|
|
215
|
-
excluded:
|
|
215
|
+
excluded: WorkspaceExclusion
|
|
216
216
|
}> {
|
|
217
217
|
const root = findWorkspaceRoot(app)
|
|
218
218
|
const excluded = await workspaceExclusion(
|
|
@@ -286,7 +286,7 @@ async function hashWorkspaceInputs(
|
|
|
286
286
|
signal?.throwIfAborted()
|
|
287
287
|
const file = path.join(directory, entry.name)
|
|
288
288
|
const relative = path.relative(root, file)
|
|
289
|
-
if (excluded(relative)) continue
|
|
289
|
+
if (excluded(relative, entry.isDirectory())) continue
|
|
290
290
|
hash.update(`${relative}\0`)
|
|
291
291
|
if (entry.isSymbolicLink()) {
|
|
292
292
|
const link = `link\0${await fs.promises.readlink(file)}\0`
|
|
@@ -446,7 +446,7 @@ function syncChangedFiles(
|
|
|
446
446
|
root: string,
|
|
447
447
|
work: string,
|
|
448
448
|
appRelative: string,
|
|
449
|
-
excluded:
|
|
449
|
+
excluded: WorkspaceExclusion,
|
|
450
450
|
installed: boolean,
|
|
451
451
|
) {
|
|
452
452
|
const copyIfNewer = (file: string, relative: string, newerOnly: boolean) => {
|
|
@@ -464,8 +464,12 @@ function syncChangedFiles(
|
|
|
464
464
|
)
|
|
465
465
|
return
|
|
466
466
|
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
467
|
-
|
|
468
|
-
|
|
467
|
+
// a tool already running from the copy (the autolinker) must never read a
|
|
468
|
+
// truncated script, so the new bytes land by rename
|
|
469
|
+
const staged = `${target}.${process.pid}.peach-sync`
|
|
470
|
+
fs.copyFileSync(file, staged)
|
|
471
|
+
fs.utimesSync(staged, source.atime, source.mtime)
|
|
472
|
+
fs.renameSync(staged, target)
|
|
469
473
|
}
|
|
470
474
|
const walkInstalled = (directory: string) => {
|
|
471
475
|
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
@@ -490,7 +494,7 @@ function syncChangedFiles(
|
|
|
490
494
|
}
|
|
491
495
|
// the app's ios project is prebuild output, not a source
|
|
492
496
|
if (
|
|
493
|
-
excluded(relative) ||
|
|
497
|
+
excluded(relative, entry.isDirectory()) ||
|
|
494
498
|
entry.isSymbolicLink() ||
|
|
495
499
|
(!sourceIos && relative === path.join(appRelative, 'ios'))
|
|
496
500
|
)
|
|
@@ -640,7 +644,7 @@ function prepare(app: string, stage: 'project' | 'workspace', signal?: AbortSign
|
|
|
640
644
|
async function copyInstalledWorkspace(
|
|
641
645
|
root: string,
|
|
642
646
|
destination: string,
|
|
643
|
-
excluded:
|
|
647
|
+
excluded: WorkspaceExclusion,
|
|
644
648
|
) {
|
|
645
649
|
const installed: string[] = []
|
|
646
650
|
await fs.promises.cp(root, destination, {
|
|
@@ -4,6 +4,8 @@ import path from 'node:path'
|
|
|
4
4
|
import { promisify } from 'node:util'
|
|
5
5
|
import ignore from 'ignore'
|
|
6
6
|
|
|
7
|
+
export type WorkspaceExclusion = (relative: string, isDirectory?: boolean) => boolean
|
|
8
|
+
|
|
7
9
|
// eas build archives a repository without its gitignored paths, so the prepare
|
|
8
10
|
// neither copies nor hashes them: files a dev server generates into an ignored
|
|
9
11
|
// directory never invalidate the prepared workspace.
|
|
@@ -13,7 +15,7 @@ export async function workspaceExclusion(
|
|
|
13
15
|
root: string,
|
|
14
16
|
portable = false,
|
|
15
17
|
linkedPackages: string[] = [],
|
|
16
|
-
) {
|
|
18
|
+
): Promise<WorkspaceExclusion> {
|
|
17
19
|
const listed = await promisify(execFile)(
|
|
18
20
|
'git',
|
|
19
21
|
['ls-files', '-z', '--others', '--ignored', '--exclude-standard', '--directory'],
|
|
@@ -34,8 +36,8 @@ export async function workspaceExclusion(
|
|
|
34
36
|
.filter(Boolean)
|
|
35
37
|
.map((entry) => entry.replace(/\/$/, '')),
|
|
36
38
|
)
|
|
37
|
-
const ignoreFiles = new Map<string, ReturnType<typeof ignore
|
|
38
|
-
return (relative
|
|
39
|
+
const ignoreFiles = new Map<string, ReturnType<typeof ignore> | null>()
|
|
40
|
+
return (relative, knownDirectory) => {
|
|
39
41
|
const parts = relative.split(path.sep)
|
|
40
42
|
const linked = linkedPackages.some((directory) =>
|
|
41
43
|
relative.startsWith(directory + path.sep),
|
|
@@ -47,16 +49,17 @@ export async function workspaceExclusion(
|
|
|
47
49
|
}
|
|
48
50
|
if (portable && relative) {
|
|
49
51
|
let excluded = false
|
|
50
|
-
const isDirectory =
|
|
52
|
+
const isDirectory =
|
|
53
|
+
knownDirectory ?? fs.lstatSync(path.join(root, relative)).isDirectory()
|
|
51
54
|
for (let index = 0; index < parts.length; index++) {
|
|
52
55
|
const directory = parts.slice(0, index).join(path.sep)
|
|
53
56
|
let rules = ignoreFiles.get(directory)
|
|
54
|
-
if (
|
|
55
|
-
rules = ignore()
|
|
57
|
+
if (rules === undefined) {
|
|
56
58
|
const file = path.join(root, directory, '.gitignore')
|
|
57
|
-
|
|
59
|
+
rules = fs.existsSync(file) ? ignore().add(fs.readFileSync(file, 'utf8')) : null
|
|
58
60
|
ignoreFiles.set(directory, rules)
|
|
59
61
|
}
|
|
62
|
+
if (!rules) continue
|
|
60
63
|
const item = parts.slice(index).join('/')
|
|
61
64
|
const result = rules.test(isDirectory ? `${item}/` : item)
|
|
62
65
|
if (result.ignored) excluded = true
|
|
@@ -29,6 +29,7 @@ async function cliAdvertises(
|
|
|
29
29
|
appRoot: string,
|
|
30
30
|
signal?: AbortSignal,
|
|
31
31
|
): Promise<boolean> {
|
|
32
|
+
const started = Date.now()
|
|
32
33
|
const { stdout, stderr } = await run('node', [cli, ...args], {
|
|
33
34
|
cwd: appRoot,
|
|
34
35
|
signal,
|
|
@@ -38,7 +39,7 @@ async function cliAdvertises(
|
|
|
38
39
|
})
|
|
39
40
|
if (!stdout.trim())
|
|
40
41
|
throw new Error(
|
|
41
|
-
`${cli} ${args.join(' ')}
|
|
42
|
+
`${cli} ${args.join(' ')} exited 0 after ${Date.now() - started}ms with empty help output${stderr.trim() ? `: ${stderr.trim()}` : ''}`,
|
|
42
43
|
)
|
|
43
44
|
return stdout.includes(token)
|
|
44
45
|
}
|
package/src/runtime-delivery.ts
CHANGED
|
@@ -39,6 +39,13 @@ export const RNX_RUNTIME_PRODUCT: RuntimeProduct = {
|
|
|
39
39
|
// vite/metro plugins serve, so its absence means the tarball is not one.
|
|
40
40
|
installedMarker: 'index.html',
|
|
41
41
|
verifyInstall: ensureCliCompanion,
|
|
42
|
+
// canvaskit's ganesh backend is a runtime pack because a browser with WebGPU
|
|
43
|
+
// never runs it, but linux and CI browsers usually have no GPU and always do
|
|
44
|
+
afterInstall: async (dir) => {
|
|
45
|
+
if (process.platform !== 'linux' && !process.env.CI) return
|
|
46
|
+
const { ensureRuntimePackFor } = await import('./runtime-packs.ts')
|
|
47
|
+
await ensureRuntimePackFor(dir, '/engine/canvaskit-ganesh.wasm')
|
|
48
|
+
},
|
|
42
49
|
env: {
|
|
43
50
|
cdnOrigin: 'PEACH_CDN_ORIGIN',
|
|
44
51
|
channel: 'PEACH_RUNTIME_CHANNEL',
|
package/src/swift-compile.ts
CHANGED
|
@@ -140,7 +140,7 @@ import {
|
|
|
140
140
|
SWIFT_FRAMEWORK_PRODUCT_FILE,
|
|
141
141
|
swiftFrameworkProductSchema,
|
|
142
142
|
} from './swiftRuntimeProductContract'
|
|
143
|
-
import { optimizeWasm, WASM_OPTIMIZE_IDENTITY } from './wasm-optimize'
|
|
143
|
+
import { KEEP_WASM_NAMES, optimizeWasm, WASM_OPTIMIZE_IDENTITY } from './wasm-optimize'
|
|
144
144
|
import { writeBuildFile } from './write-build-file'
|
|
145
145
|
import { writeXcodeHeaderSearch } from './xcode-header-search'
|
|
146
146
|
import type { SwiftImageUpload } from './swift-submit'
|
|
@@ -424,11 +424,14 @@ export function swiftModuleInterface(
|
|
|
424
424
|
// the compiler imports the module that defines a type, and UIKit's declarations
|
|
425
425
|
// live in UIKitCore/UIKitText, which only the umbrella UIKit module represents
|
|
426
426
|
// to clang. CoreFoundation's CGFloat lives in the Swift CoreFoundation overlay,
|
|
427
|
-
// while clang's Foundation umbrella
|
|
427
|
+
// while clang's Foundation umbrella also owns networking class declarations.
|
|
428
428
|
const clangInterfaceHeader = (header: string): string =>
|
|
429
429
|
header
|
|
430
430
|
.replace(/^@import (?:UIKitCore|UIKitText);$/gm, '@import UIKit;')
|
|
431
|
-
.replace(
|
|
431
|
+
.replace(
|
|
432
|
+
/^@import (?:CoreFoundation|FoundationNetworking);$/gm,
|
|
433
|
+
'@import Foundation;',
|
|
434
|
+
)
|
|
432
435
|
.replace(/\b_TtC10Foundation\d+(NS\w+)\b/g, '$1')
|
|
433
436
|
.replace(/\b__attribute__\(\(objc_subclassing_restricted\)\)\s*/g, '')
|
|
434
437
|
|
|
@@ -836,7 +839,8 @@ const OPTIONAL_FRAMEWORK_DEPENDENCIES: Record<string, string[]> = {
|
|
|
836
839
|
PeachCFNetwork: [],
|
|
837
840
|
JavaScriptCore: ['PeachJavaScriptCore'],
|
|
838
841
|
PeachJavaScriptCore: [],
|
|
839
|
-
GameplayKit
|
|
842
|
+
// GameplayKit names SpriteKit and SceneKit nodes, as on iOS
|
|
843
|
+
GameplayKit: ['SpriteKit', 'SceneKit', 'PeachBox2D', 'simd', 'GLKit'],
|
|
840
844
|
simd: [],
|
|
841
845
|
ModelIO: ['simd'],
|
|
842
846
|
GLKit: ['ModelIO'],
|
|
@@ -1593,14 +1597,25 @@ export function swiftTargetDependencies(
|
|
|
1593
1597
|
}
|
|
1594
1598
|
|
|
1595
1599
|
const ONE_PRODUCT = '.product(name: "One", package: "sootsim-swift")'
|
|
1596
|
-
|
|
1597
|
-
//
|
|
1598
|
-
//
|
|
1599
|
-
const
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1600
|
+
// the game family (plans/peach/spritekit.md, plans/peach/scenekit.md) links
|
|
1601
|
+
// only into an app whose sources import it, so no other artifact carries it.
|
|
1602
|
+
// SceneKit names SpriteKit, so importing it links both.
|
|
1603
|
+
const GAME_FAMILY = ['SpriteKit', 'SceneKit'] as const
|
|
1604
|
+
const gameProducts = (files: Record<string, string>): string[] => {
|
|
1605
|
+
const imported = new Set(
|
|
1606
|
+
Object.entries(files).flatMap(([file, contents]) =>
|
|
1607
|
+
file.endsWith('.swift') ? swiftImportNames(contents) : [],
|
|
1608
|
+
),
|
|
1603
1609
|
)
|
|
1610
|
+
if (imported.has('SceneKit')) return [...GAME_FAMILY]
|
|
1611
|
+
return imported.has('SpriteKit') ? ['SpriteKit'] : []
|
|
1612
|
+
}
|
|
1613
|
+
const gameProduct = (name: string) =>
|
|
1614
|
+
`.product(name: "${name}", package: "sootsim-swift")`
|
|
1615
|
+
const GAME_REACH: Record<string, string[]> = {
|
|
1616
|
+
SpriteKit: ['SpriteKit', 'PeachBox2D', 'simd', 'GLKit'],
|
|
1617
|
+
SceneKit: ['SceneKit'],
|
|
1618
|
+
}
|
|
1604
1619
|
// every iOS source sees through Foundation what darwin's Foundation exports:
|
|
1605
1620
|
// PeachObjC supplies the ObjectiveC module's selectors, Dispatch Foundation's
|
|
1606
1621
|
// Darwin queue exports, and FoundationNetworking (re-exporting PeachFoundation)
|
|
@@ -1672,6 +1687,7 @@ export function swiftArtifactHash(
|
|
|
1672
1687
|
hash.update(`swift-compile\n${release}\n`)
|
|
1673
1688
|
hash.update(compilerSourceDigest)
|
|
1674
1689
|
if (input.oneModule) hash.update('one-module\n')
|
|
1690
|
+
if (KEEP_WASM_NAMES) hash.update('names\n')
|
|
1675
1691
|
hash.update(swiftModuleDigest(moduleRoot))
|
|
1676
1692
|
if (input.optimize) hash.update(`optimize\n${WASM_OPTIMIZE_IDENTITY}\n`)
|
|
1677
1693
|
for (const file of Object.keys(input.files).sort()) {
|
|
@@ -1853,12 +1869,13 @@ export function emitSwiftPackageManifest(args: {
|
|
|
1853
1869
|
nativeFlags?: Map<string, string[]>
|
|
1854
1870
|
nativeImportFlags?: Map<string, string[]>
|
|
1855
1871
|
nativeHeaderFlags?: string[]
|
|
1872
|
+
nativeSwiftHeaderMaps?: ReadonlyMap<string, string>
|
|
1856
1873
|
nativeHeaderDeclarations?: Readonly<Record<string, readonly string[]>>
|
|
1857
1874
|
objcImplementationModules?: Set<string>
|
|
1858
1875
|
siblings: Map<string, string[]>
|
|
1859
1876
|
moduleRoot: string
|
|
1860
1877
|
oneModule?: boolean
|
|
1861
|
-
|
|
1878
|
+
gameProducts?: string[]
|
|
1862
1879
|
/** link the prebuilt distribution at moduleRoot instead of its sources. */
|
|
1863
1880
|
distribution?: SwiftDistributionManifest
|
|
1864
1881
|
/** prebuilt interfaces owned by local source or system-library targets. */
|
|
@@ -1883,7 +1900,14 @@ export function emitSwiftPackageManifest(args: {
|
|
|
1883
1900
|
/** the development region SwiftPM needs as defaultLocalization beside localized resources. */
|
|
1884
1901
|
defaultLocalization?: string
|
|
1885
1902
|
}): string {
|
|
1886
|
-
const {
|
|
1903
|
+
const {
|
|
1904
|
+
targets,
|
|
1905
|
+
siblings,
|
|
1906
|
+
moduleRoot,
|
|
1907
|
+
oneModule,
|
|
1908
|
+
gameProducts = [],
|
|
1909
|
+
distribution,
|
|
1910
|
+
} = args
|
|
1887
1911
|
const prebuilt = args.prebuilt
|
|
1888
1912
|
// a distribution and a separately built framework package both link objects
|
|
1889
1913
|
// instead of compiling the framework sources into this package's scratch.
|
|
@@ -1930,9 +1954,8 @@ export function emitSwiftPackageManifest(args: {
|
|
|
1930
1954
|
for (const name of [...siblings.values()].flat())
|
|
1931
1955
|
if (OPTIONAL_FRAMEWORKS.has(name) && !targets.some((target) => target.name === name))
|
|
1932
1956
|
reach(name)
|
|
1933
|
-
|
|
1934
|
-
for (const name of [
|
|
1935
|
-
}
|
|
1957
|
+
for (const product of gameProducts)
|
|
1958
|
+
for (const name of GAME_REACH[product] ?? []) reach(name)
|
|
1936
1959
|
// the distribution builder names each object lib/<target>-<file>.o.
|
|
1937
1960
|
// preserve link order; only reached framework registrants link eagerly.
|
|
1938
1961
|
// the list is named by its content: SwiftPM relinks when the linker
|
|
@@ -1968,7 +1991,7 @@ export function emitSwiftPackageManifest(args: {
|
|
|
1968
1991
|
const objects = available.filter(
|
|
1969
1992
|
(object) =>
|
|
1970
1993
|
!targets.some((target) => object.startsWith(`lib/${target.name}-`)) &&
|
|
1971
|
-
[...OPTIONAL_FRAMEWORKS,
|
|
1994
|
+
[...OPTIONAL_FRAMEWORKS, ...GAME_FAMILY, 'PeachBox2D'].every(
|
|
1972
1995
|
(name) => !object.startsWith(`lib/${name}-`) || reachedFrameworks.has(name),
|
|
1973
1996
|
),
|
|
1974
1997
|
)
|
|
@@ -2163,6 +2186,11 @@ export function emitSwiftPackageManifest(args: {
|
|
|
2163
2186
|
includeImportContext(dependency)
|
|
2164
2187
|
const importedNativeFlags = [
|
|
2165
2188
|
...(args.nativeImportFlags?.get(target.name) ?? []),
|
|
2189
|
+
...[...importContext].flatMap((name) => {
|
|
2190
|
+
const map =
|
|
2191
|
+
name === target.name ? undefined : args.nativeSwiftHeaderMaps?.get(name)
|
|
2192
|
+
return map ? ['-fmodule-map-file=' + map] : []
|
|
2193
|
+
}),
|
|
2166
2194
|
...[...importContext].flatMap((name) => args.native?.get(name)?.importFlags ?? []),
|
|
2167
2195
|
...[...importContext].flatMap((name) => {
|
|
2168
2196
|
const flags = targets.find((target) => target.name === name)?.swiftFlags ?? []
|
|
@@ -2239,7 +2267,7 @@ export function emitSwiftPackageManifest(args: {
|
|
|
2239
2267
|
: [
|
|
2240
2268
|
'.product(name: "SwiftUI", package: "sootsim-swift")',
|
|
2241
2269
|
...(oneModule ? [ONE_PRODUCT] : []),
|
|
2242
|
-
...(
|
|
2270
|
+
...gameProducts.map(gameProduct),
|
|
2243
2271
|
]),
|
|
2244
2272
|
...(siblings.get(target.name) ?? []).flatMap((dependency) =>
|
|
2245
2273
|
clang &&
|
|
@@ -2293,7 +2321,7 @@ export function emitSwiftPackageManifest(args: {
|
|
|
2293
2321
|
.unsafeFlags(${flagArray(`[
|
|
2294
2322
|
${REACTOR_FLAG}${executableLinkFlags(args.root)} "-Xlinker", "--export-if-defined=__main_argc_argv"${library},
|
|
2295
2323
|
]`)}),
|
|
2296
|
-
.unsafeFlags(["-Xlinker", "--strip-all"], .when(configuration: .release)),
|
|
2324
|
+
${KEEP_WASM_NAMES ? '' : '.unsafeFlags(["-Xlinker", "--strip-all"], .when(configuration: .release)),'}
|
|
2297
2325
|
]`
|
|
2298
2326
|
: librarySettings.length > 0
|
|
2299
2327
|
? `,
|
|
@@ -3010,8 +3038,6 @@ const FOUNDATION_OVERLAY_GLOBALS = new Set([
|
|
|
3010
3038
|
'NSURLProtectionSpaceHTTPS',
|
|
3011
3039
|
'NSURLProtectionSpaceHTTPSProxy',
|
|
3012
3040
|
'NSURLProtectionSpaceSOCKSProxy',
|
|
3013
|
-
'NSURLSessionDownloadTaskResumeData',
|
|
3014
|
-
'NSURLSessionTransferSizeUnknown',
|
|
3015
3041
|
'NSURLSessionUploadTaskResumeData',
|
|
3016
3042
|
'NSUTF16BigEndianStringEncoding',
|
|
3017
3043
|
'NSUTF16LittleEndianStringEncoding',
|
|
@@ -4610,6 +4636,7 @@ export function writeSwiftProject(
|
|
|
4610
4636
|
// declarations are imported before swift can emit the header that native
|
|
4611
4637
|
// implementations consume. give those implementations a downstream target.
|
|
4612
4638
|
const importModuleMaps = new Map<string, string>()
|
|
4639
|
+
const sourceModuleMaps = new Map<string, { path: string; contents: string }>()
|
|
4613
4640
|
const generatedModuleMaps: { output: string; module: string; published: string }[] = []
|
|
4614
4641
|
for (const target of targets) {
|
|
4615
4642
|
const prefix = target.path === '.' ? '' : `${target.path}/`
|
|
@@ -4938,6 +4965,10 @@ export function writeSwiftProject(
|
|
|
4938
4965
|
stageTargetFile(target.name, path.join(layout.root, modulemap), moduleContents, {
|
|
4939
4966
|
allowExisting: true,
|
|
4940
4967
|
})
|
|
4968
|
+
sourceModuleMaps.set(swiftTargetModuleName(target.name), {
|
|
4969
|
+
path: path.join(layout.root, modulemap),
|
|
4970
|
+
contents: moduleContents.toString(),
|
|
4971
|
+
})
|
|
4941
4972
|
// clang resolves a framework map loaded through extern module against
|
|
4942
4973
|
// the map directory, not the framework root, so mirror every header
|
|
4943
4974
|
// the map names there. clang looks in Headers/ and PrivateHeaders/ for
|
|
@@ -5272,6 +5303,7 @@ export function writeSwiftProject(
|
|
|
5272
5303
|
? ['-ivfsoverlay', headerSearch.files[0]!]
|
|
5273
5304
|
: []
|
|
5274
5305
|
const nativeHeaderFlags: string[] = [...headerAliasFlags]
|
|
5306
|
+
const nativeSwiftHeaderMaps = new Map<string, string>()
|
|
5275
5307
|
const originalMaps = new Map<string, string>()
|
|
5276
5308
|
for (const target of input.nativeTargets ?? []) {
|
|
5277
5309
|
for (const flag of [...target.flags, ...target.cxxFlags]) {
|
|
@@ -5304,9 +5336,14 @@ export function writeSwiftProject(
|
|
|
5304
5336
|
)
|
|
5305
5337
|
const moduleName = swiftTargetModuleName(name)
|
|
5306
5338
|
const originalMap = originalMaps.get(moduleName)
|
|
5307
|
-
const
|
|
5339
|
+
const stagedMap = sourceModuleMaps.get(moduleName)
|
|
5340
|
+
const originalPath = originalMap
|
|
5341
|
+
? path.join(layout.root, originalMap)
|
|
5342
|
+
: stagedMap?.path
|
|
5343
|
+
const originalContents = originalMap ? input.files[originalMap]! : stagedMap?.contents
|
|
5344
|
+
const originalTokens = originalContents ? moduleMapTokens(originalContents) : []
|
|
5308
5345
|
if (
|
|
5309
|
-
|
|
5346
|
+
originalPath &&
|
|
5310
5347
|
originalTokens.some(
|
|
5311
5348
|
(token, index) =>
|
|
5312
5349
|
token === 'module' &&
|
|
@@ -5314,26 +5351,26 @@ export function writeSwiftProject(
|
|
|
5314
5351
|
originalTokens[index + 1] === `${moduleName}.Swift`),
|
|
5315
5352
|
)
|
|
5316
5353
|
) {
|
|
5317
|
-
nativeHeaderFlags.push('-fmodule-map-file=' +
|
|
5354
|
+
nativeHeaderFlags.push('-fmodule-map-file=' + originalPath)
|
|
5355
|
+
nativeSwiftHeaderMaps.set(name, originalPath)
|
|
5318
5356
|
continue
|
|
5319
5357
|
}
|
|
5320
5358
|
files.set(
|
|
5321
5359
|
modulemap,
|
|
5322
|
-
|
|
5323
|
-
? `extern module ${moduleName} ${JSON.stringify(
|
|
5360
|
+
originalPath
|
|
5361
|
+
? `extern module ${moduleName} ${JSON.stringify(originalPath)}\nmodule ${moduleName}.Swift {\n header ${JSON.stringify(path.join(headerDirectory, name + '-Swift.h'))}\n requires objc\n}\n`
|
|
5324
5362
|
: swiftObjCModuleMap(
|
|
5325
5363
|
moduleName,
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
).map((header) => path.join(layout.root, header)),
|
|
5331
|
-
path.join(headerDirectory, name + '-Swift.h'),
|
|
5332
|
-
],
|
|
5364
|
+
(
|
|
5365
|
+
input.nativeTargets?.find((target) => target.name === name)
|
|
5366
|
+
?.publicHeaders ?? []
|
|
5367
|
+
).map((header) => path.join(layout.root, header)),
|
|
5333
5368
|
submoduleImports.get(moduleName),
|
|
5369
|
+
path.join(headerDirectory, name + '-Swift.h'),
|
|
5334
5370
|
),
|
|
5335
5371
|
)
|
|
5336
5372
|
nativeHeaderFlags.push('-fmodule-map-file=' + modulemap)
|
|
5373
|
+
nativeSwiftHeaderMaps.set(name, modulemap)
|
|
5337
5374
|
}
|
|
5338
5375
|
// swiftpm plans a build root's build once and reuses the plan until a
|
|
5339
5376
|
// manifest changes, so a file added to the module would never compile
|
|
@@ -5632,13 +5669,17 @@ export function writeSwiftProject(
|
|
|
5632
5669
|
.replace(product, `${product}\n ${ONE_PRODUCT},`)
|
|
5633
5670
|
.replace(flags, `${flags}${ONE_IMPLICIT_FLAGS}`)
|
|
5634
5671
|
}
|
|
5635
|
-
|
|
5672
|
+
const games = gameProducts(input.files)
|
|
5673
|
+
if (games.length > 0) {
|
|
5636
5674
|
const anchor = '.product(name: "CoreLocation", package: "sootsim-swift"),'
|
|
5637
5675
|
if (!manifest.includes(anchor))
|
|
5638
5676
|
throw new Error(
|
|
5639
|
-
'scripts/contrast-app-Package.swift lost the line the
|
|
5677
|
+
'scripts/contrast-app-Package.swift lost the line the game products link at',
|
|
5640
5678
|
)
|
|
5641
|
-
manifest = manifest.replace(
|
|
5679
|
+
manifest = manifest.replace(
|
|
5680
|
+
anchor,
|
|
5681
|
+
[anchor, ...games.map((name) => `${gameProduct(name)},`)].join('\n '),
|
|
5682
|
+
)
|
|
5642
5683
|
}
|
|
5643
5684
|
files.set(path.join(layout.root, 'Package.swift'), manifest + moduleFiles)
|
|
5644
5685
|
} else {
|
|
@@ -5788,6 +5829,7 @@ export function writeSwiftProject(
|
|
|
5788
5829
|
nativeFlags,
|
|
5789
5830
|
nativeImportFlags,
|
|
5790
5831
|
nativeHeaderFlags,
|
|
5832
|
+
nativeSwiftHeaderMaps,
|
|
5791
5833
|
nativeHeaderDeclarations,
|
|
5792
5834
|
objcImplementationModules: new Set(
|
|
5793
5835
|
targets
|
|
@@ -5807,7 +5849,7 @@ export function writeSwiftProject(
|
|
|
5807
5849
|
siblings: moduleSiblings,
|
|
5808
5850
|
moduleRoot,
|
|
5809
5851
|
oneModule: input.oneModule,
|
|
5810
|
-
|
|
5852
|
+
gameProducts: gameProducts(input.files),
|
|
5811
5853
|
distribution: distribution ?? undefined,
|
|
5812
5854
|
moduleExcludes,
|
|
5813
5855
|
deferDarwinOverlay:
|
|
@@ -5974,31 +6016,30 @@ export function writeSwiftProject(
|
|
|
5974
6016
|
),
|
|
5975
6017
|
]),
|
|
5976
6018
|
)
|
|
6019
|
+
const producerSet = new Set([...Object.keys(nativeHeaderDeclarations), ...producers])
|
|
6020
|
+
const orderedProducers: string[] = []
|
|
5977
6021
|
const included = new Set<string>()
|
|
5978
6022
|
const include = (name: string): void => {
|
|
5979
6023
|
if (included.has(name)) return
|
|
5980
6024
|
included.add(name)
|
|
5981
6025
|
for (const dependency of dependencies.get(name) ?? []) include(dependency)
|
|
6026
|
+
if (producerSet.has(name)) orderedProducers.push(name)
|
|
5982
6027
|
}
|
|
5983
|
-
for (const producer of
|
|
6028
|
+
for (const producer of producerSet)
|
|
5984
6029
|
for (const dependency of dependencies.get(producer) ?? []) include(dependency)
|
|
5985
|
-
|
|
6030
|
+
const needsHeaderStages = [...producerSet].some((name) => included.has(name))
|
|
6031
|
+
for (const producer of producerSet) include(producer)
|
|
5986
6032
|
return {
|
|
5987
6033
|
nativeBuildTargets: [...native].flatMap(([name, plan]) => [
|
|
5988
6034
|
...(!plan.mixed && plan.sources.length > 0 ? [name] : []),
|
|
5989
6035
|
...(plan.groups?.map((group) => group.name) ?? (plan.late ? [plan.late.name] : [])),
|
|
5990
6036
|
]),
|
|
5991
|
-
headerProducers:
|
|
5992
|
-
...new Set([
|
|
5993
|
-
...Object.keys(nativeHeaderDeclarations),
|
|
5994
|
-
...producers.filter((name) => !included.has(name)),
|
|
5995
|
-
]),
|
|
5996
|
-
],
|
|
6037
|
+
headerProducers: orderedProducers,
|
|
5997
6038
|
emittedHeaderProducers: [
|
|
5998
6039
|
...new Set([...Object.keys(nativeHeaderDeclarations), ...producers]),
|
|
5999
6040
|
],
|
|
6000
6041
|
nativeHeaderDeclarations,
|
|
6001
|
-
headerProductTarget,
|
|
6042
|
+
headerProductTarget: needsHeaderStages ? undefined : headerProductTarget,
|
|
6002
6043
|
targetFailures,
|
|
6003
6044
|
generatedOwners,
|
|
6004
6045
|
targetToolset,
|
|
@@ -6332,14 +6373,9 @@ function linkedFrameworkTargets(
|
|
|
6332
6373
|
))
|
|
6333
6374
|
reach(match[1]!)
|
|
6334
6375
|
}
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
const wanted = [
|
|
6338
|
-
'PeachApp',
|
|
6339
|
-
...(input.oneModule ? ['One'] : []),
|
|
6340
|
-
...(importsSpriteKit(input.files) ? ['SpriteKit'] : []),
|
|
6341
|
-
...reached,
|
|
6342
|
-
]
|
|
6376
|
+
const games = gameProducts(input.files)
|
|
6377
|
+
for (const product of games) for (const name of GAME_REACH[product] ?? []) reach(name)
|
|
6378
|
+
const wanted = ['PeachApp', ...(input.oneModule ? ['One'] : []), ...games, ...reached]
|
|
6343
6379
|
const linked = [...new Set(wanted)].filter((name) => libraries.has(name))
|
|
6344
6380
|
if (!linked.includes('PeachApp'))
|
|
6345
6381
|
throw new Error('swift-compile: the framework package declares no PeachApp library')
|
|
@@ -139,20 +139,22 @@ export function planAssetSymbols(
|
|
|
139
139
|
// xcode 27.1 resolves an unset TARGETED_DEVICE_FAMILY to 1 for an iOS target
|
|
140
140
|
// (xcodebuild -showBuildSettings on an application target that never sets it)
|
|
141
141
|
const families = (settings.TARGETED_DEVICE_FAMILY || '1').split(',').sort().join(',')
|
|
142
|
-
// families 6 and 7 change neither the devices nor symbols for the iOS
|
|
142
|
+
// families 3, 6 and 7 change neither the devices nor symbols for the iOS
|
|
143
|
+
// slice (3: actool output identical for 1,3,7 and 1,7, xcode 27.1)
|
|
143
144
|
const devices: AssetDevice[] | undefined = (
|
|
144
145
|
{
|
|
145
146
|
'1': ['iphone'],
|
|
146
147
|
'2': ['ipad'],
|
|
147
148
|
'1,2': ['iphone', 'ipad'],
|
|
148
149
|
'1,7': ['iphone'],
|
|
150
|
+
'1,3,7': ['iphone'],
|
|
149
151
|
'1,2,6': ['iphone', 'ipad'],
|
|
150
152
|
'1,2,7': ['iphone', 'ipad'],
|
|
151
153
|
} satisfies Record<string, AssetDevice[]>
|
|
152
154
|
)[families]
|
|
153
155
|
if (!devices)
|
|
154
156
|
return unknown(
|
|
155
|
-
`Generated asset symbols are proven only for TARGETED_DEVICE_FAMILY 1, 2, 1,2, 1,7, 1,2,6 or 1,2,7; this target resolves to "${families}".`,
|
|
157
|
+
`Generated asset symbols are proven only for TARGETED_DEVICE_FAMILY 1, 2, 1,2, 1,7, 1,3,7, 1,2,6 or 1,2,7; this target resolves to "${families}".`,
|
|
156
158
|
)
|
|
157
159
|
const plan: SwiftAssetPlan = {
|
|
158
160
|
catalogs: catalogs.map((path) => ({
|
package/src/swift-host.ts
CHANGED
|
@@ -1773,6 +1773,33 @@ export function sourceFiles(root: string): string[] {
|
|
|
1773
1773
|
}
|
|
1774
1774
|
|
|
1775
1775
|
// project files and the xcconfigs their settings read are build inputs, never resources
|
|
1776
|
+
// the app target's resources Xcode copies to the bundle root: a folder
|
|
1777
|
+
// reference keeps its tree and a catalog compiles, so neither is flat
|
|
1778
|
+
function xcodeFlatResources(
|
|
1779
|
+
app: Pick<XcodeModuleTarget, 'resources' | 'resourceNames'> | undefined,
|
|
1780
|
+
): ReadonlySet<string> {
|
|
1781
|
+
if (!app) return new Set()
|
|
1782
|
+
return new Set(
|
|
1783
|
+
app.resources.filter(
|
|
1784
|
+
(file) =>
|
|
1785
|
+
!Object.hasOwn(app.resourceNames, file) &&
|
|
1786
|
+
!file.split(path.sep).some((segment) => segment.endsWith('.xcassets')),
|
|
1787
|
+
),
|
|
1788
|
+
)
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
// an xcode target declares its resources independently of their source
|
|
1792
|
+
// directory; the bundle file and image enumerators use Resources as their root marker.
|
|
1793
|
+
function bundleResourcePath(
|
|
1794
|
+
flatResources: ReadonlySet<string>,
|
|
1795
|
+
disk: string,
|
|
1796
|
+
file: string,
|
|
1797
|
+
): string {
|
|
1798
|
+
return flatResources.has(disk) && !file.split('/').includes('Resources')
|
|
1799
|
+
? `Resources/${file}`
|
|
1800
|
+
: file
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1776
1803
|
function resourceCandidateFiles(root: string): string[] {
|
|
1777
1804
|
return packageFiles(root, false).filter(
|
|
1778
1805
|
(file) =>
|
|
@@ -1941,12 +1968,24 @@ export function buildSwiftResourceTable(
|
|
|
1941
1968
|
const disk = byRelative.get(file)
|
|
1942
1969
|
return !disk || !layout?.targetDirs.get(disk)?.startsWith(`${XCODE_FRAMEWORKS_DIR}/`)
|
|
1943
1970
|
})
|
|
1944
|
-
const
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1971
|
+
const flatResources = xcodeFlatResources(layout?.app)
|
|
1972
|
+
const bundled = new Map(
|
|
1973
|
+
relative.map((file) => [
|
|
1974
|
+
bundleResourcePath(flatResources, byRelative.get(file)!, file),
|
|
1975
|
+
file,
|
|
1976
|
+
]),
|
|
1977
|
+
)
|
|
1978
|
+
const found = enumerateBundleImages(
|
|
1979
|
+
[...bundled.keys()],
|
|
1980
|
+
(file) => readContents(bundled.get(file) ?? file),
|
|
1981
|
+
(marked) => {
|
|
1982
|
+
const file = bundled.get(marked) ?? marked
|
|
1983
|
+
const disk = byRelative.get(file)
|
|
1984
|
+
if (!disk) throw new Error(`image source ${file} has no input file`)
|
|
1985
|
+
const key = layout ? xcodeInputKey(layout, disk, file) : file
|
|
1986
|
+
return swiftResourceBundleForFile(bundles, key)?.path ?? '.'
|
|
1987
|
+
},
|
|
1988
|
+
).map((image) => ({ ...image, file: bundled.get(image.file) ?? image.file }))
|
|
1950
1989
|
const colors = enumerateBundleColors(catalogFiles, readContents)
|
|
1951
1990
|
const symbols = enumerateBundleSymbols(catalogFiles, readContents, (file) => {
|
|
1952
1991
|
const disk = byRelative.get(file)
|
|
@@ -2180,20 +2219,20 @@ export function buildSwiftBundleFiles(
|
|
|
2180
2219
|
}
|
|
2181
2220
|
}
|
|
2182
2221
|
const groups = new Map<string, Map<string, string>>()
|
|
2183
|
-
const
|
|
2222
|
+
const flatResources = xcodeFlatResources(xcode?.app)
|
|
2184
2223
|
for (const file of relative) {
|
|
2185
2224
|
const disk = path.join(packagePath, ...file.split('/'))
|
|
2225
|
+
const folderName = xcode?.app.resourceNames[disk]
|
|
2226
|
+
if (folderName) {
|
|
2227
|
+
watched.push(file)
|
|
2228
|
+
addFile(folderName, readPackageFile(packagePath, disk, limits.resourceBytes))
|
|
2229
|
+
continue
|
|
2230
|
+
}
|
|
2186
2231
|
const key = xcode ? xcodeInputKey(xcode, disk, file) : file
|
|
2187
2232
|
const bundle = swiftResourceBundleForFile(bundles, key)
|
|
2188
2233
|
const bundlePath = bundle?.path ?? '.'
|
|
2189
2234
|
const group = groups.get(bundlePath) ?? new Map<string, string>()
|
|
2190
|
-
|
|
2191
|
-
// directory; the bundle enumerator uses Resources as its root marker.
|
|
2192
|
-
const resource =
|
|
2193
|
-
appResources.has(disk) && !file.split('/').includes('Resources')
|
|
2194
|
-
? `Resources/${file}`
|
|
2195
|
-
: file
|
|
2196
|
-
group.set(resource, disk)
|
|
2235
|
+
group.set(bundleResourcePath(flatResources, disk, file), disk)
|
|
2197
2236
|
groups.set(bundlePath, group)
|
|
2198
2237
|
}
|
|
2199
2238
|
for (const bundle of bundles) {
|
package/src/swift-objc-import.ts
CHANGED
|
@@ -49,6 +49,7 @@ export function swiftObjCModuleMap(
|
|
|
49
49
|
module: string,
|
|
50
50
|
headers: readonly string[],
|
|
51
51
|
submodules: ReadonlySet<string> = new Set(),
|
|
52
|
+
swiftHeader?: string,
|
|
52
53
|
): string {
|
|
53
54
|
const header = (file: string) => `header ${JSON.stringify(file)}`
|
|
54
55
|
const stem = (file: string) =>
|
|
@@ -60,6 +61,9 @@ export function swiftObjCModuleMap(
|
|
|
60
61
|
? ` module ${stem(file)} { ${header(file)} export * }`
|
|
61
62
|
: ` ${header(file)}`,
|
|
62
63
|
),
|
|
64
|
+
...(swiftHeader
|
|
65
|
+
? [' module Swift {', ` ${header(swiftHeader)}`, ' requires objc', ' }']
|
|
66
|
+
: []),
|
|
63
67
|
' export *',
|
|
64
68
|
'}',
|
|
65
69
|
'',
|