[dotnet] Implement resource bundling. (#9472)

* Port the BundledResources test to .NET.
* Fix a minor issue in the BundledResources test to make sure it works on macOS.
* Add a unit test to make sure resources are bundled as expected.
* Modify the .NET build logic to bundle/unbundle resources.
This commit is contained in:
Rolf Bjarne Kvinge 2020-08-25 13:14:01 +02:00 коммит произвёл GitHub
Родитель 18ca278e88
Коммит ab47edcb27
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 134 добавлений и 3 удалений

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

@ -90,6 +90,9 @@
<!-- Inject our custom logic into *DependsOn variables -->
<PropertyGroup>
<BuildDependsOn>
_CollectBundleResources;
_PackLibraryResources;
_UnpackLibraryResources;
$(BuildDependsOn);
_CreateAppBundle;
Codesign;
@ -98,7 +101,6 @@
<!-- We re-use ComputeFilesToPublish & CopyFilesToPublishDirectory to copy files to the .app -->
<!-- ComputeFilesToPublish will run ILLink -->
<CreateAppBundleDependsOn>
_CollectBundleResources;
_DetectAppManifest;
_CopyResourcesToBundle;
_CompileAppManifest;

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

@ -32,7 +32,12 @@ namespace BundledResources {
// resources are removed by the linker or an extra step (e.g. "link sdk" or "don't link") but that
// extra step is done only on device (to keep the simulator builds as fast as possible)
var resources = typeof(ResourcesTest).Assembly.GetManifestResourceNames ();
if (Runtime.Arch == Arch.DEVICE) {
#if __MACOS__
var hasResources = false;
#else
var hasResources = Runtime.Arch != Arch.DEVICE;
#endif
if (!hasResources) {
Assert.That (resources.Length, Is.EqualTo (0), "No resources");
} else {
Assert.That (resources.Length, Is.GreaterThanOrEqualTo (2), "Resources");
@ -41,4 +46,4 @@ namespace BundledResources {
}
}
}
}
}

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

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.iOS.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnitLite" Version="3.12.0" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="..\..\..\monotouch-test\basn3p08.png">
<Link>basn3p08.png</Link>
</BundleResource>
<BundleResource Include="..\..\..\monotouch-test\xamvideotest.mp4">
<Link>xamvideotest.mp4</Link>
</BundleResource>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\ResourcesTest.cs" />
</ItemGroup>
</Project>

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

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.macOS.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnitLite" Version="3.12.0" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="..\..\..\monotouch-test\basn3p08.png">
<Link>basn3p08.png</Link>
</BundleResource>
<BundleResource Include="..\..\..\monotouch-test\xamvideotest.mp4">
<Link>xamvideotest.mp4</Link>
</BundleResource>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\ResourcesTest.cs" />
</ItemGroup>
</Project>

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

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.tvOS.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnitLite" Version="3.12.0" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="..\..\..\monotouch-test\basn3p08.png">
<Link>basn3p08.png</Link>
</BundleResource>
<BundleResource Include="..\..\..\monotouch-test\xamvideotest.mp4">
<Link>xamvideotest.mp4</Link>
</BundleResource>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\ResourcesTest.cs" />
</ItemGroup>
</Project>

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

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.watchOS.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnitLite" Version="3.12.0" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="..\..\..\monotouch-test\basn3p08.png">
<Link>basn3p08.png</Link>
</BundleResource>
<BundleResource Include="..\..\..\monotouch-test\xamvideotest.mp4">
<Link>xamvideotest.mp4</Link>
</BundleResource>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\ResourcesTest.cs" />
</ItemGroup>
</Project>

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

@ -211,6 +211,38 @@ namespace Xamarin.Tests {
Assert.That (ad.MainModule.Resources [0].Name, Is.EqualTo ("libtest2.a"), "libtest2.a");
}
[TestCase ("iOS", "monotouch")]
[TestCase ("tvOS", "monotouch")]
[TestCase ("watchOS", "monotouch")]
[TestCase ("macOS", "xammac")]
public void BuildBundledResources (string platform, string prefix)
{
var assemblyName = "BundledResources";
var dotnet_bindings_dir = Path.Combine (Configuration.SourceRoot, "tests", assemblyName, "dotnet");
var project_dir = Path.Combine (dotnet_bindings_dir, platform);
var project_path = Path.Combine (project_dir, $"{assemblyName}.csproj");
Clean (project_path);
CopyDotNetSupportingFiles (dotnet_bindings_dir);
var result = DotNet.AssertBuild (project_path, verbosity);
var lines = result.StandardOutput.ToString ().Split ('\n');
// Find the resulting binding assembly from the build log
var assemblies = FilterToAssembly (lines, assemblyName);
Assert.That (assemblies, Is.Not.Empty, "Assemblies");
// Make sure there's no other assembly confusing our logic
Assert.That (assemblies.Distinct ().Count (), Is.EqualTo (1), "Unique assemblies");
var asm = assemblies.First ();
Assert.That (asm, Does.Exist, "Assembly existence");
// Verify that there's one resource in the binding assembly, and its name
var ad = AssemblyDefinition.ReadAssembly (asm, new ReaderParameters { ReadingMode = ReadingMode.Deferred });
Assert.That (ad.MainModule.Resources.Count, Is.EqualTo (2), "2 resources");
// Sort the resources before we assert, since we don't care about the order, and sorted order makes the asserts simpler.
var resources = ad.MainModule.Resources.OrderBy (v => v.Name).ToArray ();
Assert.That (resources [0].Name, Is.EqualTo ($"__{prefix}_content_basn3p08.png"), $"__{prefix}_content_basn3p08.png");
Assert.That (resources [1].Name, Is.EqualTo ($"__{prefix}_content_xamvideotest.mp4"), $"__{prefix}_content_xamvideotest.mp4");
}
[TestCase ("iOS")]
[TestCase ("tvOS")]
// [TestCase ("watchOS")] // No watchOS Touch.Client project for .NET yet