Skip to content

Commit

Permalink
Add test for Binding Projects and FastUpdate
Browse files Browse the repository at this point in the history
  • Loading branch information
dellis1972 committed Mar 25, 2024
1 parent 4696bf3 commit d03b942
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,31 @@ It is shared between "legacy" binding projects and .NET 5 projects.
/>
</Target>

<Target Name="_CollectLibrariesToBind" DependsOnTargets="_CategorizeAndroidLibraries">
<ItemGroup>
<_LibrariesToBind Include="@(EmbeddedJar)" />
<_LibrariesToBind Include="@(InputJar)" />
<_LibrariesToBind Include="@(LibraryProjectZip)" />
<_LibrariesToBind Include="@(_JavaBindingSource)" Condition=" '%(_JavaBindingSource.Bind)' == 'true' "/>
</ItemGroup>
</Target>

<Target Name="_SetAndroidGenerateManagedBindings"
Condition=" '@(InputJar->Count())' != '0' Or '@(EmbeddedJar->Count())' != '0' Or '@(LibraryProjectZip->Count())' != '0' Or '@(_JavaBindingSource->Count())' != '0' ">
Condition=" '@(_LibrariesToBind->Count())' != '0' ">
<PropertyGroup>
<!-- Used throughout to determine if C# binding-related targets should skip -->
<_AndroidGenerateManagedBindings>true</_AndroidGenerateManagedBindings>
</PropertyGroup>
</Target>

<Target Name="_CollectGeneratedManagedBindingFiles">
<Target Name="_CollectGeneratedManagedBindingFiles" AfterTargets="GenerateBindings">
<ItemGroup>
<_GeneratedManagedBindingFiles Include="$(GeneratedOutputPath)**\*.cs" />
</ItemGroup>
</Target>

<Target Name="_ClearGeneratedManagedBindings"
Condition=" '@(InputJar->Count())' == '0' And '@(EmbeddedJar->Count())' == '0' And '@(LibraryProjectZip->Count())' == '0' And '@(_JavaBindingSource->Count())' == '0' "
DependsOnTargets="_CollectGeneratedManagedBindingFiles"
Condition=" '@(_LibrariesToBind->Count())' == '0' And '$(DesignTimeBuild)' != 'True' "
>
<Delete Files="@(_GeneratedManagedBindingFiles)" />
</Target>
Expand All @@ -75,7 +83,6 @@ It is shared between "legacy" binding projects and .NET 5 projects.

<Target Name="GenerateBindings"
Condition=" '$(_AndroidGenerateManagedBindings)' == 'true' "
DependsOnTargets="ExportJarToXml;_ResolveMonoAndroidSdks"
Inputs="$(ApiOutputFile);@(TransformFile);@(ReferencePath);@(ReferenceDependencyPaths);@(_AndroidMSBuildAllProjects)"
Outputs="$(_GeneratorStampFile)">

Expand Down Expand Up @@ -128,21 +135,35 @@ It is shared between "legacy" binding projects and .NET 5 projects.
Nullable="$(Nullable)"
UseJavaLegacyResolver="$(_AndroidUseJavaLegacyResolver)"
NamespaceTransforms="@(AndroidNamespaceReplacement)"
/>
GeneratedFileListFile="$(GeneratedOutputPath)src\$(AssemblyName).projitems"
>
<Output TaskParameter="GeneratedFiles" ItemName="_GeneratedBindingFiles" />
</BindingsGenerator>

<!-- Write a flag so we won't redo this target if nothing changed -->
<Touch Files="$(_GeneratorStampFile)" AlwaysCreate="true" />

<ItemGroup Condition=" '@(_GeneratedBindingFiles->Count())' != '0' ">
<_ExistingGeneratedFiles Include="$(GeneratedOutputPath)**\*.cs" />
<_ExistingGeneratedFiles Remove="@(_GeneratedBindingFiles)" />
</ItemGroup>

<!-- Delete any files which should not be there. -->
<Delete Files="@(_ExistingGeneratedFiles)" Condition=" '@(_ExistingGeneratedFiles->Count())' != '0' "/>

<ItemGroup>
<FileWrites Include="$(GeneratedOutputPath)**\*.cs" />
<FileWrites Include="$(GeneratedOutputPath)src\$(AssemblyName).projitems" />
<FileWrites Include="$(_GeneratorStampFile)" />
</ItemGroup>

<!-- Read the file list. -->

</Target>

<Target Name="AddBindingsToCompile"
Condition=" '$(_AndroidGenerateManagedBindings)' == 'true' Or '@(_GeneratedManagedBindingFiles->Count())' != '0' "
DependsOnTargets="GenerateBindings;_CollectGeneratedManagedBindingFiles">
>
<!-- bindings need AllowUnsafeBlocks -->
<PropertyGroup>
<AllowUnsafeBlocks Condition=" '$(AllowUnsafeBlocks)' != 'true' ">true</AllowUnsafeBlocks>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ It is shared between "legacy" binding projects and .NET 7+ projects.
<_AndroidIntermediateBindingClassesZip>$(IntermediateOutputPath)binding\bin\$(MSBuildProjectName).jar</_AndroidIntermediateBindingClassesZip>
<_AndroidIntermediateBindingClassesDocs>$(IntermediateOutputPath)binding\bin\$(MSBuildProjectName)-docs.xml</_AndroidIntermediateBindingClassesDocs>
<_AndroidCompileJavaStampFile>$(_AndroidStampDirectory)_CompileJava.stamp</_AndroidCompileJavaStampFile>
<_AndroidCompileJavaFileList>$(IntermediateOutputPath)_CompileJava.FileList.txt</_AndroidCompileJavaFileList>
<_AndroidCompileBindingJavaStampFile>$(_AndroidStampDirectory)_CompileBindingJava.stamp</_AndroidCompileBindingJavaStampFile>
<_AndroidCompileBindingJavaFileList>$(IntermediateOutputPath)_CompileBindingJava.FileList.txt</_AndroidCompileBindingJavaFileList>
</PropertyGroup>

<Target Name="_AdjustJavacVersionArguments">
Expand Down Expand Up @@ -74,18 +76,36 @@ It is shared between "legacy" binding projects and .NET 7+ projects.
<ItemGroup>
<_JavaBindingSource Include="@(AndroidJavaSource)" Condition=" '%(AndroidJavaSource.Bind)' == 'True' " />
</ItemGroup>
<WriteLinesToFile
File="$(_AndroidCompileBindingJavaFileList)"
Lines="@(_JavaBindingSource->ToLowerInvariant())"
Overwrite="true"
WriteOnlyWhenDifferent="true"
/>
<ItemGroup>
<FileWrites Include="$(_AndroidCompileBindingJavaFileList)" />
</ItemGroup>
</Target>

<Target Name="_CollectJavaSource">
<ItemGroup>
<_JavaSource Include="@(AndroidJavaSource)" Condition=" '%(AndroidJavaSource.Bind)' != 'True' " />
</ItemGroup>
<WriteLinesToFile
File="$(_AndroidCompileJavaFileList)"
Lines="@(_JavaSource->ToLowerInvariant())"
Overwrite="true"
WriteOnlyWhenDifferent="true"
/>
<ItemGroup>
<FileWrites Include="$(_AndroidCompileJavaFileList)" />
</ItemGroup>
</Target>

<Target Name="_CompileBindingJava"
Condition=" '@(_JavaBindingSource->Count())' != '0' "
DependsOnTargets="$(_CompileBindingJavaDependsOnTargets)"
Inputs="@(_AndroidMSBuildAllProjects);$(MonoPlatformJarPath);@(_JavaBindingSource)"
Inputs="@(_AndroidMSBuildAllProjects);$(_AndroidCompileBindingJavaFileList);$(MonoPlatformJarPath);@(_JavaBindingSource)"
Outputs="$(_AndroidCompileBindingJavaStampFile)">

<!-- remove existing <Javac /> outputs, since *.class files and classes.zip could contain old files -->
Expand Down Expand Up @@ -132,7 +152,7 @@ It is shared between "legacy" binding projects and .NET 7+ projects.

<Target Name="_CompileJava"
DependsOnTargets="$(_CompileJavaDependsOnTargets);_CollectJavaSource"
Inputs="@(_AndroidMSBuildAllProjects);$(MonoPlatformJarPath);@(_JavaStubFiles);@(_JavaSource)"
Inputs="@(_AndroidMSBuildAllProjects);$(_AndroidCompileJavaFileList);$(MonoPlatformJarPath);@(_JavaStubFiles);@(_JavaSource)"
Outputs="$(_AndroidCompileJavaStampFile)">

<!-- remove existing <Javac /> outputs, since *.class files and classes.zip could contain old files -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ properties that determine build ordering.
UpdateAndroidResources;
_BuildResourceDesigner;
UpdateAndroidInterfaceProxies;
_SetAndroidGenerateManagedBindings;
_ClearGeneratedManagedBindings;
AddBindingsToCompile;
_CheckForInvalidDesignerConfig;
</ResolveReferencesDependsOn>
<DesignTimeResolveAssemblyReferencesDependsOn>
Expand All @@ -144,6 +141,13 @@ properties that determine build ordering.
_AddAndroidDefines;
_IncludeLayoutBindingSources;
AddLibraryJarsToBind;
_CollectLibrariesToBind;
_SetAndroidGenerateManagedBindings;
ExportJarToXml;
GenerateBindings;
_CollectGeneratedManagedBindingFiles;
_ClearGeneratedManagedBindings;
AddBindingsToCompile;
_BuildResourceDesigner;
_AddResourceDesignerFiles;
$(CompileDependsOn);
Expand Down
21 changes: 20 additions & 1 deletion src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.Android.Build.Tasks;

namespace Xamarin.Android.Tasks
Expand Down Expand Up @@ -67,6 +69,10 @@ public class BindingsGenerator : AndroidDotnetToolTask

public bool UseJavaLegacyResolver { get; set; }

public string GeneratedFileListFile { get; set; }
[Output]
public ITaskItem [] GeneratedFiles { get; set; } = Array.Empty<ITaskItem> ();

private List<Tuple<string, string>> transform_files = new List<Tuple<string,string>> ();

public override bool RunTask ()
Expand Down Expand Up @@ -133,7 +139,20 @@ public override bool RunTask ()
if (Log.HasLoggedErrors)
return false;

return base.RunTask ();
var result = base.RunTask ();
List<ITaskItem> files = new List<ITaskItem> ();
if (result && GeneratedFileListFile != null && File.Exists (GeneratedFileListFile)) {
var doc = XDocument.Load (GeneratedFileListFile);
var compileItems = doc.XPathSelectElements ("//Project/ItemGroup/Compile");
foreach (var item in compileItems) {
var file = item.Attribute ("Include");
if (file != null && File.Exists (file.Value)) {
files.Add (new TaskItem (file.Value));
}
}
}
GeneratedFiles = files.ToArray ();
return result;
}

void WriteLine (StreamWriter sw, string line)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void DotNetBuildBinding ()
proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javaclasses-sources.jar") {
BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar,
});
proj.OtherBuildItems.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") {
proj.AndroidJavaSources.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") {
Encoding = Encoding.ASCII,
TextContent = () => ResourceData.JavaSourceTestExtension,
Metadata = { { "Bind", "True"} },
Expand Down Expand Up @@ -75,6 +75,7 @@ public void BindingLibraryIncremental (string classParser)
"_ResolveLibraryProjectImports",
"CoreCompile",
"_CreateAar",
"_ClearGeneratedManagedBindings",
};

var proj = new XamarinAndroidBindingProject () {
Expand Down Expand Up @@ -112,6 +113,23 @@ public void BindingLibraryIncremental (string classParser)
foreach (var target in targets) {
Assert.IsTrue (b.Output.IsTargetSkipped (target), $"`{target}` should be skipped on second build!");
}

Assert.IsTrue (b.DesignTimeBuild (proj, target: "UpdateGeneratedFiles"), "DTB should have succeeded.");
var cs_file = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "generated", "src", "Com.Larvalabs.Svgandroid.SVGParser.cs");
FileAssert.Exists (cs_file);
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "third build should succeed");
foreach (var target in targets) {
Assert.IsTrue (b.Output.IsTargetSkipped (target), $"`{target}` should be skipped on second build!");
}
// Fast Update Check Build
Assert.IsTrue (b.DesignTimeBuild (proj, target: "PrepareResources;_GenerateCompileInputs"), "DTB should have succeeded.");
cs_file = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "generated", "src", "Com.Larvalabs.Svgandroid.SVGParser.cs");
FileAssert.Exists (cs_file);
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "forth build should succeed");
foreach (var target in targets) {
Assert.IsTrue (b.Output.IsTargetSkipped (target), $"`{target}` should be skipped on second build!");
}

}
}

Expand Down Expand Up @@ -671,6 +689,10 @@ public void BindingWithAndroidJavaSource ()
StringAssertEx.ContainsText (File.ReadAllLines (generatedIface), "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 (libBuilder.Output.IsTargetSkipped ("_ClearGeneratedManagedBindings"), $"`_ClearGeneratedManagedBindings` should be skipped on second build!");
FileAssert.Exists (generatedCode, $"'{generatedCode}' should have not be deleted on second build.");
Assert.IsTrue (libBuilder.DesignTimeBuild (lib, target: "UpdateGeneratedFiles"), "DTB should have succeeded.");
FileAssert.Exists (generatedCode, $"'{generatedCode}' should have not be deleted on DTB build.");
Assert.IsTrue (appBuilder.Build (app), "App build should have succeeded.");
appBuilder.Target = "SignAndroidPackage";
Assert.IsTrue (appBuilder.Build (app), "App SignAndroidPackage should have succeeded.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ 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") {
proj.AndroidJavaSources.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") {
Encoding = Encoding.ASCII,
TextContent = () => ResourceData.JavaSourceTestExtension,
Metadata = { { "Bind", "True"} },
Expand Down Expand Up @@ -1511,7 +1511,7 @@ public void BuildApplicationWithJavaSourceUsingAndroidX ([Values(true, false)] b
{
var proj = new XamarinAndroidApplicationProject () {
IsRelease = isRelease,
OtherBuildItems = {
AndroidJavaSources = {
new BuildItem (AndroidBuildActions.AndroidJavaSource, "ToolbarEx.java") {
TextContent = () => @"package com.unnamedproject.unnamedproject;
import android.content.Context;
Expand Down Expand Up @@ -1556,11 +1556,11 @@ public void BuildApplicationCheckThatAddStaticResourcesTargetDoesNotRerun ()
public void CheckJavaError ()
{
var proj = new XamarinAndroidApplicationProject ();
proj.OtherBuildItems.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "TestMe.java") {
proj.AndroidJavaSources.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "TestMe.java") {
TextContent = () => "public classo TestMe { }",
Encoding = Encoding.ASCII
});
proj.OtherBuildItems.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "TestMe2.java") {
proj.AndroidJavaSources.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "TestMe2.java") {
TextContent = () => "public class TestMe2 {" +
"public vod Test ()" +
"}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1000,14 +1000,14 @@ public void BuildProguardEnabledProject (string rid)
XamarinAndroidApplicationProject CreateMultiDexRequiredApplication (string debugConfigurationName = "Debug", string releaseConfigurationName = "Release")
{
var proj = new XamarinAndroidApplicationProject (debugConfigurationName, releaseConfigurationName);
proj.OtherBuildItems.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "ManyMethods.java") {
proj.AndroidJavaSources.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "ManyMethods.java") {
TextContent = () => "public class ManyMethods { \n"
+ string.Join (Environment.NewLine, Enumerable.Range (0, 32768).Select (i => "public void method" + i + "() {}"))
+ "}",
Encoding = Encoding.ASCII,
Metadata = { { "Bind", "False "}},
});
proj.OtherBuildItems.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "ManyMethods2.java") {
proj.AndroidJavaSources.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 + "() {}"))
+ "}",
Expand Down Expand Up @@ -1064,8 +1064,8 @@ public void BuildAfterMultiDexIsNotRequired ()
}

//Now build project again after it no longer requires multidex, remove the *HUGE* AndroidJavaSource build items
while (proj.OtherBuildItems.Count > 1)
proj.OtherBuildItems.RemoveAt (proj.OtherBuildItems.Count - 1);
while (proj.AndroidJavaSources.Count > 1)
proj.AndroidJavaSources.RemoveAt (proj.AndroidJavaSources.Count - 1);
proj.SetProperty ("AndroidEnableMultiDex", "False");

Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "Build should have succeeded.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ public List<string> GetAssemblyMapCache ()
return File.ReadLines (path).ToList ();
}

public bool IsTargetSkipped (string target) => IsTargetSkipped (Builder.LastBuildOutput, target);
public bool IsTargetSkipped (string target, bool defaultIfNotUsed = false) => IsTargetSkipped (Builder.LastBuildOutput, target, defaultIfNotUsed);

public static bool IsTargetSkipped (IEnumerable<string> output, string target)
public static bool IsTargetSkipped (IEnumerable<string> output, string target, bool defaultIfNotUsed = false)
{
bool found = false;
foreach (var line in output) {
Expand All @@ -69,7 +69,7 @@ public static bool IsTargetSkipped (IEnumerable<string> output, string target)
if (found)
return true;
}
return false;
return defaultIfNotUsed;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ protected DotNetXamarinProject (string debugConfigurationName = "Debug", string

Sources = new List<BuildItem> ();
OtherBuildItems = new List<BuildItem> ();
AndroidJavaSources = new List<BuildItem> ();

ItemGroupList.Add (References);
ItemGroupList.Add (OtherBuildItems);
ItemGroupList.Add (Sources);
ItemGroupList.Add (AndroidJavaSources);

SetProperty ("RootNamespace", () => RootNamespace ?? ProjectName);
SetProperty ("AssemblyName", () => AssemblyName ?? ProjectName);
Expand All @@ -40,6 +42,7 @@ protected DotNetXamarinProject (string debugConfigurationName = "Debug", string

public IList<BuildItem> OtherBuildItems { get; private set; }
public IList<BuildItem> Sources { get; private set; }
public IList<BuildItem> AndroidJavaSources { get; private set; }

public IList<Property> ActiveConfigurationProperties {
get { return IsRelease ? ReleaseProperties : DebugProperties; }
Expand Down
Loading

0 comments on commit d03b942

Please sign in to comment.