-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[WIP] Expose a SwiftPM BSP interface based on Swift Build #9129
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
This is very much a WIP right now, it just exposes the bare minimum functionality so we can discuss API design |
func run(_ swiftCommandState: SwiftCommandState) async throws { | ||
// Dup stdout and redirect the fd to stderr so that a careless print() | ||
// will not break our connection stream. | ||
let realStdout = dup(STDOUT_FILENO) |
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.
We depend on Swift System, right? I suggest using FileDescriptor.duplicate cover API and not going straight down to POSIX.
IIRC there's also some oddities with the Windows versions of dup which System should be able to help smooth over.
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.
FWIW, we’re doing this in SourceKit-LSP and it hasn’t caused any issues so far.
indexRegularBuildProductsPath: ddPathPrefix + "/Index/Products", | ||
indexRegularBuildIntermediatesPath: ddPathPrefix + "/Index/Intermediates.noindex", |
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 name is a little confusing here, but FWIW this is actually meant to be swapped for the index arena 😅 - the build products/intermediate paths would be the index arena and the "index regular" paths the regular build. It's also only used for adding an overlay to fallback to the build, which we don't necessarily need.
|
||
guard let buildSystem = try await swiftCommandState.createBuildSystem() as? SwiftBuildSystem else { | ||
print("Build server requires --build-system swiftbuild") | ||
Self.exit() |
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 should exit with whatever error SwiftArgumentParser exits with when validate() fails
} | ||
) | ||
|
||
// Park the main function by sleeping for 10 years. |
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.
Cleaner solution?
await withCheckedContinuation { continuation in
clientConnection.start(
receiveHandler: server,
closeHandler: {
continuation.resume()
}
)
}
36c58fd
to
fda8c7b
Compare
func run(_ swiftCommandState: SwiftCommandState) async throws { | ||
// Dup stdout and redirect the fd to stderr so that a careless print() | ||
// will not break our connection stream. | ||
let realStdout = dup(STDOUT_FILENO) |
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.
FWIW, we’re doing this in SourceKit-LSP and it hasn’t caused any issues so far.
case let request as RequestAndReply<BuildTargetPrepareRequest>: | ||
await request.reply { | ||
for target in request.params.targets.filter({ $0.isSwiftPMBuildServerTargetID }) { | ||
// Error |
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 isn’t an error. SourceKit-LSP will eg. ask for the package manifest target to be prepared, it’s just that there’s nothing to do, so the BSP server can return immediately.
await request.reply { | ||
await waitForBuildSystemUpdates(request: request.params) |
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.
Do you also need to wait for updates of the underlying build server?
// TODO: this is overly conservative | ||
return true | ||
case .changed: | ||
// TODO: check for changes to version specific manifests 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.
FWIW, I added support for version-specific package manifests in SourceKit-LSP’s built-in SwiftPM build server in swiftlang/sourcekit-lsp#2259.
Add a
swift package bsp
command which builds on the Swift Build BSP interface to provide preparation + compiler args for packages as an out of process build server.