Adding platform-specific dependency to multi-platform Swift Package

Hello,

I am struggling with setting up a Swift Package that supports multiple platforms (iOS and tvOS in my case) and also depends on a platform-specific library (iOS in my case).

Despite adding a condition property to the platform-specific dependency, I can only build my library for the platform supported by the dependency.

My Package.swift looks like this:

// swift-tools-version:5.4
import PackageDescription

let package = Package(
  name: "Demo",
  platforms: [
    .iOS(.v14),
    .tvOS(.v14),
  ],
  products: [
    .library(
      name: "Demo",
      targets: ["Demo"]
    ),
  ],
  dependencies: [
    .package(
      name: "Firebase",
      url: "https://github.com/firebase/firebase-ios-sdk.git",
      .exact("8.1.1")
    ),
  ],
  targets: [
    .target(
      name: "Demo",
      dependencies: [
        .product(
          name: "FirebaseAnalytics",
          package: "Firebase",
          condition: .when(platforms: [.iOS])
        ),
      ]
    ),
    .testTarget(
      name: "DemoTests",
      dependencies: [
        .target(name: "Demo")
      ]
    ),
  ]
)

Note that FirebaseAnalytics only supports iOS platform, but not tvOS.

My "Demo" library builds fine for iOS, but when trying to build it for tvOS, I am getting the following error:

[...]/FirebaseAnalytics.xcframework:1:1: While building for tvOS Simulator, no library for this platform was found in '[...]/FirebaseAnalytics.xcframework'.

Not sure if such configuration is not supported, or I am doing something wrong here.

I've created an example project that demonstrates the issue:

I am using Apple Swift version 5.4 (swiftlang-1205.0.26.9 clang-1205.0.19.55) that comes with Xcode 12.5 (12E262).

All feedback and suggestions will be appreciated!

1 Like

A typical approach is to conditionalize your dependencies array so that it's empty on tvOS.

#if os(tvOS)
let dependencies: [Dependency] = []
#else
let dependencies: [Dependency] = ...
#endif

I'm not sure that's the right type for the array but you get the idea.

That’s interesting. Thanks! I will definitely try it out, although I am not sure if this will work inside Package.swift file.

Oops, yeah, I keep forgetting it's conditioned on the running OS, not the targeted one. So this would work for Linux vs. Windows vs. macOS, but not for tvOS vs. iOS. What you're doing is supposed to work I think.

1 Like

Unfortunately, using #if os(...) / #endif won't help in this case as the platform is defined by the machine I am working on (macOS) and not the target platform I would like to build for (iOS/tvOS).

I have pushed updated demo project to a separate branch. It's closer to what I am working on. My app's source code is modularized using libraries defined in Swift Package, similarly to what PointFree does in their ISOWORDS game.

Your manifest looks correct to me. (#if os(...) is an old workaround with bad side effects and should not be used in manifests anymore.)

I use it all the time, so I can also confirm that in most situations it works properly (including with 5.4 and 12.5).

Whatever is going wrong here must only be triggered by narrower set of conditions. For example, I have never attempted to conditionally use a binary dependency. Maybe there is a bug in the way the two features overlap? Anyway, it would be helpful to have a minimal demonstration where the dependency is less complicated than Firebase.

Regardless, it is supposed to work, so you can file a bug at bugs.swift.org if you can reproduce it in a native command line build (swift build), or with the Feedback Assistant if only Xcode has trouble.

This definitely looks like a bug to me. Your use case is exactly what conditional dependencies are for.

Encountered the same issue while trying to list binary target conditionally as a dependency.

Was a bug ever filed for this issue? I just ran in to it myself.

Terms of Service

Privacy Policy

Cookie Policy