You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
5.9 KiB
186 lines
5.9 KiB
#if UNITY_EDITOR_WIN
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using UnityEditor;
|
|
using UnityEditor.Build;
|
|
using UnityEditor.Build.Reporting;
|
|
using UnityEditor.UnityLinker;
|
|
using UnityEngine;
|
|
using PlayerSettings = UnityEditor.PlayerSettings;
|
|
using WW1.PlayStation;
|
|
|
|
internal class BuildPackageLibs : IPreprocessBuildWithReport, IMovePRXCallback
|
|
{
|
|
public int callbackOrder => 0;
|
|
static string PackageName => "com.ww1gameseries.pssr";
|
|
static string SourcePath => $"Packages/{PackageName}/Source~";
|
|
const int k_PRXBuildTimeOutS = 600; //10 minutes is the max time allowed to build the PRX
|
|
|
|
#region CompileLibs
|
|
readonly string[] m_CompileAgainstLibs = new string[]
|
|
{
|
|
"SceSysmodule_stub_weak",
|
|
"ScePsml",
|
|
"ScePsml_stub_weak",
|
|
"SceAgcGnmp",
|
|
"SceAgc",
|
|
"SceAgcCore",
|
|
"SceAgcGpuAddress",
|
|
"SceVideoOut_stub_weak",
|
|
"SceAgcDriver_stub_weak",
|
|
"SceAgc_stub_weak",
|
|
};
|
|
#endregion
|
|
|
|
public void OnPreprocessBuild(BuildReport report)
|
|
{
|
|
var buildTarget = report.summary.platform;
|
|
if (!IsBuildTargetValid(buildTarget))
|
|
{
|
|
return;
|
|
}
|
|
|
|
string prxPath = GetPRXBuildLocation(buildTarget);
|
|
string prxDir = Path.GetDirectoryName(prxPath);
|
|
|
|
if (IsPRXRebuildRequired(prxPath))
|
|
{
|
|
if (!Directory.Exists(prxDir))
|
|
{
|
|
if (string.IsNullOrWhiteSpace(prxDir))
|
|
{
|
|
throw new BuildFailedException("No PRX Directory");
|
|
}
|
|
Directory.CreateDirectory(prxDir);
|
|
}
|
|
|
|
BuildPackagePRX(buildTarget, prxPath, m_CompileAgainstLibs);
|
|
}
|
|
}
|
|
|
|
public void MovePRXToBuildLocation(BuildTarget target, string buildOutputLocation, bool developmentBuild)
|
|
{
|
|
if (!IsBuildTargetValid(target))
|
|
{
|
|
return;
|
|
}
|
|
|
|
string projectDir = Application.dataPath.Replace("/Assets", "");
|
|
string stagingArea = BuildUtils.GetStagingAreaLocationFor(target, projectDir, buildOutputLocation);
|
|
CopyLibraryPRXToStagingArea(GetPRXBuildLocation(target), stagingArea);
|
|
}
|
|
|
|
static bool IsPRXRebuildRequired(string prxPath)
|
|
{
|
|
if (!File.Exists(prxPath))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
DateTime prxLastWrite = File.GetLastWriteTimeUtc(prxPath);
|
|
if (BuildUtils.HaveSourceFilesBeenModifiedSince(SourcePath, prxLastWrite))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static void BuildPackagePRX(BuildTarget target, string outputPath, string[] compileAgainstLibs)
|
|
{
|
|
string sdkLoc = Environment.GetEnvironmentVariable(SDKUtils.GetSdkEnvVarFor(target));
|
|
string clangLoc = $"{sdkLoc}/host_tools/bin/{SDKUtils.GetClangFor(target)}";
|
|
|
|
string allSourcePaths = string.Empty;
|
|
string[] allDirs = Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories);
|
|
|
|
//Include the base folder also, if it has cpp files in it
|
|
if (Directory.GetFiles(SourcePath, "*.cpp").Length > 0)
|
|
{
|
|
allSourcePaths += $"\"{Path.GetFullPath(Path.Combine(SourcePath, "*.cpp"))}\" ";
|
|
}
|
|
|
|
foreach (var dir in allDirs)
|
|
{
|
|
if (Directory.GetFiles(dir, "*.cpp").Length == 0)
|
|
{
|
|
continue;
|
|
}
|
|
allSourcePaths += $"\"{Path.GetFullPath(Path.Combine(dir, "*.cpp"))}\" ";
|
|
}
|
|
|
|
string allLinkLibs = string.Empty;
|
|
foreach (var lib in compileAgainstLibs)
|
|
{
|
|
allLinkLibs += $"-l {lib} ";
|
|
}
|
|
|
|
//Additionally include the common includes
|
|
string command = $"-D\"NDEBUG\" -O2 -Wall -o\"{outputPath}\" {allSourcePaths} --for-linker=--oformat=prx {allLinkLibs}";
|
|
|
|
ProcessStartInfo startInfo = new ProcessStartInfo(clangLoc, command)
|
|
{
|
|
CreateNoWindow = true,
|
|
UseShellExecute = false,
|
|
RedirectStandardError = true,
|
|
};
|
|
|
|
Console.WriteLine($"Building PRX with {clangLoc} {command}");
|
|
Process proc = Process.Start(startInfo);
|
|
string errorOutput = proc.StandardError.ReadToEnd();
|
|
proc.WaitForExit(k_PRXBuildTimeOutS);
|
|
if (!proc.HasExited)
|
|
{
|
|
proc.Kill();
|
|
throw new BuildFailedException($"PRX Build Timed Out\n{errorOutput}");
|
|
}
|
|
|
|
if (proc.ExitCode != 0)
|
|
{
|
|
throw new BuildFailedException(errorOutput);
|
|
}
|
|
}
|
|
|
|
static void CopyLibraryPRXToStagingArea(string prxLocation, string stagingArea)
|
|
{
|
|
string copyPath = Path.Combine(stagingArea, LibraryInfo.LibraryNameWithExtension);
|
|
if (!Directory.Exists(stagingArea))
|
|
{
|
|
Directory.CreateDirectory(stagingArea);
|
|
}
|
|
|
|
File.Copy(prxLocation, copyPath, true);
|
|
}
|
|
|
|
static string GetPRXBuildLocation(BuildTarget target)
|
|
{
|
|
//Example Path: Library/SourceGeneratedPlugins/PS5/7000045/CommonDialog.prx
|
|
string relativePath = Path.Combine("Library", "SourceGeneratedPlugins", target.ToString(),
|
|
SDKUtils.GetSDKVersionString(target), $"{LibraryInfo.LibraryNameWithExtension}");
|
|
return Path.GetFullPath(relativePath);
|
|
}
|
|
|
|
static bool IsBuildTargetValid(BuildTarget target)
|
|
{
|
|
return target is BuildTarget.PS5;
|
|
}
|
|
}
|
|
|
|
internal interface IMovePRXCallback : IUnityLinkerProcessor
|
|
{
|
|
string IUnityLinkerProcessor.GenerateAdditionalLinkXmlFile(BuildReport report, UnityLinkerBuildPipelineData data)
|
|
{
|
|
//In 2021.3 report can return null for non-playstation platforms
|
|
if (report == null)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
MovePRXToBuildLocation(report.summary.platform, report.summary.outputPath, report.summary.options.HasFlag(BuildOptions.Development));
|
|
return string.Empty;
|
|
}
|
|
|
|
public void MovePRXToBuildLocation(BuildTarget target, string buildOutputLocation, bool developmentBuild);
|
|
}
|
|
#endif
|