diff --git a/CLAUDE.md b/CLAUDE.md index f68c3912a..36d356257 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -156,7 +156,7 @@ Key targets defined in `Directory.Build.targets`: | `BuildAndroidSDK` | Builds Android SDK via Gradle | | `BuildLinuxSDK` | Builds Linux SDK via CMake | | `BuildWindowsSDK` | Builds Windows SDK via CMake (Crashpad) | -| `BuildCocoaSDK` | Downloads iOS/macOS SDKs from releases | +| `BuildCocoaSDK` | Builds iOS/macOS SDKs via Xcode | | `UnityEditModeTest` | Runs edit-mode unit tests | | `UnityPlayModeTest` | Runs play-mode tests | @@ -320,6 +320,18 @@ modules/ └── sentry-cocoa/ # iOS/macOS (prebuilt XCFramework) ``` +### Local Android NDK Development + +When iterating on `modules/sentry-native/ndk` together with `modules/sentry-java`, publish the local NDK build to `~/.m2` so sentry-java picks it up instead of mavenCentral: + +```bash +pwsh scripts/build-native-ndk-local.ps1 # publish only +pwsh scripts/build-native-ndk-local.ps1 -BuildJava # publish + rebuild :sentry-android-ndk +pwsh scripts/build-native-ndk-local.ps1 -PurgeCache -BuildJava # first switch from central, or after stale builds +``` + +Prerequisite: `mavenLocal()` must precede `mavenCentral()` in `modules/sentry-java/settings.gradle.kts` (`dependencyResolutionManagement` block). The script aborts otherwise. + ### Key Source Files **Android (`src/Sentry.Unity.Android/`):** diff --git a/Directory.Build.targets b/Directory.Build.targets index 8f6613858..49fe224c5 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -117,33 +117,57 @@ - - + - + + -Clean + + + - + + + + + + + + + + $([System.IO.File]::ReadAllText("$(RepoRoot)modules/sentry-java/gradle/libs.versions.toml")) $([System.Text.RegularExpressions.Regex]::Match($(PropertiesContent), 'sentry-native-ndk\s*=\s*\{[^}]*version\s*=\s*"([^"]+)"').Groups[1].Value) - + - + - + - + + + + + + -PurgeCache + + + + + + + + + And ('$(RebuildNativeSdk)' == 'true' Or !Exists('$(SentryWindowsArtifactsDestination)sentry.dll'))" BeforeTargets="BeforeBuild"> @@ -222,10 +286,15 @@ - + + And ('$(RebuildNativeSdk)' == 'true' Or !Exists('$(SentryLinuxArtifactsDestination)libsentry.so'))" BeforeTargets="BeforeBuild"> diff --git a/scripts/build-cocoa-sdk.ps1 b/scripts/build-cocoa-sdk.ps1 index deb8444b7..ef745627f 100644 --- a/scripts/build-cocoa-sdk.ps1 +++ b/scripts/build-cocoa-sdk.ps1 @@ -8,7 +8,9 @@ param( [string]$iOSDestination, [Parameter(Mandatory = $true)] - [string]$macOSDestination + [string]$macOSDestination, + + [switch]$Clean ) Set-StrictMode -Version latest @@ -25,6 +27,11 @@ $buildPath = Join-Path $CocoaRoot "XCFrameworkBuildPath" $iOSXcframeworkPath = Join-Path $buildPath "Sentry-Dynamic-iOS.xcframework" $macOSXcframeworkPath = Join-Path $buildPath "Sentry-Dynamic-macOS.xcframework" +if ($Clean -and (Test-Path $buildPath)) { + Write-Host "Clean build requested — removing $buildPath" -ForegroundColor Yellow + Remove-Item -Path $buildPath -Recurse -Force +} + Write-Host "Building Cocoa SDK from source..." -ForegroundColor Yellow Push-Location $CocoaRoot diff --git a/scripts/build-native-ndk-local.ps1 b/scripts/build-native-ndk-local.ps1 new file mode 100644 index 000000000..05773f490 --- /dev/null +++ b/scripts/build-native-ndk-local.ps1 @@ -0,0 +1,124 @@ +<# +.SYNOPSIS + Builds modules/sentry-native (NDK) and publishes the artifact to the local + Maven repo so modules/sentry-java consumes it instead of mavenCentral. + +.DESCRIPTION + Runs :sentry-native-ndk:publishToMavenLocal in modules/sentry-native/ndk, + producing io.sentry:sentry-native-ndk: at ~/.m2. + + Requires mavenLocal() to be listed before mavenCentral() in + modules/sentry-java/settings.gradle.kts. The script verifies this and + aborts otherwise. + + Because both repos publish the same version coordinate, Gradle's module + and transform caches can hold a previously-resolved mavenCentral copy. + The first time you switch to local (or when the module cache holds a + stale build), pass -PurgeCache to wipe sentry-native-ndk caches and + stop the Gradle daemon so the next build re-resolves from mavenLocal. + +.PARAMETER PurgeCache + Delete sentry-native-ndk from the Gradle module cache and the related + transform directories, then stop the Gradle daemon. Use when switching + from mavenCentral resolution or when the consumed artifact looks stale. + +.PARAMETER BuildJava + After publishing, run :sentry-android-ndk:assembleRelease in + modules/sentry-java to consume the freshly published artifact. + +.EXAMPLE + pwsh scripts/build-native-ndk-local.ps1 + # Publish ndk to ~/.m2 (assumes caches are already clean). + +.EXAMPLE + pwsh scripts/build-native-ndk-local.ps1 -PurgeCache -BuildJava + # Wipe stale caches, publish, then rebuild sentry-android-ndk against + # the local artifact. +#> + +param( + [switch] $PurgeCache, + [switch] $BuildJava +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest + +$repoRoot = Resolve-Path (Join-Path $PSScriptRoot '..') +$ndkDir = Join-Path $repoRoot 'modules/sentry-native/ndk' +$javaDir = Join-Path $repoRoot 'modules/sentry-java' +$javaSettings = Join-Path $javaDir 'settings.gradle.kts' + +if (-not (Test-Path $ndkDir)) { + throw "sentry-native NDK module not found at $ndkDir. Did you check out the submodule?" +} +if (-not (Test-Path $javaSettings)) { + throw "sentry-java settings.gradle.kts not found at $javaSettings." +} + +$settingsContent = Get-Content $javaSettings -Raw +$drmMatch = [regex]::Match($settingsContent, 'dependencyResolutionManagement\s*\{[^}]*repositories\s*\{(?[^}]*)\}') +if (-not $drmMatch.Success) { + throw "Could not locate dependencyResolutionManagement.repositories block in $javaSettings." +} +$reposBlock = $drmMatch.Groups['repos'].Value +$localIdx = $reposBlock.IndexOf('mavenLocal()') +$centralIdx = $reposBlock.IndexOf('mavenCentral()') +if ($localIdx -lt 0 -or $centralIdx -lt 0 -or $localIdx -gt $centralIdx) { + throw @" +mavenLocal() must appear before mavenCentral() in +$javaSettings (dependencyResolutionManagement block) so sentry-java +resolves the locally-published sentry-native-ndk artifact. Reorder the +repositories and re-run this script. +"@ +} + +if ($PurgeCache) { + Write-Host '==> Purging Gradle caches for sentry-native-ndk' + $gradleCaches = Join-Path $HOME '.gradle/caches' + $moduleCache = Join-Path $gradleCaches 'modules-2/files-2.1/io.sentry/sentry-native-ndk' + if (Test-Path $moduleCache) { + Remove-Item -Recurse -Force $moduleCache + Write-Host " removed $moduleCache" + } + + if (Test-Path $gradleCaches) { + $transformRoots = Get-ChildItem -Path $gradleCaches -Recurse -Force -ErrorAction SilentlyContinue ` + | Where-Object { $_.FullName -like '*sentry-native-ndk*' } ` + | ForEach-Object { + $idx = $_.FullName.IndexOf('/transformed/') + if ($idx -lt 0) { $idx = $_.FullName.IndexOf([IO.Path]::DirectorySeparatorChar + 'transformed' + [IO.Path]::DirectorySeparatorChar) } + if ($idx -ge 0) { $_.FullName.Substring(0, $idx) } else { $null } + } ` + | Where-Object { $_ } ` + | Sort-Object -Unique + foreach ($dir in $transformRoots) { + if (Test-Path $dir) { + Remove-Item -Recurse -Force $dir + Write-Host " removed $dir" + } + } + } + + Write-Host '==> Stopping Gradle daemon to clear in-memory transform registry' + Push-Location $ndkDir + try { & ./gradlew --stop | Out-Null } finally { Pop-Location } +} + +Write-Host '==> Publishing sentry-native-ndk to mavenLocal' +Push-Location $ndkDir +try { + & ./gradlew :sentry-native-ndk:publishToMavenLocal + if ($LASTEXITCODE -ne 0) { throw "publishToMavenLocal failed (exit $LASTEXITCODE)" } +} finally { Pop-Location } + +if ($BuildJava) { + Write-Host '==> Building :sentry-android-ndk:assembleRelease against mavenLocal' + Push-Location $javaDir + try { + & ./gradlew :sentry-android-ndk:assembleRelease + if ($LASTEXITCODE -ne 0) { throw "sentry-android-ndk assembleRelease failed (exit $LASTEXITCODE)" } + } finally { Pop-Location } +} + +Write-Host '==> Done.'