Skip to content

build: consume single self-contained SentryObjC xcframework; drop Sentry.xcframework - #5500

Open
jamescrosswell wants to merge 5 commits into
mainfrom
5492-cocoa-packaging
Open

build: consume single self-contained SentryObjC xcframework; drop Sentry.xcframework#5500
jamescrosswell wants to merge 5 commits into
mainfrom
5492-cocoa-packaging

Conversation

@jamescrosswell

@jamescrosswell jamescrosswell commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Completes #5444: the .NET SDK now consumes a single self-contained SentryObjC-Dynamic.xcframework (the SentryObjC* surface with the engine baked in) and no longer ships Sentry.xcframework. Follow-up to #5450 (which removed all use of the classic Sentry* Obj-C API); this removes the last structural dependency on Sentry.framework.

We build the single framework from the modules/sentry-cocoa submodule (replacing the previous three thin xcodebuild archive frameworks with sentry-cocoa's own dynamic-variant packaging), instead of the three thin frameworks that dynamically linked each other.

Important

SentryCrash must be compiled with SENTRY_CRASH_MANAGED_RUNTIME=1 (a compile-time #ifdef that makes the signal / mach-exception monitors cooperate with the managed .NET/mono runtime). The generic release artifact isn't built with it — so we can't use the generic pre-built framework archive.

What changed

  • scripts/build-sentry-cocoa.sh — builds the single self-contained SentryObjC-Dynamic.xcframework via sentry-cocoa's own pipeline (build-xcframework-sentryobjc.sh --variant dynamic), then re-slices it to the platforms we ship: Carthage/Build-ios (device + simulator) and Carthage/Build-maccatalyst, plus headers. The old bespoke 3-scheme archive + inter-framework linking + nested-Frameworks stripping is gone.
  • scripts/sentry-cocoa.xcconfig (new) — injects GCC_PREPROCESSOR_DEFINITIONS = $(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1 via XCODE_XCCONFIG_FILE, because cocoa's packaging scripts don't expose extra build settings. (Verified: the define reaches the SentryCrash C compilation.)
  • Sentry.Bindings.Cocoa.csproj — one NativeReference (SentryObjC-Dynamic.xcframework) instead of three.
  • buildTransitive/Sentry.Bindings.Cocoa.targets — Hot-Restart simulator-strip regex updated to the single framework name.

Validation (local, macOS + Xcode 26.6, cocoa 9.26.0)

  • The built device-test app embeds only SentryObjC.framework (no Sentry.framework).
  • SENTRY_CRASH_MANAGED_RUNTIME=1 confirmed on the SentryCrash C compilation.
  • Bundled framework size (ios + mac catalyst): ~23 MB, comparable to previous.

Closes #5492
Closes #5444

🤖 Generated with Claude Code

…drop Sentry.xcframework

Completes #5444. Follow-up to #5450 (which removed all use of the
classic Sentry* ObjC API); this removes the last dependency on Sentry.framework.

The .NET SDK now consumes one self-contained SentryObjC-Dynamic.xcframework (the SentryObjC*
surface with the engine baked in) instead of three thin frameworks (Sentry + SentryObjC +
SentryObjCCompat) that dynamically linked each other.

- modules/sentry-cocoa.properties: version of the pre-built framework to download.
- scripts/download-sentry-cocoa.sh (default): download + re-slice the release artifact to the
  platforms we ship; no submodule checkout or from-source build needed.
- scripts/build-sentry-cocoa.sh (-p:BuildCocoaSdkFromSource=true): build the same framework from
  the submodule via sentry-cocoa's own dynamic-variant pipeline, for debugging. Requires xcbeautify.
- Sentry.Bindings.Cocoa.csproj: one NativeReference; _DownloadCocoaSDK / _BuildCocoaSDK select the
  source. buildTransitive Hot-Restart strip updated to the single framework.

Both paths produce byte-identical bindings. Validated locally: iOS + Mac Catalyst build, iOS
device tests (2771 run, 0 failed), and the app embeds only SentryObjC.framework.

#skip-changelog

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jamescrosswell jamescrosswell added the skip-changelog Suppress automatic changelog generation via Craft label Aug 18, 2026
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.88%. Comparing base (cf1e60c) to head (6d3b017).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5500      +/-   ##
==========================================
+ Coverage   74.73%   74.88%   +0.14%     
==========================================
  Files         513      513              
  Lines       18744    18659      -85     
  Branches     3666     3636      -30     
==========================================
- Hits        14009    13972      -37     
+ Misses       3863     3818      -45     
+ Partials      872      869       -3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

jamescrosswell and others added 2 commits August 19, 2026 13:34
…_RUNTIME=1

The generic pre-built SentryObjC-Dynamic release artifact can't be used: the .NET SDK
needs SentryCrash compiled with SENTRY_CRASH_MANAGED_RUNTIME=1 (a compile-time #ifdef so
the signal / mach-exception monitors cooperate with the managed .NET/mono runtime), and
you can't inject a compile flag into a pre-built binary. Without it, native capture of
managed crashes breaks (the "captures managed crash" integration tests fail).

So build the single self-contained SentryObjC-Dynamic.xcframework from the modules/sentry-cocoa
submodule (from-source only; no download/toggle), injecting the define via XCODE_XCCONFIG_FILE
since cocoa's packaging scripts don't expose extra build settings.

- scripts/sentry-cocoa.xcconfig: GCC_PREPROCESSOR_DEFINITIONS += SENTRY_CRASH_MANAGED_RUNTIME=1.
- scripts/build-sentry-cocoa.sh: export XCODE_XCCONFIG_FILE before cocoa's dynamic build.
- Removed the download path (download-sentry-cocoa.sh, modules/sentry-cocoa.properties) and
  the BuildCocoaSdkFromSource toggle; csproj always builds from source (submodule required).

Validated locally: SENTRY_CRASH_MANAGED_RUNTIME=1 confirmed on the SentryCrash C compilation;
iOS xUnit device suite (2771/0) and the crash-integration tests (6/0, incl. captures managed
crash / null reference) pass.

#skip-changelog

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Cocoa SDK now ships one self-contained SentryObjC-Dynamic.xcframework instead of three
frameworks, so sentry-cli uploads one native debug file (SentryObjC) rather than
Sentry + SentryObjC + SentryObjCCompat. Update the expected list accordingly (confirmed by the
actual UploadedDebugFiles reported in CI).

#skip-changelog

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj Outdated
Comment thread src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj Outdated
Comment thread src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj Outdated
Comment thread scripts/generate-cocoa-bindings.ps1 Outdated
Comment thread scripts/build-sentry-cocoa.sh Outdated
Comment thread scripts/build-sentry-cocoa.sh Outdated
Co-authored-by: James Crosswell <jamescrosswell@users.noreply.github.com>
@jamescrosswell
jamescrosswell marked this pull request as ready for review August 19, 2026 08:44
@github-actions github-actions Bot added the risk: high PR risk score: high label Aug 19, 2026
Comment on lines +68 to +74
xcodebuild -create-xcframework \
-framework "$xcf/ios-arm64/SentryObjC.framework" \
-framework "$xcf/ios-arm64_x86_64-simulator/SentryObjC.framework" \
-output "Carthage/Build-ios/$FRAMEWORK.xcframework"
xcodebuild -create-xcframework \
-framework "$xcf/ios-arm64_x86_64-maccatalyst/SentryObjC.framework" \
-output "Carthage/Build-maccatalyst/$FRAMEWORK.xcframework"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The build script hardcodes XCFramework slice directory names. This is fragile and will break the build if the sentry-cocoa dependency changes its naming convention in a future update.
Severity: MEDIUM

Suggested Fix

Instead of hardcoding the slice directory names, the script should dynamically discover them from the filesystem after the sentry-cocoa framework is built. Alternatively, add explicit checks to verify that each required slice directory exists before calling xcodebuild, and provide a clear error message if a path is not found. This will make the build process more resilient to changes in the dependency.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: scripts/build-sentry-cocoa.sh#L68-L74

Potential issue: The build script `scripts/build-sentry-cocoa.sh` uses hardcoded paths
for XCFramework slices, such as `ios-arm64` and `ios-arm64_x86_64-simulator`, when
calling `xcodebuild`. The script does not validate that these specific slice directories
exist before using them. If a future update to the `sentry-cocoa` dependency changes its
slice naming convention (for example, to support new architectures), the hardcoded paths
will become invalid. This will cause the `xcodebuild` command to fail, breaking the
entire SDK build process. While this failure would be caught by CI, it introduces
fragility and maintenance debt, as dependency updates could unexpectedly block builds.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philprime is this a realistic concern worth adding complexity for?

I'm guessing if you ever changed things around significantly, you'd probably give us a heads up... worst case, our bump to a new version of sentry-cocoa would fail and we'd discover things had moved around. So kind of thinking it's easier to react to than to anticipate and avoid in advance.

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

Labels

risk: high PR risk score: high skip-changelog Suppress automatic changelog generation via Craft

Projects

None yet

1 participant