diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000000..748c26073f --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "sharpie.bind.tool": { + "version": "26.6.0.18", + "commands": [ + "sharpie" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 74f8afd7cb..c2a8f45d76 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -105,7 +105,7 @@ Windows). |------|---------| | `*.slnf` | Edit `scripts/generate-solution-filters-config.yaml`, then run `scripts/generate-solution-filters.ps1` | | `CHANGELOG.md` | Generated on squash-merge from the PR title. `.github/workflows/changelog-guard.yml` fails CI on manual entries | -| `src/Sentry.Bindings.Cocoa/ApiDefinitions.cs`, `StructsAndEnums.cs` | Edit `scripts/patch-cocoa-bindings.cs`, then run `scripts/generate-cocoa-bindings.ps1` | +| `src/Sentry.Bindings.Cocoa/ApiDefinition.cs`, `StructsAndEnums.cs` | Edit `scripts/patch-cocoa-bindings.cs`, then run `scripts/generate-cocoa-bindings.ps1` | | `modules/**` | Git submodules pointing at other repositories — change them upstream, never in place | | `*.verified.*` | Run the tests, then `pwsh ./scripts/accept-verifier-changes.ps1` | @@ -147,7 +147,7 @@ scripts/ # Build and maintenance scripts - **macOS only**. Requires Xcode. - `Sentry.Bindings.Cocoa` wraps the native Cocoa SDK. - Device tests run in CI only. -- `src/Sentry.Bindings.Cocoa/ApiDefinitions.cs` and `StructsAndEnums.cs` are **auto-generated** — do not edit them directly. All changes must go in `scripts/patch-cocoa-bindings.cs` and be applied by running `scripts/generate-cocoa-bindings.ps1`. +- `src/Sentry.Bindings.Cocoa/ApiDefinition.cs` and `StructsAndEnums.cs` are **auto-generated** — do not edit them directly. All changes must go in `scripts/patch-cocoa-bindings.cs` and be applied by running `scripts/generate-cocoa-bindings.ps1`. ### MAUI - Requires MAUI workloads: `sudo dotnet workload restore` (macOS/Linux) or `dotnet workload restore` (Windows). diff --git a/scripts/generate-cocoa-bindings.ps1 b/scripts/generate-cocoa-bindings.ps1 index 78128e81e4..3909f293d6 100644 --- a/scripts/generate-cocoa-bindings.ps1 +++ b/scripts/generate-cocoa-bindings.ps1 @@ -19,86 +19,14 @@ if (!$IsMacOS) -CategoryActivity Error -ErrorAction Stop } -# Ensure Objective Sharpie is installed -if (!(Get-Command sharpie -ErrorAction SilentlyContinue)) -{ - Write-Output 'Objective Sharpie not found. Attempting to install via Homebrew.' - brew install --cask objectivesharpie - - if (!(Get-Command sharpie -ErrorAction SilentlyContinue)) - { - Write-Error 'Could not install Objective Sharpie automatically. Try installing from https://aka.ms/objective-sharpie manually.' - } -} - -# Ensure Xamarin is installed (or sharpie won't produce expected output). -if (!(Test-Path '/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/64bits/iOS/Xamarin.iOS.dll')) -{ - Write-Output 'Xamarin.iOS not found. Attempting to install manually.' - - # Download Xamarin.iOS package - $packageName = 'xamarin.ios-16.4.0.23.pkg' - $directDownloadUrl = 'https://github.com/getsentry/sentry-dotnet/releases/download/1.0.0.0-xamarin-ios/Xamarin.iOS.16.4.0.23.pkg' - $downloadPath = "/tmp/$packageName" - $expectedSha256 = '3c3a2e3c5adebf7955934862b89c82e4771b0fd44dfcfebad0d160033a6e0a1a' - - Write-Output "Downloading Xamarin.iOS package..." - curl -L -o $downloadPath $directDownloadUrl - - if ($LASTEXITCODE -ne 0) - { - Write-Error "Failed to download Xamarin.iOS package. Exit code: $LASTEXITCODE" - } - - # Verify checksum - Write-Output "Verifying package checksum..." - $actualSha256 = (Get-FileHash -Path $downloadPath -Algorithm SHA256).Hash.ToLower() - - if ($actualSha256 -ne $expectedSha256) - { - Write-Error "Checksum verification failed. Expected: $expectedSha256, Actual: $actualSha256" - Remove-Item $downloadPath -Force -ErrorAction SilentlyContinue - exit 1 - } - - Write-Output "Checksum verification passed." - - if (Test-Path $downloadPath) - { - Write-Output "Downloaded package to $downloadPath" - Write-Output "Installing Xamarin.iOS package..." - - # Install the package using installer command (requires sudo) - sudo installer -pkg $downloadPath -target / - - if ($LASTEXITCODE -ne 0) - { - Write-Error "Failed to install Xamarin.iOS package. Exit code: $LASTEXITCODE" - } - else - { - Write-Output "Xamarin.iOS package installed successfully" - } - - # Clean up downloaded file - Remove-Item $downloadPath -Force -ErrorAction SilentlyContinue - } - else - { - Write-Error "Downloaded package not found at $downloadPath" - } - - if (!(Test-Path '/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/64bits/iOS/Xamarin.iOS.dll')) - { - Write-Error 'Xamarin.iOS not found after installation.' - } -} +# Objective Sharpie is pinned in /.config/dotnet-tools.json. +Write-Output 'Restoring the pinned Objective Sharpie dotnet tool.' +dotnet tool restore # Get iPhone SDK version -$XcodePath = (xcode-select -p) -replace '/Contents/Developer$', '' -$iPhoneSdkVersion = sharpie xcode -xcode $XcodePath -sdks | grep -o -m 1 'iphoneos\S*' +$iPhoneSdkVersion = "iphoneos$(xcrun --sdk iphoneos --show-sdk-version)" Write-Output "iPhoneSdkVersion: $iPhoneSdkVersion" -$iPhoneSdkPath = xcrun --show-sdk-path --sdk $iPhoneSdkVersion +$iPhoneSdkPath = xcrun --show-sdk-path --sdk iphoneos Write-Output "iPhoneSdkPath: $iPhoneSdkPath" # Generate bindings. @@ -110,10 +38,13 @@ Write-Output "iPhoneSdkPath: $iPhoneSdkPath" # The SentryObjC headers resolve their own imports via `__has_include` guards and don't use the # `SENTRY_HEADER` macro, so - unlike the classic Sentry.h/Sentry-Swift.h headers we used to bind - # no header patching is needed before invoking sharpie. +# +# The header must be passed via `--header`; as a bare positional argument sharpie hands it straight +# to Clang, which then parses it as C and fails on the first Objective-C declaration. Write-Output 'Generating bindings with Objective Sharpie.' -sharpie bind -sdk $iPhoneSdkVersion ` - -scope "$CocoaSdkPath" ` - "$HeadersPath/SentryObjC.h" ` +dotnet sharpie bind -sdk $iPhoneSdkVersion ` + --scope "$CocoaSdkPath" ` + --header "$HeadersPath/SentryObjC.h" ` -o $BindingsPath ` -c -Wno-objc-property-no-attribute ` -F"$iPhoneSdkPath/System/Library/SubFrameworks" # needed for UIUtilities.framework in Xcode 26+ @@ -135,9 +66,9 @@ Copy-Item "$BindingsPath/$File" -Destination "$BackupPath/$File" & dotnet run "$PSScriptRoot/patch-cocoa-bindings.cs" "$BindingsPath/$File" | ForEach-Object { Write-Host $_ } ################################################################################ -# Patch ApiDefinitions.cs +# Patch ApiDefinition.cs ################################################################################ -$File = 'ApiDefinitions.cs' +$File = 'ApiDefinition.cs' Write-Output "Patching $BindingsPath/$File" Copy-Item "$BindingsPath/$File" -Destination "$BackupPath/$File" & dotnet run "$PSScriptRoot/patch-cocoa-bindings.cs" "$BindingsPath/$File" | ForEach-Object { Write-Host $_ } diff --git a/scripts/patch-cocoa-bindings.cs b/scripts/patch-cocoa-bindings.cs index e2455bfd01..5285ecde9a 100644 --- a/scripts/patch-cocoa-bindings.cs +++ b/scripts/patch-cocoa-bindings.cs @@ -9,7 +9,7 @@ if (args.Length != 1) { - Console.Error.WriteLine("Usage: patch-cocoa-bindings.cs "); + Console.Error.WriteLine("Usage: patch-cocoa-bindings.cs "); return; } diff --git a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs b/src/Sentry.Bindings.Cocoa/ApiDefinition.cs similarity index 99% rename from src/Sentry.Bindings.Cocoa/ApiDefinitions.cs rename to src/Sentry.Bindings.Cocoa/ApiDefinition.cs index 3c304f29cf..39ce1e4a47 100644 --- a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs +++ b/src/Sentry.Bindings.Cocoa/ApiDefinition.cs @@ -1463,7 +1463,7 @@ interface SentryObjCOptions [Wrap("WeakUrlSessionDelegate")] [NullAllowed] - NSUrlSessionDelegate UrlSessionDelegate { get; set; } + INSUrlSessionDelegate UrlSessionDelegate { get; set; } // @property (nonatomic, weak) id _Nullable urlSessionDelegate; [NullAllowed, Export("urlSessionDelegate", ArgumentSemantic.Weak)] diff --git a/src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj b/src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj index d55b7dee0a..3bdf984a2e 100644 --- a/src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj +++ b/src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj @@ -17,7 +17,7 @@ See getsentry/sentry-dotnet#5492. --> $(SentryCocoaCache)Carthage\Build-$(TargetPlatformIdentifier)\SentryObjC-Dynamic.xcframework - ../../scripts/generate-cocoa-bindings.ps1;$(SentryCocoaCache)Carthage/.built-from-sha;$(SentryCocoaCache)Carthage/Headers/**/*.h + ../../scripts/generate-cocoa-bindings.ps1;../../.config/dotnet-tools.json;$(SentryCocoaCache)Carthage/.built-from-sha;$(SentryCocoaCache)Carthage/Headers/**/*.h $([MSBuild]::NormalizePath($(MSBuildThisFileDirectory), $(SentryCocoaCache).git)) @@ -43,7 +43,7 @@ - + @@ -100,7 +100,7 @@ + Outputs="ApiDefinition.cs;StructsAndEnums.cs"> diff --git a/src/Sentry.Bindings.Cocoa/sharpie.md b/src/Sentry.Bindings.Cocoa/sharpie.md index bdb6fa8185..9c79957615 100644 --- a/src/Sentry.Bindings.Cocoa/sharpie.md +++ b/src/Sentry.Bindings.Cocoa/sharpie.md @@ -2,6 +2,10 @@ The files in this folder aren't "normal" C# files, but rather they are [Xamarin They are generated using [Objective Sharpie][2], using the script in `../scripts/generate-cocoa-bindings.ps1`. Do not modify the `.cs` files directly. Instead, update the script as needed and re-generate. +`Sentry.Bindings.Cocoa.csproj` re-runs the generation script on every macOS build whose Cocoa headers or scripts are newer than these files, and CI then fails on any difference between the regenerated output and what is committed - so a hand-edit will be overwritten locally and rejected by CI. Mechanical fixups to Sharpie's raw output belong in `../scripts/patch-cocoa-bindings.cs`, which the generation script applies afterwards. + +Objective Sharpie is the [`Sharpie.Bind.Tool`][3] dotnet tool, pinned in `/.config/dotnet-tools.json` and invoked as `dotnet sharpie`; the generation script runs `dotnet tool restore` first, so no manual install is needed. Pinning it matters because the generated output shifts between Sharpie versions - bump the manifest deliberately, then re-generate and commit the result. [1]: https://docs.microsoft.com/xamarin/cross-platform/macios/binding/objective-c-libraries [2]: https://docs.microsoft.com/xamarin/cross-platform/macios/binding/objective-sharpie +[3]: https://www.nuget.org/packages/Sharpie.Bind.Tool