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..bff7f06cb93
--- /dev/null
+++ b/Documentation/guides/BindingJavaSource.md
@@ -0,0 +1,103 @@
+---
+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.
diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md
index 837487ea0f6..44b37c48a2a 100644
--- a/Documentation/guides/building-apps/build-items.md
+++ b/Documentation/guides/building-apps/build-items.md
@@ -6,7 +6,7 @@ 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
@@ -89,6 +89,13 @@ 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
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,15 +115,17 @@ 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..75b68300b74
--- /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.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 2099fa39190..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
@@ -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;
@@ -146,6 +150,7 @@ projects, these properties are set in Xamarin.Android.Legacy.targets.
$(CleanDependsOn);
_CleanMonoAndroidIntermediateDir;
_CleanAndroidBuildPropertiesCache;
+ _CleanAarCache;
CleanBindingsOutput;
CleanLibraryProjectIntermediaries;
CleanNativeLibraryIntermediaries;
@@ -155,6 +160,7 @@ projects, these properties are set in Xamarin.Android.Legacy.targets.
_ExtractLibraryProjectImports;
_GetLibraryImports;
_ExtractAar;
+ _CollectJavaSourceForBinding;
_ExportJarToXml;
@@ -167,6 +173,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..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
@@ -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
{
@@ -90,13 +92,17 @@ 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",
+ "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)));
+ .Where (x => !ignoreFiles.Any (i => Path.GetFileName (x).Contains (i)));
CollectionAssert.IsEmpty (files, $"{proj.IntermediateOutputPath} should have no files.");
}
}
@@ -198,7 +204,7 @@ public override Java.Lang.Object LoadInBackground ()
{
return (Java.Lang.Object) LoadInBackgroundImpl ();
}
- }
+ }
}"
});
using (var b = CreateDllBuilder ()) {
@@ -357,7 +363,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 +645,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 ()
-
+