diff --git a/Source/Tools/Flax.Build/Deps/Dependencies/nethost.cs b/Source/Tools/Flax.Build/Deps/Dependencies/nethost.cs
index f5eed36d7..7966870a3 100644
--- a/Source/Tools/Flax.Build/Deps/Dependencies/nethost.cs
+++ b/Source/Tools/Flax.Build/Deps/Dependencies/nethost.cs
@@ -9,8 +9,6 @@ using Flax.Build.Platforms;
using Flax.Deploy;
using System.IO.Compression;
-#pragma warning disable 0219
-
namespace Flax.Deps.Dependencies
{
///
@@ -30,6 +28,7 @@ namespace Flax.Deps.Dependencies
return new[]
{
TargetPlatform.PS4,
+ TargetPlatform.PS5,
TargetPlatform.Switch,
};
case TargetPlatform.Linux:
@@ -46,6 +45,7 @@ namespace Flax.Deps.Dependencies
public override bool BuildByDefault => false;
private string root;
+ private bool cleanArtifacts;
private void Build(BuildOptions options, TargetPlatform targetPlatform, TargetArchitecture architecture)
{
@@ -55,13 +55,14 @@ namespace Flax.Deps.Dependencies
// Clean output directory
var artifacts = Path.Combine(root, "artifacts");
- SetupDirectory(artifacts, true);
+ SetupDirectory(artifacts, cleanArtifacts);
+ cleanArtifacts = true;
// Peek options
- string os, arch, runtimeFlavor, subset, hostRuntimeName = DotNetSdk.GetHostRuntimeIdentifier(targetPlatform, architecture), buildArgsBase = string.Empty;
- bool setupVersion = false;
- string[] hostRuntimeFiles = Array.Empty();
+ string os, arch, runtimeFlavor, hostRuntimeName = DotNetSdk.GetHostRuntimeIdentifier(targetPlatform, architecture), buildArgs = string.Empty, buildMonoAotCrossArgs = string.Empty;
+ bool setupVersion = false, buildMonoAotCross = false;
var envVars = new Dictionary();
+ envVars.Add("VisualStudioVersion", null); // Unset this so 'init-vs-env.cmd' will properly init VS Environment
switch (architecture)
{
case TargetArchitecture.x86:
@@ -83,36 +84,39 @@ namespace Flax.Deps.Dependencies
case TargetPlatform.Windows:
os = "windows";
runtimeFlavor = "CoreCLR";
- subset = "clr";
break;
case TargetPlatform.Linux:
- os = "Linux";
+ os = "linux";
runtimeFlavor = "CoreCLR";
- subset = "clr";
break;
case TargetPlatform.Mac:
- os = "OSX";
+ os = "osx";
runtimeFlavor = "CoreCLR";
- subset = "clr";
break;
case TargetPlatform.Android:
- os = "Android";
+ os = "android";
runtimeFlavor = "Mono";
- subset = "mono+libs";
break;
case TargetPlatform.PS4:
- os = "PS4";
+ case TargetPlatform.PS5:
+ case TargetPlatform.Switch:
runtimeFlavor = "Mono";
- subset = "mono+libs";
setupVersion = true;
- buildArgsBase = " /p:RuntimeOS=ps4 -cmakeargs \"-DCLR_CROSS_COMPONENTS_BUILD=1\"";
- hostRuntimeFiles = new[]
+ buildMonoAotCross = true;
+ switch (targetPlatform)
{
- "coreclr_delegates.h",
- "hostfxr.h",
- "nethost.h",
- "libnethost.a",
- };
+ case TargetPlatform.PS4:
+ os = "ps4";
+ break;
+ case TargetPlatform.PS5:
+ os = "ps5";
+ break;
+ case TargetPlatform.Switch:
+ os = "switch";
+ break;
+ default: throw new InvalidPlatformException(targetPlatform);
+ }
+ buildArgs = $" /p:RuntimeOS={os} -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 /p:ApiCompatValidateAssemblies=false";
break;
default: throw new InvalidPlatformException(targetPlatform);
}
@@ -175,74 +179,85 @@ namespace Flax.Deps.Dependencies
}
// Build
- buildArgsBase = $"-os {os} -a {arch} -f {framework} -c {configuration} -lc {configuration} -rc {configuration} -rf {runtimeFlavor}{buildArgsBase}";
- //foreach (var buildStep in new[] { subset, "host.pkg", "packs.product" })
- /*var buildStep = "host.pkg";
+ if (runtimeFlavor == "CoreCLR")
+ buildArgs = $"-os {os} -a {arch} -f {framework} -c {configuration} -lc {configuration} -rc {configuration} -rf {runtimeFlavor}{buildArgs}";
+ else if (runtimeFlavor == "Mono")
+ buildArgs = $"-os {os} -a {arch} -c {configuration} -rf {runtimeFlavor}{buildArgs}";
+ Utilities.Run(Path.Combine(root, buildScript), buildArgs, null, root, Utilities.RunOptions.DefaultTool, envVars);
+ if (buildMonoAotCross)
{
- var buildArgs = $"{buildArgsBase} -s {buildStep}";
- if (BuildPlatform == TargetPlatform.Windows)
- {
- // For some reason running from Visual Studio fails the build so use command shell
- //buildArgs = $"/C {buildScript} {buildArgs}";
- //buildApp = "cmd.exe";
- // TODO: maybe write command line into bat file and run it here?
- WinAPI.SetClipboard($"{buildScript} {buildArgs}");
- WinAPI.MessageBox.Show($"Open console command in folder '{root}' and run command from clipboard. Then close this dialog.", "Run command manually", WinAPI.MessageBox.Buttons.Ok);
- }
- else
- {
- //Utilities.Run(Path.Combine(root, buildScript), buildArgs, null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
- }
- }*/
- Utilities.Run(Path.Combine(root, buildScript), buildArgsBase, null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
+ buildMonoAotCrossArgs = $"-c {configuration} -rf {runtimeFlavor} -subset mono /p:BuildMonoAotCrossCompiler=true /p:BuildMonoAOTCrossCompilerOnly=true /p:TargetOS={os} /p:HostOS=windows -cmakeargs \"-DCMAKE_CROSSCOMPILING=True\"{buildMonoAotCrossArgs}";
+ Utilities.Run(Path.Combine(root, buildScript), buildMonoAotCrossArgs, null, root, Utilities.RunOptions.DefaultTool, envVars);
+ }
// Deploy build products
+ var privateCoreLib = "System.Private.CoreLib.dll";
var dstBinaries = GetThirdPartyFolder(options, targetPlatform, architecture);
- var srcHostRuntime = Path.Combine(artifacts, "bin", $"{hostRuntimeName}.{configuration}", "corehost");
- foreach (var file in hostRuntimeFiles)
- {
- Utilities.FileCopy(Path.Combine(srcHostRuntime, file), Path.Combine(dstBinaries, file));
- }
- var dstDotnet = Path.Combine(GetBinariesFolder(options, targetPlatform), "Dotnet");
- var dstClassLibrary = Path.Combine(dstDotnet, "shared", "Microsoft.NETCore.App", version);
- SetupDirectory(dstClassLibrary, true);
- foreach (var file in new[]
- {
- "LICENSE.TXT",
- "THIRD-PARTY-NOTICES.TXT",
- })
- {
+ var dstPlatform = Path.Combine(options.PlatformsFolder, targetPlatform.ToString());
+ var dstDotnet = Path.Combine(dstPlatform, "Dotnet");
+ foreach (var file in new[] { "LICENSE.TXT", "THIRD-PARTY-NOTICES.TXT" })
Utilities.FileCopy(Path.Combine(root, file), Path.Combine(dstDotnet, file));
- }
- var srcDotnetLibsPkg = Path.Combine(artifacts, "packages", "Release", "Shipping", $"Microsoft.NETCore.App.Runtime.Mono.{hostRuntimeName}.{version}.nupkg");
- if (!File.Exists(srcDotnetLibsPkg))
- throw new Exception($"Missing .NET Core App class library package at '{srcDotnetLibsPkg}'");
- var unpackTemp = Path.Combine(Path.GetDirectoryName(srcDotnetLibsPkg), "UnpackTemp");
- SetupDirectory(unpackTemp, true);
- using (var zip = ZipFile.Open(srcDotnetLibsPkg, ZipArchiveMode.Read))
+ if (runtimeFlavor == "CoreCLR")
{
- zip.ExtractToDirectory(unpackTemp);
- }
- var privateCorelib = "System.Private.CoreLib.dll";
- Utilities.FileCopy(Path.Combine(unpackTemp, "runtimes", hostRuntimeName, "native", privateCorelib), Path.Combine(dstClassLibrary, privateCorelib));
- Utilities.DirectoryCopy(Path.Combine(unpackTemp, "runtimes", hostRuntimeName, "lib", "net8.0"), dstClassLibrary, false, true);
- // TODO: host/fxr//hostfxr.dll
- // TODO: shared/Microsoft.NETCore.App//hostpolicy.dl
- // TODO: shared/Microsoft.NETCore.App//System.IO.Compression.Native.dll
- if (runtimeFlavor == "Mono")
- {
- // TODO: implement automatic deployment based on the setup:
- // PS4 outputs mono into artifacts\obj\mono\PS4.x64.Release\out
- // PS4 outputs native libs into artifacts\bin\native\net7.0-PS4-Release-x64\lib
- // PS4 outputs System.Private.CoreLib lib into artifacts\bin\mono\PS4.x64.Release
- // PS4 outputs C# libs into artifacts\bin\runtime\net7.0-PS4.Release.x64
- // PS4 outputs AOT compiler into artifacts\bin\mono\PS4.x64.Release\cross\ps4-x64
+ var srcHostRuntime = Path.Combine(artifacts, "bin", $"{hostRuntimeName}.{configuration}", "corehost");
+ var dstClassLibrary = Path.Combine(dstDotnet, "shared", "Microsoft.NETCore.App", version);
+ SetupDirectory(dstClassLibrary, true);
+ var srcDotnetLibsPkg = Path.Combine(artifacts, "packages", "Release", "Shipping", $"Microsoft.NETCore.App.Runtime.Mono.{hostRuntimeName}.{version}.nupkg");
+ if (!File.Exists(srcDotnetLibsPkg))
+ throw new Exception($"Missing .NET Core App class library package at '{srcDotnetLibsPkg}'");
+ var unpackTemp = Path.Combine(Path.GetDirectoryName(srcDotnetLibsPkg), "UnpackTemp");
+ SetupDirectory(unpackTemp, true);
+ using (var zip = ZipFile.Open(srcDotnetLibsPkg, ZipArchiveMode.Read))
+ zip.ExtractToDirectory(unpackTemp);
+ Utilities.FileCopy(Path.Combine(unpackTemp, "runtimes", hostRuntimeName, "native", privateCoreLib), Path.Combine(dstClassLibrary, privateCoreLib));
+ Utilities.DirectoryCopy(Path.Combine(unpackTemp, "runtimes", hostRuntimeName, "lib", framework), dstClassLibrary, false, true);
+ // TODO: host/fxr//hostfxr.dll
+ // TODO: shared/Microsoft.NETCore.App//hostpolicy.dl
+ // TODO: shared/Microsoft.NETCore.App//System.IO.Compression.Native.dll
Utilities.DirectoryCopy(Path.Combine(unpackTemp, "runtimes", hostRuntimeName, "native"), Path.Combine(dstDotnet, "native"), true, true);
- Utilities.FileDelete(Path.Combine(dstDotnet, "native", privateCorelib));
+ Utilities.FileDelete(Path.Combine(dstDotnet, "native", privateCoreLib));
+ Utilities.DirectoriesDelete(unpackTemp);
+ }
+ else if (runtimeFlavor == "Mono")
+ {
+ // Native libs
+ var src1 = Path.Combine(artifacts, "obj", "mono", $"{os}.{arch}.{configuration}", "out");
+ if (!Directory.Exists(src1))
+ throw new DirectoryNotFoundException(src1);
+ var src2 = Path.Combine(artifacts, "bin", "native", $"{framework}-{os}-{configuration}-{arch}");
+ if (!Directory.Exists(src1))
+ throw new DirectoryNotFoundException(src2);
+ foreach (var file in new[]
+ {
+ "libmonosgen-2.0.a",
+ "libmono-profiler-aot.a",
+ })
+ Utilities.FileCopy(Path.Combine(src1, "lib", file), Path.Combine(dstBinaries, file));
+ foreach (var file in new[]
+ {
+ "libSystem.Globalization.Native.a",
+ "libSystem.IO.Compression.Native.a",
+ "libSystem.IO.Ports.Native.a",
+ "libSystem.Native.a",
+ })
+ Utilities.FileCopy(Path.Combine(src2, "lib", file), Path.Combine(dstBinaries, file));
+
+ // Include headers
+ Utilities.DirectoryDelete(Path.Combine(dstBinaries, "include"));
+ Utilities.DirectoryCopy(Path.Combine(src1, "include"), Path.Combine(dstBinaries, "include"), true, true);
+
+ if (buildMonoAotCross)
+ {
+ // AOT compiler
+ Utilities.FileCopy(Path.Combine(artifacts, "bin", "mono", $"{os}.x64.{configuration}", "cross", $"{os}-x64", "mono-aot-cross.exe"), Path.Combine(dstPlatform, "Binaries", "Tools", "mono-aot-cross.exe"));
+ }
+
+ // Class library
+ var dstDotnetLib = Path.Combine(dstPlatform, "Dotnet", "lib", framework);
+ SetupDirectory(dstDotnetLib, true);
+ Utilities.FileCopy(Path.Combine(artifacts, "bin", "mono", $"{os}.{arch}.{configuration}", privateCoreLib), Path.Combine(dstDotnetLib, privateCoreLib));
+ Utilities.DirectoryCopy(Path.Combine(artifacts, "bin", "runtime", $"{framework}-{os}-{configuration}-{arch}"), dstDotnetLib, false, true, "*.dll");
}
- else
- throw new InvalidPlatformException(targetPlatform);
- Utilities.DirectoriesDelete(unpackTemp);
}
///
@@ -255,9 +270,12 @@ namespace Flax.Deps.Dependencies
Utilities.Run("cmake", "--version", null, null, Utilities.RunOptions.ThrowExceptionOnError);
// Get the source
- CloneGitRepo(root, "https://github.com/FlaxEngine/dotnet-runtime.git", null, null, true);
- GitCheckout(root, "flax-master");
- SetupDirectory(Path.Combine(root, "src", "external"), false);
+ if (!Directory.Exists(Path.Combine(root, ".git")))
+ {
+ CloneGitRepo(root, "https://github.com/FlaxEngine/dotnet-runtime.git", null, null, true);
+ GitCheckout(root, "flax-master-8");
+ SetupDirectory(Path.Combine(root, "src", "external"), false);
+ }
/*
* Mono AOT for Windows:
@@ -267,10 +285,10 @@ namespace Flax.Deps.Dependencies
* .\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
+ * .\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 /p:ApiCompatValidateAssemblies=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"
+ * .\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)
diff --git a/Source/Tools/Flax.Build/Utilities/Utilities.cs b/Source/Tools/Flax.Build/Utilities/Utilities.cs
index bf7c24e1a..02019b30d 100644
--- a/Source/Tools/Flax.Build/Utilities/Utilities.cs
+++ b/Source/Tools/Flax.Build/Utilities/Utilities.cs
@@ -320,6 +320,11 @@ namespace Flax.Build
///
ConsoleLogOutput = 1 << 7,
+ ///
+ /// Enables to run process via Shell instead of standard process startup.
+ ///
+ Shell = 1 << 8,
+
///
/// The default options.
///
@@ -398,11 +403,12 @@ namespace Flax.Build
}
bool redirectStdOut = (options & RunOptions.NoStdOutRedirect) != RunOptions.NoStdOutRedirect;
+ bool shell = options.HasFlag(RunOptions.Shell);
Process proc = new Process();
proc.StartInfo.FileName = app;
proc.StartInfo.Arguments = commandLine != null ? commandLine : "";
- proc.StartInfo.UseShellExecute = false;
+ proc.StartInfo.UseShellExecute = shell;
proc.StartInfo.RedirectStandardInput = input != null;
proc.StartInfo.CreateNoWindow = true;
@@ -411,7 +417,7 @@ namespace Flax.Build
proc.StartInfo.WorkingDirectory = workspace;
}
- if (redirectStdOut)
+ if (redirectStdOut && !shell)
{
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
@@ -427,16 +433,24 @@ namespace Flax.Build
}
}
- if (envVars != null)
+ if (envVars != null && !shell)
{
foreach (var env in envVars)
{
if (env.Key == "PATH")
{
+ // Append to path
proc.StartInfo.EnvironmentVariables[env.Key] = env.Value + ';' + proc.StartInfo.EnvironmentVariables[env.Key];
}
+ else if (env.Value == null)
+ {
+ // Remove variable
+ if (proc.StartInfo.EnvironmentVariables.ContainsKey(env.Key))
+ proc.StartInfo.EnvironmentVariables.Remove(env.Key);
+ }
else
{
+ // Set variable
proc.StartInfo.EnvironmentVariables[env.Key] = env.Value;
}
}