Skip to content

Commit 6b2b074

Browse files
committed
Move all of assembly store building code to a separate class
This makes it possible to build assembly stores easily outside `BuildApk`
1 parent c127769 commit 6b2b074

File tree

2 files changed

+87
-69
lines changed

2 files changed

+87
-69
lines changed

src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs

Lines changed: 42 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -425,16 +425,12 @@ void AddAssemblies (ZipArchiveEx apk, bool debug, bool compress, IDictionary<And
425425
string sourcePath;
426426
AssemblyCompression.AssemblyData compressedAssembly = null;
427427
string compressedOutputDir = Path.GetFullPath (Path.Combine (Path.GetDirectoryName (ApkOutputPath), "..", "lz4"));
428-
AssemblyStoreGenerator? storeGenerator;
428+
AssemblyStoreBuilder? storeBuilder = null;
429429

430430
if (UseAssemblyStore) {
431-
storeGenerator = new AssemblyStoreGenerator (Log);
432-
} else {
433-
storeGenerator = null;
431+
storeBuilder = new AssemblyStoreBuilder (Log);
434432
}
435433

436-
AssemblyStoreAssemblyInfo? storeAssemblyInfo = null;
437-
438434
// Add user assemblies
439435
AddAssembliesFromCollection (ResolvedUserAssemblies);
440436

@@ -445,7 +441,7 @@ void AddAssemblies (ZipArchiveEx apk, bool debug, bool compress, IDictionary<And
445441
return;
446442
}
447443

448-
Dictionary<AndroidTargetArch, string> assemblyStorePaths = storeGenerator.Generate (AppSharedLibrariesDir);
444+
Dictionary<AndroidTargetArch, string> assemblyStorePaths = storeBuilder.Generate (AppSharedLibrariesDir);
449445

450446
if (assemblyStorePaths.Count == 0) {
451447
throw new InvalidOperationException ("Assembly store generator did not generate any stores");
@@ -498,53 +494,35 @@ void DoAddAssembliesFromArchCollection (AndroidTargetArch arch, Dictionary<strin
498494
}
499495

500496
sourcePath = CompressAssembly (assembly);
497+
if (UseAssemblyStore) {
498+
storeBuilder.AddAssembly (sourcePath, assembly, includeDebugSymbols: debug);
499+
continue;
500+
}
501501

502502
// Add assembly
503503
(string assemblyPath, string assemblyDirectory) = GetInArchiveAssemblyPath (assembly);
504-
if (UseAssemblyStore) {
505-
storeAssemblyInfo = new AssemblyStoreAssemblyInfo (sourcePath, assembly);
506-
} else {
507-
string wrappedSourcePath = DSOWrapperGenerator.WrapIt (arch, sourcePath, Path.GetFileName (assemblyPath), this);
508-
AddFileToArchiveIfNewer (apk, wrappedSourcePath, assemblyPath, compressionMethod: GetCompressionMethod (assemblyPath));
509-
}
504+
string wrappedSourcePath = DSOWrapperGenerator.WrapIt (arch, sourcePath, Path.GetFileName (assemblyPath), this);
505+
AddFileToArchiveIfNewer (apk, wrappedSourcePath, assemblyPath, compressionMethod: GetCompressionMethod (assemblyPath));
510506

511507
// Try to add config if exists
512508
var config = Path.ChangeExtension (assembly.ItemSpec, "dll.config");
513-
if (UseAssemblyStore) {
514-
if (File.Exists (config)) {
515-
storeAssemblyInfo.ConfigFile = new FileInfo (config);
516-
}
517-
} else {
518-
AddAssemblyConfigEntry (apk, arch, assemblyDirectory, config);
519-
}
509+
AddAssemblyConfigEntry (apk, arch, assemblyDirectory, config);
520510

521511
// Try to add symbols if Debug
522-
if (debug) {
523-
var symbols = Path.ChangeExtension (assembly.ItemSpec, "pdb");
524-
string? symbolsPath = null;
525-
526-
if (File.Exists (symbols)) {
527-
symbolsPath = symbols;
528-
}
529-
530-
if (!String.IsNullOrEmpty (symbolsPath)) {
531-
if (UseAssemblyStore) {
532-
storeAssemblyInfo.SymbolsFile = new FileInfo (symbolsPath);
533-
} else {
534-
string archiveSymbolsPath = assemblyDirectory + MonoAndroidHelper.MakeDiscreteAssembliesEntryName (Path.GetFileName (symbols));
535-
string wrappedSymbolsPath = DSOWrapperGenerator.WrapIt (arch, symbolsPath, Path.GetFileName (archiveSymbolsPath), this);
536-
AddFileToArchiveIfNewer (
537-
apk,
538-
wrappedSymbolsPath,
539-
archiveSymbolsPath,
540-
compressionMethod: GetCompressionMethod (archiveSymbolsPath)
541-
);
542-
}
543-
}
512+
if (!debug) {
513+
continue;
544514
}
545515

546-
if (UseAssemblyStore) {
547-
storeGenerator.Add (storeAssemblyInfo);
516+
string symbols = Path.ChangeExtension (assembly.ItemSpec, "pdb");
517+
if (!File.Exists (symbols)) {
518+
string archiveSymbolsPath = assemblyDirectory + MonoAndroidHelper.MakeDiscreteAssembliesEntryName (Path.GetFileName (symbols));
519+
string wrappedSymbolsPath = DSOWrapperGenerator.WrapIt (arch, symbols, Path.GetFileName (archiveSymbolsPath), this);
520+
AddFileToArchiveIfNewer (
521+
apk,
522+
wrappedSymbolsPath,
523+
archiveSymbolsPath,
524+
compressionMethod: GetCompressionMethod (archiveSymbolsPath)
525+
);
548526
}
549527
}
550528
}
@@ -655,33 +633,28 @@ void AddAssemblyConfigEntry (ZipArchiveEx apk, AndroidTargetArch arch, string as
655633
}
656634

657635
string assemblyName = Path.GetFileName (assembly.ItemSpec);
658-
if (UseAssemblyStore) {
636+
// For discrete assembly entries we need to treat assemblies specially.
637+
// All of the assemblies have their names mangled so that the possibility to clash with "real" shared
638+
// library names is minimized. All of the assembly entries will start with a special character:
639+
//
640+
// `_` - for regular assemblies (e.g. `_Mono.Android.dll.so`)
641+
// `-` - for satellite assemblies (e.g. `-es-Mono.Android.dll.so`)
642+
//
643+
// Second of all, we need to treat satellite assemblies with even more care.
644+
// If we encounter one of them, we will return the culture as part of the path transformed
645+
// so that it forms a `-culture-` assembly file name prefix, not a `culture/` subdirectory.
646+
// This is necessary because Android doesn't allow subdirectories in `lib/{ABI}/`
647+
//
648+
string[] subdirParts = subDirectory.TrimEnd ('/').Split ('/');
649+
if (subdirParts.Length == 1) {
650+
// Not a satellite assembly
659651
parts.Add (subDirectory);
660-
parts.Add (assemblyName);
652+
parts.Add (MonoAndroidHelper.MakeDiscreteAssembliesEntryName (assemblyName));
653+
} else if (subdirParts.Length == 2) {
654+
parts.Add (subdirParts[0]);
655+
parts.Add (MonoAndroidHelper.MakeDiscreteAssembliesEntryName (assemblyName, subdirParts[1]));
661656
} else {
662-
// For discrete assembly entries we need to treat assemblies specially.
663-
// All of the assemblies have their names mangled so that the possibility to clash with "real" shared
664-
// library names is minimized. All of the assembly entries will start with a special character:
665-
//
666-
// `_` - for regular assemblies (e.g. `_Mono.Android.dll.so`)
667-
// `-` - for satellite assemblies (e.g. `-es-Mono.Android.dll.so`)
668-
//
669-
// Second of all, we need to treat satellite assemblies with even more care.
670-
// If we encounter one of them, we will return the culture as part of the path transformed
671-
// so that it forms a `-culture-` assembly file name prefix, not a `culture/` subdirectory.
672-
// This is necessary because Android doesn't allow subdirectories in `lib/{ABI}/`
673-
//
674-
string[] subdirParts = subDirectory.TrimEnd ('/').Split ('/');
675-
if (subdirParts.Length == 1) {
676-
// Not a satellite assembly
677-
parts.Add (subDirectory);
678-
parts.Add (MonoAndroidHelper.MakeDiscreteAssembliesEntryName (assemblyName));
679-
} else if (subdirParts.Length == 2) {
680-
parts.Add (subdirParts[0]);
681-
parts.Add (MonoAndroidHelper.MakeDiscreteAssembliesEntryName (assemblyName, subdirParts[1]));
682-
} else {
683-
throw new InvalidOperationException ($"Internal error: '{assembly}' `DestinationSubDirectory` metadata has too many components ({parts.Count} instead of 1 or 2)");
684-
}
657+
throw new InvalidOperationException ($"Internal error: '{assembly}' `DestinationSubDirectory` metadata has too many components ({parts.Count} instead of 1 or 2)");
685658
}
686659

687660
string assemblyFilePath = MonoAndroidHelper.MakeZipArchivePath (ArchiveAssembliesPath, parts);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
5+
using Microsoft.Android.Build.Tasks;
6+
using Microsoft.Build.Utilities;
7+
using Microsoft.Build.Framework;
8+
using Xamarin.Android.Tools;
9+
10+
namespace Xamarin.Android.Tasks;
11+
12+
class AssemblyStoreBuilder
13+
{
14+
readonly TaskLoggingHelper log;
15+
readonly AssemblyStoreGenerator storeGenerator;
16+
17+
public AssemblyStoreBuilder (TaskLoggingHelper log)
18+
{
19+
this.log = log;
20+
storeGenerator = new (log);
21+
}
22+
23+
public void AddAssembly (string assemblySourcePath, ITaskItem assemblyItem, bool includeDebugSymbols)
24+
{
25+
var storeAssemblyInfo = new AssemblyStoreAssemblyInfo (assemblySourcePath, assemblyItem);
26+
27+
// Try to add config if exists. We use assemblyItem, because `sourcePath` might refer to a compressed
28+
// assembly file in a different location.
29+
var config = Path.ChangeExtension (assemblyItem.ItemSpec, "dll.config");
30+
if (File.Exists (config)) {
31+
storeAssemblyInfo.ConfigFile = new FileInfo (config);
32+
}
33+
34+
if (includeDebugSymbols) {
35+
string debugSymbolsPath = Path.ChangeExtension (assemblyItem.ItemSpec, "pdb");
36+
if (File.Exists (debugSymbolsPath)) {
37+
storeAssemblyInfo.SymbolsFile = new FileInfo (debugSymbolsPath);
38+
}
39+
}
40+
41+
storeGenerator.Add (storeAssemblyInfo);
42+
}
43+
44+
public Dictionary<AndroidTargetArch, string> Generate (string outputDirectoryPath) => storeGenerator.Generate (outputDirectoryPath);
45+
}

0 commit comments

Comments
 (0)