diff --git a/Editor/BuildProcessors/FilterHotFixAssemblies.cs b/Editor/BuildProcessors/FilterHotFixAssemblies.cs index bd6cdc5..db1184d 100644 --- a/Editor/BuildProcessors/FilterHotFixAssemblies.cs +++ b/Editor/BuildProcessors/FilterHotFixAssemblies.cs @@ -1,4 +1,5 @@ -using System; +using HybridCLR.Editor.Meta; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -23,11 +24,12 @@ namespace HybridCLR.Editor.BuildProcessors Debug.Log($"[FilterHotFixAssemblies] disabled"); return assemblies; } - List allHotUpdateDllFiles = SettingsUtil.HotUpdateAssemblyFiles; + List allHotUpdateDllNames = SettingsUtil.HotUpdateAssemblyNames; + List allHotupdateDllFiles = SettingsUtil.HotUpdateAssemblyFiles; // 检查是否重复填写 var hotUpdateDllSet = new HashSet(); - foreach(var hotUpdateDll in allHotUpdateDllFiles) + foreach(var hotUpdateDll in allHotUpdateDllNames) { if (!hotUpdateDllSet.Add(hotUpdateDll)) { @@ -35,18 +37,20 @@ namespace HybridCLR.Editor.BuildProcessors } } + var assResolver = MetaUtil.CreateHotUpdateAssemblyResolver(EditorUserBuildSettings.activeBuildTarget, allHotUpdateDllNames); // 检查是否填写了正确的dll名称 - foreach (var hotUpdateDll in allHotUpdateDllFiles) + foreach (var hotUpdateDllName in allHotUpdateDllNames) { - if (assemblies.All(ass => !ass.EndsWith(hotUpdateDll))) + string hotUpdateDllFile = hotUpdateDllName + ".dll"; + if (assemblies.All(ass => !ass.EndsWith(hotUpdateDllFile)) && string.IsNullOrEmpty(assResolver.ResolveAssembly(hotUpdateDllName, false))) { - throw new Exception($"热更新 assembly:{hotUpdateDll} 不存在,请检查拼写错误"); + throw new Exception($"热更新 assembly:{hotUpdateDllFile} 不存在,请检查拼写错误"); } - Debug.Log($"[FilterHotFixAssemblies] 过滤热更新assembly:{hotUpdateDll}"); + Debug.Log($"[FilterHotFixAssemblies] 过滤热更新assembly:{hotUpdateDllFile}"); } // 将热更dll从打包列表中移除 - return assemblies.Where(ass => allHotUpdateDllFiles.All(dll => !ass.EndsWith(dll, StringComparison.OrdinalIgnoreCase))).ToArray(); + return assemblies.Where(ass => allHotupdateDllFiles.All(dll => !ass.EndsWith(dll, StringComparison.OrdinalIgnoreCase))).ToArray(); } } } diff --git a/Editor/Commands/AOTReferenceGeneratorCommand.cs b/Editor/Commands/AOTReferenceGeneratorCommand.cs index a56d12f..11e10ad 100644 --- a/Editor/Commands/AOTReferenceGeneratorCommand.cs +++ b/Editor/Commands/AOTReferenceGeneratorCommand.cs @@ -14,23 +14,19 @@ namespace HybridCLR.Editor.Commands { [MenuItem("HybridCLR/Generate/AOTGenericReference", priority = 102)] - public static void GenerateAOTGenericReference() + public static void CompileAndGenerateAOTGenericReference() { - GenerateAOTGenericReference(true); + BuildTarget target = EditorUserBuildSettings.activeBuildTarget; + CompileDllCommand.CompileDll(target); + GenerateAOTGenericReference(target); } - public static void GenerateAOTGenericReference(bool compileDll) + public static void GenerateAOTGenericReference(BuildTarget target) { - // 此处理论会有点问题,打每个平台的时候,都得针对当前平台生成桥接函数 - // 但影响不大,先这样吧 - if (compileDll) - { - CompileDllCommand.CompileDllActiveBuildTarget(); - } - var gs = SettingsUtil.HybridCLRSettings; + List hotUpdateDllNames = SettingsUtil.HotUpdateAssemblyNames; - using (AssemblyReferenceDeepCollector collector = new AssemblyReferenceDeepCollector(MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget), SettingsUtil.HotUpdateAssemblyNames)) + using (AssemblyReferenceDeepCollector collector = new AssemblyReferenceDeepCollector(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotUpdateDllNames), hotUpdateDllNames)) { var analyzer = new Analyzer(new Analyzer.Options { diff --git a/Editor/Commands/Il2CppDefGeneratorCommand.cs b/Editor/Commands/Il2CppDefGeneratorCommand.cs index b503aa1..6a9e175 100644 --- a/Editor/Commands/Il2CppDefGeneratorCommand.cs +++ b/Editor/Commands/Il2CppDefGeneratorCommand.cs @@ -17,7 +17,7 @@ namespace HybridCLR.Editor.Commands { var options = new Il2CppDef.Il2CppDefGenerator.Options() { - UnityVersion = UnityEngine.Application.unityVersion, + UnityVersion = Application.unityVersion, OutputFile = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp/il2cpp-config.h", }; diff --git a/Editor/Commands/LinkGeneratorCommand.cs b/Editor/Commands/LinkGeneratorCommand.cs index 81acaa7..68217ea 100644 --- a/Editor/Commands/LinkGeneratorCommand.cs +++ b/Editor/Commands/LinkGeneratorCommand.cs @@ -1,4 +1,5 @@ using HybridCLR.Editor.Link; +using HybridCLR.Editor.Meta; using System; using System.Collections.Generic; using System.Reflection; @@ -14,41 +15,21 @@ namespace HybridCLR.Editor.Commands [MenuItem("HybridCLR/Generate/LinkXml", priority = 100)] public static void GenerateLinkXml() { - GenerateLinkXml(true); + BuildTarget target = EditorUserBuildSettings.activeBuildTarget; + CompileDllCommand.CompileDll(target); + GenerateLinkXml(target); } - public static void GenerateLinkXml(bool compileDll) + public static void GenerateLinkXml(BuildTarget target) { - if (compileDll) - { - CompileDllCommand.CompileDllActiveBuildTarget(); - } - var ls = SettingsUtil.HybridCLRSettings; - var allAssByNames = new Dictionary(); - foreach (var ass in AppDomain.CurrentDomain.GetAssemblies()) - { - allAssByNames[ass.GetName().Name] = ass; - } + List hotfixAssemblies = SettingsUtil.HotUpdateAssemblyNames; - var hotfixAssembles = new List(); - foreach(var assName in SettingsUtil.HotUpdateAssemblyNames) - { - if (allAssByNames.TryGetValue(assName, out var ass)) - { - hotfixAssembles.Add(ass); - } - else - { - throw new Exception($"assembly:{assName} 不存在"); - } - } + var analyzer = new Analyzer(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotfixAssemblies), HybridCLRSettings.Instance.collectAssetReferenceTypes); + var refTypes = analyzer.CollectRefs(hotfixAssemblies); - var analyzer = new Analyzer(Meta.MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget), HybridCLRSettings.Instance.collectAssetReferenceTypes); - var refTypes = analyzer.CollectRefs(hotfixAssembles); - - Debug.Log($"[LinkGeneratorCommand] hotfix assembly count:{hotfixAssembles.Count}, ref type count:{refTypes.Count} output:{Application.dataPath}/{ls.outputLinkFile}"); + Debug.Log($"[LinkGeneratorCommand] hotfix assembly count:{hotfixAssemblies.Count}, ref type count:{refTypes.Count} output:{Application.dataPath}/{ls.outputLinkFile}"); var linkXmlWriter = new LinkXmlWriter(); linkXmlWriter.Write($"{Application.dataPath}/{ls.outputLinkFile}", refTypes); AssetDatabase.Refresh(); diff --git a/Editor/Commands/MethodBridgeGeneratorCommand.cs b/Editor/Commands/MethodBridgeGeneratorCommand.cs index ae19e72..e0c7447 100644 --- a/Editor/Commands/MethodBridgeGeneratorCommand.cs +++ b/Editor/Commands/MethodBridgeGeneratorCommand.cs @@ -45,21 +45,17 @@ namespace HybridCLR.Editor.Commands } [MenuItem("HybridCLR/Generate/MethodBridge", priority = 101)] - public static void GenerateMethodBridge() + public static void CompileAndGenerateMethodBridge() { - GenerateMethodBridge(true); + BuildTarget target = EditorUserBuildSettings.activeBuildTarget; + CompileDllCommand.CompileDll(target); + GenerateMethodBridge(target); } - public static void GenerateMethodBridge(bool compileDll) + public static void GenerateMethodBridge(BuildTarget target) { - // 此处理论会有点问题,打每个平台的时候,都得针对当前平台生成桥接函数 - // 但影响不大,先这样吧 - if (compileDll) - { - CompileDllCommand.CompileDllActiveBuildTarget(); - } - - using (AssemblyReferenceDeepCollector collector = new AssemblyReferenceDeepCollector(MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget), SettingsUtil.HotUpdateAssemblyNames)) + List hotUpdateDllNames = SettingsUtil.HotUpdateAssemblyNames; + using (AssemblyReferenceDeepCollector collector = new AssemblyReferenceDeepCollector(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotUpdateDllNames), hotUpdateDllNames)) { var analyzer = new Analyzer(new Analyzer.Options { diff --git a/Editor/Commands/PrebuildCommand.cs b/Editor/Commands/PrebuildCommand.cs index d2a64d5..89196c4 100644 --- a/Editor/Commands/PrebuildCommand.cs +++ b/Editor/Commands/PrebuildCommand.cs @@ -15,16 +15,20 @@ namespace HybridCLR.Editor.Commands [MenuItem("HybridCLR/Generate/All", priority = 200)] public static void GenerateAll() { + BuildTarget target = EditorUserBuildSettings.activeBuildTarget; + CompileDllCommand.CompileDll(target); Il2CppDefGeneratorCommand.GenerateIl2CppDef(); - // 顺序随意 - ReversePInvokeWrapperGeneratorCommand.GenerateReversePInvokeWrapper(); - // AOTReferenceGeneratorCommand 涉及到代码生成,必须在MethodBridgeGeneratorCommand之前 - AOTReferenceGeneratorCommand.GenerateAOTGenericReference(); - MethodBridgeGeneratorCommand.GenerateMethodBridge(); + // 这几个生成依赖HotUpdateDlls + LinkGeneratorCommand.GenerateLinkXml(target); - // 顺序随意,只要保证 GenerateLinkXml之前有调用过CompileDll即可 - LinkGeneratorCommand.GenerateLinkXml(false); + // 生成裁剪后的aot dll + StripAOTDllCommand.GenerateStripedAOTDlls(target, EditorUserBuildSettings.selectedBuildTargetGroup); + + // 桥接函数生成依赖于AOT dll,必须保证已经build过,生成AOT dll + MethodBridgeGeneratorCommand.GenerateMethodBridge(target); + ReversePInvokeWrapperGeneratorCommand.GenerateReversePInvokeWrapper(target); + AOTReferenceGeneratorCommand.GenerateAOTGenericReference(target); } } } diff --git a/Editor/Commands/ReversePInvokeWrapperGeneratorCommand.cs b/Editor/Commands/ReversePInvokeWrapperGeneratorCommand.cs index 706c019..4f097ef 100644 --- a/Editor/Commands/ReversePInvokeWrapperGeneratorCommand.cs +++ b/Editor/Commands/ReversePInvokeWrapperGeneratorCommand.cs @@ -19,12 +19,20 @@ namespace HybridCLR.Editor.Commands { [MenuItem("HybridCLR/Generate/ReversePInvokeWrapper", priority = 103)] - public static void GenerateReversePInvokeWrapper() + + public static void CompileAndGenerateReversePInvokeWrapper() { - CompileDllCommand.CompileDllActiveBuildTarget(); - using (var cache = new AssemblyCache(MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget))) + BuildTarget target = EditorUserBuildSettings.activeBuildTarget; + CompileDllCommand.CompileDll(target); + GenerateReversePInvokeWrapper(target); + } + + public static void GenerateReversePInvokeWrapper(BuildTarget target) + { + List hotUpdateDlls = SettingsUtil.HotUpdateAssemblyNames; + using (var cache = new AssemblyCache(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotUpdateDlls))) { - var analyzer = new ReversePInvokeWrap.Analyzer(cache, SettingsUtil.HotUpdateAssemblyNames); + var analyzer = new ReversePInvokeWrap.Analyzer(cache, hotUpdateDlls); analyzer.Run(); diff --git a/Editor/Commands/StripAOTDllCommand.cs b/Editor/Commands/StripAOTDllCommand.cs new file mode 100644 index 0000000..a6d99e4 --- /dev/null +++ b/Editor/Commands/StripAOTDllCommand.cs @@ -0,0 +1,119 @@ +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 UnityEngine; + +namespace HybridCLR.Editor.Commands +{ + public static class StripAOTDllCommand + { + [MenuItem("HybridCLR/Generate/AOTDlls", priority = 105)] + public static void GenerateStripedAOTDlls() + { + GenerateStripedAOTDlls(EditorUserBuildSettings.activeBuildTarget, EditorUserBuildSettings.selectedBuildTargetGroup); + } + + private static string GetLocationPathName(string buildDir, BuildTarget target) + { + switch(target) + { + case BuildTarget.StandaloneWindows: + case BuildTarget.StandaloneWindows64: return $"{buildDir}/{target}"; + case BuildTarget.StandaloneOSX: return buildDir; + case BuildTarget.iOS: return buildDir; + case BuildTarget.Android: return buildDir; + case BuildTarget.StandaloneLinux64: return buildDir; + default: return buildDir; + } + } + + public static void GenerateStripedAOTDlls(BuildTarget target, BuildTargetGroup group) + { + string outputPath = $"{SettingsUtil.HybridCLRDataDir}/StrippedAOTDllsTempProj/{target}"; + BashUtil.RemoveDir(outputPath); + + var buildOptions = BuildOptions.BuildScriptsOnly; + + bool oldExportAndroidProj = EditorUserBuildSettings.exportAsGoogleAndroidProject; +#if UNITY_EDITOR_OSX + bool oldCreateSolution = UnityEditor.OSXStandalone.UserBuildSettings.createXcodeProject; +#elif UNITY_EDITOR_WIN + bool oldCreateSolution = UnityEditor.WindowsStandalone.UserBuildSettings.createSolution; +#endif + bool oldBuildScriptsOnly = EditorUserBuildSettings.buildScriptsOnly; + EditorUserBuildSettings.buildScriptsOnly = true; + + switch (target) + { + case BuildTarget.StandaloneWindows: + case BuildTarget.StandaloneWindows64: + { +#if UNITY_EDITOR_WIN + UnityEditor.WindowsStandalone.UserBuildSettings.createSolution = true; +#endif + break; + } + case BuildTarget.StandaloneOSX: + { +#if UNITY_EDITOR_OSX + UnityEditor.OSXStandalone.UserBuildSettings.createXcodeProject = true; +#endif + break; + } + case BuildTarget.Android: + { + EditorUserBuildSettings.exportAsGoogleAndroidProject = true; + break; + } + } + + BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions() + { + scenes = EditorBuildSettings.scenes.Where(s => s.enabled).Select(s => s.path).ToArray(), + locationPathName = GetLocationPathName(outputPath, target), + options = buildOptions, + target = target, + targetGroup = group, + }; + + var report = BuildPipeline.BuildPlayer(buildPlayerOptions); + + EditorUserBuildSettings.buildScriptsOnly = oldBuildScriptsOnly; + switch (target) + { + case BuildTarget.StandaloneWindows: + case BuildTarget.StandaloneWindows64: + { +#if UNITY_EDITOR_WIN + UnityEditor.WindowsStandalone.UserBuildSettings.createSolution = oldCreateSolution; +#endif + break; + } + case BuildTarget.StandaloneOSX: + { +#if UNITY_EDITOR_OSX + UnityEditor.OSXStandalone.UserBuildSettings.createXcodeProject = oldCreateSolution; +#endif + break; + } + case BuildTarget.Android: + { + EditorUserBuildSettings.exportAsGoogleAndroidProject = oldExportAndroidProj; + break; + } + } + + if (report.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded) + { + Debug.LogError("GenerateStripedAOTDlls 失败"); + return; + } + Debug.Log($"GenerateStripedAOTDlls target:{target} group:{group} path:{outputPath}"); + } + } +} diff --git a/Editor/Meta/UnityPluginAssemblyResolver.cs.meta b/Editor/Commands/StripAOTDllCommand.cs.meta similarity index 83% rename from Editor/Meta/UnityPluginAssemblyResolver.cs.meta rename to Editor/Commands/StripAOTDllCommand.cs.meta index 707e174..3979b80 100644 --- a/Editor/Meta/UnityPluginAssemblyResolver.cs.meta +++ b/Editor/Commands/StripAOTDllCommand.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6c235be11c219a74fa5eb55ed54e7662 +guid: 21fb0a02f23185141a4a3df67fe61789 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Link/Analyzer.cs b/Editor/Link/Analyzer.cs index 9b6d417..cb1ea70 100644 --- a/Editor/Link/Analyzer.cs +++ b/Editor/Link/Analyzer.cs @@ -22,26 +22,19 @@ namespace HybridCLR.Editor.Link _analyzeAssetType = analyzeAssetType; } - public HashSet CollectRefs(List rootAssemblies) + public HashSet CollectRefs(List rootAssemblies) { using (var assCollector = new AssemblyCache(_resolver)) { - var rootAssemblyName = new HashSet(); - foreach (var ass in rootAssemblies) - { - if (!rootAssemblyName.Add(ass.GetName().Name)) - { - throw new Exception($"assembly:{ass.GetName().Name} 重复"); - } - } + var rootAssemblyNames = new HashSet(rootAssemblies); var typeRefs = new HashSet(TypeEqualityComparer.Instance); foreach (var rootAss in rootAssemblies) { - var dnAss = assCollector.LoadModule(rootAss.GetName().Name); + var dnAss = assCollector.LoadModule(rootAss, _analyzeAssetType); foreach (var type in dnAss.GetTypeRefs()) { - if (!rootAssemblyName.Contains(type.DefinitionAssembly.Name)) + if (!rootAssemblyNames.Contains(type.DefinitionAssembly.Name.ToString())) { typeRefs.Add(type); } @@ -51,7 +44,7 @@ namespace HybridCLR.Editor.Link if (_analyzeAssetType) { var modsExludeRoots = assCollector.LoadedModules - .Where(e => !rootAssemblyName.Contains(e.Key)) + .Where(e => !rootAssemblyNames.Contains(e.Key)) .ToDictionary(e => e.Key, e => e.Value); CollectObjectTypeInAssets(modsExludeRoots, typeRefs); } diff --git a/Editor/Meta/AssemblyCache.cs b/Editor/Meta/AssemblyCache.cs index 646f966..04a7442 100644 --- a/Editor/Meta/AssemblyCache.cs +++ b/Editor/Meta/AssemblyCache.cs @@ -27,7 +27,7 @@ namespace HybridCLR.Editor.Meta _asmResolver.UseGAC = false; } - public ModuleDefMD LoadModule(string moduleName) + public ModuleDefMD LoadModule(string moduleName, bool loadReferenceAssemblies = true) { // Debug.Log($"load module:{moduleName}"); if (LoadedModules.TryGetValue(moduleName, out var mod)) @@ -37,10 +37,14 @@ namespace HybridCLR.Editor.Meta mod = DoLoadModule(_assemblyPathResolver.ResolveAssembly(moduleName, true)); LoadedModules.Add(moduleName, mod); - foreach (var refAsm in mod.GetAssemblyRefs()) + if (loadReferenceAssemblies) { - LoadModule(refAsm.Name); + foreach (var refAsm in mod.GetAssemblyRefs()) + { + LoadModule(refAsm.Name); + } } + return mod; } diff --git a/Editor/Meta/AssemblyResolverBase.cs b/Editor/Meta/AssemblyResolverBase.cs new file mode 100644 index 0000000..c8fc03f --- /dev/null +++ b/Editor/Meta/AssemblyResolverBase.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HybridCLR.Editor.Meta +{ + public abstract class AssemblyResolverBase : IAssemblyResolver + { + public string ResolveAssembly(string assemblyName, bool throwExIfNotFind) + { + if (TryResolveAssembly(assemblyName, out string assemblyPath)) + { + return assemblyPath; + } + if (throwExIfNotFind) + { + throw new Exception($"resolve assembly:{assemblyName} 失败! 如果是热更新dll找不到,请先运行`HybridCLR/CompileDll/ActiveBuildTarget`编译生成热更新dll。如果是AOT dll找不到,请先运行`HybridCLR/Generate/LinkXml`,接着在`Build Settings`中打包或者导出工程来生成AOT dll"); + } + return null; + } + + protected abstract bool TryResolveAssembly(string assemblyName, out string assemblyPath); + } +} diff --git a/Editor/Meta/UnityAOTAssemblyResolver.cs.meta b/Editor/Meta/AssemblyResolverBase.cs.meta similarity index 83% rename from Editor/Meta/UnityAOTAssemblyResolver.cs.meta rename to Editor/Meta/AssemblyResolverBase.cs.meta index 8fb10f3..e153d4e 100644 --- a/Editor/Meta/UnityAOTAssemblyResolver.cs.meta +++ b/Editor/Meta/AssemblyResolverBase.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 029bc0368e1ada342aa29a18d4fae879 +guid: 5f8d48774b790364cbd36f1f68fd6614 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Meta/CombinedAssemblyResolver.cs b/Editor/Meta/CombinedAssemblyResolver.cs index c8f663a..31a0c51 100644 --- a/Editor/Meta/CombinedAssemblyResolver.cs +++ b/Editor/Meta/CombinedAssemblyResolver.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace HybridCLR.Editor.Meta { - public class CombinedAssemblyResolver : IAssemblyResolver + public class CombinedAssemblyResolver : AssemblyResolverBase { private readonly IAssemblyResolver[] _resolvers; @@ -15,21 +15,19 @@ namespace HybridCLR.Editor.Meta _resolvers = resolvers; } - public string ResolveAssembly(string assemblyName, bool throwExIfNotFind) + protected override bool TryResolveAssembly(string assemblyName, out string assemblyPath) { foreach(var resolver in _resolvers) { var assembly = resolver.ResolveAssembly(assemblyName, false); if (assembly != null) { - return assembly; + assemblyPath = assembly; + return true; } } - if (throwExIfNotFind) - { - throw new Exception($"resolve assembly:{assemblyName} fail"); - } - return null; + assemblyPath = null; + return false; } } } diff --git a/Editor/Meta/FixedSetAssemblyResolver.cs b/Editor/Meta/FixedSetAssemblyResolver.cs new file mode 100644 index 0000000..5bee4e4 --- /dev/null +++ b/Editor/Meta/FixedSetAssemblyResolver.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace HybridCLR.Editor.Meta +{ + public class FixedSetAssemblyResolver : AssemblyResolverBase + { + private readonly string _rootDir; + private readonly HashSet _fileNames; + + public FixedSetAssemblyResolver(string rootDir, IEnumerable fileNameNotExts) + { + _rootDir = rootDir; + _fileNames = new HashSet(fileNameNotExts); + } + + protected override bool TryResolveAssembly(string assemblyName, out string assemblyPath) + { + if (_fileNames.Contains(assemblyName)) + { + assemblyPath = $"{_rootDir}/{assemblyName}.dll"; + if (File.Exists(assemblyPath)) + { + Debug.Log($"[FixedSetAssemblyResolver] resolve:{assemblyName} path:{assemblyPath}"); + return true; + } + } + assemblyPath = null; + return false; + } + } +} diff --git a/Editor/Meta/UnityEditorAssemblyResolver.cs.meta b/Editor/Meta/FixedSetAssemblyResolver.cs.meta similarity index 83% rename from Editor/Meta/UnityEditorAssemblyResolver.cs.meta rename to Editor/Meta/FixedSetAssemblyResolver.cs.meta index fc640e4..cc4fb61 100644 --- a/Editor/Meta/UnityEditorAssemblyResolver.cs.meta +++ b/Editor/Meta/FixedSetAssemblyResolver.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 78d06a3ad750c0b4b80b583188b02df3 +guid: f135accd10f42c64b9735c3aa8cb1e77 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Meta/MetaUtil.cs b/Editor/Meta/MetaUtil.cs index 45983ab..539eb91 100644 --- a/Editor/Meta/MetaUtil.cs +++ b/Editor/Meta/MetaUtil.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using UnityEditor; namespace HybridCLR.Editor.Meta { @@ -119,13 +120,39 @@ namespace HybridCLR.Editor.Meta return typeSigs.Select(s => ToShareTypeSig(s)).ToList(); } - public static IAssemblyResolver CreateBuildTargetAssemblyResolver(UnityEditor.BuildTarget target) + public static IAssemblyResolver CreateHotUpdateAssemblyResolver(BuildTarget target, List hotUpdateDlls) { - return new CombinedAssemblyResolver(new PathAssemblyResolver( - SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target)), - new UnityPluginAssemblyResolver(), - new UnityAOTAssemblyResolver(), - new UnityEditorAssemblyResolver()); + var externalDirs = HybridCLRSettings.Instance.externalHotUpdateAssembliyDirs; + var defaultHotUpdateOutputDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target); + IAssemblyResolver defaultHotUpdateResolver = new FixedSetAssemblyResolver(defaultHotUpdateOutputDir, hotUpdateDlls); + if (externalDirs == null || externalDirs.Length == 0) + { + return defaultHotUpdateResolver; + } + else + { + var resolvers = new List(); + foreach (var dir in externalDirs) + { + resolvers.Add(new FixedSetAssemblyResolver($"{dir}/{target}", hotUpdateDlls)); + resolvers.Add(new FixedSetAssemblyResolver(dir, hotUpdateDlls)); + } + resolvers.Add(defaultHotUpdateResolver); + return new CombinedAssemblyResolver(resolvers.ToArray()); + } } + + public static IAssemblyResolver CreateAOTAssemblyResolver(BuildTarget target) + { + return new PathAssemblyResolver(SettingsUtil.GetAssembliesPostIl2CppStripDir(target)); + } + + public static IAssemblyResolver CreateHotUpdateAndAOTAssemblyResolver(BuildTarget target, List hotUpdateDlls) + { + return new CombinedAssemblyResolver( + CreateHotUpdateAssemblyResolver(target, hotUpdateDlls), + CreateAOTAssemblyResolver(target) + ); + } } } diff --git a/Editor/Meta/PathAssemblyResolver.cs b/Editor/Meta/PathAssemblyResolver.cs index d36aefd..a356117 100644 --- a/Editor/Meta/PathAssemblyResolver.cs +++ b/Editor/Meta/PathAssemblyResolver.cs @@ -8,7 +8,7 @@ using UnityEngine; namespace HybridCLR.Editor.Meta { - public class PathAssemblyResolver : IAssemblyResolver + public class PathAssemblyResolver : AssemblyResolverBase { private readonly string[] _searchPaths; public PathAssemblyResolver(params string[] searchPaths) @@ -16,7 +16,7 @@ namespace HybridCLR.Editor.Meta _searchPaths = searchPaths; } - public string ResolveAssembly(string assemblyName, bool throwExIfNotFind) + protected override bool TryResolveAssembly(string assemblyName, out string assemblyPath) { foreach(var path in _searchPaths) { @@ -24,14 +24,12 @@ namespace HybridCLR.Editor.Meta if (File.Exists(assPath)) { Debug.Log($"resolve {assemblyName} at {assPath}"); - return assPath; + assemblyPath = assPath; + return true; } } - if (throwExIfNotFind) - { - throw new Exception($"resolve assembly:{assemblyName} fail"); - } - return null; + assemblyPath = null; + return false; } } } diff --git a/Editor/Meta/UnityAOTAssemblyResolver.cs b/Editor/Meta/UnityAOTAssemblyResolver.cs deleted file mode 100644 index fcd0319..0000000 --- a/Editor/Meta/UnityAOTAssemblyResolver.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace HybridCLR.Editor.Meta -{ - public class UnityAOTAssemblyResolver : IAssemblyResolver - { - public string ResolveAssembly(string assemblyName, bool throwExIfNotFind) - { - // - var assemblyFile = $"{UnityEditor.EditorApplication.applicationContentsPath}/MonoBleedingEdge/lib/mono/unityaot/{assemblyName}.dll"; - if (File.Exists(assemblyFile)) - { - Debug.Log($"UnityAOTAssemblyResolver.ResolveAssembly:{assemblyFile}"); - return assemblyFile; - } - if (throwExIfNotFind) - { - throw new Exception($"resolve assembly:{assemblyName} fail"); - } - return null; - } - } -} diff --git a/Editor/Meta/UnityEditorAssemblyResolver.cs b/Editor/Meta/UnityEditorAssemblyResolver.cs deleted file mode 100644 index 092d925..0000000 --- a/Editor/Meta/UnityEditorAssemblyResolver.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace HybridCLR.Editor.Meta -{ - public class UnityEditorAssemblyResolver : IAssemblyResolver - { - public string ResolveAssembly(string assemblyName, bool throwExIfNotFind) - { - var refAss = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == assemblyName); - if (refAss != null) - { - return refAss.Location; - } - return Assembly.Load(assemblyName).Location; - } - } -} diff --git a/Editor/Meta/UnityPluginAssemblyResolver.cs b/Editor/Meta/UnityPluginAssemblyResolver.cs deleted file mode 100644 index b7ac13a..0000000 --- a/Editor/Meta/UnityPluginAssemblyResolver.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace HybridCLR.Editor.Meta -{ - public class UnityPluginAssemblyResolver : IAssemblyResolver - { - private static readonly HashSet s_ignoreDirs = new HashSet - { - "Editor", - "StreamingAssets", - "Resources", - }; - - private bool IsPluginDll(string dllPath) - { - var fileOrDirs = new HashSet(dllPath.Split('\\', '/')); - return !fileOrDirs.Any(dir => dir.EndsWith("~")) && !fileOrDirs.Intersect(s_ignoreDirs).Any(); - } - - public string ResolveAssembly(string assemblyName, bool throwExIfNotFind) - { - foreach(var dll in Directory.GetFiles(UnityEngine.Application.dataPath, "*.dll", SearchOption.AllDirectories)) - { - if (Path.GetFileNameWithoutExtension(dll) == assemblyName && IsPluginDll(dll)) - { - Debug.Log($"UnityPluginAssemblyResolver.ResolveAssembly:{dll}"); - return dll; - } - } - if (throwExIfNotFind) - { - throw new Exception($"resolve assembly:{assemblyName} fail"); - } - return null; - } - } -} diff --git a/Editor/Settings/HybridCLRSettingProvider.cs b/Editor/Settings/HybridCLRSettingProvider.cs index 234286f..a44b973 100644 --- a/Editor/Settings/HybridCLRSettingProvider.cs +++ b/Editor/Settings/HybridCLRSettingProvider.cs @@ -17,6 +17,7 @@ namespace HybridCLR.Editor private SerializedProperty _hotUpdateAssemblies; private SerializedProperty _preserveHotUpdateAssemblies; private SerializedProperty _hotUpdateDllCompileOutputRootDir; + private SerializedProperty _externalHotUpdateAssembliyDirs; private SerializedProperty _strippedAOTDllOutputRootDir; private SerializedProperty _patchAOTAssemblies; private SerializedProperty _collectAssetReferenceTypes; @@ -44,6 +45,7 @@ namespace HybridCLR.Editor _hotUpdateAssemblies = _serializedObject.FindProperty("hotUpdateAssemblies"); _preserveHotUpdateAssemblies = _serializedObject.FindProperty("preserveHotUpdateAssemblies"); _hotUpdateDllCompileOutputRootDir = _serializedObject.FindProperty("hotUpdateDllCompileOutputRootDir"); + _externalHotUpdateAssembliyDirs = _serializedObject.FindProperty("externalHotUpdateAssembliyDirs"); _strippedAOTDllOutputRootDir = _serializedObject.FindProperty("strippedAOTDllOutputRootDir"); _patchAOTAssemblies = _serializedObject.FindProperty("patchAOTAssemblies"); _collectAssetReferenceTypes = _serializedObject.FindProperty("collectAssetReferenceTypes"); @@ -132,6 +134,7 @@ namespace HybridCLR.Editor EditorGUILayout.PropertyField(_hotUpdateAssemblies); EditorGUILayout.PropertyField(_preserveHotUpdateAssemblies); EditorGUILayout.PropertyField(_hotUpdateDllCompileOutputRootDir); + EditorGUILayout.PropertyField(_externalHotUpdateAssembliyDirs); EditorGUILayout.PropertyField(_strippedAOTDllOutputRootDir); EditorGUILayout.PropertyField(_patchAOTAssemblies); EditorGUILayout.PropertyField(_collectAssetReferenceTypes); diff --git a/Editor/Settings/HybridCLRSettings.cs b/Editor/Settings/HybridCLRSettings.cs index 6b2b6d4..b97e350 100644 --- a/Editor/Settings/HybridCLRSettings.cs +++ b/Editor/Settings/HybridCLRSettings.cs @@ -29,6 +29,9 @@ namespace HybridCLR.Editor [Header("热更新dll编译输出根目录")] public string hotUpdateDllCompileOutputRootDir = "HybridCLRData/HotUpdateDlls"; + [Header("外部热更新dll搜索路径")] + public string[] externalHotUpdateAssembliyDirs; + [Header("裁减后AOT dll输出根目录")] public string strippedAOTDllOutputRootDir = "HybridCLRData/AssembliesPostIl2CppStrip"; @@ -47,9 +50,6 @@ namespace HybridCLR.Editor [Header("AOT泛型实例化搜索迭代次数")] public int maxGenericReferenceIteration = 10; - //[Header("预留MonoPInvokeCallbackAttribute函数个数")] - //public int ReversePInvokeWrapperCount = 10; - [Header("MethodBridge泛型搜索迭代次数")] public int maxMethodBridgeGenericIteration = 10; } diff --git a/package.json b/package.json index 7a83d0e..69fc5d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.focus-creative-games.hybridclr_unity", - "version": "1.0.11", + "version": "1.0.12", "displayName": "HybridCLR", "description": "Unity package for HybridCLR. It includes editor and runtime scripts and assets for HybridCLR", "category": "Runtime",