You've already forked linux-packaging-mono
Imported Upstream version 5.10.0.47
Former-commit-id: d0813289fa2d35e1f8ed77530acb4fb1df441bc0
This commit is contained in:
parent
88ff76fe28
commit
e46a49ecf1
3
external/linker/corebuild/bootstrap.ps1
vendored
3
external/linker/corebuild/bootstrap.ps1
vendored
@@ -11,6 +11,7 @@ param
|
||||
)
|
||||
|
||||
$rootCliVersion = Join-Path $RepositoryRoot ".cliversion"
|
||||
$globalJson = Join-Path $RepositoryRoot "global.json"
|
||||
$bootstrapComplete = Join-Path $ToolsLocalPath "bootstrap.complete"
|
||||
|
||||
# if the force switch is specified delete the semaphore file if it exists
|
||||
@@ -59,6 +60,8 @@ if ($LastExitCode -ne 0)
|
||||
exit $LastExitCode
|
||||
}
|
||||
|
||||
"{ `"sdk`": { `"version`": `"$dotNetCliVersion`" } }" | Out-File -Encoding utf8 -FilePath $globalJson
|
||||
|
||||
# write semaphore file
|
||||
copy $rootCliVersion $bootstrapComplete
|
||||
exit 0
|
||||
|
||||
3
external/linker/corebuild/bootstrap.sh
vendored
3
external/linker/corebuild/bootstrap.sh
vendored
@@ -150,6 +150,7 @@ fi
|
||||
|
||||
|
||||
rootCliVersion="$repoRoot/.cliversion"
|
||||
globalJson="$repoRoot/global.json"
|
||||
bootstrapComplete="$toolsLocalPath/bootstrap.complete"
|
||||
|
||||
# if the force switch is specified delete the semaphore file if it exists
|
||||
@@ -195,6 +196,8 @@ if [ $forcedCliLocalPath = "<none>" ]; then
|
||||
say_err "The .NET CLI installation failed with exit code $?"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
echo "{ \"sdk\": { \"version\": \"$dotNetCliVersion\" } }" > $globalJson
|
||||
fi
|
||||
|
||||
cp $rootCliVersion $bootstrapComplete
|
||||
|
||||
5
external/linker/corebuild/global.json
vendored
5
external/linker/corebuild/global.json
vendored
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "2.0.0"
|
||||
}
|
||||
}
|
||||
37
external/linker/corebuild/integration/ILLink.Tasks/CheckEmbeddedRootDescriptor.cs
vendored
Normal file
37
external/linker/corebuild/integration/ILLink.Tasks/CheckEmbeddedRootDescriptor.cs
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
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,11 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.Build.Utilities;
|
||||
using System.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Build.Utilities; // Task
|
||||
using Microsoft.Build.Framework; // MessageImportance
|
||||
using Microsoft.NET.Build.Tasks; // LockFileCache
|
||||
using NuGet.ProjectModel; // LockFileTargetLibrary
|
||||
using NuGet.Frameworks; // NuGetFramework.Parse(targetframework)
|
||||
using Mono.Cecil;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
@@ -32,14 +22,9 @@ namespace ILLink.Tasks
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
var managedAssemblies = new List<ITaskItem>();
|
||||
foreach (var f in Assemblies) {
|
||||
if (Utils.IsManagedAssembly(f.ItemSpec)) {
|
||||
managedAssemblies.Add(f);
|
||||
}
|
||||
}
|
||||
ManagedAssemblies = managedAssemblies.ToArray();
|
||||
|
||||
ManagedAssemblies = Assemblies
|
||||
.Where(f => Utils.IsManagedAssembly(f.ItemSpec))
|
||||
.ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
31
external/linker/corebuild/integration/ILLink.Tasks/ComputeReadyToRunAssemblies.cs
vendored
Normal file
31
external/linker/corebuild/integration/ILLink.Tasks/ComputeReadyToRunAssemblies.cs
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class ComputeReadyToRunAssemblies : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Paths to assemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
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.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public ITaskItem[] ReadyToRunAssemblies { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
ReadyToRunAssemblies = Assemblies
|
||||
.Where(f => Utils.IsReadyToRunAssembly(f.ItemSpec))
|
||||
.ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Build.Utilities; // Task
|
||||
using Microsoft.Build.Framework; // MessageImportance
|
||||
using Microsoft.NET.Build.Tasks; // LockFileCache
|
||||
using NuGet.ProjectModel; // LockFileTargetLibrary
|
||||
using NuGet.Frameworks; // NuGetFramework.Parse(targetframework)
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
|
||||
326
external/linker/corebuild/integration/ILLink.Tasks/CreateRuntimeRootDescriptorFile.cs
vendored
Normal file
326
external/linker/corebuild/integration/ILLink.Tasks/CreateRuntimeRootDescriptorFile.cs
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
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 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;
|
||||
}
|
||||
|
||||
ProcessNamespaces (namespaceFilePath);
|
||||
|
||||
ProcessMscorlib (mscorlibFilePath);
|
||||
|
||||
ProcessCoreTypes (cortypeFilePath);
|
||||
|
||||
ProcessExceptionTypes (rexcepFilePath);
|
||||
|
||||
OutputXml (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OutputXml (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);
|
||||
|
||||
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 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;
|
||||
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 className = classIdsToClassNames [classId];
|
||||
|
||||
ClassMembers members = classNamesToClassMembers [className];
|
||||
|
||||
if (members.methods == null) {
|
||||
members.methods = new HashSet<string> ();
|
||||
}
|
||||
members.methods.Add (methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
46
external/linker/corebuild/integration/ILLink.Tasks/FilterByMetadata.cs
vendored
Normal file
46
external/linker/corebuild/integration/ILLink.Tasks/FilterByMetadata.cs
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
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,13 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Microsoft.Build.Framework;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Build.Utilities; // Task
|
||||
using Microsoft.Build.Framework; // MessageImportance
|
||||
using Microsoft.NET.Build.Tasks; // LockFileCache
|
||||
using NuGet.ProjectModel; // LockFileTargetLibrary
|
||||
using NuGet.Frameworks; // NuGetFramework.Parse(targetframework)
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class GenerateRoots : Task
|
||||
{
|
||||
|
||||
[Required]
|
||||
public string AssetsFilePath { get; set; }
|
||||
|
||||
[Required]
|
||||
public string TargetFramework { get; set; }
|
||||
|
||||
[Required]
|
||||
public string RuntimeIdentifier { get; set; }
|
||||
|
||||
[Required]
|
||||
public string PublishDir { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem SingleRootXmlFilePath { get; set; }
|
||||
|
||||
[Required]
|
||||
public string MainAssemblyName { get; set; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem[] RootAssemblies { get; private set; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem[] FrameworkAssemblies { get; private set; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem[] PublishAssemblies { get; private set; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem[] UnmanagedFileAssets { get; private set; }
|
||||
|
||||
|
||||
private List<string> publishLibs;
|
||||
private List<string> unmanagedFileAssets;
|
||||
private List<string> rootLibs;
|
||||
private List<string> frameworkLibs;
|
||||
|
||||
private void WriteSingleRootXmlFile()
|
||||
{
|
||||
var xdoc = new XDocument(new XElement("linker",
|
||||
new XElement("assembly",
|
||||
new XAttribute("fullname", MainAssemblyName),
|
||||
new XElement("type",
|
||||
new XAttribute("fullname", "*"),
|
||||
new XAttribute("required", "true")))));
|
||||
|
||||
XmlWriterSettings xws = new XmlWriterSettings();
|
||||
xws.Indent = true;
|
||||
xws.OmitXmlDeclaration = true;
|
||||
|
||||
using (XmlWriter xw = XmlWriter.Create(SingleRootXmlFilePath.ItemSpec, xws))
|
||||
{
|
||||
xdoc.Save(xw);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void GetAssembliesAndFiles()
|
||||
{
|
||||
unmanagedFileAssets = new List<string>();
|
||||
publishLibs = new List<string>();
|
||||
foreach (var f in Directory.GetFiles(PublishDir))
|
||||
{
|
||||
try
|
||||
{
|
||||
AssemblyName.GetAssemblyName(f);
|
||||
publishLibs.Add(f);
|
||||
}
|
||||
catch (BadImageFormatException)
|
||||
{
|
||||
unmanagedFileAssets.Add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void PopulateOutputItems()
|
||||
{
|
||||
FrameworkAssemblies = frameworkLibs.Select(l => new TaskItem(l)).ToArray();
|
||||
|
||||
RootAssemblies = rootLibs.Select(l => Path.GetFileNameWithoutExtension(l))
|
||||
.Select(l => new TaskItem(l)).ToArray();
|
||||
|
||||
UnmanagedFileAssets = unmanagedFileAssets.Select(f => Path.GetFileName(f))
|
||||
.Select(f => new TaskItem(f)).ToArray();
|
||||
|
||||
PublishAssemblies = publishLibs.Select(l => Path.GetFileName(l))
|
||||
.Select(l => new TaskItem(l)).ToArray();
|
||||
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
if (!Directory.Exists(PublishDir))
|
||||
{
|
||||
Log.LogMessageFromText($"Publish directory {PublishDir} does not exist. Run dotnet publish before dotnet link.", MessageImportance.High); return false;
|
||||
}
|
||||
|
||||
// TODO: make this a separate msbuild task
|
||||
WriteSingleRootXmlFile();
|
||||
|
||||
// TODO: make this a separate msbuild task
|
||||
GetAssembliesAndFiles();
|
||||
|
||||
// TODO: make this a separate msbuild task
|
||||
GetFrameworkLibraries();
|
||||
|
||||
rootLibs = publishLibs.Select(l => Path.GetFileName(l)).Except(frameworkLibs).ToList();
|
||||
|
||||
PopulateOutputItems();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void GetFrameworkLibraries()
|
||||
{
|
||||
var lockFile = new LockFileCache(BuildEngine4).GetLockFile(AssetsFilePath);
|
||||
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.");
|
||||
}
|
||||
|
||||
var netCoreAppPackage = lockFileTarget.Libraries.Single(l => l.Name == "Microsoft.NETCore.App");
|
||||
|
||||
Dictionary<string, LockFileTargetLibrary> packages = new Dictionary<string, LockFileTargetLibrary>(lockFileTarget.Libraries.Count, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var lib in lockFileTarget.Libraries)
|
||||
{
|
||||
packages.Add(lib.Name, lib);
|
||||
}
|
||||
|
||||
var packageQueue = new Queue<LockFileTargetLibrary>();
|
||||
packageQueue.Enqueue(netCoreAppPackage);
|
||||
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
frameworkLibs = libraries.Select(l => Path.GetFileName(l)).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,12 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Build.Utilities; // Task
|
||||
using Microsoft.Build.Framework; // MessageImportance
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Microsoft.NET.Build.Tasks; // LockFileCache
|
||||
using NuGet.ProjectModel; // LockFileTargetLibrary
|
||||
using NuGet.Frameworks; // NuGetFramework.Parse(targetframework)
|
||||
using NuGet.ProjectModel; // LockFileTargetLibrary
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
|
||||
231
external/linker/corebuild/integration/ILLink.Tasks/ILLink.CrossGen.targets
vendored
Normal file
231
external/linker/corebuild/integration/ILLink.Tasks/ILLink.CrossGen.targets
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<PropertyGroup>
|
||||
<CrossGenDuringPublish Condition=" '$(CrossGenDuringPublish)' == '' And '$(RuntimeIdentifier)' != '' ">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)')" />
|
||||
<!-- FilesToCrossGen doesn't contain System.Private.CoreLib, so
|
||||
it will still be published. -->
|
||||
<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 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
|
||||
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>
|
||||
|
||||
<Error Text="System.Private.CoreLib should already be crossgen compiled."
|
||||
Condition=" '%(FilesToCrossGen.Filename)' == 'System.Private.CoreLib' " />
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="ComputeReadyToRunAssemblies" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="_ComputeFilesToCrossGen"
|
||||
DependsOnTargets="_ComputeDefaultFilesToCrossGen">
|
||||
|
||||
<ComputeReadyToRunAssemblies Assemblies="@(FilesToCrossGen)">
|
||||
<Output TaskParameter="ReadyToRunAssemblies" ItemName="_ReadyToRunFiles" />
|
||||
</ComputeReadyToRunAssemblies>
|
||||
|
||||
<!-- Don't try to run crossgen on assemblies that are already R2R. -->
|
||||
<ItemGroup>
|
||||
<FilesToCrossGen Remove="@(_ReadyToRunFiles)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Message Text="files to crossgen: @(FilesToCrossGen)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -83,6 +83,7 @@
|
||||
<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">
|
||||
@@ -99,13 +100,18 @@
|
||||
<Compile Include="LinkTask.cs" />
|
||||
<Compile Include="CompareSizes.cs" />
|
||||
<Compile Include="ComputeManagedAssemblies.cs" />
|
||||
<Compile Include="ComputeReadyToRunAssemblies.cs" />
|
||||
<Compile Include="GetRuntimeLibraries.cs" />
|
||||
<Compile Include="CreateRootDescriptorFile.cs" />
|
||||
<Compile Include="CreateRuntimeRootDescriptorFile.cs" />
|
||||
<Compile Include="FilterByMetadata.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
|
||||
@@ -190,8 +196,8 @@
|
||||
AfterTargets="AssignProjectConfiguration">
|
||||
<ItemGroup>
|
||||
<ProjectReferenceWithConfiguration Condition=" '%(Filename)%(Extension)' == 'Mono.Cecil.csproj' Or '%(Filename)%(Extension)' == 'Mono.Cecil.Pdb.csproj' ">
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' ">Configuration=net_4_0_$(Configuration)</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">Configuration=netstandard_$(Configuration)</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' ">Configuration=net_4_0_$(Configuration)</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">Configuration=netstandard_$(Configuration)</SetConfiguration>
|
||||
</ProjectReferenceWithConfiguration>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</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>
|
||||
|
||||
@@ -15,8 +15,19 @@
|
||||
<LinkDuringPublish Condition=" '$(LinkDuringPublish)' == '' ">true</LinkDuringPublish>
|
||||
<LinkDuringPublish Condition=" '$(LinkDuringPublish)' != 'true' ">false</LinkDuringPublish>
|
||||
<ShowLinkerSizeComparison Condition=" '$(ShowLinkerSizeComparison)' == '' ">false</ShowLinkerSizeComparison>
|
||||
<LinkerDumpDependencies Condition=" '$(LinkerDumpDependencies)' == '' ">false</LinkerDumpDependencies>
|
||||
<UsedApplicationAssemblyAction Condition=" '$(UsedApplicationAssemblyAction)' == '' ">Copy</UsedApplicationAssemblyAction>
|
||||
<UnusedApplicationAssemblyAction Condition=" '$(UnusedApplicationAssemblyAction)' == '' ">Delete</UnusedApplicationAssemblyAction>
|
||||
<UsedPlatformAssemblyAction Condition=" '$(UsedPlatformAssemblyAction)' == '' ">Link</UsedPlatformAssemblyAction>
|
||||
<UnusedPlatformAssemblyAction Condition=" '$(UnusedPlatformAssemblyAction)' == '' ">Delete</UnusedPlatformAssemblyAction>
|
||||
<RootAllApplicationAssemblies Condition=" '$(RootAllApplicationAssemblies)' == '' ">true</RootAllApplicationAssemblies>
|
||||
<RootAllApplicationAssemblies Condition=" '$(RootAllApplicationAssemblies)' != 'true' ">false</RootAllApplicationAssemblies>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<!-- This depends on LinkDuringPublish, so it needs to be imported
|
||||
after the property is set. -->
|
||||
<Import Project="$(MSBuildThisFileDirectory)ILLink.CrossGen.targets" />
|
||||
|
||||
<ItemGroup>
|
||||
<!-- LinkerRootDescriptors (the ItemGroup) is set to contain
|
||||
LinkerRootDescriptors (the Property), which allows adding
|
||||
@@ -100,6 +111,31 @@
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!-- The SDK has a target called ComputeRefAssembliesToPublish that
|
||||
runs after ComputeFilesToPublish and rewrites
|
||||
ResolvedFileToPublish to include any reference assemblies that
|
||||
aren't in ResolvedAssembliesToPublish. Because
|
||||
ComputeLinkedFilesToPublish changes ResolvedAssembliesToPublish
|
||||
(replacing the original assemblies with linked assemblies),
|
||||
this would change the behavior of
|
||||
ComputeRefAssembliesToPublish, resulting in extra assemblies
|
||||
being placed in the refs directory of the output. To prevent
|
||||
this, we save ResolvedAssembliesToPublish before linking, and
|
||||
restore it to its pre-link state before
|
||||
ComputeRefAssembliesToPublish. -->
|
||||
<Target Name="SaveResolvedAssembliesToPublish"
|
||||
BeforeTargets="ComputeLinkedFilesToPublish">
|
||||
<ItemGroup>
|
||||
<PreLinkResolvedAssembliesToPublish Include="@(ResolvedAssembliesToPublish)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<Target Name="RestoreResolvedAssembliesToPublish"
|
||||
BeforeTargets="ComputeRefAssembliesToPublish">
|
||||
<ItemGroup>
|
||||
<ResolvedAssembliesToPublish Remove="@(ResolvedAssembliesToPublish)" />
|
||||
<ResolvedAssembliesToPublish Include="@(PreLinkResolvedAssembliesToPublish)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!-- Print out a size comparison report for the linked
|
||||
assemblies. This is disabled by default, but can be turned on
|
||||
@@ -140,14 +176,41 @@
|
||||
Condition="Exists('%(Identity)') And '$(_DebugSymbolsProduced)' == 'true' " />
|
||||
</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>
|
||||
|
||||
<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>
|
||||
</Target>
|
||||
|
||||
<!-- This calls the linker. Inputs are the managed assemblies to
|
||||
link, and root specifications. The semaphore enables msbuild to
|
||||
skip linking during an incremental build, when the semaphore is
|
||||
up to date with respect to _ManagedAssembliesToLink. -->
|
||||
<UsingTask TaskName="ILLink" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="ILLink"
|
||||
DependsOnTargets="_ComputeManagedAssembliesToLink;_ComputeLinkerRootAssemblies;_ComputeLinkerRootDescriptors"
|
||||
DependsOnTargets="_ComputeManagedAssembliesToLink;_ComputeLinkerRootAssemblies;_ComputeLinkerRootDescriptors;_SetAssemblyActions"
|
||||
Inputs="@(_ManagedAssembliesToLink);@(LinkerRootDescriptors);$(MSBuildAllProjects)"
|
||||
Outputs="$(_LinkSemaphore)">
|
||||
<!-- These extra arguments have been hard-coded for now, as this
|
||||
@@ -155,12 +218,13 @@
|
||||
the future we will want to generate these depending on the
|
||||
scenario in which the linker is invoked. -->
|
||||
<PropertyGroup>
|
||||
<ExtraLinkerArgs Condition=" '$(ExtraLinkerArgs)' == '' ">-t -c link -l none -b true</ExtraLinkerArgs>
|
||||
<ExtraLinkerArgs Condition=" '$(ExtraLinkerArgs)' == '' ">-t -l none -b true</ExtraLinkerArgs>
|
||||
</PropertyGroup>
|
||||
<ILLink AssemblyPaths="@(_ManagedAssembliesToLink)"
|
||||
RootAssemblyNames="@(LinkerRootAssemblies)"
|
||||
RootDescriptorFiles="@(LinkerRootDescriptors)"
|
||||
OutputDirectory="$(IntermediateLinkDir)"
|
||||
DumpDependencies="$(LinkerDumpDependencies)"
|
||||
ExtraArgs="$(ExtraLinkerArgs)" />
|
||||
|
||||
<Touch Files="$(_LinkSemaphore)" AlwaysCreate="true">
|
||||
@@ -199,7 +263,6 @@
|
||||
|
||||
</Target>
|
||||
|
||||
|
||||
<!-- Computes the managed assemblies that are input to the
|
||||
linker. Includes managed assemblies from
|
||||
ResolvedAssembliesToPublish, and IntermediateAssembly. -->
|
||||
@@ -266,20 +329,37 @@
|
||||
be part of the build step or pack step, OR pack could be made
|
||||
to work on the publish output. -->
|
||||
<Target Name="_ComputeLinkerRootAssemblies"
|
||||
DependsOnTargets="_ComputeManagedResolvedAssembliesToPublish;_ComputePlatformLibraries">
|
||||
<!-- By default, roots are everything minus the framework
|
||||
assemblies (except for System.Private.CoreLib, which we
|
||||
always root for now). This doesn't include the intermediate
|
||||
assembly, because we root it separately using an xml file,
|
||||
which lets us explicitly root everything. -->
|
||||
<ItemGroup>
|
||||
DependsOnTargets="_ComputeManagedResolvedAssembliesToPublish;_ComputePlatformLibraries;_CheckSystemPrivateCorelibEmbeddedRoots">
|
||||
<!-- If RootAllApplicationAssemblies is true, roots are everything minus the framework
|
||||
assemblies. This doesn't include the intermediate assembly,
|
||||
because we root it separately using an xml file,
|
||||
which lets us explicitly root everything.
|
||||
|
||||
If RootAllApplicationAssemblies is false, only intermediate assembly's Main method is rooted.
|
||||
|
||||
System.Private.CoreLib is rooted unless it has an embedded
|
||||
xml descriptor file. -->
|
||||
|
||||
<ItemGroup Condition=" '$(RootAllApplicationAssemblies)' == 'true' ">
|
||||
<_LinkerRootAssemblies Include="@(_ManagedResolvedAssembliesToPublish->'%(Filename)')" />
|
||||
<_LinkerRootAssemblies Remove="@(PlatformLibraries->'%(Filename)')" />
|
||||
<_LinkerRootAssemblies Include="System.Private.CoreLib" />
|
||||
<_LinkerRootAssemblies Remove="System.Private.CoreLib" Condition=" '$(_SPCHasEmbeddedRootDescriptor)' == 'true' "/>
|
||||
<LinkerRootAssemblies Include="@(_LinkerRootAssemblies)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(RootAllApplicationAssemblies)' == 'false' ">
|
||||
<LinkerRootAssemblies Include="@(IntermediateAssembly)" />
|
||||
<LinkerRootAssemblies Include="System.Private.CoreLib" Condition=" '$(_SPCHasEmbeddedRootDescriptor)' == 'false' "/>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="CheckEmbeddedRootDescriptor" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="_CheckSystemPrivateCorelibEmbeddedRoots"
|
||||
DependsOnTargets="_ComputeManagedAssembliesToLink">
|
||||
<CheckEmbeddedRootDescriptor AssemblyPath="@(_ManagedAssembliesToLink->WithMetadataValue('Filename', 'System.Private.CoreLib'))">
|
||||
<Output TaskParameter="HasEmbeddedRootDescriptor" PropertyName="_SPCHasEmbeddedRootDescriptor" />
|
||||
</CheckEmbeddedRootDescriptor>
|
||||
</Target>
|
||||
|
||||
<!-- Platform libraries are the managed runtime assets needed by the
|
||||
"platform", currently Microsoft.NETCore.App. -->
|
||||
@@ -300,7 +380,8 @@
|
||||
dynamically include the generated descriptor files for the
|
||||
intermediate assembly. -->
|
||||
<Target Name="_ComputeLinkerRootDescriptors"
|
||||
DependsOnTargets="_GenerateIntermediateRootDescriptor">
|
||||
DependsOnTargets="_GenerateIntermediateRootDescriptor"
|
||||
Condition=" '$(RootAllApplicationAssemblies)' == 'true' ">
|
||||
<ItemGroup>
|
||||
<LinkerRootDescriptors Include="$(_IntermediateRootDescriptorPath)" />
|
||||
</ItemGroup>
|
||||
@@ -312,7 +393,8 @@
|
||||
<UsingTask TaskName="CreateRootDescriptorFile" AssemblyFile="$(LinkTaskDllPath)" />
|
||||
<Target Name="_GenerateIntermediateRootDescriptor"
|
||||
Inputs="@(IntermediateAssembly)"
|
||||
Outputs="$(_IntermediateRootDescriptorPath)">
|
||||
Outputs="$(_IntermediateRootDescriptorPath)"
|
||||
Condition=" '$(RootAllApplicationAssemblies)' == 'true' ">
|
||||
<CreateRootDescriptorFile AssemblyNames="@(IntermediateAssembly->'%(Filename)')"
|
||||
RootDescriptorFilePath="$(_IntermediateRootDescriptorPath)" />
|
||||
</Target>
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
@@ -21,7 +18,7 @@ namespace ILLink.Tasks
|
||||
/// resolved.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] AssemblyPaths { get; set; }
|
||||
public ITaskItem [] AssemblyPaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The names of the assemblies to root. This should contain
|
||||
@@ -34,7 +31,7 @@ namespace ILLink.Tasks
|
||||
/// files, or pass extra arguments for illink.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] RootAssemblyNames { get; set; }
|
||||
public ITaskItem [] RootAssemblyNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The directory in which to place linked assemblies.
|
||||
@@ -47,55 +44,74 @@ namespace ILLink.Tasks
|
||||
/// roots at a granular level. See the mono/linker
|
||||
/// documentation for details about the format.
|
||||
/// </summary>
|
||||
public ITaskItem[] RootDescriptorFiles { get; set; }
|
||||
public ITaskItem [] RootDescriptorFiles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Extra arguments to pass to illink, delimited by spaces.
|
||||
/// </summary>
|
||||
public string ExtraArgs { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
/// <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);
|
||||
int ret = Mono.Linker.Driver.Main(args);
|
||||
string [] args = GenerateCommandLineCommands ();
|
||||
var argsString = String.Join (" ", args);
|
||||
Log.LogMessageFromText ($"illink {argsString}", MessageImportance.Normal);
|
||||
int ret = Mono.Linker.Driver.Main (args);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
private string[] GenerateCommandLineCommands()
|
||||
string [] GenerateCommandLineCommands ()
|
||||
{
|
||||
var args = new List<string>();
|
||||
var args = new List<string> ();
|
||||
|
||||
if (RootDescriptorFiles != null) {
|
||||
foreach (var rootFile in RootDescriptorFiles) {
|
||||
args.Add("-x");
|
||||
args.Add(rootFile.ItemSpec);
|
||||
args.Add ("-x");
|
||||
args.Add (rootFile.ItemSpec);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var assemblyItem in RootAssemblyNames) {
|
||||
args.Add("-a");
|
||||
args.Add(assemblyItem.ItemSpec);
|
||||
args.Add ("-a");
|
||||
args.Add (assemblyItem.ItemSpec);
|
||||
}
|
||||
|
||||
var assemblyDirs = AssemblyPaths.Select(p => Path.GetDirectoryName(p.ItemSpec))
|
||||
.GroupBy(d => d).Select(ds => ds.First());
|
||||
foreach (var dir in assemblyDirs) {
|
||||
args.Add("-d");
|
||||
args.Add(dir);
|
||||
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);
|
||||
args.Add ("-out");
|
||||
args.Add (OutputDirectory.ItemSpec);
|
||||
}
|
||||
|
||||
if (ExtraArgs != null) {
|
||||
args.AddRange(ExtraArgs.Split(' '));
|
||||
args.AddRange (ExtraArgs.Split (' '));
|
||||
}
|
||||
|
||||
return args.ToArray();
|
||||
if (DumpDependencies)
|
||||
args.Add ("--dump-dependencies");
|
||||
|
||||
return args.ToArray ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
138
external/linker/corebuild/integration/ILLink.Tasks/SetAssemblyActions.cs
vendored
Normal file
138
external/linker/corebuild/integration/ILLink.Tasks/SetAssemblyActions.cs
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using System.IO;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
public class SetAssemblyActions : Task
|
||||
{
|
||||
/// <summary>
|
||||
/// Paths to the assembly files that should be considered as
|
||||
/// input to the linker.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem [] AssemblyPaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Application assembly names.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem [] ApplicationAssemblyNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Platform assembly names.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem [] PlatformAssemblyNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action to perform on used application assemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem UsedApplicationAssemblyAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action to perform on unused application assemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem UnusedApplicationAssemblyAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action to perform on used platform assemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem UsedPlatformAssemblyAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action to perform on unused platform assemblies.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem UnusedPlatformAssemblyAction { get; set; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem [] AssemblyPathsWithActions { get; set; }
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
string applicationAssemblyAction;
|
||||
string usedApplicationAssemblyAction = UsedApplicationAssemblyAction.ItemSpec;
|
||||
string unusedApplicationAssemblyAction = UnusedApplicationAssemblyAction.ItemSpec;
|
||||
if (!GetAssemblyAction (usedApplicationAssemblyAction.ToLower (), unusedApplicationAssemblyAction.ToLower (), out applicationAssemblyAction)) {
|
||||
Log.LogError ("Unsupported combination of application assembly actions: {0}, {1}.",
|
||||
usedApplicationAssemblyAction, unusedApplicationAssemblyAction);
|
||||
return false;
|
||||
}
|
||||
|
||||
string platformAssemblyAction;
|
||||
string usedPlatformAssemblyAction = UsedPlatformAssemblyAction.ItemSpec;
|
||||
string unusedPlatformAssemblyAction = UnusedPlatformAssemblyAction.ItemSpec;
|
||||
if (!GetAssemblyAction (usedPlatformAssemblyAction.ToLower (), unusedPlatformAssemblyAction.ToLower (), out platformAssemblyAction)) {
|
||||
Log.LogError ("Unsupported combination of platform assembly actions: {0}, {1}.",
|
||||
usedPlatformAssemblyAction, unusedPlatformAssemblyAction);
|
||||
return false;
|
||||
}
|
||||
|
||||
List<ITaskItem> resultAssemblies = new List<ITaskItem> ();
|
||||
|
||||
AddAssemblyActionMetadata (ApplicationAssemblyNames, applicationAssemblyAction, resultAssemblies);
|
||||
AddAssemblyActionMetadata (PlatformAssemblyNames, platformAssemblyAction, resultAssemblies);
|
||||
|
||||
AssemblyPathsWithActions = resultAssemblies.ToArray ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetAssemblyAction (string usedAssemblyAction, string unusedAssemblyAction, out string assemblyAction)
|
||||
{
|
||||
assemblyAction = "illegal";
|
||||
if ((unusedAssemblyAction != usedAssemblyAction) && (unusedAssemblyAction != "delete")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (usedAssemblyAction) {
|
||||
case "link":
|
||||
assemblyAction = "link";
|
||||
break;
|
||||
|
||||
case "copy":
|
||||
assemblyAction = (unusedAssemblyAction == "delete") ? "copyused" : "copy";
|
||||
break;
|
||||
|
||||
case "addbypassngen":
|
||||
assemblyAction = (unusedAssemblyAction == "delete") ? "addbypassngenused" : "addbypassngen";
|
||||
break;
|
||||
|
||||
case "skip":
|
||||
if (unusedAssemblyAction != usedAssemblyAction) {
|
||||
return false;
|
||||
}
|
||||
assemblyAction = "skip";
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddAssemblyActionMetadata (ITaskItem [] assemblies, string action, List<ITaskItem> resultList)
|
||||
{
|
||||
HashSet<string> assemblyHashSet = new HashSet<string> ();
|
||||
foreach (var assembly in assemblies) {
|
||||
assemblyHashSet.Add (assembly.ItemSpec);
|
||||
}
|
||||
|
||||
foreach (var assembly in AssemblyPaths) {
|
||||
if (assemblyHashSet.Contains (Path.GetFileNameWithoutExtension (assembly.ItemSpec))) {
|
||||
assembly.SetMetadata ("action", action);
|
||||
resultList.Add (assembly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user