-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Handle satellite assemblies in the Blazor build targets #18207
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,14 +74,16 @@ | |
</ItemGroup> | ||
</Target> | ||
|
||
<Target Name="_ResolveBlazorInputs"> | ||
<Target Name="_ResolveBlazorInputs" DependsOnTargets="ResolveReferences;ResolveRuntimePackAssets"> | ||
<PropertyGroup> | ||
<!-- /obj/<<configuration>>/<<targetframework>>/blazor --> | ||
<BlazorIntermediateOutputPath>$(IntermediateOutputPath)blazor\</BlazorIntermediateOutputPath> | ||
|
||
<!-- /obj/<<configuration>>/<<targetframework>>/blazor/linker.descriptor.xml --> | ||
<GeneratedBlazorLinkerDescriptor>$(BlazorIntermediateOutputPath)linker.descriptor.xml</GeneratedBlazorLinkerDescriptor> | ||
|
||
<_TypeGranularityLinkerDescriptor>$(BlazorIntermediateOutputPath)linker.typegranularityconfig.xml</_TypeGranularityLinkerDescriptor> | ||
|
||
<!-- /obj/<<configuration>>/<<targetframework>>/blazor/linker/ --> | ||
<BlazorIntermediateLinkerOutputPath>$(BlazorIntermediateOutputPath)linker/</BlazorIntermediateLinkerOutputPath> | ||
|
||
|
@@ -94,8 +96,6 @@ | |
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<_BlazorDependencyInput Include="@(ReferenceCopyLocalPaths->WithMetadataValue('Extension','.dll')->'%(FullPath)')" /> | ||
|
||
<_WebAssemblyBCLFolder Include=" | ||
$(DotNetWebAssemblyBCLPath); | ||
$(DotNetWebAssemblyBCLFacadesPath); | ||
|
@@ -104,13 +104,50 @@ | |
<_WebAssemblyBCLAssembly Include="%(_WebAssemblyBCLFolder.Identity)*.dll" /> | ||
</ItemGroup> | ||
|
||
<!-- | ||
Calculate the assemblies that act as inputs to calculate assembly closure. Based on _ComputeAssembliesToPostprocessOnPublish which is used as input to SDK's linker | ||
https://github.com/dotnet/sdk/blob/d597e7b09d7657ba4e326d6734e14fcbf8473564/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets#L864-L873 | ||
--> | ||
<ItemGroup> | ||
<!-- Assemblies from packages --> | ||
<_BlazorManagedRuntimeAssemby Include="@(RuntimeCopyLocalItems)" /> | ||
|
||
<!-- Assemblies from other references --> | ||
<_BlazorUserRuntimeAssembly Include="@(ReferencePath->WithMetadataValue('CopyLocal', 'true'))" /> | ||
<_BlazorUserRuntimeAssembly Include="@(ReferenceDependencyPaths->WithMetadataValue('CopyLocal', 'true'))" /> | ||
|
||
<_BlazorManagedRuntimeAssemby Include="@(_BlazorUserRuntimeAssembly)" /> | ||
<_BlazorManagedRuntimeAssemby Include="@(IntermediateAssembly)" /> | ||
</ItemGroup> | ||
|
||
<MakeDir Directories="$(BlazorIntermediateOutputPath)" /> | ||
</Target> | ||
|
||
<Target Name="_ResolveBlazorOutputs" DependsOnTargets="_ResolveBlazorOutputsWhenLinked;_ResolveBlazorOutputsWhenNotLinked"> | ||
<Error | ||
Message="Unrecongnized value for BlazorLinkOnBuild: '$(BlazorLinkOnBuild)'. Valid values are 'true' or 'false'." | ||
Condition="'$(BlazorLinkOnBuild)' != 'true' AND '$(BlazorLinkOnBuild)' != 'false'" /> | ||
|
||
<ItemGroup> | ||
<!-- | ||
ReferenceCopyLocalPaths includes all files that are part of the build out with CopyLocalLockFileAssemblies on. | ||
Remove assemblies that are inputs to calculating the assembly closure. Instead use the resolved outputs, since it is the minimal set. | ||
--> | ||
<_BlazorCopyLocalPaths Include="@(ReferenceCopyLocalPaths)" /> | ||
<_BlazorCopyLocalPaths Remove="@(_BlazorManagedRuntimeAssemby)" /> | ||
|
||
<BlazorOutputWithTargetPath Include="@(_BlazorCopyLocalPaths)"> | ||
<BlazorRuntimeFile>true</BlazorRuntimeFile> | ||
<TargetOutputPath>$(BlazorRuntimeBinOutputPath)%(_BlazorCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension)</TargetOutputPath> | ||
<RelativeOutputPath>%(_BlazorCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension)</RelativeOutputPath> | ||
</BlazorOutputWithTargetPath> | ||
|
||
<BlazorOutputWithTargetPath Include="@(_BlazorResolvedAssembly)"> | ||
<BlazorRuntimeFile>true</BlazorRuntimeFile> | ||
<TargetOutputPath>$(BlazorRuntimeBinOutputPath)%(FileName)%(Extension)</TargetOutputPath> | ||
<RelativeOutputPath>%(FileName)%(Extension)</RelativeOutputPath> | ||
</BlazorOutputWithTargetPath> | ||
</ItemGroup> | ||
</Target> | ||
|
||
<!-- | ||
|
@@ -124,18 +161,34 @@ | |
<Target | ||
Name="_ResolveBlazorOutputsWhenLinked" | ||
Condition="'$(BlazorLinkOnBuild)' == 'true'" | ||
DependsOnTargets="_GenerateBlazorLinkerDescriptor;_LinkBlazorApplication"> | ||
DependsOnTargets="_PrepareBlazorLinkerInputs;_GenerateBlazorLinkerDescriptor;_GenerateTypeGranularLinkerDescriptor;_LinkBlazorApplication"> | ||
|
||
<!-- _BlazorLinkerOutputCache records files linked during the last incremental build of the target. Read the contents and assign linked files to be copied to the output. --> | ||
<ReadLinesFromFile File="$(_BlazorLinkerOutputCache)"> | ||
<Output TaskParameter="Lines" ItemName="_BlazorLinkedFile"/> | ||
<Output TaskParameter="Lines" ItemName="_BlazorResolvedAssembly"/> | ||
</ReadLinesFromFile> | ||
</Target> | ||
|
||
<Target Name="_PrepareBlazorLinkerInputs"> | ||
<ItemGroup> | ||
<BlazorOutputWithTargetPath Include="%(_BlazorLinkedFile.Identity)"> | ||
<TargetOutputPath>$(BlazorRuntimeBinOutputPath)%(FileName)%(Extension)</TargetOutputPath> | ||
</BlazorOutputWithTargetPath> | ||
<_BlazorRuntimeCopyLocalItems Include="@(RuntimeCopyLocalItems)" /> | ||
|
||
<!-- | ||
Any assembly from a package reference that starts with System. file name is allowed to be linked. | ||
Assemblies from Microsoft.AspNetCore and Microsoft.Extensions, are also linked but with TypeGranularity. | ||
--> | ||
<_BlazorRuntimeCopyLocalItems IsLinkable="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('System.'))" /> | ||
<_BlazorRuntimeCopyLocalItems IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.'))" /> | ||
<_BlazorRuntimeCopyLocalItems IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.Extensions.'))" /> | ||
|
||
<_BlazorAssemblyToLink Include="@(_WebAssemblyBCLAssembly)" /> | ||
<_BlazorAssemblyToLink Include="@(_BlazorRuntimeCopyLocalItems)" Condition="'%(_BlazorRuntimeCopyLocalItems.IsLinkable)' == 'true'" /> | ||
|
||
<_BlazorLinkerRoot Include="@(IntermediateAssembly)" /> | ||
<_BlazorLinkerRoot Include="@(_BlazorUserRuntimeAssembly)" /> | ||
<_BlazorLinkerRoot Include="@(_BlazorRuntimeCopyLocalItems)" Condition="'%(_BlazorRuntimeCopyLocalItems.IsLinkable)' != 'true'" /> | ||
</ItemGroup> | ||
|
||
</Target> | ||
|
||
<UsingTask TaskName="BlazorCreateRootDescriptorFile" AssemblyFile="$(BlazorTasksPath)" /> | ||
|
@@ -157,31 +210,30 @@ | |
</ItemGroup> | ||
</Target> | ||
|
||
<UsingTask TaskName="BlazorILLink" AssemblyFile="$(BlazorTasksPath)" /> | ||
<UsingTask TaskName="GenerateTypeGranularityLinkingConfig" AssemblyFile="$(BlazorTasksPath)" /> | ||
<Target Name="_GenerateTypeGranularLinkerDescriptor" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @SteveSandersonMS this is now incremental: My guess is that for |
||
Inputs="@(_BlazorAssemblyToLink->WithMetadataValue('TypeGranularity', 'true'))" | ||
Outputs="$(_TypeGranularityLinkerDescriptor)"> | ||
|
||
<GenerateTypeGranularityLinkingConfig | ||
Assemblies="@(_BlazorAssemblyToLink->WithMetadataValue('TypeGranularity', 'true'))" | ||
OutputPath="$(_TypeGranularityLinkerDescriptor)" /> | ||
|
||
<ItemGroup> | ||
<BlazorLinkerDescriptor Include="$(_TypeGranularityLinkerDescriptor)" /> | ||
<FileWrites Include="$(_TypeGranularityLinkerDescriptor)" /> | ||
</ItemGroup> | ||
</Target> | ||
|
||
<UsingTask TaskName="BlazorILLink" AssemblyFile="$(BlazorTasksPath)" /> | ||
<Target | ||
Name="_LinkBlazorApplication" | ||
Inputs="$(ProjectAssetsFile); | ||
@(IntermediateAssembly); | ||
@(_BlazorDependencyInput); | ||
@(_BlazorManagedRuntimeAssemby); | ||
@(BlazorLinkerDescriptor); | ||
$(MSBuildAllProjects)" | ||
Outputs="$(_BlazorLinkerOutputCache)"> | ||
|
||
<ItemGroup> | ||
<_BlazorDependencyAssembly Include="@(_BlazorDependencyInput)" /> | ||
<_BlazorDependencyAssembly IsLinkable="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('System.'))" /> | ||
<_BlazorDependencyAssembly IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.'))" /> | ||
<_BlazorDependencyAssembly IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.Extensions.'))" /> | ||
|
||
<_BlazorAssemblyToLink Include="@(_WebAssemblyBCLAssembly)" /> | ||
<_BlazorAssemblyToLink Include="@(_BlazorDependencyAssembly)" Condition="'%(_BlazorDependencyAssembly.IsLinkable)' == 'true'" /> | ||
|
||
<_BlazorLinkerRoot Include="@(IntermediateAssembly)" /> | ||
<_BlazorLinkerRoot Include="@(_BlazorDependencyAssembly)" Condition="'%(_BlazorDependencyAssembly.IsLinkable)' != 'true'" /> | ||
</ItemGroup> | ||
|
||
<PropertyGroup> | ||
<_BlazorLinkerAdditionalOptions>-l $(MonoLinkerI18NAssemblies) $(AdditionalMonoLinkerOptions)</_BlazorLinkerAdditionalOptions> | ||
</PropertyGroup> | ||
|
@@ -203,15 +255,6 @@ | |
<_DotNetHostFileName Condition=" '$(OS)' == 'Windows_NT' ">dotnet.exe</_DotNetHostFileName> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup> | ||
<_TypeGranularityLinkingConfig>$(BlazorIntermediateOutputPath)linker.typegranularityconfig.xml</_TypeGranularityLinkingConfig> | ||
</PropertyGroup> | ||
<GenerateTypeGranularityLinkingConfig Assemblies="@(_BlazorAssemblyToLink->WithMetadataValue('TypeGranularity', 'true'))" OutputPath="$(_TypeGranularityLinkingConfig)" /> | ||
<ItemGroup> | ||
<BlazorLinkerDescriptor Include="$(_TypeGranularityLinkingConfig)" /> | ||
<FileWrites Include="$(_TypeGranularityLinkingConfig)" /> | ||
</ItemGroup> | ||
|
||
<BlazorILLink | ||
ILLinkPath="$(MonoLinkerPath)" | ||
AssemblyPaths="@(_BlazorAssemblyToLink)" | ||
|
@@ -230,29 +273,22 @@ | |
<WriteLinesToFile File="$(_BlazorLinkerOutputCache)" Lines="@(_LinkerResult)" Overwrite="true" /> | ||
</Target> | ||
|
||
|
||
<UsingTask TaskName="ResolveBlazorRuntimeDependencies" AssemblyFile="$(BlazorTasksPath)" /> | ||
<Target | ||
Name="_ResolveBlazorOutputsWhenNotLinked" | ||
DependsOnTargets="_ResolveBlazorRuntimeDependencies" | ||
Condition="'$(BlazorLinkOnBuild)' != 'true'"> | ||
|
||
<ReadLinesFromFile File="$(_BlazorApplicationAssembliesCacheFile)" Condition="'@(_BlazorResolvedRuntimeDependencies->Count())' == '0'"> | ||
<Output TaskParameter="Lines" ItemName="_BlazorResolvedRuntimeDependencies"/> | ||
<ReadLinesFromFile File="$(_BlazorApplicationAssembliesCacheFile)" Condition="'@(_BlazorResolvedAssembly->Count())' == '0'"> | ||
<Output TaskParameter="Lines" ItemName="_BlazorResolvedAssembly"/> | ||
</ReadLinesFromFile> | ||
|
||
<ItemGroup> | ||
<BlazorOutputWithTargetPath Include="@(_BlazorResolvedRuntimeDependencies)"> | ||
<TargetOutputPath>$(BlazorRuntimeBinOutputPath)%(FileName)%(Extension)</TargetOutputPath> | ||
</BlazorOutputWithTargetPath> | ||
</ItemGroup> | ||
</Target> | ||
|
||
<Target | ||
Name="_ResolveBlazorRuntimeDependencies" | ||
Inputs="$(ProjectAssetsFile); | ||
@(IntermediateAssembly); | ||
@(_BlazorDependencyInput)" | ||
@(_BlazorManagedRuntimeAssemby)" | ||
Outputs="$(_BlazorApplicationAssembliesCacheFile)"> | ||
|
||
<!-- | ||
|
@@ -262,10 +298,10 @@ | |
--> | ||
<ResolveBlazorRuntimeDependencies | ||
EntryPoint="@(IntermediateAssembly)" | ||
ApplicationDependencies="@(_BlazorDependencyInput)" | ||
ApplicationDependencies="@(_BlazorManagedRuntimeAssemby)" | ||
WebAssemblyBCLAssemblies="@(_WebAssemblyBCLAssembly)"> | ||
|
||
<Output TaskParameter="Dependencies" ItemName="_BlazorResolvedRuntimeDependencies" /> | ||
<Output TaskParameter="Dependencies" ItemName="_BlazorResolvedAssembly" /> | ||
</ResolveBlazorRuntimeDependencies> | ||
|
||
<WriteLinesToFile File="$(_BlazorApplicationAssembliesCacheFile)" Lines="@(_BlazorResolvedRuntimeDependencies)" Overwrite="true" /> | ||
|
@@ -282,13 +318,12 @@ | |
Inputs="@(BlazorOutputWithTargetPath)" | ||
Outputs="$(BlazorBootJsonIntermediateOutputPath)"> | ||
<ItemGroup> | ||
<_AppReferences Include="@(BlazorOutputWithTargetPath->WithMetadataValue('Extension','.dll'))" /> | ||
<_AppReferences Include="@(BlazorOutputWithTargetPath->WithMetadataValue('Extension','.pdb'))" Condition="'$(BlazorEnableDebugging)' == 'true'" /> | ||
<_BlazorRuntimeFile Include="@(BlazorOutputWithTargetPath->WithMetadataValue('BlazorRuntimeFile', 'true'))" /> | ||
</ItemGroup> | ||
|
||
<GenerateBlazorBootJson | ||
AssemblyPath="@(IntermediateAssembly)" | ||
References="@(_AppReferences)" | ||
References="@(_BlazorRuntimeFile)" | ||
LinkerEnabled="$(BlazorLinkOnBuild)" | ||
OutputPath="$(BlazorBootJsonIntermediateOutputPath)" /> | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,5 +70,66 @@ public async Task Build_WithLinkOnBuildDisabled_Works() | |
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "standalone.dll"); | ||
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. | ||
} | ||
|
||
[Fact] | ||
public async Task Build_SatelliteAssembliesAreCopiedToBuildOutput() | ||
{ | ||
// Arrange | ||
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); | ||
project.AddProjectFileContent( | ||
@" | ||
<PropertyGroup> | ||
<DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> | ||
</ItemGroup>"); | ||
|
||
var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/restore"); | ||
|
||
Assert.BuildPassed(result); | ||
|
||
var buildOutputDirectory = project.BuildOutputDirectory; | ||
|
||
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "standalone.dll"); | ||
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "classlibrarywithsatelliteassemblies.dll"); | ||
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); | ||
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. | ||
|
||
var bootJsonPath = Path.Combine(buildOutputDirectory, "dist", "_framework", "blazor.boot.json"); | ||
Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); | ||
Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Satellite assemblies get listed in the boot json. I verified that they get downloaded and loaded. But localization itself didn't seem to be working. At this point, I've only made sure that having satellite assemblies doesn't cause things to fail. |
||
} | ||
|
||
[Fact] | ||
public async Task Build_WithBlazorLinkOnBuildFalse_SatelliteAssembliesAreCopiedToBuildOutput() | ||
{ | ||
// Arrange | ||
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); | ||
project.AddProjectFileContent( | ||
@" | ||
<PropertyGroup> | ||
<BlazorLinkOnBuild>false</BlazorLinkOnBuild> | ||
<DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> | ||
</ItemGroup>"); | ||
|
||
var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/restore"); | ||
|
||
Assert.BuildPassed(result); | ||
|
||
var buildOutputDirectory = project.BuildOutputDirectory; | ||
|
||
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "standalone.dll"); | ||
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "classlibrarywithsatelliteassemblies.dll"); | ||
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); | ||
Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. | ||
|
||
var bootJsonPath = Path.Combine(buildOutputDirectory, "dist", "_framework", "blazor.boot.json"); | ||
Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); | ||
Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/cc @nguerrera in case you have suggestions on a better way of doing this.