-
Notifications
You must be signed in to change notification settings - Fork 134
Swift SDK for WASM using the run destination #966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The client can provide a Swift SDK manifest path along with a triple in the run destination to synthesize a Swift Build SDK. This serves as a fallback for cases where Swift Build cannot match an SDK for it. Note that in this first implementation the platform is hard coded to webassembly, and so only SDK's that align with WASM, such as static linking of compiler runtime pieces, and some Unix semantics will work.
…c instead of the base ld xcspec
|
@swift-ci please test |
Sources/SWBCore/SDKRegistry.swift
Outdated
| "SWIFT_RESOURCE_DIR": .plString(swiftResourceDir.str), // Resource dir for compiling Swift | ||
| "CLANG_RESOURCE_DIR": .plString(clangResourceDir.str), // Resource dir for linking C/C++/Obj-C | ||
| "SDKROOT": .plString(sysroot.str), | ||
| "OTHER_LDFLAGS": .plArray(["$(OTHER_SWIFT_FLAGS)"]), // The extra swift compiler settings in JSON are intended to go to the linker driver too |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we need to include swift flags here, we should use extraSwiftCompilerSettings instead of $(OTHER_SWIFT_FLAGS), because $(OTHER_SWIFT_FLAGS) may include other project/command line flags which are only intended for the compiler
Add the missing sdk parameter to swiftc linker driver in UnixLD.xcpsec
…izes in producing one from run destination information
|
@swift-ci please test |
|
@swift-ci please test |
jakepetroules
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! :)
Left another round of feedback.
|
|
||
| /// Refer to `SWBProtocol.RunDestinationInfo` | ||
| public struct SWBRunDestinationInfo: Codable, Sendable { | ||
| public enum SWBBuildTarget: Codable, Sendable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The general idea here makes sense. However, so far we've generally avoided using enums in the public API, in part because it's a nightmare to evolve, for things which might gain new parameters over time.
Instead, I would follow the pattern I established with SWBBuildCommand, where instead of an enum, you make SWBBuildTarget a struct, and make the enum cases into static functions. This allows you to provide additional overloads in order to extend the API with more arguments over time in a more compatible fashsion.
Then inside SWBBuildCommand you have a private enum which models the actual data, but is not exposed through the API. That one can then change however it likes without impacting ABI.
Let's also mark the loose properties as deprecated, so that we can start to transition clients to use the new ones. Instead of making the SWBBuildTarget operate in terms of the loose properties, make the loose properties operate in terms of the SWBBuildTarget. That will prevent you from having unsilenceable warnings from a non-deprecated API relying on deprecated API.
| self.platform = "" | ||
| self.sdk = "" | ||
| self.sdkVariant = nil | ||
| self.targetArchitecture = "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think targetArchitecture and supportedArchitectures should stay on the SWBRunDestinationInfo level, since they aren't logically part of platform establishment.
(This would also make more sense for future enhancements, like supporting multiple target triples in a single build request - I'd like to do that for Apple platforms, and it would make sense for Android and probably Windows, too.)
| { | ||
| Name = CLANG_SDKROOT_LINKER_INPUT; | ||
| Type = Path; | ||
| DefaultValue = "$(SDKROOT)"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this one needs to be $(SYSROOT:default=$(SDKROOT))
| { | ||
| Name = SWIFTC_SDKROOT_LINKER_INPUT; | ||
| Type = Path; | ||
| DefaultValue = "$(SYSROOT:default=$(SDKROOT))"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem right -- based on discussions around how the various platform-targeting flags would work, the consensus was:
- When targeting platforms where Swift SDK and sysroot are the same (Apple platforms), use
-sdkonly - When targeting Windows, use
-sdkonly since the sysroot concept doesn't exist - For all others, use both
-sdkand-sysroot
Wasm falls into bullet 3, so I think the sdk flag needs to be based on $(SDKROOT), while the $(SYSROOT) var would be used to pass -sysroot. That means you should be able to remove this override and use the one from the base Ld.xcspec.
| } | ||
| } | ||
|
|
||
| public struct RunDestinationInfo: SerializableCodable, Hashable, Sendable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not part of public API and there is no need to maintain backwards compatibility, so this should eliminate the dedicated properties and go straight to having a BuildTarget enum with the two cases (swiftSDK for swiftSdkPath + triple, and appleSDK for platform + sdk + sdkVariant).
| "GENERATE_INTERMEDIATE_TEXT_BASED_STUBS": "NO", | ||
|
|
||
| // TODO check how this impacts operation on Windows | ||
| "CHOWN": "/usr/bin/chown", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No such concept of CHOWN, so shouldn't matter. addSpecificChangePermissionTasks bails out early for Windows targets.
| switch runDestination.buildTarget { | ||
| case .swiftSDK: | ||
| // TODO use the triple to decide the platform, or use a fallback | ||
| guard let platform: Platform = self.core.platformRegistry.lookup(name: "webassembly") else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's fix this hardcoded webassembly reference before landing the initial change. Paraphrasing what I mentioned in another comment, a good way to do this would be to additional method on PlatformInfoExtension like func platformName(triple: LLVMTriple) -> String?.
Then, in each of the implementations:
- AndroidPlatformExtension: return "android" if triple.os == "linux" and triple.environment has prefix "android"
- GenericUnixPlatformInfoExtension: return triple.os if (triple.os is "linux" and (triple.environment has prefix "gnu" or == "musl")), "freebsd", or "openbsd"
- QNXPlatformExtension: return "qnx" if triple.os == "nto"
- WebAssemblyPlatformExtension: return "webassembly" if triple.os has prefix "wasi"
- WindowsPlatformExtension: return "windows" if triple.os == "windows
Here in Settings.swift, you enumerate the extension point conformances, add them to a Set, and if you have exactly one match, use it, else emit an error.
If you get no matches at all, fall back to the "none" platform.
--
Also make sure to factor this logic into a dedicated function; I see the hardcoded webassembly lookup is currently in 3 different places.
The client can provide a Swift SDK manifest path along with a triple in the run destination to synthesize a Swift Build SDK. This serves as a fallback for cases where Swift Build cannot match an SDK for it.
Note that in this first implementation the platform is hard coded to webassembly, and so only SDK's that align with WASM, such as static linking of compiler runtime pieces, and some Unix semantics will work.