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

feat: cocoa SDK integration for macOS #2750

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions .github/actions/buildcocoasdk/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,17 @@ runs:
using: composite

steps:

- name: Fetch version tags for Sentry Cocoa SDK
shell: bash
run: git fetch --tags --quiet
working-directory: modules/sentry-cocoa

- name: Get Sentry Cocoa SHA

- name: Get submodule status
shell: bash
run: echo "SENTRY_COCOA_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
working-directory: modules/sentry-cocoa
run: cat .git/modules/modules/sentry-cocoa/HEAD

- name: Cache Sentry Cocoa SDK
id: cache-sentry-cocoa
uses: actions/cache@v3
with:
path: modules/sentry-cocoa/Carthage
key: sentry-cocoa-${{ env.SENTRY_COCOA_SHA }}
key: sentry-cocoa-${{ hashFiles('scripts/build-sentry-cocoa.sh', '.git/modules/modules/sentry-cocoa/HEAD') }}

- name: Build Sentry Cocoa SDK
if: ${{ steps.cache-sentry-cocoa.outputs.cache-hit != 'true' }}
Expand Down
6 changes: 3 additions & 3 deletions .github/actions/environment/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ runs:
with:
dotnet-version: |
3.1.x
6.0.x
6.0.x
7.0.x
8.0.x

- name: Dependency Caching
uses: actions/cache@v3
# Cache is too slow on Windows to be useful. See https://github.com/actions/cache/issues/752
Expand All @@ -45,6 +45,6 @@ runs:
run: >
dotnet workload install \
maui-android \
${{ runner.os == 'macOS' && 'maui-ios maui-maccatalyst maui-windows' || '' }} \
${{ runner.os == 'macOS' && 'macos maui-ios maui-maccatalyst maui-windows' || '' }} \
${{ runner.os == 'Windows' && 'maui-windows' || '' }} \
--temp-dir "${{ runner.temp }}"
3 changes: 3 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<PropertyGroup>
<TargetPlatformIdentifier>$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))</TargetPlatformIdentifier>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'ios'">10.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'macos'">13.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
Expand All @@ -66,6 +67,8 @@
<!-- This is helpful in code to distinguish neutral targets. -->
<PropertyGroup>
<DefineConstants Condition="'$(TargetPlatformIdentifier)' == ''">$(DefineConstants);PLATFORM_NEUTRAL</DefineConstants>
<DefineConstants Condition="'$(TargetPlatformIdentifier)' == 'ios'">$(DefineConstants);SENTRY_UIKIT_AVAILABLE</DefineConstants>
<DefineConstants Condition="'$(TargetPlatformIdentifier)' == 'maccatalyst'">$(DefineConstants);SENTRY_UIKIT_AVAILABLE</DefineConstants>
</PropertyGroup>

<!-- We're aware it's out of support but this is a library and it doesn't require nca3.1. -->
Expand Down
9 changes: 6 additions & 3 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<PropertyGroup>
<TargetPlatformIdentifier>$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))</TargetPlatformIdentifier>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'ios'">10.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'macos'">13.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="'$(TargetPlatformIdentifier)' == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
Expand All @@ -18,7 +19,7 @@
<Compile Remove="**\Android\**\*.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetPlatformIdentifier)' != 'ios' And '$(TargetPlatformIdentifier)' != 'maccatalyst'">
<ItemGroup Condition="'$(TargetPlatformIdentifier)' != 'ios' And '$(TargetPlatformIdentifier)' != 'macos' And '$(TargetPlatformIdentifier)' != 'maccatalyst'">
<Compile Remove="**\*.iOS.cs" />
<Compile Remove="**\iOS\**\*.cs" />
</ItemGroup>
Expand Down Expand Up @@ -67,7 +68,8 @@
<!-- Workaround for https://github.com/xamarin/xamarin-macios/issues/15897 -->
<Target Name="_SetPublishFolderTypeNoneOnDocFileItems"
BeforeTargets="_ComputePublishLocation"
Condition="'$(OutputType)' == 'Exe' And ('$(TargetPlatformIdentifier)' == 'ios' Or '$(TargetPlatformIdentifier)' == 'maccatalyst')">
Condition="'$(OutputType)' == 'Exe'
and ('$(TargetPlatformIdentifier)' == 'ios' or '$(TargetPlatformIdentifier)' == 'macos' or '$(TargetPlatformIdentifier)' == 'maccatalyst')">
<ItemGroup>
<ResolvedFileToPublish
Update="@(ResolvedFileToPublish)"
Expand All @@ -82,7 +84,8 @@
-->
<Import Project="$(MSBuildThisFileDirectory)src\Sentry\buildTransitive\Sentry.targets" />
<Import Project="$(MSBuildThisFileDirectory)src\Sentry.Bindings.Cocoa\buildTransitive\Sentry.Bindings.Cocoa.targets"
Condition="'$(OutputType)' == 'Exe' And ('$(TargetPlatformIdentifier)' == 'ios' Or '$(TargetPlatformIdentifier)' == 'maccatalyst')" />
Condition="'$(OutputType)' == 'Exe'
and ('$(TargetPlatformIdentifier)' == 'ios' or '$(TargetPlatformIdentifier)' == 'macos' or '$(TargetPlatformIdentifier)' == 'maccatalyst')"></Import>
<Import Project="$(MSBuildThisFileDirectory)src\Sentry.Bindings.Native\buildTransitive\Sentry.Bindings.Native.targets" />

</Project>
114 changes: 60 additions & 54 deletions scripts/build-sentry-cocoa.sh
Original file line number Diff line number Diff line change
@@ -1,67 +1,73 @@
#!/bin/bash
set -euo pipefail

pushd "$(dirname "$0")" > /dev/null
pushd "$(dirname "$0")" >/dev/null
cd ../modules/sentry-cocoa

if [ $? -eq 0 ]
then
SHA=$(git rev-parse HEAD)
SHAFILE=./Carthage/.built-from-sha
[ -f $SHAFILE ] && SHAFROMFILE=$(<$SHAFILE)
VERSION="$(git describe --tags) ($(git rev-parse --short HEAD))"
rm -rf Carthage

if [ "$SHA" == "$SHAFROMFILE" ]; then
echo "Sentry Cocoa SDK $VERSION was already built"
else
echo "Building Sentry Cocoa SDK $VERSION"
rm -rf Carthage
# Grabbing the first SDK versions
sdks=$(xcodebuild -showsdks)
ios_sdk=$(echo "$sdks" | awk '/iOS SDKs/{getline; print $NF}')
ios_simulator_sdk=$(echo "$sdks" | awk '/iOS Simulator SDKs/{getline; print $NF}')
macos_sdk=$(echo "$sdks" | awk '/macOS SDKs/{getline; print $NF}')

# Grabbing the first SDK versions
sdks=$(xcodebuild -showsdks)
ios_sdk=$(echo "$sdks" | awk '/iOS SDKs/{getline; print $NF}')
ios_simulator_sdk=$(echo "$sdks" | awk '/iOS Simulator SDKs/{getline; print $NF}')
# Note - We keep the build output in separate directories so that .NET
# bundles iOS with net6.0-ios and Mac Catalyst with net6.0-maccatalyst.
# The lack of symlinks in the ios builds, means we should also be able
# to use the package on Windows with "Pair to Mac".

# Note - We keep the build output in separate directories so that .NET
# bundles iOS with net6.0-ios and Mac Catalyst with net6.0-maccatalyst.
# The lack of symlinks in the ios builds, means we should also be able
# to use the package on Windows with "Pair to Mac".
# Build for iOS and iOS simulator.
echo "::group::Building sentry-cocoa for iOS and iOS simulator"
xcodebuild -project Sentry.xcodeproj \
-scheme Sentry \
-configuration Release \
-sdk "$ios_sdk" \
-derivedDataPath ./Carthage/output-ios
xcodebuild -project Sentry.xcodeproj \
-scheme Sentry \
-configuration Release \
-sdk "$ios_simulator_sdk" \
-derivedDataPath ./Carthage/output-ios
xcodebuild -create-xcframework \
-framework ./Carthage/output-ios/Build/Products/Release-iphoneos/Sentry.framework \
-framework ./Carthage/output-ios/Build/Products/Release-iphonesimulator/Sentry.framework \
-output ./Carthage/Build-ios/Sentry.xcframework
echo "::endgroup::"

# Build for iOS and iOS simulator.
xcodebuild -project Sentry.xcodeproj \
-scheme Sentry \
-configuration Release \
-sdk "$ios_sdk" \
-derivedDataPath ./Carthage/output-ios
xcodebuild -project Sentry.xcodeproj \
-scheme Sentry \
-configuration Release \
-sdk "$ios_simulator_sdk" \
-derivedDataPath ./Carthage/output-ios
xcodebuild -create-xcframework \
-framework ./Carthage/output-ios/Build/Products/Release-iphoneos/Sentry.framework \
-framework ./Carthage/output-ios/Build/Products/Release-iphonesimulator/Sentry.framework \
-output ./Carthage/Build-ios/Sentry.xcframework
# Build for macOS.
echo "::group::Building sentry-cocoa for macOS"
xcodebuild -project Sentry.xcodeproj \
-scheme Sentry \
-configuration Release \
-sdk "$macos_sdk" \
-derivedDataPath ./Carthage/output-macos
xcodebuild -create-xcframework \
-framework ./Carthage/output-macos/Build/Products/Release/Sentry.framework \
-output ./Carthage/Build-macos/Sentry.xcframework
echo "::endgroup::"

# Separately, build for Mac Catalyst
xcodebuild -project Sentry.xcodeproj \
-scheme Sentry \
-configuration Release \
-destination 'platform=macOS,variant=Mac Catalyst' \
-derivedDataPath ./Carthage/output-maccatalyst
xcodebuild -create-xcframework \
-framework ./Carthage/output-maccatalyst/Build/Products/Release-maccatalyst/Sentry.framework \
-output ./Carthage/Build-maccatalyst/Sentry.xcframework
# Separately, build for Mac Catalyst
echo "::group::Building sentry-cocoa for Mac Catalyst"
xcodebuild -project Sentry.xcodeproj \
-scheme Sentry \
-configuration Release \
-destination 'platform=macOS,variant=Mac Catalyst' \
-derivedDataPath ./Carthage/output-maccatalyst
xcodebuild -create-xcframework \
-framework ./Carthage/output-maccatalyst/Build/Products/Release-maccatalyst/Sentry.framework \
-output ./Carthage/Build-maccatalyst/Sentry.xcframework
echo "::endgroup::"

# Copy headers - used for generating bindings
mkdir Carthage/Headers
find Carthage/Build-ios/Sentry.xcframework/ios-arm64 -name '*.h' -exec cp {} Carthage/Headers \;
# Copy headers - used for generating bindings
mkdir Carthage/Headers
find Carthage/Build-ios/Sentry.xcframework/ios-arm64 -name '*.h' -exec cp {} Carthage/Headers \;

echo "$SHA" > "$SHAFILE"
echo ""
fi
# Remove anything we don't want to bundle in the nuget package.
find Carthage/Build* \( -name Headers -o -name PrivateHeaders -o -name Modules \) -exec rm -rf {} +
rm -rf Carthage/output-*

# Remove anything we don't want to bundle in the nuget package.
find Carthage/Build* \( -name Headers -o -name PrivateHeaders -o -name Modules \) -exec rm -rf {} +
fi
cp ../../.git/modules/modules/sentry-cocoa/HEAD Carthage/.built-from-sha
echo ""

popd > /dev/null
popd >/dev/null
11 changes: 6 additions & 5 deletions src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks Condition="'$(NO_IOS)' == '' And '$(NO_MACCATALYST)' == ''">net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="'$(NO_IOS)' == '' And '$(NO_MACCATALYST)' == 'true'">net7.0-ios</TargetFrameworks>
<TargetFrameworks Condition="'$(NO_IOS)' == 'true' And '$(NO_MACCATALYST)' == ''">net7.0-maccatalyst</TargetFrameworks>
<TargetFrameworks>net7.0-macos</TargetFrameworks>
<TargetFrameworks Condition="'$(NO_IOS)' == ''">$(TargetFrameworks);net7.0-ios</TargetFrameworks>
<TargetFrameworks Condition="'$(NO_MACCATALYST)' == ''">$(TargetFrameworks);net7.0-maccatalyst</TargetFrameworks>
<IsBindingProject>true</IsBindingProject>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<Description>.NET Bindings for the Sentry Cocoa SDK</Description>
Expand Down Expand Up @@ -46,16 +46,17 @@

<!-- Build the Sentry Cocoa SDK -->
<Target Name="_BuildSentryCocoaSDK" BeforeTargets="DispatchToInnerBuilds;BeforeBuild" Condition="$([MSBuild]::IsOSPlatform('OSX'))"
Inputs="..\..\.git\modules\modules\sentry-cocoa\HEAD" Outputs="..\..\modules\sentry-cocoa\Carthage\.built-from-sha">
Inputs="../../.git/modules/modules/sentry-cocoa/HEAD" Outputs="../../modules/sentry-cocoa/Carthage/.built-from-sha">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="_InnerBuildSentryCocoaSDK" Properties="TargetFramework=once" />
</Target>
<Target Name="_InnerBuildSentryCocoaSDK">
<Exec Command="../../scripts/build-sentry-cocoa.sh" />
<Copy SourceFiles="../../.git/modules/modules/sentry-cocoa/HEAD" DestinationFolder="../../modules/sentry-cocoa/Carthage/.built-from-sha"/>
</Target>

<!-- Generate bindings -->
<Target Name="_GenerateSentryCocoaBindings" AfterTargets="_BuildSentryCocoaSDK" Condition="$([MSBuild]::IsOSPlatform('OSX'))"
Inputs="..\..\modules\sentry-cocoa\Carthage\.built-from-sha" Outputs="ApiDefinitions.cs;StructsAndEnums.cs">
Inputs="../../modules/sentry-cocoa/Carthage/.built-from-sha" Outputs="ApiDefinitions.cs;StructsAndEnums.cs">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="_InnerGenerateSentryCocoaBindings" Properties="TargetFramework=once" />
</Target>
<Target Name="_InnerGenerateSentryCocoaBindings">
Expand Down
2 changes: 1 addition & 1 deletion src/Sentry/CrashType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public enum CrashType
JavaBackgroundThread,
#endif

#if __MOBILE__
#if __MOBILE__ || MACOS
/// <summary>
/// A native operation that will crash the application will be performed by a C library.
/// </summary>
Expand Down
12 changes: 10 additions & 2 deletions src/Sentry/Internal/DebugStackTrace.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using Sentry.Internal.Extensions;
using Sentry.Extensibility;
using Sentry.Internal.ILSpy;
#if SENTRY_NATIVE
using Sentry.Native;
#endif

namespace Sentry.Internal;

Expand Down Expand Up @@ -229,7 +231,7 @@ private IEnumerable<SentryStackFrame> CreateFrames(StackTrace stackTrace, bool i

/// <summary>
/// Native AOT implementation of CreateFrame.
/// Native frames have only limited method information at runtime (and even that can be disabled).
/// Native frames have only limited method information at runtime (and even that can be disabled).
/// We try to parse that and also add addresses for server-side symbolication.
/// </summary>
private SentryStackFrame? TryCreateNativeAOTFrame(IStackFrame stackFrame)
Expand All @@ -244,7 +246,13 @@ private IEnumerable<SentryStackFrame> CreateFrames(StackTrace stackTrace, bool i
frame.ImageAddress = imageAddress;
frame.InstructionAddress = stackFrame.GetNativeIP();

#if SENTRY_NATIVE
_nativeDebugImages ??= C.LoadDebugImages(_options.DiagnosticLogger);
#elif MACOS
_nativeDebugImages ??= SentrySdk.LoadDebugImages(_options.DiagnosticLogger);
#else
_nativeDebugImages ??= new();
#endif
if (!_usedNativeDebugImages.Contains(imageAddress) && _nativeDebugImages.TryGetValue(imageAddress, out var debugImage))
{
_usedNativeDebugImages.Add(imageAddress);
Expand All @@ -255,7 +263,7 @@ private IEnumerable<SentryStackFrame> CreateFrames(StackTrace stackTrace, bool i
}

// Method info is currently only exposed by ToString(), see https://github.com/dotnet/runtime/issues/92869
// We only care about the case where the method is available (`StackTraceSupport` property is the default `true`):
// We only care about the case where the method is available (`StackTraceSupport` property is the default `true`):
// https://github.com/dotnet/runtime/blob/254230253da143a082f47cfaf8711627c0bf2faf/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/DeveloperExperience/DeveloperExperience.cs#L42
internal static SentryStackFrame ParseNativeAOTToString(string info)
{
Expand Down
15 changes: 15 additions & 0 deletions src/Sentry/Internal/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,19 @@ public static string ToSnakeCase(this string str) =>
/// Otherwise, returns <paramref name="str"/>.
/// </summary>
public static string? NullIfWhitespace(this string? str) => string.IsNullOrWhiteSpace(str) ? null : str;

public static long ParseHexAsLong(this string str)
{
// It should be in hex format, such as "0x7fff5bf346c0"
if (str.StartsWith("0x") &&
long.TryParse(str[2..], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))
{
return result;
}
else if (long.TryParse(str, NumberStyles.Number, CultureInfo.InvariantCulture, out result))
{
return result;
}
throw new FormatException($"ParseHexAsLong() cannot parse '{str}'");
}
}
Loading