Skip to content

Commit 65740e9

Browse files
Fix R8 JNI incremental validation tests
Allow blank records when validating generated reachability manifests, and resolve the final AAPT rules through their explicit configuration provenance instead of filesystem name uniqueness. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent e9eee01 commit 65740e9

3 files changed

Lines changed: 29 additions & 6 deletions

File tree

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ public R8JniLayoutView (android.content.Context context, android.util.AttributeS
401401
BeforeTargets="_CompileToDalvik">
402402
<WriteLinesToFile
403403
File="$(_AndroidR8JniSeedDirectory)final-configuration-items.txt"
404-
Lines="@(_ProguardConfiguration->'%(Filename)%(Extension)|%(AndroidSdkBaselineProguardConfiguration)|%(AndroidGeneratedProguardConfiguration)|%(AndroidAaptProguardConfiguration)|%(AndroidR8JniMappedProguardConfiguration)')"
404+
Lines="@(_ProguardConfiguration->'%(Identity)|%(AndroidSdkBaselineProguardConfiguration)|%(AndroidGeneratedProguardConfiguration)|%(AndroidAaptProguardConfiguration)|%(AndroidR8JniMappedProguardConfiguration)')"
405405
Overwrite="true"
406406
WriteOnlyWhenDifferent="true" />
407407
</Target>
@@ -422,10 +422,16 @@ public R8JniLayoutView (android.content.Context context, android.util.AttributeS
422422
var seedConfigurationItems = File.ReadAllLines (FindSingleFile (projectDirectory, "configuration-items.txt"));
423423
var seedConfigurationPaths = seedConfigurationItems.Select (item => item.Split ('|') [0]).ToArray ();
424424
var finalConfigurationItems = File.ReadAllLines (FindSingleFile (projectDirectory, "final-configuration-items.txt"));
425+
var finalAaptConfiguration = finalConfigurationItems
426+
.Select (item => item.Split ('|'))
427+
.Single (metadata => metadata.Length == 5 && metadata [2] == "true" && metadata [3] == "true");
425428
var manifestRules = FindSingleFile (projectDirectory, "manifest_rules.txt");
426-
var finalAaptRules = FindSingleFile (projectDirectory, "aapt_rules.txt", path => !path.Contains ("r8-jni-seed", StringComparison.Ordinal));
429+
var finalAaptRules = Path.IsPathRooted (finalAaptConfiguration [0])
430+
? finalAaptConfiguration [0]
431+
: Path.Combine (projectDirectory, finalAaptConfiguration [0]);
427432
var mappedProjectRules = FindSingleFile (projectDirectory, "proguard_project_references.cfg");
428433
var primaryRules = FindSingleFile (projectDirectory, "proguard_project_primary.cfg");
434+
FileAssert.Exists (finalAaptRules, "The final configured AAPT rules should exist.");
429435
AssertR8MappingRenamesClass (seedMapping, libraryJavaName);
430436
AssertR8MappingRenamesClass (finalMapping, libraryJavaName);
431437
AssertR8MappingContainsMember (finalMapping, libraryJavaName, "nctor_0");
@@ -440,16 +446,18 @@ public R8JniLayoutView (android.content.Context context, android.util.AttributeS
440446
"Seed manifest rules must not include resource custom views.");
441447
StringAssert.Contains ("-keep class com.example.R8JniLayoutView", File.ReadAllText (finalAaptRules),
442448
"Final AAPT rules should retain resource custom-view rules.");
449+
StringAssert.Contains ("#Auto Generated file", File.ReadAllText (finalAaptRules),
450+
"The final configured AAPT file should wrap the generated manifest and resource rules.");
443451
Assert.IsFalse (seedConfigurationPaths.Any (path =>
444452
new [] { "proguard-android.txt", "proguard_xamarin.cfg", "proguard_project_references.cfg", "proguard_project_primary.cfg", "generated-acw-keep.cfg" }.Contains (Path.GetFileName (path), StringComparer.Ordinal)),
445453
"Seed R8 should not receive generated or baseline configurations that pin managed peers.");
446-
Assert.That (finalConfigurationItems, Does.Contain ("proguard-android.txt|true|||"),
454+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("proguard-android.txt|true|||"),
447455
"Final R8 should identify only the SDK baseline by explicit provenance metadata.");
448-
Assert.That (finalConfigurationItems, Has.Some.EqualTo ("generated-acw-keep.cfg||true||"),
456+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("generated-acw-keep.cfg||true||"),
449457
"Generated ACW keep rules should carry semantic provenance so R8 can exclude them.");
450-
Assert.That (finalConfigurationItems, Has.Some.EqualTo ("aapt_rules.txt||true|true|"),
458+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("aapt_rules.txt||true|true|"),
451459
"Final AAPT rules should carry specific provenance so R8 retains them.");
452-
Assert.That (finalConfigurationItems, Has.Some.EqualTo ("proguard_project_references.cfg||true||true"),
460+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("proguard_project_references.cfg||true||true"),
453461
"Mapped linked-assembly rules should carry specific provenance so R8 retains them.");
454462
StringAssert.Contains ($"-keep,allowobfuscation class {libraryJavaName.Replace ('/', '.')}", File.ReadAllText (mappedProjectRules));
455463
StringAssert.Contains ("-keepclassmembers,allowobfuscation", File.ReadAllText (mappedProjectRules));

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/R8MappingTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,18 @@ void kept() -> a
431431
}));
432432
}
433433

434+
[Test]
435+
public void ReachabilityManifestIgnoresEmptyLines ()
436+
{
437+
R8Mapping seed = R8Mapping.Parse (new StringReader ("acme.orig.MyView -> a.b.C:\n"));
438+
R8Mapping final = R8Mapping.Parse (new StringReader ("acme.orig.MyView -> a.b.C:\n"));
439+
440+
CollectionAssert.IsEmpty (seed.GetReachabilityConflicts (final, new [] {
441+
"C\tacme/orig/MyView",
442+
"",
443+
}));
444+
}
445+
434446
[TestCase ("F\tacme/orig/MyView\tcount")]
435447
[TestCase ("M\tacme/orig/MyView\tonClick():void")]
436448
public void MemberOnlyManifestReportsRemovedDeclaringClass (string requiredEntry)

src/Xamarin.Android.Build.Tasks/Utilities/JniRemapping/R8Mapping.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,9 @@ public IEnumerable<string> GetReachabilityConflicts (R8Mapping finalMapping, IEn
404404
{
405405
var reportedRemovedClasses = new HashSet<string> (StringComparer.Ordinal);
406406
foreach (string requiredEntry in requiredEntries) {
407+
if (requiredEntry.Length == 0) {
408+
continue;
409+
}
407410
string [] parts = requiredEntry.Split ('\t');
408411
switch (parts.Length > 0 ? parts [0] : "") {
409412
case "C" when parts.Length == 2:

0 commit comments

Comments
 (0)