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

Failed to build module this SDK is not supported by the compiler #1402

Closed
akovalov opened this issue Aug 1, 2023 · 11 comments
Closed

Failed to build module this SDK is not supported by the compiler #1402

akovalov opened this issue Aug 1, 2023 · 11 comments
Assignees
Labels
compilation issue SDK doesn't compile or gives warnings.

Comments

@akovalov
Copy link

akovalov commented Aug 1, 2023

The issue

We have a custom XCFramework where we add the latest Datadog v2.0.0 via SPM (only DatadogCore and DatadogLogs are used).
On "import DatadogCore" the Xcode gives a warning:

warning: module 'DatadogCore' was not compiled with library evolution support; using it means binary compatibility for 'OurCustomSDK' can't be guaranteed

Screenshot 2023-08-01 at 14 58 13

Then we build a binary .xcframework and it is built successfully. But when adding this .xcframework to other projects and having Datadog added via SPM in that project there is such a build error in Xcode

Failed to build module 'OurCustomSDK'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)', while this compiler is 'Apple Swift version 5.9 (swiftlang-5.9.0.124.4 clang-1500.0.38.1)'). Please select a toolchain that matches the SDK.

Screenshot 2023-08-01 at 14 47 42

and also Missing required module 'DatadogPrivate'

We have BUILD_LIBRARIES_FOR_DISTRIBUTION set to YES during XCFramework building.

Do you have any suggestions? Thanks!


Datadog SDK version:

2.0.0

Dependency Manager:

SPM

Xcode version:

Xcode 14.3.1 (14E300c) and Xcode 15 Beta

Deployment Target:

iOS 14

@akovalov akovalov added the compilation issue SDK doesn't compile or gives warnings. label Aug 1, 2023
@ncreated ncreated self-assigned this Aug 1, 2023
@ncreated
Copy link
Member

ncreated commented Aug 2, 2023

Hey @akovalov 👋. We use BUILD_LIBRARY_FOR_DISTRIBUTION=YES while producing our XCFrameworks to enable Module Stability in Datadog iOS SDK (not yet offering Library Evolution Support, but it doesn't seem to be the case here).

Regarding the issue, I think there might be 2 unrelated problems, but we need a bit more information to help you. Notably:

We have a custom XCFramework where we add the latest Datadog v2.0.0 via SPM (...). On "import DatadogCore" the Xcode gives a warning:

What exactly you mean by "adding DD to XCFramework via SPM" 🙂? Is it that your framework declares DD as dependency in Package.swift and you build XCFramework from Package.swift? Could you share the build command or give us something minimal so we can reproduce the warning on our end?

The latter problem might be unrelated to DD SDK, as the error message only mentions your OurCustomSDK:

Failed to build module 'OurCustomSDK'; this SDK is not supported by the compiler (the SDK is > built with 'Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)', while > this compiler is 'Apple Swift version 5.9 (swiftlang-5.9.0.124.4 clang-1500.0.38.1)'). Please > select a toolchain that matches the SDK.

On our side, Module Stability seems to work as expected - producing Datadog*.xcframework in one version of Xcode and using it in another is fine. It is fine now in 2.0.0 but it wasn't in 1.x because we were hitting this swiftc issue. What I can recommend is checking if .swiftinterface files (part of each slice in XCFramework) show no error when opened in Xcode.

@akovalov
Copy link
Author

akovalov commented Aug 2, 2023

Hi @ncreated Thank you for the detailed reply.

The DD is added to the OurCustomSDK Xcode project in the "Package Dependencies" section on the screenshot
Screenshot 2023-08-02 at 13 51 46

And the XCFramework build script looks like this

xcodebuild -quiet archive \
    ONLY_ACTIVE_ARCH=NO \
    -scheme "OurCustomSDK" \
    -destination="generic/platform=iOS Simulator" \
    -archivePath "./build/ios-sim.xcarchive" \
    -derivedDataPath "./DerivedData/iphonesimulator" \
    -sdk iphonesimulator \
    -configuration Release \
    SKIP_INSTALL=NO \
    BUILD_LIBRARIES_FOR_DISTRIBUTION=YES \
    GCC_GENERATE_DEBUGGING_SYMBOLS=YES \
    DEBUG_INFORMATION_FORMAT="dwarf-with-dsym"
    
xcodebuild -quiet archive \
    -scheme "OurCustomSDK" \
    -destination="generic/platform=iOS" \
    -archivePath "./build/ios.xcarchive" \
    -derivedDataPath "./DerivedData/iphoneos" \
    -sdk iphoneos \
    -configuration Release \
    SKIP_INSTALL=NO \
    BUILD_LIBRARIES_FOR_DISTRIBUTION=YES \
    GCC_GENERATE_DEBUGGING_SYMBOLS=YES \
    DEBUG_INFORMATION_FORMAT="dwarf-with-dsym"

xcodebuild -create-xcframework \
    -framework "./build/ios-sim.xcarchive/Products/Library/Frameworks/OurCustomSDK.framework" \
    -framework "./build/ios.xcarchive/Products/Library/Frameworks/OurCustomSDK.framework" \
    -output "./build/OurCustomSDK.xcframework"

Regarding the ... this SDK is not supported by the compiler ... issue, I now see that xcframework takes a Swift version of the Xcode version that was used to build xcframework and allows only that version. For example, if build xcframework with Xcode 14.2 - Swift 5.7 will be taken and the result xcframework will be in Xcode 14.2 only, but not in Xcode 14.3 and others. Same, if build with Xcode 14.3.1 (Swift 5.8.1) - it will be supported in Xcode 14.3.1 but not in Xcode 14.3 or Xcode 15, etc. I guess, this is because the Xcode project has an SPM dependency (not specifically DD but will happen with any library added this way) and maybe because SPM links it as a static library without BUILD_LIBRARIES_FOR_DISTRIBUTION for it.

We provide a binary xcframework only and the Package.swift to add OurCustomSDK with DD dependency looks as follows. Using this Package.swift I get these errors.

// swift-tools-version: 5.5
import PackageDescription

let package = Package(
    name: "OurCustom",
    platforms: [
        .iOS(.v14)
    ],
    products: [
        .library(
            name: "OurCustomSDK",
            targets: ["OurCustomSDKTargets"])
    ],
    dependencies: [
        .package(url: "https://github.com/DataDog/dd-sdk-ios", from: "2.0.0")
    ],
    targets: [
        .binaryTarget(
            name: "OurCustomSDK",
            path: "./OurCustomSDK.xcframework"
        ),
        .target(
            name: "OurCustomSDKTargets",
            dependencies: [
                .target(name: "OurCustomSDK"),
                .product(name: "DatadogCore", package: "dd-sdk-ios"),
                .product(name: "DatadogLogs", package: "dd-sdk-ios")
            ]
        )
    ]
)

So it's the kinda general question of how to link a third-party library in a binary xcframewok. Do you have any ideas or examples?

Also, even when xcframework is built with Xcode 14.3.1 and I use it in Xcode 14.3.1 I get the error

Missing required module 'DatadogPrivate'

Not sure if it is because of the above error or is a different one.

@ncreated
Copy link
Member

ncreated commented Aug 4, 2023

Thanks for sharing more context @akovalov 👍

I guess, this is because the Xcode project has an SPM dependency (not specifically DD but will happen with any library added this way) and maybe because SPM links it as a static library without BUILD_LIBRARIES_FOR_DISTRIBUTION for it.

I think you're right on that part. While the BUILD_LIBRARIES_FOR_DISTRIBUTION applies to framework build from your .xcodeproj, it is rather not applied to DD (and any other) dependency built by Xcode's SPM. I wonder if this would work if the flag is defined in the Package.swift of dependant library (here: DD).

So it's the kinda general question of how to link a third-party library in a binary xcframewok. Do you have any ideas or examples?

Sorry, no quick answer to this question. I'll create a backlog item and we will investigate it internally, hopefully coming up with a solution for adding DD as dependency to Vendor frameworks through SPM.

I assume .xcframework distribution of the "OurCustomSDK" is a requirement here, and you can't fallback to building it from source alongside with DD?

@akovalov
Copy link
Author

akovalov commented Aug 9, 2023

Thank you for your reply @ncreated

Yes, the .xcframework distribution is a requirement here, so we do need to find a way to solve the linking issue.

It seems to work OK if I would add built Datadog's xcframeworks (from a release package) to the project of "OurCustomSDK" as files without SPM dependency. In this case, the resulting OurCustomSDK.xcframework could embed or not embed (according to configuration in Xcode project) Datadog frameworks and then work OK. But I will double-check if it is so.
The inconvenience with this approach is that we need to download DD xcframeworks files and not include them in our repo. But probably that would be the only working solution at least for now.

hopefully coming up with a solution for adding DD as a dependency to Vendor frameworks through SPM

That would be great, thanks. Wondering, if you have any other solutions for adding DD as a dependency to Vendor frameworks in other ways than SPM?

@akovalov
Copy link
Author

akovalov commented Aug 16, 2023

Hi @ncreated just an update that I got it working by importing all DD modules with @ _implementationOnly in "OurCustomSDK" when DD is added as an SPM dependency.

@_implementationOnly import DatadogCore
@_implementationOnly import DatadogLogs

In this way, the DD symbols stay internal to the OurCustomSDK only and are not visible to the project that adds this SDK.
And it seems working fine.
Only one thing if the project that adds OurCustomSDK has also DD dependency (I guess no matter how it's added, I tested with added via SPM) in runtime there are the following warnings in the console for multiple DD classes

objc[45377]: Class _TtC22DatadogWebViewTracking22DDScriptMessageHandler is implemented in both /Users/[user]/Library/Developer/Xcode/DerivedData/DemoSPM-axrxefcamxfafigkgldeiuevcrqg/Build/Products/Debug-iphonesimulator/OurCustomSDK.framework/OurCustomSDK (0x104ab2d80) and /Users/[user]/Library/Developer/CoreSimulator/Devices/5FC413F2-8E1A-43E8-814B-464A51459CFA/data/Containers/Bundle/Application/06C864A4-D7DA-4E20-813E-BCA106E9487B/Demo.app/Demo (0x102f5c568). One of the two will be used. Which one is undefined.

However, I didn't experience an error because of it and the DD instance continues working fine in the SDK. I guess if both project and SDK will use the same DD SDK version then should be no issues at all. Maybe, if the project's DD version is different than SDK's version and for example, the class has some function in one version but does not have it in another and the system picked the one without the function and if the function will be called the app could crash. But it's just an assumption right now, can't confirm or deny this yet.

@akovalov
Copy link
Author

Just tested both cases when the integrator project has DD v2.0 and v1.23 dependency. Seems no errors (except the above console log) in the behavior and both logs from the app and SDK are visible in the dashboard. Also no crashes so far.

So I guess we are fine with it for now and the question can be closed unless you got any more thoughts to share. Thanks!

@maxep maxep self-assigned this Aug 18, 2023
@maxep
Copy link
Member

maxep commented Aug 21, 2023

Hi @akovalov ! Thank you very much for sharing your conclusions, it's very helpful!

You are facing a limitation of SPM, there is an opened issue swiftlang/swift-package-manager#4449 as well as an evolution pitch on that matter. What you did is actually the workaround described in here, but it indeed results in duplicated symbols warnings.

Sadly, there is nothing we can do on our side to make this setup work. With a fair amount of refactoring, you could workaround this by removing the dependency to Datadog in OurCustomSDK.xcframework and replace it with protocols and dependency injection. Then, you can make OurCustom swift package to depend on OurCustomSDK.xcframework and Datadog and do the proper injection.

I will close this issue but feel free to add more comments if you have any findings.

@mnabulsi92
Copy link

Hi @akovalov, I am facing the same issue you mentioned but your workaround in this comment #1402 (comment) didn't work for me.

Can you please provide more details how you link the Frameworks in your OurCustomSDK project?
Do you support any other dependency managers for your SDK ?

Thanks,

@akovalov
Copy link
Author

Hi @mnabulsi92 I have Datadog added via SPM in the OurCustomSDK project. We provide SDK as a binary file, so during .xcframework generation, the Datadog frameworks are embedded inside the OurCustomSDK automatically during building by xcodebuild command.

In your case, you do not embed in SDK and link as a dependency of your SDK. Your error is that SPM does not load the DD library for some reason during runtime. So yes, my solution will not work for you, cause this is a different issue.

We provide SDK by xcframework file and via SPM and Cocoapods. I can't confirm at this moment that Cocoapods works with this solution, will need to test it. However, it will not help you anyway.

@mnabulsi92
Copy link

Hi @akovalov, thanks for your reply.

I tried to embed the Datadog into our .xcframework and it worked but it failed during AppStore upload for a App that integrates our SDK we get multiple errors one of them is The bundle at "...framework" contains disallowed nested bundles.

Did you face the same issue with your SDK?

@akovalov
Copy link
Author

@mnabulsi92 we just started using Datadog and didn't release a public version to try this case. Thank you for sharing it, we need to verify it asap on our end because it will be a blocker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compilation issue SDK doesn't compile or gives warnings.
Projects
None yet
Development

No branches or pull requests

4 participants