|
| 1 | +//===----------------------------------------------------------------------===// |
| 2 | +// |
| 3 | +// This source file is part of the Swift open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2025 Apple Inc. and the Swift project authors |
| 6 | +// Licensed under Apache License v2.0 with Runtime Library Exception |
| 7 | +// |
| 8 | +// See http://swift.org/LICENSE.txt for license information |
| 9 | +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| 10 | +// |
| 11 | +//===----------------------------------------------------------------------===// |
| 12 | + |
| 13 | +public import SWBUtil |
| 14 | +import SWBCore |
| 15 | +import SWBMacro |
| 16 | +import Foundation |
| 17 | + |
| 18 | +@PluginExtensionSystemActor public func initializePlugin(_ manager: PluginManager) { |
| 19 | + manager.register(WebAssemblyPlatformSpecsExtension(), type: SpecificationsExtensionPoint.self) |
| 20 | + manager.register(WebAssemblyPlatformExtension(), type: PlatformInfoExtensionPoint.self) |
| 21 | + manager.register(WebAssemblySDKRegistryExtension(), type: SDKRegistryExtensionPoint.self) |
| 22 | +} |
| 23 | + |
| 24 | +struct WebAssemblyPlatformSpecsExtension: SpecificationsExtension { |
| 25 | + func specificationFiles() -> Bundle? { |
| 26 | + .module |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +struct WebAssemblyPlatformExtension: PlatformInfoExtension { |
| 31 | + func additionalPlatforms() -> [(path: Path, data: [String: PropertyListItem])] { |
| 32 | + [ |
| 33 | + (.root, [ |
| 34 | + "Type": .plString("Platform"), |
| 35 | + "Name": .plString("webassembly"), |
| 36 | + "Identifier": .plString("webassembly"), |
| 37 | + "Description": .plString("webassembly"), |
| 38 | + "FamilyName": .plString("WebAssembly"), |
| 39 | + "FamilyIdentifier": .plString("webassembly"), |
| 40 | + "IsDeploymentPlatform": .plString("YES"), |
| 41 | + ]) |
| 42 | + ] |
| 43 | + } |
| 44 | +} |
| 45 | + |
| 46 | +// TODO: We currently hardcode WebAssembly-specific information here but |
| 47 | +// ideally we should be able to generalize this to any Swift SDK. Some of |
| 48 | +// issues including https://github.com/swiftlang/swift-build/issues/3 prevent |
| 49 | +// us from doing this today but we should revisit this later and consider |
| 50 | +// renaming this plugin to something like `SWBSwiftSDKPlatform`. |
| 51 | +struct WebAssemblySDKRegistryExtension: SDKRegistryExtension { |
| 52 | + func additionalSDKs(platformRegistry: PlatformRegistry) async -> [(path: Path, platform: SWBCore.Platform?, data: [String: PropertyListItem])] { |
| 53 | + guard let host = try? ProcessInfo.processInfo.hostOperatingSystem() else { |
| 54 | + return [] |
| 55 | + } |
| 56 | + |
| 57 | + guard let wasmPlatform = platformRegistry.lookup(name: "webassembly") else { |
| 58 | + return [] |
| 59 | + } |
| 60 | + |
| 61 | + let defaultProperties: [String: PropertyListItem] = [ |
| 62 | + "SDK_STAT_CACHE_ENABLE": "NO", |
| 63 | + |
| 64 | + // Workaround to avoid `-add_ast_path` on WebAssembly, apparently this needs to perform some "swift modulewrap" step instead. |
| 65 | + "GCC_GENERATE_DEBUGGING_SYMBOLS": .plString("NO"), |
| 66 | + |
| 67 | + "GENERATE_TEXT_BASED_STUBS": "NO", |
| 68 | + "GENERATE_INTERMEDIATE_TEXT_BASED_STUBS": "NO", |
| 69 | + |
| 70 | + "CHOWN": "/usr/bin/chown", |
| 71 | + |
| 72 | + "LIBTOOL": .plString(host.imageFormat.executableName(basename: "llvm-lib")), |
| 73 | + "AR": .plString(host.imageFormat.executableName(basename: "llvm-ar")), |
| 74 | + ] |
| 75 | + |
| 76 | + // Map triple to parsed triple components |
| 77 | + let supportedTriples: [String: (arch: String, os: String, env: String?)] = [ |
| 78 | + "wasm32-unknown-wasi": ("wasm32", "wasi", nil), |
| 79 | + "wasm32-unknown-wasip1": ("wasm32", "wasip1", nil), |
| 80 | + "wasm32-unknown-wasip1-threads": ("wasm32", "wasip1", "threads"), |
| 81 | + ] |
| 82 | + |
| 83 | + let wasmSwiftSDKs = (try? SwiftSDK.findSDKs( |
| 84 | + targetTriples: Array(supportedTriples.keys), |
| 85 | + fs: localFS |
| 86 | + )) ?? [] |
| 87 | + |
| 88 | + var wasmSDKs: [(path: Path, platform: SWBCore.Platform?, data: [String: PropertyListItem])] = [] |
| 89 | + |
| 90 | + for wasmSDK in wasmSwiftSDKs { |
| 91 | + for (triple, tripleProperties) in wasmSDK.targetTriples { |
| 92 | + guard let (arch, os, env) = supportedTriples[triple] else { |
| 93 | + continue |
| 94 | + } |
| 95 | + |
| 96 | + let wasiSysroot = wasmSDK.path.join(tripleProperties.sdkRootPath) |
| 97 | + let swiftResourceDir = wasmSDK.path.join(tripleProperties.swiftResourcesPath) |
| 98 | + |
| 99 | + wasmSDKs.append((wasiSysroot, wasmPlatform, [ |
| 100 | + "Type": .plString("SDK"), |
| 101 | + "Version": .plString("1.0.0"), |
| 102 | + "CanonicalName": .plString(wasmSDK.identifier), |
| 103 | + "IsBaseSDK": .plBool(true), |
| 104 | + "DefaultProperties": .plDict([ |
| 105 | + "PLATFORM_NAME": .plString("webassembly"), |
| 106 | + ].merging(defaultProperties, uniquingKeysWith: { _, new in new })), |
| 107 | + "CustomProperties": .plDict([ |
| 108 | + "LLVM_TARGET_TRIPLE_OS_VERSION": .plString(os), |
| 109 | + "SWIFT_LIBRARY_PATH": .plString(swiftResourceDir.join("wasi").str), |
| 110 | + "SWIFT_RESOURCE_DIR": .plString(swiftResourceDir.str), |
| 111 | + // HACK: Ld step does not use swiftc as linker driver but instead uses clang, so we need to add some Swift specific flags |
| 112 | + // assuming static linking. |
| 113 | + // Tracked in https://github.com/swiftlang/swift-build/issues/3 |
| 114 | + "OTHER_LDFLAGS": .plArray(["-lc++", "-lc++abi", "-resource-dir", "$(SWIFT_RESOURCE_DIR)/clang", "@$(SWIFT_LIBRARY_PATH)/static-executable-args.lnk"]), |
| 115 | + ]), |
| 116 | + "SupportedTargets": .plDict([ |
| 117 | + "webassembly": .plDict([ |
| 118 | + "Archs": .plArray([.plString(arch)]), |
| 119 | + "LLVMTargetTripleEnvironment": .plString(env ?? ""), |
| 120 | + "LLVMTargetTripleSys": .plString(os), |
| 121 | + "LLVMTargetTripleVendor": .plString("unknown"), |
| 122 | + ]) |
| 123 | + ]), |
| 124 | + // TODO: Leave compatible toolchain information in Swift SDKs |
| 125 | + // "Toolchains": .plArray([]) |
| 126 | + ])) |
| 127 | + } |
| 128 | + } |
| 129 | + |
| 130 | + return wasmSDKs |
| 131 | + } |
| 132 | +} |
0 commit comments