From 82163d2e505e40294b897fa7ecd1aaa51c46ed39 Mon Sep 17 00:00:00 2001 From: walon Date: Wed, 8 Jan 2025 16:20:39 +0800 Subject: [PATCH] [new] support preserve UnityEngine core types when GenerateLinkXml --- Editor/Commands/LinkGeneratorCommand.cs | 2 +- Editor/Link/Analyzer.cs | 39 ++++++++++++++++++--- Editor/Link/LinkXmlWriter.cs | 2 +- Editor/Meta/AssemblyCacheBase.cs | 7 ++++ Editor/Settings/HybridCLRSettingProvider.cs | 3 ++ Editor/Settings/HybridCLRSettings.cs | 3 ++ 6 files changed, 50 insertions(+), 6 deletions(-) diff --git a/Editor/Commands/LinkGeneratorCommand.cs b/Editor/Commands/LinkGeneratorCommand.cs index c545ff5..1a5b7b7 100644 --- a/Editor/Commands/LinkGeneratorCommand.cs +++ b/Editor/Commands/LinkGeneratorCommand.cs @@ -28,7 +28,7 @@ namespace HybridCLR.Editor.Commands List hotfixAssemblies = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved; var analyzer = new Analyzer(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotfixAssemblies)); - var refTypes = analyzer.CollectRefs(hotfixAssemblies); + var refTypes = analyzer.CollectRefs(hotfixAssemblies, !ls.dontPreserveUnityEngineCoreTypesInLinkXml); Debug.Log($"[LinkGeneratorCommand] hotfix assembly count:{hotfixAssemblies.Count}, ref type count:{refTypes.Count} output:{Application.dataPath}/{ls.outputLinkFile}"); var linkXmlWriter = new LinkXmlWriter(); diff --git a/Editor/Link/Analyzer.cs b/Editor/Link/Analyzer.cs index ffbb93d..0ddfded 100644 --- a/Editor/Link/Analyzer.cs +++ b/Editor/Link/Analyzer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; using System.Text; @@ -21,12 +22,43 @@ namespace HybridCLR.Editor.Link _resolver = resolver; } - public HashSet CollectRefs(List rootAssemblies) + + public HashSet CollectRefs(List rootAssemblies, bool includeUnityEngineCoreTypes) + { + var typeRefs = new HashSet(TypeEqualityComparer.Instance); + CollectHotUpdateRefs(rootAssemblies, typeRefs); + + if (includeUnityEngineCoreTypes) + { + CollectUnityEngineCoreTypes(typeRefs); + } + return typeRefs; + } + + private void CollectUnityEngineCoreTypes(HashSet preservedTypes) + { + Debug.Log("CollectUnityEngineCoreTypes"); + string unityEngineDllPath = $"{EditorApplication.applicationContentsPath}/Managed/UnityEngine"; + + var assCollector = new AssemblyCache(_resolver); + foreach (string unityEngineDll in Directory.GetFiles(unityEngineDllPath, "UnityEngine.*.dll", SearchOption.AllDirectories)) + { + ModuleDefMD mod = assCollector.LoadModuleFromFileWithoutCache(unityEngineDll); + foreach (TypeDef type in mod.GetTypes()) + { + if (type.Methods.Any(m => m.IsInternalCall || m.IsPinvokeImpl)) + { + preservedTypes.Add(type); + } + } + } + } + + public void CollectHotUpdateRefs(List rootAssemblies, HashSet preservedTypes) { var assCollector = new AssemblyCache(_resolver); var rootAssemblyNames = new HashSet(rootAssemblies); - var typeRefs = new HashSet(TypeEqualityComparer.Instance); foreach (var rootAss in rootAssemblies) { var dnAss = assCollector.LoadModule(rootAss, false); @@ -39,11 +71,10 @@ namespace HybridCLR.Editor.Link } if (!rootAssemblyNames.Contains(type.DefinitionAssembly.Name.ToString())) { - typeRefs.Add(type); + preservedTypes.Add(type); } } } - return typeRefs; } } } diff --git a/Editor/Link/LinkXmlWriter.cs b/Editor/Link/LinkXmlWriter.cs index ab5d448..2667308 100644 --- a/Editor/Link/LinkXmlWriter.cs +++ b/Editor/Link/LinkXmlWriter.cs @@ -11,7 +11,7 @@ namespace HybridCLR.Editor.Link { internal class LinkXmlWriter { - public void Write(string outputLinkXmlFile, HashSet refTypes) + public void Write(string outputLinkXmlFile, HashSet refTypes) { string parentDir = Directory.GetParent(outputLinkXmlFile).FullName; Directory.CreateDirectory(parentDir); diff --git a/Editor/Meta/AssemblyCacheBase.cs b/Editor/Meta/AssemblyCacheBase.cs index 04f2d15..4955223 100644 --- a/Editor/Meta/AssemblyCacheBase.cs +++ b/Editor/Meta/AssemblyCacheBase.cs @@ -71,6 +71,13 @@ namespace HybridCLR.Editor.Meta return mod; } + public ModuleDefMD LoadModuleFromFileWithoutCache(string dllPath) + { + ModuleDefMD mod = ModuleDefMD.Load(File.ReadAllBytes(dllPath), _modCtx); + mod.EnableTypeDefFindCache = true; + return mod; + } + private void LoadNetStandard() { string netstandardDllPath = _assemblyPathResolver.ResolveAssembly("netstandard", false); diff --git a/Editor/Settings/HybridCLRSettingProvider.cs b/Editor/Settings/HybridCLRSettingProvider.cs index 122187c..47da29d 100644 --- a/Editor/Settings/HybridCLRSettingProvider.cs +++ b/Editor/Settings/HybridCLRSettingProvider.cs @@ -21,6 +21,7 @@ namespace HybridCLR.Editor.Settings private SerializedProperty _externalHotUpdateAssembliyDirs; private SerializedProperty _strippedAOTDllOutputRootDir; private SerializedProperty _patchAOTAssemblies; + private SerializedProperty _dontPreserveUnityEngineCoreTypesInLinkXml; private SerializedProperty _outputLinkFile; private SerializedProperty _outputAOTGenericReferenceFile; private SerializedProperty _maxGenericReferenceIteration; @@ -51,6 +52,7 @@ namespace HybridCLR.Editor.Settings _externalHotUpdateAssembliyDirs = _serializedObject.FindProperty("externalHotUpdateAssembliyDirs"); _strippedAOTDllOutputRootDir = _serializedObject.FindProperty("strippedAOTDllOutputRootDir"); _patchAOTAssemblies = _serializedObject.FindProperty("patchAOTAssemblies"); + _dontPreserveUnityEngineCoreTypesInLinkXml = _serializedObject.FindProperty("dontPreserveUnityEngineCoreTypesInLinkXml"); _outputLinkFile = _serializedObject.FindProperty("outputLinkFile"); _outputAOTGenericReferenceFile = _serializedObject.FindProperty("outputAOTGenericReferenceFile"); _maxGenericReferenceIteration = _serializedObject.FindProperty("maxGenericReferenceIteration"); @@ -140,6 +142,7 @@ namespace HybridCLR.Editor.Settings EditorGUILayout.PropertyField(_externalHotUpdateAssembliyDirs); EditorGUILayout.PropertyField(_strippedAOTDllOutputRootDir); EditorGUILayout.PropertyField(_patchAOTAssemblies); + EditorGUILayout.PropertyField(_dontPreserveUnityEngineCoreTypesInLinkXml); EditorGUILayout.PropertyField(_outputLinkFile); EditorGUILayout.PropertyField(_outputAOTGenericReferenceFile); EditorGUILayout.PropertyField(_maxGenericReferenceIteration); diff --git a/Editor/Settings/HybridCLRSettings.cs b/Editor/Settings/HybridCLRSettings.cs index e179225..a2b4306 100644 --- a/Editor/Settings/HybridCLRSettings.cs +++ b/Editor/Settings/HybridCLRSettings.cs @@ -39,6 +39,9 @@ namespace HybridCLR.Editor.Settings [Tooltip("supplementary metadata assembly names(without .dll suffix)")] public string[] patchAOTAssemblies; + [Tooltip("don't preserve UnityEngine core types in link.xml")] + public bool dontPreserveUnityEngineCoreTypesInLinkXml = false; + [Tooltip("output file of automatic generated link.xml by scanning hot update assemblies")] public string outputLinkFile = "HybridCLRGenerate/link.xml";