[mtouch] Bundle duplicated assemblies in the container app. Fixes #58873. (#3626)

Assemblies that satisfy all of these conditions:

* Are not in the container project.
* Are in multiple app extensions.

can (and should) be bundled in the container app.

Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=58873
This commit is contained in:
Rolf Bjarne Kvinge 2018-03-02 09:39:42 +01:00 коммит произвёл GitHub
Родитель aa9243f528
Коммит a106cd7520
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 53 добавлений и 1 удалений

Просмотреть файл

@ -3033,6 +3033,43 @@ class Test {
}
}
[Test]
public void ExtensionsWithSharedLibrary ()
{
using (var tool = new MTouchTool ()) {
tool.CreateTemporaryApp ();
tool.CreateTemporaryCacheDirectory ();
tool.Linker = MTouchLinker.LinkSdk;
var tmpdir = tool.CreateTemporaryDirectory ();
var dll = CompileTestAppLibrary (tmpdir, "public class L {}", appName: "commonTestLibrary");
using (var ext1 = new MTouchTool ()) {
ext1.References = new string [] { dll };
ext1.CreateTemporaryCacheDirectory ();
ext1.CreateTemporaryTodayExtension (extraCode: "class E1 : L {}", extraArg: $"-r:{StringUtils.Quote (dll)}");
ext1.Linker = MTouchLinker.LinkSdk;
tool.AppExtensions.Add (ext1);
using (var ext2 = new MTouchTool ()) {
ext2.References = new string [] { dll };
ext2.CreateTemporaryCacheDirectory ();
ext2.CreateTemporaryServiceExtension (extraCode: "class E1 : L {}", extraArg: $"-r:{StringUtils.Quote (dll)}");
ext2.Linker = MTouchLinker.LinkSdk;
tool.AppExtensions.Add (ext2);
ext2.AssertExecute (MTouchAction.BuildDev, "ext 2 build");
ext1.AssertExecute (MTouchAction.BuildDev, "ext 1 build");
tool.AssertExecute (MTouchAction.BuildDev, "main build");
Assert.That (Path.Combine (ext1.AppPath, Path.GetFileName (dll)), Does.Not.Exist, "ext1 existence");
Assert.That (Path.Combine (ext2.AppPath, Path.GetFileName (dll)), Does.Not.Exist, "ext2 existence");
Assert.That (Path.Combine (tool.AppPath, Path.GetFileName (dll)), Does.Exist, "existence");
}
}
}
}
[Test]
public void LinkWithNoLibrary ()
{

Просмотреть файл

@ -2109,7 +2109,7 @@ namespace Xamarin.Bundler {
var size_specific = assemblies.Length > 1 && !Cache.CompareAssemblies (assemblies [0].FullPath, assemblies [1].FullPath, true, true);
if (IsExtension && !IsWatchExtension) {
var codeShared = assemblies.Count ((v) => v.IsCodeShared);
var codeShared = assemblies.Count ((v) => v.IsCodeShared || v.BundleInContainerApp);
if (codeShared > 0) {
if (codeShared != assemblies.Length)
throw ErrorHelper.CreateError (99, $"Internal error: all assemblies in a joined build target must have the same code sharing options ({string.Join (", ", assemblies.Select ((v) => v.Identity + "=" + v.IsCodeShared))}). Please file a bug report with a test case (http://bugzilla.xamarin.com).");

Просмотреть файл

@ -33,6 +33,7 @@ namespace Xamarin.Bundler {
public AssemblyBuildTarget BuildTarget;
public string BuildTargetName;
public bool IsCodeShared;
public bool BundleInContainerApp;
public Dictionary<Abi, AotInfo> AotInfos = new Dictionary<Abi, AotInfo> ();

Просмотреть файл

@ -696,6 +696,20 @@ namespace Xamarin.Bundler
t.Resolver.Add (asm.AssemblyDefinition);
}
// Find assemblies that are in more than 1 appex, but not in the container app.
// These assemblies will be bundled once into the container .app instead of in each appex.
var grouped = sharingTargets.SelectMany ((v) => v.Assemblies).
GroupBy ((v) => Assembly.GetIdentity (v.AssemblyDefinition)).
Where ((v) => !Assemblies.ContainsKey (v.Key)).
Where ((v) => v.Count () > 1);
foreach (var gr in grouped) {
var asm = gr.First ();
Assemblies.Add (asm);
Resolver.Add (asm.AssemblyDefinition);
gr.All ((v) => v.BundleInContainerApp = true);
}
// If any of the appex'es build to a grouped SDK framework, then we must ensure that all SDK assemblies
// in that appex are also in the container app.
foreach (var st in sharingTargets) {