diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets index b1717d2b0fe..f69a7ec4214 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets @@ -239,11 +239,13 @@ _ResolveAssemblies MSBuild target. <_ResolvedNativeLibraries Include="@(ResolvedFileToPublish)" Condition=" '%(ResolvedFileToPublish.Extension)' == '.so' " /> - + <_MonoComponent Condition=" '$(AndroidEnableProfiler)' == 'true' " Include="diagnostics_tracing" /> <_MonoComponent Condition=" '$(AndroidUseInterpreter)' == 'true' " Include="hot_reload" /> <_MonoComponent Condition=" '$(AndroidIncludeDebugSymbols)' == 'true' " Include="debugger" /> <_MonoComponent Condition=" '$(_AndroidExcludeMarshalIlgenComponent)' != 'true' " Include="marshal-ilgen" /> + + <_ExcludedNativeLibraries Condition=" '$(_AndroidIncludeSystemGlobalizationNative)' != 'true' " Include="libSystem.Globalization.Native" /> <_ExcludedNativeLibraries Condition=" '$(_AndroidEnableNativeStackTracing)' != 'true' " Include="libxamarin-native-tracing" /> @@ -274,6 +276,17 @@ _ResolveAssemblies MSBuild target. KnownRuntimeNativeLibraries="@(_KnownRuntimeNativeLibrary)"> + + + + arm64-v8a + + + x86_64 + + diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets index e9c75e1667d..2a13ef1a3f0 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets @@ -21,9 +21,6 @@ <_AndroidFastDeploymentSupported Condition=" Exists ('$(MSBuildThisFileDirectory)../tools/Xamarin.Android.Common.Debugging.targets') ">true <_AndroidFastDeploymentSupported Condition=" '$(_AndroidFastDeploymentSupported)' == '' ">False - - true - True + + True diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeApplicationConfigSources.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeApplicationConfigSources.cs index 81a4ef23e30..bbb3b6ac654 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeApplicationConfigSources.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeApplicationConfigSources.cs @@ -72,6 +72,7 @@ public class GenerateNativeApplicationConfigSources : AndroidTask public string? AndroidSequencePointsMode { get; set; } public bool EnableSGenConcurrent { get; set; } public string? CustomBundleConfigFile { get; set; } + public bool EnableDebugger { get; set; } bool _Debug { get { @@ -118,13 +119,20 @@ public override bool RunTask () envBuilder.AddDefaultDebugBuildLogLevel (); } - if (androidRuntime != Xamarin.Android.Tasks.AndroidRuntime.NativeAOT) { - AddDefaultEnvironmentVariables (envBuilder, HttpClientHandlerType, EnableSGenConcurrent); - } else { + if (androidRuntime == Xamarin.Android.Tasks.AndroidRuntime.NativeAOT) { // NativeAOT sets all the environment variables from Java, we don't want to repeat that // process in the native code. This is just a precaution, because NativeAOT builds should // not even use this task. envBuilder.EnvironmentVariables.Clear (); + } else if (androidRuntime == Xamarin.Android.Tasks.AndroidRuntime.CoreCLR) { + // CoreCLR needs the HTTP client handler type + envBuilder.AddHttpClientHandlerType (HttpClientHandlerType); + } else { + AddDefaultEnvironmentVariables (envBuilder, HttpClientHandlerType, EnableSGenConcurrent); + } + + if (EnableDebugger && TargetsCLR) { + envBuilder.AddDebuggerEnvironment (); } global::Android.Runtime.BoundExceptionType boundExceptionType; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs index 1f5d51ef909..fbb82251eea 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs @@ -237,5 +237,116 @@ public void CheckHttpClientHandlerType ([Values] AndroidRuntime runtime) Assert.AreEqual (expectedUpdatedValue, envvars[httpClientHandlerVarName]); } } + + [Test] + public void CheckDebuggerEnvironmentVariables () + { + const string supportedAbis = "arm64-v8a;x86_64"; + + var proj = new XamarinAndroidApplicationProject () { + IsRelease = false, + }; + + proj.SetRuntime (AndroidRuntime.CoreCLR); + proj.SetProperty ("AndroidEnableDebugger", "true"); + proj.SetAndroidSupportedAbis (supportedAbis); + + using (var b = CreateApkBuilder ()) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + + string intermediateOutputDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath); + List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, AndroidRuntime.CoreCLR); + Dictionary envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, AndroidRuntime.CoreCLR); + Assert.IsTrue (envvars.Count > 0, $"No environment variables defined"); + + Assert.IsTrue (envvars.ContainsKey ("CORECLR_ENABLE_PROFILING"), "Environment should contain CORECLR_ENABLE_PROFILING"); + Assert.AreEqual ("1", envvars ["CORECLR_ENABLE_PROFILING"], "CORECLR_ENABLE_PROFILING should be '1'"); + + Assert.IsTrue (envvars.ContainsKey ("CORECLR_PROFILER"), "Environment should contain CORECLR_PROFILER"); + Assert.AreEqual ("{9DC623E8-C88F-4FD5-AD99-77E67E1D9631}", envvars ["CORECLR_PROFILER"], "CORECLR_PROFILER GUID mismatch"); + + Assert.IsTrue (envvars.ContainsKey ("CORECLR_PROFILER_PATH"), "Environment should contain CORECLR_PROFILER_PATH"); + Assert.AreEqual ("libremotemscordbitarget.so", envvars ["CORECLR_PROFILER_PATH"], "CORECLR_PROFILER_PATH should point to libremotemscordbitarget.so"); + + Assert.IsFalse (envvars.ContainsKey ("MONO_GC_PARAMS"), "CoreCLR builds should not set MONO_GC_PARAMS"); + Assert.IsFalse (envvars.ContainsKey ("MONO_DEBUG"), "CoreCLR builds should not set MONO_DEBUG"); + } + } + + [Test] + public void CheckDebuggerNativeLibraryInApk () + { + const string supportedAbis = "arm64-v8a;x86_64"; + + var proj = new XamarinAndroidApplicationProject () { + IsRelease = false, + }; + + proj.SetRuntime (AndroidRuntime.CoreCLR); + proj.SetProperty ("AndroidEnableDebugger", "true"); + proj.SetAndroidSupportedAbis (supportedAbis); + + using (var b = CreateApkBuilder ()) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + + string apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}-Signed.apk"); + Assert.IsTrue (File.Exists (apk), $"APK not found at {apk}"); + + foreach (var abi in supportedAbis.Split (';')) { + string entryPath = $"lib/{abi}/libremotemscordbitarget.so"; + var data = ZipHelper.ReadFileFromZip (apk, entryPath); + Assert.IsNotNull (data, $"{entryPath} should be present in the APK"); + Assert.IsTrue (data.Length > 0, $"{entryPath} should not be empty"); + } + } + } + + [Test] + public void CheckDebuggerNativeLibraryNotInReleaseApk () + { + const string supportedAbis = "arm64-v8a"; + + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + }; + + proj.SetRuntime (AndroidRuntime.CoreCLR); + proj.SetAndroidSupportedAbis (supportedAbis); + + using (var b = CreateApkBuilder ()) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + + string apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}-Signed.apk"); + Assert.IsTrue (File.Exists (apk), $"APK not found at {apk}"); + + string entryPath = $"lib/{supportedAbis}/libremotemscordbitarget.so"; + var data = ZipHelper.ReadFileFromZip (apk, entryPath); + Assert.IsNull (data, $"{entryPath} should NOT be present in Release APK"); + } + } + + [Test] + public void CheckDebuggerNotEnabledInRelease () + { + const string supportedAbis = "arm64-v8a"; + + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + }; + + proj.SetRuntime (AndroidRuntime.CoreCLR); + proj.SetAndroidSupportedAbis (supportedAbis); + + using (var b = CreateApkBuilder ()) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + + string intermediateOutputDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath); + List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, AndroidRuntime.CoreCLR); + Dictionary envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, AndroidRuntime.CoreCLR); + + Assert.IsFalse (envvars.ContainsKey ("CORECLR_ENABLE_PROFILING"), "Release builds should not enable CoreCLR profiling"); + Assert.IsFalse (envvars.ContainsKey ("CORECLR_PROFILER"), "Release builds should not set CORECLR_PROFILER"); + } + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/EnvironmentBuilder.cs b/src/Xamarin.Android.Build.Tasks/Utilities/EnvironmentBuilder.cs index 51121c052bf..324ef330af4 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/EnvironmentBuilder.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/EnvironmentBuilder.cs @@ -108,5 +108,12 @@ public void AddMonoGcParams (bool enableSgenConcurrent) AddEnvironmentVariable ("MONO_GC_PARAMS", enableSgenConcurrent ? "major=marksweep-conc" : "major=marksweep"); } + public void AddDebuggerEnvironment () + { + AddEnvironmentVariable ("CORECLR_ENABLE_PROFILING", "1"); + AddEnvironmentVariable ("CORECLR_PROFILER", "{9DC623E8-C88F-4FD5-AD99-77E67E1D9631}"); + AddEnvironmentVariable ("CORECLR_PROFILER_PATH", "libremotemscordbitarget.so"); + } + static string ValidAssemblerString (string s) => s.Replace ("\\", "\\\\").Replace ("\"", "\\\""); } diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 2b0c321c53a..efc58817eb3 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -1715,6 +1715,11 @@ because xbuild doesn't support framework reference assemblies. <_AllNativeLibraries Include="@(AndroidNativeLibrary);@(EmbeddedNativeLibrary);@(FrameworkNativeLibrary)" /> + + + <_AndroidNativeLibraryNeverJniPreload Include="libremotemscordbitarget.so" /> + + @@ -1751,6 +1756,7 @@ because xbuild doesn't support framework reference assemblies. TargetsCLR="$(_AndroidUseCLR)" AndroidRuntime="$(_AndroidRuntime)" ProjectRuntimeConfigFilePath="$(ProjectRuntimeConfigFilePath)" + EnableDebugger="$(AndroidEnableDebugger)" >