Skip to content

Commit d798cc9

Browse files
authored
[Xamarin.Android.Build.Tasks] DTBs should not rm generator output (#8706)
Fixes: #8658 Fixes: #8698 Design-time builds don't play nicely with binding project builds: % dotnet new androidlib % cat > Example.java <<EOF package e; public class Example { public static void e() { } } EOF % dotnet build -p:DesignTimeBuild=true -v:diag After this initial Design-Time build, we have the following generated source code for the binding: % find obj -iname \*.cs | xargs ls -l -rw-r--r-- 1 user staff 197 Mar 25 19:22 obj/Debug/net8.0-android/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs -rw-r--r-- 1 user staff 441 Mar 25 19:22 obj/Debug/net8.0-android/__Microsoft.Android.Resource.Designer.cs -rw-r--r-- 1 user staff 2975 Mar 25 19:22 obj/Debug/net8.0-android/generated/src/E.Example.cs -rw-r--r-- 1 user staff 1518 Mar 25 19:22 obj/Debug/net8.0-android/generated/src/Java.Interop.__TypeRegistrations.cs -rw-r--r-- 1 user staff 696 Mar 25 19:22 obj/Debug/net8.0-android/generated/src/__NamespaceMapping__.cs -rw-r--r-- 1 user staff 1094 Mar 25 19:22 obj/Debug/net8.0-android/gxa-8706.AssemblyInfo.cs -rw-r--r-- 1 user staff 407 Mar 25 19:22 obj/Debug/net8.0-android/gxa-8706.GlobalUsings.g.cs Run a Design-Time build *again*: % dotnet build -p:DesignTimeBuild=true -v:diag …and we're now missing files (?!): % find obj -iname \*.cs | xargs ls -l -rw-r--r-- 1 user staff 197 Mar 25 19:22 obj/Debug/net8.0-android/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs -rw-r--r-- 1 user staff 441 Mar 25 19:22 obj/Debug/net8.0-android/__Microsoft.Android.Resource.Designer.cs -rw-r--r-- 1 user staff 1094 Mar 25 19:22 obj/Debug/net8.0-android/gxa-8706.AssemblyInfo.cs -rw-r--r-- 1 user staff 407 Mar 25 19:22 obj/Debug/net8.0-android/gxa-8706.GlobalUsings.g.cs In particular, `$(IntermediateOutputPath)generated/*/**.cs` is gone, including `E.Example.cs`! The result of this is that Design-Time builds and "normal" builds "fight" each other, constantly generating and deleting files, slowing down incremental builds. The root of the problem is the `_ClearGeneratedManagedBindings` target: It was designed to clean out the `generated` folder in the case where no binding libraries were present. However, it turns out it was running during a design time build! During design time builds the binding library item groups are not evaluated, so the `_ClearGeneratedManagedBindings` target would run, deleting everything. Fix this by ensuring we only run the `_ClearGeneratedManagedBindings` target in in "standard"/*non*-Design-Time builds.
1 parent bea92a5 commit d798cc9

File tree

10 files changed

+152
-23
lines changed

10 files changed

+152
-23
lines changed

src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,31 @@ It is shared between "legacy" binding projects and .NET 5 projects.
4444
/>
4545
</Target>
4646

47+
<Target Name="_CollectLibrariesToBind" DependsOnTargets="_CategorizeAndroidLibraries">
48+
<ItemGroup>
49+
<_LibrariesToBind Include="@(EmbeddedJar)" />
50+
<_LibrariesToBind Include="@(InputJar)" />
51+
<_LibrariesToBind Include="@(LibraryProjectZip)" />
52+
<_LibrariesToBind Include="@(_JavaBindingSource)" Condition=" '%(_JavaBindingSource.Bind)' == 'true' "/>
53+
</ItemGroup>
54+
</Target>
55+
4756
<Target Name="_SetAndroidGenerateManagedBindings"
48-
Condition=" '@(InputJar->Count())' != '0' Or '@(EmbeddedJar->Count())' != '0' Or '@(LibraryProjectZip->Count())' != '0' Or '@(_JavaBindingSource->Count())' != '0' ">
57+
Condition=" '@(_LibrariesToBind->Count())' != '0' ">
4958
<PropertyGroup>
5059
<!-- Used throughout to determine if C# binding-related targets should skip -->
5160
<_AndroidGenerateManagedBindings>true</_AndroidGenerateManagedBindings>
5261
</PropertyGroup>
5362
</Target>
5463

55-
<Target Name="_CollectGeneratedManagedBindingFiles">
64+
<Target Name="_CollectGeneratedManagedBindingFiles" AfterTargets="GenerateBindings">
5665
<ItemGroup>
5766
<_GeneratedManagedBindingFiles Include="$(GeneratedOutputPath)**\*.cs" />
5867
</ItemGroup>
5968
</Target>
6069

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

7684
<Target Name="GenerateBindings"
7785
Condition=" '$(_AndroidGenerateManagedBindings)' == 'true' "
78-
DependsOnTargets="ExportJarToXml;_ResolveMonoAndroidSdks"
7986
Inputs="$(ApiOutputFile);@(TransformFile);@(ReferencePath);@(ReferenceDependencyPaths);@(_AndroidMSBuildAllProjects)"
8087
Outputs="$(_GeneratorStampFile)">
8188

@@ -135,14 +142,17 @@ It is shared between "legacy" binding projects and .NET 5 projects.
135142

136143
<ItemGroup>
137144
<FileWrites Include="$(GeneratedOutputPath)**\*.cs" />
145+
<FileWrites Include="$(GeneratedOutputPath)src\$(AssemblyName).projitems" />
138146
<FileWrites Include="$(_GeneratorStampFile)" />
139147
</ItemGroup>
140148

149+
<!-- Read the file list. -->
150+
141151
</Target>
142152

143153
<Target Name="AddBindingsToCompile"
144154
Condition=" '$(_AndroidGenerateManagedBindings)' == 'true' Or '@(_GeneratedManagedBindingFiles->Count())' != '0' "
145-
DependsOnTargets="GenerateBindings;_CollectGeneratedManagedBindingFiles">
155+
>
146156
<!-- bindings need AllowUnsafeBlocks -->
147157
<PropertyGroup>
148158
<AllowUnsafeBlocks Condition=" '$(AllowUnsafeBlocks)' != 'true' ">true</AllowUnsafeBlocks>

src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ It is shared between "legacy" binding projects and .NET 7+ projects.
2121
<_AndroidIntermediateBindingClassesZip>$(IntermediateOutputPath)binding\bin\$(MSBuildProjectName).jar</_AndroidIntermediateBindingClassesZip>
2222
<_AndroidIntermediateBindingClassesDocs>$(IntermediateOutputPath)binding\bin\$(MSBuildProjectName)-docs.xml</_AndroidIntermediateBindingClassesDocs>
2323
<_AndroidCompileJavaStampFile>$(_AndroidStampDirectory)_CompileJava.stamp</_AndroidCompileJavaStampFile>
24+
<_AndroidCompileJavaFileList>$(IntermediateOutputPath)_CompileJava.FileList.txt</_AndroidCompileJavaFileList>
2425
<_AndroidCompileBindingJavaStampFile>$(_AndroidStampDirectory)_CompileBindingJava.stamp</_AndroidCompileBindingJavaStampFile>
26+
<_AndroidCompileBindingJavaFileList>$(IntermediateOutputPath)_CompileBindingJava.FileList.txt</_AndroidCompileBindingJavaFileList>
2527
</PropertyGroup>
2628

2729
<Target Name="_AdjustJavacVersionArguments">
@@ -74,18 +76,36 @@ It is shared between "legacy" binding projects and .NET 7+ projects.
7476
<ItemGroup>
7577
<_JavaBindingSource Include="@(AndroidJavaSource)" Condition=" '%(AndroidJavaSource.Bind)' == 'True' " />
7678
</ItemGroup>
79+
<WriteLinesToFile
80+
File="$(_AndroidCompileBindingJavaFileList)"
81+
Lines="@(_JavaBindingSource->ToLowerInvariant())"
82+
Overwrite="true"
83+
WriteOnlyWhenDifferent="true"
84+
/>
85+
<ItemGroup>
86+
<FileWrites Include="$(_AndroidCompileBindingJavaFileList)" />
87+
</ItemGroup>
7788
</Target>
7889

7990
<Target Name="_CollectJavaSource">
8091
<ItemGroup>
8192
<_JavaSource Include="@(AndroidJavaSource)" Condition=" '%(AndroidJavaSource.Bind)' != 'True' " />
8293
</ItemGroup>
94+
<WriteLinesToFile
95+
File="$(_AndroidCompileJavaFileList)"
96+
Lines="@(_JavaSource->ToLowerInvariant())"
97+
Overwrite="true"
98+
WriteOnlyWhenDifferent="true"
99+
/>
100+
<ItemGroup>
101+
<FileWrites Include="$(_AndroidCompileJavaFileList)" />
102+
</ItemGroup>
83103
</Target>
84104

85105
<Target Name="_CompileBindingJava"
86106
Condition=" '@(_JavaBindingSource->Count())' != '0' "
87107
DependsOnTargets="$(_CompileBindingJavaDependsOnTargets)"
88-
Inputs="@(_AndroidMSBuildAllProjects);$(MonoPlatformJarPath);@(_JavaBindingSource)"
108+
Inputs="@(_AndroidMSBuildAllProjects);$(_AndroidCompileBindingJavaFileList);$(MonoPlatformJarPath);@(_JavaBindingSource)"
89109
Outputs="$(_AndroidCompileBindingJavaStampFile)">
90110

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

133153
<Target Name="_CompileJava"
134154
DependsOnTargets="$(_CompileJavaDependsOnTargets);_CollectJavaSource"
135-
Inputs="@(_AndroidMSBuildAllProjects);$(MonoPlatformJarPath);@(_JavaStubFiles);@(_JavaSource)"
155+
Inputs="@(_AndroidMSBuildAllProjects);$(_AndroidCompileJavaFileList);$(MonoPlatformJarPath);@(_JavaStubFiles);@(_JavaSource)"
136156
Outputs="$(_AndroidCompileJavaStampFile)">
137157

138158
<!-- remove existing <Javac /> outputs, since *.class files and classes.zip could contain old files -->

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,6 @@ properties that determine build ordering.
120120
UpdateAndroidResources;
121121
_BuildResourceDesigner;
122122
UpdateAndroidInterfaceProxies;
123-
_SetAndroidGenerateManagedBindings;
124-
_ClearGeneratedManagedBindings;
125-
AddBindingsToCompile;
126123
_CheckForInvalidDesignerConfig;
127124
</ResolveReferencesDependsOn>
128125
<DesignTimeResolveAssemblyReferencesDependsOn>
@@ -144,6 +141,13 @@ properties that determine build ordering.
144141
_AddAndroidDefines;
145142
_IncludeLayoutBindingSources;
146143
AddLibraryJarsToBind;
144+
_CollectLibrariesToBind;
145+
_SetAndroidGenerateManagedBindings;
146+
ExportJarToXml;
147+
GenerateBindings;
148+
_CollectGeneratedManagedBindingFiles;
149+
_ClearGeneratedManagedBindings;
150+
AddBindingsToCompile;
147151
_BuildResourceDesigner;
148152
_AddResourceDesignerFiles;
149153
$(CompileDependsOn);

src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using System.Linq;
77
using System.Xml;
88
using System.Xml.Linq;
9+
using System.Xml.XPath;
910
using Microsoft.Build.Framework;
11+
using Microsoft.Build.Utilities;
1012
using Microsoft.Android.Build.Tasks;
1113

1214
namespace Xamarin.Android.Tasks

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void DotNetBuildBinding ()
3939
proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javaclasses-sources.jar") {
4040
BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar,
4141
});
42-
proj.OtherBuildItems.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") {
42+
proj.AndroidJavaSources.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") {
4343
Encoding = Encoding.ASCII,
4444
TextContent = () => ResourceData.JavaSourceTestExtension,
4545
Metadata = { { "Bind", "True"} },
@@ -75,6 +75,7 @@ public void BindingLibraryIncremental (string classParser)
7575
"_ResolveLibraryProjectImports",
7676
"CoreCompile",
7777
"_CreateAar",
78+
"_ClearGeneratedManagedBindings",
7879
};
7980

8081
var proj = new XamarinAndroidBindingProject () {
@@ -112,6 +113,23 @@ public void BindingLibraryIncremental (string classParser)
112113
foreach (var target in targets) {
113114
Assert.IsTrue (b.Output.IsTargetSkipped (target), $"`{target}` should be skipped on second build!");
114115
}
116+
117+
Assert.IsTrue (b.DesignTimeBuild (proj, target: "UpdateGeneratedFiles"), "DTB should have succeeded.");
118+
var cs_file = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "generated", "src", "Com.Larvalabs.Svgandroid.SVGParser.cs");
119+
FileAssert.Exists (cs_file);
120+
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "third build should succeed");
121+
foreach (var target in targets) {
122+
Assert.IsTrue (b.Output.IsTargetSkipped (target), $"`{target}` should be skipped on second build!");
123+
}
124+
// Fast Update Check Build
125+
Assert.IsTrue (b.DesignTimeBuild (proj, target: "PrepareResources;_GenerateCompileInputs"), "DTB should have succeeded.");
126+
cs_file = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "generated", "src", "Com.Larvalabs.Svgandroid.SVGParser.cs");
127+
FileAssert.Exists (cs_file);
128+
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "forth build should succeed");
129+
foreach (var target in targets) {
130+
Assert.IsTrue (b.Output.IsTargetSkipped (target), $"`{target}` should be skipped on second build!");
131+
}
132+
115133
}
116134
}
117135

@@ -671,6 +689,10 @@ public void BindingWithAndroidJavaSource ()
671689
StringAssertEx.ContainsText (File.ReadAllLines (generatedIface), "string GreetWithQuestion (string name, global::Java.Util.Date date, string question);");
672690
Assert.IsTrue (libBuilder.Build (lib), "Library build should have succeeded.");
673691
Assert.IsTrue (libBuilder.Output.IsTargetSkipped ("_CompileBindingJava"), $"`_CompileBindingJava` should be skipped on second build!");
692+
Assert.IsTrue (libBuilder.Output.IsTargetSkipped ("_ClearGeneratedManagedBindings"), $"`_ClearGeneratedManagedBindings` should be skipped on second build!");
693+
FileAssert.Exists (generatedCode, $"'{generatedCode}' should have not be deleted on second build.");
694+
Assert.IsTrue (libBuilder.DesignTimeBuild (lib, target: "UpdateGeneratedFiles"), "DTB should have succeeded.");
695+
FileAssert.Exists (generatedCode, $"'{generatedCode}' should have not be deleted on DTB build.");
674696
Assert.IsTrue (appBuilder.Build (app), "App build should have succeeded.");
675697
appBuilder.Target = "SignAndroidPackage";
676698
Assert.IsTrue (appBuilder.Build (app), "App SignAndroidPackage should have succeeded.");

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot, bo
7070
proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javaclasses-sources.jar") {
7171
BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar,
7272
});
73-
proj.OtherBuildItems.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") {
73+
proj.AndroidJavaSources.Add (new AndroidItem.AndroidJavaSource ("JavaSourceTestExtension.java") {
7474
Encoding = Encoding.ASCII,
7575
TextContent = () => ResourceData.JavaSourceTestExtension,
7676
Metadata = { { "Bind", "True"} },
@@ -1511,7 +1511,7 @@ public void BuildApplicationWithJavaSourceUsingAndroidX ([Values(true, false)] b
15111511
{
15121512
var proj = new XamarinAndroidApplicationProject () {
15131513
IsRelease = isRelease,
1514-
OtherBuildItems = {
1514+
AndroidJavaSources = {
15151515
new BuildItem (AndroidBuildActions.AndroidJavaSource, "ToolbarEx.java") {
15161516
TextContent = () => @"package com.unnamedproject.unnamedproject;
15171517
import android.content.Context;
@@ -1556,11 +1556,11 @@ public void BuildApplicationCheckThatAddStaticResourcesTargetDoesNotRerun ()
15561556
public void CheckJavaError ()
15571557
{
15581558
var proj = new XamarinAndroidApplicationProject ();
1559-
proj.OtherBuildItems.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "TestMe.java") {
1559+
proj.AndroidJavaSources.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "TestMe.java") {
15601560
TextContent = () => "public classo TestMe { }",
15611561
Encoding = Encoding.ASCII
15621562
});
1563-
proj.OtherBuildItems.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "TestMe2.java") {
1563+
proj.AndroidJavaSources.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "TestMe2.java") {
15641564
TextContent = () => "public class TestMe2 {" +
15651565
"public vod Test ()" +
15661566
"}",

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,14 +1000,14 @@ public void BuildProguardEnabledProject (string rid)
10001000
XamarinAndroidApplicationProject CreateMultiDexRequiredApplication (string debugConfigurationName = "Debug", string releaseConfigurationName = "Release")
10011001
{
10021002
var proj = new XamarinAndroidApplicationProject (debugConfigurationName, releaseConfigurationName);
1003-
proj.OtherBuildItems.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "ManyMethods.java") {
1003+
proj.AndroidJavaSources.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "ManyMethods.java") {
10041004
TextContent = () => "public class ManyMethods { \n"
10051005
+ string.Join (Environment.NewLine, Enumerable.Range (0, 32768).Select (i => "public void method" + i + "() {}"))
10061006
+ "}",
10071007
Encoding = Encoding.ASCII,
10081008
Metadata = { { "Bind", "False "}},
10091009
});
1010-
proj.OtherBuildItems.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "ManyMethods2.java") {
1010+
proj.AndroidJavaSources.Add (new BuildItem (AndroidBuildActions.AndroidJavaSource, "ManyMethods2.java") {
10111011
TextContent = () => "public class ManyMethods2 { \n"
10121012
+ string.Join (Environment.NewLine, Enumerable.Range (0, 32768).Select (i => "public void method" + i + "() {}"))
10131013
+ "}",
@@ -1064,8 +1064,8 @@ public void BuildAfterMultiDexIsNotRequired ()
10641064
}
10651065

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

10711071
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "Build should have succeeded.");

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/BuildOutput.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public List<string> GetAssemblyMapCache ()
5252
return File.ReadLines (path).ToList ();
5353
}
5454

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

57-
public static bool IsTargetSkipped (IEnumerable<string> output, string target)
57+
public static bool IsTargetSkipped (IEnumerable<string> output, string target, bool defaultIfNotUsed = false)
5858
{
5959
bool found = false;
6060
foreach (var line in output) {
@@ -69,7 +69,7 @@ public static bool IsTargetSkipped (IEnumerable<string> output, string target)
6969
if (found)
7070
return true;
7171
}
72-
return false;
72+
return defaultIfNotUsed;
7373
}
7474

7575
/// <summary>

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetXamarinProject.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ protected DotNetXamarinProject (string debugConfigurationName = "Debug", string
1717

1818
Sources = new List<BuildItem> ();
1919
OtherBuildItems = new List<BuildItem> ();
20+
AndroidJavaSources = new List<BuildItem> ();
2021

2122
ItemGroupList.Add (References);
2223
ItemGroupList.Add (OtherBuildItems);
2324
ItemGroupList.Add (Sources);
25+
ItemGroupList.Add (AndroidJavaSources);
2426

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

4143
public IList<BuildItem> OtherBuildItems { get; private set; }
4244
public IList<BuildItem> Sources { get; private set; }
45+
public IList<BuildItem> AndroidJavaSources { get; private set; }
4346

4447
public IList<Property> ActiveConfigurationProperties {
4548
get { return IsRelease ? ReleaseProperties : DebugProperties; }

tests/MSBuildDeviceIntegration/Tests/InstallTests.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,5 +611,73 @@ public void AdbTargetChangesAppBundle ()
611611
var after = File.GetLastWriteTimeUtc (apkset);
612612
Assert.AreNotEqual (before, after, $"{apkset} should change!");
613613
}
614+
615+
[Test]
616+
public void AppWithAndroidJavaSource ()
617+
{
618+
var path = Path.Combine ("temp", TestName);
619+
var itemToDelete = new AndroidItem.AndroidJavaSource ("TestJavaClass2.java") {
620+
Encoding = Encoding.ASCII,
621+
TextContent = () => @"package com.test.java;
622+
623+
public class TestJavaClass2 {
624+
625+
public String test(){
626+
627+
return ""Java is called"";
628+
}
629+
}",
630+
Metadata = {
631+
{ "Bind", "True" },
632+
},
633+
};
634+
var proj = new XamarinAndroidApplicationProject {
635+
EnableDefaultItems = true,
636+
AndroidJavaSources = {
637+
new AndroidItem.AndroidJavaSource ("TestJavaClass.java") {
638+
Encoding = Encoding.ASCII,
639+
TextContent = () => @"package com.test.java;
640+
641+
public class TestJavaClass {
642+
643+
public String test(){
644+
645+
return ""Java is called"";
646+
}
647+
}",
648+
Metadata = {
649+
{ "Bind", "True" },
650+
},
651+
},
652+
itemToDelete,
653+
},
654+
};
655+
using (var b = CreateApkBuilder ()) {
656+
b.ThrowOnBuildFailure = false;
657+
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
658+
b.AssertHasNoWarnings ();
659+
var generatedCode = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath,
660+
"generated", "src", "Com.Test.Java.TestJavaClass.cs");
661+
var generatedCode2 = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath,
662+
"generated", "src", "Com.Test.Java.TestJavaClass2.cs");
663+
FileAssert.Exists (generatedCode, $"'{generatedCode}' should have been generated.");
664+
FileAssert.Exists (generatedCode2, $"'{generatedCode2}' should have been generated.");
665+
Assert.IsTrue (b.DesignTimeBuild (proj, target: "UpdateGeneratedFiles"), "DTB should have succeeded.");
666+
Assert.IsTrue (b.Output.IsTargetSkipped ("_ClearGeneratedManagedBindings", defaultIfNotUsed: true), $"`_ClearGeneratedManagedBindings` should be skipped on DTB build!");
667+
FileAssert.Exists (generatedCode, $"'{generatedCode}' should have not be deleted on DTB build.");
668+
FileAssert.Exists (generatedCode2, $"'{generatedCode2}' should have not be deleted on DTB build.");
669+
proj.AndroidJavaSources.Remove (itemToDelete);
670+
File.Delete (Path.Combine (Root, b.ProjectDirectory, itemToDelete.Include ()));
671+
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "Second build should have succeeded.");
672+
FileAssert.Exists (generatedCode, $"'{generatedCode}' should have not be deleted on second build.");
673+
FileAssert.DoesNotExist (generatedCode2, $"'{generatedCode2}' should have be deleted on second build.");
674+
Assert.IsFalse (b.Output.IsTargetSkipped ("_CompileBindingJava"), $"`_CompileBindingJava` should run on second build!");
675+
Assert.IsTrue (b.Output.IsTargetSkipped ("_ClearGeneratedManagedBindings"), $"`_ClearGeneratedManagedBindings` should be skipped on second build!");
676+
// Call Install directly so Build does not get called automatically
677+
Assert.IsTrue (b.RunTarget (proj, "Install", doNotCleanupOnUpdate: true, saveProject: false), "Install build should have succeeded.");
678+
FileAssert.Exists (generatedCode, $"'{generatedCode}' should have not be deleted on Install build.");
679+
Assert.IsTrue (b.Output.IsTargetSkipped ("_ClearGeneratedManagedBindings", defaultIfNotUsed: true), $"`_ClearGeneratedManagedBindings` should be skipped on Install build!");
680+
}
681+
}
614682
}
615683
}

0 commit comments

Comments
 (0)