11using System ;
22using System . Collections . Generic ;
3- using System . Collections . Specialized ;
43using System . Diagnostics ;
54using System . IO ;
65using System . Linq ;
7- using System . Reflection ;
86using System . Text ;
97using System . Threading ;
108using Microsoft . Build . Framework ;
@@ -33,111 +31,29 @@ public enum SequencePointsMode {
3331 }
3432
3533 // can't be a single ToolTask, because it has to run mkbundle many times for each arch.
36- public class Aot : AndroidAsyncTask
34+ public class Aot : GetAotArguments
3735 {
3836 public override string TaskPrefix => "AOT" ;
3937
40- [ Required ]
41- public string AndroidAotMode { get ; set ; }
42-
43- public string AndroidNdkDirectory { get ; set ; }
44-
45- [ Required ]
46- public string AndroidApiLevel { get ; set ; }
47-
48- [ Required ]
49- public ITaskItem ManifestFile { get ; set ; }
50-
5138 [ Required ]
5239 public ITaskItem [ ] ResolvedAssemblies { get ; set ; }
5340
5441 // Which ABIs to include native libs for
5542 [ Required ]
5643 public string [ ] SupportedAbis { get ; set ; }
5744
58- [ Required ]
59- public string AotOutputDirectory { get ; set ; }
60-
6145 [ Required ]
6246 public string IntermediateAssemblyDir { get ; set ; }
6347
6448 public string LinkMode { get ; set ; }
6549
66- public bool EnableLLVM { get ; set ; }
67-
68- public string AndroidSequencePointsMode { get ; set ; }
69-
70- public string AotAdditionalArguments { get ; set ; }
71-
7250 public ITaskItem [ ] AdditionalNativeLibraryReferences { get ; set ; }
7351
7452 public string ExtraAotOptions { get ; set ; }
7553
76- public ITaskItem [ ] Profiles { get ; set ; }
77-
78- [ Required ]
79- public string AndroidBinUtilsDirectory { get ; set ; }
80-
8154 [ Output ]
8255 public string [ ] NativeLibrariesReferences { get ; set ; }
8356
84- AotMode AotMode ;
85- SequencePointsMode sequencePointsMode ;
86-
87- public override bool RunTask ( )
88- {
89- // NdkUtil must always be initialized - once per thread
90- if ( ! NdkUtil . Init ( LogCodedError , AndroidNdkDirectory ) )
91- return false ;
92-
93- return base . RunTask ( ) ;
94- }
95-
96- public static bool GetAndroidAotMode ( string androidAotMode , out AotMode aotMode )
97- {
98- aotMode = AotMode . Normal ;
99-
100- switch ( ( androidAotMode ?? string . Empty ) . ToLowerInvariant ( ) . Trim ( ) )
101- {
102- case "" :
103- case "none" :
104- aotMode = AotMode . None ;
105- return true ;
106- case "normal" :
107- aotMode = AotMode . Normal ;
108- return true ;
109- case "hybrid" :
110- aotMode = AotMode . Hybrid ;
111- return true ;
112- case "full" :
113- aotMode = AotMode . Full ;
114- return true ;
115- case "interpreter" :
116- aotMode = AotMode . Interp ;
117- return true ; // We don't do anything here for this mode, this is just to set the flag for the XA
118- // runtime to initialize Mono in the inrepreter "AOT" mode.
119- }
120-
121- return false ;
122- }
123-
124- public static bool TryGetSequencePointsMode ( string value , out SequencePointsMode mode )
125- {
126- mode = SequencePointsMode . None ;
127- switch ( ( value ?? string . Empty ) . ToLowerInvariant ( ) . Trim ( ) ) {
128- case "none" :
129- mode = SequencePointsMode . None ;
130- return true ;
131- case "normal" :
132- mode = SequencePointsMode . Normal ;
133- return true ;
134- case "offline" :
135- mode = SequencePointsMode . Offline ;
136- return true ;
137- }
138- return false ;
139- }
140-
14157 static string GetNdkToolchainLibraryDir ( string binDir , string archDir = null )
14258 {
14359 var baseDir = Path . GetFullPath ( Path . Combine ( binDir , ".." ) ) ;
@@ -183,51 +99,6 @@ static string QuoteFileName(string fileName)
18399 return builder . ToString ( ) ;
184100 }
185101
186- int GetNdkApiLevel ( string androidNdkPath , string androidApiLevel , AndroidTargetArch arch )
187- {
188- var manifest = AndroidAppManifest . Load ( ManifestFile . ItemSpec , MonoAndroidHelper . SupportedVersions ) ;
189-
190- int level ;
191- if ( manifest . MinSdkVersion . HasValue ) {
192- level = manifest . MinSdkVersion . Value ;
193- }
194- else if ( int . TryParse ( androidApiLevel , out level ) ) {
195- // level already set
196- }
197- else {
198- // Probably not ideal!
199- level = MonoAndroidHelper . SupportedVersions . MaxStableVersion . ApiLevel ;
200- }
201-
202- // Some Android API levels do not exist on the NDK level. Workaround this my mapping them to the
203- // most appropriate API level that does exist.
204- if ( level == 6 || level == 7 ) level = 5 ;
205- else if ( level == 10 ) level = 9 ;
206- else if ( level == 11 ) level = 12 ;
207- else if ( level == 20 ) level = 19 ;
208- else if ( level == 22 ) level = 21 ;
209- else if ( level == 23 ) level = 21 ;
210-
211- // API levels below level 21 do not provide support for 64-bit architectures.
212- if ( NdkUtil . IsNdk64BitArch ( arch ) && level < 21 ) {
213- level = 21 ;
214- }
215-
216- // We perform a downwards API level lookup search since we might not have hardcoded the correct API
217- // mapping above and we do not want to crash needlessly.
218- for ( ; level >= 5 ; level -- ) {
219- try {
220- NdkUtil . GetNdkPlatformLibPath ( androidNdkPath , arch , level ) ;
221- break ;
222- } catch ( InvalidOperationException ex ) {
223- // Path not found, continue searching...
224- continue ;
225- }
226- }
227-
228- return level ;
229- }
230-
231102 public async override System . Threading . Tasks . Task RunTaskAsync ( )
232103 {
233104 // NdkUtil must always be initialized - once per thread
@@ -236,19 +107,6 @@ public async override System.Threading.Tasks.Task RunTaskAsync ()
236107 return ;
237108 }
238109
239- bool hasValidAotMode = GetAndroidAotMode ( AndroidAotMode , out AotMode ) ;
240- if ( ! hasValidAotMode ) {
241- LogCodedError ( "XA3002" , Properties . Resources . XA3002 , AndroidAotMode ) ;
242- return ;
243- }
244-
245- if ( AotMode == AotMode . Interp ) {
246- LogDebugMessage ( "Interpreter AOT mode enabled" ) ;
247- return ;
248- }
249-
250- TryGetSequencePointsMode ( AndroidSequencePointsMode , out sequencePointsMode ) ;
251-
252110 var nativeLibs = new List < string > ( ) ;
253111
254112 await this . WhenAllWithLock ( GetAotConfigs ( ) ,
@@ -282,48 +140,8 @@ IEnumerable<Config> GetAotConfigs ()
282140 if ( ! Directory . Exists ( AotOutputDirectory ) )
283141 Directory . CreateDirectory ( AotOutputDirectory ) ;
284142
285- var sdkBinDirectory = MonoAndroidHelper . GetOSBinPath ( ) ;
286143 foreach ( var abi in SupportedAbis ) {
287- string aotCompiler = "" ;
288- string outdir = "" ;
289- string mtriple = "" ;
290- AndroidTargetArch arch ;
291-
292- switch ( abi ) {
293- case "armeabi-v7a" :
294- aotCompiler = Path . Combine ( sdkBinDirectory , "cross-arm" ) ;
295- outdir = Path . Combine ( AotOutputDirectory , "armeabi-v7a" ) ;
296- mtriple = "armv7-linux-gnueabi" ;
297- arch = AndroidTargetArch . Arm ;
298- break ;
299-
300- case "arm64" :
301- case "arm64-v8a" :
302- case "aarch64" :
303- aotCompiler = Path . Combine ( sdkBinDirectory , "cross-arm64" ) ;
304- outdir = Path . Combine ( AotOutputDirectory , "arm64-v8a" ) ;
305- mtriple = "aarch64-linux-android" ;
306- arch = AndroidTargetArch . Arm64 ;
307- break ;
308-
309- case "x86" :
310- aotCompiler = Path . Combine ( sdkBinDirectory , "cross-x86" ) ;
311- outdir = Path . Combine ( AotOutputDirectory , "x86" ) ;
312- mtriple = "i686-linux-android" ;
313- arch = AndroidTargetArch . X86 ;
314- break ;
315-
316- case "x86_64" :
317- aotCompiler = Path . Combine ( sdkBinDirectory , "cross-x86_64" ) ;
318- outdir = Path . Combine ( AotOutputDirectory , "x86_64" ) ;
319- mtriple = "x86_64-linux-android" ;
320- arch = AndroidTargetArch . X86_64 ;
321- break ;
322-
323- // case "mips":
324- default :
325- throw new Exception ( "Unsupported Android target architecture ABI: " + abi ) ;
326- }
144+ ( string aotCompiler , string outdir , string mtriple , AndroidTargetArch arch ) = GetAbiSettings ( abi ) ;
327145
328146 if ( EnableLLVM && ! NdkUtil . ValidateNdkPlatform ( LogMessage , LogCodedError , AndroidNdkDirectory , arch , enableLLVM : EnableLLVM ) ) {
329147 yield return Config . Invalid ;
@@ -339,10 +157,7 @@ IEnumerable<Config> GetAotConfigs ()
339157 outdir = outdir . Replace ( WorkingDirectory + Path . DirectorySeparatorChar , string . Empty ) ;
340158 }
341159
342- int level = 0 ;
343- string toolPrefix = EnableLLVM
344- ? NdkUtil . GetNdkToolPrefix ( AndroidNdkDirectory , arch , level = GetNdkApiLevel ( AndroidNdkDirectory , AndroidApiLevel , arch ) )
345- : Path . Combine ( AndroidBinUtilsDirectory , $ "{ NdkUtil . GetArchDirName ( arch ) } -") ;
160+ string toolPrefix = GetToolPrefix ( arch , out int level ) ;
346161 var toolchainPath = toolPrefix . Substring ( 0 , toolPrefix . LastIndexOf ( Path . DirectorySeparatorChar ) ) ;
347162 var ldFlags = string . Empty ;
348163 if ( EnableLLVM ) {
@@ -407,27 +222,8 @@ IEnumerable<Config> GetAotConfigs ()
407222 if ( ! Directory . Exists ( tempDir ) )
408223 Directory . CreateDirectory ( tempDir ) ;
409224
410- List < string > aotOptions = new List < string > ( ) ;
411-
412- if ( Profiles != null && Profiles . Length > 0 ) {
413- aotOptions . Add ( "profile-only" ) ;
414- foreach ( var p in Profiles ) {
415- var fp = Path . GetFullPath ( p . ItemSpec ) ;
416- aotOptions . Add ( $ "profile={ fp } ") ;
417- }
418- }
419- if ( ! string . IsNullOrEmpty ( AotAdditionalArguments ) )
420- aotOptions . Add ( AotAdditionalArguments ) ;
421- if ( sequencePointsMode == SequencePointsMode . Offline )
422- aotOptions . Add ( $ "msym-dir={ outdir } ") ;
423- if ( AotMode != AotMode . Normal )
424- aotOptions . Add ( AotMode . ToString ( ) . ToLowerInvariant ( ) ) ;
425-
225+ var aotOptions = GetAotOptions ( outdir , mtriple , toolPrefix ) ;
426226 aotOptions . Add ( $ "outfile={ outputFile } ") ;
427- aotOptions . Add ( "asmwriter" ) ;
428- aotOptions . Add ( $ "mtriple={ mtriple } ") ;
429- aotOptions . Add ( $ "tool-prefix={ toolPrefix } ") ;
430- aotOptions . Add ( $ "llvm-path={ sdkBinDirectory } ") ;
431227 aotOptions . Add ( $ "temp-path={ tempDir } ") ;
432228
433229 if ( ! String . IsNullOrEmpty ( ldName ) ) {
0 commit comments