You've already forked linux-packaging-mono
Imported Upstream version 5.14.0.78
Former-commit-id: 3494343bcc9ddb42b36b82dd9ae7b69e85e0229f
This commit is contained in:
parent
74b74abd9f
commit
19234507ba
186
external/linker/corebuild/README.md
vendored
Normal file
186
external/linker/corebuild/README.md
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
# ILLink.Tasks
|
||||
|
||||
ILLink.Tasks is a package containing MSBuild tasks and targets that
|
||||
will run the linker to run during publish of a .NET Core app.
|
||||
|
||||
ILLink.Tasks provides an MSBuild task called ILLink that makes it easy
|
||||
to run the linker from an MSBuild project file:
|
||||
|
||||
```xml
|
||||
<ILLink AssemblyPaths="@(AssemblyFilesToLink)"
|
||||
RootAssemblyNames="@(LinkerRootAssemblies)"
|
||||
RootDescriptorFiles="@(LinkerRootDescriptors)"
|
||||
OutputDirectory="output"
|
||||
ExtraArgs="-t -c link -l none" />
|
||||
```
|
||||
|
||||
For a description of the options that this task supports, see the
|
||||
comments in [LinkTask.cs](integration/ILLink.Tasks/LinkTask.cs).
|
||||
|
||||
|
||||
In addition, ILLink.Tasks contains MSBuild logic that makes the linker
|
||||
run automatically during `dotnet publish` for .NET Core apps. This
|
||||
will:
|
||||
|
||||
- Determine the assemblies and options to pass to illink.
|
||||
- Remove unused native files from the publish output.
|
||||
- Run crossgen on the linked assemblies to improve startup performance.
|
||||
|
||||
The full set of options is described below.
|
||||
|
||||
## Building
|
||||
|
||||
```
|
||||
linker> ./corebuild/dotnet.{sh/ps1} restore ./corebuild/integration/linker.sln
|
||||
linker> ./corebuild/dotnet.{sh/ps1} pack ./corebuild/integration/ILLink.Tasks/ILLink.Tasks.csproj
|
||||
```
|
||||
|
||||
The output package will be placed in
|
||||
`corebuild/integration/bin/nupkgs`. If you are building on unix, you
|
||||
will need to adjust
|
||||
[ILLink.Tasks.nuspec](integration/ILLink.Tasks/ILLink.Tasks.nuspec). Replace
|
||||
the dll file includes with the following:
|
||||
|
||||
`<file src="netcoreapp2.0/**/*.dll" target="tools/netcoreapp2.0" />`
|
||||
|
||||
## Using ILLink.Tasks
|
||||
|
||||
Add a package reference to the linker. Ensure that either the
|
||||
[dotnet-core](https://dotnet.myget.org/gallery/dotnet-core) myget feed
|
||||
or the path to the locally-built linker package path exists in the
|
||||
project's nuget.config. If using myget, you probably want to ensure
|
||||
that you're using the latest version available at
|
||||
https://dotnet.myget.org/feed/dotnet-core/package/nuget/ILLink.Tasks.
|
||||
|
||||
After adding the package, linking will be turned on during `dotnet
|
||||
publish`. The publish output will contain the linked assemblies.
|
||||
|
||||
## Default behavior
|
||||
|
||||
By default, the linker will operate in a conservative mode that keeps
|
||||
all managed assemblies that aren't part of the framework (they are
|
||||
kept intact, and the linker simply copies them). It also analyzes all
|
||||
non-framework assemblies to find and keep code used by them (they are
|
||||
roots for the analysis). This means that unanalyzed reflection calls
|
||||
within the app should continue to work after linking. Reflection calls
|
||||
to code in the framework can potentially break when using the linker,
|
||||
if the target of the call is removed.
|
||||
|
||||
For portable publish, framework assemblies usually do not get
|
||||
published with the app. In this case they will not be analyzed or
|
||||
linked.
|
||||
|
||||
For self-contained publish, framework assemblies are part of the
|
||||
publish output, and are analyzed by the linker. Any framework
|
||||
assemblies that aren't predicted to be used at runtime based on the
|
||||
linker analysis will be removed from the publish output. Used
|
||||
framework assemblies will be kept, and any used code within these
|
||||
assemblies will be compiled to native code. Unused parts of used
|
||||
framework assemblies are kept as IL, so that reflection calls will
|
||||
continue to work, with runtime JIT compilation.
|
||||
|
||||
Native dependencies that aren't referenced by any of the kept managed
|
||||
assemblies will be removed from the publish output as well.
|
||||
|
||||
## Caveats
|
||||
|
||||
You should make sure to test the publish output before deploying your
|
||||
code, because the linker can potentially break apps that use
|
||||
reflection.
|
||||
|
||||
The linker does not analyze reflection calls, so any reflection
|
||||
targets outside of the kept assemblies will need to be rooted
|
||||
explicitly using either `LinkerRootAssemblies` or
|
||||
`LinkerRootDescriptors` (see below).
|
||||
|
||||
Sometimes an application may include multiple versions of the same
|
||||
assembly. This may happen when portable apps include platform-specific
|
||||
managed code, which gets placed in the `runtimes` directory of the
|
||||
publish output. In such cases, the linker will pick one of the
|
||||
duplicate assemblies to analyze. This means that dependencies of the
|
||||
un-analyzed duplicates may not be included in the application, so you
|
||||
may need to root such dependencies manually.
|
||||
|
||||
Native compilation only works when the target platform is the same as
|
||||
the host. To use the linker when cross-targeting (building a unix app
|
||||
from windows, for example), disable `CrossGenDuringPublish`.
|
||||
|
||||
## Options
|
||||
|
||||
The following MSBuild properties can be used to control the behavior
|
||||
of the linker, from the command-line (via `dotnet publish
|
||||
/p:PropertyName=PropertyValue`), or from the .csproj file (via
|
||||
`<PropertyName>PropertyValue</PropertyName>`). They are defined and
|
||||
used in
|
||||
[ILLink.Tasks.targets](integration/ILLink.Tasks/ILLink.Tasks.targets)
|
||||
and
|
||||
[ILLink.CrossGen.targets](integration/ILLink.Tasks/ILLink.CrossGen.targets)
|
||||
|
||||
- `LinkDuringPublish` (default `true`) - Set to `false` to disable
|
||||
linking.
|
||||
|
||||
- `ShowLinkerSizeComparison` (default `false`) - Set to `true` to
|
||||
print out a table showing the size impact of the linker.
|
||||
|
||||
- `RootAllApplicationAssemblies` (default `true`) - If `true`, all
|
||||
application assemblies are rooted by the linker. This means they are
|
||||
kept in their entirety, and analyzed for dependencies. If `false`,
|
||||
only the app dll's entry point is rooted.
|
||||
|
||||
- `LinkerRootAssemblies` - The set of assemblies to root. The default
|
||||
depends on the value of `RootAllApplicationAssemblies`. Additional
|
||||
assemblies can be rooted by adding them to this ItemGroup.
|
||||
|
||||
- `LinkerRootDescriptors` - The set of [xml descriptors](../linker#syntax-of-xml-descriptor)
|
||||
specifying additional roots within assemblies. The default is to
|
||||
include a generated descriptor that roots everything in the
|
||||
application assembly if `RootAllApplicationAssemblies` is
|
||||
`true`. Additional roots from descriptors can be included by adding
|
||||
the descriptor files to this ItemGroup.
|
||||
|
||||
- `ExtraLinkerArgs` - Extra arguments to pass to the linker. The
|
||||
default sets some flags that output symbols, tolerate resolution
|
||||
errors, log warnings, skip mono-specific localization assemblies,
|
||||
and keep type-forwarder assemblies. See
|
||||
[ILLink.Tasks.targets](integration/ILLink.Tasks/ILLink.Tasks.targets).
|
||||
Setting this will override the defaults.
|
||||
|
||||
- Assembly actions: illink has the ability to specify an [action](../linker#actions-on-the-assemblies) to
|
||||
take per-assembly. ILLink.Tasks provides high-level switches that
|
||||
control the action to take for a set of assemblies. The set of
|
||||
managed files that make up the application are split into
|
||||
"application" and "platform" assemblies. The "platform" represents
|
||||
the .NET framework, while the "application" represents the rest of
|
||||
the application and its other dependencies. The assembly action can
|
||||
be set for each of these groups independently, for assemblies that
|
||||
are analyzed as used and as unused, with the following switches:
|
||||
|
||||
- `UsedApplicationAssemblyAction` - The default is to `Copy` any used
|
||||
application assemblies to the output, leaving them as-is.
|
||||
- `UnusedApplicationAssemblyAction` - The default is to `Delete` (not
|
||||
publish) unused application assemblies.
|
||||
- `UsedPlatformAssemblyAction` - For self-contained publish, the
|
||||
default is `AddBypassNGen`, which will add the BypassNGenAttribute
|
||||
to unused code in used platform assemblies. This causes the native
|
||||
compilation step to compile only parts of these assemblies that
|
||||
are used. For portable publish, the default is to `Skip` these,
|
||||
because the platform assemblies are generally not published with
|
||||
the app.
|
||||
- `UnusedPlatformAssemblyAction` - For self-contained publish, the
|
||||
default is to `Delete` (not publish) unused platform
|
||||
assemblies. For portable publish, the default is to `Skip`.
|
||||
|
||||
The full list of assembly actions is described in
|
||||
[AssemblyAction.cs](../linker/Linker/AssemblyAction.cs) Some
|
||||
combinations of actions may be disallowed if they do not make
|
||||
sense. For more details, see
|
||||
[SetAssemblyActions.cs](integration/ILLink.Tasks/SetAssemblyActions.cs).
|
||||
|
||||
- `LinkerTrimNativeDeps` (default `true`) - If `true`, enable
|
||||
detection and removal of unused native dependencies. If `false`, all
|
||||
native dependencies are kept.
|
||||
|
||||
- `CrossGenDuringPublish` (default `true`) - If `true`, run crossgen
|
||||
on the set of assemblies modified by the linker that were crossgen'd
|
||||
before linking. If `false`, just output IL for the linked
|
||||
assemblies, even if they were crossgen'd before linking.
|
||||
@@ -4,7 +4,7 @@ using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class ComputeReadyToRunAssemblies : Task
|
||||
public class ComputeCrossgenedAssemblies : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Paths to assemblies.
|
||||
@@ -13,17 +13,17 @@ namespace ILLink.Tasks
|
||||
public ITaskItem[] Assemblies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This will contain the output list of
|
||||
/// ready-to-run assemblies. Metadata from the input
|
||||
/// parameter Assemblies is preserved.
|
||||
/// This will contain the output list of crossgen-ed
|
||||
/// assemblies. Metadata from the input parameter
|
||||
/// Assemblies is preserved.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem[] ReadyToRunAssemblies { get; set; }
|
||||
public ITaskItem[] CrossgenedAssemblies { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
ReadyToRunAssemblies = Assemblies
|
||||
.Where(f => Utils.IsReadyToRunAssembly(f.ItemSpec))
|
||||
CrossgenedAssemblies = Assemblies
|
||||
.Where(f => Utils.IsCrossgenedAssembly(f.ItemSpec))
|
||||
.ToArray();
|
||||
return true;
|
||||
}
|
||||
@@ -33,6 +33,12 @@ namespace ILLink.Tasks
|
||||
[Required]
|
||||
public ITaskItem RexcepFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to ILLinkTrim.xml.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem ILLinkTrimXmlFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the file to generate.
|
||||
/// </summary>
|
||||
@@ -76,6 +82,12 @@ namespace ILLink.Tasks
|
||||
return false;
|
||||
}
|
||||
|
||||
var iLLinkTrimXmlFilePath = ILLinkTrimXmlFilePath.ItemSpec;
|
||||
if (!File.Exists (iLLinkTrimXmlFilePath)) {
|
||||
Log.LogError ("File " + iLLinkTrimXmlFilePath + " doesn't exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ProcessNamespaces (namespaceFilePath);
|
||||
|
||||
ProcessMscorlib (mscorlibFilePath);
|
||||
@@ -84,7 +96,7 @@ namespace ILLink.Tasks
|
||||
|
||||
ProcessExceptionTypes (rexcepFilePath);
|
||||
|
||||
OutputXml (RuntimeRootDescriptorFilePath.ItemSpec);
|
||||
OutputXml (iLLinkTrimXmlFilePath, RuntimeRootDescriptorFilePath.ItemSpec);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -206,22 +218,17 @@ namespace ILLink.Tasks
|
||||
string classNamespace = defElements [1]; // g_InteropNS
|
||||
string className = defElements [2]; // MarshalDirectiveException
|
||||
AddClass (classNamespace, className, classId);
|
||||
AddMethod (".ctor", classId, classNamespace, className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OutputXml (string outputFileName)
|
||||
void OutputXml (string iLLinkTrimXmlFilePath, string outputFileName)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument ();
|
||||
|
||||
XmlNode linkerNode = doc.CreateElement ("linker");
|
||||
doc.AppendChild (linkerNode);
|
||||
|
||||
XmlNode assemblyNode = doc.CreateElement ("assembly");
|
||||
XmlAttribute assemblyFullName = doc.CreateAttribute ("fullname");
|
||||
assemblyFullName.Value = "System.Private.CoreLib";
|
||||
assemblyNode.Attributes.Append (assemblyFullName);
|
||||
linkerNode.AppendChild (assemblyNode);
|
||||
doc.Load (iLLinkTrimXmlFilePath);
|
||||
XmlNode linkerNode = doc ["linker"];
|
||||
XmlNode assemblyNode = linkerNode ["assembly"];
|
||||
|
||||
foreach (string typeName in classNamesToClassMembers.Keys) {
|
||||
XmlNode typeNode = doc.CreateElement ("type");
|
||||
@@ -273,20 +280,8 @@ namespace ILLink.Tasks
|
||||
|
||||
void AddClass (string classNamespace, string className, string classId, bool keepAllFields = false)
|
||||
{
|
||||
string prefixToRemove = "g_";
|
||||
if (classNamespace.StartsWith (prefixToRemove)) {
|
||||
classNamespace = classNamespace.Substring (prefixToRemove.Length);
|
||||
}
|
||||
string suffixToRemove = "NS";
|
||||
if (classNamespace.EndsWith (suffixToRemove)) {
|
||||
classNamespace = classNamespace.Substring (0, classNamespace.Length - suffixToRemove.Length);
|
||||
}
|
||||
string fullClassName = null;
|
||||
if ((classNamespace != "NULL") && (className != "NULL")) {
|
||||
if (!namespaceDictionary.ContainsKey (classNamespace)) {
|
||||
Log.LogError ("Unknown namespace: " + classNamespace);
|
||||
}
|
||||
fullClassName = namespaceDictionary [classNamespace] + "." + className;
|
||||
string fullClassName = GetFullClassName (classNamespace, className);
|
||||
if (fullClassName != null) {
|
||||
if ((classId != null) && (classId != "NoClass")) {
|
||||
classIdsToClassNames [classId] = fullClassName;
|
||||
}
|
||||
@@ -311,16 +306,44 @@ namespace ILLink.Tasks
|
||||
members.fields.Add (fieldName);
|
||||
}
|
||||
|
||||
void AddMethod (string methodName, string classId)
|
||||
void AddMethod (string methodName, string classId, string classNamespace = null, string className = null)
|
||||
{
|
||||
string className = classIdsToClassNames [classId];
|
||||
string fullClassName;
|
||||
if (classId != null) {
|
||||
fullClassName = classIdsToClassNames [classId];
|
||||
}
|
||||
else {
|
||||
fullClassName = GetFullClassName (classNamespace, className);
|
||||
}
|
||||
|
||||
ClassMembers members = classNamesToClassMembers [className];
|
||||
ClassMembers members = classNamesToClassMembers [fullClassName];
|
||||
|
||||
if (members.methods == null) {
|
||||
members.methods = new HashSet<string> ();
|
||||
}
|
||||
members.methods.Add (methodName);
|
||||
}
|
||||
|
||||
string GetFullClassName (string classNamespace, string className)
|
||||
{
|
||||
string prefixToRemove = "g_";
|
||||
if (classNamespace.StartsWith (prefixToRemove)) {
|
||||
classNamespace = classNamespace.Substring (prefixToRemove.Length);
|
||||
}
|
||||
string suffixToRemove = "NS";
|
||||
if (classNamespace.EndsWith (suffixToRemove)) {
|
||||
classNamespace = classNamespace.Substring (0, classNamespace.Length - suffixToRemove.Length);
|
||||
}
|
||||
|
||||
if ((classNamespace == "NULL") && (className == "NULL")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!namespaceDictionary.ContainsKey (classNamespace)) {
|
||||
Log.LogError ("Unknown namespace: " + classNamespace);
|
||||
}
|
||||
|
||||
return namespaceDictionary [classNamespace] + "." + className;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
47
external/linker/corebuild/integration/ILLink.Tasks/FindDuplicatesByMetadata.cs
vendored
Normal file
47
external/linker/corebuild/integration/ILLink.Tasks/FindDuplicatesByMetadata.cs
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class FindDuplicatesByMetadata : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Items to scan.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem [] Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of metadata to scan for.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public String MetadataName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Duplicate items: the input items for which the
|
||||
/// specified metadata was shared by multiple input
|
||||
/// items.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem [] DuplicateItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Duplicate representatives: includes one input
|
||||
/// item from each set of duplicates.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem [] DuplicateRepresentatives { get; set; }
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
var duplicateGroups = Items.GroupBy (i => i.GetMetadata (MetadataName))
|
||||
.Where (g => g.Count () > 1);
|
||||
DuplicateItems = duplicateGroups.SelectMany (g => g).ToArray ();
|
||||
DuplicateRepresentatives = duplicateGroups.Select (g => g.First ()).ToArray ();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<PropertyGroup>
|
||||
<CrossGenDuringPublish Condition=" '$(CrossGenDuringPublish)' == '' And '$(RuntimeIdentifier)' != '' ">true</CrossGenDuringPublish>
|
||||
<CrossGenDuringPublish Condition=" '$(CrossGenDuringPublish)' == '' And '$(RuntimeIdentifier)' != '' And '$(LinkDuringPublish)' == 'true' ">true</CrossGenDuringPublish>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -28,8 +28,7 @@
|
||||
<ItemGroup>
|
||||
<_CrossGenResolvedAssembliesToPublishCandidates Include="@(ResolvedAssembliesToPublish->'$(IntermediateOptimizedDir)/%(Filename)%(Extension)')" />
|
||||
<_CrossGenResolvedAssembliesToPublish Include="@(_CrossGenResolvedAssembliesToPublishCandidates)" Condition="Exists('%(Identity)')" />
|
||||
<!-- FilesToCrossGen doesn't contain System.Private.CoreLib, so
|
||||
it will still be published. -->
|
||||
|
||||
<ResolvedAssembliesToPublish Remove="@(FilesToCrossGen)" />
|
||||
<ResolvedAssembliesToPublish Include="@(_CrossGenResolvedAssembliesToPublish)" />
|
||||
</ItemGroup>
|
||||
@@ -188,9 +187,9 @@
|
||||
|
||||
<UsingTask TaskName="FilterByMetadata" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<!-- This computes the default set of files that we want to be
|
||||
crossgen'd. Some of these may already be R2R images, and these
|
||||
will not be crossgen'd again. The default is to crossgen the
|
||||
app and platform libraries. Defaults will be used only if
|
||||
crossgen'd. Some of these may already be crossgen images, and
|
||||
these will not be crossgen'd again. The default is to crossgen
|
||||
the app and platform libraries. Defaults will be used only if
|
||||
FilesToCrossGen hasn't been set elsewhere, allowing users and
|
||||
other props/targets to select what will be crossgen'd. -->
|
||||
<Target Name="_ComputeDefaultFilesToCrossGen"
|
||||
@@ -208,21 +207,20 @@
|
||||
<FilesToCrossGen Include="@(_PlatformLibrariesForCrossGen)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Error Text="System.Private.CoreLib should already be crossgen compiled."
|
||||
Condition=" '%(FilesToCrossGen.Filename)' == 'System.Private.CoreLib' " />
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="ComputeReadyToRunAssemblies" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<UsingTask TaskName="ComputeCrossgenedAssemblies" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="_ComputeFilesToCrossGen"
|
||||
DependsOnTargets="_ComputeDefaultFilesToCrossGen">
|
||||
|
||||
<ComputeReadyToRunAssemblies Assemblies="@(FilesToCrossGen)">
|
||||
<Output TaskParameter="ReadyToRunAssemblies" ItemName="_ReadyToRunFiles" />
|
||||
</ComputeReadyToRunAssemblies>
|
||||
<ComputeCrossgenedAssemblies Assemblies="@(FilesToCrossGen)">
|
||||
<Output TaskParameter="CrossgenedAssemblies" ItemName="_CrossgenedFiles" />
|
||||
</ComputeCrossgenedAssemblies>
|
||||
|
||||
<!-- Don't try to run crossgen on assemblies that are already R2R. -->
|
||||
<!-- Don't try to run crossgen on assemblies that are already
|
||||
crossgen'd. -->
|
||||
<ItemGroup>
|
||||
<FilesToCrossGen Remove="@(_ReadyToRunFiles)" />
|
||||
<FilesToCrossGen Remove="@(_CrossgenedFiles)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Message Text="files to crossgen: @(FilesToCrossGen)" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>0.1.4-preview</VersionPrefix>
|
||||
<VersionPrefix>0.1.5-preview</VersionPrefix>
|
||||
<TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
@@ -101,11 +101,12 @@
|
||||
<Compile Include="LinkTask.cs" />
|
||||
<Compile Include="CompareSizes.cs" />
|
||||
<Compile Include="ComputeManagedAssemblies.cs" />
|
||||
<Compile Include="ComputeReadyToRunAssemblies.cs" />
|
||||
<Compile Include="ComputeCrossgenedAssemblies.cs" />
|
||||
<Compile Include="GetRuntimeLibraries.cs" />
|
||||
<Compile Include="CreateRootDescriptorFile.cs" />
|
||||
<Compile Include="CreateRuntimeRootDescriptorFile.cs" />
|
||||
<Compile Include="FilterByMetadata.cs" />
|
||||
<Compile Include="FindDuplicatesByMetadata.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="Microsoft.NET.Build.Tasks/LockFileCache.cs" />
|
||||
<Compile Include="Microsoft.NET.Build.Tasks/BuildErrorException.cs" />
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
<!-- Rewrite ResolvedAssembliesToPublish, which is an input to
|
||||
ComputeFilesToPublish. -->
|
||||
<ItemGroup>
|
||||
<ResolvedAssembliesToPublish Remove="@(_ManagedResolvedAssembliesToPublish)" />
|
||||
<ResolvedAssembliesToPublish Remove="@(_ManagedAssembliesToLink)" />
|
||||
<ResolvedAssembliesToPublish Remove="@(_NativeResolvedDepsToPublish)" />
|
||||
<ResolvedAssembliesToPublish Include="@(_NativeKeptDepsToPublish)" />
|
||||
<ResolvedAssembliesToPublish Include="@(_LinkedResolvedAssemblies)" />
|
||||
@@ -145,15 +145,21 @@
|
||||
<!-- Print out a size comparison report for the linked
|
||||
assemblies. This is disabled by default, but can be turned on
|
||||
by setting $(ShowLinkerSizeComparison) to true. This runs after
|
||||
the top-level link target, ComputeLinkedFilesToPublish, so it
|
||||
is output even during incremental builds. -->
|
||||
the ComputeFilesToPublish, so it is output even during
|
||||
incremental builds and takes into account all transformations
|
||||
on the files to be published, including link and crossgen. -->
|
||||
<UsingTask TaskName="CompareAssemblySizes" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="_CompareLinkedAssemblySizes"
|
||||
AfterTargets="ComputeLinkedFilesToPublish"
|
||||
AfterTargets="ComputeFilesToPublish"
|
||||
DependsOnTargets="_ComputeManagedAssembliesToLink;_ComputeLinkedAssemblies"
|
||||
Condition=" '$(LinkDuringPublish)' == 'true' And '$(ShowLinkerSizeComparison)' == 'true' ">
|
||||
<FilterByMetadata Items="@(ResolvedAssembliesToPublish);@(IntermediateAssembly)"
|
||||
MetadataName="Filename"
|
||||
MetadataValues="@(_ManagedAssembliesToLink->'%(Filename)')">
|
||||
<Output TaskParameter="FilteredItems" ItemName="_FinalAssembliesTouchedByLinker" />
|
||||
</FilterByMetadata>
|
||||
<CompareAssemblySizes UnlinkedAssemblies="@(_ManagedAssembliesToLink)"
|
||||
LinkedAssemblies="@(_LinkedIntermediateAssembly);@(_LinkedResolvedAssemblies)" />
|
||||
LinkedAssemblies="@(_FinalAssembliesTouchedByLinker)" />
|
||||
</Target>
|
||||
|
||||
|
||||
@@ -166,9 +172,10 @@
|
||||
DependsOnTargets="_ComputeManagedResolvedAssembliesToPublish;ILLink">
|
||||
<ItemGroup>
|
||||
<__LinkedResolvedAssemblies Include="@(_ManagedResolvedAssembliesToPublish->'$(IntermediateLinkDir)/%(Filename)%(Extension)')" />
|
||||
<__LinkedResolvedAssemblies Remove="@(_DuplicateManagedAssembliesToSkip->'$(IntermediateLinkDir)/%(Filename)%(Extension)')" />
|
||||
<_LinkedResolvedAssemblies Include="@(__LinkedResolvedAssemblies)" Condition="Exists('%(Identity)')" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<__LinkedIntermediateAssembly Include="@(IntermediateAssembly->'$(IntermediateLinkDir)/%(Filename)%(Extension)')" />
|
||||
<_LinkedIntermediateAssembly Include="@(__LinkedIntermediateAssembly)" Condition="Exists('%(Identity)')" />
|
||||
@@ -180,33 +187,62 @@
|
||||
<_LinkedDebugSymbols Include="@(__LinkedDebugSymbols)"
|
||||
Condition="Exists('%(Identity)') And '$(_DebugSymbolsProduced)' == 'true' " />
|
||||
</ItemGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<!-- Compute the default set of assemblies to crossgen after
|
||||
linking. This will include any assemblies modified by the
|
||||
linker that were crossgen'd before linking. -->
|
||||
<Target Name="_ComputeLinkedAssembliesToCrossgen"
|
||||
AfterTargets="_ComputeLinkedAssemblies"
|
||||
Condition=" '$(CrossGenDuringPublish)' == 'true' ">
|
||||
<FilterByMetadata Items="@(_ManagedResolvedAssembliesToPublish);@(IntermediateAssembly)"
|
||||
MetadataName="Filename"
|
||||
MetadataValues="@(_LinkedResolvedAssemblies->'%(Filename)');@(_LinkedIntermediateAssembly->'%(Filename)')">
|
||||
<Output TaskParameter="FilteredItems" ItemName="_OriginalLinkedAssemblies" />
|
||||
</FilterByMetadata>
|
||||
|
||||
<ComputeCrossgenedAssemblies Assemblies="@(_OriginalLinkedAssemblies)">
|
||||
<Output TaskParameter="CrossgenedAssemblies" ItemName="_OriginalLinkedAssembliesThatWereCrossgened" />
|
||||
</ComputeCrossgenedAssemblies>
|
||||
|
||||
<!-- Ideally, we would remember which assemblies were R2R and
|
||||
which were fragile crossgen-ed, and do the same after
|
||||
linking. Currently this makes no difference because
|
||||
System.Private.CoreLib is the only fragile image, and it
|
||||
can't be ready-to-run crossgen-ed. -->
|
||||
<ItemGroup>
|
||||
<_LinkedAssembliesToCrossgen Include="@(_OriginalLinkedAssembliesThatWereCrossgened->'$(IntermediateLinkDir)/%(Filename)%(Extension)')" />
|
||||
<FilesToCrossgen Include="@(_LinkedAssembliesToCrossgen)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="SetAssemblyActions" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="_SetAssemblyActions"
|
||||
DependsOnTargets="_ComputeManagedAssembliesToLink;_ComputePlatformLibraries">
|
||||
|
||||
<ItemGroup>
|
||||
<_PlatformAssembliesToLink Include="@(PlatformLibraries->'%(Filename)')" />
|
||||
<_PlatformAssembliesToLink Include="System.Private.CoreLib" />
|
||||
<_ApplicationAssembliesToLink Include="@(_ManagedAssembliesToLink->'%(Filename)')" />
|
||||
<_ApplicationAssembliesToLink Remove="@(_PlatformAssembliesToLink)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<_PlatformAssembliesToLink Include="@(PlatformLibraries->'%(Filename)')" />
|
||||
<_ApplicationAssembliesToLink Include="@(_ManagedAssembliesToLink->'%(Filename)')" />
|
||||
<_ApplicationAssembliesToLink Remove="@(_PlatformAssembliesToLink)" />
|
||||
</ItemGroup>
|
||||
|
||||
<SetAssemblyActions AssemblyPaths="@(_ManagedAssembliesToLink)"
|
||||
ApplicationAssemblyNames="@(_ApplicationAssembliesToLink)"
|
||||
PlatformAssemblyNames="@(_PlatformAssembliesToLink)"
|
||||
UsedApplicationAssemblyAction="$(UsedApplicationAssemblyAction)"
|
||||
UnusedApplicationAssemblyAction="$(UnusedApplicationAssemblyAction)"
|
||||
UsedPlatformAssemblyAction="$(UsedPlatformAssemblyAction)"
|
||||
UnusedPlatformAssemblyAction="$(UnusedPlatformAssemblyAction)">
|
||||
<Output TaskParameter="AssemblyPathsWithActions" ItemName="_ManagedAssembliesToLinkWithActions" />
|
||||
</SetAssemblyActions>
|
||||
<SetAssemblyActions AssemblyPaths="@(_ManagedAssembliesToLink)"
|
||||
ApplicationAssemblyNames="@(_ApplicationAssembliesToLink)"
|
||||
PlatformAssemblyNames="@(_PlatformAssembliesToLink)"
|
||||
UsedApplicationAssemblyAction="$(UsedApplicationAssemblyAction)"
|
||||
UnusedApplicationAssemblyAction="$(UnusedApplicationAssemblyAction)"
|
||||
UsedPlatformAssemblyAction="$(UsedPlatformAssemblyAction)"
|
||||
UnusedPlatformAssemblyAction="$(UnusedPlatformAssemblyAction)">
|
||||
<Output TaskParameter="AssemblyPathsWithActions" ItemName="_ManagedAssembliesToLinkWithActions" />
|
||||
</SetAssemblyActions>
|
||||
|
||||
<ItemGroup>
|
||||
<_ManagedAssembliesToLink Remove="@(_ManagedAssembliesToLink)" />
|
||||
<_ManagedAssembliesToLink Include="@(_ManagedAssembliesToLinkWithActions)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ManagedAssembliesToLink Remove="@(_ManagedAssembliesToLink)" />
|
||||
<_ManagedAssembliesToLink Include="@(_ManagedAssembliesToLinkWithActions)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!-- This calls the linker. Inputs are the managed assemblies to
|
||||
@@ -244,7 +280,8 @@
|
||||
dependencies, and these are prevented from being published. -->
|
||||
<UsingTask TaskName="FindNativeDeps" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="_FindNativeDeps"
|
||||
DependsOnTargets="_ComputeLinkedAssemblies">
|
||||
DependsOnTargets="_ComputeLinkedAssemblies"
|
||||
Condition=" '$(LinkerTrimNativeDeps)' == 'true' ">
|
||||
<ItemGroup>
|
||||
<_NativeResolvedDepsToPublish Include="@(ResolvedAssembliesToPublish)" />
|
||||
<_NativeResolvedDepsToPublish Remove="@(_ManagedResolvedAssembliesToPublish)" />
|
||||
@@ -263,21 +300,18 @@
|
||||
<_NativeDepsToAlwaysKeep Include="hostpolicy.dll;libhostpolicy.dylib;libhostpolicy.so" />
|
||||
</ItemGroup>
|
||||
|
||||
<FindNativeDeps Condition=" '$(LinkerTrimNativeDeps)' == 'true' "
|
||||
ManagedAssemblyPaths="@(_ManagedLinkedAssemblies)"
|
||||
<FindNativeDeps ManagedAssemblyPaths="@(_ManagedLinkedAssemblies);@(_DuplicateManagedAssembliesToSkip)"
|
||||
NativeDepsPaths="@(_NativeResolvedDepsToPublish)"
|
||||
NativeDepsToKeep="@(_NativeDepsToAlwaysKeep)">
|
||||
<Output TaskParameter="KeptNativeDepsPaths" ItemName="_NativeKeptDepsToPublish" />
|
||||
</FindNativeDeps>
|
||||
<PropertyGroup>
|
||||
<_NativeKeptDepsToPublish Condition=" '$(LinkerTrimNativeDeps)' != 'true' ">"@(_NativeResolvedDepsToPublish)"</_NativeKeptDepsToPublish>
|
||||
</PropertyGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<!-- Computes the managed assemblies that are input to the
|
||||
linker. Includes managed assemblies from
|
||||
ResolvedAssembliesToPublish, and IntermediateAssembly. -->
|
||||
<UsingTask TaskName="FindDuplicatesByMetadata" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="_ComputeManagedAssembliesToLink"
|
||||
DependsOnTargets="_ComputeManagedResolvedAssembliesToPublish">
|
||||
<ItemGroup>
|
||||
@@ -285,6 +319,22 @@
|
||||
<_ManagedAssembliesToLink Include="@(_ManagedResolvedAssembliesToPublish)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Remove duplicate implementation dlls. This can happen if a
|
||||
portable app has platform-specific managed assemblies. The
|
||||
linker isn't currently able to analyze multiple assemblies
|
||||
with the same identity, so we skip these, keeping only one
|
||||
representative assembly from each set of duplicates. -->
|
||||
<FindDuplicatesByMetadata Items="@(_ManagedAssembliesToLink)"
|
||||
MetadataName="Filename">
|
||||
<Output TaskParameter="DuplicateItems" ItemName="_DuplicateManagedAssemblies" />
|
||||
<Output TaskParameter="DuplicateRepresentatives" ItemName="_DuplicateManagedAssembliesToLink" />
|
||||
</FindDuplicatesByMetadata>
|
||||
<ItemGroup>
|
||||
<_DuplicateManagedAssembliesToSkip Include="@(_DuplicateManagedAssemblies)" />
|
||||
<_DuplicateManagedAssembliesToSkip Remove="@(_DuplicateManagedAssembliesToLink)" />
|
||||
<_ManagedAssembliesToLink Remove="@(_DuplicateManagedAssembliesToSkip)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Portable publish: need to supply the linker with any needed
|
||||
reference assemblies as well.
|
||||
|
||||
@@ -376,14 +426,23 @@
|
||||
<ItemGroup Condition=" '$(RootAllApplicationAssemblies)' == 'true' ">
|
||||
<_LinkerRootAssemblies Include="@(_ManagedResolvedAssembliesToPublish->'%(Filename)')" />
|
||||
<_LinkerRootAssemblies Remove="@(PlatformLibraries->'%(Filename)')" />
|
||||
<_LinkerRootAssemblies Remove="System.Private.CoreLib" Condition=" '$(_SPCHasEmbeddedRootDescriptor)' == 'true' "/>
|
||||
<LinkerRootAssemblies Include="@(_LinkerRootAssemblies)" />
|
||||
</ItemGroup>
|
||||
<RemoveDuplicates Inputs="@(_LinkerRootAssemblies)"
|
||||
Condition=" '$(RootAllApplicationAssemblies)' == 'true' ">
|
||||
<Output TaskParameter="Filtered" ItemName="_UniqueLinkerRootAssemblies" />
|
||||
</RemoveDuplicates>
|
||||
<ItemGroup Condition=" '$(RootAllApplicationAssemblies)' == 'true' ">
|
||||
<LinkerRootAssemblies Include="@(_UniqueLinkerRootAssemblies)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(RootAllApplicationAssemblies)' == 'false' ">
|
||||
<LinkerRootAssemblies Include="@(IntermediateAssembly)" />
|
||||
<LinkerRootAssemblies Include="System.Private.CoreLib" Condition=" '$(_SPCHasEmbeddedRootDescriptor)' == 'false' "/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(_SPCHasEmbeddedRootDescriptor)' != 'true' ">
|
||||
<LinkerRootAssemblies Include="@(_ManagedResolvedAssembliesToPublish->'%(Filename)')" Condition=" '%(Filename)' == 'System.Private.CoreLib' " />
|
||||
</ItemGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="CheckEmbeddedRootDescriptor" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
@@ -406,6 +465,11 @@
|
||||
PackageNames="$(MicrosoftNETPlatformLibrary)">
|
||||
<Output TaskParameter="RuntimeLibraries" ItemName="PlatformLibraries" />
|
||||
</GetRuntimeLibraries>
|
||||
|
||||
<ItemGroup>
|
||||
<PlatformLibraries Include="@(_ManagedAssembliesToLink)" Condition=" '%(Filename)' == 'System.Private.CoreLib' " />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(SelfContained)' != 'true' ">
|
||||
<!-- Portable publish: computed referenced-not-published set in _ComputeManagedAssembliesToLink -->
|
||||
<PlatformLibraries Include="@(_ReferencedLibraries)" />
|
||||
@@ -447,7 +511,7 @@
|
||||
DependsOnTargets="_ComputeManagedResolvedAssembliesToPublish;_ComputeLinkedAssemblies;_FindNativeDeps;_HandlePublishFileConflicts"
|
||||
BeforeTargets="GeneratePublishDependencyFile"
|
||||
Condition=" '$(LinkDuringPublish)' == 'true' ">
|
||||
<ComputeRemovedAssemblies InputAssemblies="@(_ManagedResolvedAssembliesToPublish)"
|
||||
<ComputeRemovedAssemblies InputAssemblies="@(_ManagedAssembliesToLink)"
|
||||
KeptAssemblies="@(_LinkedResolvedAssemblies)">
|
||||
<Output TaskParameter="RemovedAssemblies" ItemName="_RemovedManagedAssemblies" />
|
||||
</ComputeRemovedAssemblies>
|
||||
|
||||
@@ -16,6 +16,9 @@ namespace ILLink.Tasks
|
||||
/// behavior should not be relied upon. Instead, work under
|
||||
/// the assumption that only the AssemblyPaths given will be
|
||||
/// resolved.
|
||||
/// Each path can also have an "action" metadata,
|
||||
/// which will set the illink action to take for
|
||||
/// that assembly.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem [] AssemblyPaths { get; set; }
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
using Mono.Linker;
|
||||
|
||||
public class Utils
|
||||
public static class Utils
|
||||
{
|
||||
public static bool IsManagedAssembly (string fileName)
|
||||
{
|
||||
@@ -13,12 +14,11 @@ public class Utils
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsReadyToRunAssembly (string fileName)
|
||||
public static bool IsCrossgenedAssembly (string fileName)
|
||||
{
|
||||
try {
|
||||
ModuleDefinition module = ModuleDefinition.ReadModule (fileName);
|
||||
return (module.Attributes & ModuleAttributes.ILOnly) == 0 &&
|
||||
(module.Attributes & (ModuleAttributes) 0x04) != 0;
|
||||
return module.IsCrossgened ();
|
||||
} catch (BadImageFormatException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user