You've already forked linux-packaging-mono
Imported Upstream version 5.4.0.167
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
parent
e49d6f06c0
commit
536cd135cc
7
external/linker/.gitignore
vendored
7
external/linker/.gitignore
vendored
@@ -8,12 +8,15 @@
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userprefs
|
||||
.vs/
|
||||
.idea/
|
||||
|
||||
packages/
|
||||
|
||||
# Build results
|
||||
linker/obj
|
||||
linker/bin
|
||||
obj/
|
||||
bin/
|
||||
|
||||
|
||||
.DS_Store
|
||||
|
4
external/linker/NuGet.Config
vendored
4
external/linker/NuGet.Config
vendored
@@ -1,6 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<!-- nuget-build is necessary for the integration package to
|
||||
depend on the same NuGet package that the sdk uses -->
|
||||
<add key="nuget-build" value="https://dotnet.myget.org/F/nuget-build/api/v3/index.json" />
|
||||
<add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
|
9
external/linker/README.md
vendored
9
external/linker/README.md
vendored
@@ -1,8 +1,11 @@
|
||||
The Mono linker is a tool one can use to only ship the minimal possible set of functions that a set of
|
||||
# IL linker
|
||||
|
||||
The linker is a tool one can use to only ship the minimal possible IL code and metadata that a set of
|
||||
programs might require to run as opposed to the full libraries.
|
||||
|
||||
It is used by the various Xamarin products to extract only the bits of code that are needed to run
|
||||
an application on Android, iOS and other platforms.
|
||||
|
||||
This file was extracted from Mono (github.com/mono/mono) on November 1st, 2016 to allow easier
|
||||
sharing of the linker code with other .NET projects.
|
||||
### Build & Test Status
|
||||
|
||||
[](https://jenkins.mono-project.com/job/test-linker-mainline/)
|
||||
|
@@ -34,7 +34,7 @@ namespace Mono.Cecil.Cil {
|
||||
Mixin.CheckModule (module);
|
||||
Mixin.CheckStream (symbolStream);
|
||||
|
||||
return GetSymbolReader (module, Disposable.NotOwned (symbolStream), "");
|
||||
return GetSymbolReader (module, Disposable.NotOwned (symbolStream), symbolStream.GetFileName ());
|
||||
}
|
||||
|
||||
ISymbolReader GetSymbolReader (ModuleDefinition module, Disposable<Stream> symbolStream, string fileName)
|
||||
@@ -301,7 +301,11 @@ namespace Mono.Cecil.Cil {
|
||||
// PDB Age
|
||||
buffer.WriteUInt32 (1);
|
||||
// PDB Path
|
||||
buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (writer.BaseStream.GetFileName ()));
|
||||
var filename = writer.BaseStream.GetFileName ();
|
||||
if (!string.IsNullOrEmpty (filename))
|
||||
filename = Path.GetFileName (filename);
|
||||
|
||||
buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (filename));
|
||||
buffer.WriteByte (0);
|
||||
|
||||
var data = new byte [buffer.length];
|
||||
|
@@ -2986,13 +2986,13 @@ namespace Mono.Cecil {
|
||||
value = Encoding.Unicode.GetString (bytes, 0, bytes.Length);
|
||||
} else
|
||||
value = null;
|
||||
} else if (type.etype == ElementType.Object) {
|
||||
value = null;
|
||||
} else if (type.IsTypeOf ("System", "Decimal")) {
|
||||
var b = signature.ReadByte ();
|
||||
value = new decimal (signature.ReadInt32 (), signature.ReadInt32 (), signature.ReadInt32 (), (b & 0x80) != 0, (byte) (b & 0x7f));
|
||||
} else if (type.IsTypeOf ("System", "DateTime")) {
|
||||
value = new DateTime (signature.ReadInt64());
|
||||
} else if (type.etype == ElementType.Object || type.etype == ElementType.None || type.etype == ElementType.Class) {
|
||||
value = null;
|
||||
} else
|
||||
value = signature.ReadConstantSignature (type.etype);
|
||||
|
||||
|
@@ -122,9 +122,8 @@ namespace Mono.Cecil {
|
||||
#if !NET_CORE
|
||||
if (parameters.StrongNameKeyPair != null)
|
||||
CryptoService.StrongName (stream.value, writer, parameters.StrongNameKeyPair);
|
||||
|
||||
stream.Dispose ();
|
||||
#endif
|
||||
stream.Dispose ();
|
||||
}
|
||||
|
||||
static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata)
|
||||
@@ -2152,6 +2151,7 @@ namespace Mono.Cecil {
|
||||
case ElementType.SzArray:
|
||||
case ElementType.Class:
|
||||
case ElementType.Object:
|
||||
case ElementType.None:
|
||||
case ElementType.Var:
|
||||
case ElementType.MVar:
|
||||
signature.WriteInt32 (0);
|
||||
|
@@ -995,19 +995,7 @@ namespace Mono.Cecil {
|
||||
|
||||
public ImageDebugHeader GetDebugHeader ()
|
||||
{
|
||||
if (!HasDebugHeader)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
return Image.DebugHeader;
|
||||
}
|
||||
|
||||
void ProcessDebugHeader ()
|
||||
{
|
||||
if (!HasDebugHeader)
|
||||
return;
|
||||
|
||||
if (!symbol_reader.ProcessDebugHeader (GetDebugHeader ()))
|
||||
throw new InvalidOperationException ();
|
||||
return Image.DebugHeader ?? new ImageDebugHeader ();
|
||||
}
|
||||
|
||||
#if !READ_ONLY
|
||||
@@ -1084,7 +1072,10 @@ namespace Mono.Cecil {
|
||||
|
||||
symbol_reader = reader;
|
||||
|
||||
ProcessDebugHeader ();
|
||||
if (!symbol_reader.ProcessDebugHeader (GetDebugHeader ())) {
|
||||
symbol_reader = null;
|
||||
throw new InvalidOperationException ();
|
||||
}
|
||||
|
||||
if (HasImage && ReadingMode == ReadingMode.Immediate) {
|
||||
var immediate_reader = new ImmediateModuleReader (Image);
|
||||
@@ -1135,7 +1126,7 @@ namespace Mono.Cecil {
|
||||
Mixin.CheckStream (stream);
|
||||
Mixin.CheckReadSeek (stream);
|
||||
|
||||
return ReadModule (Disposable.NotOwned (stream), "", parameters);
|
||||
return ReadModule (Disposable.NotOwned (stream), stream.GetFileName (), parameters);
|
||||
}
|
||||
|
||||
static ModuleDefinition ReadModule (Disposable<Stream> stream, string fileName, ReaderParameters parameters)
|
||||
|
@@ -263,6 +263,20 @@ namespace Mono.Cecil.Tests {
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OwnedStreamModuleFileName ()
|
||||
{
|
||||
var path = GetAssemblyResourcePath ("hello.exe", GetType ().Assembly);
|
||||
using (var file = File.Open (path, FileMode.Open))
|
||||
{
|
||||
using (var module = ModuleDefinition.ReadModule (file))
|
||||
{
|
||||
Assert.IsNotNullOrEmpty (module.FileName);
|
||||
Assert.AreEqual (path, module.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadAndWriteFile ()
|
||||
{
|
||||
|
@@ -387,6 +387,22 @@ namespace Mono.Cecil.Tests {
|
||||
}, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NullClassConstant ()
|
||||
{
|
||||
TestModule ("xattr.dll", module => {
|
||||
var type = module.GetType ("Library");
|
||||
var method = type.GetMethod ("NullXAttributeConstant");
|
||||
var symbol = method.DebugInformation;
|
||||
|
||||
Assert.IsNotNull (symbol);
|
||||
Assert.AreEqual(1, symbol.Scope.Constants.Count);
|
||||
|
||||
var a = symbol.Scope.Constants [0];
|
||||
Assert.AreEqual ("a", a.Name);
|
||||
}, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PortablePdbLineInfo ()
|
||||
{
|
||||
|
BIN
external/linker/cecil/Test/Resources/assemblies/xattr.pdb
vendored
Normal file
BIN
external/linker/cecil/Test/Resources/assemblies/xattr.pdb
vendored
Normal file
Binary file not shown.
2
external/linker/corebuild/.cliversion
vendored
2
external/linker/corebuild/.cliversion
vendored
@@ -1 +1 @@
|
||||
2.0.0-preview1-005685
|
||||
2.0.0-preview2-005905
|
||||
|
18
external/linker/corebuild/bootstrap.ps1
vendored
18
external/linker/corebuild/bootstrap.ps1
vendored
@@ -59,24 +59,6 @@ if ($LastExitCode -ne 0)
|
||||
exit $LastExitCode
|
||||
}
|
||||
|
||||
# create a junction to the shared FX version directory. this is
|
||||
# so we have a stable path to dotnet.exe regardless of version.
|
||||
$runtimesPath = Join-Path $CliLocalPath "shared\Microsoft.NETCore.App"
|
||||
if ($SharedFrameworkVersion -eq "<auto>")
|
||||
{
|
||||
$SharedFrameworkVersion = Get-ChildItem $runtimesPath -Directory | Sort-Object | Select-Object -First 1 | % { New-Object System.Version($_) }
|
||||
}
|
||||
$junctionTarget = Join-Path $runtimesPath $SharedFrameworkVersion
|
||||
$junctionParent = Split-Path $SharedFrameworkSymlinkPath -Parent
|
||||
if (-Not (Test-Path $junctionParent))
|
||||
{
|
||||
mkdir $junctionParent | Out-Null
|
||||
}
|
||||
if (-Not (Test-Path $SharedFrameworkSymlinkPath))
|
||||
{
|
||||
cmd.exe /c mklink /j $SharedFrameworkSymlinkPath $junctionTarget | Out-Null
|
||||
}
|
||||
|
||||
# write semaphore file
|
||||
copy $rootCliVersion $bootstrapComplete
|
||||
exit 0
|
||||
|
20
external/linker/corebuild/bootstrap.sh
vendored
20
external/linker/corebuild/bootstrap.sh
vendored
@@ -197,26 +197,6 @@ if [ $forcedCliLocalPath = "<none>" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
runtimesPath="$cliLocalPath/shared/Microsoft.NETCore.App"
|
||||
if [ $sharedFxVersion = "<auto>" ]; then
|
||||
# OSX doesn't support --version-sort, https://stackoverflow.com/questions/21394536/how-to-simulate-sort-v-on-mac-osx
|
||||
sharedFxVersion=`ls $runtimesPath | sed 's/^[0-9]\./0&/; s/\.\([0-9]\)$/.0\1/; s/\.\([0-9]\)\./.0\1./g; s/\.\([0-9]\)\./.0\1./g' | sort -r | sed 's/^0// ; s/\.0/./g' | head -n 1`
|
||||
fi
|
||||
|
||||
# create a junction to the shared FX version directory. this is
|
||||
# so we have a stable path to dotnet.exe regardless of version.
|
||||
junctionTarget="$runtimesPath/$sharedFxVersion"
|
||||
junctionParent="$(dirname "$symlinkPath")"
|
||||
|
||||
if [ ! -d $junctionParent ]; then
|
||||
mkdir -p $junctionParent
|
||||
fi
|
||||
|
||||
if [ ! -e $symlinkPath ]; then
|
||||
ln -s $junctionTarget $symlinkPath
|
||||
fi
|
||||
|
||||
|
||||
cp $rootCliVersion $bootstrapComplete
|
||||
|
||||
say "Bootstrap finished successfully."
|
||||
|
2
external/linker/corebuild/dotnet.sh
vendored
2
external/linker/corebuild/dotnet.sh
vendored
@@ -12,7 +12,7 @@ if [ ! -e $bootStrapperPath ]; then
|
||||
cp $__scriptpath/bootstrap.sh $__scriptpath/Tools
|
||||
fi
|
||||
|
||||
$bootStrapperPath --repositoryRoot $__scriptpath --toolsLocalPath $toolsLocalPath > bootstrap.log
|
||||
$bootStrapperPath --verbose --repositoryRoot $__scriptpath --toolsLocalPath $toolsLocalPath > bootstrap.log
|
||||
lastExitCode=$?
|
||||
if [ $lastExitCode -ne 0 ]; then
|
||||
echo "Boot-strapping failed with exit code $lastExitCode, see bootstrap.log for more information."
|
||||
|
110
external/linker/corebuild/integration/ILLink.Tasks/CompareSizes.cs
vendored
Normal file
110
external/linker/corebuild/integration/ILLink.Tasks/CompareSizes.cs
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Microsoft.Build.Framework;
|
||||
|
||||
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) {
|
||||
try {
|
||||
AssemblyName.GetAssemblyName (unlinkedFile);
|
||||
}
|
||||
catch (BadImageFormatException) {
|
||||
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) {
|
||||
try {
|
||||
AssemblyName.GetAssemblyName (linkedFile);
|
||||
}
|
||||
catch (BadImageFormatException) {
|
||||
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}",
|
||||
"Total size of assemblies",
|
||||
totalUnlinked,
|
||||
totalLinked,
|
||||
((double)totalUnlinked - (double)totalLinked) / (double)totalUnlinked);
|
||||
|
||||
Console.WriteLine ("-----------");
|
||||
Console.WriteLine ("Details");
|
||||
Console.WriteLine ("-----------");
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
47
external/linker/corebuild/integration/ILLink.Tasks/ComputeManagedAssemblies.cs
vendored
Normal file
47
external/linker/corebuild/integration/ILLink.Tasks/ComputeManagedAssemblies.cs
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
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 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()
|
||||
{
|
||||
var managedAssemblies = new List<ITaskItem>();
|
||||
foreach (var f in Assemblies) {
|
||||
try {
|
||||
AssemblyName.GetAssemblyName(f.ItemSpec);
|
||||
managedAssemblies.Add(f);
|
||||
} catch (BadImageFormatException) {
|
||||
}
|
||||
}
|
||||
ManagedAssemblies = managedAssemblies.ToArray();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
56
external/linker/corebuild/integration/ILLink.Tasks/CreateRootDescriptorFile.cs
vendored
Normal file
56
external/linker/corebuild/integration/ILLink.Tasks/CreateRootDescriptorFile.cs
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
115
external/linker/corebuild/integration/ILLink.Tasks/DepsJsonLinker.cs
vendored
Normal file
115
external/linker/corebuild/integration/ILLink.Tasks/DepsJsonLinker.cs
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Microsoft.Build.Framework;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
/// <summary>
|
||||
/// This class exists as a workaround. It strips the publish
|
||||
/// dependency file of assemblies excluded from the publish
|
||||
/// output by the linker. Ideally we would pass appropriate
|
||||
/// parameters to the task that generates the deps file in
|
||||
/// the first place, instead of rewriting it. We may be
|
||||
/// ablee to do this once
|
||||
/// https://github.com/dotnet/sdk/pull/1052 is merged.
|
||||
/// </summary>
|
||||
public class DepsJsonLinker : Task
|
||||
{
|
||||
[Required]
|
||||
public ITaskItem InputDepsFilePath { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem OutputDepsFilePath { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem[] ManagedPublishAssemblies { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem[] KeptAssemblies { get; set; }
|
||||
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
string inputFile = InputDepsFilePath.ItemSpec;
|
||||
string outputFile = OutputDepsFilePath.ItemSpec;
|
||||
|
||||
string[] keptAssemblies = KeptAssemblies.Select(a => a.ItemSpec).ToArray();
|
||||
string[] allAssemblies = ManagedPublishAssemblies.Select(a => a.ItemSpec).ToArray();
|
||||
string[] removedAssemblies = allAssemblies.Except(keptAssemblies).ToArray();
|
||||
|
||||
var removedAssembliesSet = new HashSet<string> (removedAssemblies, StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
JObject o = JObject.Parse (File.ReadAllText (inputFile));
|
||||
|
||||
JObject targets = (JObject)o["targets"];
|
||||
|
||||
// Remove targets
|
||||
foreach (JProperty target in targets.Children()) {
|
||||
JEnumerable<JToken> children = target.Value.Children ();
|
||||
for (int i = 0; i < children.Count(); ++i) {
|
||||
//foreach (JProperty subtarget in target.Value.Children()) {
|
||||
var subtarget = (JProperty) children.ElementAt (i);
|
||||
string name = subtarget.Name.Substring (0, subtarget.Name.IndexOf ('/'));
|
||||
if (removedAssembliesSet.Contains (name + ".dll")) {
|
||||
subtarget.Remove ();
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove dependencies
|
||||
var dependencies = subtarget.Value["dependencies"];
|
||||
if (dependencies != null) {
|
||||
for (int j = 0; j < dependencies.Count (); ++j) {
|
||||
var dependency = ((JProperty)dependencies.ElementAt (j));
|
||||
|
||||
if (removedAssembliesSet.Contains (dependency.Name + ".dll")) {
|
||||
|
||||
dependency.Remove ();
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove runtimes
|
||||
var runtimes = subtarget.Value["runtime"];
|
||||
if (runtimes != null) {
|
||||
for (int j = 0; j < runtimes.Count (); ++j) {
|
||||
var runtime = ((JProperty)runtimes.ElementAt (j));
|
||||
string runtimeFileName = runtime.Name.Substring (runtime.Name.LastIndexOf ('/') + 1);
|
||||
|
||||
if (removedAssembliesSet.Contains (runtimeFileName)) {
|
||||
runtime.Remove ();
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove libraries
|
||||
JObject libraries = (JObject)o["libraries"];
|
||||
|
||||
JEnumerable<JToken> libraryChildren = libraries.Children ();
|
||||
for (int i = 0; i < libraryChildren.Count (); ++i) {
|
||||
var library = (JProperty)libraryChildren.ElementAt (i);
|
||||
string name = library.Name.Substring (0, library.Name.IndexOf ('/'));
|
||||
if (removedAssembliesSet.Contains (name + ".dll")) {
|
||||
library.Remove ();
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText (outputFile, o.ToString ());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
175
external/linker/corebuild/integration/ILLink.Tasks/GenerateRoots.cs
vendored
Normal file
175
external/linker/corebuild/integration/ILLink.Tasks/GenerateRoots.cs
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
87
external/linker/corebuild/integration/ILLink.Tasks/GetRuntimeLibraries.cs
vendored
Normal file
87
external/linker/corebuild/integration/ILLink.Tasks/GetRuntimeLibraries.cs
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user