Skip to content

Commit a263143

Browse files
Refactor <Aot/> to share code with .NET 6
Create a new <GetAotArguments/> task for usage in .NET 6.
1 parent d2d2e75 commit a263143

File tree

4 files changed

+275
-209
lines changed

4 files changed

+275
-209
lines changed

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Aot.targets

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ For <MonoAOTCompiler/> usage, see:
1818
TaskName="MonoAOTCompiler"
1919
AssemblyFile="$(MonoAOTCompilerTaskAssemblyPath)"
2020
/>
21+
<UsingTask TaskName="Xamarin.Android.Tasks.GetAotArguments" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
2122

2223
<Target Name="_AndroidAot"
2324
Condition=" '$(AotAssemblies)' == 'true' "
@@ -30,15 +31,30 @@ For <MonoAOTCompiler/> usage, see:
3031
* Hardcoded microsoft.netcore.app.runtime.aot.osx-x64.cross
3132
* Hardcoded '.21' to be replaced with ''
3233
-->
34+
<GetAotArguments
35+
AndroidAotMode="$(AndroidAotMode)"
36+
AndroidNdkDirectory="$(_AndroidNdkDirectory)"
37+
AndroidBinUtilsDirectory="$(AndroidBinUtilsDirectory)"
38+
AndroidApiLevel="$(_AndroidApiLevel)"
39+
ManifestFile="$(IntermediateOutputPath)android\AndroidManifest.xml"
40+
AndroidSequencePointsMode="$(_SequencePointsMode)"
41+
AotAdditionalArguments="$(AndroidAotAdditionalArguments)"
42+
AotOutputDirectory="$(_AndroidAotBinDirectory)"
43+
RuntimeIdentifier="$(RuntimeIdentifier)"
44+
EnableLLVM="$(EnableLLVM)"
45+
Profiles="@(_AotProfiles)">
46+
<Output PropertyName="_AotArguments" TaskParameter="Arguments" />
47+
</GetAotArguments>
3348
<ItemGroup>
3449
<_AotRuntimeIdentifiers Include="$([System.String]::Copy('%(_RIDs.Identity)').Replace('.21', ''))" />
3550
<_AotCompilerPaths Include="$(MSBuildThisFileDirectory)..\..\..\microsoft.netcore.app.runtime.aot.osx-x64.cross.%(_AotRuntimeIdentifiers.Identity)\$(MonoAOTCompilerVersion)\tools\mono-aot-cross" />
51+
<_AotAssemblies Include="@(_ShrunkAssemblies->'%(FullPath)')" AotArguments="$(_AotArguments)" />
3652
</ItemGroup>
3753
<MonoAOTCompiler
3854
AotModulesTableLanguage="$(_AotModulesTableLanguage)"
3955
AotModulesTablePath="$(_AotModulesTablePath)"
4056
AotProfilePath="$(_AotProfilePath)"
41-
Assemblies="@(_ShrunkAssemblies->'%(FullPath)')"
57+
Assemblies="@(_AotAssemblies)"
4258
CompilerBinaryPath="%(_AotCompilerPaths.FullPath)"
4359
DisableParallelAot="$(_DisableParallelAot)"
4460
LLVMPath="$(_LLVMPath)"

src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs

Lines changed: 4 additions & 207 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Collections.Specialized;
43
using System.Diagnostics;
54
using System.IO;
65
using System.Linq;
7-
using System.Reflection;
86
using System.Text;
97
using System.Threading;
108
using Microsoft.Build.Framework;
@@ -33,110 +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-
if (EnableLLVM && !NdkUtil.Init (LogCodedError, AndroidNdkDirectory))
90-
return false;
91-
92-
return base.RunTask ();
93-
}
94-
95-
public static bool GetAndroidAotMode(string androidAotMode, out AotMode aotMode)
96-
{
97-
aotMode = AotMode.Normal;
98-
99-
switch ((androidAotMode ?? string.Empty).ToLowerInvariant().Trim())
100-
{
101-
case "":
102-
case "none":
103-
aotMode = AotMode.None;
104-
return true;
105-
case "normal":
106-
aotMode = AotMode.Normal;
107-
return true;
108-
case "hybrid":
109-
aotMode = AotMode.Hybrid;
110-
return true;
111-
case "full":
112-
aotMode = AotMode.Full;
113-
return true;
114-
case "interpreter":
115-
aotMode = AotMode.Interp;
116-
return true; // We don't do anything here for this mode, this is just to set the flag for the XA
117-
// runtime to initialize Mono in the inrepreter "AOT" mode.
118-
}
119-
120-
return false;
121-
}
122-
123-
public static bool TryGetSequencePointsMode (string value, out SequencePointsMode mode)
124-
{
125-
mode = SequencePointsMode.None;
126-
switch ((value ?? string.Empty).ToLowerInvariant().Trim ()) {
127-
case "none":
128-
mode = SequencePointsMode.None;
129-
return true;
130-
case "normal":
131-
mode = SequencePointsMode.Normal;
132-
return true;
133-
case "offline":
134-
mode = SequencePointsMode.Offline;
135-
return true;
136-
}
137-
return false;
138-
}
139-
14057
static string GetNdkToolchainLibraryDir(string binDir, string archDir = null)
14158
{
14259
var baseDir = Path.GetFullPath(Path.Combine(binDir, ".."));
@@ -182,66 +99,8 @@ static string QuoteFileName(string fileName)
18299
return builder.ToString();
183100
}
184101

185-
int GetNdkApiLevel(string androidNdkPath, string androidApiLevel, AndroidTargetArch arch)
186-
{
187-
var manifest = AndroidAppManifest.Load (ManifestFile.ItemSpec, MonoAndroidHelper.SupportedVersions);
188-
189-
int level;
190-
if (manifest.MinSdkVersion.HasValue) {
191-
level = manifest.MinSdkVersion.Value;
192-
}
193-
else if (int.TryParse (androidApiLevel, out level)) {
194-
// level already set
195-
}
196-
else {
197-
// Probably not ideal!
198-
level = MonoAndroidHelper.SupportedVersions.MaxStableVersion.ApiLevel;
199-
}
200-
201-
// Some Android API levels do not exist on the NDK level. Workaround this my mapping them to the
202-
// most appropriate API level that does exist.
203-
if (level == 6 || level == 7) level = 5;
204-
else if (level == 10) level = 9;
205-
else if (level == 11) level = 12;
206-
else if (level == 20) level = 19;
207-
else if (level == 22) level = 21;
208-
else if (level == 23) level = 21;
209-
210-
// API levels below level 21 do not provide support for 64-bit architectures.
211-
if (NdkUtil.IsNdk64BitArch(arch) && level < 21) {
212-
level = 21;
213-
}
214-
215-
// We perform a downwards API level lookup search since we might not have hardcoded the correct API
216-
// mapping above and we do not want to crash needlessly.
217-
for (; level >= 5; level--) {
218-
try {
219-
NdkUtil.GetNdkPlatformLibPath (androidNdkPath, arch, level);
220-
break;
221-
} catch (InvalidOperationException ex) {
222-
// Path not found, continue searching...
223-
continue;
224-
}
225-
}
226-
227-
return level;
228-
}
229-
230102
public async override System.Threading.Tasks.Task RunTaskAsync ()
231103
{
232-
bool hasValidAotMode = GetAndroidAotMode (AndroidAotMode, out AotMode);
233-
if (!hasValidAotMode) {
234-
LogCodedError ("XA3002", Properties.Resources.XA3002, AndroidAotMode);
235-
return;
236-
}
237-
238-
if (AotMode == AotMode.Interp) {
239-
LogDebugMessage ("Interpreter AOT mode enabled");
240-
return;
241-
}
242-
243-
TryGetSequencePointsMode (AndroidSequencePointsMode, out sequencePointsMode);
244-
245104
var nativeLibs = new List<string> ();
246105

247106
await this.WhenAllWithLock (GetAotConfigs (),
@@ -275,48 +134,8 @@ IEnumerable<Config> GetAotConfigs ()
275134
if (!Directory.Exists (AotOutputDirectory))
276135
Directory.CreateDirectory (AotOutputDirectory);
277136

278-
var sdkBinDirectory = MonoAndroidHelper.GetOSBinPath ();
279137
foreach (var abi in SupportedAbis) {
280-
string aotCompiler = "";
281-
string outdir = "";
282-
string mtriple = "";
283-
AndroidTargetArch arch;
284-
285-
switch (abi) {
286-
case "armeabi-v7a":
287-
aotCompiler = Path.Combine (sdkBinDirectory, "cross-arm");
288-
outdir = Path.Combine (AotOutputDirectory, "armeabi-v7a");
289-
mtriple = "armv7-linux-gnueabi";
290-
arch = AndroidTargetArch.Arm;
291-
break;
292-
293-
case "arm64":
294-
case "arm64-v8a":
295-
case "aarch64":
296-
aotCompiler = Path.Combine (sdkBinDirectory, "cross-arm64");
297-
outdir = Path.Combine (AotOutputDirectory, "arm64-v8a");
298-
mtriple = "aarch64-linux-android";
299-
arch = AndroidTargetArch.Arm64;
300-
break;
301-
302-
case "x86":
303-
aotCompiler = Path.Combine (sdkBinDirectory, "cross-x86");
304-
outdir = Path.Combine (AotOutputDirectory, "x86");
305-
mtriple = "i686-linux-android";
306-
arch = AndroidTargetArch.X86;
307-
break;
308-
309-
case "x86_64":
310-
aotCompiler = Path.Combine (sdkBinDirectory, "cross-x86_64");
311-
outdir = Path.Combine (AotOutputDirectory, "x86_64");
312-
mtriple = "x86_64-linux-android";
313-
arch = AndroidTargetArch.X86_64;
314-
break;
315-
316-
// case "mips":
317-
default:
318-
throw new Exception ("Unsupported Android target architecture ABI: " + abi);
319-
}
138+
(string aotCompiler, string outdir, string mtriple, AndroidTargetArch arch) = GetAbiSettings (abi);
320139

321140
if (EnableLLVM && !NdkUtil.ValidateNdkPlatform (LogMessage, LogCodedError, AndroidNdkDirectory, arch, enableLLVM:EnableLLVM)) {
322141
yield return Config.Invalid;
@@ -332,10 +151,7 @@ IEnumerable<Config> GetAotConfigs ()
332151
outdir = outdir.Replace (WorkingDirectory + Path.DirectorySeparatorChar, string.Empty);
333152
}
334153

335-
int level = 0;
336-
string toolPrefix = EnableLLVM
337-
? NdkUtil.GetNdkToolPrefix (AndroidNdkDirectory, arch, level = GetNdkApiLevel (AndroidNdkDirectory, AndroidApiLevel, arch))
338-
: Path.Combine (AndroidBinUtilsDirectory, $"{NdkUtil.GetArchDirName (arch)}-");
154+
string toolPrefix = GetToolPrefix (arch, out int level);
339155
var toolchainPath = toolPrefix.Substring(0, toolPrefix.LastIndexOf(Path.DirectorySeparatorChar));
340156
var ldFlags = string.Empty;
341157
if (EnableLLVM) {
@@ -387,27 +203,8 @@ IEnumerable<Config> GetAotConfigs ()
387203
if (!Directory.Exists (tempDir))
388204
Directory.CreateDirectory (tempDir);
389205

390-
List<string> aotOptions = new List<string> ();
391-
392-
if (Profiles != null && Profiles.Length > 0) {
393-
aotOptions.Add ("profile-only");
394-
foreach (var p in Profiles) {
395-
var fp = Path.GetFullPath (p.ItemSpec);
396-
aotOptions.Add ($"profile={fp}");
397-
}
398-
}
399-
if (!string.IsNullOrEmpty (AotAdditionalArguments))
400-
aotOptions.Add (AotAdditionalArguments);
401-
if (sequencePointsMode == SequencePointsMode.Offline)
402-
aotOptions.Add ($"msym-dir={outdir}");
403-
if (AotMode != AotMode.Normal)
404-
aotOptions.Add (AotMode.ToString ().ToLowerInvariant ());
405-
206+
var aotOptions = GetAotOptions (outdir, mtriple, toolPrefix);
406207
aotOptions.Add ($"outfile={outputFile}");
407-
aotOptions.Add ("asmwriter");
408-
aotOptions.Add ($"mtriple={mtriple}");
409-
aotOptions.Add ($"tool-prefix={toolPrefix}");
410-
aotOptions.Add ($"llvm-path={sdkBinDirectory}");
411208
aotOptions.Add ($"temp-path={tempDir}");
412209
aotOptions.Add ($"ld-flags={ldFlags}");
413210

0 commit comments

Comments
 (0)