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
2
external/linker/README.md
vendored
2
external/linker/README.md
vendored
@@ -6,6 +6,8 @@ programs might require to run as opposed to the full libraries.
|
||||
It is used by the various Xamarin products to extract only the bits of code that are needed to run
|
||||
an application on Android, iOS and other platforms.
|
||||
|
||||
It can also be used in the form of [ILLink.Tasks](corebuild/README.md) to reduce the size of .NET Core apps.
|
||||
|
||||
# [Analyzer](analyzer/README.md)
|
||||
|
||||
The analyzer is a tool to analyze dependencies which were recorded during linker processing and led linker to mark an item to keep it in the resulting linked assembly.
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -39,15 +39,10 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
public class BlacklistStep : BaseStep {
|
||||
|
||||
protected override bool ConditionToProcess()
|
||||
{
|
||||
return Context.CoreAction == AssemblyAction.Link;
|
||||
}
|
||||
|
||||
protected override void Process ()
|
||||
{
|
||||
foreach (string name in Assembly.GetExecutingAssembly ().GetManifestResourceNames ()) {
|
||||
if (!name.EndsWith (".xml", StringComparison.OrdinalIgnoreCase) || !IsReferenced (GetAssemblyName (name)))
|
||||
if (!name.EndsWith (".xml", StringComparison.OrdinalIgnoreCase) || !ShouldProcessAssemblyResource (GetAssemblyName (name)))
|
||||
continue;
|
||||
|
||||
try {
|
||||
@@ -64,7 +59,7 @@ namespace Mono.Linker.Steps {
|
||||
.SelectMany (mod => mod.Resources)
|
||||
.Where (res => res.ResourceType == ResourceType.Embedded)
|
||||
.Where (res => res.Name.EndsWith (".xml", StringComparison.OrdinalIgnoreCase))
|
||||
.Where (res => IsReferenced (GetAssemblyName (res.Name)))
|
||||
.Where (res => ShouldProcessAssemblyResource (GetAssemblyName (res.Name)))
|
||||
.Cast<EmbeddedResource> ()) {
|
||||
try {
|
||||
Context.LogMessage ("Processing embedded resource linker descriptor: {0}", rsc.Name);
|
||||
@@ -87,13 +82,30 @@ namespace Mono.Linker.Steps {
|
||||
return descriptor.Substring (0, pos);
|
||||
}
|
||||
|
||||
bool IsReferenced (string name)
|
||||
bool ShouldProcessAssemblyResource (string name)
|
||||
{
|
||||
AssemblyDefinition assembly = GetAssemblyIfReferenced (name);
|
||||
|
||||
if (assembly == null)
|
||||
return false;
|
||||
|
||||
switch (Annotations.GetAction (assembly)) {
|
||||
case AssemblyAction.Link:
|
||||
case AssemblyAction.AddBypassNGen:
|
||||
case AssemblyAction.AddBypassNGenUsed:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
AssemblyDefinition GetAssemblyIfReferenced (string name)
|
||||
{
|
||||
foreach (AssemblyDefinition assembly in Context.GetAssemblies ())
|
||||
if (assembly.Name.Name == name)
|
||||
return true;
|
||||
return assembly;
|
||||
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual IStep GetExternalResolveStep (EmbeddedResource resource, AssemblyDefinition assembly)
|
||||
|
||||
14
external/linker/linker/Linker.Steps/MarkStep.cs
vendored
14
external/linker/linker/Linker.Steps/MarkStep.cs
vendored
@@ -308,8 +308,18 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
protected virtual bool ShouldMarkCustomAttribute (CustomAttribute ca)
|
||||
{
|
||||
if (_context.KeepUsedAttributeTypesOnly && !Annotations.IsMarked (ca.AttributeType.Resolve ()))
|
||||
return false;
|
||||
if (_context.KeepUsedAttributeTypesOnly) {
|
||||
switch (ca.AttributeType.FullName) {
|
||||
// [ThreadStatic] and [ContextStatic] are required by the runtime
|
||||
case "System.ThreadStaticAttribute":
|
||||
case "System.ContextStaticAttribute":
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Annotations.IsMarked (ca.AttributeType.Resolve ()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,12 +87,6 @@ namespace Mono.Linker.Steps {
|
||||
OutputAssembly (assembly);
|
||||
}
|
||||
|
||||
static bool IsReadyToRun (ModuleDefinition module)
|
||||
{
|
||||
return (module.Attributes & ModuleAttributes.ILOnly) == 0 &&
|
||||
(module.Attributes & (ModuleAttributes) 0x04) != 0;
|
||||
}
|
||||
|
||||
protected void WriteAssembly (AssemblyDefinition assembly, string directory)
|
||||
{
|
||||
WriteAssembly (assembly, directory, SaveSymbols (assembly));
|
||||
@@ -101,10 +95,10 @@ namespace Mono.Linker.Steps {
|
||||
protected virtual void WriteAssembly (AssemblyDefinition assembly, string directory, WriterParameters writerParameters)
|
||||
{
|
||||
foreach (var module in assembly.Modules) {
|
||||
// Write back pure IL even for R2R assemblies
|
||||
if (IsReadyToRun (module)) {
|
||||
// Write back pure IL even for crossgen-ed assemblies
|
||||
if (module.IsCrossgened ()) {
|
||||
module.Attributes |= ModuleAttributes.ILOnly;
|
||||
module.Attributes ^= (ModuleAttributes) (uint) 0x04;
|
||||
module.Attributes ^= ModuleAttributes.ILLibrary;
|
||||
module.Architecture = CalculateArchitecture (module.Architecture);
|
||||
}
|
||||
}
|
||||
@@ -168,11 +162,9 @@ namespace Mono.Linker.Steps {
|
||||
if (!assembly.MainModule.HasSymbols)
|
||||
return parameters;
|
||||
|
||||
#if NATIVE_READER_SUPPORT
|
||||
// NativePdb's can't be written on non-windows platforms
|
||||
if (Environment.OSVersion.Platform != PlatformID.Win32NT && assembly.MainModule.SymbolReader is Mono.Cecil.Pdb.NativePdbReader)
|
||||
// Use a string check to avoid a hard dependency on Mono.Cecil.Pdb
|
||||
if (Environment.OSVersion.Platform != PlatformID.Win32NT && assembly.MainModule.SymbolReader.GetType ().FullName == "Mono.Cecil.Pdb.NativePdbReader")
|
||||
return parameters;
|
||||
#endif
|
||||
|
||||
if (Context.SymbolWriterProvider != null)
|
||||
parameters.SymbolWriterProvider = Context.SymbolWriterProvider;
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Mono.Linker.Steps {
|
||||
try {
|
||||
ProcessAssemblies (Context, nav.SelectChildren ("assembly", _ns));
|
||||
|
||||
if (!string.IsNullOrEmpty (_resourceName))
|
||||
if (!string.IsNullOrEmpty (_resourceName) && Context.StripResources)
|
||||
Context.Annotations.AddResourceToRemove (_resourceAssembly, _resourceName);
|
||||
} catch (Exception ex) when (!(ex is XmlResolutionException)) {
|
||||
throw new XmlResolutionException (string.Format ("Failed to process XML description: {0}", _xmlDocumentLocation), ex);
|
||||
|
||||
16
external/linker/linker/Linker/AssemblyUtilities.cs
vendored
Normal file
16
external/linker/linker/Linker/AssemblyUtilities.cs
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Mono.Linker {
|
||||
|
||||
public static class AssemblyUtilities {
|
||||
|
||||
public static bool IsCrossgened (this ModuleDefinition module)
|
||||
{
|
||||
return (module.Attributes & ModuleAttributes.ILOnly) == 0 &&
|
||||
(module.Attributes & ModuleAttributes.ILLibrary) != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
7
external/linker/linker/Linker/Driver.cs
vendored
7
external/linker/linker/Linker/Driver.cs
vendored
@@ -143,6 +143,11 @@ namespace Mono.Linker {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token == "--strip-resources") {
|
||||
context.StripResources = bool.Parse (GetParam ());
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (token [2]) {
|
||||
case 'v':
|
||||
Version ();
|
||||
@@ -316,6 +321,7 @@ namespace Mono.Linker {
|
||||
return assemblies;
|
||||
}
|
||||
|
||||
|
||||
AssemblyAction ParseAssemblyAction (string s)
|
||||
{
|
||||
var assemblyAction = (AssemblyAction)Enum.Parse(typeof(AssemblyAction), s, true);
|
||||
@@ -362,6 +368,7 @@ namespace Mono.Linker {
|
||||
Console.WriteLine (" --reduced-tracing Reduces dependency output related to assemblies that will not be modified");
|
||||
Console.WriteLine (" --used-attrs-only Attributes on types, methods, etc will be removed if the attribute type is not used");
|
||||
Console.WriteLine (" --strip-security In linked assemblies, attributes on assemblies, types, and methods related to security will be removed");
|
||||
Console.WriteLine (" --strip-resources Remove link xml resources that were processed (true or false), default to true");
|
||||
Console.WriteLine (" -out Specify the output directory, default to `output'");
|
||||
Console.WriteLine (" -c Action on the core assemblies, skip, copy, copyused, addbypassngen, addbypassngenused or link, default to skip");
|
||||
Console.WriteLine (" -u Action on the user assemblies, skip, copy, copyused, addbypassngen, addbypassngenused or link, default to link");
|
||||
|
||||
3
external/linker/linker/Linker/LinkContext.cs
vendored
3
external/linker/linker/Linker/LinkContext.cs
vendored
@@ -111,6 +111,8 @@ namespace Mono.Linker {
|
||||
|
||||
public bool KeepUsedAttributeTypesOnly { get; set; }
|
||||
|
||||
public bool StripResources { get; set; }
|
||||
|
||||
public System.Collections.IDictionary Actions {
|
||||
get { return _actions; }
|
||||
}
|
||||
@@ -171,6 +173,7 @@ namespace Mono.Linker {
|
||||
_annotations = factory.CreateAnnotationStore (this);
|
||||
MarkingHelpers = factory.CreateMarkingHelpers (this);
|
||||
Tracer = factory.CreateTracer (this);
|
||||
StripResources = true;
|
||||
}
|
||||
|
||||
public TypeDefinition GetType (string fullName)
|
||||
|
||||
5
external/linker/linker/Mono.Linker.csproj
vendored
5
external/linker/linker/Mono.Linker.csproj
vendored
@@ -33,7 +33,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>False</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NATIVE_READER_SUPPORT</DefineConstants>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
@@ -41,7 +41,7 @@
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NATIVE_READER_SUPPORT</DefineConstants>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
@@ -81,6 +81,7 @@
|
||||
<Compile Include="Linker\AssemblyAction.cs" />
|
||||
<Compile Include="Linker\AssemblyInfo.cs" />
|
||||
<Compile Include="Linker\AssemblyResolver.cs" />
|
||||
<Compile Include="Linker\AssemblyUtilities.cs" />
|
||||
<Compile Include="Linker\DirectoryAssemblyResolver.cs" />
|
||||
<Compile Include="Linker\Driver.cs" />
|
||||
<Compile Include="Linker\LinkContext.cs" />
|
||||
|
||||
13
external/linker/linker/README.md
vendored
13
external/linker/linker/README.md
vendored
@@ -48,11 +48,16 @@ the info file.
|
||||
|
||||
You can specify what the linker should do exactly per assembly.
|
||||
|
||||
The linker can do 3 things:
|
||||
The linker can do the following things:
|
||||
|
||||
- skip them, and do nothing with them,
|
||||
- copy them to the output directory,
|
||||
- link them, to reduce their size.
|
||||
- Skip: skip them, and do nothing with them,
|
||||
- Copy: copy them to the output directory,
|
||||
- CopyUsed: copy used assemblies to the output directory,
|
||||
- Link: link them, to reduce their size,
|
||||
- Delete: remove them from the output,
|
||||
- Save: save them in memory without linking
|
||||
- AddBypassNGen: add BypassNGenAttribute to unmarked methods,
|
||||
- AddBypassNgenUsed: add BypassNGenAttribute to unmarked methods in used assemblies.
|
||||
|
||||
You can specify an action per assembly like this:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user