Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Xamarin.Android.Build.Tasks] Bump ZipFlushFilesLimit #7957

Merged
merged 5 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 15 additions & 25 deletions src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ public class BuildApk : AndroidTask

public bool UseAssemblyStore { get; set; }

public string ZipFlushFilesLimit { get; set; }

public string ZipFlushSizeLimit { get; set; }

[Required]
public string ProjectFullPath { get; set; }

Expand Down Expand Up @@ -136,6 +140,12 @@ void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOut
refresh = false;
}
using (var apk = new ZipArchiveEx (apkOutputPath, File.Exists (apkOutputPath) ? FileMode.Open : FileMode.Create )) {
if (int.TryParse (ZipFlushFilesLimit, out int flushFilesLimit)) {
apk.ZipFlushFilesLimit = flushFilesLimit;
}
if (int.TryParse (ZipFlushSizeLimit, out int flushSizeLimit)) {
apk.ZipFlushSizeLimit = flushSizeLimit;
}
if (refresh) {
for (long i = 0; i < apk.Archive.EntryCount; i++) {
ZipEntry e = apk.Archive.ReadEntry ((ulong) i);
Expand Down Expand Up @@ -206,7 +216,6 @@ void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOut
AddFileToArchiveIfNewer (apk, RuntimeConfigBinFilePath, $"{AssembliesPath}rc.bin", compressionMethod: UncompressedMethod);
}

int count = 0;
foreach (var file in files) {
var item = Path.Combine (file.archivePath.Replace (Path.DirectorySeparatorChar, '/'));
existingEntries.Remove (item);
Expand All @@ -216,12 +225,7 @@ void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOut
continue;
}
Log.LogDebugMessage ("\tAdding {0}", file.filePath);
apk.Archive.AddFile (file.filePath, item, compressionMethod: compressionMethod);
count++;
if (count >= ZipArchiveEx.ZipFlushFilesLimit) {
apk.Flush();
count = 0;
}
apk.AddFileAndFlush (file.filePath, item, compressionMethod: compressionMethod);
}

var jarFiles = (JavaSourceFiles != null) ? JavaSourceFiles.Where (f => f.ItemSpec.EndsWith (".jar", StringComparison.OrdinalIgnoreCase)) : null;
Expand All @@ -236,7 +240,6 @@ void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOut
var jarFilePaths = libraryProjectJars.Concat (jarFiles != null ? jarFiles.Select (j => j.ItemSpec) : Enumerable.Empty<string> ());
jarFilePaths = MonoAndroidHelper.DistinctFilesByContent (jarFilePaths);

count = 0;
foreach (var jarFile in jarFilePaths) {
using (var stream = File.OpenRead (jarFile))
using (var jar = ZipArchive.Open (stream)) {
Expand Down Expand Up @@ -278,14 +281,9 @@ void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOut
data = d.ToArray ();
}
Log.LogDebugMessage ($"Adding {path} from {jarFile} as the archive file is out of date.");
apk.Archive.AddEntry (data, path);
apk.AddEntryAndFlush (data, path);
}
}
count++;
if (count >= ZipArchiveEx.ZipFlushFilesLimit) {
apk.Flush();
count = 0;
}
}
// Clean up Removed files.
foreach (var entry in existingEntries) {
Expand Down Expand Up @@ -377,7 +375,6 @@ void AddAssemblies (ZipArchiveEx apk, bool debug, bool compress, IDictionary<str
storeGenerator = null;
}

int count = 0;
AssemblyStoreAssemblyInfo storeAssembly = null;

//
Expand All @@ -398,7 +395,6 @@ void AddAssemblies (ZipArchiveEx apk, bool debug, bool compress, IDictionary<str
AddAssembliesFromCollection (ResolvedUserAssemblies);

// Add framework assemblies
count = 0;
AddAssembliesFromCollection (ResolvedFrameworkAssemblies);

if (!UseAssemblyStore) {
Expand Down Expand Up @@ -482,12 +478,6 @@ void AddAssembliesFromCollection (ITaskItem[] assemblies)

if (UseAssemblyStore) {
storeGenerator.Add (assemblyStoreApkName, storeAssembly);
} else {
count++;
if (count >= ZipArchiveEx.ZipFlushFilesLimit) {
apk.Flush();
count = 0;
}
}
}
}
Expand Down Expand Up @@ -554,7 +544,7 @@ bool AddFileToArchiveIfNewer (ZipArchiveEx apk, string file, string inArchivePat
return false;
}
Log.LogDebugMessage ($"Adding {file} as the archive file is out of date.");
apk.Archive.AddFile (file, inArchivePath, compressionMethod: compressionMethod);
apk.AddFileAndFlush (file, inArchivePath, compressionMethod: compressionMethod);
return true;
}

Expand All @@ -578,7 +568,7 @@ void AddAssemblyConfigEntry (ZipArchiveEx apk, string assemblyPath, string confi
source.CopyTo (dest);
dest.WriteByte (0);
dest.Position = 0;
apk.Archive.AddEntry (inArchivePath, dest, compressionMethod);
apk.AddEntryAndFlush (inArchivePath, dest, compressionMethod);
}
}

Expand Down Expand Up @@ -625,7 +615,7 @@ void AddNativeLibraryToArchive (ZipArchiveEx apk, string abi, string filesystemP
return;
}
Log.LogDebugMessage ($"Adding native library: {filesystemPath} (APK path: {archivePath})");
apk.Archive.AddEntry (archivePath, File.OpenRead (filesystemPath), compressionMethod);
apk.AddEntryAndFlush (archivePath, File.OpenRead (filesystemPath), compressionMethod);
}

void AddRuntimeLibraries (ZipArchiveEx apk, string [] supportedAbis)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,46 @@ public void CheckExcludedFilesAreMissing ()
}
}

[Test]
[TestCase (1, -1)]
[TestCase (5, -1)]
[TestCase (50, -1)]
[TestCase (100, -1)]
[TestCase (512, -1)]
[TestCase (1024, -1)]
[TestCase (-1, 1)]
[TestCase (-1, 5)]
[TestCase (-1, 10)]
[TestCase (-1, 100)]
[TestCase (-1, 200)]
public void BuildApkWithZipFlushLimits (int filesLimit, int sizeLimit)
{
var proj = new XamarinAndroidApplicationProject {
IsRelease = false,
PackageReferences = {
KnownPackages.SupportDesign_27_0_2_1,
KnownPackages.SupportV7CardView_27_0_2_1,
KnownPackages.AndroidSupportV4_27_0_2_1,
KnownPackages.SupportCoreUtils_27_0_2_1,
KnownPackages.SupportMediaCompat_27_0_2_1,
KnownPackages.SupportFragment_27_0_2_1,
KnownPackages.SupportCoreUI_27_0_2_1,
KnownPackages.SupportCompat_27_0_2_1,
KnownPackages.SupportV7AppCompat_27_0_2_1,
KnownPackages.SupportV7MediaRouter_27_0_2_1,
},
};
proj.SetProperty ("EmbedAssembliesIntoApk", "true");
if (filesLimit > 0)
proj.SetProperty ("_ZipFlushFilesLimit", filesLimit.ToString ());
if (sizeLimit > 0)
proj.SetProperty ("_ZipFlushSizeLimit", (sizeLimit * 1024 * 1024).ToString ());
using (var b = CreateApkBuilder ()) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");

}
}

[Test]
public void ExtractNativeLibsTrue ()
{
Expand Down
33 changes: 30 additions & 3 deletions src/Xamarin.Android.Build.Tasks/Utilities/ZipArchiveEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ namespace Xamarin.Android.Tasks
public class ZipArchiveEx : IDisposable
{

public static int ZipFlushSizeLimit = 50 * 1024 * 1024;
public static int ZipFlushFilesLimit = 50;
const int DEFAULT_FLUSH_SIZE_LIMIT = 100 * 1024 * 1024;
const int DEFAULT_FLUSH_FILES_LIMIT = 512;

ZipArchive zip;
string archive;
Expand All @@ -24,6 +24,9 @@ public ZipArchive Archive {

public bool CreateDirectoriesInZip { get; set; } = true;

public int ZipFlushSizeLimit { get; set; } = DEFAULT_FLUSH_SIZE_LIMIT;
public int ZipFlushFilesLimit { get; set; } = DEFAULT_FLUSH_FILES_LIMIT;

public ZipArchiveEx (string archive) : this (archive, FileMode.CreateNew)
{
}
Expand Down Expand Up @@ -65,7 +68,31 @@ void AddFileAndFlush (string filename, long fileLength, string archiveFileName,
{
filesWrittenTotalSize += fileLength;
zip.AddFile (filename, archiveFileName, compressionMethod: compressionMethod);
if ((filesWrittenTotalSize >= ZipArchiveEx.ZipFlushSizeLimit || filesWrittenTotalCount >= ZipArchiveEx.ZipFlushFilesLimit) && AutoFlush) {
if ((filesWrittenTotalSize >= ZipFlushSizeLimit || filesWrittenTotalCount >= ZipFlushFilesLimit) && AutoFlush) {
Flush ();
}
}

public void AddFileAndFlush (string filename, string archiveFileName, CompressionMethod compressionMethod)
{
var fi = new FileInfo (filename);
AddFileAndFlush (filename, fi.Length, archiveFileName, compressionMethod);
}

public void AddEntryAndFlush (byte[] data, string archiveFileName)
{
filesWrittenTotalSize += data.Length;
zip.AddEntry (data, archiveFileName);
if ((filesWrittenTotalSize >= ZipFlushSizeLimit || filesWrittenTotalCount >= ZipFlushFilesLimit) && AutoFlush) {
Flush ();
}
}

public void AddEntryAndFlush (string archiveFileName, Stream data, CompressionMethod method)
{
filesWrittenTotalSize += data.Length;
zip.AddEntry (archiveFileName, data, method);
if ((filesWrittenTotalSize >= ZipFlushSizeLimit || filesWrittenTotalCount >= ZipFlushFilesLimit) && AutoFlush) {
Flush ();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2152,6 +2152,8 @@ because xbuild doesn't support framework reference assemblies.
CheckedBuild="$(_AndroidCheckedBuild)"
RuntimeConfigBinFilePath="$(_BinaryRuntimeConfigPath)"
ExcludeFiles="@(AndroidPackagingOptionsExclude)"
ZipFlushFilesLimit="$(_ZipFlushFilesLimit)"
ZipFlushSizeLimit="$(_ZipFlushSizeLimit)"
UseAssemblyStore="$(AndroidUseAssemblyStore)">
<Output TaskParameter="OutputFiles" ItemName="ApkFiles" />
</BuildApk>
Expand Down Expand Up @@ -2185,6 +2187,8 @@ because xbuild doesn't support framework reference assemblies.
CheckedBuild="$(_AndroidCheckedBuild)"
RuntimeConfigBinFilePath="$(_BinaryRuntimeConfigPath)"
ExcludeFiles="@(AndroidPackagingOptionsExclude)"
ZipFlushFilesLimit="$(_ZipFlushFilesLimit)"
ZipFlushSizeLimit="$(_ZipFlushSizeLimit)"
UseAssemblyStore="$(AndroidUseAssemblyStore)">
<Output TaskParameter="OutputFiles" ItemName="BaseZipFile" />
</BuildBaseAppBundle>
Expand Down