Skip to content

Commit

Permalink
building playbackengine
Browse files Browse the repository at this point in the history
  • Loading branch information
bitsandfoxes committed Mar 9, 2022
1 parent 023d178 commit 34f1204
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 60 deletions.
48 changes: 2 additions & 46 deletions src/Sentry.Unity.Editor.iOS/BuildPostProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ public static void OnPostProcessBuild(BuildTarget target, string pathToProject)
// 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
var frameworkDirectory = PlayerSettings.iOS.sdkVersion == iOSSdkVersion.DeviceSDK ? "Device" : "Simulator";
var frameworkPath = Path.GetFullPath(Path.Combine("Packages", SentryPackageInfo.GetName(), "Plugins", "iOS", frameworkDirectory, "Sentry.framework"));
CopyFramework(frameworkPath, Path.Combine(pathToProject, "Frameworks", "Sentry.framework"), options?.DiagnosticLogger);
EditorFileIO.CopyDirectory(frameworkPath, Path.Combine(pathToProject, "Frameworks", "Sentry.framework"), options?.DiagnosticLogger);

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

using var sentryXcodeProject = SentryXcodeProject.Open(pathToProject);
sentryXcodeProject.AddSentryFramework();
Expand Down Expand Up @@ -62,49 +62,5 @@ public static void OnPostProcessBuild(BuildTarget target, string pathToProject)
logger.LogError("Failed to add the Sentry framework to the generated Xcode project", e);
}
}

internal static void CopyFramework(string sourcePath, string targetPath, IDiagnosticLogger? logger)
{
if (Directory.Exists(targetPath))
{
logger?.LogDebug("'{0}' has already been copied to '{1}'", Path.GetFileName(targetPath), targetPath);
return;
}

if (Directory.Exists(sourcePath))
{
logger?.LogDebug("Copying from: '{0}' to '{1}'", sourcePath, targetPath);

Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(targetPath)));
FileUtil.CopyFileOrDirectory(sourcePath, targetPath);
}

if (!Directory.Exists(targetPath))
{
throw new DirectoryNotFoundException($"Failed to copy '{sourcePath}' to '{targetPath}'");
}
}

internal static void CopyFile(string sourcePath, string targetPath, IDiagnosticLogger? logger)
{
if (File.Exists(targetPath))
{
logger?.LogDebug("'{0}' has already been copied to '{1}'", Path.GetFileName(targetPath), targetPath);
return;
}

if (File.Exists(sourcePath))
{
logger?.LogDebug("Copying from: '{0}' to '{1}'", sourcePath, targetPath);

Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(targetPath)));
FileUtil.CopyFileOrDirectory(sourcePath, targetPath);
}

if (!File.Exists(targetPath))
{
throw new FileNotFoundException($"Failed to copy '{sourcePath}' to '{targetPath}'");
}
}
}
}
53 changes: 53 additions & 0 deletions src/Sentry.Unity.Editor/EditorFileIO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.IO;
using Sentry.Extensibility;
using UnityEditor;

namespace Sentry.Unity.Editor
{
internal static class EditorFileIO
{
internal static void CopyDirectory(string sourcePath, string targetPath, IDiagnosticLogger? logger)
{
if (Directory.Exists(targetPath))
{
logger?.LogDebug("'{0}' already already exists.", targetPath);
return;
}

if (Directory.Exists(sourcePath))
{
logger?.LogDebug("Copying from: '{0}' to '{1}'", sourcePath, targetPath);

Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(targetPath)));
FileUtil.CopyFileOrDirectory(sourcePath, targetPath);
}

if (!Directory.Exists(targetPath))
{
throw new DirectoryNotFoundException($"Failed to copy '{sourcePath}' to '{targetPath}'");
}
}

internal static void CopyFile(string sourcePath, string targetPath, IDiagnosticLogger? logger)
{
if (File.Exists(targetPath))
{
logger?.LogDebug("'{0}' has already been copied to '{1}'", Path.GetFileName(targetPath), targetPath);
return;
}

if (File.Exists(sourcePath))
{
logger?.LogDebug("Copying from: '{0}' to '{1}'", sourcePath, targetPath);

Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(targetPath)));
FileUtil.CopyFileOrDirectory(sourcePath, targetPath);
}

if (!File.Exists(targetPath))
{
throw new FileNotFoundException($"Failed to copy '{sourcePath}' to '{targetPath}'");
}
}
}
}
23 changes: 23 additions & 0 deletions src/Sentry.Unity.Editor/IEditorApplication.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using UnityEditor;

namespace Sentry.Unity.Editor
{
internal interface IEditorApplication
{
string ApplicationContentsPath { get; }
EditorApplication.CallbackFunction Update { get; set; }
}

internal sealed class EditorApplicationAdapter : IEditorApplication
{
public static readonly EditorApplicationAdapter Instance = new();

public string ApplicationContentsPath => EditorApplication.applicationContentsPath;

public EditorApplication.CallbackFunction Update
{
get => EditorApplication.update;
set => EditorApplication.update = value;
}
}
}
7 changes: 4 additions & 3 deletions src/Sentry.Unity.Editor/Native/BuildPostProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Sentry.Unity.Editor.Native
public static class BuildPostProcess
{
[PostProcessBuild(1)]
public static void OnPostProcessBuild(BuildTarget target, string executablePath)
internal static void OnPostProcessBuild(BuildTarget target, string executablePath)
{
if (target is not (BuildTarget.StandaloneWindows or BuildTarget.StandaloneWindows64))
{
Expand All @@ -25,7 +25,7 @@ public static void OnPostProcessBuild(BuildTarget target, string executablePath)
{
if (PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup) != ScriptingImplementation.IL2CPP)
{
logger.LogWarning("Failed to enable Native support - only availabile with IL2CPP scripting backend.");
logger.LogWarning("Failed to enable Native support - only available with IL2CPP scripting backend.");
return;
}

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

SentryWindowsPlayer.Build(options, executablePath);

var projectDir = Path.GetDirectoryName(executablePath);
AddCrashHandler(logger, projectDir);
UploadDebugSymbols(logger, projectDir, Path.GetFileName(executablePath));

}
catch (Exception e)
{
Expand Down
140 changes: 140 additions & 0 deletions src/Sentry.Unity.Editor/Native/SentryWindowsPlayer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
using System;
using System.Diagnostics;
using System.IO;
using Sentry.Extensibility;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;

namespace Sentry.Unity.Editor.Native
{
internal static class SentryWindowsPlayer
{
internal static readonly ProcessStartInfo StartInfo = new()
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};

internal static void AddNativeOptions(SentryUnityOptions options)
{
}

internal static void AddSentryToMain(SentryUnityOptions options)
{
}

internal static string LocateWindowsPlayerSource(IEditorApplication? editorApplication = null)
{
editorApplication ??= EditorApplicationAdapter.Instance;

var playerProjectPath = Path.Combine(editorApplication.ApplicationContentsPath, "PlaybackEngines", "windowsstandalonesupport", "source", "windowsplayer");
if (!Directory.Exists(playerProjectPath))
{
throw new DirectoryNotFoundException($"Failed to locate the WindowsPlayer source at {playerProjectPath}.");
}

return playerProjectPath;
}

internal static void CreateWindowsPlayerProject(string windowsPlayerSource, string windowsPlayerTarget, IDiagnosticLogger? logger)
{
EditorFileIO.CopyDirectory(windowsPlayerSource, windowsPlayerTarget, logger);

// TODO: Does the .props file have to look like that?
using var props = File.CreateText(Path.Combine(windowsPlayerTarget, "UnityCommon.props"));
props.Write(@"<?xml version=""1.0"" encoding=""utf-8""?>
<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
</Project>");
}

internal static string LocateMSBuild(string vsWherePath, IDiagnosticLogger? logger)
{
StartInfo.FileName = vsWherePath;
StartInfo.Arguments = "-latest -requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe";

var vsWhereOutput = "";
var process = new Process {StartInfo = StartInfo};
process.OutputDataReceived += (sender, args) => vsWhereOutput += args.Data;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();

logger?.LogDebug("VSWhere returned with: {0}", vsWhereOutput);

if (!File.Exists(vsWhereOutput))
{
throw new FileNotFoundException($"Failed to locate 'msbuild'. VSWhere returned {vsWhereOutput}");
}

return vsWhereOutput;
}

internal static string LocateVSWhere(IDiagnosticLogger? logger)
{
var projectPath = Path.GetDirectoryName(Application.dataPath);
var directories = Directory.GetDirectories(Path.Combine(projectPath, "Library", "PackageCache"), "com.unity.ide.visualstudio@*");
if (directories is null || directories.Length < 1)
{
throw new Exception("Failed lo locate the 'com.unity.ide.visualstudio' package.");
}

// TODO: Not sure if there can be more than one version of a package in the Library/PackageCache and if it even matters
var vsPackagePath = directories[0];
logger?.LogDebug("Located 'com.unity.ide.visualstudio' package at {0}", vsPackagePath);

var vsWherePath = Path.Combine(vsPackagePath, "Editor", "VSWhere", "vswhere.exe");
if (!File.Exists(vsWherePath))
{
throw new FileNotFoundException($"Failed to find 'vswhere.exe' at '{vsWherePath}'");
}

return vsWherePath;
}

public static void Build(SentryUnityOptions options, string executablePath)
{
var vsWherePath = LocateVSWhere(options.DiagnosticLogger);
var msBuildPath = LocateMSBuild(vsWherePath, options.DiagnosticLogger);

var playerSource = LocateWindowsPlayerSource();
var playerTarget = FileUtil.GetUniqueTempPathInProject();

CreateWindowsPlayerProject(playerSource, playerTarget, options.DiagnosticLogger);

AddNativeOptions(options);
AddSentryToMain(options);

StartInfo.FileName = msBuildPath;
StartInfo.Arguments = playerTarget;

var outputData = "";
var errorData = "";
var process = new Process {StartInfo = StartInfo};
process.OutputDataReceived += (sender, args) => outputData += args.Data;
process.ErrorDataReceived += (sender, args) => errorData += args.Data;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();

if (outputData.Contains("Build succeeded"))
{
options.DiagnosticLogger?.LogDebug("Succeeded building the PlaybackEngine");
}
else if (outputData.Contains("Build failed"))
{
throw new Exception($"Failed to build the PlaybackEngine: \n {outputData}");
}

var logFile = Path.Combine(playerTarget, "build.log");
File.WriteAllText(logFile, outputData);
File.AppendAllText(logFile, errorData);

// TODO: Overwrite the executable with the build output
}
}
}
15 changes: 15 additions & 0 deletions src/Sentry.Unity.Editor/Native/Temp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using UnityEditor;

namespace Sentry.Unity.Editor.Native
{
public static class Temp
{
[MenuItem("Tools/ClickMe")]
public static void ClickMe()
{
var options = new SentryUnityOptions() {Debug = true, DiagnosticLevel = SentryLevel.Debug,};
options.DiagnosticLogger = new UnityLogger(options);
SentryWindowsPlayer.Build(options, "");
}
}
}
Loading

0 comments on commit 34f1204

Please sign in to comment.