Skip to content

Commit 01024bb

Browse files
[xabt] fix incremental design-time builds (#10564)
Fixes: #10528 Fixes: #10563 There is a report in .NET 10 of *something* going wrong with incremental builds (and possibly design-time builds)... The app crashes with an error such as: android.content.res.Resources$NotFoundException: String resource ID #0x7f1000be at android.content.res.Resources.getText(Resources.java:466) at android.content.Context.getText(Context.java:933) at androidx.appcompat.widget.Toolbar.setNavigationContentDescription(Toolbar.java:1001) at crc64e02730b4d0e10e64.CustomShellRenderer_SectionRenderer.n_onCreateView(Native Method) at crc64e02730b4d0e10e64.CustomShellRenderer_SectionRenderer.onCreateView(CustomShellRenderer_SectionRenderer.java:36) ... Where the resource ID is invalid. After some debugging, after watching the video: * #10528 (comment) I was able to reproduce the issue, when I did: 1. Open emulator 2. Open project in VS 3. Ctrl+F5 (see app running) 4. Close VS (make sure emulator stays open) 5. Reopen VS 6. Ctrl+F5 again 7. App crashes Reviewing builds logs, I saw this oddity on the design-time build on step 5: Target _GenerateRtxt Building target "_GenerateRtxt" completely. Input file "Bug.Dependency.csproj" does not exist. That is a referenced project file, it definitely should exist! However, I noticed the path is wrong: Target _CollectProjectReferenceResources Task MSBuild OutputItems LibraryResourceDirectories D:\src\dotnet-android-bug-10528\src\Bug.Dependency\Resources StampFile = Bug.Dependency.csproj `%(StampFile)` is a relative path, which can be fixed via: StampFile="$(MSBuildProjectFile)" StampFile="$(MSBuildProjectFullPath)" This problem was introduced in .NET 10 via: * 9ed1469 The target also uses `$(MSBuildProjectDirectory)`, which is a full path, so it is ok. See: * https://learn.microsoft.com/visualstudio/msbuild/msbuild-reserved-and-well-known-properties I was also able to reproduce this issue by adding a class library to the existing `BuildInDesignTimeMode()` test.
1 parent 38cdcbe commit 01024bb

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Resource.Designer.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Copyright (C) 2016 Xamarin. All rights reserved.
6262
<ItemGroup>
6363
<_ProjectReferenceResourceDirectory Include="$(MSBuildProjectDirectory)\$(MonoAndroidResourcePrefix)"
6464
Condition=" !Exists('$(OutputPath)$(TargetName).aar') "
65-
StampFile="$(MSBuildProjectFile)"
65+
StampFile="$(MSBuildProjectFullPath)"
6666
/>
6767
</ItemGroup>
6868
</Target>

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

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -786,24 +786,54 @@ public void BuildInDesignTimeMode (
786786
AndroidRuntime runtime
787787
)
788788
{
789+
var path = Path.Combine (Root, "temp", $"BuildInDesignTimeMode_{useManagedParser}_{runtime}");
790+
var lib = new XamarinAndroidLibraryProject () {
791+
ProjectName = "Lib1",
792+
Sources = {
793+
new BuildItem.Source ("Foo.cs") {
794+
TextContent = () => "public class Foo { }"
795+
},
796+
},
797+
AndroidResources = {
798+
new AndroidItem.AndroidResource (() => "Resources\\drawable\\foo.png") {
799+
BinaryContent = () => XamarinAndroidApplicationProject.icon_binary_mdpi,
800+
},
801+
},
802+
};
803+
lib.SetProperty ("AndroidUseManagedDesignTimeResourceGenerator", useManagedParser.ToString ());
804+
789805
var proj = new XamarinAndroidApplicationProject () {
806+
ProjectName = "App1",
790807
IsRelease = true,
808+
References = {
809+
new BuildItem.ProjectReference (@"..\Lib1\Lib1.csproj", lib.ProjectName, lib.ProjectGuid),
810+
},
811+
Sources = {
812+
new BuildItem.Source ("Bar.cs") {
813+
TextContent = () => "public class Bar : Foo { }"
814+
},
815+
},
791816
};
792817
proj.SetRuntime (runtime);
793818
proj.SetProperty ("AndroidUseManagedDesignTimeResourceGenerator", useManagedParser.ToString ());
794-
using (var builder = CreateApkBuilder ()) {
819+
using (var libBuilder = CreateDllBuilder (Path.Combine (path, lib.ProjectName)))
820+
using (var builder = CreateApkBuilder (Path.Combine (path, proj.ProjectName))) {
821+
libBuilder.DesignTimeBuild (lib);
795822
builder.Target = "UpdateAndroidResources";
796823
builder.Build (proj, parameters: new string[] { "DesignTimeBuild=true" });
797-
Assert.IsFalse (builder.Output.IsTargetSkipped ("_CreatePropertiesCache"), "target \"_CreatePropertiesCache\" should have been run.");
798-
Assert.IsFalse (builder.Output.IsTargetSkipped ("_GenerateRtxt"), "target \"_GenerateRtxt\' should have been run.");
824+
builder.Output.AssertTargetIsNotSkipped ("_CreatePropertiesCache");
825+
builder.Output.AssertTargetIsNotSkipped ("_GenerateRtxt");
826+
builder.Build (proj, parameters: new string [] { "DesignTimeBuild=true" });
827+
builder.Output.AssertTargetIsNotSkipped ("_CreatePropertiesCache");
828+
builder.Output.AssertTargetIsSkipped ("_GenerateRtxt");
799829
var intermediate = Path.Combine (Root, builder.ProjectDirectory, proj.IntermediateOutputPath);
800830
var rTxtFile = Path.Combine (intermediate, "designtime", "R.txt");
801831
Assert.IsTrue (File.Exists (rTxtFile), $"'{rTxtFile}' should exist.");
802832
rTxtFile = Path.Combine (intermediate, "R.txt");
803833
Assert.IsFalse (File.Exists (rTxtFile), $"'{rTxtFile}' should not exist.");
804834
builder.Build (proj, parameters: new string[] { "DesignTimeBuild=true" });
805-
Assert.IsFalse (builder.Output.IsTargetSkipped ("_CreatePropertiesCache"), "target \"_CreatePropertiesCache\" should have been run.");
806-
Assert.IsTrue (builder.Output.IsTargetSkipped ("_GenerateRtxt"), "target \"_GenerateRtxt\' should have been skipped.");
835+
builder.Output.AssertTargetIsNotSkipped ("_CreatePropertiesCache");
836+
builder.Output.AssertTargetIsSkipped ("_GenerateRtxt");
807837
Assert.IsTrue (builder.Clean (proj), "Clean Should have succeeded");
808838
builder.Target = "_CleanDesignTimeIntermediateDir";
809839
Assert.IsTrue (builder.Build (proj), "_CleanDesignTimeIntermediateDir should have succeeded");

0 commit comments

Comments
 (0)