Skip to content

Commit

Permalink
refactor: use new c# compilation types and add cross-targets
Browse files Browse the repository at this point in the history
  • Loading branch information
sinnwrig committed Oct 10, 2024
1 parent fe5002b commit 25a5450
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 89 deletions.
93 changes: 43 additions & 50 deletions Prowl.Editor/Build/DesktopPlayerBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License. See the LICENSE file in the project root for details.

using System.Reflection;
using System.Runtime.InteropServices;

using Prowl.Editor.Assets;
using Prowl.Editor.ProjectSettings;
Expand All @@ -15,23 +16,8 @@ namespace Prowl.Editor.Build;

public class Desktop_Player : ProjectBuilder
{
public enum Target
{
[Text("Win x64")] win_x64,
[Text("Win ARM x64")] win_arm64,
[Text("Win x86")] win_x86,

[Text("Linux x64")] linux_x64,
[Text("Linux x86")] linux_x86,

[Text("OSX")] osx,
[Text("OSX x64")] osx_x64,
[Text("OSX ARM x64")] osx_arm64,

Universal
}

public Target target = Target.win_x64;
public Platform platform = RuntimeUtils.GetOSPlatform();
public Architecture architecture = RuntimeInformation.OSArchitecture;

public enum Configuration
{
Expand All @@ -52,28 +38,27 @@ public enum AssetPacking

protected override void Build(AssetRef<Scene>[] scenes, DirectoryInfo output)
{
output.Create();
string buildDataPath = Path.Combine(output.FullName, "GameData");
Directory.CreateDirectory(buildDataPath);

Project.Active!.NukeTemp();

Debug.Log($"Compiling project assembly...");
// Debug.Log($"Compiling project assembly.");
CompileProject(out string projectLib);

Debug.Log($"Compiling player executable...");
// Debug.Log($"Compiling player executable.");
CompilePlayer(output, projectLib);

Debug.Log($"Exporting and Packing assets to {buildDataPath}...");
// Debug.Log($"Exporting and Packing assets to {buildDataPath}.");
PackAssets(scenes, buildDataPath);

Debug.Log($"Packing scenes...");
// Debug.Log($"Packing scenes.");
PackScenes(scenes, buildDataPath);

Debug.Log($"Preparing project settings...");
// Debug.Log($"Preparing project settings.");
PackProjectSettings(buildDataPath);

Debug.Log($"Successfully built project.");
Debug.Log($"Successfully built project to {output}");

// Open the Build folder
AssetDatabase.OpenPath(output, type: FileOpenType.FileExplorer);
Expand All @@ -90,21 +75,21 @@ private void CompileProject(out string projectLib)

DirectoryInfo tmpProject = new DirectoryInfo(Path.Combine(temp.FullName, "obj", Project.GameCSProjectName));

bool allowUnsafeBlocks = BuildProjectSettings.Instance.AllowUnsafeBlocks;
bool enableAOT = BuildProjectSettings.Instance.EnableAOTCompilation;
active.GenerateGameProject();

projectLib = Path.Combine(project.FullName, Project.GameCSProjectName + ".dll");

DotnetCompileOptions projectOptions = new DotnetCompileOptions()
{
isRelease = configuration == Configuration.Release,
isSelfContained = false,
outputExecutable = false,
architecture = architecture,
platform = platform,
outputPath = project,
tempPath = tmpProject
};

active.GenerateGameProject(allowUnsafeBlocks, enableAOT);

projectLib = Path.Combine(project.FullName, Project.GameCSProjectName + ".dll");

if (!active.CompileGameAssembly(projectOptions, project, tmpProject))
if (!active.CompileGameAssembly(projectOptions))
{
Debug.LogError($"Failed to compile Project assembly.");
return;
Expand Down Expand Up @@ -139,34 +124,42 @@ private void CompilePlayer(DirectoryInfo output, string gameLibrary)
return;
}

bool enableAOT = BuildProjectSettings.Instance.EnableAOTCompilation;
bool publishAOT = BuildProjectSettings.Instance.EnableAOTCompilation;

Assembly runtimeAssembly = typeof(Application).Assembly;

ProjectCompiler.GenerateCSProject(
"DesktopPlayer",
CSProjectOptions options = new();

options.OutputName = "DesktopPlayer";
options.OutputExecutable = true;
options.AllowUnsafeCode = true;
options.EnableAOTCompatibility = true;
options.PublishAOT = publishAOT;

options.OutputPath = bin;
options.IntermediateOutputPath = tmpPlayer;
options.ReferencesArePrivate = true;

options.AddReference(runtimeAssembly, true);
options.AddReference(gameLibrary);

options.GenerateCSProject(
playerProj,
playerProj.Directory,
RecursiveGetCSFiles(playerProj.Directory),
ProjectCompiler.GetNonstandardReferences(runtimeAssembly)
.Concat([runtimeAssembly]),
[(Project.GameCSProjectName, gameLibrary)],
true,
enableAOT,
true,
bin,
tmpPlayer
playerProj.Directory!,
RecursiveGetCSFiles(playerProj.Directory!)
);

DotnetCompileOptions playerOptions = new DotnetCompileOptions()
{
isRelease = configuration == Configuration.Release,
isSelfContained = true,
outputExecutable = true,
publishAOT = enableAOT,
architecture = architecture,
platform = platform,
outputPath = output,
tempPath = tmpPlayer
};

if (!ProjectCompiler.CompileCSProject(playerProj, output, null, playerOptions))
if (ProjectCompiler.CompileCSProject(playerProj, playerOptions) != 0)
{
Debug.LogError($"Failed to compile player assembly.");
return;
Expand Down Expand Up @@ -226,11 +219,11 @@ private void PackAssets(AssetRef<Scene>[] scenes, string dataPath)
}


private void PackScenes(AssetRef<Scene>[] scenes, string dataPath)
private static void PackScenes(AssetRef<Scene>[] scenes, string dataPath)
{
for (int i = 0; i < scenes.Length; i++)
{
BoundedLog($"Packing scene_{i}.prowl...");
// Debug.Log($"Packing scene_{i}.prowl.");
AssetRef<Scene> scene = scenes[i];
SerializedProperty tag = Serializer.Serialize(scene.Res!);
BinaryTagConverter.WriteToFile(tag, new FileInfo(Path.Combine(dataPath, $"scene_{i}.prowl")));
Expand Down
25 changes: 15 additions & 10 deletions Prowl.Editor/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public static class Program
{
private static bool IsReloadingExternalAssemblies { get; set; }
public static void RegisterReloadOfExternalAssemblies() => IsReloadingExternalAssemblies = true;

private static bool s_createdDefaultWindows;
private static bool s_opened;

Expand Down Expand Up @@ -198,27 +199,31 @@ public static void CheckReloadingAssemblies()

bin.Create();

bool allowUnsafeBlocks = BuildProjectSettings.Instance.AllowUnsafeBlocks;
bool enableAOT = BuildProjectSettings.Instance.EnableAOTCompilation;

// Forcefully disable AOT for scripts run in the editor
DotnetCompileOptions options = new DotnetCompileOptions()
{
isRelease = false,
isSelfContained = false,
publishAOT = false,
outputExecutable = false,
outputPath = project,
tempPath = tmpProject
};

active.GenerateGameProject(allowUnsafeBlocks, enableAOT);
active.CompileGameAssembly(options, project, tmpProject);
active.GenerateGameProject();
active.CompileGameAssembly(options);
Assembly? gameAssembly = AssemblyManager.LoadExternalAssembly(projectOutputPath, true);

if (gameAssembly != null)
{
active.GenerateEditorProject(allowUnsafeBlocks, gameAssembly);
active.CompileEditorAssembly(options, editor, tmpEditor);
Debug.Log($"Successfully reloaded project assemblies");

options.outputPath = editor;
options.tempPath = tmpEditor;

active.GenerateEditorProject(gameAssembly);
active.CompileEditorAssembly(options);
Assembly? editorAssembly = AssemblyManager.LoadExternalAssembly(editorOutputPath, true);

if (editorAssembly != null)
Debug.Log($"Successfully reloaded editor assemblies");
}
}
catch (Exception e)
Expand Down
67 changes: 38 additions & 29 deletions Prowl.Editor/Project/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Xml.Linq;

using Prowl.Editor.Assets;
using Prowl.Editor.ProjectSettings;
using Prowl.Runtime;
using Prowl.Runtime.SceneManagement;

Expand Down Expand Up @@ -203,26 +204,30 @@ private static void CreateDefaults(Project project)
}


public void GenerateGameProject(
bool allowUnsafeBlocks,
bool publishAOT)
public void GenerateGameProject()
{
Assembly runtimeAssembly = typeof(Application).Assembly;

DirectoryInfo bin = new DirectoryInfo(Path.Combine(TempDirectory.FullName, "bin"));
DirectoryInfo tmpProject = new DirectoryInfo(Path.Combine(TempDirectory.FullName, "obj", GameCSProjectName));

ProjectCompiler.GenerateCSProject(
GameCSProjectName,
CSProjectOptions options = new();

options.OutputExecutable = false;
options.OutputName = GameCSProjectName;
options.AllowUnsafeCode = BuildProjectSettings.Instance.AllowUnsafeBlocks;
options.EnableAOTCompatibility = BuildProjectSettings.Instance.EnableAOTCompilation;
options.PublishAOT = false;
options.OutputPath = bin;
options.IntermediateOutputPath = tmpProject;

options.AddReference(runtimeAssembly, true);

options.GenerateCSProject(
GameCSProject,
ProjectDirectory,
RecursiveGetCSFiles(AssetDirectory, false),
ProjectCompiler.GetNonstandardReferences(runtimeAssembly)
.Concat([runtimeAssembly]),
allowUnsafeBlocks,
publishAOT,
outputPath: bin,
tempPath: tmpProject);
RecursiveGetCSFiles(AssetDirectory, false)
);

ProjectAssemblyReferences.Instance.AddAssembly(GameCSProjectName);
}
Expand All @@ -232,41 +237,45 @@ public void GenerateGameProject(
/// Compiles the game assembly
/// </summary>
/// <returns>True if Compiling was sucessful</returns>
public bool CompileGameAssembly(DotnetCompileOptions options, DirectoryInfo output, DirectoryInfo temp)
public bool CompileGameAssembly(DotnetCompileOptions options)
{
return ProjectCompiler.CompileCSProject(GameCSProject, output, temp, options);
return ProjectCompiler.CompileCSProject(GameCSProject, options) == 0;
}


public void GenerateEditorProject(
bool allowUnsafeBlocks,
Assembly gameAssembly)
public void GenerateEditorProject(Assembly gameAssembly)
{
Assembly runtimeAssembly = typeof(Application).Assembly;

DirectoryInfo bin = new DirectoryInfo(Path.Combine(TempDirectory.FullName, "bin"));
DirectoryInfo tmpEditor = new DirectoryInfo(Path.Combine(TempDirectory.FullName, "obj", EditorCSProjectName));
CSProjectOptions options = new();

options.OutputExecutable = false;
options.OutputName = EditorCSProjectName;
options.AllowUnsafeCode = BuildProjectSettings.Instance.AllowUnsafeBlocks;
options.EnableAOTCompatibility = false;
options.PublishAOT = false;
options.OutputPath = new DirectoryInfo(Path.Combine(TempDirectory.FullName, "bin"));
options.IntermediateOutputPath = new DirectoryInfo(Path.Combine(TempDirectory.FullName, "obj", EditorCSProjectName));

options.AddReference(runtimeAssembly, true);
options.AddReference(gameAssembly, false);
options.AddReference(typeof(Program).Assembly, false); // Just the editor assembly with none of its fancy references

ProjectCompiler.GenerateCSProject(
EditorCSProjectName,
options.GenerateCSProject(
EditorCSProject,
ProjectDirectory,
RecursiveGetCSFiles(AssetDirectory, true),
ProjectCompiler.GetNonstandardReferences(runtimeAssembly)
.Concat([runtimeAssembly, gameAssembly, typeof(Program).Assembly]),
allowUnsafeBlocks,
outputPath: bin,
tempPath: tmpEditor);
RecursiveGetCSFiles(AssetDirectory, true)
);
}


/// <summary>
/// Compiles the editor assembly
/// </summary>
/// <returns>True if Compiling was sucessful</returns>
public bool CompileEditorAssembly(DotnetCompileOptions options, DirectoryInfo output, DirectoryInfo temp)
public bool CompileEditorAssembly(DotnetCompileOptions options)
{
return ProjectCompiler.CompileCSProject(EditorCSProject, output, temp, options);
return ProjectCompiler.CompileCSProject(EditorCSProject, options) == 0;
}


Expand Down

0 comments on commit 25a5450

Please sign in to comment.