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 ();
}
}
}