diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml
index 446d491e4ed..9d70bed1ac8 100644
--- a/build-tools/automation/azure-pipelines.yaml
+++ b/build-tools/automation/azure-pipelines.yaml
@@ -103,12 +103,31 @@ extends:
macTestAgentsUseCleanImages: ${{ parameters.macTestAgentsUseCleanImages }}
- template: /build-tools/automation/yaml-templates/stage-linux-tests.yaml@self
+ parameters:
+ runtimeName: "MonoVM"
+
+ - template: /build-tools/automation/yaml-templates/stage-msbuild-tests.yaml@self
+ parameters:
+ runtimeName: "MonoVM"
+
+ - template: /build-tools/automation/yaml-templates/stage-msbuild-emulator-tests.yaml@self
+ parameters:
+ usesCleanImages: ${{ parameters.macTestAgentsUseCleanImages }}
+ runtimeName: "MonoVM"
+
+ - template: /build-tools/automation/yaml-templates/stage-linux-tests.yaml@self
+ parameters:
+ runtimeName: "CoreCLR"
- template: /build-tools/automation/yaml-templates/stage-msbuild-tests.yaml@self
+ parameters:
+ runtimeName: "CoreCLR"
+ testFilter: $(CoreCLRExcludedNunitCategories)
- template: /build-tools/automation/yaml-templates/stage-msbuild-emulator-tests.yaml@self
parameters:
usesCleanImages: ${{ parameters.macTestAgentsUseCleanImages }}
+ runtimeName: "CoreCLR"
- stage: maui_tests
displayName: MAUI Tests
diff --git a/build-tools/automation/yaml-templates/run-msbuild-tests.yaml b/build-tools/automation/yaml-templates/run-msbuild-tests.yaml
index 7853353e798..760a8377080 100644
--- a/build-tools/automation/yaml-templates/run-msbuild-tests.yaml
+++ b/build-tools/automation/yaml-templates/run-msbuild-tests.yaml
@@ -1,5 +1,6 @@
parameters:
testOS: '' # 'macOS' or 'Windows'
+ runtimeName: '' # MonoVM or CoreCLR
jobName: '' # Name of the job
jobDisplayName: '' # Display name of the job
agentCount: 1 # Number of build agents to run in parallel
@@ -42,6 +43,10 @@ jobs:
repositoryAlias: ${{ parameters.repositoryAlias }}
commit: ${{ parameters.commit }}
+ - template: /build-tools/automation/yaml-templates/select-test-runtime.yaml
+ parameters:
+ runtimeName: ${{ parameters.runtimeName }}
+
- task: DownloadPipelineArtifact@2
inputs:
artifactName: $(TestAssembliesArtifactName)
@@ -51,13 +56,13 @@ jobs:
parameters:
testAssembly: ${{ parameters.xaSourcePath }}/bin/Test$(XA.Build.Configuration)/$(DotNetStableTargetFramework)/Xamarin.Android.Build.Tests.dll
testFilter: ${{ parameters.testFilter }}
- testRunTitle: Xamarin.Android.Build.Tests - ${{ parameters.testOS }}
+ testRunTitle: Xamarin.Android.Build.Tests - ${{ parameters.testOS }} (${{ parameters.runtimeName }})
retryFailedTests: false
xaSourcePath: ${{ parameters.xaSourcePath }}
- template: /build-tools/automation/yaml-templates/upload-results.yaml
parameters:
- artifactName: Test Results - MSBuild - ${{ parameters.testOS }}-$(System.JobPositionInPhase)
+ artifactName: Test Results - MSBuild - ${{ parameters.testOS }}-${{ parameters.runtimeName }}-$(System.JobPositionInPhase)
xaSourcePath: ${{ parameters.xaSourcePath }}
use1ESTemplate: ${{ parameters.use1ESTemplate }}
diff --git a/build-tools/automation/yaml-templates/select-test-runtime.yaml b/build-tools/automation/yaml-templates/select-test-runtime.yaml
new file mode 100644
index 00000000000..c9ea2d78880
--- /dev/null
+++ b/build-tools/automation/yaml-templates/select-test-runtime.yaml
@@ -0,0 +1,14 @@
+parameters:
+ runtimeName: ''
+
+steps:
+- pwsh: |
+ Write-Host "Selecting target runtime: "${{ parameters.runtimeName }}""
+ if ("${{ parameters.runtimeName }}" -eq "CoreCLR") {
+ $useMonoRuntime="false"
+ } else {
+ $useMonoRuntime="true"
+ }
+
+ Write-Host "##vso[task.setvariable variable=USE_MONO_RUNTIME]$useMonoRuntime"
+ displayName: select target runtime (MonoVM or CoreCLR)
diff --git a/build-tools/automation/yaml-templates/stage-linux-tests.yaml b/build-tools/automation/yaml-templates/stage-linux-tests.yaml
index 92173aa7f37..643d0888089 100644
--- a/build-tools/automation/yaml-templates/stage-linux-tests.yaml
+++ b/build-tools/automation/yaml-templates/stage-linux-tests.yaml
@@ -1,15 +1,17 @@
# Runs smoke tests on Linux packages.
+parameters:
+ runtimeName: ''
stages:
-- stage: linux_tests
- displayName: Linux Tests
+- stage: linux_tests_${{ parameters.runtimeName }}
+ displayName: Linux Tests (${{ parameters.runtimeName }})
dependsOn:
- mac_build
- linux_build
jobs:
# Check - "Xamarin.Android (Linux Tests Linux > Tests > MSBuild)"
- job: linux_tests_smoke_1
- displayName: Linux > Tests > MSBuild 1
+ displayName: Linux > Tests > MSBuild 1 (${{ parameters.runtimeName }})
pool:
name: MAUI-1ESPT
image: $(LinuxPoolImage1ESPT)
@@ -20,6 +22,10 @@ stages:
steps:
- template: /build-tools/automation/yaml-templates/setup-test-environment.yaml
+ - template: /build-tools/automation/yaml-templates/select-test-runtime.yaml
+ parameters:
+ runtimeName: ${{ parameters.runtimeName }}
+
- task: DownloadPipelineArtifact@2
inputs:
artifactName: $(TestAssembliesArtifactName)
@@ -27,19 +33,19 @@ stages:
- template: /build-tools/automation/yaml-templates/run-nunit-tests.yaml
parameters:
- testRunTitle: Xamarin.Android.Build.Tests - Linux BuildTest
+ testRunTitle: Xamarin.Android.Build.Tests - Linux BuildTest (${{ parameters.runtimeName }})
testAssembly: $(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/$(DotNetStableTargetFramework)/Xamarin.Android.Build.Tests.dll
dotNetTestExtraArgs: --filter "Name = BuildTest"
- template: /build-tools/automation/yaml-templates/upload-results.yaml
parameters:
configuration: $(XA.Build.Configuration)
- artifactName: Test Results - MSBuild - Linux 1
+ artifactName: Test Results - MSBuild - Linux 1 - ${{ parameters.runtimeName }}
- template: /build-tools/automation/yaml-templates/fail-on-issue.yaml
- job: linux_tests_smoke_2
- displayName: Linux > Tests > MSBuild 2
+ displayName: Linux > Tests > MSBuild 2 (${{ parameters.runtimeName }})
pool:
name: MAUI-1ESPT
image: $(LinuxPoolImage1ESPT)
@@ -50,6 +56,10 @@ stages:
steps:
- template: /build-tools/automation/yaml-templates/setup-test-environment.yaml
+ - template: /build-tools/automation/yaml-templates/select-test-runtime.yaml
+ parameters:
+ runtimeName: ${{ parameters.runtimeName }}
+
- task: DownloadPipelineArtifact@2
inputs:
artifactName: $(TestAssembliesArtifactName)
@@ -57,19 +67,19 @@ stages:
- template: /build-tools/automation/yaml-templates/run-nunit-tests.yaml
parameters:
- testRunTitle: Xamarin.Android.Build.Tests - Linux PackagingTest
+ testRunTitle: Xamarin.Android.Build.Tests - Linux PackagingTest (${{ parameters.runtimeName }})
testAssembly: $(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/$(DotNetStableTargetFramework)/Xamarin.Android.Build.Tests.dll
dotNetTestExtraArgs: --filter "Name = PackagingTest"
- template: /build-tools/automation/yaml-templates/run-nunit-tests.yaml
parameters:
- testRunTitle: Xamarin.Android.Build.Tests - Linux XASdkTests
+ testRunTitle: Xamarin.Android.Build.Tests - Linux XASdkTests (${{ parameters.runtimeName }})
testAssembly: $(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/$(DotNetStableTargetFramework)/Xamarin.Android.Build.Tests.dll
dotNetTestExtraArgs: --filter "Name = XASdkTests & Name != XamarinLegacySdk"
- template: /build-tools/automation/yaml-templates/run-nunit-tests.yaml
parameters:
- testRunTitle: Xamarin.Android.Build.Tests - Linux AndroidDependenciesTests
+ testRunTitle: Xamarin.Android.Build.Tests - Linux AndroidDependenciesTests (${{ parameters.runtimeName }})
testAssembly: $(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/$(DotNetStableTargetFramework)/Xamarin.Android.Build.Tests.dll
dotNetTestExtraArgs: --filter "Name = AndroidDependenciesTests"
@@ -82,6 +92,6 @@ stages:
- template: /build-tools/automation/yaml-templates/upload-results.yaml
parameters:
configuration: $(XA.Build.Configuration)
- artifactName: Test Results - MSBuild - Linux 2
+ artifactName: Test Results - MSBuild - Linux 2 - ${{ parameters.runtimeName }}
- template: /build-tools/automation/yaml-templates/fail-on-issue.yaml
diff --git a/build-tools/automation/yaml-templates/stage-msbuild-emulator-tests.yaml b/build-tools/automation/yaml-templates/stage-msbuild-emulator-tests.yaml
index 957e3f239fb..9fe0cd93a13 100644
--- a/build-tools/automation/yaml-templates/stage-msbuild-emulator-tests.yaml
+++ b/build-tools/automation/yaml-templates/stage-msbuild-emulator-tests.yaml
@@ -1,6 +1,7 @@
# Runs MSBuild tests against a device running on macOS
parameters:
+ runtimeName: ''
stageName: msbuilddevice_tests
job_name: 'mac_dotnetdevice_tests'
dependsOn: mac_build
@@ -16,8 +17,8 @@ parameters:
use1ESTemplate: true
stages:
-- stage: ${{ parameters.stageName }}
- displayName: ${{ parameters.stagePrefix }}MSBuild Emulator Tests
+- stage: ${{ parameters.stageName }}_${{ parameters.runtimeName }}
+ displayName: ${{ parameters.stagePrefix }}MSBuild Emulator Tests (${{ parameters.runtimeName }})
dependsOn: ${{ parameters.dependsOn }}
condition: ${{ parameters.stageCondition }}
jobs:
@@ -44,6 +45,10 @@ stages:
commit: ${{ parameters.commit }}
xaprepareScenario: EmulatorTestDependencies
+ - template: /build-tools/automation/yaml-templates/select-test-runtime.yaml
+ parameters:
+ runtimeName: ${{ parameters.runtimeName }}
+
- task: DownloadPipelineArtifact@2
inputs:
artifactName: $(TestAssembliesArtifactName)
@@ -85,7 +90,7 @@ stages:
condition: ${{ parameters.shouldFailOnIssue }}
- job: wear_tests
- displayName: macOS > Tests > WearOS
+ displayName: macOS > Tests > WearOS (${{ parameters.runtimeName }})
timeoutInMinutes: 180
cancelTimeoutInMinutes: 2
strategy:
@@ -111,6 +116,10 @@ stages:
commit: ${{ parameters.commit }}
xaprepareScenario: EmulatorTestDependencies
+ - template: /build-tools/automation/yaml-templates/select-test-runtime.yaml
+ parameters:
+ runtimeName: ${{ parameters.runtimeName }}
+
- task: DownloadPipelineArtifact@2
inputs:
artifactName: $(TestAssembliesArtifactName)
diff --git a/build-tools/automation/yaml-templates/stage-msbuild-tests.yaml b/build-tools/automation/yaml-templates/stage-msbuild-tests.yaml
index 54fb9005e16..1d71487400e 100644
--- a/build-tools/automation/yaml-templates/stage-msbuild-tests.yaml
+++ b/build-tools/automation/yaml-templates/stage-msbuild-tests.yaml
@@ -1,6 +1,8 @@
# Runs MSBuild tests that do not require devices on Mac/Windows
parameters:
+ runtimeName: ''
+ testFilter: '' # Filter used to select tests (NUnit test selection language, not dotnet test filter language)
stageName: msbuild_dotnet
stageCondition: succeeded()
dependsOn: mac_build
@@ -12,14 +14,16 @@ parameters:
use1ESTemplate: true
stages:
-- stage: ${{ parameters.stageName }}
- displayName: ${{ parameters.stagePrefix }}MSBuild Tests
+- stage: ${{ parameters.stageName }}_${{ parameters.runtimeName }}
+ displayName: ${{ parameters.stagePrefix }}MSBuild Tests (${{ parameters.runtimeName }})
dependsOn: ${{ parameters.dependsOn }}
condition: ${{ parameters.stageCondition }}
jobs:
- template: /build-tools/automation/yaml-templates/run-msbuild-tests.yaml
parameters:
testOS: macOS
+ runtimeName: ${{ parameters.runtimeName }}
+ testFilter: ${{ parameters.testFilter }}
jobName: mac_msbuild_tests
jobDisplayName: macOS > Tests > MSBuild
agentCount: 10
@@ -32,6 +36,8 @@ stages:
- template: /build-tools/automation/yaml-templates/run-msbuild-tests.yaml
parameters:
testOS: Windows
+ runtimeName: ${{ parameters.runtimeName }}
+ testFilter: ${{ parameters.testFilter }}
jobName: win_msbuild_tests
jobDisplayName: Windows > Tests > MSBuild
agentCount: 8
diff --git a/build-tools/automation/yaml-templates/variables.yaml b/build-tools/automation/yaml-templates/variables.yaml
index f01382d246f..33f35c6621a 100644
--- a/build-tools/automation/yaml-templates/variables.yaml
+++ b/build-tools/automation/yaml-templates/variables.yaml
@@ -68,3 +68,5 @@ variables:
value: 'cat != SystemApplication & cat != TimeZoneInfo & cat != Localization'
- name: RunMAUITestJob
value: true
+- name: CoreCLRExcludedNunitCategories
+ value: 'cat != AOT'
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets
index a24f56ccf53..1876ebe9c9c 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets
@@ -33,6 +33,13 @@
<_IsPublishing Condition=" '$(_IsPublishing)' == '' and '$(_AndroidRuntime)' == 'NativeAOT' ">true
+
+ false
+
$(AndroidMinimumSupportedApiLevel)
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.NET.Sdk.Android/WorkloadManifest.in.json b/src/Xamarin.Android.Build.Tasks/Microsoft.NET.Sdk.Android/WorkloadManifest.in.json
index 5f9e689ad17..75571790f71 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.NET.Sdk.Android/WorkloadManifest.in.json
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.NET.Sdk.Android/WorkloadManifest.in.json
@@ -6,11 +6,13 @@
"packs": [
"Microsoft.Android.Sdk.net10",
"Microsoft.Android.Sdk.net9",
- "Microsoft.Android.Ref.36",
- "Microsoft.Android.Runtime.Mono.36.android-arm",
- "Microsoft.Android.Runtime.Mono.36.android-arm64",
- "Microsoft.Android.Runtime.Mono.36.android-x86",
- "Microsoft.Android.Runtime.Mono.36.android-x64",
+ "Microsoft.Android.Ref.35",
+ "Microsoft.Android.Runtime.Mono.35.android-arm",
+ "Microsoft.Android.Runtime.Mono.35.android-arm64",
+ "Microsoft.Android.Runtime.Mono.35.android-x86",
+ "Microsoft.Android.Runtime.Mono.35.android-x64",
+ "Microsoft.Android.Runtime.CoreCLR.35.android-arm64",
+ "Microsoft.Android.Runtime.CoreCLR.35.android-x64",
"Microsoft.Android.Templates"
],
"platforms": [ "win-x64", "win-arm64", "linux-x64", "linux-arm64", "osx-x64", "osx-arm64" ],
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
index acf0300f113..004e4e19535 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
@@ -28,6 +28,10 @@ public partial class BuildTest : BaseTest
[NonParallelizable] // On MacOS, parallel /restore causes issues
public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot, bool usesAssemblyStore)
{
+ if (TargetRuntimeHelper.UseCoreCLR && !TargetRuntimeHelper.CoreClrSupportsAllRIDs (runtimeIdentifiers)) {
+ Assert.Ignore ($"One or more RIDs aren't supported by CoreCLR: '{runtimeIdentifiers}'");
+ }
+
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
EnableDefaultItems = true,
@@ -170,7 +174,13 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot, bo
helper.AssertContainsEntry ($"assemblies/de-DE/{proj.ProjectName}.resources.dll", shouldContainEntry: expectEmbeddedAssembies);
foreach (var abi in rids.Select (AndroidRidAbiHelper.RuntimeIdentifierToAbi)) {
helper.AssertContainsEntry ($"lib/{abi}/libmonodroid.so");
- helper.AssertContainsEntry ($"lib/{abi}/libmonosgen-2.0.so");
+
+ if (TargetRuntimeHelper.UseCoreCLR) {
+ helper.AssertContainsEntry ($"lib/{abi}/libcoreclr.so");
+ } else {
+ helper.AssertContainsEntry ($"lib/{abi}/libmonosgen-2.0.so");
+ }
+
if (rids.Length > 1) {
helper.AssertContainsEntry ($"assemblies/{abi}/System.Private.CoreLib.dll", shouldContainEntry: expectEmbeddedAssembies);
} else {
@@ -225,6 +235,10 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot, bo
[TestCaseSource (nameof (MonoComponentMaskChecks))]
public void CheckMonoComponentsMask (bool enableProfiler, bool useInterpreter, bool debugBuild, uint expectedMask)
{
+ if (TargetRuntimeHelper.UseCoreCLR) {
+ Assert.Ignore ("CoreCLR does not support MonoVM components");
+ }
+
var proj = new XamarinFormsAndroidApplicationProject () {
IsRelease = !debugBuild,
};
@@ -265,15 +279,20 @@ public void CheckMonoComponentsMask (bool enableProfiler, bool useInterpreter, b
[Test]
[TestCaseSource (nameof (CheckAssemblyCountsSource))]
[NonParallelizable]
+ [Category ("CoreCLR")]
public void CheckAssemblyCounts (bool isRelease, bool aot)
{
+ if (aot && TargetRuntimeHelper.UseCoreCLR) {
+ Assert.Ignore ("CoreCLR doesn't support MonoVM-style AOT");
+ }
+
var proj = new XamarinFormsAndroidApplicationProject {
IsRelease = isRelease,
EmbedAssembliesIntoApk = true,
AotAssemblies = aot,
};
- var abis = new [] { "armeabi-v7a", "x86" };
+ var abis = new [] { "arm64-v8a", "x86_64" };
proj.SetRuntimeIdentifiers (abis);
proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidUseAssemblyStore", "True");
@@ -282,8 +301,17 @@ public void CheckAssemblyCounts (bool isRelease, bool aot)
string objPath = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
List envFiles = EnvironmentHelper.GatherEnvironmentFiles (objPath, String.Join (";", abis), true);
- EnvironmentHelper.ApplicationConfig app_config = EnvironmentHelper.ReadApplicationConfig (envFiles);
- Assert.That (app_config, Is.Not.Null, "application_config must be present in the environment files");
+ uint number_of_assemblies_in_apk;
+
+ if (TargetRuntimeHelper.UseMonoRuntime) {
+ EnvironmentHelper.ApplicationConfig app_config = EnvironmentHelper.ReadApplicationConfig (envFiles);
+ Assert.That (app_config, Is.Not.Null, "(MonoVM) application_config must be present in the environment files");
+ number_of_assemblies_in_apk = app_config.number_of_assemblies_in_apk;
+ } else {
+ EnvironmentHelper.ApplicationConfigCLR app_config = EnvironmentHelper.ReadApplicationConfigCLR (envFiles);
+ Assert.That (app_config, Is.Not.Null, "(CoreCLR) application_config must be present in the environment files");
+ number_of_assemblies_in_apk = app_config.number_of_assemblies_in_apk;
+ }
if (aot) {
foreach (var env in envFiles) {
@@ -297,7 +325,7 @@ public void CheckAssemblyCounts (bool isRelease, bool aot)
foreach (string abi in abis) {
AndroidTargetArch arch = MonoAndroidHelper.AbiToTargetArch (abi);
Assert.AreEqual (
- app_config.number_of_assemblies_in_apk,
+ number_of_assemblies_in_apk,
helper.GetNumberOfAssemblies (arch: arch),
$"Assembly count must be equal between ApplicationConfig and the archive contents for architecture {arch} (ABI: {abi})"
);
@@ -335,6 +363,11 @@ public static string GetLinkedPath (ProjectBuilder builder, bool isRelease, stri
[Test]
[TestCaseSource (nameof (RuntimeChecks))]
public void CheckWhichRuntimeIsIncluded (string supportedAbi, bool debugSymbols, bool? optimize, bool? embedAssemblies, string expectedRuntime) {
+
+ if (TargetRuntimeHelper.UseCoreCLR && !TargetRuntimeHelper.CoreClrSupportsAllABIs (supportedAbi)) {
+ Assert.Ignore ($"ABI '{supportedAbi}' not supported on CoreCLR");
+ }
+
var proj = new XamarinAndroidApplicationProject ();
proj.SetAndroidSupportedAbis (supportedAbi);
proj.SetProperty (proj.ActiveConfigurationProperties, "DebugSymbols", debugSymbols);
@@ -1269,7 +1302,7 @@ public void PackageNamingPolicy ([Values ("LowercaseMD5", "LowercaseCrc64")] str
var proj = new XamarinAndroidApplicationProject ();
proj.SetProperty ("UseInterpreter", "true");
proj.SetProperty ("AndroidPackageNamingPolicy", packageNamingPolicy);
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ proj.SetAndroidSupportedAbis ("arm64-v8a", "x86_64");
using (var b = CreateApkBuilder ()) {
Assert.IsTrue (b.Build (proj), "build should have succeeded.");
var environment = b.Output.GetIntermediaryPath (Path.Combine ("__environment__.txt"));
@@ -1379,7 +1412,7 @@ public void NUnitLiteNugetWorks ()
/* enableProguard */ null,
/* androidEnableProguard */ "true",
/* expectedBuildResult */ true,
- /* expectedWarning */ "0 Warning(s)",
+ /* expectedWarning */ TargetRuntimeHelper.UseCoreCLR && TargetRuntimeHelper.CoreClrIsExperimental ? "1 Warning(s)" : "0 Warning(s)",
},
new object [] {
/* linkTool */ "proguard",
@@ -1393,7 +1426,7 @@ public void NUnitLiteNugetWorks ()
/* enableProguard */ null,
/* androidEnableProguard */ null,
/* expectedBuildResult */ true,
- /* expectedWarning */ "0 Warning(s)",
+ /* expectedWarning */ TargetRuntimeHelper.UseCoreCLR && TargetRuntimeHelper.CoreClrIsExperimental ? "1 Warning(s)" : "0 Warning(s)",
},
new object [] {
/* linkTool */ null,
@@ -1674,7 +1707,7 @@ public void SimilarAndroidXAssemblyNames ([Values(true, false)] bool publishTrim
{
var proj = new XamarinAndroidApplicationProject {
IsRelease = true,
- AotAssemblies = publishTrimmed,
+ AotAssemblies = publishTrimmed && !TargetRuntimeHelper.UseCoreCLR,
PackageReferences = {
new Package { Id = "Xamarin.AndroidX.CustomView", Version = "1.1.0.17" },
new Package { Id = "Xamarin.AndroidX.CustomView.PoolingContainer", Version = "1.0.0.4" },
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs
index c9e0ac98f36..c77ff536a7b 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs
@@ -42,10 +42,10 @@ public partial class BuildTest2 : BaseTest
[TestCaseSource (nameof (MarshalMethodsDefaultStatusSource))]
public void MarshalMethodsDefaultEnabledStatus (bool isRelease, bool marshalMethodsEnabled)
{
- var abis = new [] { "armeabi-v7a", "x86" };
+ var abis = new [] { "arm64-v8a", "x86_64" };
AndroidTargetArch[] supportedArches = new [] {
- AndroidTargetArch.Arm,
- AndroidTargetArch.X86,
+ AndroidTargetArch.Arm64,
+ AndroidTargetArch.X86_64,
};
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease
@@ -68,10 +68,20 @@ public void MarshalMethodsDefaultEnabledStatus (bool isRelease, bool marshalMeth
String.Join (";", supportedArches.Select (arch => MonoAndroidHelper.ArchToAbi (arch))),
true
);
- EnvironmentHelper.ApplicationConfig app_config = EnvironmentHelper.ReadApplicationConfig (envFiles);
- Assert.That (app_config, Is.Not.Null, "application_config must be present in the environment files");
- Assert.AreEqual (app_config.marshal_methods_enabled, shouldMarshalMethodsBeEnabled, $"Marshal methods enabled status should be '{shouldMarshalMethodsBeEnabled}', but it was '{app_config.marshal_methods_enabled}'");
+ bool marshal_methods_enabled;
+ if (TargetRuntimeHelper.UseMonoRuntime) {
+ EnvironmentHelper.ApplicationConfig app_config = EnvironmentHelper.ReadApplicationConfig (envFiles);
+
+ Assert.That (app_config, Is.Not.Null, "application_config must be present in the environment files");
+ marshal_methods_enabled = app_config.marshal_methods_enabled;
+ } else {
+ EnvironmentHelper.ApplicationConfigCLR app_config = EnvironmentHelper.ReadApplicationConfigCLR (envFiles);
+
+ Assert.That (app_config, Is.Not.Null, "application_config must be present in the environment files");
+ marshal_methods_enabled = app_config.marshal_methods_enabled;
+ }
+ Assert.AreEqual (marshal_methods_enabled, shouldMarshalMethodsBeEnabled, $"Marshal methods enabled status should be '{shouldMarshalMethodsBeEnabled}', but it was '{marshal_methods_enabled}'");
}
}
@@ -109,9 +119,6 @@ public void BuildBasicApplication ([Values (true, false)] bool isRelease, [Value
[Test]
public void BasicApplicationOtherRuntime ([Values (true, false)] bool isRelease)
{
- // This test would fail, as it requires **our** updated runtime pack, which isn't currently created
- // It is created in `src/native/native-clr.csproj` which isn't built atm.
- Assert.Ignore ("CoreCLR support isn't fully enabled yet. This test will be enabled in a follow-up PR.");
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
// Add locally downloaded CoreCLR packs
@@ -430,6 +437,15 @@ public void BuildHasTrimmerWarnings (string properties, string [] codes, bool is
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
};
+ if (TargetRuntimeHelper.UseCoreCLR && TargetRuntimeHelper.CoreClrIsExperimental) {
+ // Experimental runtimes will issue warning XA1040
+ var newCodes = new List (codes);
+ newCodes.Add ("XA1040");
+ codes = newCodes.ToArray ();
+ if (totalWarnings != null) {
+ totalWarnings++;
+ }
+ }
proj.SetRuntimeIdentifier ("arm64-v8a");
proj.MainActivity = proj.DefaultMainActivity
.Replace ("//${FIELDS}", "Type type = typeof (List<>);")
@@ -579,6 +595,8 @@ static void Test ()
[NonParallelizable] // parallel NuGet restore causes failures
public void BuildBasicApplicationFSharp (bool isRelease, bool aot)
{
+ TargetRuntimeHelper.IgnoreIfIncompatibleWithMonoAOT (aot);
+
var proj = new XamarinAndroidApplicationProject {
Language = XamarinAndroidProjectLanguage.FSharp,
IsRelease = isRelease,
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildWithLibraryTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildWithLibraryTests.cs
index b911192418f..e7b3e70334a 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildWithLibraryTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildWithLibraryTests.cs
@@ -370,15 +370,15 @@ public void BuildWithNativeLibraries ([Values (true, false)] bool isRelease)
ProjectName = "Library1",
IsRelease = isRelease,
OtherBuildItems = {
- new AndroidItem.EmbeddedNativeLibrary ("foo\\armeabi-v7a\\libtest.so") {
+ new AndroidItem.EmbeddedNativeLibrary ("foo\\arm64-v8a\\libtest.so") {
BinaryContent = () => new byte[10],
- MetadataValues = "Link=libs\\armeabi-v7a\\libtest.so",
+ MetadataValues = "Link=libs\\arm64-v8a\\libtest.so",
},
- new AndroidItem.EmbeddedNativeLibrary ("foo\\x86\\libtest.so") {
+ new AndroidItem.EmbeddedNativeLibrary ("foo\\x86_64\\libtest.so") {
BinaryContent = () => new byte[10],
- MetadataValues = "Link=libs\\x86\\libtest.so",
+ MetadataValues = "Link=libs\\x86_64\\libtest.so",
},
- new AndroidItem.AndroidNativeLibrary ("armeabi-v7a\\libRSSupport.so") {
+ new AndroidItem.AndroidNativeLibrary ("arm64-v8a\\libRSSupport.so") {
BinaryContent = () => new byte[10],
},
},
@@ -390,13 +390,13 @@ public void BuildWithNativeLibraries ([Values (true, false)] bool isRelease)
new BuildItem ("ProjectReference","..\\Library1\\Library1.csproj"),
},
OtherBuildItems = {
- new AndroidItem.EmbeddedNativeLibrary ("foo\\armeabi-v7a\\libtest1.so") {
+ new AndroidItem.EmbeddedNativeLibrary ("foo\\arm64-v8a\\libtest1.so") {
BinaryContent = () => new byte[10],
- MetadataValues = "Link=libs\\armeabi-v7a\\libtest1.so",
+ MetadataValues = "Link=libs\\arm64-v8a\\libtest1.so",
},
- new AndroidItem.EmbeddedNativeLibrary ("foo\\x86\\libtest1.so") {
+ new AndroidItem.EmbeddedNativeLibrary ("foo\\x86_64\\libtest1.so") {
BinaryContent = () => new byte[10],
- MetadataValues = "Link=libs\\x86\\libtest1.so",
+ MetadataValues = "Link=libs\\x86_64\\libtest1.so",
},
},
};
@@ -407,12 +407,12 @@ public void BuildWithNativeLibraries ([Values (true, false)] bool isRelease)
new BuildItem ("ProjectReference","..\\Library2\\Library2.csproj"),
},
OtherBuildItems = {
- new AndroidItem.AndroidNativeLibrary ("armeabi-v7a\\libRSSupport.so") {
+ new AndroidItem.AndroidNativeLibrary ("arm64-v8a\\libRSSupport.so") {
BinaryContent = () => new byte[10],
},
}
};
- proj.SetRuntimeIdentifiers (["armeabi-v7a", "x86"]);
+ proj.SetRuntimeIdentifiers (["arm64-v8a", "x86_64"]);
var path = Path.Combine (Root, "temp", string.Format ("BuildWithNativeLibraries_{0}", isRelease));
using (var b1 = CreateDllBuilder (Path.Combine (path, dll2.ProjectName))) {
Assert.IsTrue (b1.Build (dll2), "Build should have succeeded.");
@@ -423,23 +423,23 @@ public void BuildWithNativeLibraries ([Values (true, false)] bool isRelease)
var apk = Path.Combine (Root, builder.ProjectDirectory,
proj.OutputPath, $"{proj.PackageName}-Signed.apk");
FileAssert.Exists (apk);
- Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, "warning XA4301: APK already contains the item lib/armeabi-v7a/libRSSupport.so; ignoring."),
+ Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, "warning XA4301: APK already contains the item lib/arm64-v8a/libRSSupport.so; ignoring."),
"warning about skipping libRSSupport.so should have been raised");
using (var zipFile = ZipHelper.OpenZip (apk)) {
- var data = ZipHelper.ReadFileFromZip (zipFile, "lib/x86/libtest.so");
- Assert.IsNotNull (data, "libtest.so for x86 should exist in the apk.");
- data = ZipHelper.ReadFileFromZip (zipFile, "lib/armeabi-v7a/libtest.so");
- Assert.IsNotNull (data, "libtest.so for armeabi-v7a should exist in the apk.");
- data = ZipHelper.ReadFileFromZip (zipFile, "lib/x86/libtest1.so");
- Assert.IsNotNull (data, "libtest1.so for x86 should exist in the apk.");
- data = ZipHelper.ReadFileFromZip (zipFile, "lib/armeabi-v7a/libtest1.so");
- Assert.IsNotNull (data, "libtest1.so for armeabi-v7a should exist in the apk.");
- data = ZipHelper.ReadFileFromZip (zipFile, "lib/armeabi-v7a/libRSSupport.so");
- Assert.IsNotNull (data, "libRSSupport.so for armeabi-v7a should exist in the apk.");
- data = ZipHelper.ReadFileFromZip (zipFile, "lib/x86/libSystem.Native.so");
- Assert.IsNotNull (data, "libSystem.Native.so for x86 should exist in the apk.");
- data = ZipHelper.ReadFileFromZip (zipFile, "lib/armeabi-v7a/libSystem.Native.so");
- Assert.IsNotNull (data, "libSystem.Native.so for armeabi-v7a should exist in the apk.");
+ var data = ZipHelper.ReadFileFromZip (zipFile, "lib/x86_64/libtest.so");
+ Assert.IsNotNull (data, "libtest.so for x86_64 should exist in the apk.");
+ data = ZipHelper.ReadFileFromZip (zipFile, "lib/arm64-v8a/libtest.so");
+ Assert.IsNotNull (data, "libtest.so for arm64-v8a should exist in the apk.");
+ data = ZipHelper.ReadFileFromZip (zipFile, "lib/x86_64/libtest1.so");
+ Assert.IsNotNull (data, "libtest1.so for x86_64 should exist in the apk.");
+ data = ZipHelper.ReadFileFromZip (zipFile, "lib/arm64-v8a/libtest1.so");
+ Assert.IsNotNull (data, "libtest1.so for arm64-v8a should exist in the apk.");
+ data = ZipHelper.ReadFileFromZip (zipFile, "lib/arm64-v8a/libRSSupport.so");
+ Assert.IsNotNull (data, "libRSSupport.so for arm64-v8a should exist in the apk.");
+ data = ZipHelper.ReadFileFromZip (zipFile, "lib/x86_64/libSystem.Native.so");
+ Assert.IsNotNull (data, "libSystem.Native.so for x86_64 should exist in the apk.");
+ data = ZipHelper.ReadFileFromZip (zipFile, "lib/arm64-v8a/libSystem.Native.so");
+ Assert.IsNotNull (data, "libSystem.Native.so for arm64-v8a should exist in the apk.");
}
}
}
@@ -456,7 +456,7 @@ public void BuildWithNativeLibraryUnknownAbi ()
},
}
};
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ proj.SetAndroidSupportedAbis ("arm64-v8a", "x86_64");
using (var builder = CreateApkBuilder (Path.Combine ("temp", TestName))) {
builder.ThrowOnBuildFailure = false;
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs
index 1d8ff21e199..eb0a127d18b 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs
@@ -17,7 +17,7 @@ public class EnvironmentContentTests : BaseTest
[NonParallelizable]
public void BuildApplicationWithMonoEnvironment ([Values ("", "Normal", "Offline")] string sequencePointsMode)
{
- const string supportedAbis = "armeabi-v7a;x86";
+ const string supportedAbis = "arm64-v8a;x86_64";
var lib = new XamarinAndroidLibraryProject {
ProjectName = "Library1",
@@ -77,7 +77,7 @@ public void BuildApplicationWithMonoEnvironment ([Values ("", "Normal", "Offline
[Test]
public void CheckMonoDebugIsAddedToEnvironment ([Values ("", "Normal", "Offline")] string sequencePointsMode)
{
- const string supportedAbis = "armeabi-v7a;x86";
+ const string supportedAbis = "arm64-v8a;x86_64";
var proj = new XamarinAndroidApplicationProject () {
IsRelease = true,
@@ -108,6 +108,10 @@ public void CheckMonoDebugIsAddedToEnvironment ([Values ("", "Normal", "Offline"
[Test]
public void CheckConcurrentGC ()
{
+ if (TargetRuntimeHelper.UseCoreCLR) {
+ Assert.Ignore ("Mono GC isn't supported on CoreCLR");
+ }
+
var proj = new XamarinAndroidApplicationProject () {
IsRelease = true,
};
@@ -160,7 +164,7 @@ public void CheckHttpClientHandlerType ()
var expectedDefaultValue = "System.Net.Http.SocketsHttpHandler, System.Net.Http";
var expectedUpdatedValue = "Xamarin.Android.Net.AndroidMessageHandler";
- var supportedAbis = "armeabi-v7a;arm64-v8a";
+ var supportedAbis = "arm64-v8a;x86_64";
proj.SetAndroidSupportedAbis (supportedAbis);
proj.PackageReferences.Add (new Package() { Id = "System.Net.Http", Version = "*" });
proj.MainActivity = proj.DefaultMainActivity.Replace ("//${AFTER_ONCREATE}", "var _ = new System.Net.Http.HttpClient ();");
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs
index bb7a266ed08..56163923301 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs
@@ -311,7 +311,7 @@ public void ResolveNativeLibrariesInManagedReferences ()
IsRelease = true,
ProjectGuid = Guid.NewGuid ().ToString (),
OtherBuildItems = {
- new BuildItem (AndroidBuildActions.EmbeddedNativeLibrary, "libs/armeabi-v7a/libfoo.so") {
+ new BuildItem (AndroidBuildActions.EmbeddedNativeLibrary, "libs/arm64-v8a/libfoo.so") {
TextContent = () => string.Empty,
Encoding = Encoding.ASCII,
}
@@ -332,14 +332,14 @@ public Class1 ()
},
},
};
- var so = lib.OtherBuildItems.First (x => x.Include () == "libs/armeabi-v7a/libfoo.so");
+ var so = lib.OtherBuildItems.First (x => x.Include () == "libs/arm64-v8a/libfoo.so");
var lib2 = new XamarinAndroidLibraryProject () {
ProjectName = "Lib2",
ProjectGuid = Guid.NewGuid ().ToString (),
IsRelease = true,
OtherBuildItems = {
- new BuildItem (AndroidBuildActions.EmbeddedNativeLibrary, "libs/armeabi-v7a/libfoo2.so") {
+ new BuildItem (AndroidBuildActions.EmbeddedNativeLibrary, "libs/arm64-v8a/libfoo2.so") {
TextContent = () => string.Empty,
Encoding = Encoding.ASCII,
},
@@ -378,12 +378,12 @@ public Class2 ()
new BuildItem.ProjectReference (@"..\Lib2\Lib2.csproj", "Lib2", lib2.ProjectGuid),
}
};
- app.SetAndroidSupportedAbis ("armeabi-v7a");
+ app.SetAndroidSupportedAbis ("arm64-v8a");
using (var builder = CreateApkBuilder (Path.Combine (path, "App"))) {
Assert.IsTrue (builder.Build (app), "app 1st. build failed");
var libfoo = ZipHelper.ReadFileFromZip (Path.Combine (Root, builder.ProjectDirectory, app.OutputPath, app.PackageName + "-Signed.apk"),
- "lib/armeabi-v7a/libfoo.so");
+ "lib/arm64-v8a/libfoo.so");
Assert.IsNotNull (libfoo, "libfoo.so should exist in the .apk");
so.TextContent = () => "newValue";
@@ -395,10 +395,10 @@ public Class2 ()
Assert.IsNotNull (libfoo, "libfoo.so should exist in the .apk");
libfoo = ZipHelper.ReadFileFromZip (Path.Combine (Root, builder.ProjectDirectory, app.OutputPath, app.PackageName + "-Signed.apk"),
- "lib/armeabi-v7a/libfoo.so");
+ "lib/arm64-v8a/libfoo.so");
Assert.AreEqual (so.TextContent ().Length, libfoo.Length, "compressed size mismatch");
var libfoo2 = ZipHelper.ReadFileFromZip (Path.Combine (Root, builder.ProjectDirectory, app.OutputPath, app.PackageName + "-Signed.apk"),
- "lib/armeabi-v7a/libfoo2.so");
+ "lib/arm64-v8a/libfoo2.so");
Assert.IsNotNull (libfoo2, "libfoo2.so should exist in the .apk");
Directory.Delete (path, recursive: true);
}
@@ -983,6 +983,7 @@ public void CasingOnJavaLangObject ()
}
[Test]
+ [Category ("CoreCLR")]
public void GenerateJavaStubsAndAssembly ([Values (true, false)] bool isRelease)
{
var targets = new [] {
@@ -992,7 +993,7 @@ public void GenerateJavaStubsAndAssembly ([Values (true, false)] bool isRelease)
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
};
- proj.SetAndroidSupportedAbis ("armeabi-v7a");
+ proj.SetAndroidSupportedAbis ("arm64-v8a");
proj.OtherBuildItems.Add (new AndroidItem.AndroidEnvironment ("Foo.txt") {
TextContent = () => "Foo=Bar",
});
@@ -1024,11 +1025,11 @@ public void GenerateJavaStubsAndAssembly ([Values (true, false)] bool isRelease)
}
readonly string [] ExpectedAssemblyFiles = new [] {
- Path.Combine ("android", "environment.armeabi-v7a.o"),
- Path.Combine ("android", "environment.armeabi-v7a.ll"),
- Path.Combine ("android", "typemaps.armeabi-v7a.o"),
- Path.Combine ("android", "typemaps.armeabi-v7a.ll"),
- Path.Combine ("app_shared_libraries", "armeabi-v7a", "libxamarin-app.so")
+ Path.Combine ("android", "environment.arm64-v8a.o"),
+ Path.Combine ("android", "environment.arm64-v8a.ll"),
+ Path.Combine ("android", "typemaps.arm64-v8a.o"),
+ Path.Combine ("android", "typemaps.arm64-v8a.ll"),
+ Path.Combine ("app_shared_libraries", "arm64-v8a", "libxamarin-app.so")
};
void AssertAssemblyFilesInFileWrites (XamarinAndroidApplicationProject proj, ProjectBuilder b)
@@ -1306,10 +1307,15 @@ public void MissingProjectReference ()
libBuilder.ThrowOnBuildFailure =
appBuilder.ThrowOnBuildFailure = false;
+ int expectedWarnings = 1;
+ if (TargetRuntimeHelper.UseCoreCLR && TargetRuntimeHelper.CoreClrIsExperimental) {
+ expectedWarnings++; // Warning XA1040 will be issued
+ }
+
// Build app before library is built
Assert.IsFalse (appBuilder.Build (app), "app build should have failed.");
Assert.IsTrue (StringAssertEx.ContainsText (appBuilder.LastBuildOutput, "warning MSB9008"), "Should receive MSB9008");
- Assert.IsTrue (StringAssertEx.ContainsText (appBuilder.LastBuildOutput, " 1 Warning(s)"), "Should receive 1 Warning");
+ Assert.IsTrue (StringAssertEx.ContainsText (appBuilder.LastBuildOutput, $" {expectedWarnings} Warning(s)"), $"Should receive {expectedWarnings} Warning(s)");
Assert.IsTrue (StringAssertEx.ContainsText (appBuilder.LastBuildOutput, "error CS0246"), "Should receive CS0246");
Assert.IsTrue (StringAssertEx.ContainsText (appBuilder.LastBuildOutput, " 1 Error(s)"), "Should receive 1 Error");
@@ -1434,10 +1440,10 @@ public void AndroidAssetMissing ()
public void ChangeSupportedAbis ()
{
var proj = new XamarinFormsAndroidApplicationProject ();
- proj.SetAndroidSupportedAbis ("armeabi-v7a");
+ proj.SetAndroidSupportedAbis ("arm64-v8a");
using (var b = CreateApkBuilder ()) {
b.Build (proj);
- b.Build (proj, parameters: new [] { $"{KnownProperties.RuntimeIdentifier}=android-x86" }, doNotCleanupOnUpdate: true);
+ b.Build (proj, parameters: new [] { $"{KnownProperties.RuntimeIdentifier}=android-x64" }, doNotCleanupOnUpdate: true);
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs
index da64e5e428e..ac0c3a42930 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs
@@ -45,6 +45,8 @@ public class InvalidConfigTests : BaseTest
[TestCaseSource (nameof (SettingCombinationsSource))]
public void SettingCombinations (bool isRelease, bool useInterpreter, bool publishTrimmed, bool aot, bool expected)
{
+ TargetRuntimeHelper.IgnoreIfIncompatibleWithMonoAOT (aot);
+
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
EnableDefaultItems = true,
@@ -103,6 +105,10 @@ public void XA0119AAB ()
[Test]
public void XA0119Interpreter ()
{
+ if (TargetRuntimeHelper.UseCoreCLR) {
+ Assert.Ignore ("Not supported by CoreCLR");
+ }
+
var proj = new XamarinAndroidApplicationProject {
IsRelease = true,
AotAssemblies = true,
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs
index 2164f147f8f..94960029493 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs
@@ -475,6 +475,10 @@ public void DirectBootAwareAttribute ()
[TestCaseSource(nameof (VersionCodeTestSource))]
public void VersionCodeTests (bool seperateApk, string abis, string versionCode, bool useLegacy, string versionCodePattern, string versionCodeProperties, bool shouldBuild, string expectedVersionCode)
{
+ if (TargetRuntimeHelper.UseCoreCLR && !TargetRuntimeHelper.CoreClrSupportsAllABIs (abis)) {
+ Assert.Ignore ($"One or more ABIs aren't supported by CoreCLR: '{abis}'");
+ }
+
var proj = new XamarinAndroidApplicationProject () {
IsRelease = true,
MinSdkVersion = "21",
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs
index e2bee620c1e..02b0334e53a 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs
@@ -85,12 +85,16 @@ public void CheckDebugModeWithTrimming ()
[NonParallelizable] // Commonly fails NuGet restore
public void CheckIncludedAssemblies ([Values (false, true)] bool usesAssemblyStores)
{
+ if (!usesAssemblyStores && TargetRuntimeHelper.UseCoreCLR) {
+ Assert.Ignore ("CoreCLR supports only assembly stores");
+ }
+
var proj = new XamarinAndroidApplicationProject {
IsRelease = true
};
AndroidTargetArch[] supportedArches = new[] {
- AndroidTargetArch.Arm,
+ AndroidTargetArch.Arm64,
};
proj.SetProperty ("AndroidUseAssemblyStore", usesAssemblyStores.ToString ());
@@ -129,9 +133,12 @@ public void CheckIncludedAssemblies ([Values (false, true)] bool usesAssemblySto
"System.Collections.dll",
"System.Collections.Concurrent.dll",
"System.Text.RegularExpressions.dll",
- "libarc.bin.so",
};
+ if (!TargetRuntimeHelper.UseCoreCLR) {
+ expectedFiles.Add ("libarc.bin.so");
+ }
+
using (var b = CreateApkBuilder ()) {
Assert.IsTrue (b.Build (proj), "build should have succeeded.");
var apk = Path.Combine (Root, b.ProjectDirectory,
@@ -173,7 +180,7 @@ public void CheckIncludedNativeLibraries ([Values (true, false)] bool compressNa
IsRelease = true,
};
proj.PackageReferences.Add(KnownPackages.SQLitePCLRaw_Core);
- proj.SetAndroidSupportedAbis ("x86");
+ proj.SetAndroidSupportedAbis ("x86_64");
proj.SetProperty (proj.ReleaseProperties, "AndroidStoreUncompressedFileExtensions", compressNativeLibraries ? "" : "so");
using (var b = CreateApkBuilder ()) {
b.ThrowOnBuildFailure = false;
@@ -183,9 +190,9 @@ public void CheckIncludedNativeLibraries ([Values (true, false)] bool compressNa
CompressionMethod method = compressNativeLibraries ? CompressionMethod.Deflate : CompressionMethod.Store;
using (var zip = ZipHelper.OpenZip (apk)) {
var libFiles = zip.Where (x => x.FullName.StartsWith("lib/", StringComparison.Ordinal) && !x.FullName.Equals("lib/", StringComparison.InvariantCultureIgnoreCase));
- var abiPaths = new string[] { "lib/x86/" };
+ var abiPaths = new string[] { "lib/x86_64/" };
foreach (var file in libFiles) {
- Assert.IsTrue (abiPaths.Any (x => file.FullName.Contains (x)), $"Apk contains an unnesscary lib file: {file.FullName}");
+ Assert.IsTrue (abiPaths.Any (x => file.FullName.Contains (x)), $"Apk contains an unnecessary lib file: {file.FullName}");
Assert.IsTrue (file.CompressionMethod == method, $"{file.FullName} should have been CompressionMethod.{method} in the apk, but was CompressionMethod.{file.CompressionMethod}");
}
}
@@ -392,10 +399,14 @@ public void CheckSignApk ([Values(true, false)] bool useApkSigner, [Values(true,
proj.SetProperty (proj.ReleaseProperties, "AndroidSigningKeyPass", Uri.EscapeDataString (pass));
proj.SetProperty (proj.ReleaseProperties, "AndroidSigningStorePass", Uri.EscapeDataString (pass));
proj.SetProperty (proj.ReleaseProperties, KnownProperties.AndroidCreatePackagePerAbi, perAbiApk);
- if (perAbiApk) {
+
+ bool thirtyTwoBitAbisSupported =
+ !TargetRuntimeHelper.UseCoreCLR ||
+ (TargetRuntimeHelper.CoreClrSupportsAbi ("armeabi-v7a") && TargetRuntimeHelper.CoreClrSupportsAbi ("x86"));
+ if (perAbiApk && thirtyTwoBitAbisSupported) { // CoreCLR doesn't support 32-bit ABIs
proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "arm64-v8a", "x86_64");
} else {
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ proj.SetAndroidSupportedAbis ("arm64-v8a", "x86_64");
}
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName, "App"))) {
var bin = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath);
@@ -411,13 +422,25 @@ public void CheckSignApk ([Values(true, false)] bool useApkSigner, [Values(true,
// Make sure the APKs have unique version codes
if (perAbiApk) {
- int armManifestCode = GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "armeabi-v7a", "AndroidManifest.xml"));
- int x86ManifestCode = GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "x86", "AndroidManifest.xml"));
+ int armManifestCode = thirtyTwoBitAbisSupported ? GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "armeabi-v7a", "AndroidManifest.xml")) : 0;
+ int x86ManifestCode = thirtyTwoBitAbisSupported ? GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "x86", "AndroidManifest.xml")) : 0;
int arm64ManifestCode = GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "arm64-v8a", "AndroidManifest.xml"));
int x86_64ManifestCode = GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "x86_64", "AndroidManifest.xml"));
- var versionList = new List { armManifestCode, x86ManifestCode, arm64ManifestCode, x86_64ManifestCode };
- Assert.True (versionList.Distinct ().Count () == versionList.Count,
- $"APK version codes were not unique - armeabi-v7a: {armManifestCode}, x86: {x86ManifestCode}, arm64-v8a: {arm64ManifestCode}, x86_64: {x86_64ManifestCode}");
+ List versionList;
+ if (thirtyTwoBitAbisSupported) {
+ versionList = new List { armManifestCode, x86ManifestCode, arm64ManifestCode, x86_64ManifestCode };
+ } else {
+ versionList = new List { arm64ManifestCode, x86_64ManifestCode };
+ }
+
+ string errorMessage;
+ if (thirtyTwoBitAbisSupported) {
+ errorMessage = $"APK version codes were not unique - armeabi-v7a: {armManifestCode}, x86: {x86ManifestCode}, arm64-v8a: {arm64ManifestCode}, x86_64: {x86_64ManifestCode}";
+ } else {
+ errorMessage = $"APK version codes were not unique - arm64-v8a: {arm64ManifestCode}, x86_64: {x86_64ManifestCode}";
+ }
+
+ Assert.True (versionList.Distinct ().Count () == versionList.Count, errorMessage);
}
var item = proj.AndroidResources.First (x => x.Include () == "Resources\\values\\Strings.xml");
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs
index 035fca0f5c5..20d5c24643c 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -649,7 +650,18 @@ public abstract class MyRunner {
}"
});
var proj = new XamarinAndroidApplicationProject { IsRelease = true, ProjectName = "App1" };
- proj.SetRuntimeIdentifiers(["armeabi-v7a", "arm64-v8a", "x86", "x86_64"]);
+
+ bool thirtyTwoBitAbisSupported =
+ !TargetRuntimeHelper.UseCoreCLR ||
+ (TargetRuntimeHelper.CoreClrSupportsAbi ("armeabi-v7a") && TargetRuntimeHelper.CoreClrSupportsAbi ("x86"));
+
+ var rids = new List { "arm64-v8a", "x86_64" };
+ if (thirtyTwoBitAbisSupported) {
+ rids.Add ("armeabi-v7a");
+ rids.Add ("x86");
+ }
+
+ proj.SetRuntimeIdentifiers (rids);
proj.References.Add(new BuildItem.ProjectReference (Path.Combine ("..", "Lib1", "Lib1.csproj"), "Lib1"));
proj.MainActivity = proj.DefaultMainActivity.Replace (
"base.OnCreate (bundle);",
@@ -665,11 +677,15 @@ public abstract class MyRunner {
var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
var dll = $"{lib.ProjectName}.dll";
- Assert64Bit ("android-arm", expected64: false);
+
Assert64Bit ("android-arm64", expected64: true);
- Assert64Bit ("android-x86", expected64: false);
Assert64Bit ("android-x64", expected64: true);
+ if (thirtyTwoBitAbisSupported) {
+ Assert64Bit ("android-arm", expected64: false);
+ Assert64Bit ("android-x86", expected64: false);
+ }
+
void Assert64Bit(string rid, bool expected64)
{
var assembly = AssemblyDefinition.ReadAssembly (Path.Combine (intermediate, rid, "linked", "shrunk", dll));
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/AssertionExtensions.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/AssertionExtensions.cs
index a6bc7f20c4b..357634b2fb9 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/AssertionExtensions.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/AssertionExtensions.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using NUnit.Framework;
@@ -125,16 +126,39 @@ public static void AssertEntryContents (this ZipArchive zip, string zipPath, str
}
}
+ static void AllowCoreCLRWarning (IEnumerable lastBuildOutput, string logFile)
+ {
+ // With CoreCLR being experimental, we allow a single warning (XA1040)
+ // Library builds won't have warnings, though, so we must account for that too.
+ bool hasNoWarnings = StringAssertEx.ContainsText (lastBuildOutput, " 0 Warning(s)");
+ bool hasOneWarning = StringAssertEx.ContainsText (lastBuildOutput, " 1 Warning(s)");
+
+ Assert.IsTrue (hasNoWarnings || hasOneWarning, $"{logFile} should have at most 1 MSBuild warning.");
+ if (hasOneWarning) {
+ Assert.True (StringAssertEx.ContainsText (lastBuildOutput, "XA1040"), "Should receive XA1040 warning");
+ }
+ }
+
[DebuggerHidden]
public static void AssertHasNoWarnings (this ProjectBuilder builder)
{
- Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, " 0 Warning(s)"), $"{builder.BuildLogFile} should have no MSBuild warnings.");
+ if (!TargetRuntimeHelper.UseCoreCLR || !TargetRuntimeHelper.CoreClrIsExperimental) {
+ Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, " 0 Warning(s)"), $"{builder.BuildLogFile} should have no MSBuild warnings.");
+ return;
+ }
+
+ AllowCoreCLRWarning (builder.LastBuildOutput, builder.BuildLogFile);
}
[DebuggerHidden]
public static void AssertHasNoWarnings (this DotNetCLI dotnet)
{
- Assert.IsTrue (StringAssertEx.ContainsText (dotnet.LastBuildOutput, " 0 Warning(s)"), $"{dotnet.BuildLogFile} should have no MSBuild warnings.");
+ if (!TargetRuntimeHelper.UseCoreCLR || !TargetRuntimeHelper.CoreClrIsExperimental) {
+ Assert.IsTrue (StringAssertEx.ContainsText (dotnet.LastBuildOutput, " 0 Warning(s)"), $"{dotnet.BuildLogFile} should have no MSBuild warnings.");
+ return;
+ }
+
+ AllowCoreCLRWarning (dotnet.LastBuildOutput, dotnet.BuildLogFile);
}
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs
index 1d3d5dca3fe..3534236e5b5 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs
@@ -69,6 +69,9 @@ public static string AndroidNdkPath {
}
}
+ public static bool TargetsMonoVM => TargetRuntimeHelper.UseMonoRuntime;
+ public static bool TargetsCoreCLR => !TargetRuntimeHelper.UseMonoRuntime;
+
///
/// Windows can only create a file of 255 characters: This type of path is composed of components separated by backslashes, each up to the value returned in the lpMaximumComponentLength parameter of the GetVolumeInformation function (this value is commonly 255 characters).
/// See: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.CoreCLR.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.CoreCLR.cs
new file mode 100644
index 00000000000..874785b5dc3
--- /dev/null
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.CoreCLR.cs
@@ -0,0 +1,207 @@
+using System;
+using System.Collections.Generic;
+
+using NUnit.Framework;
+namespace Xamarin.Android.Build.Tests;
+
+partial class EnvironmentHelper
+{
+ // This must be identical to the like-named structure in src/native/clr/include/xamarin-app.hh
+ public sealed class ApplicationConfigCLR
+ {
+ public bool uses_assembly_preload;
+ public bool jni_add_native_method_registration_attribute_present;
+ public bool marshal_methods_enabled;
+ public bool ignore_split_configs;
+ public uint number_of_runtime_properties;
+ public uint package_naming_policy;
+ public uint environment_variable_count;
+ public uint system_property_count;
+ public uint number_of_assemblies_in_apk;
+ public uint bundled_assembly_name_width;
+ public uint number_of_dso_cache_entries;
+ public uint number_of_aot_cache_entries;
+ public uint number_of_shared_libraries;
+ public uint android_runtime_jnienv_class_token;
+ public uint jnienv_initialize_method_token;
+ public uint jnienv_registerjninatives_method_token;
+ public uint jni_remapping_replacement_type_count;
+ public uint jni_remapping_replacement_method_index_entry_count;
+ public string android_package_name = String.Empty;
+ public bool managed_marshal_methods_lookup_enabled;
+ }
+
+ const uint ApplicationConfigFieldCountCLR = 20;
+
+ static readonly string[] requiredSharedLibrarySymbolsCLR = {
+ "app_system_properties",
+ "init_runtime_property_names",
+ "init_runtime_property_values",
+ "java_to_managed_hashes",
+ "java_to_managed_map",
+ "java_type_count",
+ "java_type_names",
+ "managed_to_java_map",
+ "managed_to_java_map_module_count",
+ AppEnvironmentVariablesSymbolName,
+ ApplicationConfigSymbolName,
+ };
+
+ // Reads all the environment files, makes sure they all have identical contents in the
+ // `application_config` structure and returns the config if the condition is true
+ public static ApplicationConfigCLR? ReadApplicationConfigCLR (List envFilePaths)
+ {
+ if (envFilePaths.Count == 0) {
+ return null;
+ }
+
+ ApplicationConfigCLR app_config = ReadApplicationConfigCLR (envFilePaths [0]);
+
+ for (int i = 1; i < envFilePaths.Count; i++) {
+ AssertApplicationConfigIsIdentical (app_config, envFilePaths [0].Path, ReadApplicationConfigCLR (envFilePaths[i]), envFilePaths[i].Path);
+ }
+
+ return app_config;
+ }
+
+ static ApplicationConfigCLR? ReadApplicationConfigCLR (EnvironmentFile envFile)
+ {
+ (NativeAssemblyParser parser, NativeAssemblyParser.AssemblerSymbol appConfigSymbol) = GetAssemblyParserAndValidateConfig (envFile);
+
+ var pointers = new List ();
+ var ret = new ApplicationConfigCLR ();
+ uint fieldCount = 0;
+ string[] field;
+
+ foreach (NativeAssemblyParser.AssemblerSymbolItem item in appConfigSymbol.Contents) {
+ field = GetField (envFile.Path, parser.SourceFilePath, item.Contents, item.LineNumber);
+
+ if (CanIgnoreAssemblerField (field[0])) {
+ continue;
+ }
+
+ switch (fieldCount) {
+ case 0: // uses_assembly_preload: bool / .byte
+ AssertFieldType (envFile.Path, parser.SourceFilePath, ".byte", field [0], item.LineNumber);
+ ret.uses_assembly_preload = ConvertFieldToBool ("uses_assembly_preload", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 1: // jni_add_native_method_registration_attribute_present: bool / .byte
+ AssertFieldType (envFile.Path, parser.SourceFilePath, ".byte", field [0], item.LineNumber);
+ ret.jni_add_native_method_registration_attribute_present = ConvertFieldToBool ("jni_add_native_method_registration_attribute_present", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 2: // marshal_methods_enabled: bool / .byte
+ AssertFieldType (envFile.Path, parser.SourceFilePath, ".byte", field [0], item.LineNumber);
+ ret.marshal_methods_enabled = ConvertFieldToBool ("marshal_methods_enabled", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 3: // ignore_split_configs: bool / .byte
+ AssertFieldType (envFile.Path, parser.SourceFilePath, ".byte", field [0], item.LineNumber);
+ ret.ignore_split_configs = ConvertFieldToBool ("ignore_split_configs", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 4: // number_of_runtime_properties: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.number_of_runtime_properties = ConvertFieldToUInt32 ("number_of_runtime_properties", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 5: // package_naming_policy: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.package_naming_policy = ConvertFieldToUInt32 ("package_naming_policy", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 6: // environment_variable_count: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.environment_variable_count = ConvertFieldToUInt32 ("environment_variable_count", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 7: // system_property_count: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.system_property_count = ConvertFieldToUInt32 ("system_property_count", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 8: // number_of_assemblies_in_apk: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.number_of_assemblies_in_apk = ConvertFieldToUInt32 ("number_of_assemblies_in_apk", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 9: // bundled_assembly_name_width: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.bundled_assembly_name_width = ConvertFieldToUInt32 ("bundled_assembly_name_width", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 10: // number_of_dso_cache_entries: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.number_of_dso_cache_entries = ConvertFieldToUInt32 ("number_of_dso_cache_entries", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 11: // number_of_aot_cache_entries: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.number_of_aot_cache_entries = ConvertFieldToUInt32 ("number_of_aot_cache_entries", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 12: // number_of_shared_libraries: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.number_of_shared_libraries = ConvertFieldToUInt32 ("number_of_shared_libraries", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 13: // android_runtime_jnienv_class_token: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.android_runtime_jnienv_class_token = ConvertFieldToUInt32 ("android_runtime_jnienv_class_token", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 14: // jnienv_initialize_method_token: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.jnienv_initialize_method_token = ConvertFieldToUInt32 ("jnienv_initialize_method_token", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 15: // jnienv_registerjninatives_method_token: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.jnienv_registerjninatives_method_token = ConvertFieldToUInt32 ("jnienv_registerjninatives_method_token", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 16: // jni_remapping_replacement_type_count: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.jni_remapping_replacement_type_count = ConvertFieldToUInt32 ("jni_remapping_replacement_type_count", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 17: // jni_remapping_replacement_method_index_entry_count: uint32_t / .word | .long
+ Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ ret.jni_remapping_replacement_method_index_entry_count = ConvertFieldToUInt32 ("jni_remapping_replacement_method_index_entry_count", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+
+ case 18: // android_package_name: string / [pointer type]
+ Assert.IsTrue (expectedPointerTypes.Contains (field [0]), $"Unexpected pointer field type in '{envFile.Path}:{item.LineNumber}': {field [0]}");
+ pointers.Add (field [1].Trim ());
+ break;
+
+ case 19: // managed_marshal_methods_lookup_enabled: bool / .byte
+ AssertFieldType (envFile.Path, parser.SourceFilePath, ".byte", field [0], item.LineNumber);
+ ret.managed_marshal_methods_lookup_enabled = ConvertFieldToBool ("managed_marshal_methods_lookup_enabled", envFile.Path, parser.SourceFilePath, item.LineNumber, field [1]);
+ break;
+ }
+ fieldCount++;
+ }
+
+ Assert.AreEqual (1, pointers.Count, $"Invalid number of string pointers in 'application_config' structure in environment file '{envFile.Path}'");
+
+ NativeAssemblyParser.AssemblerSymbol androidPackageNameSymbol = GetRequiredSymbol (pointers[0], envFile, parser);
+ ret.android_package_name = GetStringContents (androidPackageNameSymbol, envFile, parser);
+
+ Assert.AreEqual (ApplicationConfigFieldCountCLR, fieldCount, $"Invalid 'application_config' field count in environment file '{envFile.Path}'");
+ Assert.IsFalse (String.IsNullOrEmpty (ret.android_package_name), $"Package name field in 'application_config' in environment file '{envFile.Path}' must not be null or empty");
+
+ return ret;
+ }
+
+ static void AssertApplicationConfigIsIdentical (ApplicationConfigCLR firstAppConfig, string firstEnvFile, ApplicationConfigCLR secondAppConfig, string secondEnvFile)
+ {
+ Assert.AreEqual (firstAppConfig.uses_assembly_preload, secondAppConfig.uses_assembly_preload, $"Field 'uses_assembly_preload' has different value in environment file '{secondEnvFile}' than in environment file '{firstEnvFile}'");
+ Assert.AreEqual (firstAppConfig.marshal_methods_enabled, secondAppConfig.marshal_methods_enabled, $"Field 'marshal_methods_enabled' has different value in environment file '{secondEnvFile}' than in environment file '{firstEnvFile}'");
+ Assert.AreEqual (firstAppConfig.environment_variable_count, secondAppConfig.environment_variable_count, $"Field 'environment_variable_count' has different value in environment file '{secondEnvFile}' than in environment file '{firstEnvFile}'");
+ Assert.AreEqual (firstAppConfig.system_property_count, secondAppConfig.system_property_count, $"Field 'system_property_count' has different value in environment file '{secondEnvFile}' than in environment file '{firstEnvFile}'");
+ Assert.AreEqual (firstAppConfig.android_package_name, secondAppConfig.android_package_name, $"Field 'android_package_name' has different value in environment file '{secondEnvFile}' than in environment file '{firstEnvFile}'");
+ Assert.AreEqual (firstAppConfig.managed_marshal_methods_lookup_enabled, secondAppConfig.managed_marshal_methods_lookup_enabled, $"Field 'managed_marshal_methods_lookup_enabled' has different value in environment file '{secondEnvFile}' than in environment file '{firstEnvFile}'");
+ }
+}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.cs
index 7a86601ce43..602996ddd99 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.cs
@@ -14,7 +14,7 @@
namespace Xamarin.Android.Build.Tests
{
- class EnvironmentHelper
+ partial class EnvironmentHelper
{
public sealed class EnvironmentFile
{
@@ -36,7 +36,7 @@ public EnvironmentFile (string path, string abi)
}
}
- // This must be identical to the like-named structure in src/native/xamarin-app-stub/xamarin-app.hh
+ // This must be identical to the like-named structure in src/native/mono/xamarin-app-stub/xamarin-app.hh
public sealed class ApplicationConfig
{
public bool uses_mono_llvm;
@@ -183,7 +183,7 @@ public static ApplicationConfig ReadApplicationConfig (List env
return app_config;
}
- static ApplicationConfig ReadApplicationConfig (EnvironmentFile envFile)
+ static (NativeAssemblyParser parser, NativeAssemblyParser.AssemblerSymbol appConfigSymbol) GetAssemblyParserAndValidateConfig (EnvironmentFile envFile)
{
NativeAssemblyParser parser = CreateAssemblyParser (envFile);
@@ -193,6 +193,19 @@ static ApplicationConfig ReadApplicationConfig (EnvironmentFile envFile)
Assert.IsTrue (appConfigSymbol.Size != 0, $"{ApplicationConfigSymbolName} size as specified in the '.size' directive must not be 0");
+ return (parser, appConfigSymbol);
+ }
+
+ static bool CanIgnoreAssemblerField (string field)
+ {
+ // padding, we can safely ignore it
+ return String.Compare (".zero", field, StringComparison.Ordinal) == 0;
+ }
+
+ static ApplicationConfig ReadApplicationConfig (EnvironmentFile envFile)
+ {
+ (NativeAssemblyParser parser, NativeAssemblyParser.AssemblerSymbol appConfigSymbol) = GetAssemblyParserAndValidateConfig (envFile);
+
var pointers = new List ();
var ret = new ApplicationConfig ();
uint fieldCount = 0;
@@ -201,8 +214,8 @@ static ApplicationConfig ReadApplicationConfig (EnvironmentFile envFile)
foreach (NativeAssemblyParser.AssemblerSymbolItem item in appConfigSymbol.Contents) {
field = GetField (envFile.Path, parser.SourceFilePath, item.Contents, item.LineNumber);
- if (String.Compare (".zero", field[0], StringComparison.Ordinal) == 0) {
- continue; // padding, we can safely ignore it
+ if (CanIgnoreAssemblerField (field[0])) {
+ continue;
}
switch (fieldCount) {
@@ -521,8 +534,17 @@ static void AssertSharedLibraryHasRequiredSymbols (string dsoPath, string readEl
symbols.Add (symbolName);
}
- foreach (string symbol in requiredSharedLibrarySymbols) {
- Assert.IsTrue (symbols.Contains (symbol), $"Symbol '{symbol}' is missing from '{dsoPath}'");
+ if (TargetRuntimeHelper.UseMonoRuntime) {
+ EnsureSymbols (requiredSharedLibrarySymbols);
+ } else if (TargetRuntimeHelper.UseCoreCLR) {
+ EnsureSymbols (requiredSharedLibrarySymbolsCLR);
+ }
+
+ void EnsureSymbols (IEnumerable requiredSymbols)
+ {
+ foreach (string symbol in requiredSymbols) {
+ Assert.IsTrue (symbols.Contains (symbol), $"Symbol '{symbol}' is missing from '{dsoPath}'");
+ }
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs
index 20e919022ee..4a24692c62f 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs
@@ -203,8 +203,10 @@ public void DotNetPublishDefaultValues([Values (false, true)] bool isRelease)
}
[Test]
- public void DotNetPublish ([Values (false, true)] bool isRelease, [ValueSource(nameof(DotNetTargetFrameworks))] object[] data)
+ public void DotNetPublish ([Values (false, true)] bool isRelease, [ValueSource(nameof(DotNetTargetFrameworks))] object[] data, [Values ("Mono", "CoreCLR")] string runtime)
{
+ TargetRuntimeHelper.IgnoreOnIncompatibleRuntime (runtime);
+
var dotnetVersion = (string)data[0];
var platform = (string)data[1];
var apiLevel = (int)data[2];
@@ -218,13 +220,13 @@ public void DotNetPublish ([Values (false, true)] bool isRelease, [ValueSource(n
Assert.Ignore ($"Test for API level {apiLevel} was skipped as it matched the default or latest stable API level.");
var targetFramework = $"{dotnetVersion}-{platform}";
- const string runtimeIdentifier = "android-arm";
+ const string runtimeIdentifier = "android-arm64";
var proj = new XamarinAndroidApplicationProject {
TargetFramework = targetFramework,
IsRelease = isRelease,
EnableDefaultItems = true,
};
- proj.SetProperty (KnownProperties.RuntimeIdentifier, runtimeIdentifier);
+ proj.SetRuntimeIdentifier (runtimeIdentifier);
var preview = IsPreviewFrameworkVersion (targetFramework);
if (preview) {
@@ -249,8 +251,6 @@ public void DotNetPublish ([Values (false, true)] bool isRelease, [ValueSource(n
var expectedMonoAndroidRefPath = Path.Combine (refDirectory, "ref", dotnetVersion, "Mono.Android.dll");
Assert.IsTrue (dotnet.LastBuildOutput.ContainsText (expectedMonoAndroidRefPath), $"Build should be using {expectedMonoAndroidRefPath}");
- // TODO: We could parameterize this later
- const string runtime = "Mono";
var runtimeApiLevel = (apiLevel == XABuildConfig.AndroidDefaultTargetDotnetApiLevel && apiLevel < XABuildConfig.AndroidLatestStableApiLevel) ? XABuildConfig.AndroidLatestStableApiLevel : apiLevel;
var runtimeDirectory = Directory.GetDirectories (Path.Combine (TestEnvironment.DotNetPreviewPacksDirectory, $"Microsoft.Android.Runtime.{runtime}.{runtimeApiLevel}.{runtimeIdentifier}")).LastOrDefault ();
var expectedMonoAndroidRuntimePath = Path.Combine (runtimeDirectory, "runtimes", runtimeIdentifier, "lib", dotnetVersion, "Mono.Android.dll");
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidApplicationProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidApplicationProject.cs
index a2112ab413c..66a07f9efc3 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidApplicationProject.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidApplicationProject.cs
@@ -69,6 +69,11 @@ public XamarinAndroidApplicationProject (string debugConfigurationName = "Debug"
AndroidResources.Add (new AndroidItem.AndroidResource ("Resources\\values\\Strings.xml") { TextContent = () => StringsXml.Replace ("${PROJECT_NAME}", ProjectName) });
Sources.Add (new BuildItem.Source (() => "MainActivity" + Language.DefaultExtension) { TextContent = () => ProcessSourceTemplate (MainActivity ?? DefaultMainActivity) });
+
+ if (TargetRuntimeHelper.UseCoreCLR) {
+ // NuGet feed needed as Microsoft.Android.Runtime.CoreCLR packs not installed in workload by default
+ AddOrRemoveLocalNugetFeedPath (add: true);
+ }
}
// it is exposed as public because we may want to slightly modify this.
@@ -170,6 +175,18 @@ private bool PublishAot {
set { SetProperty (KnownProperties.PublishAot, value.ToString ()); }
}
+ void AddOrRemoveLocalNugetFeedPath (bool add)
+ {
+ var source = Path.Combine (XABuildPaths.BuildOutputDirectory, "nuget-unsigned");
+ if (add) {
+ if (!ExtraNuGetConfigSources.Contains (source)) {
+ ExtraNuGetConfigSources.Add (source);
+ }
+ } else {
+ ExtraNuGetConfigSources.Remove (source);
+ }
+ }
+
///
/// Sets properties required for $(PublishAot)=true
///
@@ -181,14 +198,13 @@ public void SetPublishAot (bool value, string androidNdkPath)
PublishAot = value;
SetProperty ("AndroidNdkDirectory", androidNdkPath);
- // NuGet feed needed as Microsoft.Android.Runtime.NativeAOT packs not installed in workload by default
- var source = Path.Combine (XABuildPaths.BuildOutputDirectory, "nuget-unsigned");
+ // CoreCLR tests won't work with PublishAot == true
if (value) {
- if (!ExtraNuGetConfigSources.Contains (source))
- ExtraNuGetConfigSources.Add (source);
- } else {
- ExtraNuGetConfigSources.Remove (source);
+ RemoveProperty ("UseMonoRuntime");
}
+
+ // NuGet feed needed as Microsoft.Android.Runtime.NativeAOT packs not installed in workload by default
+ AddOrRemoveLocalNugetFeedPath (add: value);
}
public string AndroidManifest { get; set; }
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/IShortFormProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/IShortFormProject.cs
index c1b27a070a1..1b38f33ba20 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/IShortFormProject.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/IShortFormProject.cs
@@ -18,5 +18,6 @@ public interface IShortFormProject
IList> ItemGroupList { get; }
IList Imports { get; }
void SetProperty (string name, string value, string condition = null);
+ bool RemoveProperty (string name);
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/TestEnvironment.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/TestEnvironment.cs
index 52f4a8ba835..bdc1745a112 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/TestEnvironment.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/TestEnvironment.cs
@@ -124,15 +124,24 @@ static string GetDotNetAndroidSdkDir (string packsDirectory)
IsWindows ? "Microsoft.Android.Sdk.Windows" :
"Microsoft.Android.Sdk.Linux";
+ Console.WriteLine ($"GetDotNetAndroidSdkDir (\"{packsDirectory}\")");
var sdkDir = Path.Combine (packsDirectory, sdkName);
- if (!Directory.Exists (sdkDir))
+ Console.WriteLine ($" sdkDir == '{sdkDir}'");
+ if (!Directory.Exists (sdkDir)) {
+ Console.WriteLine (" doesn't exist, returning String.Empty");
return string.Empty;
+ }
var dirs = from d in Directory.GetDirectories (sdkDir)
let version = ParseVersion (d)
orderby version descending
select d;
+ Console.WriteLine (" Got dirs:");
+ foreach (string dir in dirs) {
+ Console.WriteLine ($" {dir}");
+ }
+
return dirs.FirstOrDefault ();
}
@@ -143,7 +152,10 @@ orderby version descending
///
public static bool UseLocalBuildOutput {
get {
+ Console.WriteLine ($"UseLocalBuildOutput: local sdk dir == '{LocalDotNetAndroidSdkDirectory}'");
var msbuildDir = Path.Combine (LocalDotNetAndroidSdkDirectory, "tools");
+ bool tasksExist = File.Exists (Path.Combine (msbuildDir, "Xamarin.Android.Build.Tasks.dll"));
+ Console.WriteLine ($"UseLocalBuildOutput: msbuild dir == '{msbuildDir}' (tasks exist? {tasksExist})");
return Directory.Exists (msbuildDir) && File.Exists (Path.Combine (msbuildDir, "Xamarin.Android.Build.Tasks.dll"));
}
}
@@ -176,4 +188,3 @@ static Version ParseVersion (string path)
public static bool IsUsingJdk11 => AndroidSdkResolver.GetJavaSdkVersionString ().Contains ("11.0");
}
}
-
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs
index 601406c0748..b9248e2f916 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs
@@ -76,6 +76,9 @@ public XamarinProject (string debugConfigurationName = "Debug", string releaseCo
PropertyGroups.Add (release);
Imports = new List ();
+ // Selects between MonoVM and CoreCLR (based on presence of the USE_MONO_RUNTIME environment variable)
+ SetProperty ("UseMonoRuntime", TargetRuntimeHelper.UseMonoRuntime ? "true" : "false");
+
//NOTE: for SDK-style projects, we need $(Configuration) set before Microsoft.NET.Sdk.targets
Imports.Add (new Import ("Directory.Build.props") {
TextContent = () =>
@@ -109,6 +112,11 @@ public string TargetFrameworks {
set { SetProperty ("TargetFrameworks", value); }
}
+ public string UseMonoRuntime {
+ get { return GetProperty ("UseMonoRuntime"); }
+ set { SetProperty ("UseMonoRuntime", value); }
+ }
+
public string GetProperty (string name)
{
return GetProperty (CommonProperties, name);
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
index 0d09c5250f4..675da985b43 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
@@ -5,52 +5,76 @@
"Size": 3036
},
"classes.dex": {
- "Size": 22484
+ "Size": 22268
},
"lib/arm64-v8a/lib__Microsoft.Android.Resource.Designer.dll.so": {
"Size": 18288
},
"lib/arm64-v8a/lib_Java.Interop.dll.so": {
- "Size": 86688
+ "Size": 91792
},
"lib/arm64-v8a/lib_Mono.Android.dll.so": {
- "Size": 117712
+ "Size": 119960
},
"lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": {
- "Size": 22384
+ "Size": 23240
+ },
+ "lib/arm64-v8a/lib_System.Collections.Immutable.dll.so": {
+ "Size": 26432
},
"lib/arm64-v8a/lib_System.Console.dll.so": {
- "Size": 24392
+ "Size": 24416
+ },
+ "lib/arm64-v8a/lib_System.Diagnostics.StackTrace.dll.so": {
+ "Size": 22544
+ },
+ "lib/arm64-v8a/lib_System.IO.Compression.dll.so": {
+ "Size": 30624
+ },
+ "lib/arm64-v8a/lib_System.IO.MemoryMappedFiles.dll.so": {
+ "Size": 32664
},
"lib/arm64-v8a/lib_System.Linq.dll.so": {
- "Size": 25336
+ "Size": 25464
},
"lib/arm64-v8a/lib_System.Private.CoreLib.dll.so": {
- "Size": 628216
+ "Size": 827080
+ },
+ "lib/arm64-v8a/lib_System.Reflection.Metadata.dll.so": {
+ "Size": 65952
},
"lib/arm64-v8a/lib_System.Runtime.dll.so": {
- "Size": 20056
+ "Size": 20088
},
"lib/arm64-v8a/lib_System.Runtime.InteropServices.dll.so": {
- "Size": 21480
+ "Size": 21496
},
"lib/arm64-v8a/lib_UnnamedProject.dll.so": {
"Size": 20024
},
- "lib/arm64-v8a/libarc.bin.so": {
- "Size": 18872
+ "lib/arm64-v8a/libclrgc.so": {
+ "Size": 972344
+ },
+ "lib/arm64-v8a/libclrgcexp.so": {
+ "Size": 1025664
},
- "lib/arm64-v8a/libmono-component-marshal-ilgen.so": {
- "Size": 36440
+ "lib/arm64-v8a/libclrjit.so": {
+ "Size": 3088992
+ },
+ "lib/arm64-v8a/libcoreclr.so": {
+ "Size": 6649000
},
"lib/arm64-v8a/libmonodroid.so": {
- "Size": 1524752
+ "Size": 1216032
+ },
+ "lib/arm64-v8a/libmscordaccore.so": {
+ "Size": 2708168
},
- "lib/arm64-v8a/libmonosgen-2.0.so": {
- "Size": 3101112
+ "lib/arm64-v8a/libmscordbi.so": {
+ "Size": 1946872
},
"lib/arm64-v8a/libSystem.Globalization.Native.so": {
- "Size": 71976
+ "Size": 71952
},
"lib/arm64-v8a/libSystem.IO.Compression.Native.so": {
"Size": 758896
@@ -62,16 +86,16 @@
"Size": 165000
},
"lib/arm64-v8a/libxamarin-app.so": {
- "Size": 19536
+ "Size": 30560
},
"META-INF/BNDLTOOL.RSA": {
"Size": 1221
},
"META-INF/BNDLTOOL.SF": {
- "Size": 3266
+ "Size": 4157
},
"META-INF/MANIFEST.MF": {
- "Size": 3139
+ "Size": 4030
},
"res/drawable-hdpi-v4/icon.png": {
"Size": 2178
@@ -98,5 +122,5 @@
"Size": 1904
}
},
- "PackageSize": 3078677
+ "PackageSize": 8490176
}
\ No newline at end of file
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/AbiUtils.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/AbiUtils.cs
index 5873229dff2..5dc9e4cc607 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/AbiUtils.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/AbiUtils.cs
@@ -1,21 +1,14 @@
using System;
+using Xamarin.Android.Tasks;
+
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}");
+ return MonoAndroidHelper.AbiToRidMaybe (androidAbi);
}
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/ProjectExtensions.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/ProjectExtensions.cs
index 9492df1738c..e9a729b3ae1 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/ProjectExtensions.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/ProjectExtensions.cs
@@ -10,39 +10,76 @@ namespace Xamarin.ProjectTools
public static class ProjectExtensions
{
///
- /// Sets $(AndroidSupportedAbis) or $(RuntimeIdentifiers) depending if running under dotnet
+ /// Sets $(AndroidSupportedAbis) or $(RuntimeIdentifiers) depending if running under dotnet. If
+ /// is `true` (the default), remove potentially set properties that may break the build with `RuntimeIdentifiers` present. Currently, it
+ /// means removing the `RuntimeIdentifier`
///
[Obsolete ("SetAndroidSupportedAbis is deprecated, please use SetRuntimeIdentifiers instead.")]
- public static void SetAndroidSupportedAbis (this IShortFormProject project, params string [] abis)
+ public static void SetAndroidSupportedAbis (this IShortFormProject project, bool removeConflictingProperties, params string [] abis)
{
project.SetRuntimeIdentifiers (abis);
}
///
- /// Sets $(AndroidSupportedAbis) or $(RuntimeIdentifiers) depending if running under dotnet
+ /// Sets $(AndroidSupportedAbis) or $(RuntimeIdentifiers) depending if running under dotnet.
+ /// Remove potentially set properties that may break the build
+ /// with `RuntimeIdentifiers` present. Currently, it means removing the `RuntimeIdentifier` property.
+ ///
+ [Obsolete ("SetAndroidSupportedAbis is deprecated, please use SetRuntimeIdentifiers instead.")]
+ public static void SetAndroidSupportedAbis (this IShortFormProject project, params string [] abis)
+ {
+ project.SetAndroidSupportedAbis (removeConflictingProperties: true, abis);
+ }
+
+ ///
+ /// Sets $(AndroidSupportedAbis) or $(RuntimeIdentifiers) depending if running under dotnet. If
+ /// is `true` (the default), remove potentially set properties that may break the build with `RuntimeIdentifiers` present. Currently, it
+ /// means removing the `RuntimeIdentifier`
///
/// A semi-colon-delimited list of ABIs
[Obsolete ("SetAndroidSupportedAbis is deprecated, please use SetRuntimeIdentifiers instead.")]
- public static void SetAndroidSupportedAbis (this IShortFormProject project, string abis)
+ public static void SetAndroidSupportedAbis (this IShortFormProject project, string abis, bool removeConflictingProperties = true)
{
- project.SetRuntimeIdentifiers (abis.Split (';'));
+ project.SetRuntimeIdentifiers (abis.Split (';'), removeConflictingProperties);
}
- public static void SetRuntimeIdentifier (this IShortFormProject project, string androidAbi)
+ ///
+ /// Set the `$(RuntimeIdentifier)` property to the specified value. If is `true` (the default), remove
+ /// potentially set properties that may break the build with `RuntimeIdentifier` present. Currently, it means removing the `RuntimeIdentifiers`
+ /// property.
+ ///
+ public static void SetRuntimeIdentifier (this IShortFormProject project, string androidAbi, bool removeConflictingProperties = true)
{
project.SetProperty (KnownProperties.RuntimeIdentifier, AbiUtils.AbiToRuntimeIdentifier (androidAbi));
+ if (removeConflictingProperties) {
+ project.RemoveProperty (KnownProperties.RuntimeIdentifiers);
+ }
}
- public static void SetRuntimeIdentifiers (this IShortFormProject project, IEnumerable androidAbis)
+ ///
+ /// Set the `$(RuntimeIdentifiers)` property to the specified value. If is `true` (the default), remove
+ /// potentially set properties that may break the build with `RuntimeIdentifiers` present. Currently, it means removing the `RuntimeIdentifier`
+ /// property.
+ ///
+ public static void SetRuntimeIdentifiers (this IShortFormProject project, IEnumerable androidAbis, bool removeConflictingProperties = true)
{
var abis = new List ();
foreach (var androidAbi in androidAbis) {
abis.Add (AbiUtils.AbiToRuntimeIdentifier (androidAbi));
}
project.SetProperty (KnownProperties.RuntimeIdentifiers, string.Join (";", abis));
+
+ if (removeConflictingProperties) {
+ project.RemoveProperty (KnownProperties.RuntimeIdentifier);
+ }
}
- public static void SetRuntimeIdentifiers (this IShortFormProject project, params AndroidTargetArch[] targetArches)
+ ///
+ /// Set the `$(RuntimeIdentifiers)` property to the specified value. If is `true`, remove
+ /// potentially set properties that may break the build with `RuntimeIdentifiers` present. Currently, it means removing the `RuntimeIdentifier`
+ /// property.
+ ///
+ public static void SetRuntimeIdentifiers (this IShortFormProject project, bool removeConflictingProperties, params AndroidTargetArch[] targetArches)
{
if (targetArches == null || targetArches.Length == 0) {
throw new ArgumentException ("must not be null or empty", nameof (targetArches));
@@ -51,6 +88,15 @@ public static void SetRuntimeIdentifiers (this IShortFormProject project, params
project.SetProperty (KnownProperties.RuntimeIdentifiers, String.Join (";", targetArches.Select (arch => MonoAndroidHelper.ArchToRid (arch))));
}
+ ///
+ /// Set the `$(RuntimeIdentifiers)` property to the specified value. Remove potentially set properties that may break the build
+ /// with `RuntimeIdentifiers` present. Currently, it means removing the `RuntimeIdentifier` property.
+ ///
+ public static void SetRuntimeIdentifiers (this IShortFormProject project, params AndroidTargetArch[] targetArches)
+ {
+ project.SetRuntimeIdentifiers (removeConflictingProperties: true, targetArches);
+ }
+
public static HashSet GetRuntimeIdentifiers (this XamarinProject project)
{
var ridsPropValue = project.GetProperty (KnownProperties.RuntimeIdentifiers);
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/TargetRuntimeHelper.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/TargetRuntimeHelper.cs
new file mode 100644
index 00000000000..34f6643cc28
--- /dev/null
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/TargetRuntimeHelper.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+
+using NUnit.Framework;
+using Xamarin.Android.Tasks;
+
+namespace Xamarin.ProjectTools;
+
+public class TargetRuntimeHelper
+{
+ static readonly bool useMonoRuntime;
+ static readonly string[] coreClrSupportedAbis = new []{ "arm64-v8a", "x86_64" };
+ static readonly HashSet coreClrAbis = new (coreClrSupportedAbis, StringComparer.OrdinalIgnoreCase);
+
+ static TargetRuntimeHelper ()
+ {
+ // TODO: this detection should probably depend on something more than an envvar. We can detect Mono
+ // by looking for one of the Mono-specific types, can we do something similar to detect NativeAOT?
+ string? envvar = Environment.GetEnvironmentVariable ("USE_MONO_RUNTIME");
+ if (envvar == null || envvar.Length == 0 || String.Compare ("true", envvar, StringComparison.OrdinalIgnoreCase) == 0) {
+ useMonoRuntime = true;
+ } else {
+ useMonoRuntime = false;
+ }
+ }
+
+ ///
+ /// This must be changed when we're ready to release. It is used to make tests which require a certain amount of warnings to
+ /// work when the XA1040 warning is issued (see Xamarin.Android.Common.targets, the `_CheckNonIdealAppConfigurations` target)
+ ///
+ public static bool CoreClrIsExperimental => true;
+ public static bool UseMonoRuntime => useMonoRuntime;
+ public static bool UseCoreCLR => !useMonoRuntime;
+ public static string[] CoreClrSupportedAbis => coreClrSupportedAbis;
+ public string RuntimeName => UseMonoRuntime ? "MonoVM" : "CoreCLR";
+
+ public static bool CoreClrSupportsAbi (string abiName) => coreClrAbis.Contains (abiName);
+
+ ///
+ /// contains a list of semicolon-separated RIDs (a single RID without
+ /// semicolon is also fine) which will be checked against the list of RIDs supported by CoreCLR. If even
+ /// a single RID isn't supported, `false` is returned.
+ ///
+ public static bool CoreClrSupportsAllRIDs (string runtimeIdentifiers)
+ {
+ foreach (string rid in runtimeIdentifiers.Split (';', StringSplitOptions.RemoveEmptyEntries)) {
+ if (!CoreClrSupportsAbi (MonoAndroidHelper.RidToAbi (rid))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// contains a list of semicolon-separated ABIs (a single ABI without
+ /// semicolon is also fine) which will be checked against the list of ABIs supported by CoreCLR. If even
+ /// a single ABI isn't supported, `false` is returned.
+ ///
+ public static bool CoreClrSupportsAllABIs (string abis)
+ {
+ foreach (string abi in abis.Split (';', StringSplitOptions.RemoveEmptyEntries)) {
+ if (!CoreClrSupportsAbi (abi)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static void IgnoreOnIncompatibleRuntime (string runtime)
+ {
+ if (UseCoreCLR && String.Compare (runtime, "CoreCLR", StringComparison.OrdinalIgnoreCase) != 0) {
+ Assert.Ignore ($"{runtime} tests not supported under CoreCLR");
+ }
+
+ if (UseMonoRuntime && String.Compare (runtime, "Mono", StringComparison.OrdinalIgnoreCase) != 0) {
+ Assert.Ignore ($"{runtime} tests not supported under MonoVM");
+ }
+ }
+
+ public static void IgnoreIfIncompatibleWithMonoAOT (bool aot)
+ {
+ if (aot && UseCoreCLR) {
+ Assert.Ignore ("CoreCLR runtime doesn't support MonoVM-style AOT");
+ }
+ }
+}
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfig.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfig.cs
index 40ea29ee665..4fc992a49f4 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfig.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfig.cs
@@ -3,7 +3,7 @@
namespace Xamarin.Android.Tasks
{
// Declaration order of fields and their types must correspond *exactly* to that in
- // src/native/xamarin-app-stub/xamarin-app.hh ApplicationConfig structure
+ // src/native/mono/xamarin-app-stub/xamarin-app.hh ApplicationConfig structure
//
// Type mappings:
//
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigCLR.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigCLR.cs
index 0efed3ccc3c..9f9c46b3b45 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigCLR.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigCLR.cs
@@ -3,7 +3,7 @@
namespace Xamarin.Android.Tasks;
// Declaration order of fields and their types must correspond *exactly* to that in
-// src/native/clr/xamarin-app-stub/xamarin-app.hh ApplicationConfig structure
+// src/native/clr/include/xamarin-app.hh ApplicationConfig structure
//
// Type mappings:
//
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.Basic.cs b/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.Basic.cs
index a0c5bc10cbe..0849aa144ab 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.Basic.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.Basic.cs
@@ -102,6 +102,20 @@ public static string AbiToRid (string abi)
return rid;
}
+ ///
+ /// Return RID corresponding to the parameter. If `abiOrRid` is already a
+ /// valid RID, it is returned without changes. Otherwise an attempt is made to convert its value from
+ /// Android ABI name to .NET RID.
+ ///
+ public static string AbiToRidMaybe (string abiOrRid)
+ {
+ if (RidToAbiMap.ContainsKey (abiOrRid)) {
+ return abiOrRid;
+ }
+
+ return AbiToRid (abiOrRid);
+ }
+
public static string RidToAbi (string rid)
{
if (!RidToAbiMap.TryGetValue (rid, out string abi)) {
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
index 5339fa643ea..cafb62b4dc7 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@@ -568,6 +568,11 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
FormatArguments="AndroidFastDeploymentType;9"
Condition=" '$(AndroidFastDeploymentType)' != '' "
/>
+
+