Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-15196] Binary target required for compilation despite being a conditional dependency #4388

Open
swift-ci opened this issue Sep 14, 2021 · 33 comments
Labels

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-15196
Radar rdar://problem/83153139
Original Reporter gbrhaz (JIRA User)
Type Bug
Environment

Xcode 12.5.1

Xcode 13.0 beta 5

Additional Detail from JIRA
Votes 4
Component/s Package Manager
Labels Bug
Assignee None
Priority Medium

md5: 923498cd24ed244edda804515f08d0dd

is duplicated by:

  • SR-15836 Platform Conditionals Don't Apply To Binary Frameworks

Issue Description:

SPM has recently introduced conditional dependencies and binary targets (for xcframeworks). The two do not align, however. A binary dependency that is supported only on one platform is still linked on unsupported platforms.

I have created a repository here that I think showcases the issue:

https://github.com/gbrhaz/spm-binary-conditional

In the repository I have added the GoogleCast frameworks into an xcframework. Since GoogleCast is only supported for iOS, the xcframework supports architectures for iOS and x64 Simulator.

I want to depend on GoogleCast - but only for iOS platform, not for tvOS.

In the above repository I have also added a source-only dependency that can showcase how conditional dependencies do work for source-only frameworks. It appears to only be binary dependencies that cause issues.

@typesanitizer
Copy link

@swift-ci create

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 4, 2022
@dmcgloin
Copy link

Is there any more info that is needed to help address this issue? This is a big blocker for our team trying to create iOS and macOS shared projects.

@arielelkin
Copy link
Contributor

@shahmishal @neonichu @tomerd could you please post the workaround mentioned by Brian Michel? Looks like it was lost in the JIRA migration

@tomerd
Copy link
Member

tomerd commented Jul 14, 2022

From #4351 (comment):

This ticket can be closed as duplicate of SR-15196.

I've found a workaround in breaking apart the different platforms for the targets that I need for the time being. The branch in the description will not contain a broken Package.swift file anymore. Please look at the sample project in the linked Jira ticket.

@arielelkin
Copy link
Contributor

arielelkin commented Jul 14, 2022

@tomerd Yes that's the comment I linked to. The issue is that the workaround implementation isn't clear. Could you please share the sample project it mentions?

@tomerd
Copy link
Member

tomerd commented Jul 14, 2022

I see @arielelkin, I dont have access to the original Jira ticket any longer. @shahmishal could you help here?

@dmcgloin
Copy link

dmcgloin commented Jul 18, 2022

I will try to create a concise reproducible example for this.

But the basic steps are:

  1. Create an iOS-specific xcframework
  2. Create a macOS-specific xcframework
  3. Create a Swift Package that references both as conditional dependencies like so:
import PackageDescription

let package = Package(
    name: "MyLibrary",
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "MyLibrary",
            targets: ["MyLibrary"]),
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "MyLibrary",
            dependencies: [
                .target(name: "MyiOSFramework", condition: .when(platforms: [.iOS])),
                .target(name: "MymacOSFramework", condition: .when(platforms: [.macOS]))
            ]),
        .binaryTarget(
            name: "MyiOSFramework",
            path: "3rdParty/iOS/MyiOSFramework.xcframework"
        ),
        .binaryTarget(
            name: "MymacOSFramework",
            path: "3rdParty/macOS/MymacOSFramework.xcframework"
        ),
        .testTarget(
            name: "MyLibraryTests",
            dependencies: ["MyLibrary"]),
    ]
)

The error you get when building for iOS is:

/Users/me/Desktop/MyLibrary/3rdParty/macOS/MymacOSFramework.xcframework:1:1: While building for iOS Simulator, no library for this platform was found in '/Users/me/Desktop/MyLibrary/3rdParty/macOS/MymacOSFramework.xcframework'.

...and when building for macOS, the error is:

/Users/me/Desktop/MyLibrary/3rdParty/iOS/MyiOSFramework.xcframework:1:1: While building for macOS, no library for this platform was found in '/Users/me/Desktop/MyLibrary/3rdParty/iOS/MyiOSFramework.xcframework'.

@dmcgloin
Copy link

dmcgloin commented Jul 18, 2022

Here's a concise reproducible example.

MyLibrary.zip

  1. Open attached SPM project in Xcode version 13.4.1 (13F100)
  2. Build for iOS. Notice build errors
  3. Build for macOS. Notice similar build errors.

Same failure on Xcode 14 beta 3 as well.

@shahmishal
Copy link
Member

I see @arielelkin, I dont have access to the original Jira ticket any longer. @shahmishal could you help here?

@tomerd The original JIRA is SR-15836? Which would be #4351. The attachments are listed in the issue.

Attachment: Download

@arielelkin
Copy link
Contributor

@shahmishal the attached file is a log of build output. Could you please share the sample project attached to the JIRA ticket? You mention it here: #4351 (comment)

@dmcgloin
Copy link

@arielelkin I recall looking at the sample project from the original bug report - and is was very basic. I feel like the new example archive I posted in this thread is likely a sufficient replica of the original report.

@dmcgloin
Copy link

Same issue in Xcode version 14.0 beta 4 (14A5284g)

@arielelkin
Copy link
Contributor

@dmcgloin thanks, I'd just like to compare

@shahmishal @tomerd following up on my earlier comment, the attached file is a log of build output. Could you please share the sample project attached to the JIRA ticket? You mention it here: #4351 (comment)

@marcelmendesfilho
Copy link

@arielelkin @dmcgloin I've found the Brian Michel's repo that contains the workaround he mentioned in SR-15836. Here's the link to the repo. The workaround is available in the main branch.

@marcelmendesfilho
Copy link

@arielelkin @dmcgloin now linking to the commit

@tomerd
Copy link
Member

tomerd commented Aug 4, 2022

cc @neonichu, do we have also have a radar tracking this?

@marcelmendesfilho
Copy link

Hello all, just to let you know that Brian Michel's workaround saved my day.

@neonichu
Copy link
Member

neonichu commented Aug 5, 2022

Yes, there is rdar://83153139

@gregcotten
Copy link

Would love to see this resolved and slightly disheartened that the issue was originally raised 1 year ago without an actual solution in sight.

The workaround posted isn't even a proper workaround.

For example, if a dependency of a dependency of a dependency has "split up" libraries (macOS library w/ a binary framework dependency, all other OS library without a binary framework dependency), all the dependencies that depend on that package (or depend on a package that depends on that package) will also have to split their libraries similarly all the way up the chain. Not good!

@gregcotten
Copy link

gregcotten commented Sep 1, 2022

A random thought I had for a (maybe) proper workaround would be: could we somehow add "dummy" libraries with no symbols (.a or .dylib) to the xcframework for the missing platforms? Does anyone have experience doing anything like that? This would only work for owner of the package that supplies the binary target, but acceptable for now and requires much less jank.

@dmcgloin
Copy link

Confirming this issue is still happening in Xcode 14 RC1

@dmcgloin
Copy link

dmcgloin commented Oct 5, 2022

This is still a significant issue for our company and wondering if there is any way to push this along? Should we assume that this is now an internal Apple bug (rdar://83153139) that is actually prioritized? Btw, the proposed workarounds don't appear to solve the issue (as mentioned by @gregcotten ). Thanks for listening.

@neonichu
Copy link
Member

neonichu commented Oct 5, 2022

Yah, this is something we're aware of as a significant issue and are investigating.

@choulepoka
Copy link

Confirming this issue is still happening in XCode 14.1 RC2, with SwiftPM Tools 5.7

@jadelizardsoftware
Copy link

Having the same issue here. Trying to use GoogleMobileAds and only target with the iOS platform. I've removed tvOS, but it still fails to build with error:
"While building for tvOS Simulator, no library for this platform was found in '/Users/{myHomeF/Library/Developer/Xcode/DerivedData/{myPackageName}-bubgtznikupuivcjetnfyqxleoiu/SourcePackages/artifacts/swift-package-manager-google-mobile-ads/GoogleMobileAds.xcframework'"

@ephemer
Copy link

ephemer commented Dec 1, 2022

I would like to add that it's not only binary targets that are affected here. Normal "Source" targets are affected in exactly the same way.

Unfortunately, the issue outlined here makes the workaround suggested in this thread a non-starter for us. It's not tenable for us to have 5 layers of internal dependencies all using this workaround – it'd be a nightmare to maintain and an unreasonable amount of work to get there. In the meantime, I think we're all hoping that it will "soon" be unnecessary.

I had just started finally migrating back to SwiftPM after 4-5 years of staying away due to many compatibility and quality of life issues we had back then. And now this critical and show-stopping bug appears while migrating the very first target 👎🏼

Is there a better place to make our voices known than this thread?

@lololala22
Copy link

SPM team, when can we expect a solution on this?

@dmcgloin
Copy link

dmcgloin commented Feb 17, 2023

Looks like Xcode 14.3 beta 1 includes a fix for this: https://developer.apple.com/documentation/xcode-release-notes/xcode-14_3-release-notes

Fixed: Conditional target dependencies (SE-0273) in packages are now correctly applied to binary targets and leads to top-level targets being filtered out from builds of root packages. (85762201)

Haven't tried myself, but will give it a go soon.

@syoung-smallwisdom
Copy link

FYI: Tested this in one of our libraries in Xcode Version 14.3 beta (14E5197f) and it works with some caveats.

We found that this works:

let package = Package(
    name: "Foo",
    products: [
        .library(
            name: "Foo",
            targets: ["FooWrapper"]),
    ],
    targets: [
        .binaryTarget(name: "Foo",
                      path: "output/Foo.xcframework"),
        .target(name: "FooWrapper",
                dependencies: [
                    .target(name: "Foo", condition: .when(platforms: [.iOS]))
                ])
    ]
)

but this does not:

        .target(
            name: "OtherLibrary",
            dependencies: [
                .product(name: "Foo", package: "Foo", condition: .when(platforms: [.iOS])),
            ]),

If the package with the conditional binary does not wrap that binary in a target, then Xcode will still fail to build for macOS.

@neonichu
Copy link
Member

@syoung-smallwisdom thanks for your report, would you be able to share a full example of a case that isn't working as expected with 14.3?

@syoung-smallwisdom
Copy link

syoung-smallwisdom commented Feb 24, 2023

@neonichu

This package setup has the same failure in Xcode 14.3 beta as Xcode 14.2:

https://github.com/Sage-Bionetworks/BridgeArchiver-Swift/blob/0.3.1/Package.swift

Whereas this package setup will work in Xcode 14.3 beta because I added the conditional to the GitHub repo with the binary target in it.

https://github.com/Sage-Bionetworks/BridgeArchiver-Swift/blob/0.3.2/Package.swift

Added the conditional to the binary target here:
https://github.com/Sage-Bionetworks/CMSSupport/blob/1.2.3/Package.swift

Both still fail to build for macOS using Xcode 14.2 but yeah? A solution exists ... soon?

@dannys42
Copy link

dannys42 commented Mar 2, 2023

platform conditionals also appear to not function when using Target.Dependency.byName().

@phenemann
Copy link

I don't have this issue anymore with Xcode 14.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests