Add .NET 7 for PlayStation 4

This commit is contained in:
Wojtek Figat
2023-04-05 19:17:22 +02:00
parent 2475706df4
commit 09bd7c696b
5 changed files with 87 additions and 27 deletions

View File

@@ -72,8 +72,7 @@ public class nethost : ThirdPartyModule
case TargetPlatform.Switch:
case TargetPlatform.PS4:
case TargetPlatform.PS5:
options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libnethost.a"));
//options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libhostfxr.a"));
options.OutputFiles.Add(Path.Combine(hostRuntime.Path, "libmonosgen-2.0.a"));
break;
case TargetPlatform.Android:
options.PublicDefinitions.Add("USE_MONO_DYNAMIC_LIB");

View File

@@ -305,7 +305,6 @@ namespace Flax.Build
else if (aotMode == DotNetAOTModes.MonoAOTDynamic || aotMode == DotNetAOTModes.MonoAOTStatic)
{
var dotnetLibPath = Path.Combine(aotAssembliesPath, "lib/net7.0");
var monoAssembliesOutputPath = aotMode == DotNetAOTModes.MonoAOTDynamic ? dotnetOutputPath : null;
// Build list of assemblies to process (use game assemblies as root to walk over used references from stdlib)
var assembliesPaths = new List<string>();
@@ -346,6 +345,10 @@ namespace Flax.Build
// Run compilation
bool failed = false;
bool validCache = true;
var platformsToolsPath = Path.Combine(Globals.EngineRoot, "Source/Platforms", platform.ToString(), "Binaries/Tools");
if (!Directory.Exists(platformsToolsPath))
throw new Exception("Missing platform tools " + platformsToolsPath);
var compileAssembly = (string assemblyPath) =>
{
// Determinate whether use debug information for that assembly
@@ -357,7 +360,11 @@ namespace Flax.Build
}
// Skip if output is already generated and is newer than a source assembly
var outputFilePath = assemblyPath + buildPlatform.SharedLibraryFileExtension;
string outputFilePath;
if (aotMode == DotNetAOTModes.MonoAOTDynamic)
outputFilePath = assemblyPath + buildPlatform.SharedLibraryFileExtension;
else
outputFilePath = Path.Combine(Path.GetDirectoryName(assemblyPath), buildPlatform.StaticLibraryFilePrefix + Path.GetFileName(assemblyPath) + buildPlatform.StaticLibraryFileExtension);
if (!File.Exists(outputFilePath) || File.GetLastWriteTime(assemblyPath) > File.GetLastWriteTime(outputFilePath))
{
if (dotnetAotDebug)
@@ -366,33 +373,49 @@ namespace Flax.Build
Log.Info("");
Log.Info("");
}
Log.Info(" * " + assemblyPath);
var options = new Toolchain.CSharpOptions
{
Action = Toolchain.CSharpOptions.ActionTypes.MonoCompile,
InputFile = assemblyPath,
AssembliesFolder = aotAssembliesPath,
OutputFile = outputFilePath,
AssembliesPath = aotAssembliesPath,
ClassLibraryPath = dotnetLibPath,
PlatformsToolsPath = platformsToolsPath,
EnableDebugSymbols = useDebug,
EnableToolDebug = dotnetAotDebug,
};
if (!Directory.Exists(options.PlatformsToolsPath))
throw new Exception("Missing platform tools " + options.PlatformsToolsPath);
Log.Info(" * " + options.OutputFile);
if (buildToolchain.CompileCSharp(options))
{
Log.Error("Failed to run AOT on assembly " + assemblyPath);
failed = true;
return;
}
validCache = false;
}
// Skip if deployed file is already valid
var deployedFilePath = monoAssembliesOutputPath != null ? Path.Combine(monoAssembliesOutputPath, Path.GetFileName(outputFilePath)) : outputFilePath;
if (monoAssembliesOutputPath != null && (!File.Exists(deployedFilePath) || File.GetLastWriteTime(outputFilePath) > File.GetLastWriteTime(deployedFilePath)))
var assemblyFileName = Path.GetFileName(assemblyPath);
// TODO: consider optimizing C# assemblies when doing Mono AOT - maybe we could strip them out of the code and leave just reference/api info for the runtime
if (Configuration.AOTMode == DotNetAOTModes.MonoAOTDynamic)
{
// Skip if deployed file is already valid
var deployedFilePath = Path.Combine(dotnetOutputPath, Path.GetFileName(outputFilePath));
if (!File.Exists(deployedFilePath) || File.GetLastWriteTime(outputFilePath) > File.GetLastWriteTime(deployedFilePath))
{
// Copy to the destination folder
Utilities.FileCopy(assemblyPath, Path.Combine(dotnetOutputPath, assemblyFileName));
Utilities.FileCopy(outputFilePath, deployedFilePath);
if (useDebug && File.Exists(outputFilePath + ".pdb"))
Utilities.FileCopy(outputFilePath + ".pdb", Path.Combine(dotnetOutputPath, Path.GetFileName(outputFilePath + ".pdb")));
validCache = false;
}
}
else
{
// Copy to the destination folder
var assemblyFileName = Path.GetFileName(assemblyPath);
Utilities.FileCopy(assemblyPath, Path.Combine(monoAssembliesOutputPath, assemblyFileName));
Utilities.FileCopy(outputFilePath, deployedFilePath);
if (useDebug && File.Exists(outputFilePath + ".pdb"))
Utilities.FileCopy(outputFilePath + ".pdb", Path.Combine(monoAssembliesOutputPath, Path.GetFileName(outputFilePath + ".pdb")));
Utilities.FileCopy(assemblyPath, Path.Combine(dotnetOutputPath, assemblyFileName));
}
};
if (Configuration.MaxConcurrency > 1 && Configuration.ConcurrencyProcessorScale > 0.0f && !dotnetAotDebug)
@@ -408,6 +431,27 @@ namespace Flax.Build
}
if (failed)
throw new Exception($"Failed to run AOT. See log ({Configuration.LogFile}).");
var outputAotLib = Path.Combine(outputPath, buildPlatform.SharedLibraryFilePrefix + "AOT" + buildPlatform.SharedLibraryFileExtension);
if (Configuration.AOTMode == DotNetAOTModes.MonoAOTStatic && (!validCache || !File.Exists(outputAotLib)))
{
// Link static native libraries into a single shared module with whole C# compiled in
var options = new Toolchain.CSharpOptions
{
Action = Toolchain.CSharpOptions.ActionTypes.MonoLink,
InputFiles = assembliesPaths,
OutputFile = outputAotLib,
AssembliesPath = aotAssembliesPath,
ClassLibraryPath = dotnetLibPath,
PlatformsToolsPath = platformsToolsPath,
EnableDebugSymbols = configuration != TargetConfiguration.Release,
EnableToolDebug = dotnetAotDebug,
};
Log.Info(" * " + options.OutputFile);
if (buildToolchain.CompileCSharp(options))
{
throw new Exception("Mono AOT failed to link static libraries into a shared module");
}
}
}
else
{

View File

@@ -139,9 +139,19 @@ namespace Flax.Build
/// </summary>
public struct CSharpOptions
{
public enum ActionTypes
{
MonoCompile,
MonoLink,
};
public ActionTypes Action;
public string InputFile;
public string AssembliesFolder;
public List<string> InputFiles;
public string OutputFile;
public string AssembliesPath;
public string ClassLibraryPath;
public string PlatformsToolsPath;
public bool EnableDebugSymbols;
public bool EnableToolDebug;
}

View File

@@ -230,6 +230,8 @@ namespace Flax.Deps.Dependencies
// TODO: shared/Microsoft.NETCore.App/<version>/System.IO.Compression.Native.dll
if (runtimeFlavor == "Mono")
{
// PS4 outputs mono into artifacts\obj\mono\PS4.x64.Release\out
// PS4 output AOT compiler into artifacts/obj/mono/PS4.x64.Release/cross/out/bin/mono-aot-cross.exe
Utilities.DirectoryCopy(Path.Combine(unpackTemp, "runtimes", hostRuntimeName, "native"), Path.Combine(dstDotnet, "native"), true, true);
Utilities.FileDelete(Path.Combine(dstDotnet, "native", privateCorelib));
}
@@ -252,11 +254,17 @@ namespace Flax.Deps.Dependencies
SetupDirectory(Path.Combine(root, "src", "external"), false);
/*
* Mono AOT building for Windows:
* .\build.cmd -c release -runtimeFlavor mono mono+libs -cmakeargs "-DDISABLE_JIT=1-DENABLE_PERFTRACING=0-DDISABLE_REFLECTION_EMIT=1-DDISABLE_EVENTPIPE=1-DDISABLE_COM=1-DDISABLE_PROFILER=1-DDISABLE_COMPONENTS=1" /p:FeaturePerfTracing=false /p:FeatureManagedEtw=false /p:FeatureManagedEtwChannels=false /p:FeatureEtw=false
*
* Mono AOT for Windows:
* .\build.cmd -c release -runtimeFlavor mono -subset mono+libs -cmakeargs "-DDISABLE_JIT=1-DENABLE_PERFTRACING=0-DDISABLE_REFLECTION_EMIT=1-DDISABLE_EVENTPIPE=1-DDISABLE_COM=1-DDISABLE_PROFILER=1-DDISABLE_COMPONENTS=1" /p:FeaturePerfTracing=false /p:FeatureManagedEtw=false /p:FeatureManagedEtwChannels=false /p:FeatureEtw=false
*
* Mono AOT cross-compiler for Windows:
* .\build.cmd -c release -runtimeFlavor mono -subset mono /p:BuildMonoAotCrossCompiler=true
* .\build.cmd -c release -runtimeFlavor mono -subset mono /p:BuildMonoAotCrossCompiler=true /p:BuildMonoAOTCrossCompilerOnly=true
*
* Mono AOT for PS4:
* .\build.cmd -os PS4 -a x64 /p:RuntimeOS=ps4 -c release -runtimeFlavor mono -subset mono+libs -cmakeargs "-DDISABLE_JIT=1-DENABLE_PERFTRACING=0-DDISABLE_REFLECTION_EMIT=1-DDISABLE_EVENTPIPE=1-DDISABLE_COM=1-DDISABLE_PROFILER=1-DDISABLE_COMPONENTS=1" /p:FeaturePerfTracing=false /p:FeatureManagedEtw=false /p:FeatureManagedEtwChannels=false /p:FeatureEtw=false
*
* Mono AOT cross-compiler for PS4:
* .\build.cmd -c release -runtimeFlavor mono -subset mono /p:BuildMonoAotCrossCompiler=true /p:BuildMonoAOTCrossCompilerOnly=true /p:TargetOS=PS4 /p:HostOS=windows -cmakeargs "-DCMAKE_CROSSCOMPILING=True"
*/
foreach (var platform in options.Platforms)

View File

@@ -1028,26 +1028,25 @@ namespace Flax.Build.Platforms
/// <inheritdoc />
public override bool CompileCSharp(CSharpOptions options)
{
var platformToolsRoot = Path.Combine(Globals.EngineRoot, "Source/Platforms", Platform.Target.ToString(), "Binaries/Tools");
if (!Directory.Exists(platformToolsRoot))
throw new Exception("Missing platform tools " + platformToolsRoot);
var aotCompilerPath = Path.Combine(platformToolsRoot, "mono-aot-cross.exe");
if (options.Action != CSharpOptions.ActionTypes.MonoCompile)
return true;
var aotCompilerPath = Path.Combine(options.PlatformsToolsPath, "mono-aot-cross.exe");
// Setup options
var monoAotMode = "full";
var debugMode = options.EnableDebugSymbols ? "soft-debug" : "nodebug";
var aotCompilerArgs = $"--aot={monoAotMode},verbose,stats,print-skipped,{debugMode} -O=all";
var monoDebugMode = options.EnableDebugSymbols ? "soft-debug" : "nodebug";
var aotCompilerArgs = $"--aot={monoAotMode},verbose,stats,print-skipped,{monoDebugMode} -O=all";
if (options.EnableDebugSymbols || options.EnableToolDebug)
aotCompilerArgs = "--debug " + aotCompilerArgs;
var envVars = new Dictionary<string, string>();
envVars["MONO_PATH"] = options.AssembliesFolder + ";" + options.ClassLibraryPath;
envVars["MONO_PATH"] = options.AssembliesPath + ";" + options.ClassLibraryPath;
if (options.EnableToolDebug)
{
envVars["MONO_LOG_LEVEL"] = "debug";
}
// Run cross-compiler compiler
int result = Utilities.Run(aotCompilerPath, $"{aotCompilerArgs} \"{options.InputFile}\"", null, platformToolsRoot, Utilities.RunOptions.AppMustExist | Utilities.RunOptions.ConsoleLogOutput, envVars);
int result = Utilities.Run(aotCompilerPath, $"{aotCompilerArgs} \"{options.InputFile}\"", null, options.PlatformsToolsPath, Utilities.RunOptions.AppMustExist | Utilities.RunOptions.ConsoleLogOutput, envVars);
return result != 0;
}
}