mirror of https://github.com/winsw/winsw
Update .NET Framework packaging
parent
a16c93e558
commit
5546e655cc
|
@ -0,0 +1,126 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace WinSW.Tasks
|
||||
{
|
||||
public sealed class Trim : Task
|
||||
{
|
||||
private readonly HashSet<TypeDefinition> usedTypes = new HashSet<TypeDefinition>();
|
||||
|
||||
[Required]
|
||||
public string Path { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
using var module = ModuleDefinition.ReadModule(this.Path, new ReaderParameters { ReadWrite = true });
|
||||
|
||||
this.WalkType(module.EntryPoint.DeclaringType);
|
||||
|
||||
var types = module.Types;
|
||||
for (int i = types.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var type = types[i];
|
||||
if (type.FullName.Contains("WinSW.Plugins"))
|
||||
{
|
||||
this.WalkType(type);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = types.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var type = types[i];
|
||||
if (type.FullName == "<Module>")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.usedTypes.Contains(type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Log.LogMessage(MessageImportance.High, type.FullName);
|
||||
types.RemoveAt(i);
|
||||
}
|
||||
|
||||
module.Write();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void WalkType(TypeReference typeRef)
|
||||
{
|
||||
if (typeRef is TypeSpecification typeSpec)
|
||||
{
|
||||
this.WalkType(typeSpec.ElementType);
|
||||
|
||||
if (typeRef is GenericInstanceType genericType)
|
||||
{
|
||||
foreach (var genericArg in genericType.GenericArguments)
|
||||
{
|
||||
this.WalkType(genericArg);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeRef is TypeDefinition typeDef)
|
||||
{
|
||||
if (!this.usedTypes.Add(typeDef))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeDef.DeclaringType != null)
|
||||
{
|
||||
this.WalkType(typeDef.DeclaringType);
|
||||
}
|
||||
|
||||
if (typeDef.BaseType != null)
|
||||
{
|
||||
this.WalkType(typeDef.BaseType);
|
||||
}
|
||||
|
||||
var methods = typeDef.Methods.ToList();
|
||||
var bodies = methods.Where(m => m.HasBody).Select(m => m.Body);
|
||||
var operands = bodies.SelectMany(b => b.Instructions).Select(i => i.Operand);
|
||||
|
||||
var types = typeDef.CustomAttributeTypes()
|
||||
.Union(typeDef.GenericParameters.SelectMany(p => p.CustomAttributeTypes()))
|
||||
.Union(typeDef.Interfaces.Select(i => i.InterfaceType))
|
||||
.Union(typeDef.Fields.SelectMany(f => f.CustomAttributeTypes()))
|
||||
.Union(typeDef.Fields.Select(f => f.FieldType))
|
||||
.Union(typeDef.Properties.SelectMany(p => p.CustomAttributeTypes()))
|
||||
.Union(typeDef.Events.SelectMany(e => e.CustomAttributeTypes()))
|
||||
.Union(typeDef.Events.Select(e => e.EventType))
|
||||
.Union(methods.SelectMany(m => m.CustomAttributeTypes()))
|
||||
.Union(methods.SelectMany(m => m.GenericParameters).SelectMany(p => p.CustomAttributeTypes()))
|
||||
.Union(methods.SelectMany(m => m.MethodReturnType.CustomAttributeTypes()))
|
||||
.Union(methods.Select(m => m.ReturnType))
|
||||
.Union(methods.SelectMany(m => m.Parameters).SelectMany(p => p.CustomAttributeTypes()))
|
||||
.Union(methods.SelectMany(m => m.Parameters).Select(p => p.ParameterType))
|
||||
.Union(bodies.SelectMany(b => b.Variables).Select(v => v.VariableType))
|
||||
.Union(operands.OfType<TypeReference>())
|
||||
.Union(operands.OfType<MemberReference>().Select(m => m.DeclaringType))
|
||||
.Union(operands.OfType<GenericInstanceMethod>().SelectMany(m => m.GenericArguments));
|
||||
|
||||
foreach (var t in types)
|
||||
{
|
||||
this.WalkType(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Extensions
|
||||
{
|
||||
internal static IEnumerable<TypeReference> CustomAttributeTypes(this ICustomAttributeProvider provider)
|
||||
{
|
||||
return provider.HasCustomAttributes ? provider.CustomAttributes.Select(a => a.AttributeType) : Enumerable.Empty<TypeReference>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net461</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="16.6.0" />
|
||||
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,32 @@
|
|||
#if NET461
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using WinSW.Tests.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WinSW.Tests
|
||||
{
|
||||
public sealed class MetadataTests
|
||||
{
|
||||
[Fact]
|
||||
public void Extern()
|
||||
{
|
||||
var version = new Version(4, 0, 0, 0);
|
||||
|
||||
using var file = File.OpenRead(Path.Combine(Layout.ArtifactsDirectory, "WinSW.NET461.exe"));
|
||||
using var peReader = new PEReader(file);
|
||||
var metadataReader = peReader.GetMetadataReader();
|
||||
foreach (var handle in metadataReader.AssemblyReferences)
|
||||
{
|
||||
var assembly = metadataReader.GetAssemblyReference(handle);
|
||||
if (metadataReader.GetString(assembly.Name) != "System.IO.Compression")
|
||||
{
|
||||
Assert.Equal(version, assembly.Version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -19,6 +19,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp5.0'">
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="1.8.1" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinSW.Plugins", "WinSW.Plug
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinSW.Tests", "WinSW.Tests\WinSW.Tests.csproj", "{691DE22D-4565-4E3C-9CC7-918A0098219E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinSW.Tasks", "WinSW.Tasks\WinSW.Tasks.csproj", "{EFDE140A-BB31-4509-A835-766520FEAEB9}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4975DCF4-C32C-43ED-A731-8FCC1F7E6746}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
|
@ -38,6 +40,10 @@ Global
|
|||
{691DE22D-4565-4E3C-9CC7-918A0098219E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{691DE22D-4565-4E3C-9CC7-918A0098219E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{691DE22D-4565-4E3C-9CC7-918A0098219E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EFDE140A-BB31-4509-A835-766520FEAEB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EFDE140A-BB31-4509-A835-766520FEAEB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EFDE140A-BB31-4509-A835-766520FEAEB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EFDE140A-BB31-4509-A835-766520FEAEB9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
<ProjectReference Include="..\WinSW.Plugins\WinSW.Plugins.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
|
||||
<ProjectReference Include="..\WinSW.Tasks\WinSW.Tasks.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PublishCoreZip" AfterTargets="Publish" Condition="'$(TargetFramework)' == 'netcoreapp3.1' and '$(PublishSingleFile)' != 'true'">
|
||||
|
||||
<MakeDir Directories="$(ArtifactsDir)" />
|
||||
|
@ -64,6 +68,11 @@
|
|||
<InputAssemblies>$(InputAssemblies) "$(OutDir)WinSW.Plugins.dll"</InputAssemblies>
|
||||
<InputAssemblies>$(InputAssemblies) "$(OutDir)log4net.dll"</InputAssemblies>
|
||||
<InputAssemblies>$(InputAssemblies) "$(OutDir)System.CommandLine.dll"</InputAssemblies>
|
||||
<InputAssemblies>$(InputAssemblies) "$(OutDir)System.Buffers.dll"</InputAssemblies>
|
||||
<InputAssemblies>$(InputAssemblies) "$(OutDir)System.Memory.dll"</InputAssemblies>
|
||||
<InputAssemblies>$(InputAssemblies) "$(OutDir)System.Numerics.Vectors.dll"</InputAssemblies>
|
||||
<InputAssemblies>$(InputAssemblies) "$(OutDir)System.Runtime.CompilerServices.Unsafe.dll"</InputAssemblies>
|
||||
<InputAssemblies>$(InputAssemblies) "$(OutDir)System.ValueTuple.dll"</InputAssemblies>
|
||||
<OutputAssembly>"$(ArtifactsDir)WinSW.$(TargetFrameworkSuffix).exe"</OutputAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -74,9 +83,13 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<MakeDir Directories="$(ArtifactsDir)" />
|
||||
<Message Text="$(ILMergeCommand)" Importance="high" />
|
||||
<Exec Command="$(ILMergeCommand)" />
|
||||
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="WinSW.Tasks.Trim" AssemblyFile="..\WinSW.Tasks\bin\$(Configuration)\net461\WinSW.Tasks.dll" />
|
||||
<Target Name="Trim" AfterTargets="Merge" Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
|
||||
<Trim Path="$(ArtifactsDir)WinSW.$(TargetFrameworkSuffix).exe" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
Loading…
Reference in New Issue