Patrick
Patrick

Reputation: 2432

Is there a way to generate dSYMs for Swift Packages when Xcode archiving?

In the past when I've used Cocoapods to manage dependencies, archiving an app would put the frameworks in the dSYM folder of the archive. I would have one dSYM for the app, and one dSYM for each dependency. When using SPM, the archive dSYM folder only contains the app dSYM.

Is there a way to generate dSYMs for Swift Packages in the same way (or is my understanding wrong and this one dSYM contains everything)?

My configuration:

Steps to reproduce:

  1. Create a new Xcode project (macOS or iOS).
  2. Check that Debug Information Format = DWARF with dSYM File
  3. Add a dependency via SPM (https://github.com/hmlongco/Resolver).
  4. Archive the project.
  5. Open xxx.xcarchive/dSYMS
  6. Notice only one dSYM for app but none for dependency.

Upvotes: 3

Views: 2106

Answers (1)

iUrii
iUrii

Reputation: 13838

It depends how your dependencies are linked into your app.

If you use Cocoapods with use_frameworks! all dependencies will be compiled as separate dynamic frameworks and will put into Frameworks folder inside your app and in this case XCode can generate dSYM files for each of them. But when you link your libraries statically the symbolication info is put into "YourApp.dSYM" file because libraries code is injected inside your app’s binary.

The same works with SPM. By default swift packages are compiled as static libraries so that its binaries will be inserted in your app's binary and all symbolication info will be inside "YourApp.dSYM" under __swift_ast section.

To make your package as dynamic library you should state it implicitly inside Package.swift file and after XCode can generate dSYM for it, e.g.:

let package = Package(
    name: "MyDynamic",
    products: [
        .library(
            name: "MyDynamic",
            type: .dynamic,
            targets: ["MyDynamic"]),
    ],
…

But if you want to link already static third party package dynamically you can make you own local dynamic package (wrapper) with needed static dependencies, for instance with Realm:

let package = Package(
    name: "MyDynamic",
    platforms: [
        .iOS(.v12),
    ],
    products: [
        .library(
            name: "MyDynamic",
            type: .dynamic,
            targets: ["MyDynamic"]),
    ],
    dependencies: [
        .package(name: "Realm", url: "https://github.com/realm/realm-swift.git", from: "10.28.1")
    ],
    targets: [
        .target(
            name: "MyDynamic",
            dependencies: [.product(name: "RealmSwift", package: "Realm")]),
        .testTarget(
            name: "MyDynamicTests",
            dependencies: ["MyDynamic"]),
    ]
)

Next add it to your app (File > Add Packages… > Add local..) and then you can use Realm as usual inside your code because all MyDynamic dependencies are public to your app:

import RealmSwift

func load() {
    let realm = try? Realm()
    …
}

And “MyDynamic.framework.dSYM” will be generated and has all Realm symbolication info.

Upvotes: 3

Related Questions