Skip to content

Commit

Permalink
Assembly stores are the only way to embed assemblies in the apk now
Browse files Browse the repository at this point in the history
  • Loading branch information
grendello committed Oct 28, 2024
1 parent 417f8ba commit 68bd71a
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 152 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,34 +137,30 @@ public void BuildAotApplicationWithSpecialCharactersInProject (string testName,
new object[] {
/* supportedAbis */ "arm64-v8a",
/* enableLLVM */ false,
/* usesAssemblyBlobs */ false,
},
new object[] {
/* supportedAbis */ "armeabi-v7a;x86",
/* enableLLVM */ true,
/* usesAssemblyBlobs */ true,
},
new object[] {
/* supportedAbis */ "armeabi-v7a;arm64-v8a;x86;x86_64",
/* enableLLVM */ false,
/* usesAssemblyBlobs */ true,
},
new object[] {
/* supportedAbis */ "armeabi-v7a;arm64-v8a;x86;x86_64",
/* enableLLVM */ true,
/* usesAssemblyBlobs */ false,
},
};

[Test]
[TestCaseSource (nameof (AotChecks))]
public void BuildAotApplicationWithNdkAndBundleAndÜmläüts (string supportedAbis, bool enableLLVM, bool usesAssemblyBlobs)
public void BuildAotApplicationWithNdkAndBundleAndÜmläüts (string supportedAbis, bool enableLLVM)
{
if (IsWindows)
Assert.Ignore ("https://github.com/dotnet/runtime/issues/88625");

var abisSanitized = supportedAbis.Replace (";", "").Replace ("-", "").Replace ("_", "");
var path = Path.Combine ("temp", string.Format ("BuildAotNdk AndÜmläüts_{0}_{1}_{2}", abisSanitized, enableLLVM, usesAssemblyBlobs));
var path = Path.Combine ("temp", string.Format ("BuildAotNdk AndÜmläüts_{0}_{1}", abisSanitized, enableLLVM));
var proj = new XamarinAndroidApplicationProject () {
IsRelease = true,
AotAssemblies = true,
Expand All @@ -174,7 +170,6 @@ public void BuildAotApplicationWithNdkAndBundleAndÜmläüts (string supportedAb
proj.SetProperty ("AndroidNdkDirectory", AndroidNdkPath);
proj.SetRuntimeIdentifiers (supportedAbis.Split (';'));
proj.SetProperty ("EnableLLVM", enableLLVM.ToString ());
proj.SetProperty ("AndroidUseAssemblyStore", usesAssemblyBlobs.ToString ());
bool checkMinLlvmPath = enableLLVM && (supportedAbis == "armeabi-v7a" || supportedAbis == "x86");
if (checkMinLlvmPath) {
// Set //uses-sdk/@android:minSdkVersion so that LLVM uses the right libc.so
Expand All @@ -195,7 +190,7 @@ public void BuildAotApplicationWithNdkAndBundleAndÜmläüts (string supportedAb
var apk = Path.Combine (Root, b.ProjectDirectory,
proj.OutputPath, $"{proj.PackageName}-Signed.apk");

var helper = new ArchiveAssemblyHelper (apk, usesAssemblyBlobs);
var helper = new ArchiveAssemblyHelper (apk);
Assert.IsTrue (helper.Exists ($"assemblies/{abi}/UnnamedProject.dll"), $"{abi}/UnnamedProject.dll should be in {proj.PackageName}-Signed.apk");
using (var zipFile = ZipHelper.OpenZip (apk)) {
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
Expand All @@ -215,21 +210,20 @@ public void BuildAotApplicationWithNdkAndBundleAndÜmläüts (string supportedAb

[Test]
[TestCaseSource (nameof (AotChecks))]
public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableLLVM, bool usesAssemblyBlobs)
public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableLLVM)
{
if (IsWindows)
Assert.Ignore ("https://github.com/dotnet/runtime/issues/88625");

var abisSanitized = supportedAbis.Replace (";", "").Replace ("-", "").Replace ("_", "");
var path = Path.Combine ("temp", string.Format ("BuildAot AndÜmläüts_{0}_{1}_{2}", abisSanitized, enableLLVM, usesAssemblyBlobs));
var path = Path.Combine ("temp", string.Format ("BuildAot AndÜmläüts_{0}_{1}", abisSanitized, enableLLVM));
var proj = new XamarinAndroidApplicationProject () {
IsRelease = true,
AotAssemblies = true,
PackageName = "com.xamarin.buildaotappandbundlewithspecialchars",
};
proj.SetRuntimeIdentifiers (supportedAbis.Split (';'));
proj.SetProperty ("EnableLLVM", enableLLVM.ToString ());
proj.SetProperty ("AndroidUseAssemblyStore", usesAssemblyBlobs.ToString ());
using (var b = CreateApkBuilder (path)) {
b.ThrowOnBuildFailure = false;
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
Expand All @@ -240,7 +234,7 @@ public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableL
var apk = Path.Combine (Root, b.ProjectDirectory,
proj.OutputPath, $"{proj.PackageName}-Signed.apk");

var helper = new ArchiveAssemblyHelper (apk, usesAssemblyBlobs);
var helper = new ArchiveAssemblyHelper (apk);
Assert.IsTrue (helper.Exists ($"assemblies/{abi}/UnnamedProject.dll"), $"{abi}/UnnamedProject.dll should be in {proj.PackageName}-Signed.apk");
using (var zipFile = ZipHelper.OpenZip (apk)) {
Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,97 +16,81 @@ public partial class BuildTest : BaseTest
/* runtimeIdentifiers */ "android-arm",
/* isRelease */ false,
/* aot */ false,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-arm",
/* isRelease */ false,
/* aot */ false,
/* usesAssemblyStore */ true,
},
new object [] {
/* runtimeIdentifiers */ "android-arm64",
/* isRelease */ false,
/* aot */ false,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-x86",
/* isRelease */ false,
/* aot */ false,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-x64",
/* isRelease */ false,
/* aot */ false,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-arm",
/* isRelease */ true,
/* aot */ false,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-arm",
/* isRelease */ true,
/* aot */ false,
/* usesAssemblyStore */ true,
},
new object [] {
/* runtimeIdentifiers */ "android-arm",
/* isRelease */ true,
/* aot */ true,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-arm",
/* isRelease */ true,
/* aot */ true,
/* usesAssemblyStore */ true,
},
new object [] {
/* runtimeIdentifiers */ "android-arm64",
/* isRelease */ true,
/* aot */ false,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-arm;android-arm64;android-x86;android-x64",
/* isRelease */ false,
/* aot */ false,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-arm;android-arm64;android-x86;android-x64",
/* isRelease */ false,
/* aot */ false,
/* usesAssemblyStore */ true,
},
new object [] {
/* runtimeIdentifiers */ "android-arm;android-arm64;android-x86",
/* isRelease */ true,
/* aot */ false,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-arm;android-arm64;android-x86;android-x64",
/* isRelease */ true,
/* aot */ false,
/* usesAssemblyStore */ false,
},
new object [] {
/* runtimeIdentifiers */ "android-arm;android-arm64;android-x86;android-x64",
/* isRelease */ true,
/* aot */ false,
/* usesAssemblyStore */ true,
},
new object [] {
/* runtimeIdentifiers */ "android-arm;android-arm64;android-x86;android-x64",
/* isRelease */ true,
/* aot */ true,
/* usesAssemblyStore */ false,
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public partial class BuildTest : BaseTest
[Category ("SmokeTests")]
[TestCaseSource (nameof (DotNetBuildSource))]
[NonParallelizable] // On MacOS, parallel /restore causes issues
public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot, bool usesAssemblyStore)
public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot)
{
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
Expand Down Expand Up @@ -63,7 +63,6 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot, bo
};
proj.MainActivity = proj.DefaultMainActivity.Replace (": Activity", ": AndroidX.AppCompat.App.AppCompatActivity")
.Replace ("//${AFTER_ONCREATE}", @"button.Text = Resource.CancelButton;");
proj.SetProperty ("AndroidUseAssemblyStore", usesAssemblyStore.ToString ());
proj.SetProperty ("RunAOTCompilation", aot.ToString ());
proj.OtherBuildItems.Add (new AndroidItem.InputJar ("javaclasses.jar") {
BinaryContent = () => ResourceData.JavaSourceJarTestJar,
Expand Down Expand Up @@ -158,7 +157,7 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease, bool aot, bo
bool expectEmbeddedAssembies = !(TestEnvironment.CommercialBuildAvailable && !isRelease);
var apkPath = Path.Combine (outputPath, $"{proj.PackageName}-Signed.apk");
FileAssert.Exists (apkPath);
var helper = new ArchiveAssemblyHelper (apkPath, usesAssemblyStore, rids);
var helper = new ArchiveAssemblyHelper (apkPath, rids);
helper.AssertContainsEntry ($"assemblies/{proj.ProjectName}.dll", shouldContainEntry: expectEmbeddedAssembies);
helper.AssertContainsEntry ($"assemblies/{proj.ProjectName}.pdb", shouldContainEntry: !TestEnvironment.CommercialBuildAvailable && !isRelease);
helper.AssertContainsEntry ($"assemblies/Mono.Android.dll", shouldContainEntry: expectEmbeddedAssembies);
Expand Down Expand Up @@ -262,7 +261,6 @@ public void CheckAssemblyCounts (bool isRelease, bool aot)

var abis = new [] { "armeabi-v7a", "x86" };
proj.SetRuntimeIdentifiers (abis);
proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidUseAssemblyStore", "True");

using (var b = CreateApkBuilder ()) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
Expand All @@ -279,7 +277,7 @@ public void CheckAssemblyCounts (bool isRelease, bool aot)
}

string apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}-Signed.apk");
var helper = new ArchiveAssemblyHelper (apk, useAssemblyStores: true);
var helper = new ArchiveAssemblyHelper (apk);

foreach (string abi in abis) {
AndroidTargetArch arch = MonoAndroidHelper.AbiToTargetArch (abi);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ public void BuildReleaseArm64 ([Values (false, true)] bool forms)
proj.AotAssemblies = false; // Release defaults to Profiled AOT for .NET 6
proj.SetAndroidSupportedAbis ("arm64-v8a");
proj.SetProperty ("LinkerDumpDependencies", "True");
proj.SetProperty ("AndroidUseAssemblyStore", "False");

var flavor = (forms ? "XForms" : "Simple") + "DotNet";
var apkDescFilename = $"BuildReleaseArm64{flavor}.apkdesc";
Expand Down Expand Up @@ -319,7 +318,7 @@ public void XA1037PropertyDeprecatedWarning (string property, string value, bool
XamarinAndroidProject proj = isBindingProject ? new XamarinAndroidBindingProject () : new XamarinAndroidApplicationProject ();
proj.IsRelease = isRelease;
proj.SetProperty (property, value);

using (ProjectBuilder b = isBindingProject ? CreateDllBuilder (Path.Combine ("temp", TestName)) : CreateApkBuilder (Path.Combine ("temp", TestName))) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
Assert.IsTrue (StringAssertEx.ContainsText (b.LastBuildOutput, $"The '{property}' MSBuild property is deprecated and will be removed"),
Expand Down Expand Up @@ -1369,7 +1368,7 @@ public Class2 ()
};

string apkPath = Path.Combine (outputPath, proj.PackageName + "-Signed.apk");
var helper = new ArchiveAssemblyHelper (apkPath, useAssemblyStores: false, proj.GetRuntimeIdentifiers ().ToArray ());
var helper = new ArchiveAssemblyHelper (apkPath, proj.GetRuntimeIdentifiers ().ToArray ());
foreach (string abi in proj.GetRuntimeIdentifiersAsAbis ()) {
foreach ((string fileName, bool existsInBin) in fileNames) {
EnsureFilesAreTheSame (intermediate, existsInBin ? outputPath : null, fileName, abi, helper, uncompressIfNecessary: fileName.EndsWith (".dll", StringComparison.Ordinal));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void CheckR8InfoMessagesToNotBreakTheBuild ()

[Test]
[NonParallelizable] // Commonly fails NuGet restore
public void CheckIncludedAssemblies ([Values (false, true)] bool usesAssemblyStores)
public void CheckIncludedAssemblies ()
{
var proj = new XamarinAndroidApplicationProject {
IsRelease = true
Expand All @@ -68,7 +68,6 @@ public void CheckIncludedAssemblies ([Values (false, true)] bool usesAssemblySto
AndroidTargetArch.Arm,
};

proj.SetProperty ("AndroidUseAssemblyStore", usesAssemblyStores.ToString ());
proj.SetRuntimeIdentifiers (supportedArches);
proj.PackageReferences.Add (new Package {
Id = "Humanizer.Core",
Expand Down Expand Up @@ -111,7 +110,7 @@ public void CheckIncludedAssemblies ([Values (false, true)] bool usesAssemblySto
Assert.IsTrue (b.Build (proj), "build should have succeeded.");
var apk = Path.Combine (Root, b.ProjectDirectory,
proj.OutputPath, $"{proj.PackageName}-Signed.apk");
var helper = new ArchiveAssemblyHelper (apk, usesAssemblyStores);
var helper = new ArchiveAssemblyHelper (apk);
List<string> existingFiles;
List<string> missingFiles;
List<string> additionalFiles;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,21 +261,20 @@ public void WarnAboutAppDomains ([Values (true, false)] bool isRelease)
}

[Test]
public void RemoveDesigner ([Values (true, false)] bool useAssemblyStore)
public void RemoveDesigner ()
{
var proj = new XamarinAndroidApplicationProject {
IsRelease = true,
};
proj.SetProperty ("AndroidEnableAssemblyCompression", "False");
proj.SetProperty ("AndroidLinkResources", "True");
proj.SetProperty ("AndroidUseAssemblyStore", useAssemblyStore.ToString ());
string assemblyName = proj.ProjectName;

using var b = CreateApkBuilder ();
Assert.IsTrue (b.Build (proj), "build should have succeeded.");
var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}-Signed.apk");
FileAssert.Exists (apk);
var helper = new ArchiveAssemblyHelper (apk, useAssemblyStore);
var helper = new ArchiveAssemblyHelper (apk);
foreach (string abi in proj.GetRuntimeIdentifiersAsAbis ()) {
Assert.IsTrue (helper.Exists ($"assemblies/{abi}/{assemblyName}.dll"), $"{assemblyName}.dll should exist in apk!");

Expand All @@ -297,7 +296,7 @@ public void RemoveDesigner ([Values (true, false)] bool useAssemblyStore)
}

[Test]
public void LinkDescription ([Values (true, false)] bool useAssemblyStore)
public void LinkDescription ()
{
string assembly_name = "System.Console";
string linker_xml = "<linker/>";
Expand All @@ -312,7 +311,6 @@ public void LinkDescription ([Values (true, false)] bool useAssemblyStore)
};
// So we can use Mono.Cecil to open assemblies directly
proj.SetProperty ("AndroidEnableAssemblyCompression", "False");
proj.SetProperty ("AndroidUseAssemblyStore", useAssemblyStore.ToString ());

using (var b = CreateApkBuilder ()) {
Assert.IsTrue (b.Build (proj), "first build should have succeeded.");
Expand All @@ -331,7 +329,7 @@ public void LinkDescription ([Values (true, false)] bool useAssemblyStore)

var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}-Signed.apk");
FileAssert.Exists (apk);
var helper = new ArchiveAssemblyHelper (apk, useAssemblyStore);
var helper = new ArchiveAssemblyHelper (apk);
foreach (string abi in proj.GetRuntimeIdentifiersAsAbis ()) {
Assert.IsTrue (helper.Exists ($"assemblies/{abi}/{assembly_name}.dll"), $"{assembly_name}.dll should exist in apk!");
}
Expand Down
Loading

0 comments on commit 68bd71a

Please sign in to comment.