dd-sdk-ios icon indicating copy to clipboard operation
dd-sdk-ios copied to clipboard

Cannot build for testing: Undefined symbol

Open gmoraleda opened this issue 2 years ago • 5 comments

The issue

I've integrated DD in a custom Swift Package. Importing that package into my app target works flawlessly. I'm facing issues when building for testing. The compiler throws the following errors:

image

Datadog SDK version:

2.1.2

Last working Datadog SDK version:

N/A

Dependency Manager:

SPM

Xcode version:

Version 14.3 (14E222b)

Swift version:

swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100)

Deployment Target:

iOS 15: iPhone

macOS version:

13.5.1 (22G90)

This is my Package.swift manifest:

let package = Package(
    name: "CapmoLogging",
    platforms: [
        .iOS(.v15),
    ],
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "CapmoLogging",
            targets: ["CapmoLogging"]
        ),
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        .package(url: "https://github.com/CocoaLumberjack/CocoaLumberjack.git", exact: "3.8.1"),
        .package(url: "https://github.com/Datadog/dd-sdk-ios.git", exact: "2.1.2"),
        .package(url: "https://github.com/firebase/firebase-ios-sdk.git", exact: "10.14.0"),
        .package(url: "https://github.com/apollographql/apollo-ios.git", exact: "1.4.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: "CapmoLogging",
            dependencies: [
                .product(name: "CocoaLumberjackSwift", package: "CocoaLumberjack"),
                .product(name: "DatadogCore", package: "dd-sdk-ios"),
                .product(name: "DatadogLogs", package: "dd-sdk-ios"),
                .product(name: "DatadogRUM", package: "dd-sdk-ios"),
                .product(name: "DatadogTrace", package: "dd-sdk-ios"),
                .product(name: "FirebaseCrashlytics", package: "firebase-ios-sdk"),
                .product(name: "Apollo", package: "apollo-ios"),
            ]
        ),
        .testTarget(
            name: "CapmoLoggingTests",
            dependencies: ["CapmoLogging"]
        ),
    ]
)

The issue seems to be around DatadogInternal, which I require to inject the DatatodURLSessionDelegate in my Apollo client:

import Apollo
import DatadogTrace
import Foundation

// Helpers https://github.com/DataDog/dd-sdk-ios/issues/416
// https://github.com/ncreated/iOSTutorial/pull/1/files#diff-cbdc81feecfa385baf9dbbbde18afc412bddea7518c879a2e3a393ac28d298f5

public final class DatadogURLSessionClient: URLSessionClient, __URLSessionDelegateProviding {
    public let ddURLSessionDelegate = DatadogURLSessionDelegate()

    override public func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
        ddURLSessionDelegate.urlSession(session, task: task, didFinishCollecting: metrics)
        super.urlSession(session, task: task, didFinishCollecting: metrics)
    }

    override public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        ddURLSessionDelegate.urlSession(session, task: task, didCompleteWithError: error)
        super.urlSession(session, task: task, didCompleteWithError: error)
    }

    override public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        ddURLSessionDelegate.urlSession(session, dataTask: dataTask, didReceive: data)
        super.urlSession(session, dataTask: dataTask, didReceive: data)
    }
}

gmoraleda avatar Aug 31 '23 17:08 gmoraleda

~I was able to solve this issue by specifying my library type as dynamic in the Package manifest. In case it helps other folks.~

gmoraleda avatar Sep 01 '23 09:09 gmoraleda

Sadly, the Testflight version would crash immediately due to the missing dynamic library. I reopen the issue in case anyone has other ideas about how to fix this.

gmoraleda avatar Sep 01 '23 12:09 gmoraleda

This is a real issue we've been seeing for a year+. One way to work past it might be to xcodebuild build-for-testing then xcodebuild test-without-building. I haven't found a workaround that allows executing tests within Xcode.

Screenshot 2024-05-14 at 4 42 25 PM

pm-dev avatar May 14 '24 21:05 pm-dev

Hey @gmoraleda and @pm-dev

I'm very sorry for such a long reply, we totally missed it.

I'm not able to replicate, here the sample project I have setup: sample.zip

The test target compiles and run fine in my case. Do you have sample project that replicate the issue?

Thanks!

maxep avatar May 15 '24 09:05 maxep

This seems to happen during incremental builds with a specific dependency hierarchy, so it's a bit hard to reproduce despite it happening frequently in my project. Although this is likely an spm/xcodebuild bug where the build gets confused by from DatadogInternal, there may be a workaround that prevents this. I'll keep working on a consistent repro.

pm-dev avatar May 16 '24 20:05 pm-dev

Closing this issue due to inactivity. We're unable to reproduce this problem on our side. If it still persists (there were both SDK and Xcode updates since it was first opened) please attach sample project that we can look into and we will re-open it.

ncreated avatar Jun 26 '24 09:06 ncreated