Support binary dependencies on Linux (and Windows?)

Hi everybody,

in order to get implement DocumentFormattingRequest by Trzyipolkostkicukru · Pull Request #361 · apple/sourcekit-lsp · GitHub merged, @blangmuir mentioned in the discussion of the PR that support for binary dependencies on Linux is needed.

What is needed to get this implemented in SwiftPM? Do we need a pitch and a Swift Evolution Proposal? Or can this be implemented straight away?

I'd really like to see some progress on that DocumentFormattingRequest PR. So let's do what needs to be done to get that thing rolling.

Kind regards,

Lars

1 Like

Hi @IOOI, thanks for bringing this up.

SE-0305 defines the foundation for binary dependencies distribution and how tools (executables) are distributed. The proposal stops short from defining how binary libraries may be distributed, and leaves that for future proposals. Libraries have additional complexity given their nature and may require additional metadata defined to drive that logic.

Would love to see a proposal on how to take this forward!

1 Like

I am afraid bringing this up was all I can do. A future proposal for this is way above my skill level in this regard. I hope others (@compnerd maybe?) can take over on this task.

Kind regards,

Lars

Couldn't you just do something like this in the Package.swift file?

#if swift(>=5.7)
#elif swift(>=5.6)
.package(url: "https://github.com/apple/swift-format.git", .branch("swift-5.6-branch")),
#elif swift(>=5.5)
.package(url: "https://github.com/apple/swift-format.git", .branch("swift-5.5-branch")),
...
#endif

Then also limit this feature based on swift version?

The dependency is tighter than just the branch; you would need a different case in that if chain for every patch release of the compiler you want to support building with, and if you wanted to use a nightly build of the compiler, you would need a corresponding swift-format and swift-syntax tag for that toolchain, and possibly #if in the code itself any time there is an API break. Quoting myself

Swift-syntax has an unstable dependency on lib_InternalSwiftSyntaxParser from the toolchain. Currently, you must use an identical tag of swift-syntax and the parser library. At the same time, the Swift API of swift-syntax is not API-stable. This means that if we use main branch of swift-format/swift-syntax, we cannot use it without building the whole toolchain from source. Alternatively, if we used the latest released tag version we would always be a full release behind any syntax changes to the language, and we would open ourselves up to incompatibility between what happens in a development build, and what happens when building the toolchain for swift.org.

The reason a binary dependency helps here is that during development we can use a parser library that is not part of the user's toolchain, decoupling the compiler you use to build sourcekit-lsp and the swift-syntax that you are using. At the same time, we could keep the dependency on swift-syntax/swift-format as up-to-date as possible, which avoids compatibility issues between what is being developed and what will end up in the toolchain in swift ci.

Originally when I looked into binary dependencies I wanted to support Linux (windows wasn’t a valid target platform at the time). There are a lot of challenges. This is why when discussing SE-272 (which I only ended up helping with a tiny bit) we quickly dropped it from the first version of binary dependencies even when I suggested it.

The main challenges I remember are these:

  1. Lack of ABI on non apple platforms.

  2. On Linux different distros use different formats for bundling them. Should it have a standardized SwiftPM format for them or should it somehow embrace the platform packaging? The main reason we might want to embrace a more standard approach is if we want to support install commands (which was also something I strongly wanted at the time).

  3. How would it handle different architectures? xcframeworks handle this with their structure of essentially nesting more traditional frameworks in a directory hierarchy. How would these binaries handle intel, arm, 32 bit, 64 bit etc.

Overall it is something I am still interested in just less so, my job at the time would have been able to take huge advantage of binary dependencies on Linux.

The other challenge here is linkage. Specifically, "Linux" is a kernel, not a platform. Working out what the platform actually is, and what you can rely on being present, is not straightforward at all.

4 Likes

Ya… totally forgot that one. Even the same distro can be vastly different depending on which flags you compile it with.