diff --git a/.external b/.external
index 4860877f91c..01e4987437b 100644
--- a/.external
+++ b/.external
@@ -1,2 +1,2 @@
-xamarin/monodroid:main@2e93b630e47701dae56f426fe5934846d571832b
+xamarin/monodroid:main@dade1f497271f3ae5ceb1fe8c6c672b399a369ec
mono/mono:2020-02@c66141a8c7ba2566c578c2dd012b2b723e006213
diff --git a/.gitmodules b/.gitmodules
index 3fda7ea93db..03f994fd0a8 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -35,6 +35,10 @@
url = https://github.com/Guardsquare/proguard.git
branch = master
ignore = dirty
+[submodule "external/robin-map"]
+ path = external/robin-map
+ url = https://github.com/Tessil/robin-map.git
+ branch = master
[submodule "external/sqlite"]
path = external/sqlite
url = https://github.com/xamarin/sqlite.git
diff --git a/Configuration.props b/Configuration.props
index 1ac20529783..5e87a5827f3 100644
--- a/Configuration.props
+++ b/Configuration.props
@@ -75,8 +75,11 @@
$(AndroidToolchainDirectory)\dotnet\
$(DotNetPreviewPath)dotnet
+
6.0.100
$(DotNetPreviewVersionBand)-preview.1.21109.8
+
+ 6.0.0-preview.2.21108.2
6.0.0
$(ILLinkVersionBand)-alpha.1.21109.1
$(AndroidToolchainDirectory)\wix\
diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt
index 31a8d5b57b0..d84d5f7a3e8 100644
--- a/ThirdPartyNotices.txt
+++ b/ThirdPartyNotices.txt
@@ -15,6 +15,7 @@ The attached notices are provided for information only.
2. bazelbuild/bazel (https://github.com/bazelbuild/bazel/)
3. force-net/crc32.net (https://github.com/force-net/Crc32.NET)
4. nunit/nunitlite (https://github.com/nunit/nunitlite/)
+5. tessil/robin-map (https://github.com/Tessil/robin-map)
%% android/platform/tools/base NOTICES AND INFORMATION BEGIN HERE
=================================================================
@@ -487,3 +488,31 @@ THE SOFTWARE.
=====================================================
END OF nunit/nunitlite NOTICES AND INFORMATION
+%% tessil/robin-map NOTICES AND INFORMATION BEGIN HERE
+======================================================
+MIT License
+
+Copyright (c) 2017 Thibaut Goetghebuer-Planchon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+======================================================
+END OF tessil/robin-map NOTICES AND INFORMATION
+
diff --git a/build-tools/create-packs/Directory.Build.targets b/build-tools/create-packs/Directory.Build.targets
index 173ccd7ed0a..43efa9ab75a 100644
--- a/build-tools/create-packs/Directory.Build.targets
+++ b/build-tools/create-packs/Directory.Build.targets
@@ -77,10 +77,10 @@
-
-
-
-
+
+
+
+
diff --git a/build-tools/create-packs/Microsoft.Android.Runtime.proj b/build-tools/create-packs/Microsoft.Android.Runtime.proj
index 2e89e21a009..cdf18885614 100644
--- a/build-tools/create-packs/Microsoft.Android.Runtime.proj
+++ b/build-tools/create-packs/Microsoft.Android.Runtime.proj
@@ -11,7 +11,7 @@ projects that use the Microsoft.Android framework in .NET 5.
android-arm64
- arm64-v8a
+ arm64-v8a-net6
Microsoft.Android.Runtime.$(AndroidRID)
Microsoft.Android runtime components. Please do not reference directly.
<_AndroidRuntimePackAssemblyPath>runtimes\$(AndroidRID)\lib\net6.0
@@ -39,7 +39,6 @@ projects that use the Microsoft.Android framework in .NET 5.
<_AndroidRuntimePackAssemblies Include="$(_MonoAndroidNETOutputDir)Mono.Android.Export.dll" />
<_AndroidRuntimePackAssets Include="$(XAInstallPrefix)xbuild\Xamarin\Android\lib\$(AndroidABI)\libmono-android.debug.so" />
<_AndroidRuntimePackAssets Include="$(XAInstallPrefix)xbuild\Xamarin\Android\lib\$(AndroidABI)\libmono-android.release.so" />
- <_AndroidRuntimePackAssets Include="$(XAInstallPrefix)xbuild\Xamarin\Android\lib\$(AndroidABI)\libxa-internal-api.so" />
<_AndroidRuntimePackAssets Include="$(XAInstallPrefix)xbuild\Xamarin\Android\lib\$(AndroidABI)\libxamarin-debug-app-helper.so" />
diff --git a/build-tools/create-pkg/create-pkg.targets b/build-tools/create-pkg/create-pkg.targets
index e9d24dc0b0a..bdd498a5616 100644
--- a/build-tools/create-pkg/create-pkg.targets
+++ b/build-tools/create-pkg/create-pkg.targets
@@ -27,6 +27,10 @@
$(XAFrameworkDir)\lib\xamarin.android\xbuild-frameworks\MonoAndroid
+
+
+
+
Microsoft/Framework/MonoAndroid/$([System.IO.Path]::GetDirectoryName(%(RelativePath)))
+
+
Xamarin/Android/$([System.IO.Path]::GetDirectoryName(%(RelativePath)))
diff --git a/build-tools/installers/create-installers.targets b/build-tools/installers/create-installers.targets
index ea061103c1a..51f3f728e0f 100644
--- a/build-tools/installers/create-installers.targets
+++ b/build-tools/installers/create-installers.targets
@@ -227,10 +227,14 @@
<_MSBuildFiles Include="$(MSBuildSrcDir)\startup-xf.aotprofile" />
<_MSBuildFiles Include="$(MSBuildSrcDir)\r8.jar" />
<_MSBuildFiles Include="$(MSBuildSrcDir)\bundletool.jar" ExcludeFromAndroidNETSdk="true" />
- <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime.jar" />
- <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_fastdev.jar" />
- <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime.dex" />
- <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_fastdev.dex" />
+ <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime.jar" ExcludeFromAndroidNETSdk="true" />
+ <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_fastdev.jar" ExcludeFromAndroidNETSdk="true" />
+ <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime.dex" ExcludeFromAndroidNETSdk="true" />
+ <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_fastdev.dex" ExcludeFromAndroidNETSdk="true" />
+ <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_net6.jar" ExcludeFromLegacy="true" />
+ <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_fastdev_net6.jar" ExcludeFromLegacy="true" />
+ <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_net6.dex" ExcludeFromLegacy="true" />
+ <_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_fastdev_net6.dex" ExcludeFromLegacy="true" />
<_MSBuildFiles Include="$(MSBuildSrcDir)\manifestmerger.jar" />
<_MSBuildFiles Include="$(MSBuildSrcDir)\protobuf-net.dll" />
<_MSBuildFiles Include="$(MSBuildSrcDir)\SgmlReaderDll.dll" />
diff --git a/build-tools/scripts/Ndk.projitems.in b/build-tools/scripts/Ndk.projitems.in
index 14a9400db15..8f1971136d4 100644
--- a/build-tools/scripts/Ndk.projitems.in
+++ b/build-tools/scripts/Ndk.projitems.in
@@ -3,9 +3,13 @@
@NDK_RELEASE@
@NDK_ARMEABI_V7_API@
+ @NDK_ARMEABI_V7_API_NET6@
@NDK_ARM64_V8A_API@
+ @NDK_ARM64_V8A_API_NET6@
@NDK_X86_API@
+ @NDK_X86_API_NET6@
@NDK_X86_64_API@
+ @NDK_X86_64_API_NET6@
@@ -13,24 +17,28 @@
Include="armeabi-v7a"
Condition=" $(AndroidSupportedTargetJitAbisForConditionalChecks.Contains (':armeabi-v7a:')) ">
$(AndroidNdkApiLevel_ArmV7a)
+ $(AndroidNdkApiLevel_ArmV7a_NET6)
$(AndroidNdkApiLevel_ArmV8a)
+ $(AndroidNdkApiLevel_ArmV8a_NET6)
$(AndroidNdkApiLevel_X86)
+ $(AndroidNdkApiLevel_X86_NET6)
$(AndroidNdkApiLevel_X86_64)
+ $(AndroidNdkApiLevel_X86_64_NET6)
diff --git a/build-tools/scripts/xa_build_configuration.cmake.in b/build-tools/scripts/xa_build_configuration.cmake.in
new file mode 100644
index 00000000000..ad6da1b812a
--- /dev/null
+++ b/build-tools/scripts/xa_build_configuration.cmake.in
@@ -0,0 +1,4 @@
+set(NETCORE_APP_RUNTIME_DIR_ARM "@NETCORE_APP_RUNTIME_ANDROID_ARM@")
+set(NETCORE_APP_RUNTIME_DIR_ARM64 "@NETCORE_APP_RUNTIME_ANDROID_ARM64@")
+set(NETCORE_APP_RUNTIME_DIR_X86 "@NETCORE_APP_RUNTIME_ANDROID_X86@")
+set(NETCORE_APP_RUNTIME_DIR_X86_64 "@NETCORE_APP_RUNTIME_ANDROID_X86_64@")
diff --git a/build-tools/xaprepare/xaprepare/Application/GeneratedMonodroidCmakeFiles.cs b/build-tools/xaprepare/xaprepare/Application/GeneratedMonodroidCmakeFiles.cs
index 94d3af6553e..fa1b0647f6b 100644
--- a/build-tools/xaprepare/xaprepare/Application/GeneratedMonodroidCmakeFiles.cs
+++ b/build-tools/xaprepare/xaprepare/Application/GeneratedMonodroidCmakeFiles.cs
@@ -40,16 +40,20 @@ public override void Generate (Context context)
static readonly Dictionary ApiLevelVariableNames = new Dictionary (StringComparer.Ordinal) {
{ AbiNames.TargetJit.AndroidArmV7a, "NDK_LEGACY_API_ARMV7A" },
+ { BuildAndroidPlatforms.AndroidArmV7a_NET6, "NDK_NET6_API_ARMV7A" },
{ AbiNames.TargetJit.AndroidArmV8a, "NDK_LEGACY_API_ARMV8A" },
+ { BuildAndroidPlatforms.AndroidArmV8a_NET6, "NDK_NET6_API_ARMV8A" },
{ AbiNames.TargetJit.AndroidX86, "NDK_LEGACY_API_X86" },
+ { BuildAndroidPlatforms.AndroidX86_NET6, "NDK_NET6_API_X86" },
{ AbiNames.TargetJit.AndroidX86_64, "NDK_LEGACY_API_X86_64" },
+ { BuildAndroidPlatforms.AndroidX86_64_NET6, "NDK_NET6_API_X86_64" },
};
static readonly Dictionary JitAbis = new Dictionary (StringComparer.Ordinal) {
- { AbiNames.TargetJit.AndroidArmV7a, String.Empty },
- { AbiNames.TargetJit.AndroidArmV8a, String.Empty },
- { AbiNames.TargetJit.AndroidX86, String.Empty },
- { AbiNames.TargetJit.AndroidX86_64, String.Empty },
+ { AbiNames.TargetJit.AndroidArmV7a, BuildAndroidPlatforms.AndroidArmV7a_NET6 },
+ { AbiNames.TargetJit.AndroidArmV8a, BuildAndroidPlatforms.AndroidArmV8a_NET6 },
+ { AbiNames.TargetJit.AndroidX86, BuildAndroidPlatforms.AndroidX86_NET6 },
+ { AbiNames.TargetJit.AndroidX86_64, BuildAndroidPlatforms.AndroidX86_64_NET6 },
};
static readonly Dictionary HostAbis = new Dictionary (StringComparer.Ordinal) {
@@ -107,9 +111,13 @@ void GenerateShellConfig (Context context, StreamWriter sw)
sw.WriteLine ();
WriteApiLevelVariable (AbiNames.TargetJit.AndroidArmV7a);
+ WriteApiLevelVariable (BuildAndroidPlatforms.AndroidArmV7a_NET6);
WriteApiLevelVariable (AbiNames.TargetJit.AndroidArmV8a);
+ WriteApiLevelVariable (BuildAndroidPlatforms.AndroidArmV8a_NET6);
WriteApiLevelVariable (AbiNames.TargetJit.AndroidX86);
+ WriteApiLevelVariable (BuildAndroidPlatforms.AndroidX86_NET6);
WriteApiLevelVariable (AbiNames.TargetJit.AndroidX86_64);
+ WriteApiLevelVariable (BuildAndroidPlatforms.AndroidX86_64_NET6);
sw.WriteLine ();
string indent = "\t";
@@ -240,8 +248,8 @@ void WriteShellRuntimeCommand (StreamWriter sw, Dictionary abis,
foreach (var kvp in abis) {
string abi = kvp.Key;
- string apiLevelVarName = kvp.Key;
- string outputDirName = abi;
+ string apiLevelVarName = command.IsNet6 ? kvp.Value : kvp.Key;
+ string outputDirName = command.IsNet6 ? $"{abi}-net6" : abi;
string isMxe = "no";
string mxeBitness = String.Empty;
bool forMxe = false;
@@ -353,7 +361,6 @@ void GenerateMonodroidTargets (Context context, StreamWriter sw)
{ "@NATIVE_API_LEVEL@", "" },
{ "@ABI@", "%(AndroidSupportedTargetJitAbi.Identity)" },
{ "@OUTPUT_DIRECTORY@", "" },
-
};
var hostRuntimeReplacements = new Dictionary (StringComparer.Ordinal) {
@@ -419,12 +426,13 @@ string EnsureRequired (string name, string v)
void WriteMSBuildConfigureAndroidRuntimeCommands (StreamWriter sw, string indent, CmakeBuilds.RuntimeCommand command, Dictionary replacements)
{
const string LegacyOutputDirectory = "$(OutputPath)%(AndroidSupportedTargetJitAbi.Identity)";
+ const string Net6OutputDirectory = LegacyOutputDirectory + "-net6";
WriteMSBuildConfigureRuntimeCommands (
sw,
indent,
$"$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.Identity)-{command.Suffix}",
- LegacyOutputDirectory,
+ command.IsNet6 ? Net6OutputDirectory : LegacyOutputDirectory,
"@(AndroidSupportedTargetJitAbi)",
CmakeBuilds.ConfigureAndroidRuntimeCommandsCommonFlags,
command,
diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs
index cb1c4b41a56..4567610119a 100644
--- a/build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs
+++ b/build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs
@@ -42,11 +42,17 @@ class BuildAndroidPlatforms
new AndroidPlatform (apiName: "S", apiLevel: 31, platformID: "S", include: "v11.0.99", framework: "v11.0.99", stable: false),
};
+ // These are here until we can drop "legacy" targets and use only .NET6+
+ public const string AndroidArmV7a_NET6 = AbiNames.TargetJit.AndroidArmV7a + "_NET6";
+ public const string AndroidArmV8a_NET6 = AbiNames.TargetJit.AndroidArmV8a + "_NET6";
+ public const string AndroidX86_NET6 = AbiNames.TargetJit.AndroidX86 + "_NET6";
+ public const string AndroidX86_64_NET6 = AbiNames.TargetJit.AndroidX86_64 + "_NET6";
+
public static readonly Dictionary NdkMinimumAPI = new Dictionary {
- { AbiNames.TargetJit.AndroidArmV7a, 16 },
- { AbiNames.TargetJit.AndroidArmV8a, 21 },
- { AbiNames.TargetJit.AndroidX86, 16 },
- { AbiNames.TargetJit.AndroidX86_64, 21 },
+ { AbiNames.TargetJit.AndroidArmV7a, 16 }, { AndroidArmV7a_NET6, 21 },
+ { AbiNames.TargetJit.AndroidArmV8a, 21 }, { AndroidArmV8a_NET6, 21 },
+ { AbiNames.TargetJit.AndroidX86, 16 }, { AndroidX86_NET6, 21 },
+ { AbiNames.TargetJit.AndroidX86_64, 21 }, { AndroidX86_64_NET6, 21 },
};
}
}
diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/CmakeBuilds.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/CmakeBuilds.cs
index 4b5a247e460..d3b03f10470 100644
--- a/build-tools/xaprepare/xaprepare/ConfigAndData/CmakeBuilds.cs
+++ b/build-tools/xaprepare/xaprepare/ConfigAndData/CmakeBuilds.cs
@@ -20,6 +20,7 @@ public sealed class RuntimeCommand
public string Suffix = String.Empty;
public string MSBuildApiLevel = String.Empty;
public List? ExtraOptions = null;
+ public bool IsNet6 = false;
public bool IsHost = false;
};
@@ -83,6 +84,7 @@ public sealed class RuntimeCommand
public static readonly List AsanExtraOptions = new List {
"-DENABLE_CLANG_ASAN=ON",
+ "-DANDROID_STL=\"c++_static\"",
};
public static readonly List UbsanExtraOptions = new List {
@@ -91,6 +93,19 @@ public sealed class RuntimeCommand
"-DANDROID_CPP_FEATURES=\"rtti exceptions\"",
};
+ const string enableNet6 = "-DENABLE_NET6=ON";
+ public static readonly List Net6ExtraOptions = new List {
+ enableNet6,
+ };
+
+ public static readonly List Net6AsanExtraOptions = new List (AsanExtraOptions) {
+ enableNet6,
+ };
+
+ public static readonly List Net6UbsanExtraOptions = new List (UbsanExtraOptions) {
+ enableNet6,
+ };
+
public static readonly List AndroidRuntimeCommands = new List {
// Debug builds
new RuntimeCommand {
@@ -116,6 +131,33 @@ public sealed class RuntimeCommand
ExtraOptions = UbsanExtraOptions,
},
+ new RuntimeCommand {
+ Suffix = "net6-Debug",
+ Configuration = "Release",
+ BuildType = "Debug",
+ MSBuildApiLevel = msbuildApiLevelNet6,
+ ExtraOptions = Net6ExtraOptions,
+ IsNet6 = true,
+ },
+
+ new RuntimeCommand {
+ Suffix = "net6-asan-Debug",
+ Configuration = "Release",
+ BuildType = "Debug",
+ MSBuildApiLevel = msbuildApiLevelNet6,
+ ExtraOptions = Net6AsanExtraOptions,
+ IsNet6 = true,
+ },
+
+ new RuntimeCommand {
+ Suffix = "net6-ubsan-Debug",
+ Configuration = "Release",
+ BuildType = "Debug",
+ MSBuildApiLevel = msbuildApiLevelNet6,
+ ExtraOptions = Net6UbsanExtraOptions,
+ IsNet6 = true,
+ },
+
// Release builds
new RuntimeCommand {
@@ -140,6 +182,33 @@ public sealed class RuntimeCommand
MSBuildApiLevel = msbuildApiLevelLegacy,
ExtraOptions = UbsanExtraOptions,
},
+
+ new RuntimeCommand {
+ Suffix = "net6-Release",
+ Configuration = "Debug",
+ BuildType = "Release",
+ MSBuildApiLevel = msbuildApiLevelNet6,
+ ExtraOptions = Net6ExtraOptions,
+ IsNet6 = true,
+ },
+
+ new RuntimeCommand {
+ Suffix = "net6-asan-Release",
+ Configuration = "Debug",
+ BuildType = "Release",
+ MSBuildApiLevel = msbuildApiLevelNet6,
+ ExtraOptions = Net6AsanExtraOptions,
+ IsNet6 = true,
+ },
+
+ new RuntimeCommand {
+ Suffix = "net6-ubsan-Release",
+ Configuration = "Debug",
+ BuildType = "Release",
+ MSBuildApiLevel = msbuildApiLevelNet6,
+ ExtraOptions = Net6UbsanExtraOptions,
+ IsNet6 = true,
+ },
};
public static readonly List HostRuntimeCommands = new List {
diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs
index 90eee6e1251..94811ca21dc 100644
--- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs
+++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs
@@ -367,6 +367,12 @@ public static partial class Paths
public static string MonoArchiveLocalPath => Path.Combine (ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainCacheDirectory), MonoArchiveFileName);
public static string MonoArchiveWindowsLocalPath => Path.Combine (ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainCacheDirectory), MonoArchiveWindowsFileName);
+ // .NET 6
+ public static string NetcoreAppRuntimeAndroidARM => GetCachedPath (ref netcoreAppRuntimeAndroidARM, () => GetNetcoreAppRuntimePath (ctx, "arm"));
+ public static string NetcoreAppRuntimeAndroidARM64 => GetCachedPath (ref netcoreAppRuntimeAndroidARM64, () => GetNetcoreAppRuntimePath (ctx, "arm64"));
+ public static string NetcoreAppRuntimeAndroidX86 => GetCachedPath (ref netcoreAppRuntimeAndroidX86, () => GetNetcoreAppRuntimePath (ctx, "x86"));
+ public static string NetcoreAppRuntimeAndroidX86_64 => GetCachedPath (ref netcoreAppRuntimeAndroidX86_64, () => GetNetcoreAppRuntimePath (ctx, "x64"));
+
// CMake
public static string CmakeMSBuildPropsName = "cmake-config.props";
public static string CmakeShellScriptsPropsName = "cmake-config.sh";
@@ -392,6 +398,17 @@ public static partial class Paths
return Directory.Exists (path) ? path : Path.Combine (MonoSdksTpnExternalPath, "llvm");
});
+ static string GetNetcoreAppRuntimePath (Context ctx, string androidTarget)
+ {
+ return Path.Combine (
+ XAPackagesDir,
+ $"microsoft.netcore.app.runtime.android-{androidTarget}",
+ ctx.Properties.GetRequiredValue (KnownProperties.DotNetRuntimePacksVersion),
+ "runtimes",
+ $"android-{androidTarget}"
+ );
+ }
+
static string DetermineNugetPackagesDir (Context ctx)
{
return Path.GetFullPath (
@@ -470,6 +487,10 @@ static string GetCachedPath (ref string? variable, Func creator)
static string? configurationPropsGeneratedPath;
static string? windowsBinutilsInstallDir;
static string? hostBinutilsInstallDir;
+ static string? netcoreAppRuntimeAndroidARM;
+ static string? netcoreAppRuntimeAndroidARM64;
+ static string? netcoreAppRuntimeAndroidX86;
+ static string? netcoreAppRuntimeAndroidX86_64;
static string? monodroidSourceDir;
}
}
diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs b/build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs
index f36482a88be..97a9a524c5a 100644
--- a/build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs
+++ b/build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs
@@ -48,12 +48,14 @@ protected override async Task Execute (Context context)
return new List {
Get_MonoGitHash_props (context),
Get_Configuration_Generated_Props (context),
+ Get_Cmake_XA_Build_Configuration (context),
new GeneratedMonodroidCmakeFiles (Configurables.Paths.BuildBinDir),
};
} else {
return new List {
Get_Configuration_OperatingSystem_props (context),
Get_Configuration_Generated_Props (context),
+ Get_Cmake_XA_Build_Configuration (context),
new GeneratedMonodroidCmakeFiles (Configurables.Paths.BuildBinDir),
Get_Ndk_projitems (context),
Get_XABuildConfig_cs (context),
@@ -81,12 +83,30 @@ protected override async Task Execute (Context context)
partial void AddUnixPostBuildSteps (Context context, List steps);
partial void AddOSSpecificSteps (Context context, List steps);
+ GeneratedFile Get_Cmake_XA_Build_Configuration (Context context)
+ {
+ const string OutputFileName = "xa_build_configuration.cmake";
+
+ var replacements = new Dictionary (StringComparer.Ordinal) {
+ { "@NETCORE_APP_RUNTIME_ANDROID_ARM@", Utilities.EscapePathSeparators (Configurables.Paths.NetcoreAppRuntimeAndroidARM) },
+ { "@NETCORE_APP_RUNTIME_ANDROID_ARM64@", Utilities.EscapePathSeparators (Configurables.Paths.NetcoreAppRuntimeAndroidARM64) },
+ { "@NETCORE_APP_RUNTIME_ANDROID_X86@", Utilities.EscapePathSeparators (Configurables.Paths.NetcoreAppRuntimeAndroidX86) },
+ { "@NETCORE_APP_RUNTIME_ANDROID_X86_64@", Utilities.EscapePathSeparators (Configurables.Paths.NetcoreAppRuntimeAndroidX86_64) },
+ };
+
+ return new GeneratedPlaceholdersFile (
+ replacements,
+ Path.Combine (Configurables.Paths.BuildToolsScriptsDir, $"{OutputFileName}.in"),
+ Path.Combine (Configurables.Paths.BuildBinDir, OutputFileName)
+ );
+ }
+
GeneratedFile Get_Configuration_Generated_Props (Context context)
{
const string OutputFileName = "Configuration.Generated.props";
var replacements = new Dictionary (StringComparer.Ordinal) {
- { "@XA_PACKAGES_DIR@", Configurables.Paths.XAPackagesDir },
+ { "@XA_PACKAGES_DIR@", Configurables.Paths.XAPackagesDir },
};
return new GeneratedPlaceholdersFile (
@@ -162,9 +182,13 @@ GeneratedFile Get_Ndk_projitems (Context context)
var replacements = new Dictionary (StringComparer.Ordinal) {
{ "@NDK_RELEASE@", BuildAndroidPlatforms.AndroidNdkVersion },
{ "@NDK_ARMEABI_V7_API@", BuildAndroidPlatforms.NdkMinimumAPI [AbiNames.TargetJit.AndroidArmV7a].ToString () },
+ { "@NDK_ARMEABI_V7_API_NET6@", BuildAndroidPlatforms.NdkMinimumAPI [BuildAndroidPlatforms.AndroidArmV7a_NET6].ToString () },
{ "@NDK_ARM64_V8A_API@", BuildAndroidPlatforms.NdkMinimumAPI [AbiNames.TargetJit.AndroidArmV8a].ToString () },
+ { "@NDK_ARM64_V8A_API_NET6@", BuildAndroidPlatforms.NdkMinimumAPI [BuildAndroidPlatforms.AndroidArmV8a_NET6].ToString () },
{ "@NDK_X86_API@", BuildAndroidPlatforms.NdkMinimumAPI [AbiNames.TargetJit.AndroidX86].ToString () },
+ { "@NDK_X86_API_NET6@", BuildAndroidPlatforms.NdkMinimumAPI [BuildAndroidPlatforms.AndroidX86_NET6].ToString () },
{ "@NDK_X86_64_API@", BuildAndroidPlatforms.NdkMinimumAPI [AbiNames.TargetJit.AndroidX86_64].ToString () },
+ { "@NDK_X86_64_API_NET6@", BuildAndroidPlatforms.NdkMinimumAPI [BuildAndroidPlatforms.AndroidX86_64_NET6].ToString () },
};
return new GeneratedPlaceholdersFile (
diff --git a/build-tools/xaprepare/xaprepare/ThirdPartyNotices/bionic.cs b/build-tools/xaprepare/xaprepare/ThirdPartyNotices/bionic.cs
new file mode 100644
index 00000000000..fcc87a3ae7b
--- /dev/null
+++ b/build-tools/xaprepare/xaprepare/ThirdPartyNotices/bionic.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace Xamarin.Android.Prepare
+{
+ [TPN]
+ class google_bionic_TPN : ThirdPartyNotice
+ {
+ static readonly Uri url = new Uri ("https://android.googlesource.com/platform/bionic/");
+
+ public override string LicenseFile => String.Empty;
+ public override string Name => "google/bionic";
+ public override Uri SourceUrl => url;
+ public override string LicenseText => @"
+Copyright (C) 2006 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the ""License"");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an ""AS IS"" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+";
+
+ public override bool Include (bool includeExternalDeps, bool includeBuildDeps) => includeExternalDeps;
+ }
+}
diff --git a/build-tools/xaprepare/xaprepare/ThirdPartyNotices/robin-map.cs b/build-tools/xaprepare/xaprepare/ThirdPartyNotices/robin-map.cs
new file mode 100644
index 00000000000..560f8d62cdb
--- /dev/null
+++ b/build-tools/xaprepare/xaprepare/ThirdPartyNotices/robin-map.cs
@@ -0,0 +1,19 @@
+using System;
+using System.IO;
+
+namespace Xamarin.Android.Prepare
+{
+ [TPN]
+ class tessil_robin_map_TPN : ThirdPartyNotice
+ {
+ static readonly Uri url = new Uri ("https://github.com/Tessil/robin-map");
+ static readonly string licenseFile = Path.Combine (Configurables.Paths.ExternalDir, "robin-map", "LICENSE");
+
+ public override string LicenseFile => licenseFile;
+ public override string Name => "tessil/robin-map";
+ public override Uri SourceUrl => url;
+ public override string LicenseText => String.Empty;
+
+ public override bool Include (bool includeExternalDeps, bool includeBuildDeps) => includeBuildDeps;
+ }
+}
diff --git a/build-tools/xaprepare/xaprepare/xaprepare.csproj b/build-tools/xaprepare/xaprepare/xaprepare.csproj
index 1e95fdd4157..0c13e86bbc6 100644
--- a/build-tools/xaprepare/xaprepare/xaprepare.csproj
+++ b/build-tools/xaprepare/xaprepare/xaprepare.csproj
@@ -60,4 +60,10 @@
+
+
+
+
+
+
diff --git a/external/robin-map b/external/robin-map
new file mode 160000
index 00000000000..a603419b9a0
--- /dev/null
+++ b/external/robin-map
@@ -0,0 +1 @@
+Subproject commit a603419b9a0687c9148e02c8bd5e3db180bb9ac0
diff --git a/src-ThirdParty/bionic/bionic_futex.hh b/src-ThirdParty/bionic/bionic_futex.hh
new file mode 100644
index 00000000000..094ec5028ff
--- /dev/null
+++ b/src-ThirdParty/bionic/bionic_futex.hh
@@ -0,0 +1,84 @@
+/*
+ * Ported to Xamarin.Android from: https://android.googlesource.com/platform/bionic/+/refs/tags/android-11.0.0_r31/libc/private/bionic_futex.h
+ */
+
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _BIONIC_FUTEX_H
+#define _BIONIC_FUTEX_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct timespec;
+
+static inline __always_inline long __futex(volatile void* ftx, int op, int value,
+ const timespec* timeout, int bitset) {
+ // Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to.
+ int saved_errno = errno;
+ long result = syscall(__NR_futex, ftx, op, value, timeout, NULL, bitset);
+ if (__predict_false(result == -1)) {
+ result = -errno;
+ errno = saved_errno;
+ }
+ return result;
+}
+
+static inline long __futex_wake(volatile void* ftx, int count) {
+ return __futex(ftx, FUTEX_WAKE, count, nullptr, 0);
+}
+
+static inline long __futex_wake_ex(volatile void* ftx, bool shared, int count) {
+ return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, nullptr, 0);
+}
+
+static inline long __futex_wait(volatile void* ftx, int value, const timespec* timeout) {
+ return __futex(ftx, FUTEX_WAIT, value, timeout, 0);
+}
+
+static inline long __futex_wait_ex(volatile void* ftx, bool shared, int value) {
+ return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE), value, nullptr,
+ static_cast(FUTEX_BITSET_MATCH_ANY));
+}
+
+__LIBC_HIDDEN__ long __futex_wait_ex(volatile void* ftx, bool shared, int value,
+ bool use_realtime_clock, const timespec* abs_timeout);
+
+static inline long __futex_pi_unlock(volatile void* ftx, bool shared) {
+ return __futex(ftx, shared ? FUTEX_UNLOCK_PI : FUTEX_UNLOCK_PI_PRIVATE, 0, nullptr, 0);
+}
+
+__LIBC_HIDDEN__ long __futex_pi_lock_ex(volatile void* ftx, bool shared, bool use_realtime_clock,
+ const timespec* abs_timeout);
+
+#endif /* _BIONIC_FUTEX_H */
diff --git a/src-ThirdParty/bionic/cxa_guard.cc b/src-ThirdParty/bionic/cxa_guard.cc
new file mode 100644
index 00000000000..099d8f476eb
--- /dev/null
+++ b/src-ThirdParty/bionic/cxa_guard.cc
@@ -0,0 +1,130 @@
+//
+// Ported to Xamarin.Android from: https://android.googlesource.com/platform/bionic/+/refs/tags/android-11.0.0_r31/libc/bionic/__cxa_guard.cpp
+//
+
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+#include
+#include
+
+#include "bionic_futex.hh"
+
+// This file contains C++ ABI support functions for one time
+// constructors as defined in the "Run-time ABI for the ARM Architecture"
+// section 4.4.2
+//
+// ARM C++ ABI and Itanium/x86 C++ ABI has different definition for
+// one time construction:
+//
+// ARM C++ ABI defines the LSB of guard variable should be tested
+// by compiler-generated code before calling __cxa_guard_acquire et al.
+//
+// The Itanium/x86 C++ ABI defines the low-order _byte_ should be
+// tested instead.
+//
+// Meanwhile, guard variable are 32bit aligned for ARM, and 64bit
+// aligned for x86.
+//
+// Reference documentation:
+//
+// section 3.2.3 of ARM IHI 0041C (for ARM)
+// section 3.3.2 of the Itanium C++ ABI specification v1.83 (for x86).
+//
+// There is no C++ ABI available for other ARCH. But the gcc source
+// shows all other ARCH follow the definition of Itanium/x86 C++ ABI.
+
+#if defined(__arm__)
+// The ARM C++ ABI mandates that guard variables are 32-bit aligned, 32-bit
+// values. The LSB is tested by the compiler-generated code before calling
+// __cxa_guard_acquire.
+union _guard_t {
+ atomic_int state;
+ int32_t aligner;
+};
+
+#else
+// The Itanium/x86 C++ ABI (used by all other architectures) mandates that
+// guard variables are 64-bit aligned, 64-bit values. The LSB is tested by
+// the compiler-generated code before calling __cxa_guard_acquire.
+union _guard_t {
+ atomic_int state;
+ int64_t aligner;
+};
+
+#endif
+
+// Set construction state values according to reference documentation.
+// 0 is the initialization value.
+// Arm requires ((*gv & 1) == 1) after __cxa_guard_release, ((*gv & 3) == 0) after __cxa_guard_abort.
+// X86 requires first byte not modified by __cxa_guard_acquire, first byte is non-zero after
+// __cxa_guard_release.
+
+#define CONSTRUCTION_NOT_YET_STARTED 0
+#define CONSTRUCTION_COMPLETE 1
+#define CONSTRUCTION_UNDERWAY_WITHOUT_WAITER 0x100
+#define CONSTRUCTION_UNDERWAY_WITH_WAITER 0x200
+
+extern "C" int __cxa_guard_acquire(_guard_t* gv) {
+ int old_value = atomic_load_explicit(&gv->state, memory_order_acquire);
+ // In the common CONSTRUCTION_COMPLETE case we have to ensure that all the stores performed by
+ // the construction function are observable on this CPU after we exit. A similar constraint may
+ // apply in the CONSTRUCTION_NOT_YET_STARTED case with a prior abort.
+
+ while (true) {
+ if (old_value == CONSTRUCTION_COMPLETE) {
+ return 0;
+ } else if (old_value == CONSTRUCTION_NOT_YET_STARTED) {
+ if (!atomic_compare_exchange_weak_explicit(&gv->state, &old_value,
+ CONSTRUCTION_UNDERWAY_WITHOUT_WAITER,
+ memory_order_acquire /* or relaxed in C++17 */,
+ memory_order_acquire)) {
+ continue;
+ }
+ return 1;
+ } else if (old_value == CONSTRUCTION_UNDERWAY_WITHOUT_WAITER) {
+ if (!atomic_compare_exchange_weak_explicit(&gv->state, &old_value,
+ CONSTRUCTION_UNDERWAY_WITH_WAITER,
+ memory_order_acquire /* or relaxed in C++17 */,
+ memory_order_acquire)) {
+ continue;
+ }
+ }
+
+ __futex_wait_ex(&gv->state, false, CONSTRUCTION_UNDERWAY_WITH_WAITER);
+ old_value = atomic_load_explicit(&gv->state, memory_order_acquire);
+ }
+}
+
+extern "C" void __cxa_guard_release(_guard_t* gv) {
+ // Release fence is used to make all stores performed by the construction function
+ // visible in other threads.
+ int old_value = atomic_exchange_explicit(&gv->state, CONSTRUCTION_COMPLETE, memory_order_release);
+ if (old_value == CONSTRUCTION_UNDERWAY_WITH_WAITER) {
+ __futex_wake_ex(&gv->state, false, INT_MAX);
+ }
+}
+
+extern "C" void __cxa_guard_abort(_guard_t* gv) {
+ // Release fence is used to make all stores performed by the construction function
+ // visible in other threads.
+ int old_value = atomic_exchange_explicit(&gv->state, CONSTRUCTION_NOT_YET_STARTED, memory_order_release);
+ if (old_value == CONSTRUCTION_UNDERWAY_WITH_WAITER) {
+ __futex_wake_ex(&gv->state, false, INT_MAX);
+ }
+}
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.NET.Workload.Android/WorkloadManifest.in.json b/src/Xamarin.Android.Build.Tasks/Microsoft.NET.Workload.Android/WorkloadManifest.in.json
index e856c4e1dc1..e74c9547d6e 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.NET.Workload.Android/WorkloadManifest.in.json
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.NET.Workload.Android/WorkloadManifest.in.json
@@ -17,7 +17,8 @@
"version": "@SDK_PACK_VERSION@",
"alias-to": {
"osx-x64": "Microsoft.Android.Sdk.osx-x64",
- "win-x64": "Microsoft.Android.Sdk.win-x64"
+ "win-x64": "Microsoft.Android.Sdk.win-x64",
+ "linux-x64": "Microsoft.Android.Sdk.linux-x64"
}
},
"Microsoft.Android.Sdk.BundleTool": {
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs
index e5bdd637424..06258e10dab 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs
@@ -17,6 +17,8 @@ public class Builder : IDisposable
const string SigSegvError = "Got a SIGSEGV while executing native code";
const string ConsoleLoggerError = "[ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: is negative";
+ string Arm32AbiDir => UseDotNet ? "armeabi-v7a-net6" : "armeabi-v7a";
+
///
/// If true, use `dotnet build` and IShortFormProject throughout the tests
///
@@ -80,7 +82,7 @@ public string BuildOutputDirectory {
get {
var outdir = Environment.GetEnvironmentVariable ("XA_BUILD_OUTPUT_PATH");
string configuration = Environment.GetEnvironmentVariable ("CONFIGURATION") ?? XABuildPaths.Configuration;
- var libmonodroidPath = Path.Combine ("lib", "xamarin.android", "xbuild", "Xamarin", "Android", "lib", "armeabi-v7a", "libmono-android.release.so");
+ var libmonodroidPath = Path.Combine ("lib", "xamarin.android", "xbuild", "Xamarin", "Android", "lib", Arm32AbiDir, "libmono-android.release.so");
if (String.IsNullOrEmpty(outdir))
outdir = Path.GetFullPath (Path.Combine (Root, "..", "..", "..", "..", "..", "..", "..", "out"));
if (!Directory.Exists (Path.Combine (outdir, "lib")) || !File.Exists (Path.Combine (outdir, libmonodroidPath)))
@@ -105,7 +107,7 @@ public string BuildOutputDirectory {
public string AndroidMSBuildDirectory {
get {
var msbuildDir = Path.Combine (BuildOutputDirectory, "lib", "xamarin.android", "xbuild", "Xamarin", "Android");
- if (Directory.Exists (msbuildDir) && File.Exists (Path.Combine (msbuildDir, "lib", "armeabi-v7a", "libmono-android.release.so")))
+ if (Directory.Exists (msbuildDir) && File.Exists (Path.Combine (msbuildDir, "lib", Arm32AbiDir, "libmono-android.release.so")))
return msbuildDir;
return TestEnvironment.MonoAndroidToolsDirectory;
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
index 491562ff420..53bfeee4bb3 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@@ -1261,8 +1261,11 @@ because xbuild doesn't support framework reference assemblies.
- <_RuntimeJar>$(MSBuildThisFileDirectory)\java_runtime.jar
- <_RuntimeDex>$(MSBuildThisFileDirectory)\java_runtime.dex
+ <_RuntimeJar Condition=" '$(UsingAndroidNETSdk)' != 'True' ">$(MSBuildThisFileDirectory)\java_runtime.jar
+ <_RuntimeDex Condition=" '$(UsingAndroidNETSdk)' != 'True' ">$(MSBuildThisFileDirectory)\java_runtime.dex
+
+ <_RuntimeJar Condition=" '$(UsingAndroidNETSdk)' == 'True' ">$(MSBuildThisFileDirectory)\java_runtime_net6.jar
+ <_RuntimeDex Condition=" '$(UsingAndroidNETSdk)' == 'True' ">$(MSBuildThisFileDirectory)\java_runtime_net6.dex
diff --git a/src/java-runtime/java-runtime.targets b/src/java-runtime/java-runtime.targets
index 99cb0d31c05..0f17932c4d7 100644
--- a/src/java-runtime/java-runtime.targets
+++ b/src/java-runtime/java-runtime.targets
@@ -7,14 +7,29 @@
$(OutputPath)java_runtime.dex
$(IntermediateOutputPath)release
$(IntermediateOutputPath)release.txt
- ..\..\src-ThirdParty\bazel\java\mono\android\debug\MultiDexLoader.java;java\mono\android\debug\BuildConfig.java
+ ..\..\src-ThirdParty\bazel\java\mono\android\debug\MultiDexLoader.java;java\mono\android\debug\BuildConfig.java;java\mono\android\debug-net6\BuildConfig.java;java\mono\android\release-net6\BuildConfig.java
<_RuntimeOutput Include="$(OutputPath)java_runtime_fastdev.jar">
$(OutputPath)java_runtime_fastdev.jar
$(OutputPath)java_runtime_fastdev.dex
$(IntermediateOutputPath)fastdev
$(IntermediateOutputPath)fastdev.txt
- ..\..\src-ThirdParty\bazel\java\mono\android\release\MultiDexLoader.java;java\mono\android\release\BuildConfig.java
+ ..\..\src-ThirdParty\bazel\java\mono\android\release\MultiDexLoader.java;java\mono\android\release\BuildConfig.java;java\mono\android\release-net6\BuildConfig.java;java\mono\android\debug-net6\BuildConfig.java
+
+
+ <_RuntimeOutput Include="$(OutputPath)java_runtime_net6.jar">
+ $(OutputPath)java_runtime_net6.jar
+ $(OutputPath)java_runtime_net6.dex
+ $(IntermediateOutputPath)release-net6
+ $(IntermediateOutputPath)release-net6.txt
+ ..\..\src-ThirdParty\bazel\java\mono\android\debug\MultiDexLoader.java;java\mono\android\debug-net6\BuildConfig.java;java\mono\android\debug\BuildConfig.java;java\mono\android\release\BuildConfig.java
+
+ <_RuntimeOutput Include="$(OutputPath)java_runtime_fastdev_net6.jar">
+ $(OutputPath)java_runtime_fastdev_net6.jar
+ $(OutputPath)java_runtime_fastdev_net6.dex
+ $(IntermediateOutputPath)fastdev-net6
+ $(IntermediateOutputPath)fastdev-net6.txt
+ ..\..\src-ThirdParty\bazel\java\mono\android\release\MultiDexLoader.java;java\mono\android\release-net6\BuildConfig.java;java\mono\android\release\BuildConfig.java;java\mono\android\debug\BuildConfig.java
diff --git a/src/java-runtime/java/mono/android/MonoPackageManager.java b/src/java-runtime/java/mono/android/MonoPackageManager.java
index 96048d65c12..52451489f33 100644
--- a/src/java-runtime/java/mono/android/MonoPackageManager.java
+++ b/src/java-runtime/java/mono/android/MonoPackageManager.java
@@ -79,13 +79,9 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack
}
System.loadLibrary("xamarin-app");
- // .net5+ APKs don't contain `libmono-native.so` but we can't just perform a file existence check
- // because we might be running with embedded DSOs enabled in which case the check would fail and we
- // would have to catch the exception anyway in this case.
- try {
+ if (!BuildConfig.DotNetRuntime) {
+ // .net5+ APKs don't contain `libmono-native.so`
System.loadLibrary("mono-native");
- } catch (java.lang.UnsatisfiedLinkError ex) {
- Log.i ("monodroid", "Failed to preload libmono-native.so (may not exist), ignoring", ex);
}
System.loadLibrary("monodroid");
diff --git a/src/java-runtime/java/mono/android/debug-net6/BuildConfig.java b/src/java-runtime/java/mono/android/debug-net6/BuildConfig.java
new file mode 100644
index 00000000000..e05ba068714
--- /dev/null
+++ b/src/java-runtime/java/mono/android/debug-net6/BuildConfig.java
@@ -0,0 +1,6 @@
+package mono.android;
+
+public class BuildConfig {
+ public static boolean Debug = true;
+ public static boolean DotNetRuntime = true;
+}
diff --git a/src/java-runtime/java/mono/android/debug/BuildConfig.java b/src/java-runtime/java/mono/android/debug/BuildConfig.java
index 198c2d10df9..575b166ca60 100644
--- a/src/java-runtime/java/mono/android/debug/BuildConfig.java
+++ b/src/java-runtime/java/mono/android/debug/BuildConfig.java
@@ -2,4 +2,5 @@
public class BuildConfig {
public static boolean Debug = true;
+ public static boolean DotNetRuntime = false;
}
diff --git a/src/java-runtime/java/mono/android/release-net6/BuildConfig.java b/src/java-runtime/java/mono/android/release-net6/BuildConfig.java
new file mode 100644
index 00000000000..498a947ff8c
--- /dev/null
+++ b/src/java-runtime/java/mono/android/release-net6/BuildConfig.java
@@ -0,0 +1,6 @@
+package mono.android;
+
+public class BuildConfig {
+ public static boolean Debug = false;
+ public static boolean DotNetRuntime = true;
+}
diff --git a/src/java-runtime/java/mono/android/release/BuildConfig.java b/src/java-runtime/java/mono/android/release/BuildConfig.java
index e709a143496..4070a147bb1 100644
--- a/src/java-runtime/java/mono/android/release/BuildConfig.java
+++ b/src/java-runtime/java/mono/android/release/BuildConfig.java
@@ -2,4 +2,5 @@
public class BuildConfig {
public static boolean Debug = false;
+ public static boolean DotNetRuntime = false;
}
diff --git a/src/monodroid/CMakeLists.txt b/src/monodroid/CMakeLists.txt
index 8b9c6f2bd60..b3d75cd85a1 100644
--- a/src/monodroid/CMakeLists.txt
+++ b/src/monodroid/CMakeLists.txt
@@ -22,6 +22,7 @@ set(CMAKE_C_EXTENSIONS OFF)
option(ENABLE_CLANG_ASAN "Enable the clang AddressSanitizer support" OFF)
option(ENABLE_CLANG_UBSAN "Enable the clang UndefinedBehaviorSanitizer support" OFF)
+option(ENABLE_NET6 "Enable compilation for .NET6" OFF)
option(ENABLE_TIMING "Build with timing support" OFF)
option(STRIP_DEBUG "Strip debugging information when linking" ON)
option(DISABLE_DEBUG "Disable the built-in debugging code" OFF)
@@ -32,6 +33,14 @@ else()
set(DEBUG_BUILD False)
endif()
+if(ANDROID)
+ if(ANDROID_STL STREQUAL none)
+ set(USES_LIBSTDCPP False)
+ else()
+ set(USES_LIBSTDCPP True)
+ endif()
+endif()
+
# Environment checks
if(NOT DEFINED MONO_PATH)
@@ -106,11 +115,13 @@ endif()
set(EXTERNAL_DIR "../../external")
set(JAVA_INTEROP_SRC_PATH "${EXTERNAL_DIR}/Java.Interop/src/java-interop")
set(SOURCES_DIR ${CMAKE_SOURCE_DIR}/jni)
+set(BIONIC_SOURCES_DIR "../../src-ThirdParty/bionic")
set(LZ4_SRC_DIR "${EXTERNAL_DIR}/lz4/lib")
set(LZ4_INCLUDE_DIR ${LZ4_SRC_DIR})
set(XA_BIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/${XA_BUILD_CONFIGURATION}")
set(XA_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/Build${XA_BUILD_CONFIGURATION}")
set(XA_LIB_TOP_DIR "${XA_BIN_DIR}/lib/xamarin.android/xbuild/Xamarin/Android/lib")
+set(ROBIN_MAP_DIR "${EXTERNAL_DIR}/robin-map")
if(NOT ANDROID)
if(WIN32 OR MINGW)
@@ -130,12 +141,29 @@ if(NOT ANDROID)
endif()
endif()
+include("${XA_BUILD_DIR}/xa_build_configuration.cmake")
+
+if(ENABLE_NET6)
+ if(ANDROID_ABI MATCHES "^arm64-v8a")
+ set(NET6_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM64}")
+ elseif(ANDROID_ABI MATCHES "^armeabi-v7a")
+ set(NET6_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM}")
+ elseif(ANDROID_ABI MATCHES "^x86_64")
+ set(NET6_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86_64}")
+ elseif(ANDROID_ABI MATCHES "^x86")
+ set(NET6_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86}")
+ else()
+ message(FATAL "${ANDROID_ABI} is not supported for .NET6 builds")
+ endif()
+endif()
+
set(LZ4_SOURCES
"${LZ4_SRC_DIR}/lz4.c"
)
# Include directories
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/ ${CMAKE_SOURCE_DIR}/include)
+include_directories(${ROBIN_MAP_DIR}/include)
if(NOT ANDROID)
string(REPLACE " " ";" JDK_INCLUDE_LIST ${JDK_INCLUDE})
@@ -176,7 +204,12 @@ if (WIN32)
include_directories(BEFORE "jni/win32")
endif()
-include_directories("${XA_BIN_DIR}/include/mono-2.0")
+if(ENABLE_NET6)
+ include_directories("${NET6_RUNTIME_DIR}/native/include/mono-2.0")
+else()
+ include_directories("${XA_BIN_DIR}/include/mono-2.0")
+endif()
+
include_directories("jni")
include_directories("${XA_BIN_DIR}/include")
include_directories("${XA_BIN_DIR}/include/${ANDROID_ABI}/eglib")
@@ -196,11 +229,17 @@ xa_macos_prepare_arm64()
# Compiler defines
-add_compile_definitions(DHAVE_CONFIG_H)
+add_compile_definitions(TSL_NO_EXCEPTIONS)
+add_compile_definitions(HAVE_CONFIG_H)
add_compile_definitions(_REENTRANT)
add_compile_definitions(JI_DLL_EXPORT)
add_compile_definitions(MONO_DLL_EXPORT)
+if(ENABLE_NET6)
+ add_compile_definitions(NET6)
+ add_compile_definitions(JI_NO_VISIBILITY)
+endif()
+
if(DEBUG_BUILD AND NOT DISABLE_DEBUG)
add_compile_definitions(DEBUG)
endif()
@@ -341,8 +380,13 @@ endif()
# Library directories
if(ANDROID)
- set(XA_LIBRARY_OUTPUT_DIRECTORY "${XA_LIB_TOP_DIR}/${ANDROID_ABI}")
- link_directories("${XA_LIBRARY_OUTPUT_DIRECTORY}")
+ if(ENABLE_NET6)
+ set(XA_LIBRARY_OUTPUT_DIRECTORY "${XA_LIB_TOP_DIR}/${ANDROID_ABI}-net6")
+ link_directories("${NET6_RUNTIME_DIR}/native")
+ else()
+ set(XA_LIBRARY_OUTPUT_DIRECTORY "${XA_LIB_TOP_DIR}/${ANDROID_ABI}")
+ link_directories("${XA_LIBRARY_OUTPUT_DIRECTORY}")
+ endif()
endif()
if(WIN32 OR MINGW)
@@ -399,7 +443,6 @@ set(XAMARIN_MONODROID_SOURCES
${SOURCES_DIR}/globals.cc
${SOURCES_DIR}/logger.cc
${SOURCES_DIR}/monodroid-glue.cc
- ${SOURCES_DIR}/xa-internal-api.cc
${SOURCES_DIR}/osbridge.cc
${SOURCES_DIR}/shared-constants.cc
${SOURCES_DIR}/timezones.cc
@@ -414,9 +457,18 @@ if(ANDROID)
list(APPEND XAMARIN_MONODROID_SOURCES
${LZ4_SOURCES}
)
+
+ if(NOT USES_LIBSTDCPP)
+ list(APPEND XAMARIN_MONODROID_SOURCES
+ ${BIONIC_SOURCES_DIR}/cxa_guard.cc
+ ${SOURCES_DIR}/cxx-abi/string.cc
+ ${SOURCES_DIR}/cxx-abi/terminate.cc
+ )
+ endif()
else()
list(APPEND XAMARIN_MONODROID_SOURCES
${SOURCES_DIR}/designer-assemblies.cc
+ ${SOURCES_DIR}/monodroid-glue-designer.cc
${JAVA_INTEROP_SRC_PATH}/java-interop-gc-bridge-mono.cc
${JAVA_INTEROP_SRC_PATH}/java-interop-jvm.cc
)
@@ -429,11 +481,23 @@ if(UNIX)
)
endif()
-set(XAMARIN_INTERNAL_API_SOURCES
- ${SOURCES_DIR}/jni.c
- ${SOURCES_DIR}/internal-pinvoke-api.cc
- ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc
- )
+if(ANDROID AND ENABLE_NET6)
+ list(APPEND XAMARIN_MONODROID_SOURCES
+ ${SOURCES_DIR}/pinvoke-override-api.cc
+ ${SOURCES_DIR}/java_interop_api.c
+ ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc
+ )
+else()
+ list(APPEND XAMARIN_MONODROID_SOURCES
+ ${SOURCES_DIR}/xa-internal-api.cc
+ )
+
+ set(XAMARIN_INTERNAL_API_SOURCES
+ ${SOURCES_DIR}/java_interop_api.c
+ ${SOURCES_DIR}/internal-pinvoke-api.cc
+ ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc
+ )
+endif()
set(XAMARIN_APP_STUB_SOURCES
${SOURCES_DIR}/application_dso_stub.cc
@@ -451,21 +515,23 @@ set(XAMARIN_DEBUG_APP_HELPER_SOURCES
# Build
configure_file(jni/host-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/host-config.h)
-add_library(
- ${XAMARIN_INTERNAL_API_LIB}
- SHARED
- ${XAMARIN_INTERNAL_API_SOURCES}
- )
+if(NOT (ANDROID AND ENABLE_NET6))
+ add_library(
+ ${XAMARIN_INTERNAL_API_LIB}
+ SHARED
+ ${XAMARIN_INTERNAL_API_SOURCES}
+ )
-target_compile_options(
- ${XAMARIN_INTERNAL_API_LIB}
- PRIVATE -fvisibility=default
- )
+ target_compile_options(
+ ${XAMARIN_INTERNAL_API_LIB}
+ PRIVATE -fvisibility=default
+ )
-target_link_options(
- ${XAMARIN_INTERNAL_API_LIB}
- PRIVATE -fvisibility=default
- )
+ target_link_options(
+ ${XAMARIN_INTERNAL_API_LIB}
+ PRIVATE -fvisibility=default
+ )
+endif()
add_library(
${XAMARIN_APP_STUB_LIB}
diff --git a/src/monodroid/jni/cpu-arch.hh b/src/monodroid/jni/cpu-arch.hh
index 5d66b8a959a..9be5d356e5c 100644
--- a/src/monodroid/jni/cpu-arch.hh
+++ b/src/monodroid/jni/cpu-arch.hh
@@ -10,5 +10,8 @@
#define CPU_KIND_X86 ((unsigned short)4)
#define CPU_KIND_X86_64 ((unsigned short)5)
-MONO_API void _monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit);
-#endif
+#if !defined(NET6)
+MONO_API
+#endif // def NET6
+void _monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit);
+#endif // ndef NET6
diff --git a/src/monodroid/jni/cxx-abi/string.cc b/src/monodroid/jni/cxx-abi/string.cc
new file mode 100644
index 00000000000..53b5731defc
--- /dev/null
+++ b/src/monodroid/jni/cxx-abi/string.cc
@@ -0,0 +1,13 @@
+//
+// Defining the macro will make the the explicit instantations below truely hidden
+//
+#define _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
+
+#include
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template class __attribute__ ((__visibility__("hidden"))) __basic_string_common;
+template class __attribute__ ((__visibility__("hidden"))) basic_string;
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/src/monodroid/jni/cxx-abi/terminate.cc b/src/monodroid/jni/cxx-abi/terminate.cc
new file mode 100644
index 00000000000..624274a30d8
--- /dev/null
+++ b/src/monodroid/jni/cxx-abi/terminate.cc
@@ -0,0 +1,17 @@
+//
+// Simple implementation of std::terminate() for Xamarin.Android
+//
+// Does NOT support terminate handlers, since we don't use them.
+//
+#include
+#include
+#include
+
+namespace std {
+ [[noreturn]] void
+ terminate () noexcept
+ {
+ __android_log_write (ANDROID_LOG_FATAL, "monodroid", "std::terminate() called. Aborting.");
+ abort ();
+ }
+}
diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/monodroid/jni/embedded-assemblies.cc
index 845272eda90..c526ad5b18f 100644
--- a/src/monodroid/jni/embedded-assemblies.cc
+++ b/src/monodroid/jni/embedded-assemblies.cc
@@ -133,8 +133,20 @@ EmbeddedAssemblies::get_assembly_data (const MonoBundledAssembly *e, char*& asse
}
MonoAssembly*
+#if defined (NET6) && defined (NET6_ALC_WORKS)
+EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, MonoAssemblyLoadContextGCHandle alc_gchandle, MonoError *error)
+#else // !(def NET6 && def NET6_ALC_WORKS)
EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, bool ref_only)
+#endif // def NET6 && def NET6_ALC_WORKS
{
+#if defined (NET6)
+ // NET6 doesn't support reference-only loads, define the variable here to minimize ifdefs in the code below
+#if defined (NET6_ALC_WORKS)
+ constexpr bool ref_only = false;
+#else // def NET6_ALC_WORKS
+ ref_only = false;
+#endif // ndef NET6_ALC_WORKS
+#endif // def NET6
const char *culture = mono_assembly_name_get_culture (aname);
const char *asmname = mono_assembly_name_get_name (aname);
@@ -176,19 +188,51 @@ EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, bool ref_only)
get_assembly_data (e, assembly_data, assembly_data_size);
- if ((image = mono_image_open_from_data_with_name (assembly_data, assembly_data_size, 0, nullptr, ref_only, name.get ())) != nullptr &&
- (a = mono_assembly_load_from_full (image, name.get (), &status, ref_only)) != nullptr) {
- mono_config_for_assembly (image);
- break;
+#if defined (NET6) && defined (NET6_ALC_WORKS)
+ image = mono_image_open_from_data_alc (
+ alc_gchandle,
+ assembly_data,
+ assembly_data_size,
+ 0 /* need_copy */,
+ nullptr /* status */,
+ name.get ()
+ );
+#else // (def NET6 && def NET6_ALC_WORKS)
+ image = mono_image_open_from_data_with_name (assembly_data, assembly_data_size, 0, nullptr, ref_only, name.get ());
+#endif // !(def NET6 && def NET6_ALC_WORKS)
+ if (image == nullptr) {
+ continue;
+ }
+
+ a = mono_assembly_load_from_full (image, name.get (), &status, ref_only);
+ if (a == nullptr) {
+ continue;
}
+
+ mono_config_for_assembly (image);
+ break;
}
- if (a && utils.should_log (LOG_ASSEMBLY)) {
+ if (a != nullptr && utils.should_log (LOG_ASSEMBLY)) {
log_info_nocheck (LOG_ASSEMBLY, "open_from_bundles: loaded assembly: %p\n", a);
}
+
+#if defined (NET6) && defined (NET6_ALC_WORKS)
+ if (error != nullptr) {
+ error->error_code = a == nullptr ? MONO_ERROR_NONE : MONO_ERROR_FILE_NOT_FOUND;
+ }
+#endif // def NET6 && def NET6_ALC_WORKS
return a;
}
+#if defined (NET6) && defined (NET6_ALC_WORKS)
+MonoAssembly*
+EmbeddedAssemblies::open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, [[maybe_unused]] char **assemblies_path, [[maybe_unused]] void *user_data, MonoError *error)
+{
+ log_warn (LOG_DEFAULT, __PRETTY_FUNCTION__);
+ return embeddedAssemblies.open_from_bundles (aname, alc_gchandle, error);
+}
+#else // def NET6 && def NET6_ALC_WORKS
MonoAssembly*
EmbeddedAssemblies::open_from_bundles_full (MonoAssemblyName *aname, UNUSED_ARG char **assemblies_path, UNUSED_ARG void *user_data)
{
@@ -200,12 +244,23 @@ EmbeddedAssemblies::open_from_bundles_refonly (MonoAssemblyName *aname, UNUSED_A
{
return embeddedAssemblies.open_from_bundles (aname, true);
}
+#endif // !(def NET6 && def NET6_ALC_WORKS)
void
EmbeddedAssemblies::install_preload_hooks ()
{
+#if defined (NET6) && defined (NET6_ALC_WORKS)
+ mono_install_assembly_preload_hook_v3 (
+ open_from_bundles,
+ nullptr /* user_data */,
+ 0 /* append */
+ );
+#else // def NET6 && def NET6_ALC_WORKS
mono_install_assembly_preload_hook (open_from_bundles_full, nullptr);
+#if !defined (NET6) // Reference-only loads don't exist in NET6
mono_install_assembly_refonly_preload_hook (open_from_bundles_refonly, nullptr);
+#endif // !def NET6
+#endif // !(def NET6 && def NET6_ALC_WORKS)
}
template
diff --git a/src/monodroid/jni/embedded-assemblies.hh b/src/monodroid/jni/embedded-assemblies.hh
index 0eaaf8c9767..2ce875dbe1f 100644
--- a/src/monodroid/jni/embedded-assemblies.hh
+++ b/src/monodroid/jni/embedded-assemblies.hh
@@ -6,6 +6,10 @@
#include
#include
+#if defined (NET6)
+#include
+#endif
+
#include "strings.hh"
#include "xamarin-app.hh"
@@ -72,7 +76,11 @@ namespace xamarin::android::internal {
MonoReflectionType* typemap_java_to_managed (const char *java_type_name);
size_t register_from (const char *apk_file, monodroid_should_register should_register);
void gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register);
+#if defined (NET6) && defined (NET6_ALC_WORKS)
+ MonoAssembly* open_from_bundles (MonoAssemblyName* aname, MonoAssemblyLoadContextGCHandle alc_gchandle, MonoError *error);
+#else // def NET6 && def NET6_ALC_WORKS
MonoAssembly* open_from_bundles (MonoAssemblyName* aname, bool ref_only);
+#endif // !(def NET6 && def NET6_ALC_WORKS)
#if defined (DEBUG) || !defined (ANDROID)
template
bool typemap_read_header (int dir_fd, const char *file_type, const char *dir_path, const char *file_path, uint32_t expected_magic, H &header, size_t &file_size, int &fd);
@@ -86,9 +94,12 @@ namespace xamarin::android::internal {
bool register_debug_symbols_for_assembly (const char *entry_name, MonoBundledAssembly *assembly, const mono_byte *debug_contents, int debug_size);
static md_mmap_info md_mmap_apk_file (int fd, uint32_t offset, uint32_t size, const char* filename, const char* apk);
-
+#if defined (NET6) && defined (NET6_ALC_WORKS)
+ static MonoAssembly* open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, char **assemblies_path, void *user_data, MonoError *error);
+#else // def NET6 && def NET6_ALC_WORKS
static MonoAssembly* open_from_bundles_full (MonoAssemblyName *aname, char **assemblies_path, void *user_data);
static MonoAssembly* open_from_bundles_refonly (MonoAssemblyName *aname, char **assemblies_path, void *user_data);
+#endif // !(def NET6 && def NET6_ALC_WORKS)
static void get_assembly_data (const MonoBundledAssembly *e, char*& assembly_data, uint32_t& assembly_data_size);
void zip_load_entries (int fd, const char *apk_name, monodroid_should_register should_register);
@@ -132,5 +143,8 @@ namespace xamarin::android::internal {
};
}
+#if !defined (NET6)
MONO_API int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix);
+#endif // ndef NET6
+
#endif /* INC_MONODROID_EMBEDDED_ASSEMBLIES_H */
diff --git a/src/monodroid/jni/jni.c b/src/monodroid/jni/java_interop_api.c
similarity index 98%
rename from src/monodroid/jni/jni.c
rename to src/monodroid/jni/java_interop_api.c
index 111f401226f..c4602190919 100644
--- a/src/monodroid/jni/jni.c
+++ b/src/monodroid/jni/java_interop_api.c
@@ -1,35 +1,10 @@
/*
* Generated file; DO NOT EDIT!
*
- * To make changes, edit Java.Interop/tools/jnienv-gen and rerun
+ * To make changes, edit Java.Interop/build-tools/jnienv-gen and rerun
*/
-#include
-
-typedef jmethodID jstaticmethodID;
-typedef jfieldID jstaticfieldID;
-typedef jobject jglobal;
-
-/* VS 2010 and later have stdint.h */
-#if defined(_MSC_VER)
-
- #define JI_API_EXPORT __declspec(dllexport)
- #define JI_API_IMPORT __declspec(dllimport)
-
-#else /* defined(_MSC_VER */
-
- #define JI_API_EXPORT __attribute__ ((visibility ("default")))
- #define JI_API_IMPORT
-
-#endif /* !defined(_MSC_VER) */
-
-#if defined(JI_DLL_EXPORT)
- #define JI_API JI_API_EXPORT
-#elif defined(JI_DLL_IMPORT)
- #define JI_API JI_API_IMPORT
-#else /* !defined(JI_DLL_IMPORT) && !defined(JI_API_IMPORT) */
- #define JI_API
-#endif /* JI_DLL_EXPORT... */
+#include "java_interop_api.h"
JI_API jint
java_interop_jnienv_get_version (JNIEnv *env)
diff --git a/src/monodroid/jni/java_interop_api.h b/src/monodroid/jni/java_interop_api.h
new file mode 100644
index 00000000000..012c34a2948
--- /dev/null
+++ b/src/monodroid/jni/java_interop_api.h
@@ -0,0 +1,230 @@
+/*
+ * Generated file; DO NOT EDIT!
+ *
+ * To make changes, edit Java.Interop/build-tools/jnienv-gen and rerun
+ */
+
+#if !defined (__JAVA_INTEROP_NATIVE_H)
+#define __JAVA_INTEROP_NATIVE_H
+
+#include
+
+typedef jmethodID jstaticmethodID;
+typedef jfieldID jstaticfieldID;
+typedef jobject jglobal;
+
+#if !defined(JI_NO_VISIBILITY)
+ /* VS 2010 and later have stdint.h */
+ #if defined(_MSC_VER)
+
+ #define JI_API_EXPORT __declspec(dllexport)
+ #define JI_API_IMPORT __declspec(dllimport)
+
+ #else /* defined(_MSC_VER */
+
+ #define JI_API_EXPORT __attribute__ ((visibility ("default")))
+ #define JI_API_IMPORT
+
+ #endif /* !defined(_MSC_VER) */
+
+ #if defined(JI_DLL_EXPORT)
+ #define JI_API JI_API_EXPORT
+ #elif defined(JI_DLL_IMPORT)
+ #define JI_API JI_API_IMPORT
+ #else /* !defined(JI_DLL_IMPORT) && !defined(JI_API_IMPORT) */
+ #define JI_API
+ #endif /* JI_DLL_EXPORT... */
+#else // JI_NO_VISIBILITY
+ #define JI_API
+#endif // JI_NO_VISIBILITY
+
+JI_API jint java_interop_jnienv_get_version (JNIEnv *env);
+JI_API jclass java_interop_jnienv_define_class (JNIEnv *env, jthrowable *_thrown, const char* name, jobject loader, const jbyte* buffer, jsize bufferLength);
+JI_API jclass java_interop_jnienv_find_class (JNIEnv *env, jthrowable *_thrown, const char* classname);
+JI_API jobject java_interop_jnienv_to_reflected_method (JNIEnv *env, jthrowable *_thrown, jclass type, jmethodID method, jboolean isStatic);
+JI_API jclass java_interop_jnienv_get_superclass (JNIEnv *env, jclass type);
+JI_API jboolean java_interop_jnienv_is_assignable_from (JNIEnv *env, jclass class1, jclass class2);
+JI_API jobject java_interop_jnienv_to_reflected_field (JNIEnv *env, jthrowable *_thrown, jclass type, jfieldID field, jboolean isStatic);
+JI_API jint java_interop_jnienv_throw (JNIEnv *env, jthrowable toThrow);
+JI_API jint java_interop_jnienv_throw_new (JNIEnv *env, jclass type, const char* message);
+JI_API jthrowable java_interop_jnienv_exception_occurred (JNIEnv *env);
+JI_API void java_interop_jnienv_exception_describe (JNIEnv *env);
+JI_API void java_interop_jnienv_exception_clear (JNIEnv *env);
+JI_API void java_interop_jnienv_fatal_error (JNIEnv *env, const char* message);
+JI_API jint java_interop_jnienv_push_local_frame (JNIEnv *env, jint capacity);
+JI_API jobject java_interop_jnienv_pop_local_frame (JNIEnv *env, jobject result);
+JI_API jglobal java_interop_jnienv_new_global_ref (JNIEnv *env, jobject instance);
+JI_API void java_interop_jnienv_delete_global_ref (JNIEnv *env, jobject instance);
+JI_API void java_interop_jnienv_delete_local_ref (JNIEnv *env, jobject instance);
+JI_API jboolean java_interop_jnienv_is_same_object (JNIEnv *env, jobject object1, jobject object2);
+JI_API jobject java_interop_jnienv_new_local_ref (JNIEnv *env, jobject instance);
+JI_API jint java_interop_jnienv_ensure_local_capacity (JNIEnv *env, jint capacity);
+JI_API jobject java_interop_jnienv_alloc_object (JNIEnv *env, jthrowable *_thrown, jclass type);
+JI_API jobject java_interop_jnienv_new_object (JNIEnv *env, jthrowable *_thrown, jclass type, jmethodID method);
+JI_API jobject java_interop_jnienv_new_object_a (JNIEnv *env, jthrowable *_thrown, jclass type, jmethodID method, jvalue* args);
+JI_API jclass java_interop_jnienv_get_object_class (JNIEnv *env, jobject instance);
+JI_API jboolean java_interop_jnienv_is_instance_of (JNIEnv *env, jobject instance, jclass type);
+JI_API jmethodID java_interop_jnienv_get_method_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature);
+JI_API jobject java_interop_jnienv_call_object_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API jobject java_interop_jnienv_call_object_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API jboolean java_interop_jnienv_call_boolean_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API jboolean java_interop_jnienv_call_boolean_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API jbyte java_interop_jnienv_call_byte_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API jbyte java_interop_jnienv_call_byte_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API jchar java_interop_jnienv_call_char_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API jchar java_interop_jnienv_call_char_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API jshort java_interop_jnienv_call_short_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API jshort java_interop_jnienv_call_short_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API jint java_interop_jnienv_call_int_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API jint java_interop_jnienv_call_int_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API jlong java_interop_jnienv_call_long_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API jlong java_interop_jnienv_call_long_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API jfloat java_interop_jnienv_call_float_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API jfloat java_interop_jnienv_call_float_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API jdouble java_interop_jnienv_call_double_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API jdouble java_interop_jnienv_call_double_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API void java_interop_jnienv_call_void_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
+JI_API void java_interop_jnienv_call_void_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
+JI_API jobject java_interop_jnienv_call_nonvirtual_object_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API jobject java_interop_jnienv_call_nonvirtual_object_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API jboolean java_interop_jnienv_call_nonvirtual_boolean_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API jboolean java_interop_jnienv_call_nonvirtual_boolean_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API jbyte java_interop_jnienv_call_nonvirtual_byte_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API jbyte java_interop_jnienv_call_nonvirtual_byte_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API jchar java_interop_jnienv_call_nonvirtual_char_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API jchar java_interop_jnienv_call_nonvirtual_char_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API jshort java_interop_jnienv_call_nonvirtual_short_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API jshort java_interop_jnienv_call_nonvirtual_short_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API jint java_interop_jnienv_call_nonvirtual_int_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API jint java_interop_jnienv_call_nonvirtual_int_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API jlong java_interop_jnienv_call_nonvirtual_long_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API jlong java_interop_jnienv_call_nonvirtual_long_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API jfloat java_interop_jnienv_call_nonvirtual_float_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API jfloat java_interop_jnienv_call_nonvirtual_float_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API jdouble java_interop_jnienv_call_nonvirtual_double_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API jdouble java_interop_jnienv_call_nonvirtual_double_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API void java_interop_jnienv_call_nonvirtual_void_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
+JI_API void java_interop_jnienv_call_nonvirtual_void_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
+JI_API jfieldID java_interop_jnienv_get_field_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature);
+JI_API jobject java_interop_jnienv_get_object_field (JNIEnv *env, jobject instance, jfieldID field);
+JI_API jboolean java_interop_jnienv_get_boolean_field (JNIEnv *env, jobject instance, jfieldID field);
+JI_API jbyte java_interop_jnienv_get_byte_field (JNIEnv *env, jobject instance, jfieldID field);
+JI_API jchar java_interop_jnienv_get_char_field (JNIEnv *env, jobject instance, jfieldID field);
+JI_API jshort java_interop_jnienv_get_short_field (JNIEnv *env, jobject instance, jfieldID field);
+JI_API jint java_interop_jnienv_get_int_field (JNIEnv *env, jobject instance, jfieldID field);
+JI_API jlong java_interop_jnienv_get_long_field (JNIEnv *env, jobject instance, jfieldID field);
+JI_API jfloat java_interop_jnienv_get_float_field (JNIEnv *env, jobject instance, jfieldID field);
+JI_API jdouble java_interop_jnienv_get_double_field (JNIEnv *env, jobject instance, jfieldID field);
+JI_API void java_interop_jnienv_set_object_field (JNIEnv *env, jobject instance, jfieldID field, jobject value);
+JI_API void java_interop_jnienv_set_boolean_field (JNIEnv *env, jobject instance, jfieldID field, jboolean value);
+JI_API void java_interop_jnienv_set_byte_field (JNIEnv *env, jobject instance, jfieldID field, jbyte value);
+JI_API void java_interop_jnienv_set_char_field (JNIEnv *env, jobject instance, jfieldID field, jchar value);
+JI_API void java_interop_jnienv_set_short_field (JNIEnv *env, jobject instance, jfieldID field, jshort value);
+JI_API void java_interop_jnienv_set_int_field (JNIEnv *env, jobject instance, jfieldID field, jint value);
+JI_API void java_interop_jnienv_set_long_field (JNIEnv *env, jobject instance, jfieldID field, jlong value);
+JI_API void java_interop_jnienv_set_float_field (JNIEnv *env, jobject instance, jfieldID field, jfloat value);
+JI_API void java_interop_jnienv_set_double_field (JNIEnv *env, jobject instance, jfieldID field, jdouble value);
+JI_API jstaticmethodID java_interop_jnienv_get_static_method_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature);
+JI_API jobject java_interop_jnienv_call_static_object_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API jobject java_interop_jnienv_call_static_object_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API jboolean java_interop_jnienv_call_static_boolean_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API jboolean java_interop_jnienv_call_static_boolean_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API jbyte java_interop_jnienv_call_static_byte_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API jbyte java_interop_jnienv_call_static_byte_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API jchar java_interop_jnienv_call_static_char_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API jchar java_interop_jnienv_call_static_char_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API jshort java_interop_jnienv_call_static_short_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API jshort java_interop_jnienv_call_static_short_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API jint java_interop_jnienv_call_static_int_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API jint java_interop_jnienv_call_static_int_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API jlong java_interop_jnienv_call_static_long_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API jlong java_interop_jnienv_call_static_long_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API jfloat java_interop_jnienv_call_static_float_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API jfloat java_interop_jnienv_call_static_float_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API jdouble java_interop_jnienv_call_static_double_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API jdouble java_interop_jnienv_call_static_double_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API void java_interop_jnienv_call_static_void_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
+JI_API void java_interop_jnienv_call_static_void_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
+JI_API jstaticfieldID java_interop_jnienv_get_static_field_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature);
+JI_API jobject java_interop_jnienv_get_static_object_field (JNIEnv *env, jclass type, jstaticfieldID field);
+JI_API jboolean java_interop_jnienv_get_static_boolean_field (JNIEnv *env, jclass type, jstaticfieldID field);
+JI_API jbyte java_interop_jnienv_get_static_byte_field (JNIEnv *env, jclass type, jstaticfieldID field);
+JI_API jchar java_interop_jnienv_get_static_char_field (JNIEnv *env, jclass type, jstaticfieldID field);
+JI_API jshort java_interop_jnienv_get_static_short_field (JNIEnv *env, jclass type, jstaticfieldID field);
+JI_API jint java_interop_jnienv_get_static_int_field (JNIEnv *env, jclass type, jstaticfieldID field);
+JI_API jlong java_interop_jnienv_get_static_long_field (JNIEnv *env, jclass type, jstaticfieldID field);
+JI_API jfloat java_interop_jnienv_get_static_float_field (JNIEnv *env, jclass type, jstaticfieldID field);
+JI_API jdouble java_interop_jnienv_get_static_double_field (JNIEnv *env, jclass type, jstaticfieldID field);
+JI_API void java_interop_jnienv_set_static_object_field (JNIEnv *env, jclass type, jstaticfieldID field, jobject value);
+JI_API void java_interop_jnienv_set_static_boolean_field (JNIEnv *env, jclass type, jstaticfieldID field, jboolean value);
+JI_API void java_interop_jnienv_set_static_byte_field (JNIEnv *env, jclass type, jstaticfieldID field, jbyte value);
+JI_API void java_interop_jnienv_set_static_char_field (JNIEnv *env, jclass type, jstaticfieldID field, jchar value);
+JI_API void java_interop_jnienv_set_static_short_field (JNIEnv *env, jclass type, jstaticfieldID field, jshort value);
+JI_API void java_interop_jnienv_set_static_int_field (JNIEnv *env, jclass type, jstaticfieldID field, jint value);
+JI_API void java_interop_jnienv_set_static_long_field (JNIEnv *env, jclass type, jstaticfieldID field, jlong value);
+JI_API void java_interop_jnienv_set_static_float_field (JNIEnv *env, jclass type, jstaticfieldID field, jfloat value);
+JI_API void java_interop_jnienv_set_static_double_field (JNIEnv *env, jclass type, jstaticfieldID field, jdouble value);
+JI_API jstring java_interop_jnienv_new_string (JNIEnv *env, jthrowable *_thrown, jchar* unicodeChars, jsize length);
+JI_API jsize java_interop_jnienv_get_string_length (JNIEnv *env, jstring stringInstance);
+JI_API const jchar* java_interop_jnienv_get_string_chars (JNIEnv *env, jstring stringInstance, jboolean* isCopy);
+JI_API void java_interop_jnienv_release_string_chars (JNIEnv *env, jstring stringInstance, jchar* chars);
+JI_API jsize java_interop_jnienv_get_array_length (JNIEnv *env, jarray array);
+JI_API jobjectArray java_interop_jnienv_new_object_array (JNIEnv *env, jthrowable *_thrown, jsize length, jclass elementClass, jobject initialElement);
+JI_API jobject java_interop_jnienv_get_object_array_element (JNIEnv *env, jthrowable *_thrown, jobjectArray array, jsize index);
+JI_API void java_interop_jnienv_set_object_array_element (JNIEnv *env, jthrowable *_thrown, jobjectArray array, jsize index, jobject value);
+JI_API jbooleanArray java_interop_jnienv_new_boolean_array (JNIEnv *env, jsize length);
+JI_API jbyteArray java_interop_jnienv_new_byte_array (JNIEnv *env, jsize length);
+JI_API jcharArray java_interop_jnienv_new_char_array (JNIEnv *env, jsize length);
+JI_API jshortArray java_interop_jnienv_new_short_array (JNIEnv *env, jsize length);
+JI_API jintArray java_interop_jnienv_new_int_array (JNIEnv *env, jsize length);
+JI_API jlongArray java_interop_jnienv_new_long_array (JNIEnv *env, jsize length);
+JI_API jfloatArray java_interop_jnienv_new_float_array (JNIEnv *env, jsize length);
+JI_API jdoubleArray java_interop_jnienv_new_double_array (JNIEnv *env, jsize length);
+JI_API jboolean* java_interop_jnienv_get_boolean_array_elements (JNIEnv *env, jbooleanArray array, jboolean* isCopy);
+JI_API jbyte* java_interop_jnienv_get_byte_array_elements (JNIEnv *env, jbyteArray array, jboolean* isCopy);
+JI_API jchar* java_interop_jnienv_get_char_array_elements (JNIEnv *env, jcharArray array, jboolean* isCopy);
+JI_API jshort* java_interop_jnienv_get_short_array_elements (JNIEnv *env, jshortArray array, jboolean* isCopy);
+JI_API jint* java_interop_jnienv_get_int_array_elements (JNIEnv *env, jintArray array, jboolean* isCopy);
+JI_API jlong* java_interop_jnienv_get_long_array_elements (JNIEnv *env, jlongArray array, jboolean* isCopy);
+JI_API jfloat* java_interop_jnienv_get_float_array_elements (JNIEnv *env, jfloatArray array, jboolean* isCopy);
+JI_API jdouble* java_interop_jnienv_get_double_array_elements (JNIEnv *env, jdoubleArray array, jboolean* isCopy);
+JI_API void java_interop_jnienv_release_boolean_array_elements (JNIEnv *env, jbooleanArray array, jboolean* elements, jint mode);
+JI_API void java_interop_jnienv_release_byte_array_elements (JNIEnv *env, jbyteArray array, jbyte* elements, jint mode);
+JI_API void java_interop_jnienv_release_char_array_elements (JNIEnv *env, jcharArray array, jchar* elements, jint mode);
+JI_API void java_interop_jnienv_release_short_array_elements (JNIEnv *env, jshortArray array, jshort* elements, jint mode);
+JI_API void java_interop_jnienv_release_int_array_elements (JNIEnv *env, jintArray array, jint* elements, jint mode);
+JI_API void java_interop_jnienv_release_long_array_elements (JNIEnv *env, jlongArray array, jlong* elements, jint mode);
+JI_API void java_interop_jnienv_release_float_array_elements (JNIEnv *env, jfloatArray array, jfloat* elements, jint mode);
+JI_API void java_interop_jnienv_release_double_array_elements (JNIEnv *env, jdoubleArray array, jdouble* elements, jint mode);
+JI_API void java_interop_jnienv_get_boolean_array_region (JNIEnv *env, jthrowable *_thrown, jbooleanArray array, jsize start, jsize length, jboolean* buffer);
+JI_API void java_interop_jnienv_get_byte_array_region (JNIEnv *env, jthrowable *_thrown, jbyteArray array, jsize start, jsize length, jbyte* buffer);
+JI_API void java_interop_jnienv_get_char_array_region (JNIEnv *env, jthrowable *_thrown, jcharArray array, jsize start, jsize length, jchar* buffer);
+JI_API void java_interop_jnienv_get_short_array_region (JNIEnv *env, jthrowable *_thrown, jshortArray array, jsize start, jsize length, jshort* buffer);
+JI_API void java_interop_jnienv_get_int_array_region (JNIEnv *env, jthrowable *_thrown, jintArray array, jsize start, jsize length, jint* buffer);
+JI_API void java_interop_jnienv_get_long_array_region (JNIEnv *env, jthrowable *_thrown, jlongArray array, jsize start, jsize length, jlong* buffer);
+JI_API void java_interop_jnienv_get_float_array_region (JNIEnv *env, jthrowable *_thrown, jlongArray array, jsize start, jsize length, jfloat* buffer);
+JI_API void java_interop_jnienv_get_double_array_region (JNIEnv *env, jthrowable *_thrown, jdoubleArray array, jsize start, jsize length, jdouble* buffer);
+JI_API void java_interop_jnienv_set_boolean_array_region (JNIEnv *env, jthrowable *_thrown, jbooleanArray array, jsize start, jsize length, jboolean* buffer);
+JI_API void java_interop_jnienv_set_byte_array_region (JNIEnv *env, jthrowable *_thrown, jbyteArray array, jsize start, jsize length, jbyte* buffer);
+JI_API void java_interop_jnienv_set_char_array_region (JNIEnv *env, jthrowable *_thrown, jcharArray array, jsize start, jsize length, const jchar* buffer);
+JI_API void java_interop_jnienv_set_short_array_region (JNIEnv *env, jthrowable *_thrown, jshortArray array, jsize start, jsize length, jshort* buffer);
+JI_API void java_interop_jnienv_set_int_array_region (JNIEnv *env, jthrowable *_thrown, jintArray array, jsize start, jsize length, jint* buffer);
+JI_API void java_interop_jnienv_set_long_array_region (JNIEnv *env, jthrowable *_thrown, jlongArray array, jsize start, jsize length, jlong* buffer);
+JI_API void java_interop_jnienv_set_float_array_region (JNIEnv *env, jthrowable *_thrown, jfloatArray array, jsize start, jsize length, jfloat* buffer);
+JI_API void java_interop_jnienv_set_double_array_region (JNIEnv *env, jthrowable *_thrown, jdoubleArray array, jsize start, jsize length, jdouble* buffer);
+JI_API jint java_interop_jnienv_register_natives (JNIEnv *env, jthrowable *_thrown, jclass type, const JNINativeMethod* methods, jint numMethods);
+JI_API jint java_interop_jnienv_unregister_natives (JNIEnv *env, jclass type);
+JI_API jint java_interop_jnienv_monitor_enter (JNIEnv *env, jobject instance);
+JI_API jint java_interop_jnienv_monitor_exit (JNIEnv *env, jobject instance);
+JI_API jint java_interop_jnienv_get_java_vm (JNIEnv *env, JavaVM** vm);
+JI_API void* java_interop_jnienv_get_primitive_array_critical (JNIEnv *env, jarray array, jboolean* isCopy);
+JI_API void java_interop_jnienv_release_primitive_array_critical (JNIEnv *env, jarray array, void* carray, jint mode);
+JI_API jweak java_interop_jnienv_new_weak_global_ref (JNIEnv *env, jobject instance);
+JI_API void java_interop_jnienv_delete_weak_global_ref (JNIEnv *env, jobject instance);
+JI_API jboolean java_interop_jnienv_exception_check (JNIEnv *env);
+JI_API jobject java_interop_jnienv_new_direct_byte_buffer (JNIEnv *env, jthrowable *_thrown, void* address, jlong capacity);
+JI_API void* java_interop_jnienv_get_direct_buffer_address (JNIEnv *env, jobject buffer);
+JI_API jlong java_interop_jnienv_get_direct_buffer_capacity (JNIEnv *env, jobject buffer);
+JI_API jobjectRefType java_interop_jnienv_get_object_ref_type (JNIEnv *env, jobject instance);
+
+#endif // __JAVA_INTEROP_NATIVE_H
diff --git a/src/monodroid/jni/mono_android_Runtime.h b/src/monodroid/jni/mono_android_Runtime.h
index 40f51c63825..0e5aa37d095 100644
--- a/src/monodroid/jni/mono_android_Runtime.h
+++ b/src/monodroid/jni/mono_android_Runtime.h
@@ -39,6 +39,7 @@ JNIEXPORT void JNICALL Java_mono_android_Runtime_register
JNIEXPORT void JNICALL Java_mono_android_Runtime_notifyTimeZoneChanged
(JNIEnv *, jclass);
+#if !defined (ANDROID)
/*
* Class: mono_android_Runtime
* Method: createNewContext
@@ -70,6 +71,7 @@ JNIEXPORT void JNICALL Java_mono_android_Runtime_switchToContext
*/
JNIEXPORT void JNICALL Java_mono_android_Runtime_destroyContexts
(JNIEnv *, jclass, jintArray);
+#endif // ndef ANDROID
/*
* Class: mono_android_Runtime
diff --git a/src/monodroid/jni/monodroid-glue-designer.cc b/src/monodroid/jni/monodroid-glue-designer.cc
new file mode 100644
index 00000000000..422e45e3c12
--- /dev/null
+++ b/src/monodroid/jni/monodroid-glue-designer.cc
@@ -0,0 +1,147 @@
+//
+// Android designer support code, not used on devices
+//
+#include "globals.hh"
+#include "mono_android_Runtime.h"
+#include "monodroid-glue-internal.hh"
+
+using namespace xamarin::android::internal;
+
+// DO NOT USE ON NORMAL X.A
+// This function only works with the custom TypeManager embedded with the designer process.
+force_inline static void
+reinitialize_android_runtime_type_manager (JNIEnv *env)
+{
+ jclass typeManager = env->FindClass ("mono/android/TypeManager");
+ env->UnregisterNatives (typeManager);
+
+ jmethodID resetRegistration = env->GetStaticMethodID (typeManager, "resetRegistration", "()V");
+ env->CallStaticVoidMethod (typeManager, resetRegistration);
+
+ env->DeleteLocalRef (typeManager);
+}
+
+inline void
+MonodroidRuntime::shutdown_android_runtime (MonoDomain *domain)
+{
+ MonoClass *runtime = get_android_runtime_class (domain);
+ MonoMethod *method = mono_class_get_method_from_name (runtime, "Exit", 0);
+
+ utils.monodroid_runtime_invoke (domain, method, nullptr, nullptr, nullptr);
+}
+
+inline jint
+MonodroidRuntime::Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava,
+ jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies)
+{
+ log_info (LOG_DEFAULT, "CREATING NEW CONTEXT");
+ reinitialize_android_runtime_type_manager (env);
+ MonoDomain *root_domain = mono_get_root_domain ();
+ mono_jit_thread_attach (root_domain);
+
+ jstring_array_wrapper runtimeApks (env, runtimeApksJava);
+ jstring_array_wrapper assemblies (env, assembliesJava);
+ jstring_array_wrapper assembliePaths (env, assembliesPaths);
+ MonoDomain *domain = create_and_initialize_domain (env, klass, runtimeApks, assemblies, assembliesBytes, assembliePaths, loader, /*is_root_domain:*/ false, force_preload_assemblies);
+ mono_domain_set (domain, FALSE);
+ int domain_id = mono_domain_get_id (domain);
+ current_context_id = domain_id;
+ log_info (LOG_DEFAULT, "Created new context with id %d\n", domain_id);
+ return domain_id;
+}
+
+inline void
+MonodroidRuntime::Java_mono_android_Runtime_switchToContext (JNIEnv *env, jint contextID)
+{
+ log_info (LOG_DEFAULT, "SWITCHING CONTEXT");
+ MonoDomain *domain = mono_domain_get_by_id ((int)contextID);
+ if (current_context_id != (int)contextID) {
+ mono_domain_set (domain, TRUE);
+ // Reinitialize TypeManager so that its JNI handle goes into the right domain
+ reinitialize_android_runtime_type_manager (env);
+ }
+ current_context_id = (int)contextID;
+}
+
+inline void
+MonodroidRuntime::Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jintArray array)
+{
+ MonoDomain *root_domain = mono_get_root_domain ();
+ mono_jit_thread_attach (root_domain);
+ current_context_id = -1;
+
+ jint *contextIDs = env->GetIntArrayElements (array, nullptr);
+ jsize count = env->GetArrayLength (array);
+
+ log_info (LOG_DEFAULT, "Cleaning %d domains", count);
+
+ for (jsize i = 0; i < count; i++) {
+ int domain_id = contextIDs[i];
+ MonoDomain *domain = mono_domain_get_by_id (domain_id);
+
+ if (domain == nullptr)
+ continue;
+ log_info (LOG_DEFAULT, "Shutting down domain `%d'", contextIDs[i]);
+ shutdown_android_runtime (domain);
+ osBridge.remove_monodroid_domain (domain);
+ designerAssemblies.clear_for_domain (domain);
+ }
+ osBridge.on_destroy_contexts ();
+ for (jsize i = 0; i < count; i++) {
+ int domain_id = contextIDs[i];
+ MonoDomain *domain = mono_domain_get_by_id (domain_id);
+
+ if (domain == nullptr)
+ continue;
+ log_info (LOG_DEFAULT, "Unloading domain `%d'", contextIDs[i]);
+ mono_domain_unload (domain);
+ }
+ env->ReleaseIntArrayElements (array, contextIDs, JNI_ABORT);
+
+ reinitialize_android_runtime_type_manager (env);
+
+ log_info (LOG_DEFAULT, "All domain cleaned up");
+}
+
+JNIEXPORT jint
+JNICALL Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies)
+{
+ return monodroidRuntime.Java_mono_android_Runtime_createNewContextWithData (
+ env,
+ klass,
+ runtimeApksJava,
+ assembliesJava,
+ assembliesBytes,
+ assembliesPaths,
+ loader,
+ force_preload_assemblies
+ );
+}
+
+/* !DO NOT REMOVE! Used by older versions of the Android Designer (pre-16.4) */
+JNIEXPORT jint
+JNICALL Java_mono_android_Runtime_createNewContext (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, jobject loader)
+{
+ return monodroidRuntime.Java_mono_android_Runtime_createNewContextWithData (
+ env,
+ klass,
+ runtimeApksJava,
+ assembliesJava,
+ nullptr, // assembliesBytes
+ nullptr, // assembliesPaths
+ loader,
+ false // force_preload_assemblies
+ );
+}
+
+JNIEXPORT void
+JNICALL Java_mono_android_Runtime_switchToContext (JNIEnv *env, [[maybe_unused]] jclass klass, jint contextID)
+{
+ monodroidRuntime.Java_mono_android_Runtime_switchToContext (env, contextID);
+}
+
+JNIEXPORT void
+JNICALL Java_mono_android_Runtime_destroyContexts (JNIEnv *env, [[maybe_unused]] jclass klass, jintArray array)
+{
+ monodroidRuntime.Java_mono_android_Runtime_destroyContexts (env, array);
+}
diff --git a/src/monodroid/jni/monodroid-glue-internal.hh b/src/monodroid/jni/monodroid-glue-internal.hh
index 1dc9dfee2b7..9369f5a29b4 100644
--- a/src/monodroid/jni/monodroid-glue-internal.hh
+++ b/src/monodroid/jni/monodroid-glue-internal.hh
@@ -2,6 +2,7 @@
#ifndef __MONODROID_GLUE_INTERNAL_H
#define __MONODROID_GLUE_INTERNAL_H
+#include
#include
#include "android-system.hh"
#include "osbridge.hh"
@@ -10,10 +11,65 @@
#include
#include
+#if defined (NET6)
+// NDEBUG causes robin_map.h not to include which, in turn, prevents indirect inclusion of .
+// conflicts with our std::mutex definition in cppcompat.hh
+#if !defined (NDEBUG)
+#define NDEBUG
+#define NDEBUG_UNDEFINE
+#endif
+
+// hush some compiler warnings
+#if defined (__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#endif // __clang__
+
+#include
+
+#if defined (__clang__)
+#pragma clang diagnostic pop
+#endif // __clang__
+
+#if defined (NDEBUG_UNDEFINE)
+#undef NDEBUG
+#undef NDEBUG_UNDEFINE
+#endif
+
+#include
+#include
+
+// This should be defined in the public Mono headers
+typedef void * (*PInvokeOverrideFn) (const char *libraryName, const char *entrypointName);
+#endif
+
namespace xamarin::android::internal
{
class MonodroidRuntime
{
+#if defined (NET6)
+ using pinvoke_api_map = tsl::robin_map<
+ std::string,
+ void*,
+ std::hash,
+ std::equal_to,
+ std::allocator>,
+ true
+ >;
+
+ using pinvoke_api_map_ptr = pinvoke_api_map*;
+ using pinvoke_library_map = tsl::robin_map<
+ std::string,
+ pinvoke_api_map_ptr,
+ std::hash,
+ std::equal_to,
+ std::allocator>,
+ true
+ >;
+
+ static constexpr pinvoke_library_map::size_type LIBRARY_MAP_INITIAL_BUCKET_COUNT = 1;
+#endif // def NET6
+
#if defined (DEBUG) && !defined (WINDOWS)
struct RuntimeOptions {
bool debug = false;
@@ -61,6 +117,7 @@ namespace xamarin::android::internal
#else
true;
#endif
+
#define MAKE_API_DSO_NAME(_ext_) "libxa-internal-api." # _ext_
#if defined (WINDOWS)
static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (dll);
@@ -70,6 +127,12 @@ namespace xamarin::android::internal
static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (so);
#endif // defined(WINDOWS)
public:
+ static constexpr bool is_net6 =
+#if NET6
+ true;
+#else // def NET6
+ false;
+#endif // ndef NET6
static constexpr int XA_LOG_COUNTERS = MONO_COUNTER_JIT | MONO_COUNTER_METADATA | MONO_COUNTER_GC | MONO_COUNTER_GENERICS | MONO_COUNTER_INTERP;
public:
@@ -77,10 +140,13 @@ namespace xamarin::android::internal
void Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava,
jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader,
jobjectArray assembliesJava, jint apiLevel, jboolean isEmulator);
+#if !defined (ANDROID)
jint Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava,
jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies);
void Java_mono_android_Runtime_switchToContext (JNIEnv *env, jint contextID);
void Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jintArray array);
+ void shutdown_android_runtime (MonoDomain *domain);
+#endif
jint Java_JNI_OnLoad (JavaVM *vm, void *reserved);
int get_android_api_level () const
@@ -139,10 +205,18 @@ namespace xamarin::android::internal
#if defined (WINDOWS) || defined (APPLE_OS_X)
static const char* get_my_location (bool remove_file_name = true);
#endif // defined(WINDOWS) || defined(APPLE_OS_X)
+#if defined (NET6)
+ static void* load_library_entry (std::string const& library_name, std::string const& entrypoint_name, pinvoke_api_map_ptr api_map);
+ static void* fetch_or_create_pinvoke_map_entry (std::string const& library_name, std::string const& entrypoint_name, pinvoke_api_map_ptr api_map, bool need_lock);
+ static void* monodroid_pinvoke_override (const char *library_name, const char *entrypoint_name);
+ static void* monodroid_dlopen (const char *name, int flags, char **err);
+#endif // def NET6
static void* monodroid_dlopen (const char *name, int flags, char **err, void *user_data);
static void* monodroid_dlsym (void *handle, const char *name, char **err, void *user_data);
static void* monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory, bool need_api_init = false);
+#if !defined (NET6)
static void init_internal_api_dso (void *handle);
+#endif // ndef NET6
int LocalRefsAreIndirect (JNIEnv *env, jclass runtimeClass, int version);
void create_xdg_directory (jstring_wrapper& home, size_t home_len, const char *relativePath, size_t relative_path_len, const char *environmentVariableName);
void create_xdg_directories_and_environment (jstring_wrapper &homeDir);
@@ -168,7 +242,6 @@ namespace xamarin::android::internal
}
MonoClass* get_android_runtime_class (MonoDomain *domain);
- void shutdown_android_runtime (MonoDomain *domain);
MonoDomain* create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain);
MonoDomain* create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks,
jstring_array_wrapper &assemblies, jobjectArray assembliesBytes, jstring_array_wrapper &assembliesPaths,
@@ -227,8 +300,14 @@ namespace xamarin::android::internal
*/
int current_context_id = -1;
+#if defined (NET6)
+ static std::mutex pinvoke_map_write_lock;
+ static pinvoke_api_map xa_pinvoke_map;
+ static pinvoke_library_map other_pinvoke_map;
+#else // def NET6
static std::mutex api_init_lock;
static void *api_dso_handle;
+#endif // !def NET6
};
}
#endif
diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc
index f7dc3ec1c51..634fd108ad6 100644
--- a/src/monodroid/jni/monodroid-glue.cc
+++ b/src/monodroid/jni/monodroid-glue.cc
@@ -1,7 +1,6 @@
#include
#include
#include
-#include
#include
#include
@@ -99,11 +98,17 @@ using namespace xamarin::android::internal;
// implementation details as it would prevent mkbundle from working
#include "mkbundle-api.h"
+#if !defined (NET6)
#include "config.include"
+#endif // ndef NET6
#include "machine.config.include"
+#if defined (NET6)
+std::mutex MonodroidRuntime::pinvoke_map_write_lock;
+#else // def NET6
std::mutex MonodroidRuntime::api_init_lock;
void *MonodroidRuntime::api_dso_handle = nullptr;
+#endif // ndef NET6
#ifdef WINDOWS
static const char* get_xamarin_android_msbuild_path (void);
@@ -395,9 +400,7 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks,
size_t cur_num_assemblies = embeddedAssemblies.register_from (apk_file.get_cstr ());
- if (strstr (apk_file.get_cstr (), "/Mono.Android.DebugRuntime") == nullptr &&
- strstr (apk_file.get_cstr (), "/Mono.Android.Platform.ApiLevel_") == nullptr)
- *out_user_assemblies_count += (cur_num_assemblies - prev_num_assemblies);
+ *out_user_assemblies_count += (cur_num_assemblies - prev_num_assemblies);
prev_num_assemblies = cur_num_assemblies;
}
}
@@ -1013,7 +1016,7 @@ MonodroidRuntime::init_android_runtime (MonoDomain *domain, JNIEnv *env, jclass
}
}
-inline MonoClass*
+MonoClass*
MonodroidRuntime::get_android_runtime_class (MonoDomain *domain)
{
MonoAssembly *assm = utils.monodroid_load_assembly (domain, "Mono.Android");
@@ -1023,15 +1026,6 @@ MonodroidRuntime::get_android_runtime_class (MonoDomain *domain)
return runtime;
}
-inline void
-MonodroidRuntime::shutdown_android_runtime (MonoDomain *domain)
-{
- MonoClass *runtime = get_android_runtime_class (domain);
- MonoMethod *method = mono_class_get_method_from_name (runtime, "Exit", 0);
-
- utils.monodroid_runtime_invoke (domain, method, nullptr, nullptr, nullptr);
-}
-
inline void
MonodroidRuntime::propagate_uncaught_exception (MonoDomain *domain, JNIEnv *env, jobject javaThread, jthrowable javaException)
{
@@ -1066,6 +1060,7 @@ MonodroidRuntime::convert_dl_flags (int flags)
return lflags;
}
+#if !defined (NET6)
force_inline void
MonodroidRuntime::init_internal_api_dso (void *handle)
{
@@ -1113,9 +1108,10 @@ MonodroidRuntime::init_internal_api_dso (void *handle)
exit (FATAL_EXIT_MONO_MISSING_SYMBOLS);
}
}
+#endif // ndef NET6
force_inline void*
-MonodroidRuntime::monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory, bool need_api_init)
+MonodroidRuntime::monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory, [[maybe_unused]] bool need_api_init)
{
if (handle == nullptr && err != nullptr) {
*err = utils.monodroid_strdup_printf ("Could not load library: Library '%s' not found.", full_name);
@@ -1125,14 +1121,77 @@ MonodroidRuntime::monodroid_dlopen_log_and_return (void *handle, char **err, con
delete[] full_name;
}
+#if !defined (NET6)
if (!need_api_init)
return handle;
-
init_internal_api_dso (handle);
+#endif // ndef NET6
return handle;
}
+#if defined (NET6) && defined (ANDROID)
+force_inline void*
+MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err)
+{
+ unsigned int dl_flags = monodroidRuntime.convert_dl_flags (flags);
+ void *h = androidSystem.load_dso_from_any_directories (name, dl_flags);
+ if (h != nullptr) {
+ return monodroid_dlopen_log_and_return (h, err, name, false /* name_needs_free */);
+ }
+
+ if (!utils.ends_with (name, ".dll.so")) {
+ return monodroid_dlopen_log_and_return (h, err, name, false /* name_needs_free */);
+ }
+
+ char *basename_part = const_cast (strrchr (name, '/'));
+ if (basename_part != nullptr) {
+ basename_part++;
+ } else {
+ basename_part = (char*)name;
+ }
+
+ constexpr char LIBAOT_PREFIX[] = "libaot-";
+ constexpr size_t LIBAOT_PREFIX_SIZE = sizeof(LIBAOT_PREFIX);
+
+ size_t base_len = strlen (basename_part);
+ size_t len = base_len + LIBAOT_PREFIX_SIZE; // includes the trailing \0
+ static_local_string basename (len);
+
+ basename.append (LIBAOT_PREFIX).append (basename_part);
+
+ h = androidSystem.load_dso_from_any_directories (basename.get (), dl_flags);
+
+ if (h != nullptr && XA_UNLIKELY (utils.should_log (LOG_ASSEMBLY))) {
+ log_info_nocheck (LOG_ASSEMBLY, "Loaded AOT image '%s'", basename.get ());
+ }
+
+ return h;
+}
+
+void*
+MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err, [[maybe_unused]] void *user_data)
+{
+ log_warn (LOG_DEFAULT, "MonodroidRuntime::monodroid_dlopen (\"%s\", 0x%x, %p, %p)", name, flags, err, user_data);
+ if (name == nullptr) {
+ log_warn (LOG_ASSEMBLY, "monodroid_dlopen got a null name. This is not supported in NET6+");
+ return nullptr;
+ }
+
+ constexpr char DSO_EXTENSION[] = ".so";
+ constexpr size_t DSO_EXTENSION_SIZE = sizeof(DSO_EXTENSION);
+
+ if (utils.ends_with (name, DSO_EXTENSION)) {
+ return monodroid_dlopen (name, flags, err);
+ }
+
+ size_t len = ADD_WITH_OVERFLOW_CHECK (size_t, strlen (name), DSO_EXTENSION_SIZE); // includes the trailing \0
+ static_local_string full_name (len);
+
+ full_name.append (name).append (DSO_EXTENSION);
+ return monodroid_dlopen (full_name.get (), flags, err);
+}
+#else // def NET6 && def ANDROID
void*
MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err, [[maybe_unused]] void *user_data)
{
@@ -1252,6 +1311,7 @@ MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err, [[m
return h;
}
+#endif // !(def NET6 && def ANDROID)
void*
MonodroidRuntime::monodroid_dlsym (void *handle, const char *name, char **err, [[maybe_unused]] void *user_data)
@@ -1635,6 +1695,20 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl
total_time.mark_start ();
}
+#if defined (NET6)
+ {
+ PInvokeOverrideFn pinvoke_override_cb = monodroid_pinvoke_override;
+ char ptr_str[20];
+ snprintf (ptr_str, sizeof(ptr_str), "%p", pinvoke_override_cb);
+
+ const char* property_keys[] { "PINVOKE_OVERRIDE" };
+ const char* property_values[] { ptr_str };
+
+ log_warn (LOG_DEFAULT, "Initializing .NET6 Mono VM (override callback at %p, passed as %s", pinvoke_override_cb, ptr_str);
+ monovm_initialize (1, property_keys, property_values);
+ }
+#endif // def NET6
+
jstring_array_wrapper applicationDirs (env, appDirs);
android_api_level = apiLevel;
@@ -1710,8 +1784,9 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl
#endif // defined(WINDOWS) || defined(APPLE_OS_X)
if (dso_handle == nullptr)
dso_handle = androidSystem.load_dso_from_any_directories (API_DSO_NAME, JAVA_INTEROP_LIB_LOAD_GLOBALLY);
+#if !defined (NET6)
init_internal_api_dso (dso_handle);
-
+#endif // ndef NET6
mono_dl_fallback_register (monodroid_dlopen, monodroid_dlsym, nullptr, nullptr);
set_profile_options ();
@@ -1722,7 +1797,9 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl
debug.start_debugging_and_profiling ();
#endif
+#if !defined (NET6)
mono_config_parse_memory (reinterpret_cast (monodroid_config));
+#endif // ndef NET6
mono_register_machine_config (reinterpret_cast (monodroid_machine_config));
log_info (LOG_DEFAULT, "Probing for Mono AOT mode\n");
@@ -1928,97 +2005,6 @@ JNICALL Java_mono_android_Runtime_register (JNIEnv *env, [[maybe_unused]] jclass
monodroidRuntime.Java_mono_android_Runtime_register (env, managedType, nativeClass, methods);
}
-// DO NOT USE ON NORMAL X.A
-// This function only works with the custom TypeManager embedded with the designer process.
-static void
-reinitialize_android_runtime_type_manager (JNIEnv *env)
-{
- jclass typeManager = env->FindClass ("mono/android/TypeManager");
- env->UnregisterNatives (typeManager);
-
- jmethodID resetRegistration = env->GetStaticMethodID (typeManager, "resetRegistration", "()V");
- env->CallStaticVoidMethod (typeManager, resetRegistration);
-
- env->DeleteLocalRef (typeManager);
-}
-
-inline jint
-MonodroidRuntime::Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava,
- jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies)
-{
- log_info (LOG_DEFAULT, "CREATING NEW CONTEXT");
- reinitialize_android_runtime_type_manager (env);
- MonoDomain *root_domain = mono_get_root_domain ();
- mono_jit_thread_attach (root_domain);
-
- jstring_array_wrapper runtimeApks (env, runtimeApksJava);
- jstring_array_wrapper assemblies (env, assembliesJava);
- jstring_array_wrapper assembliePaths (env, assembliesPaths);
- MonoDomain *domain = create_and_initialize_domain (env, klass, runtimeApks, assemblies, assembliesBytes, assembliePaths, loader, /*is_root_domain:*/ false, force_preload_assemblies);
- mono_domain_set (domain, FALSE);
- int domain_id = mono_domain_get_id (domain);
- current_context_id = domain_id;
- log_info (LOG_DEFAULT, "Created new context with id %d\n", domain_id);
- return domain_id;
-}
-
-inline void
-MonodroidRuntime::Java_mono_android_Runtime_switchToContext (JNIEnv *env, jint contextID)
-{
- log_info (LOG_DEFAULT, "SWITCHING CONTEXT");
- MonoDomain *domain = mono_domain_get_by_id ((int)contextID);
- if (current_context_id != (int)contextID) {
- mono_domain_set (domain, TRUE);
- // Reinitialize TypeManager so that its JNI handle goes into the right domain
- reinitialize_android_runtime_type_manager (env);
- }
- current_context_id = (int)contextID;
-}
-
-inline void
-MonodroidRuntime::Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jintArray array)
-{
- MonoDomain *root_domain = mono_get_root_domain ();
- mono_jit_thread_attach (root_domain);
- current_context_id = -1;
-
- jint *contextIDs = env->GetIntArrayElements (array, nullptr);
- jsize count = env->GetArrayLength (array);
-
- log_info (LOG_DEFAULT, "Cleaning %d domains", count);
-
- for (jsize i = 0; i < count; i++) {
- int domain_id = contextIDs[i];
- MonoDomain *domain = mono_domain_get_by_id (domain_id);
-
- if (domain == nullptr)
- continue;
- log_info (LOG_DEFAULT, "Shutting down domain `%d'", contextIDs[i]);
- shutdown_android_runtime (domain);
- osBridge.remove_monodroid_domain (domain);
-#ifndef ANDROID
- designerAssemblies.clear_for_domain (domain);
-#endif
- }
- osBridge.on_destroy_contexts ();
-#ifndef ANDROID
- for (jsize i = 0; i < count; i++) {
- int domain_id = contextIDs[i];
- MonoDomain *domain = mono_domain_get_by_id (domain_id);
-
- if (domain == nullptr)
- continue;
- log_info (LOG_DEFAULT, "Unloading domain `%d'", contextIDs[i]);
- mono_domain_unload (domain);
- }
-#endif // !defined(ANDROID)
- env->ReleaseIntArrayElements (array, contextIDs, JNI_ABORT);
-
- reinitialize_android_runtime_type_manager (env);
-
- log_info (LOG_DEFAULT, "All domain cleaned up");
-}
-
char*
MonodroidRuntime::get_java_class_name_for_TypeManager (jclass klass)
{
@@ -2058,49 +2044,6 @@ get_jnienv (void)
return osBridge.ensure_jnienv ();
}
-JNIEXPORT jint
-JNICALL Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies)
-{
- return monodroidRuntime.Java_mono_android_Runtime_createNewContextWithData (
- env,
- klass,
- runtimeApksJava,
- assembliesJava,
- assembliesBytes,
- assembliesPaths,
- loader,
- force_preload_assemblies
- );
-}
-
-/* !DO NOT REMOVE! Used by older versions of the Android Designer (pre-16.4) */
-JNIEXPORT jint
-JNICALL Java_mono_android_Runtime_createNewContext (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, jobject loader)
-{
- return monodroidRuntime.Java_mono_android_Runtime_createNewContextWithData (
- env,
- klass,
- runtimeApksJava,
- assembliesJava,
- nullptr, // assembliesBytes
- nullptr, // assembliesPaths
- loader,
- false // force_preload_assemblies
- );
-}
-
-JNIEXPORT void
-JNICALL Java_mono_android_Runtime_switchToContext (JNIEnv *env, [[maybe_unused]] jclass klass, jint contextID)
-{
- monodroidRuntime.Java_mono_android_Runtime_switchToContext (env, contextID);
-}
-
-JNIEXPORT void
-JNICALL Java_mono_android_Runtime_destroyContexts (JNIEnv *env, [[maybe_unused]] jclass klass, jintArray array)
-{
- monodroidRuntime.Java_mono_android_Runtime_destroyContexts (env, array);
-}
-
JNIEXPORT void
JNICALL Java_mono_android_Runtime_propagateUncaughtException (JNIEnv *env, [[maybe_unused]] jclass klass, jobject javaThread, jthrowable javaException)
{
diff --git a/src/monodroid/jni/monodroid-glue.hh b/src/monodroid/jni/monodroid-glue.hh
index 1f0adad5020..956f93ac5c6 100644
--- a/src/monodroid/jni/monodroid-glue.hh
+++ b/src/monodroid/jni/monodroid-glue.hh
@@ -8,14 +8,17 @@
#include
#include
+#if !defined (NET6)
#ifdef __cplusplus
extern "C" {
-#endif
+#endif // __cplusplus
MONO_API int monodroid_get_system_property (const char *name, char **value);
MONO_API int monodroid_getpagesize (void);
#ifdef __cplusplus
}
-#endif
+#endif // __cplusplus
+#endif // NET6
+
int monodroid_get_system_property_from_overrides (const char *name, char ** value);
JNIEnv* get_jnienv (void);
diff --git a/src/monodroid/jni/pinvoke-override-api.cc b/src/monodroid/jni/pinvoke-override-api.cc
new file mode 100644
index 00000000000..fa2e1837a3f
--- /dev/null
+++ b/src/monodroid/jni/pinvoke-override-api.cc
@@ -0,0 +1,714 @@
+#include
+#include
+#include
+#include
+
+extern "C" {
+#include "java_interop_api.h"
+}
+
+#include "globals.hh"
+#include "monodroid-glue.hh"
+#include "monodroid-glue-internal.hh"
+#include "timing.hh"
+#include "java-interop.h"
+#include "cpu-arch.hh"
+
+extern "C" {
+ int _monodroid_getifaddrs (struct _monodroid_ifaddrs **ifap);
+ void _monodroid_freeifaddrs (struct _monodroid_ifaddrs *ifa);
+}
+
+mono_bool _monodroid_get_network_interface_up_state (const char *ifname, mono_bool *is_up);
+mono_bool _monodroid_get_network_interface_supports_multicast (const char *ifname, mono_bool *supports_multicast);
+int _monodroid_get_dns_servers (void **dns_servers_array);
+
+using namespace xamarin::android;
+using namespace xamarin::android::internal;
+
+static unsigned int
+monodroid_get_log_categories ()
+{
+ return log_categories;
+}
+
+static int
+monodroid_get_system_property (const char *name, char **value)
+{
+ return androidSystem.monodroid_get_system_property (name, value);
+}
+
+static int
+monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix)
+{
+ embeddedAssemblies.set_assemblies_prefix (prefix);
+ return 0;
+}
+
+static void
+monodroid_log (LogLevel level, LogCategories category, const char *message)
+{
+ switch (level) {
+ case LogLevel::Verbose:
+ case LogLevel::Debug:
+ log_debug_nocheck (category, message);
+ break;
+
+ case LogLevel::Info:
+ log_info_nocheck (category, message);
+ break;
+
+ case LogLevel::Warn:
+ case LogLevel::Silent: // warn is always printed
+ log_warn (category, message);
+ break;
+
+ case LogLevel::Error:
+ log_error (category, message);
+ break;
+
+ case LogLevel::Fatal:
+ log_fatal (category, message);
+ break;
+
+ default:
+ case LogLevel::Unknown:
+ case LogLevel::Default:
+ log_info_nocheck (category, message);
+ break;
+ }
+}
+
+static void
+monodroid_free (void *ptr)
+{
+ free (ptr);
+}
+
+static int
+_monodroid_max_gref_get ()
+{
+ return static_cast(androidSystem.get_max_gref_count ());
+}
+
+static int
+_monodroid_gref_get ()
+{
+ return osBridge.get_gc_gref_count ();
+}
+
+
+static void
+_monodroid_gref_log (const char *message)
+{
+ osBridge._monodroid_gref_log (message);
+}
+
+static int
+_monodroid_gref_log_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable)
+{
+ return osBridge._monodroid_gref_log_new (curHandle, curType, newHandle, newType, threadName, threadId, from, from_writable);
+}
+
+static void
+_monodroid_gref_log_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable)
+{
+ osBridge._monodroid_gref_log_delete (handle, type, threadName, threadId, from, from_writable);
+}
+
+static void
+_monodroid_weak_gref_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable)
+{
+ osBridge._monodroid_weak_gref_new (curHandle, curType, newHandle, newType, threadName, threadId, from, from_writable);
+}
+
+static void
+_monodroid_weak_gref_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable)
+{
+ osBridge._monodroid_weak_gref_delete (handle, type, threadName, threadId, from, from_writable);
+}
+
+static void
+_monodroid_lref_log_new (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable)
+{
+ osBridge._monodroid_lref_log_new (lrefc, handle, type, threadName, threadId, from, from_writable);
+}
+
+static void
+_monodroid_lref_log_delete (int lrefc, jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable)
+{
+ osBridge._monodroid_lref_log_delete (lrefc, handle, type, threadName, threadId, from, from_writable);
+}
+
+static void
+_monodroid_gc_wait_for_bridge_processing ()
+{
+ mono_gc_wait_for_bridge_processing ();
+}
+
+static int
+_monodroid_get_android_api_level ()
+{
+ return monodroidRuntime.get_android_api_level ();
+}
+
+static void
+monodroid_clear_gdb_wait ()
+{
+ monodroidRuntime.set_monodroid_gdb_wait (false);
+}
+
+static void*
+_monodroid_get_identity_hash_code (JNIEnv *env, void *v)
+{
+ intptr_t rv = env->CallStaticIntMethod (monodroidRuntime.get_java_class_System (), monodroidRuntime.get_java_class_method_System_identityHashCode (), v);
+ return (void*) rv;
+}
+
+static void*
+_monodroid_timezone_get_default_id ()
+{
+ JNIEnv *env = osBridge.ensure_jnienv ();
+ jmethodID getDefault = env->GetStaticMethodID (monodroidRuntime.get_java_class_TimeZone (), "getDefault", "()Ljava/util/TimeZone;");
+ jmethodID getID = env->GetMethodID (monodroidRuntime.get_java_class_TimeZone (), "getID", "()Ljava/lang/String;");
+ jobject d = env->CallStaticObjectMethod (monodroidRuntime.get_java_class_TimeZone (), getDefault);
+ jstring id = reinterpret_cast (env->CallObjectMethod (d, getID));
+ const char *mutf8 = env->GetStringUTFChars (id, nullptr);
+
+ if (mutf8 == nullptr) {
+ log_error (LOG_DEFAULT, "Failed to convert Java TimeZone ID to UTF8 (out of memory?)");
+ env->DeleteLocalRef (id);
+ env->DeleteLocalRef (d);
+ return nullptr;
+ }
+
+ char *def_id = strdup (mutf8);
+
+ env->ReleaseStringUTFChars (id, mutf8);
+ env->DeleteLocalRef (id);
+ env->DeleteLocalRef (d);
+
+ return def_id;
+}
+
+static void
+_monodroid_counters_dump (const char *format, va_list args)
+{
+ monodroidRuntime.dump_counters_v (format, args);
+}
+
+static managed_timing_sequence*
+monodroid_timing_start (const char *message)
+{
+ if (timing == nullptr)
+ return nullptr;
+
+ managed_timing_sequence *ret = timing->get_available_sequence ();
+ if (message != nullptr) {
+ log_info (LOG_TIMING, message);
+ }
+ ret->period.mark_start ();
+
+ return ret;
+}
+
+static void
+monodroid_timing_stop (managed_timing_sequence *sequence, const char *message)
+{
+ static constexpr const char DEFAULT_MESSAGE[] = "Managed Timing";
+
+ if (sequence == nullptr)
+ return;
+
+ sequence->period.mark_end ();
+ Timing::info (sequence->period, message == nullptr ? DEFAULT_MESSAGE : message);
+ timing->release_sequence (sequence);
+}
+
+static char**
+monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens)
+{
+ return utils.monodroid_strsplit (str, delimiter, max_tokens);
+}
+
+static void
+monodroid_strfreev (char **str_array)
+{
+ utils.monodroid_strfreev (str_array);
+}
+
+static char*
+monodroid_strdup_printf (const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ char *ret = utils.monodroid_strdup_vprintf (format, args);
+ va_end (args);
+
+ return ret;
+}
+
+static char*
+monodroid_TypeManager_get_java_class_name (jclass klass)
+{
+ return monodroidRuntime.get_java_class_name_for_TypeManager (klass);
+}
+
+static void
+monodroid_store_package_name (const char *name)
+{
+ utils.monodroid_store_package_name (name);
+}
+
+static int
+monodroid_get_namespaced_system_property (const char *name, char **value)
+{
+ return static_cast(androidSystem.monodroid_get_system_property (name, value));
+}
+
+static FILE*
+monodroid_fopen (const char* filename, const char* mode)
+{
+ return utils.monodroid_fopen (filename, mode);
+}
+
+static int
+send_uninterrupted (int fd, void *buf, int len)
+{
+ if (len < 0)
+ len = 0;
+ return utils.send_uninterrupted (fd, buf, static_cast(len));
+}
+
+static int
+recv_uninterrupted (int fd, void *buf, int len)
+{
+ if (len < 0)
+ len = 0;
+ return static_cast(utils.recv_uninterrupted (fd, buf, static_cast(len)));
+}
+
+static void
+set_world_accessable (const char *path)
+{
+ utils.set_world_accessable (path);
+}
+
+static void
+create_public_directory (const char *dir)
+{
+ utils.create_public_directory (dir);
+}
+
+static char*
+path_combine (const char *path1, const char *path2)
+{
+ return utils.path_combine (path1, path2);
+}
+
+static void*
+monodroid_dylib_mono_new ([[maybe_unused]] const char *libmono_path)
+{
+ return nullptr;
+}
+
+static void
+monodroid_dylib_mono_free ([[maybe_unused]] void *mono_imports)
+{
+ // no-op
+}
+
+/*
+ this function is used from JavaInterop and should be treated as public API
+ https://github.com/xamarin/java.interop/blob/master/src/java-interop/java-interop-gc-bridge-mono.c#L266
+
+ it should also accept libmono_path = nullptr parameter
+*/
+static int
+monodroid_dylib_mono_init (void *mono_imports, [[maybe_unused]] const char *libmono_path)
+{
+ if (mono_imports == nullptr)
+ return FALSE;
+ return TRUE;
+}
+
+static void*
+monodroid_get_dylib (void)
+{
+ return nullptr;
+}
+
+#define PINVOKE_SYMBOL(_sym_) { #_sym_, reinterpret_cast(&_sym_) }
+
+MonodroidRuntime::pinvoke_api_map MonodroidRuntime::xa_pinvoke_map = {
+ PINVOKE_SYMBOL (create_public_directory),
+ PINVOKE_SYMBOL (java_interop_free),
+ PINVOKE_SYMBOL (java_interop_jnienv_alloc_object),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_boolean_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_boolean_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_byte_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_byte_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_char_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_char_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_double_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_double_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_float_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_float_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_int_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_int_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_long_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_long_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_boolean_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_boolean_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_byte_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_byte_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_char_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_char_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_double_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_double_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_float_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_float_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_int_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_int_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_long_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_long_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_object_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_object_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_short_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_short_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_void_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_nonvirtual_void_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_object_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_object_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_short_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_short_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_boolean_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_boolean_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_byte_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_byte_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_char_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_char_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_double_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_double_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_float_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_float_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_int_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_int_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_long_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_long_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_object_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_object_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_short_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_short_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_void_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_static_void_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_void_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_call_void_method_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_define_class),
+ PINVOKE_SYMBOL (java_interop_jnienv_delete_global_ref),
+ PINVOKE_SYMBOL (java_interop_jnienv_delete_local_ref),
+ PINVOKE_SYMBOL (java_interop_jnienv_delete_weak_global_ref),
+ PINVOKE_SYMBOL (java_interop_jnienv_ensure_local_capacity),
+ PINVOKE_SYMBOL (java_interop_jnienv_exception_check),
+ PINVOKE_SYMBOL (java_interop_jnienv_exception_clear),
+ PINVOKE_SYMBOL (java_interop_jnienv_exception_describe),
+ PINVOKE_SYMBOL (java_interop_jnienv_exception_occurred),
+ PINVOKE_SYMBOL (java_interop_jnienv_fatal_error),
+ PINVOKE_SYMBOL (java_interop_jnienv_find_class),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_array_length),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_boolean_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_boolean_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_boolean_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_byte_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_byte_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_byte_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_char_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_char_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_char_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_direct_buffer_address),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_direct_buffer_capacity),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_double_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_double_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_double_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_field_id),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_float_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_float_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_float_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_int_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_int_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_int_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_java_vm),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_long_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_long_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_long_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_method_id),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_object_array_element),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_object_class),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_object_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_object_ref_type),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_primitive_array_critical),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_short_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_short_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_short_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_boolean_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_byte_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_char_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_double_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_field_id),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_float_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_int_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_long_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_method_id),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_object_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_static_short_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_string_chars),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_string_length),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_superclass),
+ PINVOKE_SYMBOL (java_interop_jnienv_get_version),
+ PINVOKE_SYMBOL (java_interop_jnienv_is_assignable_from),
+ PINVOKE_SYMBOL (java_interop_jnienv_is_instance_of),
+ PINVOKE_SYMBOL (java_interop_jnienv_is_same_object),
+ PINVOKE_SYMBOL (java_interop_jnienv_monitor_enter),
+ PINVOKE_SYMBOL (java_interop_jnienv_monitor_exit),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_boolean_array),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_byte_array),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_char_array),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_direct_byte_buffer),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_double_array),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_float_array),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_global_ref),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_int_array),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_local_ref),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_long_array),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_object),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_object_a),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_object_array),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_short_array),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_string),
+ PINVOKE_SYMBOL (java_interop_jnienv_new_weak_global_ref),
+ PINVOKE_SYMBOL (java_interop_jnienv_pop_local_frame),
+ PINVOKE_SYMBOL (java_interop_jnienv_push_local_frame),
+ PINVOKE_SYMBOL (java_interop_jnienv_register_natives),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_boolean_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_byte_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_char_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_double_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_float_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_int_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_long_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_primitive_array_critical),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_short_array_elements),
+ PINVOKE_SYMBOL (java_interop_jnienv_release_string_chars),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_boolean_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_boolean_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_byte_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_byte_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_char_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_char_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_double_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_double_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_float_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_float_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_int_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_int_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_long_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_long_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_object_array_element),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_object_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_short_array_region),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_short_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_static_boolean_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_static_byte_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_static_char_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_static_double_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_static_float_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_static_int_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_static_long_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_static_object_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_set_static_short_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_throw),
+ PINVOKE_SYMBOL (java_interop_jnienv_throw_new),
+ PINVOKE_SYMBOL (java_interop_jnienv_to_reflected_field),
+ PINVOKE_SYMBOL (java_interop_jnienv_to_reflected_method),
+ PINVOKE_SYMBOL (java_interop_jnienv_unregister_natives),
+ PINVOKE_SYMBOL (java_interop_strdup),
+ PINVOKE_SYMBOL (monodroid_clear_gdb_wait),
+ PINVOKE_SYMBOL (_monodroid_counters_dump),
+ PINVOKE_SYMBOL (_monodroid_detect_cpu_and_architecture),
+ PINVOKE_SYMBOL (monodroid_dylib_mono_free),
+ PINVOKE_SYMBOL (monodroid_dylib_mono_init),
+ PINVOKE_SYMBOL (monodroid_dylib_mono_new),
+ PINVOKE_SYMBOL (monodroid_embedded_assemblies_set_assemblies_prefix),
+ PINVOKE_SYMBOL (monodroid_fopen),
+ PINVOKE_SYMBOL (monodroid_free),
+ PINVOKE_SYMBOL (_monodroid_freeifaddrs),
+ PINVOKE_SYMBOL (_monodroid_gc_wait_for_bridge_processing),
+ PINVOKE_SYMBOL (_monodroid_get_android_api_level),
+ PINVOKE_SYMBOL (_monodroid_get_dns_servers),
+ PINVOKE_SYMBOL (monodroid_get_dylib),
+ PINVOKE_SYMBOL (_monodroid_get_identity_hash_code),
+ PINVOKE_SYMBOL (_monodroid_getifaddrs),
+ PINVOKE_SYMBOL (monodroid_get_log_categories),
+ PINVOKE_SYMBOL (monodroid_get_namespaced_system_property),
+ PINVOKE_SYMBOL (_monodroid_get_network_interface_supports_multicast),
+ PINVOKE_SYMBOL (_monodroid_get_network_interface_up_state),
+ PINVOKE_SYMBOL (monodroid_get_system_property),
+ PINVOKE_SYMBOL (_monodroid_gref_get),
+ PINVOKE_SYMBOL (_monodroid_gref_log),
+ PINVOKE_SYMBOL (_monodroid_gref_log_delete),
+ PINVOKE_SYMBOL (_monodroid_gref_log_new),
+ PINVOKE_SYMBOL (monodroid_log),
+ PINVOKE_SYMBOL (_monodroid_lref_log_delete),
+ PINVOKE_SYMBOL (_monodroid_lref_log_new),
+ PINVOKE_SYMBOL (_monodroid_max_gref_get),
+ PINVOKE_SYMBOL (monodroid_store_package_name),
+ PINVOKE_SYMBOL (monodroid_strdup_printf),
+ PINVOKE_SYMBOL (monodroid_strfreev),
+ PINVOKE_SYMBOL (monodroid_strsplit),
+ PINVOKE_SYMBOL (_monodroid_timezone_get_default_id),
+ PINVOKE_SYMBOL (monodroid_timing_start),
+ PINVOKE_SYMBOL (monodroid_timing_stop),
+ PINVOKE_SYMBOL (monodroid_TypeManager_get_java_class_name),
+ PINVOKE_SYMBOL (_monodroid_weak_gref_delete),
+ PINVOKE_SYMBOL (_monodroid_weak_gref_new),
+ PINVOKE_SYMBOL (path_combine),
+ PINVOKE_SYMBOL (recv_uninterrupted),
+ PINVOKE_SYMBOL (send_uninterrupted),
+ PINVOKE_SYMBOL (set_world_accessable),
+};
+
+MonodroidRuntime::pinvoke_library_map MonodroidRuntime::other_pinvoke_map (MonodroidRuntime::LIBRARY_MAP_INITIAL_BUCKET_COUNT);
+
+// `pinvoke_map_write_lock` MUST be held when calling this method
+force_inline void*
+MonodroidRuntime::load_library_entry (std::string const& library_name, std::string const& entrypoint_name, pinvoke_api_map_ptr api_map)
+{
+ // Make sure some other thread hasn't just added the entry
+ auto iter = api_map->find (entrypoint_name);
+ if (iter != api_map->end () && iter->second != nullptr) {
+ return iter->second;
+ }
+
+ void *lib_handle = monodroid_dlopen (library_name.c_str (), MONO_DL_LOCAL, nullptr, nullptr);
+ if (lib_handle == nullptr) {
+ log_warn (LOG_ASSEMBLY, "Shared library '%s' not loaded, p/invoke '%s' may fail", library_name.c_str (), entrypoint_name.c_str ());
+ return nullptr;
+ }
+
+ void *entry_handle = monodroid_dlsym (lib_handle, entrypoint_name.c_str (), nullptr, nullptr);
+ if (entry_handle == nullptr) {
+ log_warn (LOG_ASSEMBLY, "Symbol '%s' not found in shared library '%s', p/invoke may fail", entrypoint_name.c_str (), library_name.c_str ());
+ return nullptr;
+ }
+
+ log_warn (LOG_ASSEMBLY, "Caching p/invoke entry %s @ %s", library_name.c_str (), entrypoint_name.c_str ());
+ (*api_map)[entrypoint_name] = entry_handle;
+ return entry_handle;
+}
+
+force_inline void*
+MonodroidRuntime::fetch_or_create_pinvoke_map_entry (std::string const& library_name, std::string const& entrypoint_name, pinvoke_api_map_ptr api_map, bool need_lock)
+{
+ auto iter = api_map->find (entrypoint_name);
+ if (iter != api_map->end () && iter->second != nullptr) {
+ return iter->second;
+ }
+
+ if (!need_lock) {
+ return load_library_entry (library_name, entrypoint_name, api_map);
+ }
+
+ std::lock_guard lock (pinvoke_map_write_lock);
+ return load_library_entry (library_name, entrypoint_name, api_map);
+}
+
+void*
+MonodroidRuntime::monodroid_pinvoke_override (const char *library_name, const char *entrypoint_name)
+{
+ log_warn (LOG_DEFAULT, "MonodroidRuntime::monodroid_pinvoke_override (\"%s\", \"%s\")", library_name, entrypoint_name);
+
+ timing_period total_time;
+ if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) {
+ total_time.mark_start ();
+ }
+
+ if (library_name == nullptr || *library_name == '\0' || entrypoint_name == nullptr || *entrypoint_name == '\0') {
+ return nullptr;
+ }
+
+ bool is_internal;
+ switch (library_name[0]) {
+ case 'j':
+ is_internal = strcmp ("java-interop", library_name) == 0;
+ break;
+
+ case 'x':
+ is_internal = strcmp ("xa-internal-api", library_name) == 0;
+ break;
+
+ default:
+ is_internal = false;
+ break;
+ }
+
+ if (!is_internal) {
+ std::string lib_name (library_name);
+ std::string func_name (entrypoint_name);
+
+ auto iter = other_pinvoke_map.find (lib_name);
+ void *handle = nullptr;
+ if (iter == other_pinvoke_map.end ()) {
+ std::lock_guard lock (pinvoke_map_write_lock);
+
+ pinvoke_api_map_ptr lib_map;
+ // Make sure some other thread hasn't just added the map
+ iter = other_pinvoke_map.find (lib_name);
+ if (iter == other_pinvoke_map.end () || iter->second == nullptr) {
+ lib_map = new pinvoke_api_map (1);
+ other_pinvoke_map[lib_name] = lib_map;
+ } else {
+ lib_map = iter->second;
+ }
+
+ handle = fetch_or_create_pinvoke_map_entry (lib_name, func_name, lib_map, /* need_lock */ false);
+ } else {
+ if (XA_UNLIKELY (iter->second == nullptr)) {
+ log_warn (LOG_ASSEMBLY, "Internal error: null entry in p/invoke map for key '%s'", library_name);
+ return nullptr; // fall back to `monodroid_dlopen`
+ }
+
+ handle = fetch_or_create_pinvoke_map_entry (lib_name, func_name, iter->second, /* need_lock */ true);
+ }
+
+ if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) {
+ total_time.mark_end ();
+
+ TIMING_LOG_INFO (total_time, "p/invoke override for '%s' (foreign)", entrypoint_name);
+ }
+
+ return handle;
+ }
+
+ timing_period lookup_time;
+ if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) {
+ lookup_time.mark_start ();
+ }
+ auto iter = xa_pinvoke_map.find (entrypoint_name);
+ if (iter == xa_pinvoke_map.end ()) {
+ // TODO: perhaps it should be fatal?
+ log_fatal (LOG_ASSEMBLY, "Internal p/invoke symbol '%s @ %s' not found in compile-time map.", library_name, entrypoint_name);
+ abort ();
+ return nullptr;
+ }
+
+ if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) {
+ lookup_time.mark_end ();
+ total_time.mark_end ();
+
+ TIMING_LOG_INFO (lookup_time, "p/invoke cache lookup for '%s' (internal)", entrypoint_name);
+ TIMING_LOG_INFO (total_time, "p/invoke override for '%s' (internal)", entrypoint_name);
+ }
+ log_warn (LOG_DEFAULT, "Found %s@%s in internal p/invoke map (%p)", library_name, entrypoint_name, iter->second);
+ return iter->second;
+}
diff --git a/src/monodroid/jni/util.hh b/src/monodroid/jni/util.hh
index 936a0d3380c..15b2fa02938 100644
--- a/src/monodroid/jni/util.hh
+++ b/src/monodroid/jni/util.hh
@@ -42,6 +42,7 @@ constexpr int FALSE = 0;
#include "java-interop-util.h"
#include "logger.hh"
+#if !defined (NET6)
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
@@ -59,7 +60,10 @@ extern "C" {
MONO_API char *path_combine (const char *path1, const char *path2);
#ifdef __cplusplus
}
+#endif // __cplusplus
+#endif // NET6
+#ifdef __cplusplus
namespace xamarin::android
{
class Util : public BasicUtilities
diff --git a/src/monodroid/monodroid.targets b/src/monodroid/monodroid.targets
index 662ece0d650..9610c46361d 100644
--- a/src/monodroid/monodroid.targets
+++ b/src/monodroid/monodroid.targets
@@ -42,7 +42,9 @@
<_ConfigureRuntimesInputs Include="CMakeLists.txt" />
<_ConfigureRuntimesInputs Include="..\..\build-tools\scripts\Ndk.targets" />
<_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(Identity)-Debug\CMakeCache.txt')" />
+ <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(Identity)-net6-Debug\CMakeCache.txt')" />
<_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(Identity)-Release\CMakeCache.txt')" />
+ <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(Identity)-net6-Release\CMakeCache.txt')" />
<_ConfigureRuntimesOutputs Include="@(_HostRuntime->'$(IntermediateOutputPath)%(OutputDirectory)-Debug\CMakeCache.txt')" />
<_ConfigureRuntimesOutputs Include="@(_HostRuntime->'$(IntermediateOutputPath)%(OutputDirectory)-Release\CMakeCache.txt')" />
@@ -66,17 +68,27 @@
DependsOnTargets="_FindMonoDroidSources">
<_BuildAndroidRuntimesInputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(Identity)-Debug\CMakeCache.txt')" />
+ <_BuildAndroidRuntimesInputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(Identity)-net6-Debug\CMakeCache.txt')" />
<_BuildAndroidRuntimesInputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(Identity)-Release\CMakeCache.txt')" />
+ <_BuildAndroidRuntimesInputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(Identity)-net6-Release\CMakeCache.txt')" />
<_BuildAndroidRuntimesInputs Include="@(_MonoDroidSources)" />
<_BuildAndroidRuntimesInputs Include="..\..\build-tools\scripts\Ndk.targets" />
<_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)\libmono-android.debug.so')" />
+ <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)-net6\libmono-android.debug.so')" />
<_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)\libmono-android-checked+ubsan.debug.so')" />
+ <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)-net6\libmono-android-checked+ubsan.debug.so')" />
<_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)\libmono-android-checked+asan.debug.so')" />
+ <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)-net6\libmono-android-checked+asan.debug.so')" />
<_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)\libmono-android.release.so')" />
+ <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)-net6\libmono-android.release.so')" />
<_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)\libmono-android-checked+asan.release.so')" />
+ <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)-net6\libmono-android-checked+asan.release.so')" />
<_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)\libmono-android-checked+ubsan.release.so')" />
+ <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)-net6\libmono-android-checked+ubsan.release.so')" />
<_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)\Debug\libxamarin-app.so')" />
+ <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)-net6\Debug\libxamarin-app.so')" />
<_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)\Release\libxamarin-app.so')" />
+ <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(Identity)-net6\Release\libxamarin-app.so')" />
@@ -89,31 +101,61 @@
WorkingDirectory="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.Identity)-Debug"
/>
+
+
+
+
+
+
+
+
+
+
+
+