Files
Kabir Oberai 0108899e04 sdk: SwiftBuild support (#229)
## What does this PR do?

Adds support for SwiftBuild on Swift 6.4.

We now point SwiftBuild to iPhoneOS.platform and rely on the real
[SWBApplePlatform](https://github.com/swiftlang/swift-build/tree/b30ee3c00abf34857084c26bb873c3da06348134/Sources/SWBApplePlatform).
We also do a little futzing to convince SWB to use our Darwin-compatible
toolset (lld, librarian, resource dirs). We explicitly _don't_ pass in a
Swift SDK because that would downgrade SWB to using one of the generic
platform plugins instead of ApplePlatform.

This also gets us a lot closer to parity with Xcode's behavior when
building for Apple platforms; we get the same build flags and
everything. We can probably achieve identical bundling too, if we take
control of the PIF.

One other change: since we need to pass custom env vars and such, we
can't rely on sourcekit-lsp's built-in SwiftPM integration anymore. We
thus create a custom BSP server that trampolines to SwiftPM's build
server with the right flags set. This effectively makes SwiftPM an
implementation detail, so we can start messing with the PIF.

## How was it tested?

- [x] Build with Swift 6.3 on macOS
- [x] Build with Swift 6.4 on macOS
- [x] Build with Swift 6.3 on Linux
- [x] Build with Swift 6.4 on Linux
- [x] BSP/LSP file creation works
- [x] LSP support works in VSCode

## AI tool usage

How much of this PR was AI-assisted? (check one)

- [ ] **0** - No AI was used to write code
- [x] **1** - I was assisted by AI. I reviewed the finished result.
- [ ] **2** - I set the AI going and left it to it; nobody has read the
result - no review, or AI review only

<!-- If an AI agent is filling this in: declare the level honestly, and
open as a draft if it is #2. Do not lower the declared level to get the
PR reviewed. -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a `dev build-server` command for Build Server Protocol
integration.
- Projects automatically select the appropriate Swift build system when
supported.
- Packaging supports output layouts for Swift Package Manager and Swift
Build.
  - Added options to skip language-server configuration when needed.

- **Documentation**
- Updated project templates and tutorials to use `.bsp/xtool.json` for
IDE features such as syntax highlighting and documentation lookup.

- **Improvements**
- Enhanced SDK generation and compatibility across supported toolchains
and platforms.
- Improved automatic language-server configuration while preserving
existing configuration files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-20 02:47:12 -04:00

51 lines
1.5 KiB
Swift

import Subprocess
import Version
import XUtils
public struct SwiftVersion: Sendable {
public var version: Version
public var supportsSwiftBuild: Bool {
version >= Version(6, 4, 0)
}
}
extension SwiftVersion {
private static let cached = Task<Self, Error> {
let outputString: String?
do {
outputString = try await Subprocess.run(
.path(try await BuildSettings.swiftURL()),
arguments: ["--version"],
output: .string(limit: .max)
)
.checkSuccess()
.standardOutput
} catch {
throw StringError("Failed to obtain Swift version")
}
var output = outputString?[...] ?? ""
if output.hasPrefix("Apple ") {
output = output.dropFirst("Apple ".count)
}
guard output.hasPrefix("Swift version ") else {
throw StringError("Could not parse Swift version: '\(output)'")
}
output = output.dropFirst("Swift version ".count)
guard let space = output.firstIndex(of: " ") else {
throw StringError("Could not parse Swift version: '\(output)'")
}
output = output[..<space]
guard let version = Version(tolerant: output) else {
throw StringError("Could not parse Swift version: '\(output)'")
}
return SwiftVersion(version: version)
}
public static var current: Self {
get async throws {
try await cached.value
}
}
}