Skip to content

Commit a181fd5

Browse files
Link more assemblies (type granularity linking for real this time) (#18165)
1 parent d4ada34 commit a181fd5

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHost.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ internal class WebAssemblyHost : IWebAssemblyHost
1919

2020
public WebAssemblyHost(IServiceProvider services, IJSRuntime runtime)
2121
{
22+
// To ensure JS-invoked methods don't get linked out, have a reference to their enclosing types
23+
GC.KeepAlive(typeof(EntrypointInvoker));
24+
GC.KeepAlive(typeof(JSInteropMethods));
25+
GC.KeepAlive(typeof(WebAssemblyEventDispatcher));
26+
2227
Services = services ?? throw new ArgumentNullException(nameof(services));
2328
_runtime = runtime ?? throw new ArgumentNullException(nameof(runtime));
2429
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.IO;
5+
using System.Xml.Linq;
6+
using Microsoft.Build.Framework;
7+
using Microsoft.Build.Utilities;
8+
9+
namespace Microsoft.AspNetCore.Blazor.Build.Tasks
10+
{
11+
public class GenerateTypeGranularityLinkingConfig : Task
12+
{
13+
[Required]
14+
public ITaskItem[] Assemblies { get; set; }
15+
16+
[Required]
17+
public string OutputPath { get; set; }
18+
19+
public override bool Execute()
20+
{
21+
var linkerElement = new XElement("linker",
22+
new XComment(" THIS IS A GENERATED FILE - DO NOT EDIT MANUALLY "));
23+
24+
foreach (var assembly in Assemblies)
25+
{
26+
var assemblyElement = CreateTypeGranularityConfig(assembly);
27+
linkerElement.Add(assemblyElement);
28+
}
29+
30+
using var fileStream = File.Open(OutputPath, FileMode.Create);
31+
new XDocument(linkerElement).Save(fileStream);
32+
33+
return true;
34+
}
35+
36+
private XElement CreateTypeGranularityConfig(ITaskItem assembly)
37+
{
38+
// We match all types in the assembly, and for each one, tell the linker to preserve all
39+
// its members (preserve=all) but only if there's some reference to the type (required=false)
40+
return new XElement("assembly",
41+
new XAttribute("fullname", Path.GetFileNameWithoutExtension(assembly.ItemSpec)),
42+
new XElement("type",
43+
new XAttribute("fullname", "*"),
44+
new XAttribute("preserve", "all"),
45+
new XAttribute("required", "false")));
46+
}
47+
}
48+
}

src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.targets

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
</Target>
161161

162162
<UsingTask TaskName="BlazorILLink" AssemblyFile="$(BlazorTasksPath)" />
163+
<UsingTask TaskName="GenerateTypeGranularityLinkingConfig" AssemblyFile="$(BlazorTasksPath)" />
163164

164165
<Target
165166
Name="_LinkBlazorApplication"
@@ -171,7 +172,10 @@
171172
Outputs="$(_BlazorLinkerOutputCache)">
172173

173174
<ItemGroup>
174-
<_BlazorDependencyAssembly Include="@(_BlazorDependencyInput)" IsLinkable="$([System.String]::Copy('%(FileName)').StartsWith('System.'))" />
175+
<_BlazorDependencyAssembly Include="@(_BlazorDependencyInput)" />
176+
<_BlazorDependencyAssembly IsLinkable="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('System.'))" />
177+
<_BlazorDependencyAssembly IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.'))" />
178+
<_BlazorDependencyAssembly IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.Extensions.'))" />
175179

176180
<_BlazorAssemblyToLink Include="@(_WebAssemblyBCLAssembly)" />
177181
<_BlazorAssemblyToLink Include="@(_BlazorDependencyAssembly)" Condition="'%(_BlazorDependencyAssembly.IsLinkable)' == 'true'" />
@@ -201,6 +205,15 @@
201205
<_DotNetHostFileName Condition=" '$(OS)' == 'Windows_NT' ">dotnet.exe</_DotNetHostFileName>
202206
</PropertyGroup>
203207

208+
<PropertyGroup>
209+
<_TypeGranularityLinkingConfig>$(BlazorIntermediateOutputPath)linker.typegranularityconfig.xml</_TypeGranularityLinkingConfig>
210+
</PropertyGroup>
211+
<GenerateTypeGranularityLinkingConfig Assemblies="@(_BlazorAssemblyToLink->WithMetadataValue('TypeGranularity', 'true'))" OutputPath="$(_TypeGranularityLinkingConfig)" />
212+
<ItemGroup>
213+
<BlazorLinkerDescriptor Include="$(_TypeGranularityLinkingConfig)" />
214+
<FileWrites Include="$(_TypeGranularityLinkingConfig)" />
215+
</ItemGroup>
216+
204217
<BlazorILLink
205218
ILLinkPath="$(MonoLinkerPath)"
206219
AssemblyPaths="@(_BlazorAssemblyToLink)"

0 commit comments

Comments
 (0)