Skip to content

linker block is silently ignored when the Kotlin CocoaPods plugin is applied #573

Description

@Curs3W4ll

Framework

Kotlin Multiplatform

Platform

Apple

Installed

None

Version

0.27.0

Steps to Reproduce

  1. Create a KMP module with Apple targets and a dynamic framework, applying both the Kotlin
    CocoaPods plugin (needed so the iOS app can consume the shared framework as a pod) and
    io.sentry.kotlin.multiplatform.gradle:

    plugins {
      alias(libs.plugins.kotlin.multiplatform)
      alias(libs.plugins.kotlin.cocoapods)
      alias(libs.plugins.sentry.kotlin.multiplatform)
    }
    
    kotlin {
      iosArm64()
      iosSimulatorArm64()
      cocoapods {
        podfile = project.file("../ios-app/Podfile")
        framework {
          baseName = "Shared"
          isStatic = false
        }
      }
    }
  2. Because Sentry-Cocoa no longer publishes to CocoaPods, turn off the pod auto-install and point the
    documented linker block at a locally downloaded XCFramework instead:

    sentryKmp {
      autoInstall.commonMain.enabled = false
      autoInstall.cocoapods.enabled = false
      linker.frameworkPath = "/abs/path/to/Sentry-Dynamic.xcframework"
    }
  3. Run ./gradlew :shared:linkPodDebugFrameworkIosSimulatorArm64.

Environment: sentry-kotlin-multiplatform 0.27.0, Kotlin 2.4.0, Gradle 9.7.1, Xcode 27,
macOS on Apple Silicon.

Expected Result

linker.frameworkPath is honored: the plugin resolves the XCFramework slice for each Apple target and
adds the corresponding linker options, so the framework links.

Failing that, the build fails fast with a message saying the configured linker was ignored and why.

Actual Result

The linker configuration is silently discarded and the link fails:

ld: warning: ignoring duplicate libraries: '-ldl', '-lobjc', '-lz'
ld: framework 'Sentry' not found

Nothing is logged to indicate linker.frameworkPath was ignored — at --info the plugin prints only
[sentry] Sentry telemetry has been disabled.

Cause. In the 0.27.0 plugin jar, SentryPlugin.executeConfiguration computes whether
KotlinCocoapodsPlugin is present and passes it into
maybeLinkCocoaFramework(project, hasCocoapodsPlugin, ...), which starts:

0: iload_2          // second boolean
1: ifeq  122        // -> return
4: iload_1          // hasCocoapodsPlugin
5: ifne  122        // -> return

So the whole linking setup — FrameworkPathResolver, CustomPathStrategy, DerivedDataStrategy,
FrameworkLinker — is skipped as soon as the CocoaPods plugin is detected, whatever linker was set to.

The docs say the linker block "is only relevant if you are using SPM", so this may well be deliberate.
But the configuration page does not state that the two are mutually exclusive, and applying the Kotlin
CocoaPods plugin does not imply that Sentry comes from CocoaPods — only that the module publishes a pod.

Why this leaves no path. Sentry-Cocoa has deprecated CocoaPods: 9.19.1 is the last published
version, publishing stopped end of June 2026, and per getsentry/sentry-cocoa#7383 the trunk goes
read-only on 2 December 2026. For a KMP module that must apply the Kotlin CocoaPods plugin, that leaves
autoInstall.cocoapods (a frozen, soon read-only channel) or linker (inert, per the above). The KMP
install docs still present CocoaPods as the default with no deprecation notice, so this is not
discoverable until the build breaks.

Workaround. We bypass the plugin's linking entirely — fetch Sentry-Dynamic.xcframework from the
GitHub release and add the search path per target:

binaries.configureEach {
  linkerOpts("-F", sliceDir, "-rpath", sliceDir)
}

Both device and simulator then link, and the commonTest executables run. Two things that cost us time
and may be worth surfacing in the SDK or docs:

  1. The dynamic XCFramework is required for a non-static framework — FrameworkLinker picks the
    static or dynamic path from Framework.isStatic, so the static Sentry.xcframework fails to link
    against a dynamic framework.
  2. Supplying Sentry-Cocoa outside CocoaPods links but does not embed it: Shared.framework ends up
    with @rpath/Sentry.framework/Sentry and the app fails in dyld at launch unless the framework is
    embedded separately. CocoaPods used to do that automatically.

Possible fixes, roughly by usefulness:

  1. Honor linker when explicitly configured, even with the CocoaPods plugin applied.
  2. If the exclusion is intentional, warn when a configured linker is discarded instead of failing later at ld.
  3. Document the interaction, and document a supported path for "KMP module publishes its own pod,
    Sentry-Cocoa comes from elsewhere".
  4. Consider supporting a pinned pre-built XCFramework directly — independent of both CocoaPods and
    DerivedData, and works in CI with no prior Xcode build.

Related: #551 (migrate away from CocoaPods — scoped to the SDK's own build), #484 and #318 (framework
resolution failures via DerivedData), getsentry/sentry-cocoa#7383.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions