Binary Target stopped working in Xcode 15.3

This might be an Xcode issue (I have reported feedback) but just want to make sure I am not doing something obviously wrong in my Package.swift file. I have a project with a local package that depends on a binary target (OpenCV).

A stripped down repro looks like this:

// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "Experiment",
    platforms: [.iOS(.v17)],
    products: [
        // Products define the executables and libraries a package produces, making them visible to other packages.
        .library(
            name: "Experiment",
            targets: ["Experiment"]),
    ],
    targets: [
        // Targets are the basic building blocks of a package, defining a module or a test suite.
        // Targets can depend on other targets in this package and products from dependencies.
        .target(
            name: "Experiment",
            dependencies: ["opencv2"]),
        .binaryTarget(name: "opencv2",
                      url: "<some-server>/opencv2.xcframework.zip?raw=1",
                      checksum: "<checksum>"),
        .testTarget(
            name: "ExperimentTests",
            dependencies: ["Experiment"]),
    ]
)

The app builds and runs fine with Xcode 15.2 and earlier. In Xcode 15.3, I get an error when it tries to install the app (simulator or device) relating to the OpenCV.xcframework's Info.plist.

Failed to load Info.plist from bundle at path /Users/rayfix/Library/Developer/CoreSimulator/Devices/2F5E4E52-C9F2-47AD-973F-37653A8173FD/data/Library/Caches/com.apple.mobile.installd.staging/temp.fQ0GZz/extracted/ReproProblem.app/Frameworks/opencv2.framework;

There is, of course, an Info.plist in the binary target's xcframework but it is not getting copied to this extraction directory apparently.

Any ideas of things I might try to get things building, installing and running again. Could there be an error in the Info.plist itself that is causing it?

Thanks for any pointers.

Ray

Can you put this XCFramework somewhere I can download it?

My experience is that the majority of problems like this occur because:

  • The framework isn’t following the rules in Placing Content in a Bundle.

  • Or the framework’s Info.plist is not constructed properly.

This is particularly common for cross-platform frameworks that start out a dynamic library but have to be wrapped in a framework to work on iOS.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like

Sure. It would be great if you could give it a quick look. (Just so you know, I also posted a TSI about it, but I will also post the results here if I am able to solve it.)

I cobbled this xcframework build together last year (after you and others helped me out). It was working great until Xcode 15.3

Hi Ray, I had a binary framework that was working with Xcode 15.2 but not Xcode 15.3. In the end it was because as of 15.3 you need to code sign your .xcframework at the top level now as outlined in this article: Embedding a privacy manifest into an XCFramework – Rhonabwy. Privacy manifests are not required as yet but I imagine they will be before too long. For me for Xcode 15.3 the main thing was to sign the .xcframework itself, not just its contents.

1 Like

Just so you know, I also posted a TSI about it,

Yeah, I saw that after I responded here (-:

Thanks for the link to the download.

The thing that immediately jumps out is that your XCFramework has component frameworks that target iOS but which use the macOS-style ‘deep’ framework format. Consider this:

% ls -l opencv2.xcframework/ios-arm64/opencv2.framework/
total 0
lrwxr-xr-x@ … Headers -> Versions/Current/Headers
lrwxr-xr-x@ … Modules -> Versions/Current/Modules
lrwxr-xr-x@ … Resources -> Versions/Current/Resources
drwxr-xr-x@ … Versions
lrwxr-xr-x@ … opencv2 -> Versions/Current/opencv2

In an iOS-style framework, there is no Versions directory and all those top-level symlinks are replaced by the real items. Placing Content in a Bundle explains that structure in more detail.

I recommend that you fix this and retest.

Honestly, I’m surprised this ever worked (-:

ps If you’re building an XCFramework that supports macOS and other platforms, you’ll end up with different structures in the component frameworks. Use the macOS structure in your macOS framework and the iOS structure in all the others.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

We had the opposite problem. We had been using the simpler iOS style framework structure for macOS and Catalyst. It worked fine until Xcode 15.3 which forced us to switch to the 'deep' framework format (and address several knock-on issues for internal and external tooling that did not properly support symlinks).

1 Like

We had the opposite problem.

Yep. This sort of thing is common, to the point where Placing Content in a Bundle has this warning:

If you put content in the wrong location, you may encounter hard-to-debug code signing and distribution problems. These problems aren’t always immediately obvious.

It would be nice if Apple’s tooling has a single coherent way to check whether a bundle structure is valid. Sadly, that’s not the case )-:

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple