@@ -21,6 +21,10 @@ public class GenerateNativeMarshalMethodSources : AndroidTask
21
21
22
22
public bool EnableMarshalMethods { get ; set ; }
23
23
24
+ public bool EnableNativeRuntimeLinking { get ; set ; }
25
+
26
+ public ITaskItem [ ] MonoComponents { get ; set ; } = [ ] ;
27
+
24
28
[ Required ]
25
29
public string EnvironmentOutputDirectory { get ; set ; } = "" ;
26
30
@@ -39,7 +43,7 @@ public override bool RunTask ()
39
43
{
40
44
NativeCodeGenStateCollection ? nativeCodeGenStates = null ;
41
45
42
- if ( EnableMarshalMethods ) {
46
+ if ( EnableMarshalMethods || EnableNativeRuntimeLinking ) {
43
47
// Retrieve the stored NativeCodeGenStateCollection (and remove it from the cache)
44
48
nativeCodeGenStates = BuildEngine4 . UnregisterTaskObjectAssemblyLocal < NativeCodeGenStateCollection > (
45
49
MonoAndroidHelper . GetProjectBuildSpecificTaskObjectKey ( GenerateJavaStubs . NativeCodeGenStateObjectRegisterTaskKey , WorkingDirectory , IntermediateOutputDirectory ) ,
@@ -58,7 +62,9 @@ void Generate (NativeCodeGenStateCollection? nativeCodeGenStates, string abi)
58
62
var targetAbi = abi . ToLowerInvariant ( ) ;
59
63
var targetArch = MonoAndroidHelper . AbiToTargetArch ( abi ) ;
60
64
var marshalMethodsBaseAsmFilePath = Path . Combine ( EnvironmentOutputDirectory , $ "marshal_methods.{ targetAbi } ") ;
65
+ var pinvokePreserveBaseAsmFilePath = EnableNativeRuntimeLinking ? Path . Combine ( EnvironmentOutputDirectory , $ "pinvoke_preserve.{ targetAbi } ") : null ;
61
66
var marshalMethodsLlFilePath = $ "{ marshalMethodsBaseAsmFilePath } .ll";
67
+ var pinvokePreserveLlFilePath = pinvokePreserveBaseAsmFilePath != null ? $ "{ pinvokePreserveBaseAsmFilePath } .ll" : null ;
62
68
var ( assemblyCount , uniqueAssemblyNames ) = GetAssemblyCountAndUniqueNames ( ) ;
63
69
64
70
MarshalMethodsNativeAssemblyGenerator marshalMethodsAsmGen ;
@@ -80,6 +86,20 @@ void Generate (NativeCodeGenStateCollection? nativeCodeGenStates, string abi)
80
86
) ;
81
87
}
82
88
89
+ if ( EnableNativeRuntimeLinking ) {
90
+ var pinvokePreserveGen = new PreservePinvokesNativeAssemblyGenerator ( Log , EnsureCodeGenState ( nativeCodeGenStates , targetArch ) , MonoComponents ) ;
91
+ LLVMIR . LlvmIrModule pinvokePreserveModule = pinvokePreserveGen . Construct ( ) ;
92
+ using var pinvokePreserveWriter = MemoryStreamPool . Shared . CreateStreamWriter ( ) ;
93
+ try {
94
+ pinvokePreserveGen . Generate ( pinvokePreserveModule , targetArch , pinvokePreserveWriter , pinvokePreserveLlFilePath ! ) ;
95
+ } catch {
96
+ throw ;
97
+ } finally {
98
+ pinvokePreserveWriter . Flush ( ) ;
99
+ Files . CopyIfStreamChanged ( pinvokePreserveWriter . BaseStream , pinvokePreserveLlFilePath ! ) ;
100
+ }
101
+ }
102
+
83
103
var marshalMethodsModule = marshalMethodsAsmGen . Construct ( ) ;
84
104
using var marshalMethodsWriter = MemoryStreamPool . Shared . CreateStreamWriter ( ) ;
85
105
0 commit comments