Do SwiftPM conditional target dependencies work?

According to SE-0278 it should be possible to conditionally include a dependency into a target so that under certain circumstances the dependency does not compile or link. The example given in the proposal is that of depending on two Bluetooth libraries, one that works for macOS and the other that works for Linux.

That seems great, but in practice I am finding that the dependency compiles and links regardless of the condition. I have a sample SPM package to demonstrate this.

In a nutshell, I have a very simple package with a single executable target that conditionally depends on some Wasm-related dependencies:

let package = Package(
  name: "WhenCondition",
  platforms: [.macOS(.v11)],
  dependencies: [
    .package(url: "https://github.com/swiftwasm/JavaScriptKit", exact: "0.19.2"),
    .package(url: "https://github.com/swiftwasm/carton", from: "1.0.0"),
  ],
  targets: [
    .executableTarget(
      name: "WhenCondition",
      dependencies: [
        .product(
          name: "JavaScriptKit",
          package: "JavaScriptKit",
          condition: .when(platforms: [.wasi])
        )
      ]
    ),
  ]
)

My understanding of SE-0278 tells me that the JavaScriptKit library should not be compiled or linked when building for macOS.

To test this I put the following in my main.swift:

#if canImport(JavaScriptKit)
  import JavaScriptKit
  print("Hello from WASI!")
#else
  print("Hello!")
#endif

…and when running the executable (in Xcode) I see "Hello from WASI!" printed to the console, and in the build logs I can see that JavaScriptKit was indeed compiled and linked.

Is this to be expected? Or is there anything I'm missing?

Thanks!

3 Likes

Seems like a bug, probably best to file a GitHub issue. cc @dschaefer2

Actually looks like an issue with Xcode. That example works with swiftpm command line tools.

1 Like

Yeah, after posting this I realized that it is only in Xcode that this behavior occurs. Running the executable from the command line and from run carton dev produces the output I would expect.

This does seem to make cross-platform Swift less attractive. It means that if one shares library code between Apple platforms and another platform, then when compiling for Apple platforms the binary will be bloated with unnecessary code.

1 Like

To be fair, this is fixable.

Thanks for confirmation, and I just filed this feedback FB14859516 with the project attached.

3 Likes

Thanks Brandon!

1 Like