mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
接入obfuz->2.0
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
using System;
|
||||
using HybridCLR.Editor.Installer;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using System.Reflection;
|
||||
using HybridCLR.Editor.Settings;
|
||||
#if UNITY_2019 && (UNITY_IOS || UNITY_TVOS)
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEditor.iOS.Xcode;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
public static class AddLil2cppSourceCodeToXcodeproj2019
|
||||
{
|
||||
[PostProcessBuild]
|
||||
public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
|
||||
{
|
||||
if (!HybridCLRSettings.Instance.enable)
|
||||
return;
|
||||
/*
|
||||
* 1. 生成lump,并且添加到工程
|
||||
3. 将libil2cpp目录复制到 Library/. 删除旧的. search paths里修改 libil2cpp/include为libil2cpp
|
||||
3. Libraries/bdwgc/include -> Libraries/external/bdwgc/include
|
||||
4. 将external目录复制到 Library/external。删除旧目录
|
||||
5. 将Library/external/baselib/Platforms/OSX改名为 IOS 全大写
|
||||
6. 将 external/zlib下c 文件添加到工程
|
||||
7. 移除libil2cpp.a
|
||||
8. Include path add libil2cpp/os/ClassLibraryPAL/brotli/include
|
||||
9. add external/xxHash
|
||||
10. add "#include <stdio.h>" to Classes/Prefix.pch
|
||||
*/
|
||||
|
||||
string pbxprojFile = BuildProcessorUtil.GetXcodeProjectFile(pathToBuiltProject);
|
||||
string srcLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";
|
||||
string dstLibil2cppDir = $"{pathToBuiltProject}/Libraries/libil2cpp";
|
||||
string lumpDir = $"{pathToBuiltProject}/Libraries/lumps";
|
||||
string srcExternalDir = $"{SettingsUtil.LocalIl2CppDir}/external";
|
||||
string dstExternalDir = $"{pathToBuiltProject}/Libraries/external";
|
||||
//RemoveExternalLibil2cppOption(srcExternalDir, dstExternalDir);
|
||||
CopyLibil2cppToXcodeProj(srcLibil2cppDir, dstLibil2cppDir);
|
||||
CopyExternalToXcodeProj(srcExternalDir, dstExternalDir);
|
||||
var lumpFiles = CreateLumps(dstLibil2cppDir, lumpDir);
|
||||
var extraSources = GetExtraSourceFiles(dstExternalDir, dstLibil2cppDir);
|
||||
var cflags = new List<string>()
|
||||
{
|
||||
"-DIL2CPP_MONO_DEBUGGER_DISABLED",
|
||||
};
|
||||
ModifyPBXProject(pathToBuiltProject, pbxprojFile, lumpFiles, extraSources, cflags);
|
||||
AddSystemHeaderToPrefixPch(pathToBuiltProject);
|
||||
}
|
||||
|
||||
private static void AddSystemHeaderToPrefixPch(string pathToBuiltProject)
|
||||
{
|
||||
// 如果不将 stdio.h 添加到 Prefix.pch, zutil.c会有编译错误
|
||||
string prefixPchFile = $"{pathToBuiltProject}/Classes/Prefix.pch";
|
||||
string fileContent = File.ReadAllText(prefixPchFile, Encoding.UTF8);
|
||||
if (!fileContent.Contains("stdio.h"))
|
||||
{
|
||||
string newFileContent = fileContent + "\n#include <stdio.h>\n";
|
||||
File.WriteAllText(prefixPchFile, newFileContent, Encoding.UTF8);
|
||||
UnityEngine.Debug.Log($"append header to {prefixPchFile}");
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetRelativePathFromProj(string path)
|
||||
{
|
||||
return path.Substring(path.IndexOf("Libraries", StringComparison.Ordinal)).Replace('\\', '/');
|
||||
}
|
||||
|
||||
private static void ModifyPBXProject(string pathToBuiltProject, string pbxprojFile, List<LumpFile> lumpFiles, List<string> extraFiles, List<string> cflags)
|
||||
{
|
||||
var proj = new PBXProject();
|
||||
proj.ReadFromFile(pbxprojFile);
|
||||
string targetGUID = proj.GetUnityFrameworkTargetGuid();
|
||||
// 移除旧的libil2cpp.a
|
||||
var libil2cppGUID = proj.FindFileGuidByProjectPath("Libraries/libil2cpp.a");
|
||||
if (!string.IsNullOrEmpty(libil2cppGUID))
|
||||
{
|
||||
proj.RemoveFileFromBuild(targetGUID, libil2cppGUID);
|
||||
proj.RemoveFile(libil2cppGUID);
|
||||
File.Delete(Path.Combine(pathToBuiltProject, "Libraries", "libil2cpp.a"));
|
||||
}
|
||||
|
||||
//var lumpGroupGuid = proj.AddFile("Lumps", $"Classes/Lumps", PBXSourceTree.Group);
|
||||
|
||||
foreach (var lumpFile in lumpFiles)
|
||||
{
|
||||
string lumpFileName = Path.GetFileName(lumpFile.lumpFile);
|
||||
string projPathOfFile = $"Classes/Lumps/{lumpFileName}";
|
||||
string relativePathOfFile = GetRelativePathFromProj(lumpFile.lumpFile);
|
||||
string lumpGuid = proj.FindFileGuidByProjectPath(projPathOfFile);
|
||||
if (!string.IsNullOrEmpty(lumpGuid))
|
||||
{
|
||||
proj.RemoveFileFromBuild(targetGUID, lumpGuid);
|
||||
proj.RemoveFile(lumpGuid);
|
||||
}
|
||||
lumpGuid = proj.AddFile(relativePathOfFile, projPathOfFile, PBXSourceTree.Source);
|
||||
proj.AddFileToBuild(targetGUID, lumpGuid);
|
||||
}
|
||||
|
||||
foreach (var extraFile in extraFiles)
|
||||
{
|
||||
string projPathOfFile = $"Classes/Extrals/{Path.GetFileName(extraFile)}";
|
||||
string extraFileGuid = proj.FindFileGuidByProjectPath(projPathOfFile);
|
||||
if (!string.IsNullOrEmpty(extraFileGuid))
|
||||
{
|
||||
proj.RemoveFileFromBuild(targetGUID, extraFileGuid);
|
||||
proj.RemoveFile(extraFileGuid);
|
||||
//Debug.LogWarning($"remove exist extra file:{projPathOfFile} guid:{extraFileGuid}");
|
||||
}
|
||||
var lumpGuid = proj.AddFile(GetRelativePathFromProj(extraFile), projPathOfFile, PBXSourceTree.Source);
|
||||
proj.AddFileToBuild(targetGUID, lumpGuid);
|
||||
}
|
||||
|
||||
foreach(var configName in proj.BuildConfigNames())
|
||||
{
|
||||
//Debug.Log($"build config:{bcn}");
|
||||
string configGuid = proj.BuildConfigByName(targetGUID, configName);
|
||||
string headerSearchPaths = "HEADER_SEARCH_PATHS";
|
||||
string hspProp = proj.GetBuildPropertyForConfig(configGuid, headerSearchPaths);
|
||||
//Debug.Log($"config guid:{configGuid} prop:{hspProp}");
|
||||
string newPro = hspProp.Replace("libil2cpp/include", "libil2cpp")
|
||||
.Replace("Libraries/bdwgc", "Libraries/external/bdwgc");
|
||||
|
||||
//if (!newPro.Contains("Libraries/libil2cpp/os/ClassLibraryPAL/brotli/include"))
|
||||
//{
|
||||
// newPro += " $(SRCROOT)/Libraries/libil2cpp/os/ClassLibraryPAL/brotli/include";
|
||||
//}
|
||||
if (!newPro.Contains("Libraries/external/xxHash"))
|
||||
{
|
||||
newPro += " $(SRCROOT)/Libraries/external/xxHash";
|
||||
}
|
||||
newPro += " $(SRCR00T)/Libraries/external/mono";
|
||||
//Debug.Log($"config:{bcn} new prop:{newPro}");
|
||||
proj.SetBuildPropertyForConfig(configGuid, headerSearchPaths, newPro);
|
||||
|
||||
string cflagKey = "OTHER_CFLAGS";
|
||||
string cfProp = proj.GetBuildPropertyForConfig(configGuid, cflagKey);
|
||||
foreach (var flag in cflags)
|
||||
{
|
||||
if (!cfProp.Contains(flag))
|
||||
{
|
||||
cfProp += " " + flag;
|
||||
}
|
||||
}
|
||||
if (configName.Contains("Debug") && !cfProp.Contains("-DIL2CPP_DEBUG="))
|
||||
{
|
||||
cfProp += " -DIL2CPP_DEBUG=1 -DDEBUG=1";
|
||||
}
|
||||
proj.SetBuildPropertyForConfig(configGuid, cflagKey, cfProp);
|
||||
|
||||
}
|
||||
proj.WriteToFile(pbxprojFile);
|
||||
}
|
||||
|
||||
private static void CopyLibil2cppToXcodeProj(string srcLibil2cppDir, string dstLibil2cppDir)
|
||||
{
|
||||
BashUtil.RemoveDir(dstLibil2cppDir);
|
||||
BashUtil.CopyDir(srcLibil2cppDir, dstLibil2cppDir, true);
|
||||
}
|
||||
|
||||
|
||||
private static void CopyExternalToXcodeProj(string srcExternalDir, string dstExternalDir)
|
||||
{
|
||||
BashUtil.RemoveDir(dstExternalDir);
|
||||
BashUtil.CopyDir(srcExternalDir, dstExternalDir, true);
|
||||
|
||||
//string baselibPlatfromsDir = $"{dstExternalDir}/baselib/Platforms";
|
||||
//BashUtil.RemoveDir($"{baselibPlatfromsDir}/IOS");
|
||||
//BashUtil.CopyDir($"{baselibPlatfromsDir}/OSX", $"{baselibPlatfromsDir}/IOS", true);
|
||||
}
|
||||
|
||||
class LumpFile
|
||||
{
|
||||
public List<string> cppFiles = new List<string>();
|
||||
|
||||
public readonly string lumpFile;
|
||||
|
||||
public readonly string il2cppConfigFile;
|
||||
|
||||
public LumpFile(string lumpFile, string il2cppConfigFile)
|
||||
{
|
||||
this.lumpFile = lumpFile;
|
||||
this.il2cppConfigFile = il2cppConfigFile;
|
||||
this.cppFiles.Add(il2cppConfigFile);
|
||||
}
|
||||
|
||||
public void SaveFile()
|
||||
{
|
||||
var lumpFileContent = new List<string>();
|
||||
foreach (var file in cppFiles)
|
||||
{
|
||||
lumpFileContent.Add($"#include \"{GetRelativePathFromProj(file)}\"");
|
||||
}
|
||||
File.WriteAllLines(lumpFile, lumpFileContent, Encoding.UTF8);
|
||||
Debug.Log($"create lump file:{lumpFile}");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<LumpFile> CreateLumps(string libil2cppDir, string outputDir)
|
||||
{
|
||||
BashUtil.RecreateDir(outputDir);
|
||||
|
||||
string il2cppConfigFile = $"{libil2cppDir}/il2cpp-config.h";
|
||||
var lumpFiles = new List<LumpFile>();
|
||||
int lumpFileIndex = 0;
|
||||
foreach (var cppDir in Directory.GetDirectories(libil2cppDir, "*", SearchOption.AllDirectories).Concat(new string[] {libil2cppDir}))
|
||||
{
|
||||
var lumpFile = new LumpFile($"{outputDir}/lump_{Path.GetFileName(cppDir)}_{lumpFileIndex}.cpp", il2cppConfigFile);
|
||||
foreach (var file in Directory.GetFiles(cppDir, "*.cpp", SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
lumpFile.cppFiles.Add(file);
|
||||
}
|
||||
lumpFile.SaveFile();
|
||||
lumpFiles.Add(lumpFile);
|
||||
++lumpFileIndex;
|
||||
}
|
||||
|
||||
var mmFiles = Directory.GetFiles(libil2cppDir, "*.mm", SearchOption.AllDirectories);
|
||||
if (mmFiles.Length > 0)
|
||||
{
|
||||
var lumpFile = new LumpFile($"{outputDir}/lump_mm.mm", il2cppConfigFile);
|
||||
foreach (var file in mmFiles)
|
||||
{
|
||||
lumpFile.cppFiles.Add(file);
|
||||
}
|
||||
lumpFile.SaveFile();
|
||||
lumpFiles.Add(lumpFile);
|
||||
}
|
||||
return lumpFiles;
|
||||
}
|
||||
|
||||
private static List<string> GetExtraSourceFiles(string externalDir, string libil2cppDir)
|
||||
{
|
||||
var files = new List<string>();
|
||||
foreach (string extraDir in new string[]
|
||||
{
|
||||
$"{externalDir}/zlib",
|
||||
$"{externalDir}/xxHash",
|
||||
$"{libil2cppDir}/os/ClassLibraryPAL/brotli",
|
||||
})
|
||||
{
|
||||
if (!Directory.Exists(extraDir))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
files.AddRange(Directory.GetFiles(extraDir, "*.c", SearchOption.AllDirectories));
|
||||
}
|
||||
return files;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2f62ca12f2eb4f2fba8e9cb51279421
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using HybridCLR.Editor.Installer;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using System.Reflection;
|
||||
using HybridCLR.Editor.Settings;
|
||||
#if (UNITY_2020 || UNITY_2021) && (UNITY_IOS || UNITY_TVOS)
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEditor.iOS.Xcode;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
public static class AddLil2cppSourceCodeToXcodeproj2020Or2021
|
||||
{
|
||||
|
||||
[PostProcessBuild]
|
||||
public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
|
||||
{
|
||||
if (!HybridCLRSettings.Instance.enable)
|
||||
return;
|
||||
/*
|
||||
* 1. 生成lump,并且添加到工程
|
||||
3. 将libil2cpp目录复制到 Library/. 删除旧的. search paths里修改 libil2cpp/include为libil2cpp
|
||||
3. Libraries/bdwgc/include -> Libraries/external/bdwgc/include
|
||||
4. 将external目录复制到 Library/external。删除旧目录
|
||||
5. 将Library/external/baselib/Platforms/OSX改名为 IOS 全大写
|
||||
6. 将 external/zlib下c 文件添加到工程
|
||||
7. 移除libil2cpp.a
|
||||
8. Include path add libil2cpp/os/ClassLibraryPAL/brotli/include
|
||||
9. add external/xxHash
|
||||
*/
|
||||
|
||||
string pbxprojFile = BuildProcessorUtil.GetXcodeProjectFile(pathToBuiltProject);
|
||||
string srcLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";
|
||||
string dstLibil2cppDir = $"{pathToBuiltProject}/Libraries/libil2cpp";
|
||||
string lumpDir = $"{pathToBuiltProject}/Libraries/lumps";
|
||||
string srcExternalDir = $"{SettingsUtil.LocalIl2CppDir}/external";
|
||||
string dstExternalDir = $"{pathToBuiltProject}/Libraries/external";
|
||||
//RemoveExternalLibil2cppOption(srcExternalDir, dstExternalDir);
|
||||
CopyLibil2cppToXcodeProj(srcLibil2cppDir, dstLibil2cppDir);
|
||||
CopyExternalToXcodeProj(srcExternalDir, dstExternalDir);
|
||||
var lumpFiles = CreateLumps(dstLibil2cppDir, lumpDir);
|
||||
var extraSources = GetExtraSourceFiles(dstExternalDir, dstLibil2cppDir);
|
||||
var cflags = new List<string>()
|
||||
{
|
||||
"-DIL2CPP_MONO_DEBUGGER_DISABLED",
|
||||
};
|
||||
ModifyPBXProject(pathToBuiltProject, pbxprojFile, lumpFiles, extraSources, cflags);
|
||||
}
|
||||
|
||||
private static string GetRelativePathFromProj(string path)
|
||||
{
|
||||
return path.Substring(path.IndexOf("Libraries", StringComparison.Ordinal)).Replace('\\', '/');
|
||||
}
|
||||
|
||||
private static void ModifyPBXProject(string pathToBuiltProject, string pbxprojFile, List<LumpFile> lumpFiles, List<string> extraFiles, List<string> cflags)
|
||||
{
|
||||
var proj = new PBXProject();
|
||||
proj.ReadFromFile(pbxprojFile);
|
||||
string targetGUID = proj.GetUnityFrameworkTargetGuid();
|
||||
// 移除旧的libil2cpp.a
|
||||
var libil2cppGUID = proj.FindFileGuidByProjectPath("Libraries/libil2cpp.a");
|
||||
if (!string.IsNullOrEmpty(libil2cppGUID))
|
||||
{
|
||||
proj.RemoveFileFromBuild(targetGUID, libil2cppGUID);
|
||||
proj.RemoveFile(libil2cppGUID);
|
||||
File.Delete(Path.Combine(pathToBuiltProject, "Libraries", "libil2cpp.a"));
|
||||
}
|
||||
|
||||
//var lumpGroupGuid = proj.AddFile("Lumps", $"Classes/Lumps", PBXSourceTree.Group);
|
||||
|
||||
foreach (var lumpFile in lumpFiles)
|
||||
{
|
||||
string lumpFileName = Path.GetFileName(lumpFile.lumpFile);
|
||||
string projPathOfFile = $"Classes/Lumps/{lumpFileName}";
|
||||
string relativePathOfFile = GetRelativePathFromProj(lumpFile.lumpFile);
|
||||
string lumpGuid = proj.FindFileGuidByProjectPath(projPathOfFile);
|
||||
if (!string.IsNullOrEmpty(lumpGuid))
|
||||
{
|
||||
proj.RemoveFileFromBuild(targetGUID, lumpGuid);
|
||||
proj.RemoveFile(lumpGuid);
|
||||
}
|
||||
lumpGuid = proj.AddFile(relativePathOfFile, projPathOfFile, PBXSourceTree.Source);
|
||||
proj.AddFileToBuild(targetGUID, lumpGuid);
|
||||
}
|
||||
|
||||
foreach (var extraFile in extraFiles)
|
||||
{
|
||||
string projPathOfFile = $"Classes/Extrals/{Path.GetFileName(extraFile)}";
|
||||
string extraFileGuid = proj.FindFileGuidByProjectPath(projPathOfFile);
|
||||
if (!string.IsNullOrEmpty(extraFileGuid))
|
||||
{
|
||||
proj.RemoveFileFromBuild(targetGUID, extraFileGuid);
|
||||
proj.RemoveFile(extraFileGuid);
|
||||
//Debug.LogWarning($"remove exist extra file:{projPathOfFile} guid:{extraFileGuid}");
|
||||
}
|
||||
var lumpGuid = proj.AddFile(GetRelativePathFromProj(extraFile), projPathOfFile, PBXSourceTree.Source);
|
||||
proj.AddFileToBuild(targetGUID, lumpGuid);
|
||||
}
|
||||
|
||||
foreach(var configName in proj.BuildConfigNames())
|
||||
{
|
||||
//Debug.Log($"build config:{bcn}");
|
||||
string configGuid = proj.BuildConfigByName(targetGUID, configName);
|
||||
string headerSearchPaths = "HEADER_SEARCH_PATHS";
|
||||
string hspProp = proj.GetBuildPropertyForConfig(configGuid, headerSearchPaths);
|
||||
//Debug.Log($"config guid:{configGuid} prop:{hspProp}");
|
||||
string newPro = hspProp.Replace("libil2cpp/include", "libil2cpp")
|
||||
.Replace("Libraries/bdwgc", "Libraries/external/bdwgc");
|
||||
|
||||
if (!newPro.Contains("Libraries/libil2cpp/os/ClassLibraryPAL/brotli/include"))
|
||||
{
|
||||
newPro += " $(SRCROOT)/Libraries/libil2cpp/os/ClassLibraryPAL/brotli/include";
|
||||
}
|
||||
if (!newPro.Contains("Libraries/external/xxHash"))
|
||||
{
|
||||
newPro += " $(SRCROOT)/Libraries/external/xxHash";
|
||||
}
|
||||
newPro += " $(SRCR00T)/Libraries/external/mono";
|
||||
//Debug.Log($"config:{bcn} new prop:{newPro}");
|
||||
proj.SetBuildPropertyForConfig(configGuid, headerSearchPaths, newPro);
|
||||
|
||||
string cflagKey = "OTHER_CFLAGS";
|
||||
string cfProp = proj.GetBuildPropertyForConfig(configGuid, cflagKey);
|
||||
foreach (var flag in cflags)
|
||||
{
|
||||
if (!cfProp.Contains(flag))
|
||||
{
|
||||
cfProp += " " + flag;
|
||||
}
|
||||
}
|
||||
if (configName.Contains("Debug") && !cfProp.Contains("-DIL2CPP_DEBUG="))
|
||||
{
|
||||
cfProp += " -DIL2CPP_DEBUG=1 -DDEBUG=1";
|
||||
}
|
||||
proj.SetBuildPropertyForConfig(configGuid, cflagKey, cfProp);
|
||||
|
||||
}
|
||||
proj.WriteToFile(pbxprojFile);
|
||||
}
|
||||
|
||||
private static void CopyLibil2cppToXcodeProj(string srcLibil2cppDir, string dstLibil2cppDir)
|
||||
{
|
||||
BashUtil.RemoveDir(dstLibil2cppDir);
|
||||
BashUtil.CopyDir(srcLibil2cppDir, dstLibil2cppDir, true);
|
||||
}
|
||||
|
||||
|
||||
private static void CopyExternalToXcodeProj(string srcExternalDir, string dstExternalDir)
|
||||
{
|
||||
BashUtil.RemoveDir(dstExternalDir);
|
||||
BashUtil.CopyDir(srcExternalDir, dstExternalDir, true);
|
||||
|
||||
string baselibPlatfromsDir = $"{dstExternalDir}/baselib/Platforms";
|
||||
BashUtil.RemoveDir($"{baselibPlatfromsDir}/IOS");
|
||||
BashUtil.CopyDir($"{baselibPlatfromsDir}/OSX", $"{baselibPlatfromsDir}/IOS", true);
|
||||
}
|
||||
|
||||
class LumpFile
|
||||
{
|
||||
public List<string> cppFiles = new List<string>();
|
||||
|
||||
public readonly string lumpFile;
|
||||
|
||||
public readonly string il2cppConfigFile;
|
||||
|
||||
public LumpFile(string lumpFile, string il2cppConfigFile)
|
||||
{
|
||||
this.lumpFile = lumpFile;
|
||||
this.il2cppConfigFile = il2cppConfigFile;
|
||||
this.cppFiles.Add(il2cppConfigFile);
|
||||
}
|
||||
|
||||
public void SaveFile()
|
||||
{
|
||||
var lumpFileContent = new List<string>();
|
||||
foreach (var file in cppFiles)
|
||||
{
|
||||
lumpFileContent.Add($"#include \"{GetRelativePathFromProj(file)}\"");
|
||||
}
|
||||
File.WriteAllLines(lumpFile, lumpFileContent, Encoding.UTF8);
|
||||
Debug.Log($"create lump file:{lumpFile}");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<LumpFile> CreateLumps(string libil2cppDir, string outputDir)
|
||||
{
|
||||
BashUtil.RecreateDir(outputDir);
|
||||
|
||||
string il2cppConfigFile = $"{libil2cppDir}/il2cpp-config.h";
|
||||
var lumpFiles = new List<LumpFile>();
|
||||
int lumpFileIndex = 0;
|
||||
foreach (var cppDir in Directory.GetDirectories(libil2cppDir, "*", SearchOption.AllDirectories).Concat(new string[] {libil2cppDir}))
|
||||
{
|
||||
var lumpFile = new LumpFile($"{outputDir}/lump_{Path.GetFileName(cppDir)}_{lumpFileIndex}.cpp", il2cppConfigFile);
|
||||
foreach (var file in Directory.GetFiles(cppDir, "*.cpp", SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
lumpFile.cppFiles.Add(file);
|
||||
}
|
||||
lumpFile.SaveFile();
|
||||
lumpFiles.Add(lumpFile);
|
||||
++lumpFileIndex;
|
||||
}
|
||||
|
||||
var mmFiles = Directory.GetFiles(libil2cppDir, "*.mm", SearchOption.AllDirectories);
|
||||
if (mmFiles.Length > 0)
|
||||
{
|
||||
var lumpFile = new LumpFile($"{outputDir}/lump_mm.mm", il2cppConfigFile);
|
||||
foreach (var file in mmFiles)
|
||||
{
|
||||
lumpFile.cppFiles.Add(file);
|
||||
}
|
||||
lumpFile.SaveFile();
|
||||
lumpFiles.Add(lumpFile);
|
||||
}
|
||||
return lumpFiles;
|
||||
}
|
||||
|
||||
private static List<string> GetExtraSourceFiles(string externalDir, string libil2cppDir)
|
||||
{
|
||||
var files = new List<string>();
|
||||
foreach (string extraDir in new string[]
|
||||
{
|
||||
$"{externalDir}/zlib",
|
||||
$"{externalDir}/xxHash",
|
||||
$"{libil2cppDir}/os/ClassLibraryPAL/brotli",
|
||||
})
|
||||
{
|
||||
if (!Directory.Exists(extraDir))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
files.AddRange(Directory.GetFiles(extraDir, "*.c", SearchOption.AllDirectories));
|
||||
}
|
||||
return files;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61948fcb1bc40ba47b8c10b0ae801ebb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,82 @@
|
||||
using HybridCLR.Editor.Installer;
|
||||
using HybridCLR.Editor.Settings;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEngine;
|
||||
|
||||
#if UNITY_2022 && (UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS)
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
public static class AddLil2cppSourceCodeToXcodeproj2022OrNewer
|
||||
{
|
||||
|
||||
[PostProcessBuild]
|
||||
public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
|
||||
{
|
||||
if (!HybridCLRSettings.Instance.enable)
|
||||
return;
|
||||
string pbxprojFile = BuildProcessorUtil.GetXcodeProjectFile(pathToBuiltProject);
|
||||
RemoveExternalLibil2cppOption(pbxprojFile);
|
||||
CopyLibil2cppToXcodeProj(pathToBuiltProject);
|
||||
}
|
||||
|
||||
private static string TryRemoveDunplicateShellScriptSegment(string pbxprojFile, string pbxprojContent)
|
||||
{
|
||||
// will appear duplicated Shell Script segment when append to existed xcode project.
|
||||
// This is unity bug.
|
||||
// we remove duplicated Shell Script to avoid build error.
|
||||
string copyFileComment = @"/\* CopyFiles \*/,\s+([A-Z0-9]{24}) /\* ShellScript \*/,\s+([A-Z0-9]{24}) /\* ShellScript \*/,";
|
||||
var m = Regex.Match(pbxprojContent, copyFileComment, RegexOptions.Multiline);
|
||||
if (!m.Success)
|
||||
{
|
||||
return pbxprojContent;
|
||||
}
|
||||
|
||||
if (m.Groups[1].Value != m.Groups[2].Value)
|
||||
{
|
||||
throw new BuildFailedException($"find invalid /* ShellScript */ segment");
|
||||
}
|
||||
|
||||
int startIndexOfDupShellScript = m.Groups[2].Index;
|
||||
int endIndexOfDupShellScript = pbxprojContent.IndexOf(",", startIndexOfDupShellScript);
|
||||
|
||||
pbxprojContent = pbxprojContent.Remove(startIndexOfDupShellScript, endIndexOfDupShellScript + 1 - startIndexOfDupShellScript);
|
||||
Debug.LogWarning($"[AddLil2cppSourceCodeToXcodeproj] remove duplicated '/* ShellScript */' from file '{pbxprojFile}'");
|
||||
return pbxprojContent;
|
||||
}
|
||||
|
||||
private static void RemoveExternalLibil2cppOption(string pbxprojFile)
|
||||
{
|
||||
string pbxprojContent = File.ReadAllText(pbxprojFile, Encoding.UTF8);
|
||||
string removeBuildOption = @"--external-lib-il2-cpp=\""$PROJECT_DIR/Libraries/libil2cpp.a\""";
|
||||
if (pbxprojContent.Contains(removeBuildOption))
|
||||
{
|
||||
pbxprojContent = pbxprojContent.Replace(removeBuildOption, "");
|
||||
Debug.Log($"[AddLil2cppSourceCodeToXcodeproj] remove il2cpp build option '{removeBuildOption}' from file '{pbxprojFile}'");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[AddLil2cppSourceCodeToXcodeproj] project.pbxproj remove building option:'{removeBuildOption}' fail. This may occur when 'Append' to existing xcode project in building");
|
||||
}
|
||||
|
||||
pbxprojContent = TryRemoveDunplicateShellScriptSegment(pbxprojFile, pbxprojContent);
|
||||
|
||||
|
||||
File.WriteAllText(pbxprojFile, pbxprojContent, Encoding.UTF8);
|
||||
}
|
||||
|
||||
private static void CopyLibil2cppToXcodeProj(string pathToBuiltProject)
|
||||
{
|
||||
string srcLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";
|
||||
string destLibil2cppDir = $"{pathToBuiltProject}/Il2CppOutputProject/IL2CPP/libil2cpp";
|
||||
BashUtil.RemoveDir(destLibil2cppDir);
|
||||
BashUtil.CopyDir(srcLibil2cppDir, destLibil2cppDir, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4ce072f7e4a17248a3d9ebfd011356b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,34 @@
|
||||
using HybridCLR.Editor.Installer;
|
||||
using HybridCLR.Editor.Settings;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEngine;
|
||||
|
||||
#if UNITY_2023_1_OR_NEWER && (UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS)
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
public static class AddLil2cppSourceCodeToXcodeproj2022OrNewer
|
||||
{
|
||||
|
||||
[PostProcessBuild]
|
||||
public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
|
||||
{
|
||||
if (!HybridCLRSettings.Instance.enable)
|
||||
return;
|
||||
CopyLibil2cppToXcodeProj(pathToBuiltProject);
|
||||
}
|
||||
|
||||
private static void CopyLibil2cppToXcodeProj(string pathToBuiltProject)
|
||||
{
|
||||
string srcLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";
|
||||
string destLibil2cppDir = $"{pathToBuiltProject}/Il2CppOutputProject/IL2CPP/libil2cpp";
|
||||
BashUtil.RemoveDir(destLibil2cppDir);
|
||||
BashUtil.CopyDir(srcLibil2cppDir, destLibil2cppDir, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2fa46135129b046a28014d58fdfd18ca
|
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor.Build;
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
|
||||
public static class BuildProcessorUtil
|
||||
{
|
||||
|
||||
public static string GetXcodeProjectFile(string pathToBuiltProject)
|
||||
{
|
||||
foreach (string dir in Directory.GetDirectories(pathToBuiltProject, "*.xcodeproj", SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
string pbxprojFile = $"{dir}/project.pbxproj";
|
||||
if (File.Exists(pbxprojFile))
|
||||
{
|
||||
return pbxprojFile;
|
||||
}
|
||||
}
|
||||
throw new BuildFailedException($"can't find xxxx.xcodeproj/project.pbxproj in {pathToBuiltProject}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c680e56f90f2745298a90803c04f6efc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,94 @@
|
||||
using HybridCLR.Editor.Settings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEngine;
|
||||
using static UnityEngine.GraphicsBuffer;
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
internal class CheckSettings : IPreprocessBuildWithReport
|
||||
{
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public static bool DisableMethodBridgeDevelopmentFlagChecking { get; set; }
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
HybridCLRSettings globalSettings = SettingsUtil.HybridCLRSettings;
|
||||
if (!globalSettings.enable || globalSettings.useGlobalIl2cpp)
|
||||
{
|
||||
string oldIl2cppPath = Environment.GetEnvironmentVariable("UNITY_IL2CPP_PATH");
|
||||
if (!string.IsNullOrEmpty(oldIl2cppPath))
|
||||
{
|
||||
Environment.SetEnvironmentVariable("UNITY_IL2CPP_PATH", "");
|
||||
Debug.Log($"[CheckSettings] clean process environment variable: UNITY_IL2CPP_PATH, old vlaue:'{oldIl2cppPath}'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string curIl2cppPath = Environment.GetEnvironmentVariable("UNITY_IL2CPP_PATH");
|
||||
if (curIl2cppPath != SettingsUtil.LocalIl2CppDir)
|
||||
{
|
||||
Environment.SetEnvironmentVariable("UNITY_IL2CPP_PATH", SettingsUtil.LocalIl2CppDir);
|
||||
Debug.Log($"[CheckSettings] UNITY_IL2CPP_PATH old value:'{curIl2cppPath}', new value:'{SettingsUtil.LocalIl2CppDir}'");
|
||||
}
|
||||
}
|
||||
if (!globalSettings.enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
|
||||
ScriptingImplementation curScriptingImplementation = PlayerSettings.GetScriptingBackend(buildTargetGroup);
|
||||
ScriptingImplementation targetScriptingImplementation = ScriptingImplementation.IL2CPP;
|
||||
if (curScriptingImplementation != targetScriptingImplementation)
|
||||
{
|
||||
Debug.LogError($"[CheckSettings] current ScriptingBackend:{curScriptingImplementation},have been switched to:{targetScriptingImplementation} automatically");
|
||||
PlayerSettings.SetScriptingBackend(buildTargetGroup, targetScriptingImplementation);
|
||||
}
|
||||
|
||||
var installer = new Installer.InstallerController();
|
||||
if (!installer.HasInstalledHybridCLR())
|
||||
{
|
||||
throw new BuildFailedException($"You have not initialized HybridCLR, please install it via menu 'HybridCLR/Installer'");
|
||||
}
|
||||
|
||||
if (installer.PackageVersion != installer.InstalledLibil2cppVersion)
|
||||
{
|
||||
throw new BuildFailedException($"You must run `HybridCLR/Installer` after upgrading package");
|
||||
}
|
||||
|
||||
HybridCLRSettings gs = SettingsUtil.HybridCLRSettings;
|
||||
if (((gs.hotUpdateAssemblies?.Length + gs.hotUpdateAssemblyDefinitions?.Length) ?? 0) == 0)
|
||||
{
|
||||
Debug.LogWarning("[CheckSettings] No hot update modules configured in HybridCLRSettings");
|
||||
}
|
||||
|
||||
if (!DisableMethodBridgeDevelopmentFlagChecking)
|
||||
{
|
||||
string methodBridgeFile = $"{SettingsUtil.GeneratedCppDir}/MethodBridge.cpp";
|
||||
var match = Regex.Match(File.ReadAllText(methodBridgeFile), @"// DEVELOPMENT=(\d)");
|
||||
if (match.Success)
|
||||
{
|
||||
int developmentFlagInMethodBridge = int.Parse(match.Groups[1].Value);
|
||||
int developmentFlagInEditorSettings = EditorUserBuildSettings.development ? 1 : 0;
|
||||
if (developmentFlagInMethodBridge != developmentFlagInEditorSettings)
|
||||
{
|
||||
Debug.LogError($"[CheckSettings] MethodBridge.cpp DEVELOPMENT flag:{developmentFlagInMethodBridge} is inconsistent with EditorUserBuildSettings.development:{developmentFlagInEditorSettings}. Please run 'HybridCLR/Generate/All' before building.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[CheckSettings] MethodBridge.cpp DEVELOPMENT flag not found. Please run 'HybridCLR/Generate/All' before building.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb4ba063068b17247b2d0233420aa5f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,134 @@
|
||||
using HybridCLR.Editor.Installer;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEditor.UnityLinker;
|
||||
using UnityEngine;
|
||||
#if !UNITY_2021_1_OR_NEWER
|
||||
using UnityEditor.Il2Cpp;
|
||||
#endif
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
internal class CopyStrippedAOTAssemblies : IPostprocessBuildWithReport, IPreprocessBuildWithReport
|
||||
#if !UNITY_2021_1_OR_NEWER
|
||||
, IIl2CppProcessor
|
||||
#endif
|
||||
{
|
||||
|
||||
public int callbackOrder => 0;
|
||||
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
public static string GetStripAssembliesDir2021(BuildTarget target)
|
||||
{
|
||||
string projectDir = SettingsUtil.ProjectDir;
|
||||
switch (target)
|
||||
{
|
||||
case BuildTarget.StandaloneWindows:
|
||||
case BuildTarget.StandaloneWindows64:
|
||||
return $"{projectDir}/Library/Bee/artifacts/WinPlayerBuildProgram/ManagedStripped";
|
||||
case BuildTarget.StandaloneLinux64:
|
||||
return $"{projectDir}/Library/Bee/artifacts/LinuxPlayerBuildProgram/ManagedStripped";
|
||||
case BuildTarget.WSAPlayer:
|
||||
return $"{projectDir}/Library/Bee/artifacts/UWPPlayerBuildProgram/ManagedStripped";
|
||||
case BuildTarget.Android:
|
||||
return $"{projectDir}/Library/Bee/artifacts/Android/ManagedStripped";
|
||||
#if TUANJIE_2022_3_OR_NEWER
|
||||
case BuildTarget.HMIAndroid:
|
||||
return $"{projectDir}/Library/Bee/artifacts/HMIAndroid/ManagedStripped";
|
||||
#endif
|
||||
case BuildTarget.iOS:
|
||||
#if UNITY_TVOS
|
||||
case BuildTarget.tvOS:
|
||||
#endif
|
||||
return $"{projectDir}/Library/Bee/artifacts/iOS/ManagedStripped";
|
||||
#if UNITY_VISIONOS
|
||||
case BuildTarget.VisionOS:
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
return $"{projectDir}/Library/Bee/artifacts/VisionOS/ManagedStripped";
|
||||
#else
|
||||
return $"{projectDir}/Library/Bee/artifacts/iOS/ManagedStripped";
|
||||
#endif
|
||||
#endif
|
||||
case BuildTarget.WebGL:
|
||||
return $"{projectDir}/Library/Bee/artifacts/WebGL/ManagedStripped";
|
||||
case BuildTarget.StandaloneOSX:
|
||||
return $"{projectDir}/Library/Bee/artifacts/MacStandalonePlayerBuildProgram/ManagedStripped";
|
||||
case BuildTarget.PS4:
|
||||
return $"{projectDir}/Library/Bee/artifacts/PS4PlayerBuildProgram/ManagedStripped";
|
||||
case BuildTarget.PS5:
|
||||
return $"{projectDir}/Library/Bee/artifacts/PS5PlayerBuildProgram/ManagedStripped";
|
||||
#if UNITY_WEIXINMINIGAME
|
||||
case BuildTarget.WeixinMiniGame:
|
||||
return $"{projectDir}/Library/Bee/artifacts/WeixinMiniGame/ManagedStripped";
|
||||
#endif
|
||||
#if UNITY_OPENHARMONY
|
||||
case BuildTarget.OpenHarmony:
|
||||
return $"{projectDir}/Library/Bee/artifacts/OpenHarmonyPlayerBuildProgram/ManagedStripped";
|
||||
#endif
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
#else
|
||||
private string GetStripAssembliesDir2020(BuildTarget target)
|
||||
{
|
||||
string subPath = target == BuildTarget.Android ?
|
||||
"assets/bin/Data/Managed" :
|
||||
"Data/Managed/";
|
||||
return $"{SettingsUtil.ProjectDir}/Temp/StagingArea/{subPath}";
|
||||
}
|
||||
|
||||
public void OnBeforeConvertRun(BuildReport report, Il2CppBuildPipelineData data)
|
||||
{
|
||||
BuildTarget target = report.summary.platform;
|
||||
CopyStripDlls(GetStripAssembliesDir2020(target), target);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void CopyStripDlls(string srcStripDllPath, BuildTarget target)
|
||||
{
|
||||
if (!SettingsUtil.Enable)
|
||||
{
|
||||
Debug.Log($"[CopyStrippedAOTAssemblies] disabled");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"[CopyStrippedAOTAssemblies] CopyScripDlls. src:{srcStripDllPath} target:{target}");
|
||||
|
||||
var dstPath = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
|
||||
|
||||
Directory.CreateDirectory(dstPath);
|
||||
|
||||
foreach (var fileFullPath in Directory.GetFiles(srcStripDllPath, "*.dll"))
|
||||
{
|
||||
var file = Path.GetFileName(fileFullPath);
|
||||
Debug.Log($"[CopyStrippedAOTAssemblies] copy strip dll {fileFullPath} ==> {dstPath}/{file}");
|
||||
File.Copy($"{fileFullPath}", $"{dstPath}/{file}", true);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPostprocessBuild(BuildReport report)
|
||||
{
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
BuildTarget target = report.summary.platform;
|
||||
string srcStripDllPath = GetStripAssembliesDir2021(target);
|
||||
if (!string.IsNullOrEmpty(srcStripDllPath) && Directory.Exists(srcStripDllPath))
|
||||
{
|
||||
CopyStripDlls(srcStripDllPath, target);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
BuildTarget target = report.summary.platform;
|
||||
var dstPath = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
|
||||
BashUtil.RecreateDir(dstPath);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7884710ec2f8e545b3fe9aa05def5a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,68 @@
|
||||
using HybridCLR.Editor.Meta;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
/// <summary>
|
||||
/// 将热更新dll从Build过程中过滤,防止打包到主工程中
|
||||
/// </summary>
|
||||
internal class FilterHotFixAssemblies : IFilterBuildAssemblies
|
||||
{
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public string[] OnFilterAssemblies(BuildOptions buildOptions, string[] assemblies)
|
||||
{
|
||||
if (!SettingsUtil.Enable)
|
||||
{
|
||||
Debug.Log($"[FilterHotFixAssemblies] disabled");
|
||||
return assemblies;
|
||||
}
|
||||
List<string> allHotUpdateDllNames = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;
|
||||
|
||||
// 检查是否重复填写
|
||||
var hotUpdateDllSet = new HashSet<string>();
|
||||
foreach(var hotUpdateDll in allHotUpdateDllNames)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(hotUpdateDll))
|
||||
{
|
||||
throw new BuildFailedException($"hot update assembly name cann't be empty");
|
||||
}
|
||||
if (!hotUpdateDllSet.Add(hotUpdateDll))
|
||||
{
|
||||
throw new BuildFailedException($"hot update assembly:{hotUpdateDll} is duplicated");
|
||||
}
|
||||
}
|
||||
|
||||
var assResolver = MetaUtil.CreateHotUpdateAssemblyResolver(EditorUserBuildSettings.activeBuildTarget, allHotUpdateDllNames);
|
||||
// 检查是否填写了正确的dll名称
|
||||
foreach (var hotUpdateDllName in allHotUpdateDllNames)
|
||||
{
|
||||
if (assemblies.Select(Path.GetFileNameWithoutExtension).All(ass => ass != hotUpdateDllName)
|
||||
&& string.IsNullOrEmpty(assResolver.ResolveAssembly(hotUpdateDllName, false)))
|
||||
{
|
||||
throw new BuildFailedException($"hot update assembly:{hotUpdateDllName} doesn't exist");
|
||||
}
|
||||
}
|
||||
|
||||
// 将热更dll从打包列表中移除
|
||||
return assemblies.Where(ass =>
|
||||
{
|
||||
string assName = Path.GetFileNameWithoutExtension(ass);
|
||||
bool reserved = allHotUpdateDllNames.All(dll => !assName.Equals(dll, StringComparison.Ordinal));
|
||||
if (!reserved)
|
||||
{
|
||||
Debug.Log($"[FilterHotFixAssemblies] filter assembly:{assName}");
|
||||
}
|
||||
return reserved;
|
||||
}).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9dec2922e3df5464aa047b636eb19e0d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,32 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
|
||||
public class MsvcStdextWorkaround : IPreprocessBuildWithReport
|
||||
{
|
||||
const string kWorkaroundFlag = "/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS";
|
||||
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
var clEnv = Environment.GetEnvironmentVariable("_CL_");
|
||||
|
||||
if (string.IsNullOrEmpty(clEnv))
|
||||
{
|
||||
Environment.SetEnvironmentVariable("_CL_", kWorkaroundFlag);
|
||||
}
|
||||
else if (!clEnv.Contains(kWorkaroundFlag))
|
||||
{
|
||||
clEnv += " " + kWorkaroundFlag;
|
||||
Environment.SetEnvironmentVariable("_CL_", clEnv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // UNITY_EDITOR
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bff6cadf0b8db54b87ba51b24d080f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,189 @@
|
||||
using HybridCLR.Editor.UnityBinFileReader;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Android;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEditor.UnityLinker;
|
||||
using UnityEngine;
|
||||
using UnityFS;
|
||||
#if !UNITY_2023_1_OR_NEWER
|
||||
using UnityEditor.Il2Cpp;
|
||||
#endif
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
public class PatchScriptingAssemblyList :
|
||||
#if UNITY_ANDROID
|
||||
IPostGenerateGradleAndroidProject,
|
||||
#elif UNITY_OPENHARMONY
|
||||
UnityEditor.OpenHarmony.IPostGenerateOpenHarmonyProject,
|
||||
#endif
|
||||
IPostprocessBuildWithReport
|
||||
#if !UNITY_2021_1_OR_NEWER && UNITY_WEBGL
|
||||
, IIl2CppProcessor
|
||||
#endif
|
||||
|
||||
#if UNITY_PS5
|
||||
, IUnityLinkerProcessor
|
||||
#endif
|
||||
|
||||
{
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public void OnPostGenerateGradleAndroidProject(string path)
|
||||
{
|
||||
// 如果直接打包apk,没有机会在PostprocessBuild中修改ScriptingAssemblies.json。
|
||||
// 因此需要在这个时机处理
|
||||
// Unity有bug,偶然情况下会传入apk的路径,导致替换失败
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
PathScriptingAssembilesFile(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
PathScriptingAssembilesFile($"{SettingsUtil.ProjectDir}/Library");
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_OPENHARMONY
|
||||
|
||||
public void OnPostGenerateOpenHarmonyProject(string path)
|
||||
{
|
||||
OnPostGenerateGradleAndroidProject(path);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public void OnPostprocessBuild(BuildReport report)
|
||||
{
|
||||
// 如果target为Android,由于已经在OnPostGenerateGradelAndroidProject中处理过,
|
||||
// 这里不再重复处理
|
||||
#if !UNITY_ANDROID && !UNITY_WEBGL && !UNITY_OPENHARMONY
|
||||
PathScriptingAssembilesFile(report.summary.outputPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_PS5
|
||||
/// <summary>
|
||||
/// 打包模式如果是 Package 需要在这个阶段提前处理 .json , PC Hosted 和 GP5 模式不受影响
|
||||
/// </summary>
|
||||
|
||||
public string GenerateAdditionalLinkXmlFile(UnityEditor.Build.Reporting.BuildReport report, UnityEditor.UnityLinker.UnityLinkerBuildPipelineData data)
|
||||
{
|
||||
string path = $"{SettingsUtil.ProjectDir}/Library/PlayerDataCache/PS5/Data";
|
||||
PathScriptingAssembilesFile(path);
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
public void PathScriptingAssembilesFile(string path)
|
||||
{
|
||||
if (!SettingsUtil.Enable)
|
||||
{
|
||||
Debug.Log($"[PatchScriptingAssemblyList] disabled");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"[PatchScriptingAssemblyList]. path:{path}");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
path = Path.GetDirectoryName(path);
|
||||
Debug.Log($"[PatchScriptingAssemblyList] get path parent:{path}");
|
||||
}
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
AddHotFixAssembliesToScriptingAssembliesJson(path);
|
||||
#else
|
||||
AddHotFixAssembliesToBinFile(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void AddHotFixAssembliesToScriptingAssembliesJson(string path)
|
||||
{
|
||||
Debug.Log($"[PatchScriptingAssemblyList]. path:{path}");
|
||||
/*
|
||||
* ScriptingAssemblies.json 文件中记录了所有的dll名称,此列表在游戏启动时自动加载,
|
||||
* 不在此列表中的dll在资源反序列化时无法被找到其类型
|
||||
* 因此 OnFilterAssemblies 中移除的条目需要再加回来
|
||||
*/
|
||||
string[] jsonFiles = Directory.GetFiles(path, SettingsUtil.ScriptingAssembliesJsonFile, SearchOption.AllDirectories);
|
||||
|
||||
if (jsonFiles.Length == 0)
|
||||
{
|
||||
Debug.LogWarning($"can not find file {SettingsUtil.ScriptingAssembliesJsonFile}");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string file in jsonFiles)
|
||||
{
|
||||
var patcher = new ScriptingAssembliesJsonPatcher();
|
||||
patcher.Load(file);
|
||||
patcher.AddScriptingAssemblies(SettingsUtil.HotUpdateAssemblyFilesIncludePreserved);
|
||||
patcher.Save(file);
|
||||
}
|
||||
}
|
||||
private void AddHotFixAssembliesToBinFile(string path)
|
||||
{
|
||||
#if UNITY_STANDALONE_OSX
|
||||
path = Path.GetDirectoryName(path);
|
||||
#endif
|
||||
if (AddHotFixAssembliesToGlobalgamemanagers(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (AddHotFixAssembliesTodataunity3d(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Debug.LogError($"[PatchScriptingAssemblyList] can not find file '{SettingsUtil.GlobalgamemanagersBinFile}' or '{SettingsUtil.Dataunity3dBinFile}' in '{path}'");
|
||||
}
|
||||
|
||||
private bool AddHotFixAssembliesToGlobalgamemanagers(string path)
|
||||
{
|
||||
string[] binFiles = Directory.GetFiles(path, SettingsUtil.GlobalgamemanagersBinFile, SearchOption.AllDirectories);
|
||||
|
||||
if (binFiles.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (string binPath in binFiles)
|
||||
{
|
||||
var binFile = new UnityBinFile();
|
||||
binFile.Load(binPath);
|
||||
binFile.AddScriptingAssemblies(SettingsUtil.HotUpdateAssemblyFilesIncludePreserved);
|
||||
binFile.Save(binPath);
|
||||
Debug.Log($"[PatchScriptingAssemblyList] patch {binPath}");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool AddHotFixAssembliesTodataunity3d(string path)
|
||||
{
|
||||
string[] binFiles = Directory.GetFiles(path, SettingsUtil.Dataunity3dBinFile, SearchOption.AllDirectories);
|
||||
|
||||
if (binFiles.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (string binPath in binFiles)
|
||||
{
|
||||
var patcher = new Dataunity3dPatcher();
|
||||
patcher.ApplyPatch(binPath, SettingsUtil.HotUpdateAssemblyFilesIncludePreserved);
|
||||
Debug.Log($"[PatchScriptingAssemblyList] patch {binPath}");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_2022_3_OR_NEWER
|
||||
public void OnBeforeConvertRun(BuildReport report, Il2CppBuildPipelineData data)
|
||||
{
|
||||
PathScriptingAssembilesFile($"{SettingsUtil.ProjectDir}/Temp/StagingArea/Data");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9bb6e2908d8948648979c9ff6bb7937d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HybridCLR.Editor.BuildProcessors
|
||||
{
|
||||
public class ScriptingAssembliesJsonPatcher
|
||||
{
|
||||
[Serializable]
|
||||
private class ScriptingAssemblies
|
||||
{
|
||||
public List<string> names;
|
||||
public List<int> types;
|
||||
}
|
||||
|
||||
private string _file;
|
||||
ScriptingAssemblies _scriptingAssemblies;
|
||||
|
||||
public void Load(string file)
|
||||
{
|
||||
_file = file;
|
||||
string content = File.ReadAllText(file);
|
||||
_scriptingAssemblies = JsonUtility.FromJson<ScriptingAssemblies>(content);
|
||||
}
|
||||
|
||||
public void AddScriptingAssemblies(List<string> assemblies)
|
||||
{
|
||||
foreach (string name in assemblies)
|
||||
{
|
||||
if (!_scriptingAssemblies.names.Contains(name))
|
||||
{
|
||||
_scriptingAssemblies.names.Add(name);
|
||||
_scriptingAssemblies.types.Add(16); // user dll type
|
||||
Debug.Log($"[PatchScriptAssembliesJson] add hotfix assembly:{name} to {_file}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(string jsonFile)
|
||||
{
|
||||
string content = JsonUtility.ToJson(_scriptingAssemblies);
|
||||
|
||||
File.WriteAllText(jsonFile, content);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4455f7304f8678f408dd6cf21734f55e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user