Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- The `EnableMetrics` option is now marked as `[Obsolete]` and no longer has any effect, following the .NET SDK where metrics are always enabled. Disable the individual `Auto*Metrics` options instead, or filter emitted metrics with `SetBeforeSendMetric`. ([#2828](https://github.com/getsentry/sentry-unity/pull/2828))

### Features

- Added Nintendo Switch 2 support. The SDK now recognises the platform, links the Switch 2 build of the native library from `Assets/Plugins/Sentry/Switch2/`, and uploads its debug symbols. Switch 2 shares the existing `SwitchNativeSupportEnabled` option ([#2834](https://github.com/getsentry/sentry-unity/pull/2834))
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated

### Fixes

- IL2CPP line numbers now work on Android x86/x86_64 builds. il2cpp fails to report the image UUID there, so the SDK falls back to looking the debug image up by name ([#2817](https://github.com/getsentry/sentry-unity/pull/2817))
Expand Down
4 changes: 4 additions & 0 deletions package-dev/Plugins/Switch/sentry_native_stubs.c.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package-dev/Runtime/Sentry.Unity.Native.Switch.dll.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package-dev/Runtime/SentryInitialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#define SENTRY_NATIVE_SWITCH
#endif

#if UNITY_SWITCH2
#define SENTRY_NATIVE_SWITCH2
#endif

#if UNITY_WEBGL
#define SENTRY_WEBGL
#endif
Expand All @@ -45,7 +49,7 @@
using Sentry.Unity.iOS;
#elif SENTRY_NATIVE_ANDROID
using Sentry.Unity.Android;
#elif SENTRY_NATIVE || SENTRY_NATIVE_SWITCH
#elif SENTRY_NATIVE || SENTRY_NATIVE_SWITCH || SENTRY_NATIVE_SWITCH2
using Sentry.Unity.Native;
#elif SENTRY_WEBGL
using Sentry.Unity.WebGL;
Expand Down Expand Up @@ -108,7 +112,7 @@ private static void SetUpPlatformServices()
SentryPlatformServices.PlatformConfiguration = SentryNativeCocoa.Configure;
#elif SENTRY_NATIVE_ANDROID
SentryPlatformServices.PlatformConfiguration = SentryNativeAndroid.Configure;
#elif SENTRY_NATIVE_SWITCH
#elif SENTRY_NATIVE_SWITCH || SENTRY_NATIVE_SWITCH2
SentryPlatformServices.PlatformConfiguration = SentryNativeSwitch.Configure;
#elif SENTRY_NATIVE
SentryPlatformServices.PlatformConfiguration = SentryNative.Configure;
Expand Down
1 change: 1 addition & 0 deletions package-dev/Runtime/io.sentry.unity.dev.runtime.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"LinuxStandalone64",
"macOSStandalone",
"Switch",
"Switch2",
"PS5",
"WSA",
"WebGL",
Expand Down
1 change: 1 addition & 0 deletions package/Runtime/io.sentry.unity.runtime.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"macOSStandalone",
"PS5",
"Switch",
"Switch2",
"WSA",
"WebGL",
"WindowsStandalone32",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ internal static void Display(ScriptableSentryUnityOptions options, SentryCliOpti
options.PlayStationNativeSupportEnabled);

options.SwitchNativeSupportEnabled = EditorGUILayout.Toggle(
new GUIContent("Nintendo Switch", "Whether to enable native scope sync support on Nintendo Switch."),
new GUIContent("Nintendo Switch", "Whether to enable native scope sync support on Nintendo Switch and Switch 2."),
options.SwitchNativeSupportEnabled);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.IO;
using System.Linq;
using Sentry.Extensibility;
Expand All @@ -21,32 +22,57 @@ namespace Sentry.Unity.Editor.Native;
/// </remarks>
internal class SwitchNativePluginBuildPreProcess : IPreprocessBuildWithReport
{
private static readonly string[] RequiredFiles =
/// <summary>
/// <c>BuildTarget.Switch2</c> only exists in Unity 6000.3 and newer, and this assembly is
/// compiled against a single Unity version, so the target is matched by name. The build report
/// hands us the value itself, so the enum member never has to be referenced.
Comment thread
sentry[bot] marked this conversation as resolved.
Outdated
/// </summary>
internal const string Switch2BuildTargetName = "Switch2";

private static bool IsSwitchFamily(BuildTarget target) =>
target == BuildTarget.Switch || IsSwitch2(target);

private static bool IsSwitch2(BuildTarget target) =>
string.Equals(target.ToString(), Switch2BuildTargetName, StringComparison.Ordinal);

/// <summary>
/// Both platforms share one stub, so the required libraries are what differ between them.
/// </summary>
private static string[] RequiredFilesFor(BuildTarget target)
{
"Assets/Plugins/Sentry/Switch/libsentry.a",
"Assets/Plugins/Sentry/Switch/libzstd.a",
};
var directory = IsSwitch2(target) ? Switch2BuildTargetName : nameof(BuildTarget.Switch);
return new[]
{
$"Assets/Plugins/Sentry/{directory}/libsentry.a",
$"Assets/Plugins/Sentry/{directory}/libzstd.a",
};
}

public int callbackOrder => -100;

public void OnPreprocessBuild(BuildReport report)
{
if (report.summary.platform != BuildTarget.Switch)
if (!IsSwitchFamily(report.summary.platform))
{
return;
}

var options = SentryScriptableObject.LoadOptions(isBuilding: true);
var logger = options?.DiagnosticLogger ?? new UnityLogger(new SentryUnityOptions());

ConfigureStub(logger, options?.SwitchNativeSupportEnabled ?? false);
// Switch 2 reuses the Switch implementation and therefore its option.
ConfigureStub(logger, options?.SwitchNativeSupportEnabled ?? false, report.summary.platform);
}

internal static void ConfigureStub(IDiagnosticLogger logger, bool nativeSupportEnabled)
internal static void ConfigureStub(IDiagnosticLogger logger, bool nativeSupportEnabled, BuildTarget target)
{
logger.LogDebug("Switch native support: checking for required files:\n{0}",
string.Join("\n", RequiredFiles.Select(f => $" - {f}")));
var requiredFiles = RequiredFilesFor(target);

logger.LogDebug("{0} native support: checking for required files:\n{1}",
target, string.Join("\n", requiredFiles.Select(f => $" - {f}")));

// One stub serves both platforms; the importer tracks compatibility per build target, so
// enabling it for one does not affect the other.
var stubPath = Path.Combine("Packages", SentryPackageInfo.GetName(), "Plugins", "Switch", "sentry_native_stubs.c");

var importer = AssetImporter.GetAtPath(stubPath) as PluginImporter;
Expand All @@ -56,14 +82,16 @@ internal static void ConfigureStub(IDiagnosticLogger logger, bool nativeSupportE
return;
}

var existingFiles = RequiredFiles.Where(File.Exists).ToList();
var missingFiles = RequiredFiles.Except(existingFiles).ToList();
var existingFiles = requiredFiles.Where(File.Exists).ToList();
var missingFiles = requiredFiles.Except(existingFiles).ToList();

var someFilesPresent = existingFiles.Count > 0 && missingFiles.Count > 0;
if (someFilesPresent)
{
// LogError has no two-argument overload that does not also take an exception, so the
// target goes into the format string rather than being passed alongside the file list.
logger.LogError(
"Switch native support is partially configured. Missing files:\n{0}\n" +
target + " native support is partially configured. Missing files:\n{0}\n" +
"Please add all required files to enable native support, or remove all files to fall back on no-op stubs.\n" +
"Build sentry-switch and copy the libraries to the expected locations. " +
"See: https://github.com/getsentry/sentry-switch",
Expand All @@ -75,26 +103,26 @@ internal static void ConfigureStub(IDiagnosticLogger logger, bool nativeSupportE
var allFilesPresent = missingFiles.Count == 0;
if (allFilesPresent)
{
logger.LogInfo("Switch native libraries found:\n{0}",
string.Join("\n", existingFiles.Select(f => $" - {f}")));
importer.SetCompatibleWithPlatform(BuildTarget.Switch, false);
logger.LogInfo("{0} native libraries found:\n{1}",
target, string.Join("\n", existingFiles.Select(f => $" - {f}")));
importer.SetCompatibleWithPlatform(target, false);
}
else
{
if (nativeSupportEnabled)
{
logger.LogWarning(
"Switch native support is enabled but required files are missing:\n{0}\n" +
"{0} native support is enabled but required files are missing:\n{1}\n" +
"Build sentry-switch and copy the libraries to the expected locations. " +
"See: https://github.com/getsentry/sentry-switch",
string.Join("\n", missingFiles.Select(f => $" - {f}"))
target, string.Join("\n", missingFiles.Select(f => $" - {f}"))
);
}
else
{
logger.LogDebug("Switch native support is disabled. Enabling stubs (native calls will be no-op).");
logger.LogDebug("{0} native support is disabled. Enabling stubs (native calls will be no-op).", target);
}
importer.SetCompatibleWithPlatform(BuildTarget.Switch, true);
importer.SetCompatibleWithPlatform(target, true);
}

importer.SaveAndReimport();
Expand Down
1 change: 1 addition & 0 deletions src/Sentry.Unity/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[assembly: InternalsVisibleTo("Sentry.Unity.Native")]
[assembly: InternalsVisibleTo("Sentry.Unity.Native.PlayStation")]
[assembly: InternalsVisibleTo("Sentry.Unity.Native.Switch")]
[assembly: InternalsVisibleTo("Sentry.Unity.Native.Switch2")]
[assembly: InternalsVisibleTo("Sentry.Unity.Native.Xbox")]
[assembly: InternalsVisibleTo("Sentry.Unity.Tests")]
[assembly: InternalsVisibleTo("Sentry.Unity.Editor")]
Expand Down
18 changes: 18 additions & 0 deletions src/Sentry.Unity/SentryUnityOptionsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,27 @@ internal static bool IsValid(this SentryUnityOptions options)
return true;
}

/// <summary>
/// <c>RuntimePlatform.Switch2</c> was only added in Unity 6000.3. This assembly is compiled
/// against a single Unity version while the SDK still supports 2021.3, so Switch 2 is matched
/// by name instead of by enum member - referencing the member directly would stop the SDK from
/// building against the editors that predate it.
/// </summary>
internal const string Switch2PlatformName = "Switch2";

internal static bool IsSwitch2(this RuntimePlatform platform) =>
string.Equals(platform.ToString(), Switch2PlatformName, StringComparison.Ordinal);

internal static bool IsNativeSupportEnabled(this SentryUnityOptions options, RuntimePlatform? platform = null)
{
platform ??= ApplicationAdapter.Instance.Platform;

// Switch 2 reuses the Switch native support, and therefore its option.
if (platform.Value.IsSwitch2())
{
return options.SwitchNativeSupportEnabled;
}

return platform switch
{
RuntimePlatform.Android => options.AndroidNativeSupportEnabled,
Expand Down
31 changes: 31 additions & 0 deletions test/Sentry.Unity.Tests/SentryUnityOptionsExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Linq;
using NUnit.Framework;
using Sentry.Unity.Tests.Stubs;
Expand Down Expand Up @@ -207,4 +208,34 @@ public void IsNativeSupportEnabled_ConsolePlatforms_ReturnsExpectedValue(

Assert.AreEqual(expectedResult, result);
}

/// <summary>
/// Switch 2 shares the Switch option. It is resolved by name because
/// <c>RuntimePlatform.Switch2</c> does not exist on the Unity versions the SDK still supports,
/// so this parses the member instead of referencing it and skips where it is unavailable.
/// </summary>
[Test]
[TestCase(true, true)]
[TestCase(false, false)]
public void IsNativeSupportEnabled_Switch2_FollowsSwitchOption(bool optionEnabled, bool expectedResult)
{
if (!Enum.TryParse<RuntimePlatform>(
SentryUnityOptionsExtensions.Switch2PlatformName, out var switch2))
{
Assert.Ignore("This Unity version predates 'RuntimePlatform.Switch2'.");
}

var options = _fixture.GetSut();
options.SwitchNativeSupportEnabled = optionEnabled;

Assert.AreEqual(expectedResult, options.IsNativeSupportEnabled(switch2));
}

[Test]
public void IsSwitch2_OtherPlatforms_ReturnsFalse()
{
Assert.IsFalse(RuntimePlatform.Switch.IsSwitch2());
Assert.IsFalse(RuntimePlatform.PS5.IsSwitch2());
Assert.IsFalse(RuntimePlatform.WindowsPlayer.IsSwitch2());
}
}
Loading