From 8d6b76d7863e60f0cc7a720a8eb5664cde797af3 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 12 May 2021 14:15:35 +0100 Subject: [PATCH 01/10] [Xamarin.Android.Build.Tasks] Add Support for AndroidJavaSource to Bindings It would be nice to be able to introduce custom Java code and API's to a binding project. This would allow developers to simplify an API and still expose that to the C# Developer. Using the existing `AndroidJavaSource` ItemGroup we can do exactly that. This ItemGroup now supports the `Bind` metadata which will build and bind the java code *prior* to the main C# compiled running. Historically `AndroidJavaSource` was only available on Application Projects. However this ItemGroup can now be used in any project type. The `Bind` metadata is `true` by default and will cause the Java code to be compiled into a .jar file before the C# compiler is run. It will then be bound using the Java.Interop Java->C# binding system. The final C# apis will be generated an included in the final C# compilation. There are some restrictions on the Java code. You can only use Java types or types which are defined in .jar or .aar files you reference for that project via `AndroidLibrary` or `EmbeddedJar`. It is advised that you DO NOT export types which include Java Generics via this mechanism. Like normal bindings, Java Generics cause significant problems. Try to stuck to normal types if you can. --- .vscode/settings.json | 4 +- Documentation/guides/BindingJavaSource.md | 104 +++++++++++++ .../installers/create-installers.targets | 1 + .../Xamarin.Android.AvailableItems.targets | 3 + ...amarin.Android.Bindings.ClassParse.targets | 2 +- .../Xamarin.Android.Bindings.Core.targets | 9 +- .../Android/Xamarin.Android.Javac.targets | 141 ++++++++++++++++++ .../Sdk/AutoImport.props | 1 + .../Microsoft.Android.Sdk.BuildOrder.targets | 12 +- .../Tasks/ClassParse.cs | 2 +- .../Tasks/Generator.cs | 4 +- .../Tasks/GetJavaPlatformJar.cs | 2 +- .../Tasks/JavaCompileToolTask.cs | 13 +- .../Tasks/Javac.cs | 1 + .../BindingBuildTest.cs | 66 +++++++- .../Xamarin.Android.Build.Tests/BuildTest2.cs | 6 +- .../IncrementalBuildTest.cs | 1 + .../Resources/JavaSourceTestExtension.java | 7 + .../Utilities/ResourceData.cs | 3 + .../Xamarin.Android.Build.Tests/XASdkTests.cs | 40 +++++ .../Xamarin.ProjectTools/Common/Builder.cs | 3 +- .../Xamarin.Android.Bindings.targets | 19 ++- .../Xamarin.Android.Build.Tasks.targets | 4 + .../Xamarin.Android.Common.targets | 77 +--------- .../Xamarin.Android.Tooling.targets | 9 ++ .../Tests/UncaughtExceptionTests.cs | 2 +- 26 files changed, 432 insertions(+), 104 deletions(-) create mode 100644 Documentation/guides/BindingJavaSource.md create mode 100644 src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets create mode 100644 src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/JavaSourceTestExtension.java diff --git a/.vscode/settings.json b/.vscode/settings.json index 86dd807da21..a500d3e01c7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,6 @@ { "nxunitExplorer.modules": [ - "bin/TestDebug/MSBuildDeviceIntegration/net472/MSBuildDeviceIntegration.dll", - "bin/TestDebug/net472/Xamarin.Android.Build.Tests.dll", - "bin/TestRelease/MSBuildDeviceIntegration/net472/MSBuildDeviceIntegration.dll", + "bin/Test*/**/net472/*.dll", ], "cmake.configureOnOpen": false, "dotnetCoreExplorer.searchpatterns": "bin/Test{Debug,Release}/**/net6.0/{Xamarin.Android.Build.Tests,MSBuildDeviceIntegration}.dll", diff --git a/Documentation/guides/BindingJavaSource.md b/Documentation/guides/BindingJavaSource.md new file mode 100644 index 00000000000..1896cad3ecf --- /dev/null +++ b/Documentation/guides/BindingJavaSource.md @@ -0,0 +1,104 @@ +--- +id: +title: "Binding Java Source" +dateupdated: 2021-05-21 +--- + +# Overview + +With .net 6 Bindings can be done on not only .jar and .aar files +but also raw .java code. This will allow developers of bindings +or applications to write custom API's for underlying bindings +and expose them easily to the developer. + +Applications already had the ability to include `AndroidJavaSource` +items in them, these would then be compiled into the final `classes.dex`. +However this custom java source code was not "bound" and if users wanted +to call these classes they would need to do that manually. + +The `AndroidJavaSource` Item Group now supports a `Bind` attribute. This +will instruct the build system to not only compile the code but also +produce a C# API for it. + +The `%(Bind)` attribute metadata is `True` by default. If you do not want +to bind the Java code, set `%(Bind)` to `False`. + +```xml + + + +``` + +# Example + +Consider the following Java code. + +```java +package com.xamarin.test; + +class MyClass { + public boolean IsDave (String name) + { + return name.equals ("Dave"); + } +} +``` + +We want to bind this into a C# API in our app project. By default +the app project will pick up ALL `.java` files and add them to +the `AndroidJavaSource` ItemGroup. The `Bind` attribute is `true` +by default as well so it will be automatically bound. + +```xml + + + +``` + +When we build the app, the java code will be compiled into a +.jar file which matches the application project name. +This .jar will then be bound and the generated C# API will end +up being something like this. + +```csharp +using System; + +namespace Com.Xamarin.Test { + public class MyClass : Java.Lang.Object { + public virtual bool IsDave (string name){ + // binding code + } + } +} +``` + +All this will happen before the main C# code is compiled. The binding +code will be included in the C# compile process, so you can use the +code directly in your app. + +```csharp +public class MainActivity : Activity { + public override void OnCreate() + { + var c = new MyClass (); + c.IsDave ("Bob"); + } +} +``` + + +# Limitations + +This feature is only available in .net 6. + +You will be limited to standard java types and any types that +are available in a .jar or .aar which you reference. + +You CANNOT use Java Generics. The Binding process currently does not +really support Java Generic very well. So stick to primitive types +or normal classes as much as possible. This is so that you don't need +to use the metadata.xml to alter the API of the Java class. + +Because of the point at which the Java compilation happens in this case +(before Csc), you will not be able to access any of the `R.*` Resource +types either. \ No newline at end of file diff --git a/build-tools/installers/create-installers.targets b/build-tools/installers/create-installers.targets index b0ce8279e3a..3a18d226aa9 100644 --- a/build-tools/installers/create-installers.targets +++ b/build-tools/installers/create-installers.targets @@ -288,6 +288,7 @@ <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.DX.targets" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.EmbeddedResource.targets" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.FSharp.targets" ExcludeFromAndroidNETSdk="true" /> + <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Javac.targets" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Legacy.targets" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.PCLSupport.props" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.PCLSupport.targets" ExcludeFromAndroidNETSdk="true" /> diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.AvailableItems.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.AvailableItems.targets index 4d11ec2c80d..3e63db73393 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.AvailableItems.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.AvailableItems.targets @@ -66,6 +66,9 @@ This item group populates the Build Action drop-down in IDEs. true true + + true + true diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets index de37de3657f..e0f1240f3d1 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets @@ -52,7 +52,7 @@ This file is only used by binding projects. - + $(IntermediateOutputPath)generated\ intellisense $(IntermediateOutputPath)api.xml - <_GeneratorStampFile>$(IntermediateOutputPath)generator.stamp + <_GeneratorStampFile>$(_AndroidStampDirectory)generator.stamp @@ -29,7 +29,7 @@ It is shared between "legacy" binding projects and .NET 5 projects. + Condition=" '@(InputJar->Count())' != '0' Or '@(EmbeddedJar->Count())' != '0' Or '@(LibraryProjectZip->Count())' != '0' Or '@(_JavaBindingSource->Count())' != '0' "> <_AndroidGenerateManagedBindings>true @@ -115,13 +115,14 @@ It is shared between "legacy" binding projects and .NET 5 projects. + - + - + diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets new file mode 100644 index 00000000000..fb73f8e6c03 --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets @@ -0,0 +1,141 @@ + + + + + + + + + + <_AndroidIntermediateBindingJavaClassDirectory>$(IntermediateOutputPath)binding\bin\classes\ + <_AndroidIntermediateBindingJavaSourceDirectory>$(IntermediateOutputPath)binding\src + <_AndroidIntermediateBindingClassesZip>$(IntermediateOutputPath)binding\bin\$(MSBuildProjectName).jar + <_AndroidCompileJavaStampFile>$(_AndroidStampDirectory)_CompileJava.stamp + <_AndroidCompileBindingJavaStampFile>$(_AndroidStampDirectory)_CompileBindingJava.stamp + + + + + + + + + + + + + + + + + + + + + + + + + <_JavaLibrariesToCompileForApp Include="@(_JavaLibrariesToCompile)" Condition=" '$(_InstantRunEnabled)' != 'True' " /> + + + + + + + <_JavaBindingSource Include="@(AndroidJavaSource)" Condition=" '%(AndroidJavaSource.Bind)' == 'True' " /> + + + + + + <_JavaSource Include="@(AndroidJavaSource)" Condition=" '%(AndroidJavaSource.Bind)' != 'True' " /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props index c29ff35a393..b87c047a612 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props @@ -48,6 +48,7 @@ https://github.com/dotnet/designs/blob/4703666296f5e59964961464c25807c727282cae/ + diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets index 2099fa39190..fd9d173e3a1 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets @@ -25,6 +25,8 @@ projects, these properties are set in Xamarin.Android.Legacy.targets. _CheckForObsoleteFrameworkAssemblies; _ValidateAndroidPackageProperties; AddLibraryJarsToBind; + _CollectJavaSourceForBinding; + _CompileBindingJava; $(BuildDependsOn); _CompileDex; $(_AfterCompileDex); @@ -92,7 +94,10 @@ projects, these properties are set in Xamarin.Android.Legacy.targets. _RemoveLegacyDesigner; _ValidateAndroidPackageProperties; AddLibraryJarsToBind; + _CollectJavaSourceForBinding; + _CompileBindingJava; $(BuildDependsOn); + _CreateAar; _AddFilesToFileWrites; @@ -120,7 +125,6 @@ projects, these properties are set in Xamarin.Android.Legacy.targets. _CheckForDeletedResourceFile; _ComputeAndroidResourcePaths; _UpdateAndroidResgen; - _CreateAar; _SetupMSBuildAllProjects; @@ -155,6 +159,7 @@ projects, these properties are set in Xamarin.Android.Legacy.targets. _ExtractLibraryProjectImports; _GetLibraryImports; _ExtractAar; + _CollectJavaSourceForBinding; _ExportJarToXml; @@ -167,6 +172,11 @@ projects, these properties are set in Xamarin.Android.Legacy.targets. <_ResolveLibraryProjectsDependsOn> _ExtractAar; + <_CompileBindingJavaDependsOnTargets> + _AdjustJavacVersionArguments; + _DetermineBindingJavaLibrariesToCompile; + _GetJavaPlatformJar; + diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ClassParse.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ClassParse.cs index fe99bcea1d9..984bc8b4ab1 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ClassParse.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ClassParse.cs @@ -38,7 +38,7 @@ protected override string GenerateCommandLineCommands () WriteLine (sw, $"\"{doc}\""); } - cmd.AppendSwitch ($"@{responseFile}"); + cmd.AppendSwitch ($"\"@{responseFile}\""); return cmd.ToString (); } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs index e4ab768c852..f9b434e0e45 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs @@ -236,8 +236,8 @@ protected override string GenerateCommandLineCommands () WriteLine (sw, "--use-legacy-java-resolver=true"); } - cmd.AppendSwitch (ApiXmlInput); - cmd.AppendSwitch ($"@{responseFile}"); + cmd.AppendSwitch ($"\"{ApiXmlInput}\""); + cmd.AppendSwitch ($"\"@{responseFile}\""); return cmd.ToString (); } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs index 879db6f1e49..5586e0c2ec9 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs @@ -128,7 +128,7 @@ string GetTargetSdkVersion (string target, XAttribute target_sdk) ); return targetFrameworkVersion; } - return targetSdkVersion; + return targetSdkVersion ?? targetFrameworkVersion; } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/JavaCompileToolTask.cs b/src/Xamarin.Android.Build.Tasks/Tasks/JavaCompileToolTask.cs index 27e41a9e306..a3c1a73f6c3 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/JavaCompileToolTask.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/JavaCompileToolTask.cs @@ -15,7 +15,6 @@ namespace Xamarin.Android.Tasks public abstract class JavaCompileToolTask : JavaToolTask { - [Required] public string StubSourceDirectory { get; set; } public ITaskItem[] JavaSourceFiles { get; set; } @@ -27,9 +26,9 @@ protected override string ToolName { } private bool IsRunningInsideVS { - get { + get { var vside = false; - return bool.TryParse(Environment.GetEnvironmentVariable("VSIDE"), out vside) && vside; + return bool.TryParse(Environment.GetEnvironmentVariable("VSIDE"), out vside) && vside; } } @@ -65,7 +64,13 @@ private void GenerateResponseFile () // Include any user .java files if (JavaSourceFiles != null) foreach (var file in JavaSourceFiles.Where (p => Path.GetExtension (p.ItemSpec) == ".java")) - sw.WriteLine (string.Format ("\"{0}\"", file.ItemSpec.Replace (@"\", @"\\"))); + sw.WriteLine (string.Format ("\"{0}\"", file.ItemSpec.Replace (@"\", @"\\"))); + + if (string.IsNullOrEmpty (StubSourceDirectory)) + return; + + if (!Directory.Exists (StubSourceDirectory)) + return; foreach (var file in Directory.GetFiles (StubSourceDirectory, "*.java", SearchOption.AllDirectories)) { // This makes sense. BAD sense. but sense. diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs index 483bf9be55b..b7df052a49f 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using Xamarin.Tools.Zip; using Xamarin.Android.Tools; +using Microsoft.Android.Build.Tasks; namespace Xamarin.Android.Tasks { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs index 07c1c103abc..a806c92fcac 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs @@ -4,8 +4,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Xml.Linq; using Xamarin.ProjectTools; +using Microsoft.Android.Build.Tasks; namespace Xamarin.Android.Build.Tests { @@ -198,7 +200,7 @@ public override Java.Lang.Object LoadInBackground () { return (Java.Lang.Object) LoadInBackgroundImpl (); } - } + } }" }); using (var b = CreateDllBuilder ()) { @@ -357,7 +359,7 @@ public void BindingCheckHiddenFiles () FileAssert.DoesNotExist (Path.Combine (dsStorePath, ".DS_Store")); DirectoryAssert.DoesNotExist (Path.Combine (dsStorePath, "_MACOSX")); var svgJar = Builder.UseDotNet ? - Path.Combine (libraryProjects, assemblyIdentityMap.IndexOf ($"{binding.ProjectName}.aar").ToString (), "jl", "libs", "FD575F2BC294C4A9.jar") : + Path.Combine (libraryProjects, assemblyIdentityMap.IndexOf ($"{binding.ProjectName}.aar").ToString (), "jl", "libs", "FD575F2BC294C4A9.jar") : Path.Combine (dsStorePath, "svg-android.jar"); FileAssert.Exists (svgJar); } @@ -639,6 +641,66 @@ public void BugzillaBug11964 () } } + [Test] + public void BindingWithAndroidJavaSource () + { + if (!Builder.UseDotNet) + Assert.Ignore ("This Feature and Test is not available in Legacy Projects"); + var path = Path.Combine ("temp", TestName); + var lib = new XamarinAndroidBindingProject () { + ProjectName = "BindingsProject", + AndroidClassParser = "class-parse", + Jars = { + new AndroidItem.EmbeddedJar ("javasourcejartest.jar") { + BinaryContent = () => ResourceData.JavaSourceJarTestJar, + } + }, + OtherBuildItems = { + new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") { + Encoding = Encoding.ASCII, + TextContent = () => ResourceData.JavaSourceTestExtension, + Metadata = { + { "Bind", "True" }, + }, + }, + }, + + }; + var app = new XamarinAndroidApplicationProject () { + ProjectName = "App", + References = { new BuildItem.ProjectReference ($"..\\{lib.ProjectName}\\{lib.ProjectName}.csproj", lib.ProjectName, lib.ProjectGuid) } + }; + using (var libBuilder = CreateDllBuilder (Path.Combine (path, lib.ProjectName), cleanupAfterSuccessfulBuild: false)) + using (var appBuilder = CreateApkBuilder (Path.Combine (path, app.ProjectName))) { + Assert.IsTrue (libBuilder.Build (lib), "Library build should have succeeded."); + var generatedCode = Path.Combine (Root, libBuilder.ProjectDirectory, lib.IntermediateOutputPath, + "generated", "src", "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceTestExtension.cs"); + FileAssert.Exists (generatedCode, $"'{generatedCode}' should have been generated."); + StringAssertEx.ContainsText (File.ReadAllLines (generatedCode), "public virtual unsafe string GreetWithQuestion (string name, global::Java.Util.Date date, string question)"); + Assert.IsTrue (libBuilder.Build (lib), "Library build should have succeeded."); + Assert.IsTrue (libBuilder.Output.IsTargetSkipped ("_CompileBindingJava"), $"`_CompileBindingJava` should be skipped on second build!"); + Assert.IsTrue (appBuilder.Build (app), "App build should have succeeded."); + appBuilder.Target = "SignAndroidPackage"; + Assert.IsTrue (appBuilder.Build (app), "App SignAndroidPackage should have succeeded."); + var hash = Files.HashString (Path.Combine (lib.IntermediateOutputPath, + "binding", "bin", $"{lib.ProjectName}.jar").Replace ("\\", "/")); + var intermediate = Path.Combine (Root, appBuilder.ProjectDirectory, app.IntermediateOutputPath); + var lpPath = Path.Combine ("0", "jl", $"{lib.ProjectName}.jar"); + if (Builder.UseDotNet) { + lpPath = Path.Combine ("1", "jl", "libs", $"{hash}.jar"); + } + var jar = Path.Combine (intermediate, "lp", lpPath); + FileAssert.Exists (jar, $"'{jar}' should have been generated."); + var dexFile = Path.Combine (intermediate, "android", "bin", "classes.dex"); + FileAssert.Exists (dexFile); + string className = "Lcom/xamarin/android/test/msbuildtest/JavaSourceJarTest;"; + Assert.IsTrue (DexUtils.ContainsClass (className, dexFile, AndroidSdkPath), $"`{dexFile}` should include `{className}`!"); + className = "Lcom/xamarin/android/test/msbuildtest/JavaSourceTestExtension;"; + Assert.IsTrue (DexUtils.ContainsClass (className, dexFile, AndroidSdkPath), $"`{dexFile}` should include `{className}`!"); + Assert.IsTrue (appBuilder.Clean (app), "App clean should have succeeded."); + } + } + [Test] public void LibraryProjectZipWithLint () { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs index 060b9d49832..28789f9eb3e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs @@ -1178,13 +1178,15 @@ XamarinAndroidApplicationProject CreateMultiDexRequiredApplication (string debug TextContent = () => "public class ManyMethods { \n" + string.Join (Environment.NewLine, Enumerable.Range (0, 32768).Select (i => "public void method" + i + "() {}")) + "}", - Encoding = Encoding.ASCII + Encoding = Encoding.ASCII, + Metadata = { { "Bind", "False "}}, }); proj.OtherBuildItems.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "ManyMethods2.java") { TextContent = () => "public class ManyMethods2 { \n" + string.Join (Environment.NewLine, Enumerable.Range (0, 32768).Select (i => "public void method" + i + "() {}")) + "}", - Encoding = Encoding.ASCII + Encoding = Encoding.ASCII, + Metadata = { { "Bind", "False "}}, }); return proj; } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs index 53e24f6886f..379a9c99464 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs @@ -261,6 +261,7 @@ public TestMe createTestMe () { } }", Encoding = Encoding.ASCII, + MetadataValues = "Bind=False", } }, }; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/JavaSourceTestExtension.java b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/JavaSourceTestExtension.java new file mode 100644 index 00000000000..df727c0055a --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/JavaSourceTestExtension.java @@ -0,0 +1,7 @@ +// some comment +package com.xamarin.android.test.msbuildtest; +public class JavaSourceTestExtension extends JavaSourceJarTest { + public String greetWithQuestion (String name, java.util.Date date, String question) { + return greet (name, date) + question; + } +} diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/ResourceData.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/ResourceData.cs index 19c2cba2839..163241116fe 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/ResourceData.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/ResourceData.cs @@ -17,6 +17,7 @@ static class ResourceData static Lazy library2Aar = new Lazy (() => GetResourceData ("library2.aar")); static Lazy apacheHttpClient_cs = new Lazy (() => GetResourceData ("ApacheHttpClient.cs")); static Lazy javadocCopyright = new Lazy (() => GetResourceData ("javadoc-copyright.xml")); + static Lazy javaSourceTestExtension = new Lazy (() => GetResourceData ("JavaSourceTestExtension.java")); public static byte[] JavaSourceJarTestJar => javaSourceJarTestJar.Value; public static byte[] JavaSourceJarTestSourcesJar => javaSourceJarTestSourcesJar.Value; @@ -26,6 +27,8 @@ static class ResourceData public static byte [] ApacheHttpClient_cs => apacheHttpClient_cs.Value; public static byte [] JavadocCopyright => javadocCopyright.Value; + public static string JavaSourceTestExtension => Encoding.ASCII.GetString (javaSourceTestExtension.Value); + static byte[] GetResourceData (string name) { using var s = typeof (ResourceData).Assembly.GetManifestResourceStream (name); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs index 50c189c23f9..1562bc9d3c9 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs @@ -3,6 +3,8 @@ using System.IO; using System.Linq; using System.Xml.Linq; +using System.Reflection; +using System.Text; using Mono.Cecil; using NUnit.Framework; using Xamarin.Android.Tasks; @@ -118,6 +120,11 @@ public Foo () MetadataValues = "Link=x86\\libfoo.so", BinaryContent = () => Array.Empty (), }); + libB.OtherBuildItems.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") { + Encoding = Encoding.ASCII, + TextContent = () => ResourceData.JavaSourceTestExtension, + Metadata = { { "Bind", "True"} }, + }); libB.AddReference (libC); activity = libB.Sources.FirstOrDefault (s => s.Include () == "MainActivity.cs"); @@ -126,6 +133,9 @@ public Foo () var libBBuilder = CreateDotNetBuilder (libB, Path.Combine (path, libB.ProjectName)); Assert.IsTrue (libBBuilder.Build (), $"{libB.ProjectName} should succeed"); + var projectJarHash = Files.HashString (Path.Combine (libB.IntermediateOutputPath, + "binding", "bin", $"{libB.ProjectName}.jar").Replace ("\\", "/")); + // Check .aar file for class library var aarPath = Path.Combine (FullProjectDirectory, libB.OutputPath, $"{libB.ProjectName}.aar"); FileAssert.Exists (aarPath); @@ -137,6 +147,7 @@ public Foo () aar.AssertContainsEntry (aarPath, ".net/env/190E30B3D205731E.env"); aar.AssertContainsEntry (aarPath, ".net/env/2CBDAB7FEEA94B19.env"); aar.AssertContainsEntry (aarPath, "libs/A1AFA985571E728E.jar"); + aar.AssertContainsEntry (aarPath, $"libs/{projectJarHash}.jar"); aar.AssertContainsEntry (aarPath, "jni/arm64-v8a/libfoo.so"); aar.AssertContainsEntry (aarPath, "jni/x86/libfoo.so"); } @@ -183,6 +194,8 @@ public Foo () FileAssert.Exists (dexFile); string className = "Lcom/xamarin/android/test/msbuildtest/JavaSourceJarTest;"; Assert.IsTrue (DexUtils.ContainsClass (className, dexFile, AndroidSdkPath), $"`{dexFile}` should include `{className}`!"); + className = "Lcom/xamarin/android/test/msbuildtest/JavaSourceTestExtension;"; + Assert.IsTrue (DexUtils.ContainsClass (className, dexFile, AndroidSdkPath), $"`{dexFile}` should include `{className}`!"); // Check environment variable var environmentFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediate, "x86", required: true); @@ -274,6 +287,18 @@ public void DotNetPack (string dotnetVersion, string platform, int apiLevel) MetadataValues = "Link=x86\\libfoo.so", BinaryContent = () => Array.Empty (), }); + proj.OtherBuildItems.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTest.java") { + Encoding = Encoding.ASCII, + TextContent = () => @"package com.xamarin.android.test.msbuildtest; +public class JavaSourceTest { + public String Say (String quote) { + return quote; + } +} +", + Metadata = { { "Bind", "True"} }, + } + ); var dotnet = CreateDotNetBuilder (proj); Assert.IsTrue (dotnet.Pack (), "`dotnet pack` should succeed"); @@ -418,6 +443,11 @@ public void DotNetBuildBinding () proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javaclasses-sources.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar, }); + proj.OtherBuildItems.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") { + Encoding = Encoding.ASCII, + TextContent = () => ResourceData.JavaSourceTestExtension, + Metadata = { { "Bind", "True"} }, + }); var dotnet = CreateDotNetBuilder (proj); Assert.IsTrue (dotnet.Build (), "`dotnet build` should succeed"); @@ -427,6 +457,9 @@ public void DotNetBuildBinding () var typeName = "MSBuildTest.JavaSourceJarTest"; var type = assembly.MainModule.GetType (typeName); Assert.IsNotNull (type, $"{assemblyPath} should contain {typeName}"); + typeName = "MSBuildTest.JavaSourceTestExtension"; + type = assembly.MainModule.GetType (typeName); + Assert.IsNotNull (type, $"{assemblyPath} should contain {typeName}"); } } @@ -575,6 +608,11 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot, bo proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javaclasses-sources.jar") { BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar, }); + proj.OtherBuildItems.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") { + Encoding = Encoding.ASCII, + TextContent = () => ResourceData.JavaSourceTestExtension, + Metadata = { { "Bind", "True"} }, + }); if (!runtimeIdentifiers.Contains (";")) { proj.SetProperty (KnownProperties.RuntimeIdentifier, runtimeIdentifiers); } else { @@ -631,6 +669,8 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot, bo Assert.IsNotNull (assembly.MainModule.GetType (typeName), $"{assemblyPath} should contain {typeName}"); typeName = "Com.Balysv.Material.Drawable.Menu.MaterialMenuView"; Assert.IsNotNull (assembly.MainModule.GetType (typeName), $"{assemblyPath} should contain {typeName}"); + typeName = "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceTestExtension"; + Assert.IsNotNull (assembly.MainModule.GetType (typeName), $"{assemblyPath} should contain {typeName}"); } var rids = runtimeIdentifiers.Split (';'); 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 cf9fc86cdbe..0278c04a7a8 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 @@ -16,6 +16,7 @@ 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"; + const int DefaultBuildTimeOut = 30; string Arm32AbiDir => UseDotNet ? "armeabi-v7a-net6" : "armeabi-v7a"; @@ -404,7 +405,7 @@ protected bool BuildInternal (string projectOrSolution, string target, string [] p.Start (); p.BeginOutputReadLine (); p.BeginErrorReadLine (); - ranToCompletion = p.WaitForExit ((int)new TimeSpan (0, 15, 0).TotalMilliseconds); + ranToCompletion = p.WaitForExit ((int)new TimeSpan (0, DefaultBuildTimeOut, 0).TotalMilliseconds); if (psi.RedirectStandardOutput) stdout.WaitOne (); if (psi.RedirectStandardError) diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets index 39d627f9cfa..99527343326 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets @@ -24,11 +24,11 @@ Copyright (C) 2012 Xamarin Inc. All rights reserved. - True False @@ -128,6 +128,12 @@ Copyright (C) 2012 Xamarin Inc. All rights reserved. /> + + + + @@ -159,6 +165,7 @@ Copyright (C) 2012 Xamarin Inc. All rights reserved. + @@ -167,10 +174,10 @@ Copyright (C) 2012 Xamarin Inc. All rights reserved. - diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets index 93cf53d9822..7e786d8dbf2 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets @@ -123,6 +123,10 @@ PreserveNewest Xamarin.Android.Aapt2.targets + + PreserveNewest + Xamarin.Android.Javac.targets + PreserveNewest diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index a9ee698265d..551c9180ccd 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -17,7 +17,6 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. - @@ -62,9 +61,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. - - @@ -85,7 +82,6 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. - @@ -365,6 +361,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. + @@ -533,14 +530,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. - - - - - + DependsOnTargets="_GetAndroidPackageName;_GetJavaPlatformJar"> $(IntermediateOutputPath)android\bin\$(_AndroidPackage).apk <_BaseZipIntermediate>$(IntermediateOutputPath)android\bin\base.zip @@ -1736,20 +1726,6 @@ because xbuild doesn't support framework reference assemblies. - - - - - - - - <_CompileJavaDependsOnTargets> _AdjustJavacVersionArguments; @@ -1767,54 +1743,6 @@ because xbuild doesn't support framework reference assemblies. - - - - - - - - - - - - - - - - - - - - - - <_JavaLibrariesToCompileForApp Include="@(_JavaLibrariesToCompile)" Condition=" '$(_InstantRunEnabled)' != 'True' " /> - - - - <_CompileToDalvikDependsOnTargets> _CompileJava; @@ -2470,7 +2398,6 @@ because xbuild doesn't support framework reference assemblies. - diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Tooling.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Tooling.targets index 42ebfd4003a..4838fa35119 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Tooling.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Tooling.targets @@ -12,6 +12,7 @@ projects. + @@ -96,4 +97,12 @@ projects. + + + + + + diff --git a/tests/MSBuildDeviceIntegration/Tests/UncaughtExceptionTests.cs b/tests/MSBuildDeviceIntegration/Tests/UncaughtExceptionTests.cs index 368353f8dfa..167c60238d2 100644 --- a/tests/MSBuildDeviceIntegration/Tests/UncaughtExceptionTests.cs +++ b/tests/MSBuildDeviceIntegration/Tests/UncaughtExceptionTests.cs @@ -41,7 +41,7 @@ public void EnsureUncaughtExceptionWorks () - + From bf3adb03b46b5603aa97b3dc31d363e55d79db0f Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 4 May 2022 14:31:40 +0100 Subject: [PATCH 02/10] Fix up a unit test which was broken --- .../Xamarin/Android/Xamarin.Android.Bindings.Core.targets | 1 + .../Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets index 8c8697e9e47..7e69c7221d3 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets @@ -125,6 +125,7 @@ It is shared between "legacy" binding projects and .NET 5 projects. + diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs index a806c92fcac..1303a465991 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs @@ -92,13 +92,14 @@ public void CleanBasicBindingLibrary (string classParser) proj.AndroidClassParser = classParser; using (var b = CreateDllBuilder (Path.Combine ("temp", TestName))) { Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + b.BuildLogFile = "clean.log"; Assert.IsTrue (b.Clean (proj), "Clean should have succeeded"); var ignoreFiles = new string [] { "TemporaryGeneratedFile", "FileListAbsolute.txt", }; var files = Directory.GetFiles (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath), "*", SearchOption.AllDirectories) - .Where (x => !ignoreFiles.Any (i => !Path.GetFileName (x).Contains (i))); + .Where (x => !ignoreFiles.Any (i => Path.GetFileName (x).Contains (i))); CollectionAssert.IsEmpty (files, $"{proj.IntermediateOutputPath} should have no files."); } } From 5e01b94c7b7b07f5dd9bb98602653c8d877be549 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 4 May 2022 15:39:15 +0100 Subject: [PATCH 03/10] Fix broken test --- .../targets/Microsoft.Android.Sdk.AndroidLibraries.targets | 4 ++++ .../targets/Microsoft.Android.Sdk.BuildOrder.targets | 1 + .../Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AndroidLibraries.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AndroidLibraries.targets index 94cfa5eed8a..aab24a7676b 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AndroidLibraries.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AndroidLibraries.targets @@ -113,4 +113,8 @@ projects. + + + + diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets index fd9d173e3a1..02cf141b5e5 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets @@ -150,6 +150,7 @@ projects, these properties are set in Xamarin.Android.Legacy.targets. $(CleanDependsOn); _CleanMonoAndroidIntermediateDir; _CleanAndroidBuildPropertiesCache; + _CleanAarCache; CleanBindingsOutput; CleanLibraryProjectIntermediaries; CleanNativeLibraryIntermediaries; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs index 1303a465991..d13d0684cb1 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs @@ -97,6 +97,8 @@ public void CleanBasicBindingLibrary (string classParser) var ignoreFiles = new string [] { "TemporaryGeneratedFile", "FileListAbsolute.txt", + "assets.cache", + "Resource.designer.cs", }; var files = Directory.GetFiles (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath), "*", SearchOption.AllDirectories) .Where (x => !ignoreFiles.Any (i => Path.GetFileName (x).Contains (i))); From 4c1820324de5a0fd7e56a636433e915fd7cd0046 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Thu, 5 May 2022 14:23:08 +0100 Subject: [PATCH 04/10] ignore more stuff --- .../Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs index d13d0684cb1..6dd55442064 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs @@ -99,6 +99,7 @@ public void CleanBasicBindingLibrary (string classParser) "FileListAbsolute.txt", "assets.cache", "Resource.designer.cs", + "_TelemetryProps", }; var files = Directory.GetFiles (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath), "*", SearchOption.AllDirectories) .Where (x => !ignoreFiles.Any (i => Path.GetFileName (x).Contains (i))); From 54ecf6037156227db2dbb32b86ed5c01c6da616f Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 6 May 2022 22:01:34 +0100 Subject: [PATCH 05/10] Update Documentation/guides/BindingJavaSource.md Co-authored-by: Jonathan Peppers --- Documentation/guides/BindingJavaSource.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/guides/BindingJavaSource.md b/Documentation/guides/BindingJavaSource.md index 1896cad3ecf..345c12b3932 100644 --- a/Documentation/guides/BindingJavaSource.md +++ b/Documentation/guides/BindingJavaSource.md @@ -89,7 +89,7 @@ public class MainActivity : Activity { # Limitations -This feature is only available in .net 6. +This feature is only available in .NET 7. You will be limited to standard java types and any types that are available in a .jar or .aar which you reference. From e005b11ba6d3c649b9124937c3f9f2ade3ee289e Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 6 May 2022 22:01:51 +0100 Subject: [PATCH 06/10] Update src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets Co-authored-by: Jonathan Peppers --- .../MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets index fb73f8e6c03..75b68300b74 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets @@ -4,7 +4,7 @@ Xamarin.Android.Javac.targets This file contains the core MSBuild logic for Xamarin.Android Java Invocations. -It is shared between "legacy" binding projects and .NET 5 projects. +It is shared between "legacy" binding projects and .NET 7+ projects. *********************************************************************************************** --> From faebe4958266ee392c29396d87e3361758f53fc3 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 10 May 2022 14:16:14 -0400 Subject: [PATCH 07/10] Copy editing --- Documentation/guides/BindingJavaSource.md | 107 +++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/Documentation/guides/BindingJavaSource.md b/Documentation/guides/BindingJavaSource.md index 345c12b3932..6e34a0e810f 100644 --- a/Documentation/guides/BindingJavaSource.md +++ b/Documentation/guides/BindingJavaSource.md @@ -1,7 +1,7 @@ --- id: title: "Binding Java Source" -dateupdated: 2021-05-21 +dateupdated: 2022-05-10 --- # Overview @@ -42,8 +42,111 @@ class MyClass { return name.equals ("Dave"); } } +```--- +id: +title: "Binding Java Source" +dateupdated: 2021-05-21 +--- + +# Overview + +With .net 6 Bindings can be done on not only `.jar` and `.aar` files +but also raw `.java` code. This will allow developers of bindings +or applications to write custom API's for underlying bindings +and expose them easily to the developer. + +Applications already had the ability to include +[`AndroidJavaSource`](https://docs.microsoft.com/en-us/xamarin/android/deploy-test/building-apps/build-items#androidjavasource) +items in them, these would then be compiled into the final `classes.dex`. +However this custom java source code was not "bound" and if users wanted +to call these classes they would need to do that manually. + +Starting with .NET 7, all `*.java` files within the project directory are +automatically added to the `AndroidJavaSource` item group. Additionally, +`AndroidJavaSource` now supports `Bind` item metadata. This will instruct +the build system to not only compile the code but also produce a C# API for it. + +The `%(Bind)` attribute metadata is `True` by default. If you do not want +to bind the Java code, set `%(Bind)` to `False`. + +```xml + + + +``` + +# Example + +Consider the following Java code. + +```java +package com.xamarin.test; + +class MyClass { + public boolean isDave (String name) + { + return name.equals ("Dave"); + } +} +``` + +We want to bind this into a C# API in our app project. By default +the app project will pick up ALL `.java` files and add them to +the `AndroidJavaSource` ItemGroup. The `Bind` attribute is `true` +by default as well so it will be automatically bound. + +```xml + +``` + +When we build the app, the java code will be compiled into a +`.jar` file which matches the application project name. +This `.jar` will then be bound and the generated C# API will end +up being something like this. + +```csharp +using System; + +namespace Com.Xamarin.Test { + public class MyClass : Java.Lang.Object { + public virtual bool IsDave (string name) => …; + } +} +``` + +All this will happen before the main C# code is compiled. The binding +code will be included in the C# compile process, so you can use the +code directly in your app. + +```csharp +public class MainActivity : Activity { + public override void OnCreate() + { + var c = new MyClass (); + c.IsDave ("Bob"); + } +} ``` + +# Limitations + +This feature is only available in .NET 7. + +You will be limited to standard java types and any types that +are available in a `.jar` or `.aar` which you reference. + +You *should not* use Java Generics. The Binding process currently does not +really support Java Generic very well. Stick to primitive types +or normal classes as much as possible, so that you don't need to use +[`metadata.xml`](https://docs.microsoft.com/en-us/xamarin/android/platform/binding-java-library/customizing-bindings/java-bindings-metadata) +to alter the API of the Java class. + +Because of the point at which the Java compilation happens +(before the `` task), you will not be able to access any of the +`R.*` Resource types either. This may be addressed in a later release. + + We want to bind this into a C# API in our app project. By default the app project will pick up ALL `.java` files and add them to the `AndroidJavaSource` ItemGroup. The `Bind` attribute is `true` @@ -101,4 +204,4 @@ to use the metadata.xml to alter the API of the Java class. Because of the point at which the Java compilation happens in this case (before Csc), you will not be able to access any of the `R.*` Resource -types either. \ No newline at end of file +types either. From 0c14e00fd7e5edcfb7b41c4022804a22d8f25a4f Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 10 May 2022 14:17:01 -0400 Subject: [PATCH 08/10] Update AndroidJavaSource docs --- .../guides/building-apps/build-items.md | 408 ++++++++++++++++++ 1 file changed, 408 insertions(+) diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index 837487ea0f6..03e9cdfc27d 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -40,6 +40,50 @@ build action to a file containing an AOT profile. ## AndroidAppBundleMetaDataFile +Specifies a file that will be included as metadata in the Android App Bundle. +The format of the flag value is `:` where +`bundle-path` denotes the file location inside the App Bundle's metadata--- +title: "Build Items" +description: "This document will list all supported item groups in the Xamarin.Android build process." +ms.prod: xamarin +ms.assetid: 5EBEE1A5-3879-45DD-B1DE-5CD4327C2656 +ms.technology: xamarin-android +author: jonpryor +ms.author: jopryo +ms.date: 03/29/2022 +--- + +# Build Items + +Build items control how a Xamarin.Android application +or library project is built. + +## AndroidAsset + +Supports [Android Assets](https://developer.android.com/guide/topics/resources/providing-resources#OriginalFiles), +files that would be included in the `assets` folder in a Java Android project. + +## AndroidAarLibrary + +The Build action of `AndroidAarLibrary` should be used to directly +reference `.aar` files. This build action will be most commonly used +by Xamarin Components. Namely to include references to `.aar` files +which are required to get Google Play and other services working. + +Files with this Build action will be treated in a similar fashion to +the embedded resources found in Library projects. The `.aar` will be +extracted into the intermediate directory. Then any assets, resource +and `.jar` files will be included in the appropriate item groups. + +## AndroidAotProfile + +Used to provide an AOT profile, for use with profile-guided AOT. + +It can be also used from Visual Studio by setting the `AndroidAotProfile` +build action to a file containing an AOT profile. + +## AndroidAppBundleMetaDataFile + Specifies a file that will be included as metadata in the Android App Bundle. The format of the flag value is `:` where `bundle-path` denotes the file location inside the App Bundle's metadata @@ -89,6 +133,370 @@ package. Files with a Build action of `AndroidJavaSource` are Java source code which will be included in the final Android package. +Starting with .NET 7, all `**\*.java` files within the project directory +automatically have a Build action of `AndroidJavaSource`, *and* will be +bound prior to the Assembly build. This allows C# code to easily use +types and members present within the `**\*.java` files. + +Set `%(AndroidJavaSource.Bind)` to False to disable this behavior. + +## AndroidLibrary + +**AndroidLibrary** is a new build action for simplifying how +`.jar` and `.aar` files are included in projects. + +Any project can specify: + +```xml + + + + +``` + +The result of the above code snippet has a different effect for each +Xamarin.Android project type: + +* Application and class library projects: + * `foo.jar` maps to [**AndroidJavaLibrary**](#androidjavalibrary). + * `bar.aar` maps to [**AndroidAarLibrary**](#androidaarlibrary). +* Java binding projects: + * `foo.jar` maps to [**EmbeddedJar**](#embeddedjar). + * `foo.jar` maps to [**EmbeddedReferenceJar**](#embeddedreferencejar) + if `Bind="false"` metadata is added. + * `bar.aar` maps to [**LibraryProjectZip**](#libraryprojectzip). + +This simplification means you can use **AndroidLibrary** everywhere. + +This build action was added in Xamarin.Android 11.2. + +## AndroidLintConfig + +The Build action 'AndroidLintConfig' should be used in conjunction with the +[`$(AndroidLintEnabled)`](~/android/deploy-test/building-apps/build-properties.md#androidlintenabled) +property. Files with this build action will be merged together and passed to the +android `lint` tooling. They should be XML files which contain information on +which tests to enable and disable. + +See the [lint documentation](https://developer.android.com/studio/write/lint) +for more details. + +## AndroidManifestOverlay + +The `AndroidManifestOverlay` build action can be used to provide additional +`AndroidManifest.xml` files to the [Manifest Merger](https://developer.android.com/studio/build/manifest-merge) tool. +Files with this build action will be passed to the Manifest Merger along with +the main `AndroidManifest.xml` file and any additional manifest files from +references. These will then be merged into the final manifest. + +You can use this build action to provide additional changes and settings to +your app depending on your build configuration. For example, if you need to +have a specific permission only while debugging, you can use the overlay to +inject that permission when debugging. For example, given the following +overlay file contents: + +``` + + + +``` + +You can use the following to add this for a debug build: + +``` + + + +``` + +This build action was introduced in Xamarin.Android 11.2. + +## AndroidInstallModules + +Specifies the modules which get installed by **bundletool** command when +installing app bundles. + +This build action was introduced in Xamarin.Android 11.3. + +## AndroidNativeLibrary + +[Native libraries](~/android/platform/native-libraries.md) +are added to the build by setting their Build action to +`AndroidNativeLibrary`. + +Note that since Android supports multiple Application Binary Interfaces +(ABIs), the build system must know which ABI the native library is +built for. There are two ways this can be done: + +1. Path "sniffing". +2. Using the `Abi` item attribute. + +With path sniffing, the parent directory name of the native library is +used to specify the ABI that the library targets. Thus, if you add +`lib/armeabi-v7a/libfoo.so` to the build, then the ABI will be "sniffed" as +`armeabi-v7a`. + +### Item Attribute Name + +**Abi** – Specifies the ABI of the native library. + +```xml + + + armeabi-v7a + + +``` + +## AndroidResource + +All files with an *AndroidResource* build action are compiled into +Android resources during the build process and made accessible via `$(AndroidResgenFile)`. + +```xml + + + +``` + +More advanced users might perhaps wish to have different resources used in +different configurations but with the same effective path. This can be achieved +by having multiple resource directories and having files with the same relative +paths within these different directories, and using MSBuild conditions to +conditionally include different files in different configurations. For +example: + +```xml + + + + + + + + Resources;Resources-Debug + +``` + +**LogicalName** – Specifies the resource path explicitly. Allows +“aliasing” files so that they will be available as multiple +distinct resource names. + +```xml + + + + + + values/strings.xml + + +``` + +## AndroidResourceAnalysisConfig + +The Build action `AndroidResourceAnalysisConfig` marks a file as a +severity level configuration file for the Xamarin Android Designer +layout diagnostics tool. This is currently only used in the layout +editor and not for build messages. + +See the [Android Resource Analysis +documentation](../../user-interface/android-designer/diagnostics.md) for more +details. + +Added in Xamarin.Android 10.2. + +## Content + +The normal `Content` Build action is not supported (as we +haven't figured out how to support it without a possibly costly first-run +step). + +Starting in Xamarin.Android 5.1, attempting to use the `@(Content)` +Build action will result in a `XA0101` warning. + +## EmbeddedJar + +In a Xamarin.Android binding project, the **EmbeddedJar** build action +binds the Java/Kotlin library and embeds the `.jar` file into the +library. When a Xamarin.Android application project consumes the +library, it will have access to the Java/Kotlin APIs from C# as well +as include the Java/Kotlin code in the final Android application. + +Since Xamarin.Android 11.2, you can use the +[**AndroidLibrary**](#androidlibrary) build action as an alternative +such as: + +```xml + + + + + +``` + +## EmbeddedNativeLibrary + +In a Xamarin.Android class library or Java binding project, the +**EmbeddedNativeLibrary** build action bundles a native library such +as `lib/armeabi-v7a/libfoo.so` into the library. When a +Xamarin.Android application consumes the library, the `libfoo.so` file +will be included in the final Android application. + +Since Xamarin.Android 11.2, you can use the +[**AndroidNativeLibrary**](#androidnativelibrary) build action as an +alternative. + +## EmbeddedReferenceJar + +In a Xamarin.Android binding project, the **EmbeddedReferenceJar** +build action embeds the `.jar` file into the library but does not +create a C# binding as [**EmbeddedJar**](#embeddedjar) does. When a +Xamarin.Android application project consumes the library, it will +include the Java/Kotlin code in the final Android application. + +Since Xamarin.Android 11.2, you can use the +[**AndroidLibrary**](#androidlibrary) build action as an alternative +such as ``: + +```xml + + + + + + + + +``` + +## JavaDocJar + +In a Xamarin.Android binding project, the **JavaDocJar** build action +is used on `.jar` files which contain *Javadoc HTML*. The Javadoc HTML +is parsed in order to extract parameter names. + +Only certain "Javadoc HTML dialects" are supported, including: + + * JDK 1.7 `javadoc` output. + * JDK 1.8 `javadoc` output. + * Droiddoc output. + +This build action is deprecated in Xamarin.Android 11.3, and will not be +supported in .NET 6. +The `@(JavaSourceJar)` build action is preferred. + +## JavaSourceJar + +In a Xamarin.Android binding project, the **JavaSourceJar** build action +is used on `.jar` files that contain *Java source code*, which contain +[Javadoc documentation comments](https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html). + +Prior to Xamarin.Android 11.3, the Javadoc would be converted into HTML +via the `javadoc` utility during build time, and later turned into +XML documentation. + +Starting with Xamarin.Android 11.3, Javadoc will instead be converted into +[C# XML Documentation Comments](/dotnet/csharp/codedoc) +within the generated binding source code. + +`$(AndroidJavadocVerbosity)` controls how "verbose" or "complete" the imported Javadoc is. + +Starting in Xamarin.Android 11.3, the following MSBuild metadata is supported: + +* `%(CopyrightFile)`: A path to a file that contains copyright + information for the Javadoc contents, which will be appended to + all imported documentation. + +* `%(UrlPrefix)`: A URL prefix to support linking to online + documentation within imported documentation. + +* `%(UrlStyle)`: The "style" of URLs to generate when linking to + online documentation. Only one style is currently supported: + `developer.android.com/reference@2020-Nov`. + +Starting in Xamarin.Android 12.3, the following MSBuild metadata is supported: + +* `%(DocRootUrl)`: A URL prefix to use in place of all {@docroot} + instances in the imported documentation. + + +## LibraryProjectZip + +In a Xamarin.Android binding project, the **LibraryProjectZip** build +action binds the Java/Kotlin library and embeds the `.zip` or `.aar` +file into the library. When a Xamarin.Android application project +consumes the library, it will have access to the Java/Kotlin APIs from +C# as well as include the Java/Kotlin code in the final Android +application. + +> [!NOTE] +> Only a single **LibraryProjectZip** can be included in a +> Xamarin.Android binding project. This limitation will be removed +> in .NET 6. + +## LinkDescription + +Files with a *LinkDescription* build action are used to +[control linker behavior](~/cross-platform/deploy-test/linker.md). + +## ProguardConfiguration + +Files with a *ProguardConfiguration* build action contain options which +are used to control `proguard` behavior. For more information about +this build action, see +[ProGuard](~/android/deploy-test/release-prep/proguard.md). + +These files are ignored unless the +[`$(EnableProguard)`](~/android/deploy-test/building-apps/build-properties.md#enableproguard) +MSBuild property is `True`. + +directory, and `physical-file` is an existing file containing the raw data +to be stored. + +```xml + + + +``` + +See [bundletool](https://developer.android.com/studio/build/building-cmdline#build_your_app_bundle_using_bundletool) documentation for more details. + +Added in Xamarin.Android 12.3. + +## AndroidBoundLayout + +Indicates that the layout file is to have code-behind generated for it in case when +the `AndroidGenerateLayoutBindings` property is set to `false`. In all other aspects +it is identical to `AndroidResource` described above. This action can be used **only** +with layout files: + +```xml + +``` + +## AndroidEnvironment + +Files with a Build action of `AndroidEnvironment` are used +to [initialize environment variables and system properties during process startup](~/android/deploy-test/environment.md). +The `AndroidEnvironment` Build action may be applied to +multiple files, and they will be evaluated in no particular order (so don't +specify the same environment variable or system property in multiple +files). + +## AndroidJavaLibrary + +Files with a Build action of `AndroidJavaLibrary` are Java +Archives ( `.jar` files) which will be included in the final Android +package. + +## AndroidJavaSource + +Files with a Build action of `AndroidJavaSource` are Java source code which +will be included in the final Android package. + ## AndroidLibrary **AndroidLibrary** is a new build action for simplifying how From afde00799f8d569493cd1b387291395d2c0d95a2 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 11 May 2022 20:53:51 -0400 Subject: [PATCH 09/10] Let's try this again? --- Documentation/guides/BindingJavaSource.md | 104 ---------------------- 1 file changed, 104 deletions(-) diff --git a/Documentation/guides/BindingJavaSource.md b/Documentation/guides/BindingJavaSource.md index 6e34a0e810f..bff7f06cb93 100644 --- a/Documentation/guides/BindingJavaSource.md +++ b/Documentation/guides/BindingJavaSource.md @@ -1,50 +1,6 @@ --- id: title: "Binding Java Source" -dateupdated: 2022-05-10 ---- - -# Overview - -With .net 6 Bindings can be done on not only .jar and .aar files -but also raw .java code. This will allow developers of bindings -or applications to write custom API's for underlying bindings -and expose them easily to the developer. - -Applications already had the ability to include `AndroidJavaSource` -items in them, these would then be compiled into the final `classes.dex`. -However this custom java source code was not "bound" and if users wanted -to call these classes they would need to do that manually. - -The `AndroidJavaSource` Item Group now supports a `Bind` attribute. This -will instruct the build system to not only compile the code but also -produce a C# API for it. - -The `%(Bind)` attribute metadata is `True` by default. If you do not want -to bind the Java code, set `%(Bind)` to `False`. - -```xml - - - -``` - -# Example - -Consider the following Java code. - -```java -package com.xamarin.test; - -class MyClass { - public boolean IsDave (String name) - { - return name.equals ("Dave"); - } -} -```--- -id: -title: "Binding Java Source" dateupdated: 2021-05-21 --- @@ -145,63 +101,3 @@ to alter the API of the Java class. Because of the point at which the Java compilation happens (before the `` task), you will not be able to access any of the `R.*` Resource types either. This may be addressed in a later release. - - -We want to bind this into a C# API in our app project. By default -the app project will pick up ALL `.java` files and add them to -the `AndroidJavaSource` ItemGroup. The `Bind` attribute is `true` -by default as well so it will be automatically bound. - -```xml - - - -``` - -When we build the app, the java code will be compiled into a -.jar file which matches the application project name. -This .jar will then be bound and the generated C# API will end -up being something like this. - -```csharp -using System; - -namespace Com.Xamarin.Test { - public class MyClass : Java.Lang.Object { - public virtual bool IsDave (string name){ - // binding code - } - } -} -``` - -All this will happen before the main C# code is compiled. The binding -code will be included in the C# compile process, so you can use the -code directly in your app. - -```csharp -public class MainActivity : Activity { - public override void OnCreate() - { - var c = new MyClass (); - c.IsDave ("Bob"); - } -} -``` - - -# Limitations - -This feature is only available in .NET 7. - -You will be limited to standard java types and any types that -are available in a .jar or .aar which you reference. - -You CANNOT use Java Generics. The Binding process currently does not -really support Java Generic very well. So stick to primitive types -or normal classes as much as possible. This is so that you don't need -to use the metadata.xml to alter the API of the Java class. - -Because of the point at which the Java compilation happens in this case -(before Csc), you will not be able to access any of the `R.*` Resource -types either. From 7fa137ea687e3a68c390e4d622b91d590d0e6682 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 11 May 2022 20:54:37 -0400 Subject: [PATCH 10/10] oops. --- .../guides/building-apps/build-items.md | 403 +----------------- 1 file changed, 1 insertion(+), 402 deletions(-) diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index 03e9cdfc27d..44b37c48a2a 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -6,51 +6,7 @@ ms.assetid: 5EBEE1A5-3879-45DD-B1DE-5CD4327C2656 ms.technology: xamarin-android author: jonpryor ms.author: jopryo -ms.date: 03/29/2022 ---- - -# Build Items - -Build items control how a Xamarin.Android application -or library project is built. - -## AndroidAsset - -Supports [Android Assets](https://developer.android.com/guide/topics/resources/providing-resources#OriginalFiles), -files that would be included in the `assets` folder in a Java Android project. - -## AndroidAarLibrary - -The Build action of `AndroidAarLibrary` should be used to directly -reference `.aar` files. This build action will be most commonly used -by Xamarin Components. Namely to include references to `.aar` files -which are required to get Google Play and other services working. - -Files with this Build action will be treated in a similar fashion to -the embedded resources found in Library projects. The `.aar` will be -extracted into the intermediate directory. Then any assets, resource -and `.jar` files will be included in the appropriate item groups. - -## AndroidAotProfile - -Used to provide an AOT profile, for use with profile-guided AOT. - -It can be also used from Visual Studio by setting the `AndroidAotProfile` -build action to a file containing an AOT profile. - -## AndroidAppBundleMetaDataFile - -Specifies a file that will be included as metadata in the Android App Bundle. -The format of the flag value is `:` where -`bundle-path` denotes the file location inside the App Bundle's metadata--- -title: "Build Items" -description: "This document will list all supported item groups in the Xamarin.Android build process." -ms.prod: xamarin -ms.assetid: 5EBEE1A5-3879-45DD-B1DE-5CD4327C2656 -ms.technology: xamarin-android -author: jonpryor -ms.author: jopryo -ms.date: 03/29/2022 +ms.date: 05/11/2022 --- # Build Items @@ -450,360 +406,3 @@ this build action, see These files are ignored unless the [`$(EnableProguard)`](~/android/deploy-test/building-apps/build-properties.md#enableproguard) MSBuild property is `True`. - -directory, and `physical-file` is an existing file containing the raw data -to be stored. - -```xml - - - -``` - -See [bundletool](https://developer.android.com/studio/build/building-cmdline#build_your_app_bundle_using_bundletool) documentation for more details. - -Added in Xamarin.Android 12.3. - -## AndroidBoundLayout - -Indicates that the layout file is to have code-behind generated for it in case when -the `AndroidGenerateLayoutBindings` property is set to `false`. In all other aspects -it is identical to `AndroidResource` described above. This action can be used **only** -with layout files: - -```xml - -``` - -## AndroidEnvironment - -Files with a Build action of `AndroidEnvironment` are used -to [initialize environment variables and system properties during process startup](~/android/deploy-test/environment.md). -The `AndroidEnvironment` Build action may be applied to -multiple files, and they will be evaluated in no particular order (so don't -specify the same environment variable or system property in multiple -files). - -## AndroidJavaLibrary - -Files with a Build action of `AndroidJavaLibrary` are Java -Archives ( `.jar` files) which will be included in the final Android -package. - -## AndroidJavaSource - -Files with a Build action of `AndroidJavaSource` are Java source code which -will be included in the final Android package. - -## AndroidLibrary - -**AndroidLibrary** is a new build action for simplifying how -`.jar` and `.aar` files are included in projects. - -Any project can specify: - -```xml - - - - -``` - -The result of the above code snippet has a different effect for each -Xamarin.Android project type: - -* Application and class library projects: - * `foo.jar` maps to [**AndroidJavaLibrary**](#androidjavalibrary). - * `bar.aar` maps to [**AndroidAarLibrary**](#androidaarlibrary). -* Java binding projects: - * `foo.jar` maps to [**EmbeddedJar**](#embeddedjar). - * `foo.jar` maps to [**EmbeddedReferenceJar**](#embeddedreferencejar) - if `Bind="false"` metadata is added. - * `bar.aar` maps to [**LibraryProjectZip**](#libraryprojectzip). - -This simplification means you can use **AndroidLibrary** everywhere. - -This build action was added in Xamarin.Android 11.2. - -## AndroidLintConfig - -The Build action 'AndroidLintConfig' should be used in conjunction with the -[`$(AndroidLintEnabled)`](~/android/deploy-test/building-apps/build-properties.md#androidlintenabled) -property. Files with this build action will be merged together and passed to the -android `lint` tooling. They should be XML files which contain information on -which tests to enable and disable. - -See the [lint documentation](https://developer.android.com/studio/write/lint) -for more details. - -## AndroidManifestOverlay - -The `AndroidManifestOverlay` build action can be used to provide additional -`AndroidManifest.xml` files to the [Manifest Merger](https://developer.android.com/studio/build/manifest-merge) tool. -Files with this build action will be passed to the Manifest Merger along with -the main `AndroidManifest.xml` file and any additional manifest files from -references. These will then be merged into the final manifest. - -You can use this build action to provide additional changes and settings to -your app depending on your build configuration. For example, if you need to -have a specific permission only while debugging, you can use the overlay to -inject that permission when debugging. For example, given the following -overlay file contents: - -``` - - - -``` - -You can use the following to add this for a debug build: - -``` - - - -``` - -This build action was introduced in Xamarin.Android 11.2. - -## AndroidInstallModules - -Specifies the modules which get installed by **bundletool** command when -installing app bundles. - -This build action was introduced in Xamarin.Android 11.3. - -## AndroidNativeLibrary - -[Native libraries](~/android/platform/native-libraries.md) -are added to the build by setting their Build action to -`AndroidNativeLibrary`. - -Note that since Android supports multiple Application Binary Interfaces -(ABIs), the build system must know which ABI the native library is -built for. There are two ways this can be done: - -1. Path "sniffing". -2. Using the `Abi` item attribute. - -With path sniffing, the parent directory name of the native library is -used to specify the ABI that the library targets. Thus, if you add -`lib/armeabi-v7a/libfoo.so` to the build, then the ABI will be "sniffed" as -`armeabi-v7a`. - -### Item Attribute Name - -**Abi** – Specifies the ABI of the native library. - -```xml - - - armeabi-v7a - - -``` - -## AndroidResource - -All files with an *AndroidResource* build action are compiled into -Android resources during the build process and made accessible via `$(AndroidResgenFile)`. - -```xml - - - -``` - -More advanced users might perhaps wish to have different resources used in -different configurations but with the same effective path. This can be achieved -by having multiple resource directories and having files with the same relative -paths within these different directories, and using MSBuild conditions to -conditionally include different files in different configurations. For -example: - -```xml - - - - - - - - Resources;Resources-Debug - -``` - -**LogicalName** – Specifies the resource path explicitly. Allows -“aliasing” files so that they will be available as multiple -distinct resource names. - -```xml - - - - - - values/strings.xml - - -``` - -## AndroidResourceAnalysisConfig - -The Build action `AndroidResourceAnalysisConfig` marks a file as a -severity level configuration file for the Xamarin Android Designer -layout diagnostics tool. This is currently only used in the layout -editor and not for build messages. - -See the [Android Resource Analysis -documentation](../../user-interface/android-designer/diagnostics.md) for more -details. - -Added in Xamarin.Android 10.2. - -## Content - -The normal `Content` Build action is not supported (as we -haven't figured out how to support it without a possibly costly first-run -step). - -Starting in Xamarin.Android 5.1, attempting to use the `@(Content)` -Build action will result in a `XA0101` warning. - -## EmbeddedJar - -In a Xamarin.Android binding project, the **EmbeddedJar** build action -binds the Java/Kotlin library and embeds the `.jar` file into the -library. When a Xamarin.Android application project consumes the -library, it will have access to the Java/Kotlin APIs from C# as well -as include the Java/Kotlin code in the final Android application. - -Since Xamarin.Android 11.2, you can use the -[**AndroidLibrary**](#androidlibrary) build action as an alternative -such as: - -```xml - - - - - -``` - -## EmbeddedNativeLibrary - -In a Xamarin.Android class library or Java binding project, the -**EmbeddedNativeLibrary** build action bundles a native library such -as `lib/armeabi-v7a/libfoo.so` into the library. When a -Xamarin.Android application consumes the library, the `libfoo.so` file -will be included in the final Android application. - -Since Xamarin.Android 11.2, you can use the -[**AndroidNativeLibrary**](#androidnativelibrary) build action as an -alternative. - -## EmbeddedReferenceJar - -In a Xamarin.Android binding project, the **EmbeddedReferenceJar** -build action embeds the `.jar` file into the library but does not -create a C# binding as [**EmbeddedJar**](#embeddedjar) does. When a -Xamarin.Android application project consumes the library, it will -include the Java/Kotlin code in the final Android application. - -Since Xamarin.Android 11.2, you can use the -[**AndroidLibrary**](#androidlibrary) build action as an alternative -such as ``: - -```xml - - - - - - - - -``` - -## JavaDocJar - -In a Xamarin.Android binding project, the **JavaDocJar** build action -is used on `.jar` files which contain *Javadoc HTML*. The Javadoc HTML -is parsed in order to extract parameter names. - -Only certain "Javadoc HTML dialects" are supported, including: - - * JDK 1.7 `javadoc` output. - * JDK 1.8 `javadoc` output. - * Droiddoc output. - -This build action is deprecated in Xamarin.Android 11.3, and will not be -supported in .NET 6. -The `@(JavaSourceJar)` build action is preferred. - -## JavaSourceJar - -In a Xamarin.Android binding project, the **JavaSourceJar** build action -is used on `.jar` files that contain *Java source code*, which contain -[Javadoc documentation comments](https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html). - -Prior to Xamarin.Android 11.3, the Javadoc would be converted into HTML -via the `javadoc` utility during build time, and later turned into -XML documentation. - -Starting with Xamarin.Android 11.3, Javadoc will instead be converted into -[C# XML Documentation Comments](/dotnet/csharp/codedoc) -within the generated binding source code. - -`$(AndroidJavadocVerbosity)` controls how "verbose" or "complete" the imported Javadoc is. - -Starting in Xamarin.Android 11.3, the following MSBuild metadata is supported: - -* `%(CopyrightFile)`: A path to a file that contains copyright - information for the Javadoc contents, which will be appended to - all imported documentation. - -* `%(UrlPrefix)`: A URL prefix to support linking to online - documentation within imported documentation. - -* `%(UrlStyle)`: The "style" of URLs to generate when linking to - online documentation. Only one style is currently supported: - `developer.android.com/reference@2020-Nov`. - -Starting in Xamarin.Android 12.3, the following MSBuild metadata is supported: - -* `%(DocRootUrl)`: A URL prefix to use in place of all {@docroot} - instances in the imported documentation. - - -## LibraryProjectZip - -In a Xamarin.Android binding project, the **LibraryProjectZip** build -action binds the Java/Kotlin library and embeds the `.zip` or `.aar` -file into the library. When a Xamarin.Android application project -consumes the library, it will have access to the Java/Kotlin APIs from -C# as well as include the Java/Kotlin code in the final Android -application. - -> [!NOTE] -> Only a single **LibraryProjectZip** can be included in a -> Xamarin.Android binding project. This limitation will be removed -> in .NET 6. - -## LinkDescription - -Files with a *LinkDescription* build action are used to -[control linker behavior](~/cross-platform/deploy-test/linker.md). - -## ProguardConfiguration - -Files with a *ProguardConfiguration* build action contain options which -are used to control `proguard` behavior. For more information about -this build action, see -[ProGuard](~/android/deploy-test/release-prep/proguard.md). - -These files are ignored unless the -[`$(EnableProguard)`](~/android/deploy-test/building-apps/build-properties.md#enableproguard) -MSBuild property is `True`.