Skip to content

SPM - Target Dependency Condition ignored for .target dependencies #5866

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

Closed
gpfister opened this issue Jun 24, 2022 · 9 comments
Closed

SPM - Target Dependency Condition ignored for .target dependencies #5866

gpfister opened this issue Jun 24, 2022 · 9 comments
Labels

Comments

@gpfister
Copy link

Describe the bug

I have a package which holds my Cloud API (built on Firebase). I have multiple apps (macOS, iOS) which uses this API, shared as a single package. I'm now trying to build a watchOS companion App, and some of the Firebase API is not provided, namely the Analytics. So I split my code into multiple libraries (inside the same package), and user condition: .when(platforms: [.iOS, .macOS]) so that I can only included dependencies (Analytics is a behind the scene piece, not really something I manipulate within the app).

However, the condition is ignored, it tries to build this target which fails because the framework is missing for watchOS.

To Reproduce

Here's a swift package example:

import PackageDescription

let package = Package(
    name: "OSKCloudKit",
    platforms: [.iOS(.v15), .macOS(.v12), .watchOS(.v8)],
    products: [
        .library(
            name: "OSKCloudAnalytics",
            targets: ["OSKCloudAnalytics"]
        ),
        .library(
            name: "OSKCloudAuth",
            targets: ["OSKCloudAuth"]
        ),
        .library(
            name: "OSKCloudCore",
            targets: ["OSKCloudCore"]
        ),
        .library(
            name: "OSKCloudModel",
            targets: ["OSKCloudModel"]
        ),
        .library(
            name: "OSKCloudServices",
            targets: ["OSKCloudServices"]
        )
    ],
    dependencies: [
        .package(url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "9.2.0")),
    ],
    targets: [
        .target(
            name: "OSKCloudAnalytics",
            dependencies: [
                .product(name: "FirebaseAnalytics", package: "firebase-ios-sdk"),
                .product(name: "FirebaseCrashlytics", package: "firebase-ios-sdk"),
            ]
        ),
        .target(
            name: "OSKCloudAuth",
            dependencies: [
                .target(name: "OSKCloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
                .target(name: "OSKCloudModel"),
                .product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
            ]
        ),
        .target(
            name: "OSKCloudCore",
            dependencies: [
                .product(name: "FirebaseAppCheck", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
                .product(name: "FirebaseFirestore", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseFunctions", package: "firebase-ios-sdk"),
                .product(name: "FirebaseStorage", package: "firebase-ios-sdk")
            ]
        ),
        .target(
            name: "OSKCloudModel",
            dependencies: [
                .product(name: "FirebaseFirestoreSwift", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
            ]
        ),
        .target(
            name: "OSKCloudServices",
            dependencies: [
                .target(name: "OSKCloudAnalytics"),
                .target(name: "OSKCloudModel"),
                .product(name: "FirebaseAnalytics", package: "firebase-ios-sdk"),
                .product(name: "FirebaseFirestore", package: "firebase-ios-sdk"),
                .product(name: "FirebaseFunctions", package: "firebase-ios-sdk"),
                .product(name: "FirebaseStorage", package: "firebase-ios-sdk")
            ]
        ),
        .testTarget(
            name: "OSKCloudKitTests",
            dependencies: [
                "OSKCloudModel",
                "OSKCloudServices",
            ]
        ),
    ]
)

When building OSKCloudAuth on iOS device, it works, on watchOS device it fails:

/Users/xxxxxxxx/Library/Developer/Xcode/DerivedData/ios-oskey-dev-azwwbbesmdjzuvbwptqniydxopne/SourcePackages/artifacts/firebase-ios-sdk/FirebaseAnalytics.xcframework:1:1: While building for watchOS Simulator, no library for this platform was found in '/Users/gpfister/Library/Developer/Xcode/DerivedData/ios-oskey-dev-azwwbbesmdjzuvbwptqniydxopne/SourcePackages/artifacts/firebase-ios-sdk/FirebaseAnalytics.xcframework'.

Expected behavior

The target OSKCloudAuth has a dependency on OSKCloudAnalytics:

        .target(
            name: "OSKCloudAuth",
            dependencies: [
                .target(name: "OSKCloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
                .target(name: "OSKCloudModel"),
                .product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
            ]
        ),

It should not try to build it, just like if it was:

        .target(
            name: "OSKCloudAuth",
            dependencies: [
                .target(name: "OSKCloudModel"),
                .product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
            ]
        ),

Screenshots
If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

  • OS: macOS 12.4
  • Xcode Version/Tag/Branch: Xcode 13.4.1

Additional context
Add any other context about the problem here.

@gpfister gpfister added the bug label Jun 24, 2022
@pchelnikov
Copy link

@gpfister did you find any solution? I've got the same issue when I updated Facebook SDK.

@gpfister
Copy link
Author

gpfister commented Jul 8, 2022

@pchelnikov No, I think the issue is in the way SPM works: it should not try to resolve the dependency (i.e. check for a valid product with that name in the package for the arch you are building for), but check the conditions first, and only resolve it if they are met.

As a workaround, I proposed to Firebase team to allow the target to be built on any arch (even if the build fails, as it will not try to build it). That way SPM finds the product for the arch, but ignores it because it doesn't meet the condition.

Should I be in the shoes of thoses providing the SDK, I would argue that this is something that should be fixed here, as workaround is not a sustainable approach.

@gohnjanotis
Copy link

Has anyone found a workaround for this? I'd really like to be able to use Xcode Previews for watchOS apps.

@gpfister
Copy link
Author

@gohnjanotis: This doesn't seem to get any attention from the project team...

@AnthonyLatsis
Copy link
Contributor

This looks like a package manager issue, not a compiler one. @hborla Should we transfer it?

@hborla hborla transferred this issue from swiftlang/swift Nov 2, 2022
@neonichu
Copy link
Contributor

neonichu commented Nov 2, 2022

The issue here is that we have two competing definitions of what should be built for root packages. On the one hand, there's the rule to always build all targets, on the other hand there's the reasonable expectation that if a target is conditionalized at least once, it should not be build in that context.

We're aware of this issue and it has recently been fixed for SwiftPM itself #5784 -- an equivalent fix will be needed on the Xcode build system side to solve this concrete case, though (tracked by rdar://91946186).

@gpfister
Copy link
Author

gpfister commented Nov 2, 2022

Thank you for the feedback. It seems that this issue can be closed.

@gpfister gpfister closed this as completed Nov 2, 2022
@linkrjr
Copy link

linkrjr commented Sep 5, 2023

Do we have a solution for this in xcode?

@NikolayJuly
Copy link

I have same issue. Work with "swift build" in terminal and doesn't work in xcode. Here id Feedback id - FB15945161

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

7 participants