Skip to content

Commit 34f1204

Browse files
committed
building playbackengine
1 parent 023d178 commit 34f1204

File tree

8 files changed

+255
-60
lines changed

8 files changed

+255
-60
lines changed

src/Sentry.Unity.Editor.iOS/BuildPostProcess.cs

+2-46
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ public static void OnPostProcessBuild(BuildTarget target, string pathToProject)
2525
// Unity doesn't allow an appending builds when switching iOS SDK versions and this will make sure we always copy the correct version of the Sentry.framework
2626
var frameworkDirectory = PlayerSettings.iOS.sdkVersion == iOSSdkVersion.DeviceSDK ? "Device" : "Simulator";
2727
var frameworkPath = Path.GetFullPath(Path.Combine("Packages", SentryPackageInfo.GetName(), "Plugins", "iOS", frameworkDirectory, "Sentry.framework"));
28-
CopyFramework(frameworkPath, Path.Combine(pathToProject, "Frameworks", "Sentry.framework"), options?.DiagnosticLogger);
28+
EditorFileIO.CopyDirectory(frameworkPath, Path.Combine(pathToProject, "Frameworks", "Sentry.framework"), options?.DiagnosticLogger);
2929

3030
var nativeBridgePath = Path.GetFullPath(Path.Combine("Packages", SentryPackageInfo.GetName(), "Plugins", "iOS", "SentryNativeBridge.m"));
31-
CopyFile(nativeBridgePath, Path.Combine(pathToProject, "Libraries", SentryPackageInfo.GetName(), "SentryNativeBridge.m"), options?.DiagnosticLogger);
31+
EditorFileIO.CopyFile(nativeBridgePath, Path.Combine(pathToProject, "Libraries", SentryPackageInfo.GetName(), "SentryNativeBridge.m"), options?.DiagnosticLogger);
3232

3333
using var sentryXcodeProject = SentryXcodeProject.Open(pathToProject);
3434
sentryXcodeProject.AddSentryFramework();
@@ -62,49 +62,5 @@ public static void OnPostProcessBuild(BuildTarget target, string pathToProject)
6262
logger.LogError("Failed to add the Sentry framework to the generated Xcode project", e);
6363
}
6464
}
65-
66-
internal static void CopyFramework(string sourcePath, string targetPath, IDiagnosticLogger? logger)
67-
{
68-
if (Directory.Exists(targetPath))
69-
{
70-
logger?.LogDebug("'{0}' has already been copied to '{1}'", Path.GetFileName(targetPath), targetPath);
71-
return;
72-
}
73-
74-
if (Directory.Exists(sourcePath))
75-
{
76-
logger?.LogDebug("Copying from: '{0}' to '{1}'", sourcePath, targetPath);
77-
78-
Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(targetPath)));
79-
FileUtil.CopyFileOrDirectory(sourcePath, targetPath);
80-
}
81-
82-
if (!Directory.Exists(targetPath))
83-
{
84-
throw new DirectoryNotFoundException($"Failed to copy '{sourcePath}' to '{targetPath}'");
85-
}
86-
}
87-
88-
internal static void CopyFile(string sourcePath, string targetPath, IDiagnosticLogger? logger)
89-
{
90-
if (File.Exists(targetPath))
91-
{
92-
logger?.LogDebug("'{0}' has already been copied to '{1}'", Path.GetFileName(targetPath), targetPath);
93-
return;
94-
}
95-
96-
if (File.Exists(sourcePath))
97-
{
98-
logger?.LogDebug("Copying from: '{0}' to '{1}'", sourcePath, targetPath);
99-
100-
Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(targetPath)));
101-
FileUtil.CopyFileOrDirectory(sourcePath, targetPath);
102-
}
103-
104-
if (!File.Exists(targetPath))
105-
{
106-
throw new FileNotFoundException($"Failed to copy '{sourcePath}' to '{targetPath}'");
107-
}
108-
}
10965
}
11066
}
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System.IO;
2+
using Sentry.Extensibility;
3+
using UnityEditor;
4+
5+
namespace Sentry.Unity.Editor
6+
{
7+
internal static class EditorFileIO
8+
{
9+
internal static void CopyDirectory(string sourcePath, string targetPath, IDiagnosticLogger? logger)
10+
{
11+
if (Directory.Exists(targetPath))
12+
{
13+
logger?.LogDebug("'{0}' already already exists.", targetPath);
14+
return;
15+
}
16+
17+
if (Directory.Exists(sourcePath))
18+
{
19+
logger?.LogDebug("Copying from: '{0}' to '{1}'", sourcePath, targetPath);
20+
21+
Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(targetPath)));
22+
FileUtil.CopyFileOrDirectory(sourcePath, targetPath);
23+
}
24+
25+
if (!Directory.Exists(targetPath))
26+
{
27+
throw new DirectoryNotFoundException($"Failed to copy '{sourcePath}' to '{targetPath}'");
28+
}
29+
}
30+
31+
internal static void CopyFile(string sourcePath, string targetPath, IDiagnosticLogger? logger)
32+
{
33+
if (File.Exists(targetPath))
34+
{
35+
logger?.LogDebug("'{0}' has already been copied to '{1}'", Path.GetFileName(targetPath), targetPath);
36+
return;
37+
}
38+
39+
if (File.Exists(sourcePath))
40+
{
41+
logger?.LogDebug("Copying from: '{0}' to '{1}'", sourcePath, targetPath);
42+
43+
Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(targetPath)));
44+
FileUtil.CopyFileOrDirectory(sourcePath, targetPath);
45+
}
46+
47+
if (!File.Exists(targetPath))
48+
{
49+
throw new FileNotFoundException($"Failed to copy '{sourcePath}' to '{targetPath}'");
50+
}
51+
}
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using UnityEditor;
2+
3+
namespace Sentry.Unity.Editor
4+
{
5+
internal interface IEditorApplication
6+
{
7+
string ApplicationContentsPath { get; }
8+
EditorApplication.CallbackFunction Update { get; set; }
9+
}
10+
11+
internal sealed class EditorApplicationAdapter : IEditorApplication
12+
{
13+
public static readonly EditorApplicationAdapter Instance = new();
14+
15+
public string ApplicationContentsPath => EditorApplication.applicationContentsPath;
16+
17+
public EditorApplication.CallbackFunction Update
18+
{
19+
get => EditorApplication.update;
20+
set => EditorApplication.update = value;
21+
}
22+
}
23+
}

src/Sentry.Unity.Editor/Native/BuildPostProcess.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Sentry.Unity.Editor.Native
1111
public static class BuildPostProcess
1212
{
1313
[PostProcessBuild(1)]
14-
public static void OnPostProcessBuild(BuildTarget target, string executablePath)
14+
internal static void OnPostProcessBuild(BuildTarget target, string executablePath)
1515
{
1616
if (target is not (BuildTarget.StandaloneWindows or BuildTarget.StandaloneWindows64))
1717
{
@@ -25,7 +25,7 @@ public static void OnPostProcessBuild(BuildTarget target, string executablePath)
2525
{
2626
if (PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup) != ScriptingImplementation.IL2CPP)
2727
{
28-
logger.LogWarning("Failed to enable Native support - only availabile with IL2CPP scripting backend.");
28+
logger.LogWarning("Failed to enable Native support - only available with IL2CPP scripting backend.");
2929
return;
3030
}
3131

@@ -41,10 +41,11 @@ public static void OnPostProcessBuild(BuildTarget target, string executablePath)
4141
return;
4242
}
4343

44+
SentryWindowsPlayer.Build(options, executablePath);
45+
4446
var projectDir = Path.GetDirectoryName(executablePath);
4547
AddCrashHandler(logger, projectDir);
4648
UploadDebugSymbols(logger, projectDir, Path.GetFileName(executablePath));
47-
4849
}
4950
catch (Exception e)
5051
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using System;
2+
using System.Diagnostics;
3+
using System.IO;
4+
using Sentry.Extensibility;
5+
using UnityEditor;
6+
using UnityEngine;
7+
using Debug = UnityEngine.Debug;
8+
9+
namespace Sentry.Unity.Editor.Native
10+
{
11+
internal static class SentryWindowsPlayer
12+
{
13+
internal static readonly ProcessStartInfo StartInfo = new()
14+
{
15+
UseShellExecute = false,
16+
RedirectStandardOutput = true,
17+
RedirectStandardError = true,
18+
CreateNoWindow = true
19+
};
20+
21+
internal static void AddNativeOptions(SentryUnityOptions options)
22+
{
23+
}
24+
25+
internal static void AddSentryToMain(SentryUnityOptions options)
26+
{
27+
}
28+
29+
internal static string LocateWindowsPlayerSource(IEditorApplication? editorApplication = null)
30+
{
31+
editorApplication ??= EditorApplicationAdapter.Instance;
32+
33+
var playerProjectPath = Path.Combine(editorApplication.ApplicationContentsPath, "PlaybackEngines", "windowsstandalonesupport", "source", "windowsplayer");
34+
if (!Directory.Exists(playerProjectPath))
35+
{
36+
throw new DirectoryNotFoundException($"Failed to locate the WindowsPlayer source at {playerProjectPath}.");
37+
}
38+
39+
return playerProjectPath;
40+
}
41+
42+
internal static void CreateWindowsPlayerProject(string windowsPlayerSource, string windowsPlayerTarget, IDiagnosticLogger? logger)
43+
{
44+
EditorFileIO.CopyDirectory(windowsPlayerSource, windowsPlayerTarget, logger);
45+
46+
// TODO: Does the .props file have to look like that?
47+
using var props = File.CreateText(Path.Combine(windowsPlayerTarget, "UnityCommon.props"));
48+
props.Write(@"<?xml version=""1.0"" encoding=""utf-8""?>
49+
<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
50+
</Project>");
51+
}
52+
53+
internal static string LocateMSBuild(string vsWherePath, IDiagnosticLogger? logger)
54+
{
55+
StartInfo.FileName = vsWherePath;
56+
StartInfo.Arguments = "-latest -requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe";
57+
58+
var vsWhereOutput = "";
59+
var process = new Process {StartInfo = StartInfo};
60+
process.OutputDataReceived += (sender, args) => vsWhereOutput += args.Data;
61+
process.Start();
62+
process.BeginOutputReadLine();
63+
process.BeginErrorReadLine();
64+
process.WaitForExit();
65+
66+
logger?.LogDebug("VSWhere returned with: {0}", vsWhereOutput);
67+
68+
if (!File.Exists(vsWhereOutput))
69+
{
70+
throw new FileNotFoundException($"Failed to locate 'msbuild'. VSWhere returned {vsWhereOutput}");
71+
}
72+
73+
return vsWhereOutput;
74+
}
75+
76+
internal static string LocateVSWhere(IDiagnosticLogger? logger)
77+
{
78+
var projectPath = Path.GetDirectoryName(Application.dataPath);
79+
var directories = Directory.GetDirectories(Path.Combine(projectPath, "Library", "PackageCache"), "com.unity.ide.visualstudio@*");
80+
if (directories is null || directories.Length < 1)
81+
{
82+
throw new Exception("Failed lo locate the 'com.unity.ide.visualstudio' package.");
83+
}
84+
85+
// TODO: Not sure if there can be more than one version of a package in the Library/PackageCache and if it even matters
86+
var vsPackagePath = directories[0];
87+
logger?.LogDebug("Located 'com.unity.ide.visualstudio' package at {0}", vsPackagePath);
88+
89+
var vsWherePath = Path.Combine(vsPackagePath, "Editor", "VSWhere", "vswhere.exe");
90+
if (!File.Exists(vsWherePath))
91+
{
92+
throw new FileNotFoundException($"Failed to find 'vswhere.exe' at '{vsWherePath}'");
93+
}
94+
95+
return vsWherePath;
96+
}
97+
98+
public static void Build(SentryUnityOptions options, string executablePath)
99+
{
100+
var vsWherePath = LocateVSWhere(options.DiagnosticLogger);
101+
var msBuildPath = LocateMSBuild(vsWherePath, options.DiagnosticLogger);
102+
103+
var playerSource = LocateWindowsPlayerSource();
104+
var playerTarget = FileUtil.GetUniqueTempPathInProject();
105+
106+
CreateWindowsPlayerProject(playerSource, playerTarget, options.DiagnosticLogger);
107+
108+
AddNativeOptions(options);
109+
AddSentryToMain(options);
110+
111+
StartInfo.FileName = msBuildPath;
112+
StartInfo.Arguments = playerTarget;
113+
114+
var outputData = "";
115+
var errorData = "";
116+
var process = new Process {StartInfo = StartInfo};
117+
process.OutputDataReceived += (sender, args) => outputData += args.Data;
118+
process.ErrorDataReceived += (sender, args) => errorData += args.Data;
119+
process.Start();
120+
process.BeginOutputReadLine();
121+
process.BeginErrorReadLine();
122+
process.WaitForExit();
123+
124+
if (outputData.Contains("Build succeeded"))
125+
{
126+
options.DiagnosticLogger?.LogDebug("Succeeded building the PlaybackEngine");
127+
}
128+
else if (outputData.Contains("Build failed"))
129+
{
130+
throw new Exception($"Failed to build the PlaybackEngine: \n {outputData}");
131+
}
132+
133+
var logFile = Path.Combine(playerTarget, "build.log");
134+
File.WriteAllText(logFile, outputData);
135+
File.AppendAllText(logFile, errorData);
136+
137+
// TODO: Overwrite the executable with the build output
138+
}
139+
}
140+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using UnityEditor;
2+
3+
namespace Sentry.Unity.Editor.Native
4+
{
5+
public static class Temp
6+
{
7+
[MenuItem("Tools/ClickMe")]
8+
public static void ClickMe()
9+
{
10+
var options = new SentryUnityOptions() {Debug = true, DiagnosticLevel = SentryLevel.Debug,};
11+
options.DiagnosticLogger = new UnityLogger(options);
12+
SentryWindowsPlayer.Build(options, "");
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)