File: Plugin.swift

package info (click to toggle)
swiftlang 6.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,856,264 kB
  • sloc: cpp: 9,995,718; ansic: 2,234,019; asm: 1,092,167; python: 313,940; objc: 82,726; f90: 80,126; lisp: 38,373; pascal: 25,580; sh: 20,378; ml: 5,058; perl: 4,751; makefile: 4,725; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (132 lines) | stat: -rw-r--r-- 6,292 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

public import SWBUtil
import SWBCore
import SWBMacro
import Foundation

@PluginExtensionSystemActor public func initializePlugin(_ manager: PluginManager) {
    manager.register(WebAssemblyPlatformSpecsExtension(), type: SpecificationsExtensionPoint.self)
    manager.register(WebAssemblyPlatformExtension(), type: PlatformInfoExtensionPoint.self)
    manager.register(WebAssemblySDKRegistryExtension(), type: SDKRegistryExtensionPoint.self)
}

struct WebAssemblyPlatformSpecsExtension: SpecificationsExtension {
    func specificationFiles(resourceSearchPaths: [Path]) -> Bundle? {
        findResourceBundle(nameWhenInstalledInToolchain: "SwiftBuild_SWBWebAssemblyPlatform", resourceSearchPaths: resourceSearchPaths, defaultBundle: Bundle.module)
    }

    func specificationDomains() -> [String: [String]] {
        ["webassembly": ["generic-unix"]]
    }
}

struct WebAssemblyPlatformExtension: PlatformInfoExtension {
    func additionalPlatforms(context: any PlatformInfoExtensionAdditionalPlatformsContext) throws -> [(path: Path, data: [String: PropertyListItem])] {
        [
            (.root, [
                "Type": .plString("Platform"),
                "Name": .plString("webassembly"),
                "Identifier": .plString("webassembly"),
                "Description": .plString("webassembly"),
                "FamilyName": .plString("WebAssembly"),
                "FamilyIdentifier": .plString("webassembly"),
                "IsDeploymentPlatform": .plString("YES"),
            ])
        ]
    }
}

// TODO: We currently hardcode WebAssembly-specific information here but
// ideally we should be able to generalize this to any Swift SDK. Some of
// issues including https://github.com/swiftlang/swift-build/issues/3 prevent
// us from doing this today but we should revisit this later and consider
// renaming this plugin to something like `SWBSwiftSDKPlatform`.
struct WebAssemblySDKRegistryExtension: SDKRegistryExtension {
    func additionalSDKs(context: any SDKRegistryExtensionAdditionalSDKsContext) async throws -> [(path: Path, platform: SWBCore.Platform?, data: [String: PropertyListItem])] {
        let host = context.hostOperatingSystem
        guard let wasmPlatform = context.platformRegistry.lookup(name: "webassembly") else {
            return []
        }

        let defaultProperties: [String: PropertyListItem] = [
            "SDK_STAT_CACHE_ENABLE": "NO",

            "GENERATE_TEXT_BASED_STUBS": "NO",
            "GENERATE_INTERMEDIATE_TEXT_BASED_STUBS": "NO",

            "CHOWN": "/usr/bin/chown",

            "LIBTOOL": .plString(host.imageFormat.executableName(basename: "llvm-lib")),
            "AR": .plString(host.imageFormat.executableName(basename: "llvm-ar")),
        ]

        // Map triple to parsed triple components
        let supportedTriples: [String: (arch: String, os: String, env: String?)] = [
            "wasm32-unknown-wasi": ("wasm32", "wasi", nil),
            "wasm32-unknown-wasip1": ("wasm32", "wasip1", nil),
            "wasm32-unknown-wasip1-threads": ("wasm32", "wasip1", "threads"),
        ]

        let wasmSwiftSDKs = (try? SwiftSDK.findSDKs(
            targetTriples: Array(supportedTriples.keys),
            fs: context.fs,
            hostOperatingSystem: context.hostOperatingSystem
        )) ?? []

        var wasmSDKs: [(path: Path, platform: SWBCore.Platform?, data: [String: PropertyListItem])] = []

        for wasmSDK in wasmSwiftSDKs {
            for (triple, tripleProperties) in wasmSDK.targetTriples {
                guard let (arch, os, env) = supportedTriples[triple] else {
                    continue
                }

                let wasiSysroot = wasmSDK.path.join(tripleProperties.sdkRootPath)
                let swiftResourceDir = wasmSDK.path.join(tripleProperties.swiftResourcesPath)

                wasmSDKs.append((wasiSysroot, wasmPlatform, [
                    "Type": .plString("SDK"),
                    "Version": .plString("1.0.0"),
                    "CanonicalName": .plString(wasmSDK.identifier),
                    "Aliases": ["webassembly", "wasi"],
                    "IsBaseSDK": .plBool(true),
                    "DefaultProperties": .plDict([
                        "PLATFORM_NAME": .plString("webassembly"),
                    ].merging(defaultProperties, uniquingKeysWith: { _, new in new })),
                    "CustomProperties": .plDict([
                        "LLVM_TARGET_TRIPLE_OS_VERSION": .plString(os),
                        "SWIFT_LIBRARY_PATH": .plString(swiftResourceDir.join("wasi").str),
                        "SWIFT_RESOURCE_DIR": .plString(swiftResourceDir.str),
                        // HACK: Ld step does not use swiftc as linker driver but instead uses clang, so we need to add some Swift specific flags
                        // assuming static linking.
                        // Tracked in https://github.com/swiftlang/swift-build/issues/3
                        "OTHER_LDFLAGS": .plArray(["-lc++", "-lc++abi", "-resource-dir", "$(SWIFT_RESOURCE_DIR)/clang", "@$(SWIFT_LIBRARY_PATH)/static-executable-args.lnk"]),
                    ]),
                    "SupportedTargets": .plDict([
                        "webassembly": .plDict([
                            "Archs": .plArray([.plString(arch)]),
                            "LLVMTargetTripleEnvironment": .plString(env ?? ""),
                            "LLVMTargetTripleSys": .plString(os),
                            "LLVMTargetTripleVendor": .plString("unknown"),
                        ])
                    ]),
                    // TODO: Leave compatible toolchain information in Swift SDKs
                    // "Toolchains": .plArray([])
                ]))
            }
        }

        return wasmSDKs
    }
}