SwiftPM Platform conditional target dependancy not resolved for tvOS

Hi,

I have some target that conditionally links other tvOS-specific and iOS-specific targets.
When building for iOS all goes well, but when I try to build for tvOS - build fails due to not available APIs for tvOS in iOS-specific-target being built...

     .target(
            name: "SomeTarget",
            dependencies: [
                "Common-Target",

                .target(name: "iOS-specific-target", condition: .when(platforms: [.iOS])),                
                .target(name: "TV-Specific-target", condition: .when(platforms: [.tvOS]))
            ],
        )

What am I doing wrong?

Found some bugs:

And that post:

With StackOverflow too:

So is it a binary dependency in your case? Or do we need to keep debugging?

Yo, I'm the guy from the mentioned StackOverflow thread.
Not a binary dependency in my case.
Here's a sample project that demonstrates the issue: GitHub - Moriquendi/bug-conditional-dependency
Run a SwiftUI preview on a macOS target - it won't work.
(Radar: FB9940620)

The Xcode project has no tvOS scheme, but I just built Packages/Components for tvOS without any issues (with Xcode 13.3.1):

My sample project demonstrates the issue for macOS + iOS, but I'm sure it's the same issue that Andrey has with tvOS.

To clarify - the app / package does build ok for me too. The build only fails when you try to run SwiftUI Previews.

Steps to reproduce:

  1. Select "PreviewTests" scheme, target macOS
  2. Open ContentView
  3. Try running SwiftUI Preview.

I'm attaching a screenshot that shows the issue. You can see it fails because it cannot find UIKit when building iOS-only dependency.

If the build is fine and only Xcode previews fails, then you are not doing anything wrong and the fault is with Xcode. Xcode is closed source, so there is nothing I can do to help. https://feedbackassistant.apple.com

1 Like

In my case I'm running a pure Xcode build for tvOS target and getting compilation error due to non-compatible API usage occur in iOS target.

I maid an example and strange, but got error only once (may be not...), but I found that my production app has a slightly different structure: error occurs when I add second level iOS-only dependency to the the one added conditionally. Reproduces stable.

Here is my example project:

As I said: the issue is only applicable for tvOS build (the very same structure for iOS build run without any error).

And as I see, if declare second-level dependency conditionally linked, then compilation succeeds. So we have a workaround...)

It does incorrectly attempt to build the tvOS stuff for iOS too, it is just less noticeable since that build succeeds. If you place something nonsensical inside #if !os(whichever), you can quickly prove that the problem affects pretty much every platform.

This is definitely a bug, but is unfortunately also of the Feedback Assistant kind. (Include a link to this thread instead of repeating yourself.)

I believe most of us have not noticed this because we test our packages at the package level. Since there is no such thing as a conditional target, attempting to build the entire package for tvOS would rightly fail, because it would involve building iOS-specific-target as one of the final products anyway, even though it would not be used in turn by any of the other products. Because that is the case, most of us are accustomed to surrounding files in #if os(iOS) anyway so that all targets build for all platforms anything in the package supports. The result is that our conditional dependencies are only ever across package boundaries (which definitely works). I mention it because either using #if or splitting the conditional dependencies into separate packages might be more resilient workarounds, depending on how your real project is actually arranged. But duplicating the condition at each level of the dependency tree as you have done is definitely the least invasive option for any project where it is sufficient.

Feedback reported: FB9987670

1 Like