You've already forked linux-packaging-mono
Imported Upstream version 6.0.0.172
Former-commit-id: f3cc9b82f3e5bd8f0fd3ebc098f789556b44e9cd
This commit is contained in:
parent
8016999e4d
commit
64ac736ec5
@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Mono.Linker;
|
||||
using Mono.Linker.Steps;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ILLink.CustomSteps
|
||||
{
|
||||
public class ClearInitLocalsStep : BaseStep
|
||||
{
|
||||
HashSet<string> _assemblies;
|
||||
|
||||
protected override void Process ()
|
||||
{
|
||||
string parameterName = "ClearInitLocalsAssemblies";
|
||||
|
||||
if (Context.HasParameter (parameterName)) {
|
||||
string parameter = Context.GetParameter (parameterName);
|
||||
_assemblies = new HashSet<string> (parameter.Split(','), StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ProcessAssembly (AssemblyDefinition assembly)
|
||||
{
|
||||
if ((_assemblies != null) && (!_assemblies.Contains (assembly.Name.Name))) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
foreach (ModuleDefinition module in assembly.Modules) {
|
||||
foreach (TypeDefinition type in module.Types) {
|
||||
foreach (MethodDefinition method in type.Methods) {
|
||||
if (method.Body != null) {
|
||||
if (method.Body.InitLocals) {
|
||||
method.Body.InitLocals = false;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed && (Annotations.GetAction (assembly) == AssemblyAction.Copy))
|
||||
Annotations.SetAction (assembly, AssemblyAction.Save);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
<DefineConstants>$(DefineConstants);FEATURE_ILLINK</DefineConstants>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AssemblyName>ILLink.CustomSteps</AssemblyName>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{275C1D10-168A-4AC4-8F3E-AD969F580B9C}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="ClearInitLocals.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\linker\Mono.Linker.csproj">
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Debug' ">Configuration=illink_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Release' ">Configuration=illink_Release</SetConfiguration>
|
||||
<Project>{DD28E2B1-057B-4B4D-A04D-B2EBD9E76E46}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\cecil\Mono.Cecil.csproj">
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Debug' ">Configuration=netstandard_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Debug' And '$(TargetFramework)' == 'net46' ">Configuration=net_4_0_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Release' ">Configuration=netstandard_Release</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Release' And '$(TargetFramework)' == 'net46' ">Configuration=net_4_0_Release</SetConfiguration>
|
||||
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- The reference to the linker will cause Mono.Cecil.Pdb to be
|
||||
built in the wrong configuration unless we apply this
|
||||
workaround. -->
|
||||
<Target Name="SetCecilConfiguration"
|
||||
AfterTargets="AssignProjectConfiguration">
|
||||
<ItemGroup>
|
||||
<ProjectReferenceWithConfiguration Condition=" '%(Filename)%(Extension)' == 'Mono.Cecil.Pdb.csproj' ">
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' And '$(Configuration)' == 'illink_Debug' ">Configuration=net_4_0_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' And '$(Configuration)' == 'illink_Debug' ">Configuration=netstandard_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' And '$(Configuration)' == 'illink_Release' ">Configuration=net_4_0_Release</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' And '$(Configuration)' == 'illink_Release' ">Configuration=netstandard_Release</SetConfiguration>
|
||||
</ProjectReferenceWithConfiguration>
|
||||
<ProjectReferenceWithConfiguration Condition=" '%(Filename)%(Extension)' == 'Mono.Cecil.Mdb.csproj' ">
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' And '$(Configuration)' == 'illink_Debug' ">Configuration=net_4_0_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' And '$(Configuration)' == 'illink_Debug' ">Configuration=netstandard_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' And '$(Configuration)' == 'illink_Release' ">Configuration=net_4_0_Release</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' And '$(Configuration)' == 'illink_Release' ">Configuration=netstandard_Release</SetConfiguration>
|
||||
</ProjectReferenceWithConfiguration>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
class AdapterLogger : Mono.Linker.ILogger
|
||||
{
|
||||
private TaskLoggingHelper log;
|
||||
|
||||
public AdapterLogger (TaskLoggingHelper log)
|
||||
{
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public void LogMessage (Mono.Linker.MessageImportance importance, string message, params object[] values)
|
||||
{
|
||||
Microsoft.Build.Framework.MessageImportance msBuildImportance;
|
||||
switch (importance)
|
||||
{
|
||||
case Mono.Linker.MessageImportance.High:
|
||||
msBuildImportance = MessageImportance.High;
|
||||
break;
|
||||
case Mono.Linker.MessageImportance.Normal:
|
||||
msBuildImportance = MessageImportance.Normal;
|
||||
break;
|
||||
case Mono.Linker.MessageImportance.Low:
|
||||
msBuildImportance = MessageImportance.Low;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException ($"Unrecognized importance level {importance}", nameof(importance));
|
||||
}
|
||||
|
||||
log.LogMessageFromText (String.Format (message, values), msBuildImportance);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using Microsoft.Build.Utilities; // Task
|
||||
using Microsoft.Build.Framework; // ITaskItem
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class CheckEmbeddedRootDescriptor : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Path to the assembly.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem AssemblyPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This will be set to true if the assembly has an embedded root descriptor.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public bool HasEmbeddedRootDescriptor { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
ModuleDefinition module = ModuleDefinition.ReadModule (AssemblyPath.ItemSpec);
|
||||
string assemblyName = module.Assembly.Name.Name;
|
||||
string expectedResourceName = assemblyName + ".xml";
|
||||
HasEmbeddedRootDescriptor = false;
|
||||
foreach (var resource in module.Resources) {
|
||||
if (resource.Name == expectedResourceName) {
|
||||
HasEmbeddedRootDescriptor = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
struct AssemblySizes
|
||||
{
|
||||
public long unlinkedSize;
|
||||
public long linkedSize;
|
||||
}
|
||||
public class CompareAssemblySizes : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Paths to managed assemblies before linking.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] UnlinkedAssemblies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Paths to managed assemblies after linking. These
|
||||
/// assembly names should be a subset of the
|
||||
/// assembly names in UnlinkedAssemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] LinkedAssemblies { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
string[] unlinkedFiles = UnlinkedAssemblies.Select (i => i.ItemSpec).ToArray();
|
||||
string[] linkedFiles = LinkedAssemblies.Select (i => i.ItemSpec).ToArray();
|
||||
|
||||
Dictionary<string, AssemblySizes> sizes = new Dictionary<string, AssemblySizes> ();
|
||||
|
||||
long totalUnlinked = 0;
|
||||
foreach (string unlinkedFile in unlinkedFiles) {
|
||||
if (!Utils.IsManagedAssembly (unlinkedFile)) {
|
||||
continue;
|
||||
}
|
||||
string fileName = Path.GetFileName (unlinkedFile);
|
||||
AssemblySizes assemblySizes = new AssemblySizes ();
|
||||
assemblySizes.unlinkedSize = new System.IO.FileInfo (unlinkedFile).Length;
|
||||
totalUnlinked += assemblySizes.unlinkedSize;
|
||||
sizes[fileName] = assemblySizes;
|
||||
}
|
||||
|
||||
long totalLinked = 0;
|
||||
foreach (string linkedFile in linkedFiles) {
|
||||
if (!Utils.IsManagedAssembly (linkedFile)) {
|
||||
continue;
|
||||
}
|
||||
string fileName = Path.GetFileName (linkedFile);
|
||||
if (!sizes.ContainsKey(fileName)) {
|
||||
Console.WriteLine ($"{linkedFile} was specified as an assembly kept by the linker, but {fileName} was not specified as a managed publish assembly.");
|
||||
continue;
|
||||
}
|
||||
AssemblySizes assemblySizes = sizes[fileName];
|
||||
assemblySizes.linkedSize = new System.IO.FileInfo (linkedFile).Length;
|
||||
totalLinked += assemblySizes.linkedSize;
|
||||
sizes[fileName] = assemblySizes;
|
||||
}
|
||||
|
||||
Console.WriteLine ("{0, -60} {1,-20:N0} {2, -20:N0} {3, -10:P}",
|
||||
"",
|
||||
"Before linking (B)",
|
||||
"After linking (B)",
|
||||
"Size decrease");
|
||||
Console.WriteLine ("{0, -60} {1,-20:N0} {2, -20:N0} {3, -10:P}",
|
||||
"-----------",
|
||||
"-----------",
|
||||
"-----------",
|
||||
"-----------"
|
||||
);
|
||||
|
||||
Console.WriteLine ("{0, -60} {1,-20:N0} {2, -20:N0} {3, -10:P}",
|
||||
"Total size of assemblies",
|
||||
totalUnlinked,
|
||||
totalLinked,
|
||||
((double)totalUnlinked - (double)totalLinked) / (double)totalUnlinked);
|
||||
|
||||
Console.WriteLine ("{0, -60} {1,-20:N0} {2, -20:N0} {3, -10:P}",
|
||||
"-----------",
|
||||
"-----------",
|
||||
"-----------",
|
||||
"-----------"
|
||||
);
|
||||
|
||||
foreach (string assembly in sizes.Keys) {
|
||||
Console.WriteLine ("{0, -60} {1,-20:N0} {2, -20:N0} {3, -10:P}",
|
||||
assembly,
|
||||
sizes[assembly].unlinkedSize,
|
||||
sizes[assembly].linkedSize,
|
||||
(double)(sizes[assembly].unlinkedSize - sizes[assembly].linkedSize)/(double)sizes[assembly].unlinkedSize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static long DirSize(DirectoryInfo d)
|
||||
{
|
||||
long size = 0;
|
||||
// Add file sizes.
|
||||
FileInfo[] fis = d.GetFiles ();
|
||||
foreach (FileInfo fi in fis) {
|
||||
size += fi.Length;
|
||||
}
|
||||
// Add subdirectory sizes.
|
||||
DirectoryInfo[] dis = d.GetDirectories ();
|
||||
foreach (DirectoryInfo di in dis) {
|
||||
size += DirSize (di);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
using System.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class ComputeCrossgenedAssemblies : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Paths to assemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] Assemblies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This will contain the output list of crossgen-ed
|
||||
/// assemblies. Metadata from the input parameter
|
||||
/// Assemblies is preserved.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem[] CrossgenedAssemblies { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
CrossgenedAssemblies = Assemblies
|
||||
.Where(f => Utils.IsCrossgenedAssembly(f.ItemSpec))
|
||||
.ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
using System.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class ComputeManagedAssemblies : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Paths to assemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] Assemblies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This will contain the output list of managed
|
||||
/// assemblies. Metadata from the input parameter
|
||||
/// Assemblies is preserved.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem[] ManagedAssemblies { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
ManagedAssemblies = Assemblies
|
||||
.Where(f => Utils.IsManagedAssembly(f.ItemSpec))
|
||||
.ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class ComputeRemovedAssemblies : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// The paths to the inputs to the linker.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] InputAssemblies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The paths to the linked assemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] KeptAssemblies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of assemblies in the inputs that weren't kept by
|
||||
/// the linker. These items include the full metadata from
|
||||
/// the input assemblies, and only the filenames of the
|
||||
/// inputs are used to determine which assemblies were
|
||||
/// removed.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem[] RemovedAssemblies { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
var keptAssemblyNames = new HashSet<string> (
|
||||
KeptAssemblies.Select(i => Path.GetFileName(i.ItemSpec))
|
||||
);
|
||||
RemovedAssemblies = InputAssemblies.Where(i =>
|
||||
!keptAssemblyNames.Contains(Path.GetFileName(i.ItemSpec))
|
||||
).ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class CreateRootDescriptorFile : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Assembly names (without path or extension) to
|
||||
/// include in the generated root file.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] AssemblyNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the file to generate.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem RootDescriptorFilePath { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
var roots = new XElement("linker");
|
||||
foreach (var assemblyItem in AssemblyNames) {
|
||||
var assemblyName = assemblyItem.ItemSpec;
|
||||
roots.Add(new XElement("assembly",
|
||||
new XAttribute("fullname", assemblyName),
|
||||
new XElement("type",
|
||||
new XAttribute("fullname", "*"),
|
||||
new XAttribute("required", "true"))));
|
||||
}
|
||||
|
||||
var xdoc = new XDocument(roots);
|
||||
|
||||
XmlWriterSettings xws = new XmlWriterSettings();
|
||||
xws.Indent = true;
|
||||
xws.OmitXmlDeclaration = true;
|
||||
|
||||
using (XmlWriter xw = XmlWriter.Create(RootDescriptorFilePath.ItemSpec, xws)) {
|
||||
xdoc.Save(xw);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,349 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Build.Utilities; // Task
|
||||
using Microsoft.Build.Framework; // ITaskItem
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class CreateRuntimeRootILLinkDescriptorFile : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// The path to namespace.h.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem NamespaceFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to mscorlib.h.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem MscorlibFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to cortypeinfo.h.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem CortypeFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to rexcep.h.
|
||||
/// </summary>
|
||||
[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>
|
||||
[Required]
|
||||
public ITaskItem RuntimeRootDescriptorFilePath { get; set; }
|
||||
|
||||
class ClassMembers
|
||||
{
|
||||
public bool keepAllFields;
|
||||
public HashSet<string> methods;
|
||||
public HashSet<string> fields;
|
||||
}
|
||||
|
||||
Dictionary<string, string> namespaceDictionary = new Dictionary<string, string> ();
|
||||
Dictionary<string, string> classIdsToClassNames = new Dictionary<string, string> ();
|
||||
Dictionary<string, ClassMembers> classNamesToClassMembers = new Dictionary<string, ClassMembers> ();
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
var namespaceFilePath = NamespaceFilePath.ItemSpec;
|
||||
if (!File.Exists (namespaceFilePath)) {
|
||||
Log.LogError ("File " + namespaceFilePath + " doesn't exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var mscorlibFilePath = MscorlibFilePath.ItemSpec;
|
||||
if (!File.Exists (mscorlibFilePath)) {
|
||||
Log.LogError ("File " + mscorlibFilePath + " doesn't exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var cortypeFilePath = CortypeFilePath.ItemSpec;
|
||||
if (!File.Exists (cortypeFilePath)) {
|
||||
Log.LogError ("File " + cortypeFilePath + " doesn't exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var rexcepFilePath = RexcepFilePath.ItemSpec;
|
||||
if (!File.Exists (rexcepFilePath)) {
|
||||
Log.LogError ("File " + rexcepFilePath + " doesn't exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var iLLinkTrimXmlFilePath = ILLinkTrimXmlFilePath.ItemSpec;
|
||||
if (!File.Exists (iLLinkTrimXmlFilePath)) {
|
||||
Log.LogError ("File " + iLLinkTrimXmlFilePath + " doesn't exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ProcessNamespaces (namespaceFilePath);
|
||||
|
||||
ProcessMscorlib (mscorlibFilePath);
|
||||
|
||||
ProcessCoreTypes (cortypeFilePath);
|
||||
|
||||
ProcessExceptionTypes (rexcepFilePath);
|
||||
|
||||
OutputXml (iLLinkTrimXmlFilePath, RuntimeRootDescriptorFilePath.ItemSpec);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProcessNamespaces (string namespaceFile)
|
||||
{
|
||||
string [] namespaces = File.ReadAllLines (namespaceFile);
|
||||
|
||||
// Process definitions of the form
|
||||
// #define g_SystemNS "System"
|
||||
// from namespace.h
|
||||
foreach (string namespaceDef in namespaces) {
|
||||
if (namespaceDef.StartsWith ("#define")) {
|
||||
char [] separators = { '"', ' ' };
|
||||
string [] namespaceDefElements = namespaceDef.Split (separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
int startIndex = "g_".Length;
|
||||
// E.g., if namespaceDefElements [1] is "g_RuntimeNS", lhs is "Runtime".
|
||||
string lhs = namespaceDefElements [1].Substring (startIndex, namespaceDefElements [1].LastIndexOf ('N') - startIndex);
|
||||
if (namespaceDefElements.Length == 3) {
|
||||
// E.G., #define g_SystemNS "System"
|
||||
// "System" --> "System"
|
||||
namespaceDictionary [lhs] = namespaceDefElements [2];
|
||||
}
|
||||
else {
|
||||
// E.g., #define g_RuntimeNS g_SystemNS ".Runtime"
|
||||
// "Runtime" --> "System.Runtime"
|
||||
string prefix = namespaceDefElements [2].Substring (startIndex, namespaceDefElements [2].LastIndexOf ('N') - startIndex);
|
||||
namespaceDictionary [lhs] = namespaceDictionary [prefix] + namespaceDefElements [3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessMscorlib (string typeFile)
|
||||
{
|
||||
string [] types = File.ReadAllLines (typeFile);
|
||||
string classId = null;
|
||||
|
||||
foreach (string def in types) {
|
||||
string [] defElements = null;
|
||||
if (def.StartsWith ("DEFINE_") || def.StartsWith ("// DEFINE_")) {
|
||||
char [] separators = { ',', '(', ')', ' ', '/' };
|
||||
defElements = def.Split (separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
if (def.StartsWith ("DEFINE_CLASS(") || def.StartsWith ("// DEFINE_CLASS(")) {
|
||||
// E.g., DEFINE_CLASS(APP_DOMAIN, System, AppDomain)
|
||||
classId = defElements [1]; // APP_DOMAIN
|
||||
string classNamespace = defElements [2]; // System
|
||||
string className = defElements [3]; // AppDomain
|
||||
AddClass (classNamespace, className, classId);
|
||||
}
|
||||
else if (def.StartsWith ("DEFINE_CLASS_U(")) {
|
||||
// E.g., DEFINE_CLASS_U(System, AppDomain, AppDomainBaseObject)
|
||||
string classNamespace = defElements [1]; // System
|
||||
string className = defElements [2]; // AppDomain
|
||||
classId = defElements [3]; // AppDomainBaseObject
|
||||
// For these classes the sizes of managed and unmanaged classes and field offsets
|
||||
// are compared so we need to preserve all fields.
|
||||
const bool keepAllFields = true;
|
||||
AddClass (classNamespace, className, classId, keepAllFields);
|
||||
}
|
||||
else if (def.StartsWith ("DEFINE_FIELD(")) {
|
||||
// E.g., DEFINE_FIELD(ACCESS_VIOLATION_EXCEPTION, IP, _ip)
|
||||
classId = defElements [1]; // ACCESS_VIOLATION_EXCEPTION
|
||||
string fieldName = defElements [3]; // _ip
|
||||
AddField (fieldName, classId);
|
||||
}
|
||||
else if (def.StartsWith ("DEFINE_METHOD(")) {
|
||||
// E.g., DEFINE_METHOD(APP_DOMAIN, ON_ASSEMBLY_LOAD, OnAssemblyLoadEvent, IM_Assembly_RetVoid)
|
||||
string methodName = defElements [3]; // OnAssemblyLoadEvent
|
||||
classId = defElements [1]; // APP_DOMAIN
|
||||
AddMethod (methodName, classId);
|
||||
}
|
||||
else if (def.StartsWith ("DEFINE_PROPERTY(") || def.StartsWith ("DEFINE_STATIC_PROPERTY(")) {
|
||||
// E.g., DEFINE_PROPERTY(ARRAY, LENGTH, Length, Int)
|
||||
// or DEFINE_STATIC_PROPERTY(THREAD, CURRENT_THREAD, CurrentThread, Thread)
|
||||
string propertyName = defElements [3]; // Length or CurrentThread
|
||||
classId = defElements [1]; // ARRAY or THREAD
|
||||
AddMethod ("get_" + propertyName, classId);
|
||||
}
|
||||
else if (def.StartsWith ("DEFINE_SET_PROPERTY(")) {
|
||||
// E.g., DEFINE_SET_PROPERTY(THREAD, UI_CULTURE, CurrentUICulture, CultureInfo)
|
||||
string propertyName = defElements [3]; // CurrentUICulture
|
||||
classId = defElements [1]; // THREAD
|
||||
AddMethod ("get_" + propertyName, classId);
|
||||
AddMethod ("set_" + propertyName, classId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessCoreTypes (string corTypeFile)
|
||||
{
|
||||
string [] corTypes = File.ReadAllLines (corTypeFile);
|
||||
|
||||
foreach (string def in corTypes) {
|
||||
// E.g., TYPEINFO(ELEMENT_TYPE_VOID, "System", "Void", 0, TYPE_GC_NONE, false, true, false, false, false) // 0x01
|
||||
if (def.StartsWith ("TYPEINFO(")) {
|
||||
char [] separators = { ',', '(', ')', '"', ' ' };
|
||||
string [] defElements = def.Split (separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
string classId = null;
|
||||
string classNamespace = defElements [2]; // System
|
||||
string className = defElements [3]; // Void
|
||||
AddClass (classNamespace, className, classId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessExceptionTypes (string excTypeFile)
|
||||
{
|
||||
string [] excTypes = File.ReadAllLines (excTypeFile);
|
||||
|
||||
foreach (string def in excTypes) {
|
||||
// E.g., DEFINE_EXCEPTION(g_InteropNS, MarshalDirectiveException, false, COR_E_MARSHALDIRECTIVE)
|
||||
if (def.StartsWith ("DEFINE_EXCEPTION(")) {
|
||||
char [] separators = { ',', '(', ')', ' ' };
|
||||
string [] defElements = def.Split (separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
string classId = null;
|
||||
string classNamespace = defElements [1]; // g_InteropNS
|
||||
string className = defElements [2]; // MarshalDirectiveException
|
||||
AddClass (classNamespace, className, classId);
|
||||
AddMethod (".ctor", classId, classNamespace, className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OutputXml (string iLLinkTrimXmlFilePath, string outputFileName)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument ();
|
||||
doc.Load (iLLinkTrimXmlFilePath);
|
||||
XmlNode linkerNode = doc ["linker"];
|
||||
XmlNode assemblyNode = linkerNode ["assembly"];
|
||||
|
||||
foreach (string typeName in classNamesToClassMembers.Keys) {
|
||||
XmlNode typeNode = doc.CreateElement ("type");
|
||||
XmlAttribute typeFullName = doc.CreateAttribute ("fullname");
|
||||
typeFullName.Value = typeName;
|
||||
typeNode.Attributes.Append (typeFullName);
|
||||
|
||||
ClassMembers members = classNamesToClassMembers [typeName];
|
||||
|
||||
// We need to keep everyting in System.Runtime.InteropServices.WindowsRuntime and
|
||||
// System.Threading.Volatile.
|
||||
if (!typeName.StartsWith ("System.Runtime.InteropServices.WindowsRuntime") &&
|
||||
!typeName.StartsWith ("System.Threading.Volatile")) {
|
||||
if (members.keepAllFields) {
|
||||
XmlAttribute preserve = doc.CreateAttribute ("preserve");
|
||||
preserve.Value = "fields";
|
||||
typeNode.Attributes.Append (preserve);
|
||||
}
|
||||
else if ((members.fields == null) && (members.methods == null)) {
|
||||
XmlAttribute preserve = doc.CreateAttribute ("preserve");
|
||||
preserve.Value = "nothing";
|
||||
typeNode.Attributes.Append (preserve);
|
||||
}
|
||||
|
||||
if (!members.keepAllFields && (members.fields != null)) {
|
||||
foreach (string field in members.fields) {
|
||||
XmlNode fieldNode = doc.CreateElement ("field");
|
||||
XmlAttribute fieldName = doc.CreateAttribute ("name");
|
||||
fieldName.Value = field;
|
||||
fieldNode.Attributes.Append (fieldName);
|
||||
typeNode.AppendChild (fieldNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (members.methods != null) {
|
||||
foreach (string method in members.methods) {
|
||||
XmlNode methodNode = doc.CreateElement ("method");
|
||||
XmlAttribute methodName = doc.CreateAttribute ("name");
|
||||
methodName.Value = method;
|
||||
methodNode.Attributes.Append (methodName);
|
||||
typeNode.AppendChild (methodNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
assemblyNode.AppendChild (typeNode);
|
||||
}
|
||||
doc.Save (outputFileName);
|
||||
}
|
||||
|
||||
void AddClass (string classNamespace, string className, string classId, bool keepAllFields = false)
|
||||
{
|
||||
string fullClassName = GetFullClassName (classNamespace, className);
|
||||
if (fullClassName != null) {
|
||||
if ((classId != null) && (classId != "NoClass")) {
|
||||
classIdsToClassNames [classId] = fullClassName;
|
||||
}
|
||||
ClassMembers members;
|
||||
if (!classNamesToClassMembers.TryGetValue (fullClassName, out members)) {
|
||||
members = new ClassMembers ();
|
||||
classNamesToClassMembers [fullClassName] = members;
|
||||
}
|
||||
members.keepAllFields |= keepAllFields;
|
||||
}
|
||||
}
|
||||
|
||||
void AddField (string fieldName, string classId)
|
||||
{
|
||||
string className = classIdsToClassNames [classId];
|
||||
|
||||
ClassMembers members = classNamesToClassMembers [className];
|
||||
|
||||
if (members.fields == null) {
|
||||
members.fields = new HashSet<string> ();
|
||||
}
|
||||
members.fields.Add (fieldName);
|
||||
}
|
||||
|
||||
void AddMethod (string methodName, string classId, string classNamespace = null, string className = null)
|
||||
{
|
||||
string fullClassName;
|
||||
if (classId != null) {
|
||||
fullClassName = classIdsToClassNames [classId];
|
||||
}
|
||||
else {
|
||||
fullClassName = GetFullClassName (classNamespace, 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class FilterByMetadata : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Items to filter.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of metadata to filter on.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public String MetadataName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of metadata values to include.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] MetadataValues { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Filtered items: the input items for which the
|
||||
/// specified metadata was one of the allowed
|
||||
/// values.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem[] FilteredItems { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
var metadataValues = new HashSet<string>(MetadataValues.Select(v => v.ItemSpec));
|
||||
FilteredItems = Items
|
||||
.Where(i => metadataValues.Contains(i.GetMetadata(MetadataName)))
|
||||
.ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
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,91 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class FindNativeDeps : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// The managed assemblies to scan for references to native
|
||||
/// dependencies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem [] ManagedAssemblyPaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of native dependencies to keep even if they
|
||||
/// aren't found to be referenced by a managed assembly.
|
||||
/// </summary>
|
||||
public ITaskItem [] NativeDepsToKeep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The paths to the available native dependencies. We
|
||||
/// expect that all references found point to existing
|
||||
/// native files.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem [] NativeDepsPaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of native dependencies to keep, including those
|
||||
/// found in the analysis, and those explicitly marked keep
|
||||
/// by NativeDepsToKeep. This includes metadata from the
|
||||
/// input NativeDepsToKeep.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem [] KeptNativeDepsPaths { get; set; }
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
var allNativeNames = new HashSet<string> ();
|
||||
foreach (var nativeDep in NativeDepsPaths)
|
||||
allNativeNames.Add (Path.GetFileName (nativeDep.ItemSpec));
|
||||
var keptNativeNames = new HashSet<string> ();
|
||||
foreach (var nativeDep in NativeDepsToKeep)
|
||||
keptNativeNames.Add (Path.GetFileName (nativeDep.ItemSpec));
|
||||
|
||||
var managedAssemblies = ManagedAssemblyPaths.Select (i => i.ItemSpec).ToArray ();
|
||||
foreach (string managedAssembly in managedAssemblies) {
|
||||
using (var peReader = new PEReader(new FileStream (managedAssembly, FileMode.Open, FileAccess.Read, FileShare.Read))) {
|
||||
if (peReader.HasMetadata) {
|
||||
var reader = peReader.GetMetadataReader ();
|
||||
for (int i = 1, count = reader.GetTableRowCount (TableIndex.ModuleRef); i <= count; i++) {
|
||||
var moduleRef = reader.GetModuleReference (MetadataTokens.ModuleReferenceHandle (i));
|
||||
var moduleName = reader.GetString (moduleRef.Name);
|
||||
|
||||
var moduleRefCandidates = new [] { moduleName, moduleName + ".dll", moduleName + ".so", moduleName + ".dylib" };
|
||||
|
||||
bool foundModuleRef = false;
|
||||
foreach (string moduleRefCandidate in moduleRefCandidates) {
|
||||
if (allNativeNames.Contains (moduleRefCandidate)) {
|
||||
keptNativeNames.Add (moduleRefCandidate);
|
||||
foundModuleRef = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundModuleRef)
|
||||
Log.LogMessage("unsatisfied DLLImport: " + managedAssembly + " -> " + moduleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var keptNativeDeps = new List<ITaskItem> ();
|
||||
foreach (var nativeDep in NativeDepsPaths) {
|
||||
var fileName = Path.GetFileName (nativeDep.ItemSpec);
|
||||
if (keptNativeNames.Contains (fileName))
|
||||
keptNativeDeps.Add (nativeDep);
|
||||
}
|
||||
|
||||
KeptNativeDepsPaths = keptNativeDeps.ToArray ();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Microsoft.NET.Build.Tasks; // LockFileCache
|
||||
using NuGet.Frameworks; // NuGetFramework.Parse(targetframework)
|
||||
using NuGet.ProjectModel; // LockFileTargetLibrary
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class GetRuntimeLibraries : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Path to the assets file.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem AssetsFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Target framework for which to get the platform
|
||||
/// libraries.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string TargetFramework { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Runtime identifier for which to get the platform
|
||||
/// libraries.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string RuntimeIdentifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the library to consider the "platform"
|
||||
/// library.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string[] PackageNames { get; set; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem[] RuntimeLibraries { get; private set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
var lockFile = new LockFileCache(BuildEngine4).GetLockFile(AssetsFilePath.ItemSpec);
|
||||
var lockFileTarget = lockFile.GetTarget(NuGetFramework.Parse(TargetFramework), RuntimeIdentifier);
|
||||
|
||||
if (lockFileTarget == null) {
|
||||
var targetString = string.IsNullOrEmpty(RuntimeIdentifier) ? TargetFramework : $"{TargetFramework}/{RuntimeIdentifier}";
|
||||
|
||||
throw new Exception($"Missing target section {targetString} from assets file {AssetsFilePath}. Ensure you have restored this project previously.");
|
||||
}
|
||||
|
||||
Dictionary<string, LockFileTargetLibrary> packages = new Dictionary<string, LockFileTargetLibrary>(lockFileTarget.Libraries.Count, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var lib in lockFileTarget.Libraries) {
|
||||
packages.Add(lib.Name, lib);
|
||||
}
|
||||
|
||||
HashSet<string> packageNames = new HashSet<string>(PackageNames);
|
||||
var rootPackages = lockFileTarget.Libraries.Where(l => packageNames.Contains(l.Name));
|
||||
|
||||
var packageQueue = new Queue<LockFileTargetLibrary>(rootPackages);
|
||||
|
||||
var libraries = new List<string>();
|
||||
while (packageQueue.Count > 0) {
|
||||
var package = packageQueue.Dequeue();
|
||||
foreach (var lib in package.RuntimeAssemblies) {
|
||||
libraries.Add(lib.ToString());
|
||||
}
|
||||
|
||||
foreach (var dep in package.Dependencies.Select(d => d.Id)) {
|
||||
packageQueue.Enqueue(packages[dep]);
|
||||
}
|
||||
}
|
||||
|
||||
RuntimeLibraries = libraries.Select(l => new TaskItem(l)).ToArray();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,229 +0,0 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<PropertyGroup>
|
||||
<CrossGenDuringPublish Condition=" '$(CrossGenDuringPublish)' == '' And '$(RuntimeIdentifier)' != '' And '$(LinkDuringPublish)' == 'true' ">true</CrossGenDuringPublish>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<IntermediateOptimizedDirName Condition=" '$(IntermediateOptimizedDirName)' == '' ">optimized</IntermediateOptimizedDirName>
|
||||
<IntermediateOptimizedDir Condition=" '$(IntermediateOptimizedDir)' == '' ">$(IntermediateOutputPath)$(IntermediateOptimizedDirName)</IntermediateOptimizedDir>
|
||||
<IntermediateCrossGenDirName Condition=" '$(IntermediateCrossGenDirName)' == '' ">crossgen</IntermediateCrossGenDirName>
|
||||
<IntermediateCrossGenDir Condition=" '$(IntermediateCrossGenDir)' == '' ">$(IntermediateOutputPath)$(IntermediateCrossGenDirName)</IntermediateCrossGenDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ComputeCrossGenFilesToPublishAfter Condition=" '$(LinkDuringPublish)' == 'true' ">ComputeLinkedFilesToPublish</ComputeCrossGenFilesToPublishAfter>
|
||||
<ComputeCrossGenFilesToPublishBefore Condition=" '$(LinkDuringPublish)' != 'true' ">ComputeFilesToPublish</ComputeCrossGenFilesToPublishBefore>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Rewrite inputs to ComputeFilesToPublish, so that crossgen'd
|
||||
files get published instead of the pre-crossgen assemblies. -->
|
||||
<Target Name="ComputeCrossGenFilesToPublish"
|
||||
BeforeTargets="$(ComputeCrossGenFilesToPublishBefore)"
|
||||
AfterTargets="$(ComputeCrossGenFilesToPublishAfter)"
|
||||
Condition=" '$(CrossGenDuringPublish)' == 'true' "
|
||||
DependsOnTargets="_CrossGenForPublish">
|
||||
|
||||
<!-- Rewrite ResolvedAssembliesToPublish, preserving metadata. -->
|
||||
<ItemGroup>
|
||||
<_CrossGenResolvedAssembliesToPublishCandidates Include="@(ResolvedAssembliesToPublish->'$(IntermediateOptimizedDir)/%(Filename)%(Extension)')" />
|
||||
<_CrossGenResolvedAssembliesToPublish Include="@(_CrossGenResolvedAssembliesToPublishCandidates)" Condition="Exists('%(Identity)')" />
|
||||
|
||||
<ResolvedAssembliesToPublish Remove="@(FilesToCrossGen)" />
|
||||
<ResolvedAssembliesToPublish Include="@(_CrossGenResolvedAssembliesToPublish)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Rewrite IntermediateAssembly, preserving metadata. -->
|
||||
<ItemGroup>
|
||||
<_CrossGenIntermediateAssemblyCandidates Include="@(IntermediateAssembly->'$(IntermediateOptimizedDir)/%(Filename)%(Extension)')" />
|
||||
<_CrossGenIntermediateAssembly Include="@(_CrossGenIntermediateAssemblyCandidates)" Condition="Exists('%(Identity)')" />
|
||||
<IntermediateAssembly Remove="@(FilesToCrossGen)" />
|
||||
<IntermediateAssembly Include="@(_CrossGenIntermediateAssembly)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<!-- The target that runs crossgen on all input assemblies. We could
|
||||
probably also reuse _RunCrossgen, but this gets its inputs from
|
||||
ResolvedFileToPublish, so we would need to run crossgen after
|
||||
ComputeFilesToPublish. -->
|
||||
<Target Name="_CrossGenForPublish"
|
||||
DependsOnTargets="PrepOptimizer;_ComputeCrossGenInputs">
|
||||
|
||||
<MakeDir Directories="$(IntermediateOptimizedDir)" />
|
||||
|
||||
<PropertyGroup>
|
||||
<_CrossGenPlatformAssemblies>@(_CrossGenPlatformAssemblies)</_CrossGenPlatformAssemblies>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<CrossGenInvocations Include="$(MSBuildProjectFullPath)">
|
||||
<Properties>
|
||||
CrossGenExe=$(Crossgen);
|
||||
CrossGenInput=%(FilesToCrossGen.FullPath);
|
||||
CrossGenOutput=$(IntermediateOptimizedDir)/%(Filename)%(Extension);
|
||||
CrossGenPlatformAssemblies=$(_CrossGenPlatformAssemblies)
|
||||
</Properties>
|
||||
</CrossGenInvocations>
|
||||
</ItemGroup>
|
||||
|
||||
<MSBuild Projects="@(CrossGenInvocations)"
|
||||
Targets="RunCrossGenForPublish" />
|
||||
|
||||
</Target>
|
||||
|
||||
<!-- Workarounds for SDK issues around the interdependency between
|
||||
ComposeStore targets and CrossGen targets. These let us reuse
|
||||
PrepOptimizer from the SDK to obtain a crossgen executable for
|
||||
the target RID. -->
|
||||
|
||||
<!-- _RestoreCrossgen (a dependency of PrepOptimizer) requires _TFM
|
||||
to be set, but it is only set in an unrelated target called
|
||||
during ComposeStore (PrepareForComposeStore). -->
|
||||
<Target Name="_SetTFMForCrossGenRestore"
|
||||
BeforeTargets="_RestoreCrossgen"
|
||||
Condition=" '$(CrossGenDuringPublish)' == 'true' ">
|
||||
<PropertyGroup>
|
||||
<_TFM Condition=" '$(_TFM)' == '' ">$(TargetFramework)</_TFM>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<!-- _RestoreCrossgen also requires _CrossProjAssetsFile to be
|
||||
set. This path is computed from ComposeWorkingDir in the target
|
||||
_GetCrossgenProps, but ComposeWorkingDir is set only in
|
||||
store-related targets. We hook into _GetCrossgenProps to
|
||||
specify where to restore crossgen. -->
|
||||
<Target Name="_SetComposeWorkingDirForCrossGenRestore"
|
||||
AfterTargets="_GetCrossgenProps"
|
||||
Condition=" '$(CrossGenDuringPublish)' == 'true' ">
|
||||
<PropertyGroup>
|
||||
<_CrossProjFileDir>$([System.IO.Path]::GetFullPath($(IntermediateCrossGenDir)))</_CrossProjFileDir>
|
||||
<_NetCoreRefDir>$([System.IO.Path]::Combine($(_CrossProjFileDir), "netcoreapp"))</_NetCoreRefDir>
|
||||
<_CrossProjAssetsFile>$([System.IO.Path]::Combine($(_CrossProjFileDir), project.assets.json))</_CrossProjAssetsFile>
|
||||
</PropertyGroup>
|
||||
<MakeDir Directories="$(_CrossProjFileDir)" />
|
||||
</Target>
|
||||
|
||||
<!-- PrepforRestoreForComposeStore (a dependency of
|
||||
_RestoreCrossgen) sets BaseIntermediateOutputPath and
|
||||
ProjectAssetsFile to the compose working directory. We don't
|
||||
want this because we are not composing a package store, so we
|
||||
save and restore these properties. -->
|
||||
<Target Name="_SavePropsModifiedByPrepforRestoreForComposeStore"
|
||||
BeforeTargets="PrepforRestoreForComposeStore"
|
||||
Condition=" '$(CrossGenDuringPublish)' == 'true' ">
|
||||
<PropertyGroup>
|
||||
<_SavedBaseIntermediateOutputPath>$(BaseIntermediateOutputPath)</_SavedBaseIntermediateOutputPath>
|
||||
<_SavedProjectAssetsFile>$(ProjectAssetsFile)</_SavedProjectAssetsFile>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
<Target Name="_RestorePropsModifiedByPrepforRestoreForComposeStore"
|
||||
AfterTargets="PrepforRestoreForComposeStore">
|
||||
<PropertyGroup>
|
||||
<BaseIntermediateOutputPath>$(_SavedBaseIntermediateOutputPath)</BaseIntermediateOutputPath>
|
||||
<ProjectAssetsFile>$(_SavedProjectAssetsFile)</ProjectAssetsFile>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<!-- Run crossgen on a single input assembly. -->
|
||||
<Target Name="RunCrossGenForPublish"
|
||||
Inputs="$(CrossGenInput);$(CrossGenPlatformAssemblies)"
|
||||
Outputs="$(CrossGenOutput)">
|
||||
|
||||
<!-- The property CrossGenPlatformAssemblies must be
|
||||
semicolon-delimited for incremental build to work correctly,
|
||||
but the directory paths have to be passed with
|
||||
platform-specific path separators in the crossgen command.
|
||||
-->
|
||||
<ItemGroup>
|
||||
<_CrossGenPlatformAssemblies Include="$(CrossGenPlatformAssemblies)" />
|
||||
<__CrossGenPlatformAssembliesPaths Include="@(_CrossGenPlatformAssemblies->'%(RootDir)%(Directory)')" />
|
||||
<_CrossGenPlatformAssembliesPaths Include="@(__CrossGenPlatformAssembliesPaths->Distinct())" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<_PathSeparator>$([System.IO.Path]::PathSeparator)</_PathSeparator>
|
||||
<_CrossGenPlatformAssembliesPaths>@(_CrossGenPlatformAssembliesPaths, '$(_PathSeparator)')</_CrossGenPlatformAssembliesPaths>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CrossGenCommand>$(CrossGenExe) -readytorun -in $(CrossGenInput) -out $(CrossGenOutput) -platform_assemblies_paths $(_CrossGenPlatformAssembliesPaths)</CrossGenCommand>
|
||||
</PropertyGroup>
|
||||
|
||||
<Message Text="$(CrossGenCommand)" />
|
||||
<Exec Command="$(CrossGenCommand)" />
|
||||
|
||||
</Target>
|
||||
|
||||
<Target Name="_ComputeCrossGenInputs"
|
||||
DependsOnTargets="_ComputeCrossGenPlatformAssemblies;_ComputeFilesToCrossGen" />
|
||||
|
||||
<!-- Compute the platform assembly paths, a parameter to crossgen
|
||||
that lets it find dependencies of the input file. This needs to
|
||||
include the path to the input file and its dependency closure,
|
||||
including System.Private.CoreLib. -->
|
||||
<Target Name="_ComputeCrossGenPlatformAssemblies"
|
||||
DependsOnTargets="_ComputeManagedResolvedAssembliesForCrossGen">
|
||||
|
||||
<ItemGroup>
|
||||
<_CrossGenPlatformAssemblies Include="@(_ManagedResolvedAssembliesForCrossGen)" />
|
||||
<_CrossGenPlatformAssemblies Include="@(IntermediateAssembly)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<!-- _ManagedResolvedAssembliesForCrossGen includes the app's
|
||||
managed dependency closure, including System.Private.CoreLib,
|
||||
but not the app itself or resource assemblies. -->
|
||||
<Target Name="_ComputeManagedResolvedAssembliesForCrossGen">
|
||||
<ComputeManagedAssemblies Assemblies="@(ResolvedAssembliesToPublish)">
|
||||
<Output TaskParameter="ManagedAssemblies" ItemName="_ManagedResolvedAssembliesForCrossGen" />
|
||||
</ComputeManagedAssemblies>
|
||||
|
||||
<ItemGroup>
|
||||
<_ManagedResolvedAssembliesForCrossGen Remove="@(_ManagedResolvedAssembliesForCrossGen->WithMetadataValue('AssetType', 'resources'))" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<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 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"
|
||||
DependsOnTargets="_ComputeManagedResolvedAssembliesForCrossGen;_ComputePlatformLibraries"
|
||||
Condition=" '@(FilesToCrossGen->Count())' == '0' ">
|
||||
|
||||
<FilterByMetadata Items="@(_ManagedResolvedAssembliesForCrossGen)"
|
||||
MetadataName="Filename"
|
||||
MetadataValues="@(PlatformLibraries->'%(Filename)')">
|
||||
<Output TaskParameter="FilteredItems" ItemName="_PlatformLibrariesForCrossGen" />
|
||||
</FilterByMetadata>
|
||||
|
||||
<ItemGroup>
|
||||
<FilesToCrossGen Include="@(IntermediateAssembly)" />
|
||||
<FilesToCrossGen Include="@(_PlatformLibrariesForCrossGen)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="ComputeCrossgenedAssemblies" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="_ComputeFilesToCrossGen"
|
||||
DependsOnTargets="_ComputeDefaultFilesToCrossGen">
|
||||
|
||||
<ComputeCrossgenedAssemblies Assemblies="@(FilesToCrossGen)">
|
||||
<Output TaskParameter="CrossgenedAssemblies" ItemName="_CrossgenedFiles" />
|
||||
</ComputeCrossgenedAssemblies>
|
||||
|
||||
<!-- Don't try to run crossgen on assemblies that are already
|
||||
crossgen'd. -->
|
||||
<ItemGroup>
|
||||
<FilesToCrossGen Remove="@(_CrossgenedFiles)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Message Text="files to crossgen: @(FilesToCrossGen)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
@ -1,225 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>0.1.5-preview</VersionPrefix>
|
||||
<TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<BaseOutputPath>../bin/</BaseOutputPath>
|
||||
<PackageOutputPath>$(BaseOutputPath)nupkgs</PackageOutputPath>
|
||||
|
||||
<!-- IsTool true causes the build output to be placed in the
|
||||
package's tools folder. This allows projects to reference the
|
||||
tasks package without including the tasks dll in their
|
||||
output. -->
|
||||
<!-- TODO: This has no effect currently, because we are using a
|
||||
custom .nuspec with the tools path hardcoded. Uncomment this
|
||||
once we are able to remove the custom .nuspec workaround. -->
|
||||
<!-- <IsTool>true</IsTool> -->
|
||||
|
||||
<!-- We want to package the tasks package together with its
|
||||
package dependencies, the linker, and the linker's
|
||||
dependencies, in order to prevent projects that consume the
|
||||
tasks package from pulling in the linker. To do this, we need
|
||||
to include project references and package references in the
|
||||
package, and prevent any of these references from being
|
||||
marked as dependencies in the tasks package.
|
||||
|
||||
To include the linker in the package, we want to package the
|
||||
tasks project together with its project references. This is
|
||||
not supported by the pack targets
|
||||
(https://github.com/dotnet/cli/issues/1290,
|
||||
https://github.com/dotnet/cli/issues/3959), so we work around
|
||||
this by explicitly setting the package path to include the
|
||||
build output. Using the publish directory will also cause
|
||||
dependencies from package references to be packaged.
|
||||
|
||||
To prevent the linker from being marked as a package
|
||||
dependency, we can't use PrivateAssets="All", because this
|
||||
removes it from the publish output as well, due to an issue
|
||||
in the SDK (https://github.com/dotnet/sdk/issues/952). To
|
||||
work around this, we use a custom .nuspec that doesn't
|
||||
declare any dependencies. This also prevents package
|
||||
references from being marked as dependencies. -->
|
||||
<!-- TODO: Remove the custom .nuspec once the P2P PrivateAssets
|
||||
issue is fixed. -->
|
||||
<NuspecFileName>ILLink.Tasks.nuspec</NuspecFileName>
|
||||
<NuspecFile>$(BaseOutputPath)$(NuspecFileName)</NuspecFile>
|
||||
<NuspecProperties>id=$(AssemblyName);authors=$(AssemblyName);description=linker tasks;</NuspecProperties>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- TODO: Remove this workaround once we're able to avoid using a
|
||||
custom .nuspec. We may still need a similar workaround to
|
||||
dynamically include the publish output in the package contents.
|
||||
|
||||
We can't specify the output path to package in the static
|
||||
nuspec properties, because the project's output path gets set
|
||||
at a later point. To work around this, we add the output path
|
||||
to the nuspec properties dynamically as part of the pack
|
||||
target. We use the same workaround to set the version in the
|
||||
.nuspec file.
|
||||
|
||||
We can't insert this into the pack target by modifying
|
||||
PackDependsOn, since GenerateNuspec is always prepended to
|
||||
PackDependsOn, which would cause the nuspec file to be
|
||||
generated before our extra properties are added.
|
||||
|
||||
Instead, we use GenerateNuspecDependsOn. We could probably also
|
||||
use BeforeTargets="GenerateNuspec". -->
|
||||
<PropertyGroup>
|
||||
<GenerateNuspecDependsOn>SetDynamicNuspecProperties;BinPlacePackageDeps;$(GenerateNuspecDependsOn)</GenerateNuspecDependsOn>
|
||||
</PropertyGroup>
|
||||
<Target Name="SetDynamicNuspecProperties"
|
||||
DependsOnTargets="LayoutPackage">
|
||||
<PropertyGroup>
|
||||
<NuspecProperties>$(NuspecProperties)version=$(Version);</NuspecProperties>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<!-- This target is necessary because the .nuspec includes the full
|
||||
path of the selected dlls in the package layout. We want the
|
||||
assets to be included in the package without the bin prefix, so
|
||||
we place the .nuspec and the included targets alongside the
|
||||
publish directories in the bin directory. -->
|
||||
<Target Name="BinPlacePackageDeps">
|
||||
<Copy SourceFiles="$(NuspecFileName)" DestinationFolder="$(BaseOutputPath)" />
|
||||
<Copy SourceFiles="ILLink.Tasks.targets" DestinationFolder="$(BaseOutputPath)" />
|
||||
<Copy SourceFiles="ILLink.CrossGen.targets" DestinationFolder="$(BaseOutputPath)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="LayoutPackage">
|
||||
<ItemGroup>
|
||||
<TFMsToPublish Include="$(TargetFrameworks)" />
|
||||
<ProjectsToPublish Include="$(MSBuildProjectFile)">
|
||||
<AdditionalProperties>TargetFramework=%(TFMsToPublish.Identity);PublishDir=$(BaseOutputPath)%(TFMsToPublish.Identity)</AdditionalProperties>
|
||||
</ProjectsToPublish>
|
||||
</ItemGroup>
|
||||
<MSBuild Projects="@(ProjectsToPublish)" Targets="Publish" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="AdapterLogger.cs" />
|
||||
<Compile Include="LinkTask.cs" />
|
||||
<Compile Include="CompareSizes.cs" />
|
||||
<Compile Include="ComputeManagedAssemblies.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" />
|
||||
<Compile Include="FindNativeDeps.cs" />
|
||||
<Compile Include="ComputeRemovedAssemblies.cs" />
|
||||
<Compile Include="CheckEmbeddedRootDescriptor.cs" />
|
||||
<Compile Include="SetAssemblyActions.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- TODO: Uncomment this once we can avoid hard-coding this in a
|
||||
custom .nuspec. -->
|
||||
<!-- Targets under the build directory of the package automatically
|
||||
get included in the consumer's build.
|
||||
-->
|
||||
<!--
|
||||
<ItemGroup>
|
||||
<Content Include="ILLink.Tasks.targets">
|
||||
<PackagePath>build</PackagePath>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
-->
|
||||
|
||||
<!-- TODO: Use this to set the package contents once we can avoid
|
||||
using a custom .nuspec. -->
|
||||
<!-- We can't glob everything in the output path for two reasons:
|
||||
|
||||
1. Content gets expanded before "Build" is called during
|
||||
"Pack". We could work around this by creating our own target to
|
||||
call build and then pack, but it would be nice to avoid
|
||||
changing the build/package pipeline.
|
||||
|
||||
2. We'll try to include the tasks dll twice. This only causes a
|
||||
warning during pack, but should be avoided.
|
||||
|
||||
<Content Include="$(OutputPath)*.dll;$(OutputPath)*.json">
|
||||
<PackagePath>tools</PackagePath>
|
||||
</Content>
|
||||
|
||||
There may also be a better ItemGroup to use than
|
||||
Content. Content semantics mean to output with the build, which
|
||||
isn't our goal. Instead, we want to include these dependencies
|
||||
in the package without necessarily including them in the build.
|
||||
-->
|
||||
<!--
|
||||
<ItemGroup>
|
||||
<Content Include="$(OutputPath)illink.dll;$(OutputPath)Mono.Cecil.dll">
|
||||
<PackagePath>tools</PackagePath>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
-->
|
||||
|
||||
<ItemGroup>
|
||||
<!-- TODO: Once https://github.com/dotnet/sdk/issues/952 is fixed,
|
||||
use PrivateAssets="All" to prevent this project reference
|
||||
from being marked as a dependency of the tasks package (while
|
||||
still including it in the publish output). -->
|
||||
<ProjectReference Include="../../../linker/Mono.Linker.csproj">
|
||||
<!-- SetConfiguration isn't required when the configuration is
|
||||
already set in the solution. Setting it here allows packing
|
||||
the tasks csproj on its own. This lets us avoid some of the
|
||||
strange behavior that shows up when trying to build from a
|
||||
.sln file.
|
||||
|
||||
There is a nuget bug that prevents this from working
|
||||
properly during restore
|
||||
(https://github.com/NuGet/Home/issues/4873). For the
|
||||
moment, the linker has a workaround for this issue.
|
||||
|
||||
However, this still won't work properly because the build
|
||||
target doesn't propagate this information properly either -
|
||||
this is probably another bug. Building from the .csproj
|
||||
would cause cecil to be built twice, once through the
|
||||
linker with the netstandard configuration and once directly
|
||||
from the tasks project in the default configuration info
|
||||
(because some target gets its reference information from
|
||||
the lock file, which doesn't have configuration info).
|
||||
-->
|
||||
<SetConfiguration>Configuration=illink_$(Configuration)</SetConfiguration>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../../../cecil/Mono.Cecil.csproj" />
|
||||
|
||||
<ProjectReference Include="../ILLink.CustomSteps/ILLink.CustomSteps.csproj">
|
||||
<SetConfiguration>Configuration=illink_$(Configuration)</SetConfiguration>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Workaround for the SetConfiguration issue described above. -->
|
||||
<Target Name="SetCecilConfiguration"
|
||||
AfterTargets="AssignProjectConfiguration">
|
||||
<ItemGroup>
|
||||
<ProjectReferenceWithConfiguration Condition=" '%(Filename)%(Extension)' == 'Mono.Cecil.csproj' Or '%(Filename)%(Extension)' == 'Mono.Cecil.Pdb.csproj' Or '%(Filename)%(Extension)' == 'Mono.Cecil.Mdb.csproj' ">
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' ">Configuration=net_4_0_$(Configuration)</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">Configuration=netstandard_$(Configuration)</SetConfiguration>
|
||||
</ProjectReferenceWithConfiguration>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<!-- TODO: Once we can avoid using a custom .nuspec, we should be
|
||||
able to set PrivateAssets="All" on these packages to prevent
|
||||
them from becoming package dependencies, and use an msbuild
|
||||
itemgroup to include their assets in the package instead of
|
||||
passing the publish path to the .nuspec. -->
|
||||
<!-- We use private assets for the Microsoft.Build packages to
|
||||
prevent them from being published with the tasks dll, because
|
||||
these are already a part of the SDK. -->
|
||||
<PackageReference Include="Microsoft.Build.Framework" Version="15.1.1012"
|
||||
PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.1.1012"
|
||||
PrivateAssets="All" />
|
||||
<PackageReference Include="NuGet.ProjectModel" Version="4.3.0-preview1-2500" />
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="1.3.0"
|
||||
PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>$id$</id>
|
||||
<version>$version$</version>
|
||||
<authors>$authors$</authors>
|
||||
<description>$description$</description>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="ILLink.Tasks.targets" target="build" />
|
||||
<file src="ILLink.CrossGen.targets" target="build" />
|
||||
<file src="netcoreapp2.0/**/*.dll" target="tools" />
|
||||
<file src="net46/**/*.dll" target="tools" />
|
||||
</files>
|
||||
</package>
|
File diff suppressed because it is too large
Load Diff
@ -1,144 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class ILLink : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Paths to the assembly files that should be considered as
|
||||
/// input to the linker. Currently the linker will
|
||||
/// additionally be able to resolve any assemblies in the
|
||||
/// same directory as an assembly in AssemblyPaths, but this
|
||||
/// 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; }
|
||||
|
||||
/// <summary>
|
||||
/// The names of the assemblies to root. This should contain
|
||||
/// assembly names without an extension, not file names or
|
||||
/// paths. Exactly which parts of the assemblies get rooted
|
||||
/// is subject to change. Currently these get passed to
|
||||
/// illink with "-a", which roots the entry point for
|
||||
/// executables, and everything for libraries. To control
|
||||
/// the linker more explicitly, either pass descriptor
|
||||
/// files, or pass extra arguments for illink.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem [] RootAssemblyNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The directory in which to place linked assemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem OutputDirectory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of XML root descriptor files specifying linker
|
||||
/// roots at a granular level. See the mono/linker
|
||||
/// documentation for details about the format.
|
||||
/// </summary>
|
||||
public ITaskItem [] RootDescriptorFiles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean specifying whether to clear initlocals flag on methods.
|
||||
/// </summary>
|
||||
public bool ClearInitLocals { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A comma-separated list of assemblies whose methods
|
||||
/// should have initlocals flag cleared if ClearInitLocals is true.
|
||||
/// </summary>
|
||||
public string ClearInitLocalsAssemblies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Extra arguments to pass to illink, delimited by spaces.
|
||||
/// </summary>
|
||||
public string ExtraArgs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Make illink dump dependencies file for linker analyzer tool.
|
||||
/// </summary>
|
||||
public bool DumpDependencies { get; set; }
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
string [] args = GenerateCommandLineCommands ();
|
||||
var argsString = String.Join (" ", args);
|
||||
Log.LogMessageFromText ($"illink {argsString}", MessageImportance.Normal);
|
||||
var logger = new AdapterLogger (Log);
|
||||
int ret = Mono.Linker.Driver.Execute (args, logger);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
string [] GenerateCommandLineCommands ()
|
||||
{
|
||||
var args = new List<string> ();
|
||||
|
||||
if (RootDescriptorFiles != null) {
|
||||
foreach (var rootFile in RootDescriptorFiles) {
|
||||
args.Add ("-x");
|
||||
args.Add (rootFile.ItemSpec);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var assemblyItem in RootAssemblyNames) {
|
||||
args.Add ("-a");
|
||||
args.Add (assemblyItem.ItemSpec);
|
||||
}
|
||||
|
||||
HashSet<string> directories = new HashSet<string> ();
|
||||
foreach (var assembly in AssemblyPaths) {
|
||||
var assemblyPath = assembly.ItemSpec;
|
||||
var dir = Path.GetDirectoryName (assemblyPath);
|
||||
if (!directories.Contains (dir)) {
|
||||
directories.Add (dir);
|
||||
args.Add ("-d");
|
||||
args.Add (dir);
|
||||
}
|
||||
|
||||
string action = assembly.GetMetadata ("action");
|
||||
if ((action != null) && (action.Length > 0)) {
|
||||
args.Add ("-p");
|
||||
args.Add (action);
|
||||
args.Add (Path.GetFileNameWithoutExtension (assemblyPath));
|
||||
}
|
||||
}
|
||||
|
||||
if (OutputDirectory != null) {
|
||||
args.Add ("-out");
|
||||
args.Add (OutputDirectory.ItemSpec);
|
||||
}
|
||||
|
||||
if (ClearInitLocals) {
|
||||
args.Add ("-s");
|
||||
// Version of ILLink.CustomSteps is passed as a workaround for msbuild issue #3016
|
||||
args.Add ("ILLink.CustomSteps.ClearInitLocalsStep,ILLink.CustomSteps,Version=0.0.0.0:OutputStep");
|
||||
if ((ClearInitLocalsAssemblies != null) && (ClearInitLocalsAssemblies.Length > 0)) {
|
||||
args.Add ("-m");
|
||||
args.Add ("ClearInitLocalsAssemblies");
|
||||
args.Add (ClearInitLocalsAssemblies);
|
||||
}
|
||||
}
|
||||
|
||||
if (ExtraArgs != null) {
|
||||
args.AddRange (ExtraArgs.Split (' '));
|
||||
}
|
||||
|
||||
if (DumpDependencies)
|
||||
args.Add ("--dump-dependencies");
|
||||
|
||||
return args.ToArray ();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Microsoft.NET.Build.Tasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an error that is neither avoidable in all cases nor indicative of a bug in this library.
|
||||
/// It will be logged as a plain build error without the exception type or stack.
|
||||
/// </summary>
|
||||
internal class BuildErrorException : Exception
|
||||
{
|
||||
public BuildErrorException()
|
||||
{
|
||||
}
|
||||
|
||||
public BuildErrorException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildErrorException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildErrorException(string format, params string[] args)
|
||||
: this(string.Format(CultureInfo.CurrentCulture, format, args))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user