Use a task to launch the linker (#17313)
* Use a task to launch the linker Fixes https://github.com/aspnet/AspNetCore/issues/17264
This commit is contained in:
parent
e470aead3e
commit
e862ce7cee
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Blazor.Build
|
||||||
|
{
|
||||||
|
// Based on https://github.com/mono/linker/blob/3b329b9481e300bcf4fb88a2eebf8cb5ef8b323b/src/ILLink.Tasks/CreateRootDescriptorFile.cs
|
||||||
|
public class BlazorCreateRootDescriptorFile : Task
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public ITaskItem[] AssemblyNames { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public ITaskItem RootDescriptorFilePath { get; set; }
|
||||||
|
|
||||||
|
public override bool Execute()
|
||||||
|
{
|
||||||
|
using var fileStream = File.Create(RootDescriptorFilePath.ItemSpec);
|
||||||
|
var assemblyNames = AssemblyNames.Select(a => a.ItemSpec);
|
||||||
|
|
||||||
|
WriteRootDescriptor(fileStream, assemblyNames);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void WriteRootDescriptor(Stream stream, IEnumerable<string> assemblyNames)
|
||||||
|
{
|
||||||
|
var roots = new XElement("linker");
|
||||||
|
foreach (var assemblyName in assemblyNames)
|
||||||
|
{
|
||||||
|
roots.Add(new XElement("assembly",
|
||||||
|
new XAttribute("fullname", assemblyName),
|
||||||
|
new XElement("type",
|
||||||
|
new XAttribute("fullname", "*"),
|
||||||
|
new XAttribute("required", "true"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
var xmlWriterSettings = new XmlWriterSettings
|
||||||
|
{
|
||||||
|
Indent = true,
|
||||||
|
OmitXmlDeclaration = true
|
||||||
|
};
|
||||||
|
|
||||||
|
using var writer = XmlWriter.Create(stream, xmlWriterSettings);
|
||||||
|
var xDocument = new XDocument(roots);
|
||||||
|
|
||||||
|
xDocument.Save(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,189 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Blazor.Build.Tasks
|
||||||
|
{
|
||||||
|
// Based on https://github.com/mono/linker/blob/3b329b9481e300bcf4fb88a2eebf8cb5ef8b323b/src/ILLink.Tasks/LinkTask.cs
|
||||||
|
public class BlazorILLink : ToolTask
|
||||||
|
{
|
||||||
|
private const string DotNetHostPathEnvironmentName = "DOTNET_HOST_PATH";
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string ILLinkPath { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public ITaskItem[] AssemblyPaths { get; set; }
|
||||||
|
|
||||||
|
public ITaskItem[] ReferenceAssemblyPaths { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public ITaskItem[] RootAssemblyNames { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public ITaskItem OutputDirectory { get; set; }
|
||||||
|
|
||||||
|
public ITaskItem[] RootDescriptorFiles { get; set; }
|
||||||
|
|
||||||
|
public bool ClearInitLocals { get; set; }
|
||||||
|
|
||||||
|
public string ClearInitLocalsAssemblies { get; set; }
|
||||||
|
|
||||||
|
public string ExtraArgs { get; set; }
|
||||||
|
|
||||||
|
public bool DumpDependencies { get; set; }
|
||||||
|
|
||||||
|
private string _dotnetPath;
|
||||||
|
|
||||||
|
private string DotNetPath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_dotnetPath))
|
||||||
|
{
|
||||||
|
return _dotnetPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dotnetPath = Environment.GetEnvironmentVariable(DotNetHostPathEnvironmentName);
|
||||||
|
if (string.IsNullOrEmpty(_dotnetPath))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"{DotNetHostPathEnvironmentName} is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _dotnetPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override MessageImportance StandardErrorLoggingImportance => MessageImportance.High;
|
||||||
|
|
||||||
|
protected override string ToolName => Path.GetFileName(DotNetPath);
|
||||||
|
|
||||||
|
protected override string GenerateFullPathToTool() => DotNetPath;
|
||||||
|
|
||||||
|
protected override string GenerateCommandLineCommands() => ILLinkPath;
|
||||||
|
|
||||||
|
private static string Quote(string path)
|
||||||
|
{
|
||||||
|
return $"\"{path.TrimEnd('\\')}\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string GenerateResponseFileCommands()
|
||||||
|
{
|
||||||
|
var args = new StringBuilder();
|
||||||
|
|
||||||
|
if (RootDescriptorFiles != null)
|
||||||
|
{
|
||||||
|
foreach (var rootFile in RootDescriptorFiles)
|
||||||
|
{
|
||||||
|
args.Append("-x ").AppendLine(Quote(rootFile.ItemSpec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var assemblyItem in RootAssemblyNames)
|
||||||
|
{
|
||||||
|
args.Append("-a ").AppendLine(Quote(assemblyItem.ItemSpec));
|
||||||
|
}
|
||||||
|
|
||||||
|
var assemblyNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
foreach (var assembly in AssemblyPaths)
|
||||||
|
{
|
||||||
|
var assemblyPath = assembly.ItemSpec;
|
||||||
|
var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);
|
||||||
|
|
||||||
|
// If there are multiple paths with the same assembly name, only use the first one.
|
||||||
|
if (!assemblyNames.Add(assemblyName))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Append("-reference ")
|
||||||
|
.AppendLine(Quote(assemblyPath));
|
||||||
|
|
||||||
|
var action = assembly.GetMetadata("action");
|
||||||
|
if ((action != null) && (action.Length > 0))
|
||||||
|
{
|
||||||
|
args.Append("-p ");
|
||||||
|
args.Append(action);
|
||||||
|
args.Append(" ").AppendLine(Quote(assemblyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReferenceAssemblyPaths != null)
|
||||||
|
{
|
||||||
|
foreach (var assembly in ReferenceAssemblyPaths)
|
||||||
|
{
|
||||||
|
var assemblyPath = assembly.ItemSpec;
|
||||||
|
var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);
|
||||||
|
|
||||||
|
// Don't process references for which we already have
|
||||||
|
// implementation assemblies.
|
||||||
|
if (assemblyNames.Contains(assemblyName))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Append("-reference ").AppendLine(Quote(assemblyPath));
|
||||||
|
|
||||||
|
// Treat reference assemblies as "skip". Ideally we
|
||||||
|
// would not even look at the IL, but only use them to
|
||||||
|
// resolve surface area.
|
||||||
|
args.Append("-p skip ").AppendLine(Quote(assemblyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OutputDirectory != null)
|
||||||
|
{
|
||||||
|
args.Append("-out ").AppendLine(Quote(OutputDirectory.ItemSpec));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ClearInitLocals)
|
||||||
|
{
|
||||||
|
args.AppendLine("--enable-opt clearinitlocals");
|
||||||
|
if ((ClearInitLocalsAssemblies != null) && (ClearInitLocalsAssemblies.Length > 0))
|
||||||
|
{
|
||||||
|
args.Append("-m ClearInitLocalsAssemblies ");
|
||||||
|
args.AppendLine(ClearInitLocalsAssemblies);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ExtraArgs != null)
|
||||||
|
{
|
||||||
|
args.AppendLine(ExtraArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DumpDependencies)
|
||||||
|
{
|
||||||
|
args.AppendLine("--dump-dependencies");
|
||||||
|
}
|
||||||
|
|
||||||
|
return args.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool HandleTaskExecutionErrors()
|
||||||
|
{
|
||||||
|
// Show a slightly better error than the standard ToolTask message that says "dotnet" failed.
|
||||||
|
Log.LogError($"ILLink failed with exited code {ExitCode}.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(singleLine) && singleLine.StartsWith("Unhandled exception.", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
// The Mono linker currently prints out an entire stack trace when the linker fails.
|
||||||
|
// We want to show something actionable in the VS Error window.
|
||||||
|
Log.LogError(singleLine);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base.LogEventsFromTextOutput(singleLine, messageImportance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -97,6 +97,13 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<_BlazorDependencyInput Include="@(ReferenceCopyLocalPaths->WithMetadataValue('Extension','.dll')->'%(FullPath)')" />
|
<_BlazorDependencyInput Include="@(ReferenceCopyLocalPaths->WithMetadataValue('Extension','.dll')->'%(FullPath)')" />
|
||||||
|
|
||||||
|
<_WebAssemblyBCLFolder Include="
|
||||||
|
$(DotNetWebAssemblyBCLPath);
|
||||||
|
$(DotNetWebAssemblyBCLFacadesPath);
|
||||||
|
$(DotNetWebAssemblyFrameworkPath)" />
|
||||||
|
|
||||||
|
<_WebAssemblyBCLAssembly Include="%(_WebAssemblyBCLFolder.Identity)*.dll" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<MakeDir Directories="$(BlazorIntermediateOutputPath)" />
|
<MakeDir Directories="$(BlazorIntermediateOutputPath)" />
|
||||||
|
|
@ -119,7 +126,7 @@
|
||||||
<Target
|
<Target
|
||||||
Name="_ResolveBlazorOutputsWhenLinked"
|
Name="_ResolveBlazorOutputsWhenLinked"
|
||||||
Condition="'$(BlazorLinkOnBuild)' == 'true'"
|
Condition="'$(BlazorLinkOnBuild)' == 'true'"
|
||||||
DependsOnTargets="_GenerateLinkerDescriptor;_LinkBlazorApplication">
|
DependsOnTargets="_GenerateBlazorLinkerDescriptor;_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. -->
|
<!-- _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)">
|
<ReadLinesFromFile File="$(_BlazorLinkerOutputCache)">
|
||||||
|
|
@ -133,36 +140,27 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="_GenerateLinkerDescriptor"
|
<UsingTask TaskName="BlazorCreateRootDescriptorFile" AssemblyFile="$(BlazorTasksPath)" />
|
||||||
|
<Target Name="_GenerateBlazorLinkerDescriptor"
|
||||||
Inputs="@(IntermediateAssembly)"
|
Inputs="@(IntermediateAssembly)"
|
||||||
Outputs="$(GeneratedBlazorLinkerDescriptor)"
|
Outputs="$(GeneratedBlazorLinkerDescriptor)"
|
||||||
Condition="'@(BlazorLinkerDescriptor)' == ''">
|
Condition="'@(BlazorLinkerDescriptor)' == ''">
|
||||||
|
|
||||||
<!-- Generate linker descriptors if the project doesn't explicitly provide one. -->
|
<!-- Generate linker descriptors if the project doesn't explicitly provide one. -->
|
||||||
|
|
||||||
<ItemGroup>
|
<BlazorCreateRootDescriptorFile
|
||||||
<_PrepareLinkerDescriptorAssemblyLine Include="@(IntermediateAssembly->'%(FileName)')" />
|
AssemblyNames="@(IntermediateAssembly->'%(Filename)')"
|
||||||
<_GeneratedLinkerDescriptorLine Include="<linker>" />
|
RootDescriptorFilePath="$(GeneratedBlazorLinkerDescriptor)" />
|
||||||
<_GeneratedLinkerDescriptorLine Include="@(_PrepareLinkerDescriptorAssemblyLine->'<assembly fullname="%(Identity)" />')" />
|
|
||||||
<_GeneratedLinkerDescriptorLine Include="</linker>" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<WriteLinesToFile
|
|
||||||
Lines="@(_GeneratedLinkerDescriptorLine)"
|
|
||||||
File="$(GeneratedBlazorLinkerDescriptor)"
|
|
||||||
Overwrite="true"
|
|
||||||
WriteOnlyWhenDifferent="True" />
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<FileWrites Include="$(GeneratedBlazorLinkerDescriptor)" />
|
<FileWrites Include="$(GeneratedBlazorLinkerDescriptor)" />
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<BlazorLinkerDescriptor Include="$(_BlazorBuiltInBclLinkerDescriptor)" />
|
|
||||||
<BlazorLinkerDescriptor Include="$(GeneratedBlazorLinkerDescriptor)" />
|
<BlazorLinkerDescriptor Include="$(GeneratedBlazorLinkerDescriptor)" />
|
||||||
|
<BlazorLinkerDescriptor Include="$(_BlazorBuiltInBclLinkerDescriptor)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
<UsingTask TaskName="BlazorILLink" AssemblyFile="$(BlazorTasksPath)" />
|
||||||
|
|
||||||
<Target
|
<Target
|
||||||
Name="_LinkBlazorApplication"
|
Name="_LinkBlazorApplication"
|
||||||
Inputs="$(ProjectAssetsFile);
|
Inputs="$(ProjectAssetsFile);
|
||||||
|
|
@ -173,39 +171,44 @@
|
||||||
Outputs="$(_BlazorLinkerOutputCache)">
|
Outputs="$(_BlazorLinkerOutputCache)">
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<_BlazorDependencyAssembly Include="@(_BlazorDependencyInput)">
|
<_BlazorDependencyAssembly Include="@(_BlazorDependencyInput)" IsLinkable="$([System.String]::Copy('%(FileName)').StartsWith('System.'))" />
|
||||||
<RelativeDirNoTrailingSlash>$([System.String]::Copy('%(RelativeDir)').TrimEnd('\').TrimEnd('/'))</RelativeDirNoTrailingSlash>
|
|
||||||
<IsLinkable Condition="$([System.String]::Copy('%(FileName)').StartsWith('System.'))">true</IsLinkable>
|
|
||||||
</_BlazorDependencyAssembly>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<_WebAssemblyBCLFolder Include="$(DotNetWebAssemblyBCLPath);$(DotNetWebAssemblyBCLFacadesPath);$(DotNetWebAssemblyFrameworkPath)" />
|
|
||||||
<_BlazorAssembliesToCopy Include="@(IntermediateAssembly->'-a "%(FullPath)"')" />
|
|
||||||
<_BlazorFolderLookupPaths Include="@(_WebAssemblyBCLFolder->'-d "%(Identity)"')" />
|
|
||||||
|
|
||||||
<!-- For linkable assemblies, add their directories as lookup paths -->
|
<_BlazorAssemblyToLink Include="@(_WebAssemblyBCLAssembly)" />
|
||||||
<_BlazorFolderLookupPaths Condition="'%(_BlazorDependencyAssembly.IsLinkable)' == 'true'" Include="@(_BlazorDependencyAssembly->'-d "%(RelativeDirNoTrailingSlash)"')" />
|
<_BlazorAssemblyToLink Include="@(_BlazorDependencyAssembly)" Condition="'%(_BlazorDependencyAssembly.IsLinkable)' == 'true'" />
|
||||||
|
|
||||||
<!-- For non-linkable assemblies, reference the .dll directly -->
|
<_BlazorLinkerRoot Include="@(IntermediateAssembly)" />
|
||||||
<_BlazorAssembliesToCopy Condition="'%(_BlazorDependencyAssembly.IsLinkable)' != 'true'" Include="@(_BlazorDependencyAssembly->'-a "%(FullPath)"')" />
|
<_BlazorLinkerRoot Include="@(_BlazorDependencyAssembly)" Condition="'%(_BlazorDependencyAssembly.IsLinkable)' != 'true'" />
|
||||||
|
|
||||||
<_BlazorAssemblyDescriptorFiles
|
|
||||||
Include="@(BlazorLinkerDescriptor->'-x "%(FullPath)"')" Condition="'@(BlazorLinkerDescriptor)' != ''" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<_BlazorLinkerAdditionalOptions>-l $(MonoLinkerI18NAssemblies) $(AdditionalMonoLinkerOptions)</_BlazorLinkerAdditionalOptions>
|
<_BlazorLinkerAdditionalOptions>-l $(MonoLinkerI18NAssemblies) $(AdditionalMonoLinkerOptions)</_BlazorLinkerAdditionalOptions>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- Clear the contents of /obj/<<configuration>>/<<targetframework>>/blazor/linker -->
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<_OldLinkedFile Include="$(BlazorIntermediateLinkerOutputPath)*.dll" />
|
<_OldLinkedFile Include="$(BlazorIntermediateLinkerOutputPath)*.dll" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Delete Files="@(_OldLinkedFile)" />
|
<Delete Files="@(_OldLinkedFile)" />
|
||||||
|
|
||||||
<!-- Run the linker and put the results in /obj/<<configuration>>/<<targetframework>>/blazor/blazor/linker -->
|
<!--
|
||||||
<Exec Command="dotnet "$(MonoLinkerPath)" $(_BlazorLinkerAdditionalOptions) @(_BlazorFolderLookupPaths, ' ') -o "$(BlazorIntermediateLinkerOutputPath)" @(_BlazorAssemblyDescriptorFiles, ' ') @(_BlazorAssembliesToCopy, ' ')" />
|
When running from Desktop MSBuild, DOTNET_HOST_PATH is not set.
|
||||||
|
In this case, explicitly specify the path to the dotnet host.
|
||||||
|
-->
|
||||||
|
<PropertyGroup Condition=" '$(DOTNET_HOST_PATH)' == '' ">
|
||||||
|
<_DotNetHostDirectory>$(NetCoreRoot)</_DotNetHostDirectory>
|
||||||
|
<_DotNetHostFileName>dotnet</_DotNetHostFileName>
|
||||||
|
<_DotNetHostFileName Condition=" '$(OS)' == 'Windows_NT' ">dotnet.exe</_DotNetHostFileName>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<BlazorILLink
|
||||||
|
ILLinkPath="$(MonoLinkerPath)"
|
||||||
|
AssemblyPaths="@(_BlazorAssemblyToLink)"
|
||||||
|
RootAssemblyNames="@(_BlazorLinkerRoot)"
|
||||||
|
RootDescriptorFiles="@(BlazorLinkerDescriptor)"
|
||||||
|
OutputDirectory="$(BlazorIntermediateLinkerOutputPath)"
|
||||||
|
ExtraArgs="$(_BlazorLinkerAdditionalOptions)"
|
||||||
|
ToolExe="$(_DotNetHostFileName)"
|
||||||
|
ToolPath="$(_DotNetHostDirectory)" />
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<_LinkerResult Include="$(BlazorIntermediateLinkerOutputPath)*.dll" />
|
<_LinkerResult Include="$(BlazorIntermediateLinkerOutputPath)*.dll" />
|
||||||
|
|
@ -214,6 +217,7 @@
|
||||||
<WriteLinesToFile File="$(_BlazorLinkerOutputCache)" Lines="@(_LinkerResult)" Overwrite="true" />
|
<WriteLinesToFile File="$(_BlazorLinkerOutputCache)" Lines="@(_LinkerResult)" Overwrite="true" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
|
||||||
<UsingTask TaskName="ResolveBlazorRuntimeDependencies" AssemblyFile="$(BlazorTasksPath)" />
|
<UsingTask TaskName="ResolveBlazorRuntimeDependencies" AssemblyFile="$(BlazorTasksPath)" />
|
||||||
<Target
|
<Target
|
||||||
Name="_ResolveBlazorOutputsWhenNotLinked"
|
Name="_ResolveBlazorOutputsWhenNotLinked"
|
||||||
|
|
@ -242,13 +246,7 @@
|
||||||
At this point we have decided not to run the linker and instead to just copy the assemblies
|
At this point we have decided not to run the linker and instead to just copy the assemblies
|
||||||
from the BCL referenced by the app the nuget package into the _framework/_bin folder.
|
from the BCL referenced by the app the nuget package into the _framework/_bin folder.
|
||||||
The only thing we need to do here is collect the list of items that will go into _framework/_bin.
|
The only thing we need to do here is collect the list of items that will go into _framework/_bin.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<_WebAssemblyBCLFolder Include="$(DotNetWebAssemblyBCLPath);$(DotNetWebAssemblyBCLFacadesPath);$(DotNetWebAssemblyFrameworkPath)" />
|
|
||||||
<_WebAssemblyBCLAssembly Include="%(_WebAssemblyBCLFolder.Identity)*.dll" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ResolveBlazorRuntimeDependencies
|
<ResolveBlazorRuntimeDependencies
|
||||||
EntryPoint="@(IntermediateAssembly)"
|
EntryPoint="@(IntermediateAssembly)"
|
||||||
ApplicationDependencies="@(_BlazorDependencyInput)"
|
ApplicationDependencies="@(_BlazorDependencyInput)"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Blazor.Build
|
||||||
|
{
|
||||||
|
public class BlazorCreateRootDescriptorFileTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void ProducesRootDescriptor()
|
||||||
|
{
|
||||||
|
// Arrange/Act
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
BlazorCreateRootDescriptorFile.WriteRootDescriptor(
|
||||||
|
stream,
|
||||||
|
new[] { "MyApp.dll" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
stream.Position = 0;
|
||||||
|
var document = XDocument.Load(stream);
|
||||||
|
var rootElement = document.Root;
|
||||||
|
|
||||||
|
var assemblyElement = Assert.Single(rootElement.Elements());
|
||||||
|
Assert.Equal("assembly", assemblyElement.Name.ToString());
|
||||||
|
Assert.Equal("MyApp.dll", assemblyElement.Attribute("fullname").Value);
|
||||||
|
|
||||||
|
var typeElement = Assert.Single(assemblyElement.Elements());
|
||||||
|
Assert.Equal("type", typeElement.Name.ToString());
|
||||||
|
Assert.Equal("*", typeElement.Attribute("fullname").Value);
|
||||||
|
Assert.Equal("true", typeElement.Attribute("required").Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue