Skip to content

Conversation

@hassila
Copy link

@hassila hassila commented Jan 10, 2024

Provide experimental support for XCFrameworks for Linux for well-defined, identical, deployments.

Motivation:

Providing informal, experimental support for (very) heterogenous cluster deployments on Linux as discussed previously in #5714

It allows for deployments which use XCFrameworks and library evolution on identically patches / toolchains on Linux as an interim escape hatch until wider support might be available.

Modifications:

Enable XCFrameworks for Linux if the _SWIFTPM_EXPERIMENTAL_LINUX_XCFRAMEWORK environment variable is set.

Result:

Users may experiment with library evolution and XCFrameworks on Linux without having to roll their own toolchains while waiting for wider support for shared libraries / evolution on Linux in general.

The default behavior remains unchanged and there should be zero impact for users who doesn't set this environment variable.

@MaxDesiatov
Copy link
Contributor

MaxDesiatov commented Jan 10, 2024

To manage expectations on this, I personally don't think XCFrameworks should be ever supported anywhere outside of builds on macOS with the Xcode build system. It's an Xcode-specific format that's not meant to be cross-platform outside of Xcode use cases isolated to Darwin. The proper format for true cross-platform binary libraries is .artifactbundle, which was designed in the open specifically for that purpose.

Thus if you'd like to push forward with the overall concept of cross-platform binary libraries, I advise switching to .artifactbundle and improving upon #6967 with questions addressed that we've identified in #7035 (comment).

@hassila
Copy link
Author

hassila commented Jan 10, 2024

Thanks @MaxDesiatov, we'll have a look at that, appreciate the pointers.

@hassila
Copy link
Author

hassila commented Oct 2, 2025

@dschaefer2 ping from Swift in server

Copy link
Contributor

@ktoso ktoso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the chat @hassila @dschaefer2 ! Hope we can get this in :-)

Copy link
Contributor

@jakepetroules jakepetroules left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, if this is behind an unsupported environment variable I suppose I'm somewhat OK with it.

Note that this would also need changes in Swift Build.

@owenv, any thoughts here from you?

return "tvos"
case .watchos:
return "watchos"
case .linux:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would need to return nil for Android triples. We should move the extension from Triple.OS to Triple and check both the os and environment fields; ensuring the environment field is gnu or musl, or at least not android/androideabi.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jakepetroules ,

Moved and added an android check

@dschaefer2
Copy link
Member

As we discussed in London, I think this is an important short term stop gap until we can the SwiftPM Vision doc together and cover all the use cases we see for binary artifacts. We learned a lot from prebuilts to support many platforms and compiler versions that I want to formalize and bring forward.

case .watchos:
return "watchos"
case .linux:
return ProcessInfo.processInfo.environment["_SWIFTPM_EXPERIMENTAL_LINUX_XCFRAMEWORK"] == "1" ? "linux" : nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer this being an experimental flag that we can make hidden if necessary. This is how we did the prebuilts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just actively trying to make sure SwiftPM doesn't necessitate the need for Environment changes. It's just too many degrees of separation between where they're set and where they're used.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dschaefer2 ,

Do you mean to define a hidden boolean flag under GlobalOptions.BuildOptions in Options.swift and then to pass this to BuildParameters via SwiftCommandState and making use of this in:

  1. BuildPlan+Swift.swift
  2. BuildPlan+Product.swift
  3. BuildPlan+Clang.swift

Or is there more locations where changes are required?

Copy link
Member

@dschaefer2 dschaefer2 Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the environment variable is pretty deep in the call tree here. That whole getter has a pretty heavy side effect relying on the name being nil to disallow a platform. Not a choice I would have made :). But let's not change too much.

We should really check at the BuildPlan level wherever we're calling parseXCFramework and only do linux if the flag is enabled.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, any preference on what the flag should be named ?

/// Hidden option to allow XCFrameworks on Linux @Flag( name: .customLong("experimental-xcframeworks-on-linux"), help: .hidden ) public var enableXCFrameworksOnLinux: Bool = false 
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dschaefer2,

I have removed the env variable and added swift-build --experimental-xcframeworks-on-linux, which compiles our product successfully.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent. Thanks! I'm wondering if there's a test we can add to make sure it stays working as we make changes in there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean something like testXCFrameworkBinaryTargets(), to create a new test function for Linux ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dschaefer2 ,

I have added a test on BuildPlan for the optional flag validation and also a functional test which compiles a library with Library Evolution; packages this into XCF; builds and runs a test binary on Linux.

@hassila
Copy link
Author

hassila commented Oct 24, 2025

Thanks for the feedback and thanking @vsarunas for addressing it - @dschaefer2 anything more you'd need from us to move this further?

@dschaefer2
Copy link
Member

@swift-ci please test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

7 participants