Files
plugin-library/Assets/01.HybridCLR/Editor/Commands/MethodBridgeGeneratorCommand.cs

99 lines
4.4 KiB
C#
Raw Normal View History

2025-03-31 14:55:24 +08:00
using HybridCLR.Editor;
using HybridCLR.Editor.ABI;
using HybridCLR.Editor.Meta;
using HybridCLR.Editor.MethodBridge;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.Build;
using UnityEngine;
namespace HybridCLR.Editor.Commands
{
using Analyzer = HybridCLR.Editor.MethodBridge.Analyzer;
public class MethodBridgeGeneratorCommand
{
public static void CleanIl2CppBuildCache()
{
string il2cppBuildCachePath = SettingsUtil.Il2CppBuildCacheDir;
if (!Directory.Exists(il2cppBuildCachePath))
{
return;
}
Debug.Log($"clean il2cpp build cache:{il2cppBuildCachePath}");
Directory.Delete(il2cppBuildCachePath, true);
}
2025-06-12 18:00:06 +08:00
private static void GenerateMethodBridgeCppFile(IReadOnlyCollection<GenericMethod> genericMethods, List<RawMonoPInvokeCallbackMethodInfo> reversePInvokeMethods, IReadOnlyCollection<CallNativeMethodSignatureInfo> calliMethodSignatures, string tempFile, string outputFile)
2025-03-31 14:55:24 +08:00
{
2025-06-12 18:00:06 +08:00
string templateCode = File.ReadAllText(tempFile, Encoding.UTF8);
2025-03-31 14:55:24 +08:00
var g = new Generator(new Generator.Options()
{
TemplateCode = templateCode,
OutputFile = outputFile,
2025-06-12 18:00:06 +08:00
GenericMethods = genericMethods,
ReversePInvokeMethods = reversePInvokeMethods,
CalliMethodSignatures = calliMethodSignatures,
Development = EditorUserBuildSettings.development,
2025-03-31 14:55:24 +08:00
});
g.Generate();
Debug.LogFormat("[MethodBridgeGeneratorCommand] output:{0}", outputFile);
}
2025-06-12 18:00:06 +08:00
[MenuItem("HybridCLR/Generate/MethodBridgeAndReversePInvokeWrapper", priority = 101)]
public static void GenerateMethodBridgeAndReversePInvokeWrapper()
2025-03-31 14:55:24 +08:00
{
BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
2025-06-12 18:00:06 +08:00
GenerateMethodBridgeAndReversePInvokeWrapper(target);
2025-03-31 14:55:24 +08:00
}
2025-06-12 18:00:06 +08:00
public static void GenerateMethodBridgeAndReversePInvokeWrapper(BuildTarget target)
2025-03-31 14:55:24 +08:00
{
string aotDllDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
List<string> aotAssemblyNames = Directory.Exists(aotDllDir) ?
Directory.GetFiles(aotDllDir, "*.dll", SearchOption.TopDirectoryOnly).Select(Path.GetFileNameWithoutExtension).ToList()
: new List<string>();
if (aotAssemblyNames.Count == 0)
{
throw new Exception($"no aot assembly found. please run `HybridCLR/Generate/All` or `HybridCLR/Generate/AotDlls` to generate aot dlls before runing `HybridCLR/Generate/MethodBridge`");
}
2025-06-12 18:00:06 +08:00
AssemblyReferenceDeepCollector collector = new AssemblyReferenceDeepCollector(MetaUtil.CreateAOTAssemblyResolver(target), aotAssemblyNames);
var methodBridgeAnalyzer = new Analyzer(new Analyzer.Options
2025-03-31 14:55:24 +08:00
{
2025-06-12 18:00:06 +08:00
MaxIterationCount = Math.Min(20, SettingsUtil.HybridCLRSettings.maxMethodBridgeGenericIteration),
Collector = collector,
});
2025-03-31 14:55:24 +08:00
2025-06-12 18:00:06 +08:00
methodBridgeAnalyzer.Run();
List<string> hotUpdateDlls = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;
var cache = new AssemblyCache(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotUpdateDlls));
var reversePInvokeAnalyzer = new MonoPInvokeCallbackAnalyzer(cache, hotUpdateDlls);
reversePInvokeAnalyzer.Run();
var calliAnalyzer = new CalliAnalyzer(cache, hotUpdateDlls);
calliAnalyzer.Run();
var pinvokeAnalyzer = new PInvokeAnalyzer(cache, hotUpdateDlls);
pinvokeAnalyzer.Run();
var callPInvokeMethodSignatures = pinvokeAnalyzer.PInvokeMethodSignatures;
string templateFile = $"{SettingsUtil.TemplatePathInPackage}/MethodBridge.cpp.tpl";
string outputFile = $"{SettingsUtil.GeneratedCppDir}/MethodBridge.cpp";
var callNativeMethodSignatures = calliAnalyzer.CalliMethodSignatures.Concat(pinvokeAnalyzer.PInvokeMethodSignatures).ToList();
GenerateMethodBridgeCppFile(methodBridgeAnalyzer.GenericMethods, reversePInvokeAnalyzer.ReversePInvokeMethods, callNativeMethodSignatures, templateFile, outputFile);
2025-03-31 14:55:24 +08:00
CleanIl2CppBuildCache();
}
}
}