Skip to content

Commit 77b3dc4

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 134519e commit 77b3dc4

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
@@ -493,7 +493,7 @@ public R8JniLayoutView (android.content.Context context, android.util.AttributeS
493493
BeforeTargets="_CompileToDalvik">
494494
<WriteLinesToFile
495495
File="$(_AndroidR8JniSeedDirectory)final-configuration-items.txt"
496-
Lines="@(_ProguardConfiguration->'%(Filename)%(Extension)|%(AndroidSdkBaselineProguardConfiguration)|%(AndroidGeneratedProguardConfiguration)|%(AndroidAaptProguardConfiguration)|%(AndroidR8JniMappedProguardConfiguration)')"
496+
Lines="@(_ProguardConfiguration->'%(Identity)|%(AndroidSdkBaselineProguardConfiguration)|%(AndroidGeneratedProguardConfiguration)|%(AndroidAaptProguardConfiguration)|%(AndroidR8JniMappedProguardConfiguration)')"
497497
Overwrite="true"
498498
WriteOnlyWhenDifferent="true" />
499499
</Target>
@@ -514,10 +514,16 @@ public R8JniLayoutView (android.content.Context context, android.util.AttributeS
514514
var seedConfigurationItems = File.ReadAllLines (FindSingleFile (projectDirectory, "configuration-items.txt"));
515515
var seedConfigurationPaths = seedConfigurationItems.Select (item => item.Split ('|') [0]).ToArray ();
516516
var finalConfigurationItems = File.ReadAllLines (FindSingleFile (projectDirectory, "final-configuration-items.txt"));
517+
var finalAaptConfiguration = finalConfigurationItems
518+
.Select (item => item.Split ('|'))
519+
.Single (metadata => metadata.Length == 5 && metadata [2] == "true" && metadata [3] == "true");
517520
var manifestRules = FindSingleFile (projectDirectory, "manifest_rules.txt");
518-
var finalAaptRules = FindSingleFile (projectDirectory, "aapt_rules.txt", path => !path.Contains ("r8-jni-seed", StringComparison.Ordinal));
521+
var finalAaptRules = Path.IsPathRooted (finalAaptConfiguration [0])
522+
? finalAaptConfiguration [0]
523+
: Path.Combine (projectDirectory, finalAaptConfiguration [0]);
519524
var mappedProjectRules = FindSingleFile (projectDirectory, "proguard_project_references.cfg");
520525
var primaryRules = FindSingleFile (projectDirectory, "proguard_project_primary.cfg");
526+
FileAssert.Exists (finalAaptRules, "The final configured AAPT rules should exist.");
521527
AssertR8MappingRenamesClass (seedMapping, libraryJavaName);
522528
AssertR8MappingRenamesClass (finalMapping, libraryJavaName);
523529
AssertR8MappingContainsMember (finalMapping, libraryJavaName, "nctor_0");
@@ -532,16 +538,18 @@ public R8JniLayoutView (android.content.Context context, android.util.AttributeS
532538
"Seed manifest rules must not include resource custom views.");
533539
StringAssert.Contains ("-keep class com.example.R8JniLayoutView", File.ReadAllText (finalAaptRules),
534540
"Final AAPT rules should retain resource custom-view rules.");
541+
StringAssert.Contains ("#Auto Generated file", File.ReadAllText (finalAaptRules),
542+
"The final configured AAPT file should wrap the generated manifest and resource rules.");
535543
Assert.IsFalse (seedConfigurationPaths.Any (path =>
536544
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)),
537545
"Seed R8 should not receive generated or baseline configurations that pin managed peers.");
538-
Assert.That (finalConfigurationItems, Does.Contain ("proguard-android.txt|true|||"),
546+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("proguard-android.txt|true|||"),
539547
"Final R8 should identify only the SDK baseline by explicit provenance metadata.");
540-
Assert.That (finalConfigurationItems, Has.Some.EqualTo ("generated-acw-keep.cfg||true||"),
548+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("generated-acw-keep.cfg||true||"),
541549
"Generated ACW keep rules should carry semantic provenance so R8 can exclude them.");
542-
Assert.That (finalConfigurationItems, Has.Some.EqualTo ("aapt_rules.txt||true|true|"),
550+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("aapt_rules.txt||true|true|"),
543551
"Final AAPT rules should carry specific provenance so R8 retains them.");
544-
Assert.That (finalConfigurationItems, Has.Some.EqualTo ("proguard_project_references.cfg||true||true"),
552+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("proguard_project_references.cfg||true||true"),
545553
"Mapped linked-assembly rules should carry specific provenance so R8 retains them.");
546554
StringAssert.Contains ($"-keep,allowobfuscation class {libraryJavaName.Replace ('/', '.')}", File.ReadAllText (mappedProjectRules));
547555
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
@@ -421,6 +421,9 @@ public IEnumerable<string> GetReachabilityConflicts (R8Mapping finalMapping, IEn
421421
{
422422
var reportedRemovedClasses = new HashSet<string> (StringComparer.Ordinal);
423423
foreach (string requiredEntry in requiredEntries) {
424+
if (requiredEntry.Length == 0) {
425+
continue;
426+
}
424427
string [] parts = requiredEntry.Split ('\t');
425428
switch (parts.Length > 0 ? parts [0] : "") {
426429
case "C" when parts.Length == 2:

0 commit comments

Comments
 (0)