mirror of
https://github.com/xtool-org/xtool.git
synced 2026-10-04 16:56:44 +02:00
## 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 -->
51 lines
1.5 KiB
Swift
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
|
|
}
|
|
}
|
|
}
|