Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
AndroidApiLevel="$(_AndroidApiLevel)"
MinimumSupportedApiLevel="$(AndroidMinimumSupportedApiLevel)"
AndroidSequencePointsMode="$(_SequencePointsMode)"
AotAdditionalArguments="$(AndroidAotAdditionalArguments)"
TargetName="$(TargetName)"
ResolvedAssemblies="@(_AndroidAotInputs)"
AotOutputDirectory="$(_AndroidAotBinDirectory)"
RuntimeIdentifier="$(RuntimeIdentifier)"
EnableLLVM="$(EnableLLVM)"
UsingAndroidNETSdk="true"
Profiles="@(AndroidAotProfile)">
<Output PropertyName="_Triple" TaskParameter="Triple" />
<Output PropertyName="_ToolPrefix" TaskParameter="ToolPrefix" />
<Output PropertyName="_MsymPath" TaskParameter="MsymPath" />
<Output PropertyName="_LdName" TaskParameter="LdName" />
<Output PropertyName="_LdFlags" TaskParameter="LdFlags" />
<Output ItemName="_MonoAOTAssemblies" TaskParameter="ResolvedAssemblies" />
</GetAotAssemblies>
<PropertyGroup>
Expand All @@ -69,7 +72,10 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
</PropertyGroup>
<MakeDir Directories="$(IntermediateOutputPath)aot\" />
<MonoAOTCompiler
Assemblies="@(_MonoAOTAssemblies->'%(FullPath)')"
Triple="$(_Triple)"
ToolPrefix="$(_ToolPrefix)"
MsymPath="$(_MsymPath)"
Assemblies="@(_MonoAOTAssemblies)"
CompilerBinaryPath="$(_MonoAOTCompilerPath)"
DisableParallelAot="$(_DisableParallelAot)"
IntermediateOutputPath="$(IntermediateOutputPath)"
Expand All @@ -79,7 +85,11 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
OutputType="Library"
UseAotDataFile="false"
UseLLVM="$(EnableLLVM)"
LLVMPath="$(_LLVMPath)">
LLVMPath="$(_LLVMPath)"
LdName="$(_LdName)"
LdFlags="$(_LdFlags)"
WorkingDirectory="$(MSBuildProjectDirectory)"
AotArguments="$(AndroidAotAdditionalArguments)">
<Output TaskParameter="CompiledAssemblies" ItemName="_AotCompiledAssemblies" />
<Output TaskParameter="FileWrites" ItemName="FileWrites" />
</MonoAOTCompiler>
Expand Down
26 changes: 22 additions & 4 deletions src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class Aot : GetAotArguments

public string ExtraAotOptions { get; set; }

public string AotAdditionalArguments { get; set; }

[Output]
public string[] NativeLibrariesReferences { get; set; }

Expand Down Expand Up @@ -137,11 +139,27 @@ IEnumerable<Config> GetAotConfigs (NdkTools ndk)
string tempDir = Path.Combine (outdir, Path.GetFileName (assembly.ItemSpec));
Directory.CreateDirectory (tempDir);

var aotOptions = GetAotOptions (ndk, arch, level, outdir, mtriple, toolPrefix);
GetAotOptions (ndk, arch, level, outdir, toolPrefix);
// NOTE: ordering seems to matter on Windows
aotOptions.Insert (0, $"outfile={outputFile}");
aotOptions.Insert (0, $"llvm-path={SdkBinDirectory}");
aotOptions.Insert (0, $"temp-path={tempDir}");
var aotOptions = new List<string> ();
aotOptions.Add ("asmwriter");
aotOptions.Add ($"mtriple={mtriple}");
aotOptions.Add ($"tool-prefix={toolPrefix}");
aotOptions.Add ($"outfile={outputFile}");
aotOptions.Add ($"llvm-path={SdkBinDirectory}");
aotOptions.Add ($"temp-path={tempDir}");
if (!string.IsNullOrEmpty (AotAdditionalArguments)) {
aotOptions.Add (AotAdditionalArguments);
}
if (!string.IsNullOrEmpty (MsymPath)) {
aotOptions.Add ($"msym-dir={MsymPath}");
}
if (!string.IsNullOrEmpty (LdName)) {
aotOptions.Add ($"ld-name={LdName}");
}
if (!string.IsNullOrEmpty (LdFlags)) {
aotOptions.Add ($"ld-flags={LdFlags}");
}
if (Profiles != null && Profiles.Length > 0) {
if (Path.GetFileNameWithoutExtension (assembly.ItemSpec) == TargetName) {
LogDebugMessage ($"Not using profile(s) for main assembly: {assembly.ItemSpec}");
Expand Down
51 changes: 21 additions & 30 deletions src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,24 @@ public abstract class GetAotArguments : AndroidAsyncTask

public ITaskItem [] Profiles { get; set; } = Array.Empty<ITaskItem> ();

public bool UsingAndroidNETSdk { get; set; }

public string AotAdditionalArguments { get; set; } = "";

[Required, Output]
public ITaskItem [] ResolvedAssemblies { get; set; } = Array.Empty<ITaskItem> ();

[Output]
public string? Triple { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming suggestion: TargetTriplet (as per autoconf docs) instead of Triple. Triple is not necessarily "fully semantically meaningful."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neither TargetTriplet or Triple really mean anything to me -- so open to suggestions.

The <MonoAOTCompiler/> task uses Triple, which passes mtriple to the actual AOT compiler:

https://github.com/dotnet/runtime/blob/bdc6ad73834a13e80f131e402e883903c31ea172/src/tasks/AotCompilerTask/MonoAOTCompiler.cs#L573-L576

We could use a different name, but is that worse? We'd still be using Triple on the next task unless we also renamed it -- and also got that change backported.


[Output]
public string? ToolPrefix { get; set; }

[Output]
public string? MsymPath { get; set; }

[Output]
public string? LdName { get; set; }

[Output]
public string? LdFlags { get; set; }

protected AotMode AotMode;
protected SequencePointsMode SequencePointsMode;
protected string SdkBinDirectory = "";
Expand Down Expand Up @@ -208,22 +219,12 @@ int GetNdkApiLevel (NdkTools ndk, AndroidTargetArch arch)
}

/// <summary>
/// Returns a list of parameters to pass to the --aot switch
/// Fills [Output] parameters to pass to the --aot switch
/// </summary>
protected List<string> GetAotOptions (NdkTools ndk, AndroidTargetArch arch, int level, string outdir, string mtriple, string toolPrefix)
protected void GetAotOptions (NdkTools ndk, AndroidTargetArch arch, int level, string outdir, string toolPrefix)
{
List<string> aotOptions = new List<string> ();

if (!string.IsNullOrEmpty (AotAdditionalArguments))
aotOptions.Add (AotAdditionalArguments);
if (SequencePointsMode == SequencePointsMode.Offline)
aotOptions.Add ($"msym-dir={outdir}");
if (AotMode != AotMode.Normal)
aotOptions.Add (AotMode.ToString ().ToLowerInvariant ());

aotOptions.Add ("asmwriter");
aotOptions.Add ($"mtriple={mtriple}");
aotOptions.Add ($"tool-prefix={toolPrefix}");
MsymPath = outdir;

string ldName;
if (EnableLLVM) {
Expand All @@ -238,16 +239,12 @@ protected List<string> GetAotOptions (NdkTools ndk, AndroidTargetArch arch, int
ldName = "ld";
}
string ldFlags = GetLdFlags (ndk, arch, level, toolPrefix);

// MUST be before `ld-flags`, otherwise Mono fails to parse it on Windows
if (!string.IsNullOrEmpty (ldName)) {
aotOptions.Add ($"ld-name={ldName}");
LdName = ldName;
}
if (!string.IsNullOrEmpty (ldFlags)) {
aotOptions.Add ($"ld-flags={ldFlags}");
LdFlags = ldFlags;
}

return aotOptions;
}

string GetLdFlags(NdkTools ndk, AndroidTargetArch arch, int level, string toolPrefix)
Expand Down Expand Up @@ -292,13 +289,7 @@ string GetLdFlags(NdkTools ndk, AndroidTargetArch arch, int level, string toolPr
libs.Add (Path.Combine (androidLibPath, "libc.so"));
libs.Add (Path.Combine (androidLibPath, "libm.so"));

if (UsingAndroidNETSdk) {
// NOTE: in .NET 6+ use space for the delimiter and escape spaces in paths
var escaped = libs.Select (l => l.Replace (" ", "\\ "));
ldFlags = string.Join (" ", escaped);
} else {
ldFlags = $"\\\"{string.Join ("\\\";\\\"", libs)}\\\"";
}
ldFlags = $"\\\"{string.Join ("\\\";\\\"", libs)}\\\"";
}
return ldFlags;
}
Expand Down
16 changes: 9 additions & 7 deletions src/Xamarin.Android.Build.Tasks/Tasks/GetAotAssemblies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ public override Task RunTaskAsync ()
}

(_, string outdir, string mtriple, AndroidTargetArch arch) = GetAbiSettings (abi);
string toolPrefix = GetToolPrefix (ndk, arch, out int level);
Triple = mtriple;
ToolPrefix = GetToolPrefix (ndk, arch, out int level);

var aotOptions = GetAotOptions (ndk, arch, level, outdir, mtriple, toolPrefix);
GetAotOptions (ndk, arch, level, outdir, ToolPrefix);

var aotProfiles = new StringBuilder ();
if (Profiles != null && Profiles.Length > 0) {
Expand All @@ -56,15 +57,16 @@ public override Task RunTaskAsync ()
}
}

var arguments = string.Join (",", aotOptions);
foreach (var assembly in ResolvedAssemblies) {
var temp = Path.GetFullPath (Path.Combine (outdir, Path.GetFileNameWithoutExtension (assembly.ItemSpec)));
var temp = Path.Combine (outdir, Path.GetFileNameWithoutExtension (assembly.ItemSpec));
Directory.CreateDirectory (temp);
if (Path.GetFileNameWithoutExtension (assembly.ItemSpec) == TargetName) {
LogDebugMessage ($"Not using profile(s) for main assembly: {assembly.ItemSpec}");
assembly.SetMetadata ("AotArguments", $"{arguments},temp-path={temp}");
if (Profiles != null && Profiles.Length > 0) {
LogDebugMessage ($"Not using profile(s) for main assembly: {assembly.ItemSpec}");
}
assembly.SetMetadata ("AotArguments", $"asmwriter,temp-path={temp}");
} else {
assembly.SetMetadata ("AotArguments", $"{arguments},temp-path={temp}{aotProfiles}");
assembly.SetMetadata ("AotArguments", $"asmwriter,temp-path={temp}{aotProfiles}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ public void Setup ()
{
if (!IsWindows)
return;
// Use standard NDK directory for now
// See: https://github.com/dotnet/runtime/issues/56163
if (Builder.UseDotNet)
return;

var sdkPath = AndroidSdkPath;
var ndkPath = AndroidNdkPath;
Expand All @@ -49,10 +45,6 @@ public void TearDown ()
{
if (!IsWindows)
return;
// Use standard NDK directory for now
// See: https://github.com/dotnet/runtime/issues/56163
if (Builder.UseDotNet)
return;
Environment.SetEnvironmentVariable ("TEST_ANDROID_SDK_PATH", "");
Environment.SetEnvironmentVariable ("TEST_ANDROID_NDK_PATH", "");
Directory.Delete (SdkWithSpacesPath, recursive: true);
Expand Down Expand Up @@ -169,7 +161,6 @@ public void BuildBasicApplicationReleaseProfiledAotWithoutDefaultProfile ()

[Test]
[TestCaseSource (nameof (AotChecks))]
[Category ("DotNetIgnore")] // Not currently working, see: https://github.com/dotnet/runtime/issues/56163
public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult, bool usesAssemblyBlobs)
{
var path = Path.Combine ("temp", string.Format ("BuildAotApplication AndÜmläüts_{0}_{1}_{2}_{3}", supportedAbis, enableLLVM, expectedResult, usesAssemblyBlobs));
Expand Down Expand Up @@ -203,7 +194,7 @@ public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableL
if (!expectedResult)
return;
//NOTE: Windows has shortened paths such as: C:\Users\myuser\ANDROI~3\ndk\PLATFO~1\AN3971~1\arch-x86\usr\lib\libc.so
if (checkMinLlvmPath && !IsWindows) {
if (checkMinLlvmPath && !IsWindows && !Builder.UseDotNet) {
Xamarin.Android.Tasks.NdkTools ndk = Xamarin.Android.Tasks.NdkTools.Create (AndroidNdkPath);
bool ndk22OrNewer = ndk.Version.Main.Major >= 22;

Expand All @@ -218,12 +209,13 @@ public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableL
}
}
foreach (var abi in supportedAbis.Split (new char [] { ';' })) {
var libapp = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath,
"bundles", abi, "libmonodroid_bundle_app.so");
Assert.IsFalse (File.Exists (libapp), abi + " libmonodroid_bundle_app.so should not exist");
var assemblies = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath,
"aot", abi, "libaot-UnnamedProject.dll.so");
Assert.IsTrue (File.Exists (assemblies), "{0} libaot-UnnamedProject.dll.so does not exist", abi);
var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
var libapp = Path.Combine (intermediate, "bundles", abi, "libmonodroid_bundle_app.so");
FileAssert.DoesNotExist (libapp);
var aotNativeLibrary = Builder.UseDotNet ?
Path.Combine (intermediate, AbiUtils.AbiToRuntimeIdentifier (abi), "aot", "UnnamedProject.dll.so") :
Path.Combine (intermediate, "aot", abi, "libaot-UnnamedProject.dll.so");
FileAssert.Exists (aotNativeLibrary);
var apk = Path.Combine (Root, b.ProjectDirectory,
proj.OutputPath, $"{proj.PackageName}-Signed.apk");

Expand All @@ -248,7 +240,6 @@ public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableL
[Test]
[TestCaseSource (nameof (AotChecks))]
[Category ("Minor"), Category ("MkBundle")]
[Category ("DotNetIgnore")] // Not currently working, see: https://github.com/dotnet/runtime/issues/56163
public void BuildAotApplicationAndBundleAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult, bool usesAssemblyBlobs)
{
var path = Path.Combine ("temp", string.Format ("BuildAotApplicationAndBundle AndÜmläüts_{0}_{1}_{2}_{3}", supportedAbis, enableLLVM, expectedResult, usesAssemblyBlobs));
Expand Down Expand Up @@ -449,10 +440,6 @@ public static void Foo () {
[Category ("LLVM")]
public void NoSymbolsArgShouldReduceAppSize ([Values ("", "Hybrid")] string androidAotMode)
{
if (Builder.UseDotNet) {
Assert.Ignore ("https://github.com/dotnet/runtime/issues/57800");
}

AssertAotModeSupported (androidAotMode);

var proj = new XamarinAndroidApplicationProject () {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;

namespace Xamarin.ProjectTools
{
public static class AbiUtils
{
public static string AbiToRuntimeIdentifier (string androidAbi)
{
if (androidAbi == "armeabi-v7a") {
return "android-arm";
} else if (androidAbi == "arm64-v8a") {
return "android-arm64";
} else if (androidAbi == "x86") {
return "android-x86";
} else if (androidAbi == "x86_64") {
return "android-x64";
}
throw new InvalidOperationException ($"Unknown abi: {androidAbi}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,14 @@ public static void SetAndroidSupportedAbis (this IShortFormProject project, stri

public static void SetRuntimeIdentifier (this IShortFormProject project, string androidAbi)
{
if (androidAbi == "armeabi-v7a") {
project.SetProperty (KnownProperties.RuntimeIdentifier, "android-arm");
} else if (androidAbi == "arm64-v8a") {
project.SetProperty (KnownProperties.RuntimeIdentifier, "android-arm64");
} else if (androidAbi == "x86") {
project.SetProperty (KnownProperties.RuntimeIdentifier, "android-x86");
} else if (androidAbi == "x86_64") {
project.SetProperty (KnownProperties.RuntimeIdentifier, "android-x64");
}
project.SetProperty (KnownProperties.RuntimeIdentifier, AbiUtils.AbiToRuntimeIdentifier (androidAbi));
}

public static void SetRuntimeIdentifiers (this IShortFormProject project, string [] androidAbis)
{
var abis = new List<string> ();
foreach (var androidAbi in androidAbis) {
if (androidAbi == "armeabi-v7a") {
abis.Add ("android-arm");
} else if (androidAbi == "arm64-v8a") {
abis.Add ("android-arm64");
} else if (androidAbi == "x86") {
abis.Add ("android-x86");
} else if (androidAbi == "x86_64") {
abis.Add ("android-x64");
}
abis.Add (AbiUtils.AbiToRuntimeIdentifier (androidAbi));
}
project.SetProperty (KnownProperties.RuntimeIdentifiers, string.Join (";", abis));
}
Expand Down