You've already forked linux-packaging-mono
Imported Upstream version 6.4.0.137
Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
This commit is contained in:
parent
e9207cf623
commit
ef583813eb
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<!-- net46 build is disabled until cecil uses SDK-style projects. -->
|
||||
@@ -12,38 +11,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\linker\Mono.Linker.csproj">
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Debug' ">Configuration=illink_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Release' ">Configuration=illink_Release</SetConfiguration>
|
||||
<Project>{DD28E2B1-057B-4B4D-A04D-B2EBD9E76E46}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\external\cecil\Mono.Cecil.csproj">
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Debug' ">Configuration=netstandard_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Debug' And '$(TargetFramework)' == 'net46' ">Configuration=net_4_0_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Release' ">Configuration=netstandard_Release</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'illink_Release' And '$(TargetFramework)' == 'net46' ">Configuration=net_4_0_Release</SetConfiguration>
|
||||
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\linker\Mono.Linker.csproj" />
|
||||
<ProjectReference Include="..\..\external\cecil\Mono.Cecil.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- The reference to the linker will cause Mono.Cecil.Pdb to be
|
||||
built in the wrong configuration unless we apply this
|
||||
workaround. -->
|
||||
<Target Name="SetCecilConfiguration"
|
||||
AfterTargets="AssignProjectConfiguration">
|
||||
<ItemGroup>
|
||||
<ProjectReferenceWithConfiguration Condition=" '%(Filename)%(Extension)' == 'Mono.Cecil.Pdb.csproj' ">
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' And '$(Configuration)' == 'illink_Debug' ">Configuration=net_4_0_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' And '$(Configuration)' == 'illink_Debug' ">Configuration=netstandard_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' And '$(Configuration)' == 'illink_Release' ">Configuration=net_4_0_Release</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' And '$(Configuration)' == 'illink_Release' ">Configuration=netstandard_Release</SetConfiguration>
|
||||
</ProjectReferenceWithConfiguration>
|
||||
<ProjectReferenceWithConfiguration Condition=" '%(Filename)%(Extension)' == 'Mono.Cecil.Mdb.csproj' ">
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' And '$(Configuration)' == 'illink_Debug' ">Configuration=net_4_0_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' And '$(Configuration)' == 'illink_Debug' ">Configuration=netstandard_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' And '$(Configuration)' == 'illink_Release' ">Configuration=net_4_0_Release</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' And '$(Configuration)' == 'illink_Release' ">Configuration=netstandard_Release</SetConfiguration>
|
||||
</ProjectReferenceWithConfiguration>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace ILLink.Tasks
|
||||
{
|
||||
class AdapterLogger : Mono.Linker.ILogger
|
||||
{
|
||||
private TaskLoggingHelper log;
|
||||
|
||||
public AdapterLogger (TaskLoggingHelper log)
|
||||
{
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public void LogMessage (Mono.Linker.MessageImportance importance, string message, params object[] values)
|
||||
{
|
||||
Microsoft.Build.Framework.MessageImportance msBuildImportance;
|
||||
switch (importance)
|
||||
{
|
||||
case Mono.Linker.MessageImportance.High:
|
||||
msBuildImportance = MessageImportance.High;
|
||||
break;
|
||||
case Mono.Linker.MessageImportance.Normal:
|
||||
msBuildImportance = MessageImportance.Normal;
|
||||
break;
|
||||
case Mono.Linker.MessageImportance.Low:
|
||||
msBuildImportance = MessageImportance.Low;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException ($"Unrecognized importance level {importance}", nameof(importance));
|
||||
}
|
||||
|
||||
log.LogMessageFromText (String.Format (message, values), msBuildImportance);
|
||||
}
|
||||
}
|
||||
}
|
||||
250
external/linker/src/ILLink.Tasks/ILLink.Tasks.csproj
vendored
250
external/linker/src/ILLink.Tasks/ILLink.Tasks.csproj
vendored
@@ -1,102 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="$(MSBuildThisFileDirectory)../../eng/Versions.props" Condition=" '$(ArcadeBuild)' != 'true' " />
|
||||
<PropertyGroup>
|
||||
<!-- net46 build is disabled until cecil uses SDK-style projects. -->
|
||||
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.0;net472</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<BaseOutputPath>bin/</BaseOutputPath>
|
||||
<PackageOutputPath>$(BaseOutputPath)nupkgs</PackageOutputPath>
|
||||
<IsPackable>true</IsPackable>
|
||||
<!-- IsTool true causes the build output to be placed in the
|
||||
package's tools folder. This allows projects to reference the
|
||||
tasks package without including the tasks dll in their
|
||||
output. -->
|
||||
<!-- TODO: This has no effect currently, because we are using a
|
||||
custom .nuspec with the tools path hardcoded. Uncomment this
|
||||
once we are able to remove the custom .nuspec workaround. -->
|
||||
<!-- <IsTool>true</IsTool> -->
|
||||
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<Description>MSBuild tasks for running the IL Linker</Description>
|
||||
<Authors>$(AssemblyName)</Authors>
|
||||
<!-- Don't include the build output. Instead, we want to include
|
||||
the TargetFramework-specific publish output. -->
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<!-- We want to package the tasks package together with its
|
||||
package dependencies, the linker, and the linker's
|
||||
dependencies, in order to prevent projects that consume the
|
||||
tasks package from pulling in the linker. To do this, we need
|
||||
to include project references and package references in the
|
||||
package, and prevent any of these references from being
|
||||
marked as dependencies in the tasks package.
|
||||
transitive dependencies and the linker, without marking them
|
||||
as dependencies in the tasks package.
|
||||
|
||||
To include the linker in the package, we want to package the
|
||||
tasks project together with its project references. This is
|
||||
not supported by the pack targets
|
||||
(https://github.com/dotnet/cli/issues/1290,
|
||||
https://github.com/dotnet/cli/issues/3959), so we work around
|
||||
this by explicitly setting the package path to include the
|
||||
build output. Using the publish directory will also cause
|
||||
dependencies from package references to be packaged.
|
||||
|
||||
To prevent the linker from being marked as a package
|
||||
dependency, we can't use PrivateAssets="All", because this
|
||||
removes it from the publish output as well, due to an issue
|
||||
in the SDK (https://github.com/dotnet/sdk/issues/952). To
|
||||
work around this, we use a custom .nuspec that doesn't
|
||||
declare any dependencies. This also prevents package
|
||||
references from being marked as dependencies. -->
|
||||
<!-- TODO: Remove the custom .nuspec once the P2P PrivateAssets
|
||||
issue is fixed. -->
|
||||
<NuspecFileName>ILLink.Tasks.nuspec</NuspecFileName>
|
||||
<NuspecFile>$(BaseOutputPath)$(NuspecFileName)</NuspecFile>
|
||||
<NuspecProperties>id=$(AssemblyName);authors=$(AssemblyName);description=linker tasks;</NuspecProperties>
|
||||
Pack doesn't support including project references
|
||||
(https://github.com/NuGet/Home/issues/3891), so we work
|
||||
around this by explicitly including the publish output in the
|
||||
package. -->
|
||||
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);_LayoutPackage</TargetsForTfmSpecificContentInPackage>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- TODO: Remove this workaround once we're able to avoid using a
|
||||
custom .nuspec. We may still need a similar workaround to
|
||||
dynamically include the publish output in the package contents.
|
||||
|
||||
We can't specify the output path to package in the static
|
||||
nuspec properties, because the project's output path gets set
|
||||
at a later point. To work around this, we add the output path
|
||||
to the nuspec properties dynamically as part of the pack
|
||||
target. We use the same workaround to set the version in the
|
||||
.nuspec file.
|
||||
|
||||
We can't insert this into the pack target by modifying
|
||||
PackDependsOn, since GenerateNuspec is always prepended to
|
||||
PackDependsOn, which would cause the nuspec file to be
|
||||
generated before our extra properties are added.
|
||||
|
||||
Instead, we use GenerateNuspecDependsOn. We could probably also
|
||||
use BeforeTargets="GenerateNuspec". -->
|
||||
<PropertyGroup>
|
||||
<GenerateNuspecDependsOn>SetDynamicNuspecProperties;BinPlacePackageDeps;$(GenerateNuspecDependsOn)</GenerateNuspecDependsOn>
|
||||
</PropertyGroup>
|
||||
<Target Name="SetDynamicNuspecProperties"
|
||||
DependsOnTargets="LayoutPackage">
|
||||
<PropertyGroup>
|
||||
<NuspecProperties>$(NuspecProperties)version=$(Version);</NuspecProperties>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<!-- This target is necessary because the .nuspec includes the full
|
||||
path of the selected dlls in the package layout. We want the
|
||||
assets to be included in the package without the bin prefix, so
|
||||
we place the .nuspec and the included targets alongside the
|
||||
publish directories in the bin directory. -->
|
||||
<Target Name="BinPlacePackageDeps">
|
||||
<Copy SourceFiles="$(NuspecFileName)" DestinationFolder="$(BaseOutputPath)" />
|
||||
<Copy SourceFiles="ILLink.Tasks.targets" DestinationFolder="$(BaseOutputPath)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="LayoutPackage">
|
||||
<ItemGroup>
|
||||
<TFMsToPublish Include="$(TargetFrameworks)" />
|
||||
<ProjectsToPublish Include="$(MSBuildProjectFile)">
|
||||
<AdditionalProperties>TargetFramework=%(TFMsToPublish.Identity);PublishDir=$(BaseOutputPath)%(TFMsToPublish.Identity)</AdditionalProperties>
|
||||
</ProjectsToPublish>
|
||||
</ItemGroup>
|
||||
<MSBuild Projects="@(ProjectsToPublish)" Targets="Publish" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="AdapterLogger.cs" />
|
||||
<Compile Include="LinkTask.cs" />
|
||||
<Compile Include="CheckEmbeddedRootDescriptor.cs" />
|
||||
<Compile Include="CompareSizes.cs" />
|
||||
@@ -109,114 +37,72 @@
|
||||
<Compile Include="FindNativeDeps.cs" />
|
||||
<Compile Include="SetAssemblyActions.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Content Include="Sdk\Sdk.props">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="ILLink.Tasks.targets">
|
||||
<PackagePath>build</PackagePath>
|
||||
</Content>
|
||||
<Content Include="Sdk/Sdk.props">
|
||||
<PackagePath>Sdk</PackagePath>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- TODO: Uncomment this once we can avoid hard-coding this in a
|
||||
custom .nuspec. -->
|
||||
<!-- Targets under the build directory of the package automatically
|
||||
get included in the consumer's build.
|
||||
-->
|
||||
<!--
|
||||
<ItemGroup>
|
||||
<Content Include="ILLink.Tasks.targets">
|
||||
<PackagePath>build</PackagePath>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
-->
|
||||
<Target Name="_LayoutPackage">
|
||||
|
||||
<!-- TODO: Use this to set the package contents once we can avoid
|
||||
using a custom .nuspec. -->
|
||||
<!-- We can't glob everything in the output path for two reasons:
|
||||
<PropertyGroup>
|
||||
<PublishDir>$(BaseOutputPath)$(TargetFramework)</PublishDir>
|
||||
</PropertyGroup>
|
||||
|
||||
1. Content gets expanded before "Build" is called during
|
||||
"Pack". We could work around this by creating our own target to
|
||||
call build and then pack, but it would be nice to avoid
|
||||
changing the build/package pipeline.
|
||||
|
||||
2. We'll try to include the tasks dll twice. This only causes a
|
||||
warning during pack, but should be avoided.
|
||||
|
||||
<Content Include="$(OutputPath)*.dll;$(OutputPath)*.json">
|
||||
<PackagePath>tools</PackagePath>
|
||||
</Content>
|
||||
|
||||
There may also be a better ItemGroup to use than
|
||||
Content. Content semantics mean to output with the build, which
|
||||
isn't our goal. Instead, we want to include these dependencies
|
||||
in the package without necessarily including them in the build.
|
||||
-->
|
||||
<!--
|
||||
<ItemGroup>
|
||||
<Content Include="$(OutputPath)illink.dll;$(OutputPath)Mono.Cecil.dll">
|
||||
<PackagePath>tools</PackagePath>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
-->
|
||||
|
||||
<ItemGroup>
|
||||
<!-- TODO: Once https://github.com/dotnet/sdk/issues/952 is fixed,
|
||||
use PrivateAssets="All" to prevent this project reference
|
||||
from being marked as a dependency of the tasks package (while
|
||||
still including it in the publish output). -->
|
||||
<ProjectReference Include="../linker/Mono.Linker.csproj">
|
||||
<!-- SetConfiguration isn't required when the configuration is
|
||||
already set in the solution. Setting it here allows packing
|
||||
the tasks csproj on its own. This lets us avoid some of the
|
||||
strange behavior that shows up when trying to build from a
|
||||
.sln file.
|
||||
|
||||
There is a nuget bug that prevents this from working
|
||||
properly during restore
|
||||
(https://github.com/NuGet/Home/issues/4873). For the
|
||||
moment, the linker has a workaround for this issue.
|
||||
|
||||
However, this still won't work properly because the build
|
||||
target doesn't propagate this information properly either -
|
||||
this is probably another bug. Building from the .csproj
|
||||
would cause cecil to be built twice, once through the
|
||||
linker with the netstandard configuration and once directly
|
||||
from the tasks project in the default configuration info
|
||||
(because some target gets its reference information from
|
||||
the lock file, which doesn't have configuration info).
|
||||
-->
|
||||
<SetConfiguration>Configuration=illink_$(Configuration)</SetConfiguration>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../../external/cecil/Mono.Cecil.csproj" />
|
||||
|
||||
<ProjectReference Include="../ILLink.CustomSteps/ILLink.CustomSteps.csproj">
|
||||
<SetConfiguration>Configuration=illink_$(Configuration)</SetConfiguration>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Workaround for the SetConfiguration issue described above. -->
|
||||
<Target Name="SetCecilConfiguration"
|
||||
AfterTargets="AssignProjectConfiguration">
|
||||
<ItemGroup>
|
||||
<ProjectReferenceWithConfiguration Condition=" '%(Filename)%(Extension)' == 'Mono.Cecil.csproj' Or '%(Filename)%(Extension)' == 'Mono.Cecil.Pdb.csproj' Or '%(Filename)%(Extension)' == 'Mono.Cecil.Mdb.csproj' ">
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'net46' ">Configuration=net_4_0_$(Configuration)</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">Configuration=netstandard_$(Configuration)</SetConfiguration>
|
||||
</ProjectReferenceWithConfiguration>
|
||||
<ProjectsToPublish Include="$(MSBuildProjectFile)">
|
||||
<AdditionalProperties>TargetFramework=$(TargetFramework);PublishDir=$(PublishDir)</AdditionalProperties>
|
||||
</ProjectsToPublish>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Clean the publish directory in case there are any left-over
|
||||
artifacts (publish does not work incrementally). -->
|
||||
<ItemGroup>
|
||||
<_FilesToDelete Remove="@(_FilesToDelete)" />
|
||||
<_FilesToDelete Include="$(PublishDir)/*.dll" />
|
||||
<_FilesToDelete Include="$(PublishDir)/*.json" />
|
||||
</ItemGroup>
|
||||
<Delete Files="@(_FilesToDelete)" />
|
||||
|
||||
<MSBuild Projects="@(ProjectsToPublish)" Targets="Publish" />
|
||||
<ItemGroup>
|
||||
<TfmSpecificPackageFile Include="$(PublishDir)/*.dll" PackagePath="tools\$(TargetFramework)" />
|
||||
<TfmSpecificPackageFile Include="$(PublishDir)/*.json" PackagePath="tools\$(TargetFramework)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../linker/Mono.Linker.csproj"
|
||||
PrivateAssets="All"
|
||||
Condition=" '$(TargetFramework)' == 'netcoreapp2.0' " />
|
||||
<ProjectReference Include="../../external/cecil/Mono.Cecil.csproj"
|
||||
PrivateAssets="All" />
|
||||
<ProjectReference Include="../ILLink.CustomSteps/ILLink.CustomSteps.csproj"
|
||||
PrivateAssets="All"
|
||||
Condition=" '$(TargetFramework)' == 'netcoreapp2.0' " />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<!-- TODO: Once we can avoid using a custom .nuspec, we should be
|
||||
able to set PrivateAssets="All" on these packages to prevent
|
||||
them from becoming package dependencies, and use an msbuild
|
||||
itemgroup to include their assets in the package instead of
|
||||
passing the publish path to the .nuspec. -->
|
||||
<!-- We use private assets for the Microsoft.Build packages to
|
||||
prevent them from being published with the tasks dll, because
|
||||
these are already a part of the SDK. -->
|
||||
<PackageReference Include="Microsoft.Build.Framework" Version="15.1.1012"
|
||||
PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.1.1012"
|
||||
PrivateAssets="All" />
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="1.3.0"
|
||||
PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkVersion)"
|
||||
PrivateAssets="All"
|
||||
ExcludeAssets="Runtime" />
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCoreVersion)"
|
||||
PrivateAssets="All"
|
||||
ExcludeAssets="Runtime" />
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)"
|
||||
Condition=" '$(TargetFramework)' == 'net472' "
|
||||
PrivateAssets="All"
|
||||
Publish="True" />
|
||||
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>$id$</id>
|
||||
<version>$version$</version>
|
||||
<authors>$authors$</authors>
|
||||
<description>$description$</description>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="ILLink.Tasks.targets" target="build" />
|
||||
<file src="netcoreapp2.0/**/*.dll" target="tools" />
|
||||
<file src="netcoreapp2.0/**/*.json" target="tools" />
|
||||
<file src="netcoreapp2.0/Sdk/Sdk.props" target="Sdk/Sdk.props" />
|
||||
</files>
|
||||
</package>
|
||||
152
external/linker/src/ILLink.Tasks/LinkTask.cs
vendored
152
external/linker/src/ILLink.Tasks/LinkTask.cs
vendored
@@ -12,12 +12,7 @@ namespace ILLink.Tasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Paths to the assembly files that should be considered as
|
||||
/// input to the linker. Currently the linker will
|
||||
/// additionally be able to resolve any assemblies in the
|
||||
/// same directory as an assembly in AssemblyPaths, but this
|
||||
/// behavior should not be relied upon. Instead, work under
|
||||
/// the assumption that only the AssemblyPaths given will be
|
||||
/// resolved.
|
||||
/// input to the linker.
|
||||
/// Each path can also have an "action" metadata,
|
||||
/// which will set the illink action to take for
|
||||
/// that assembly.
|
||||
@@ -25,6 +20,12 @@ namespace ILLink.Tasks
|
||||
[Required]
|
||||
public ITaskItem [] AssemblyPaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Paths to assembly files that are reference assemblies,
|
||||
/// representing the surface area for compilation.
|
||||
/// </summary>
|
||||
public ITaskItem [] ReferenceAssemblyPaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The names of the assemblies to root. This should contain
|
||||
/// assembly names without an extension, not file names or
|
||||
@@ -82,14 +83,12 @@ namespace ILLink.Tasks
|
||||
get
|
||||
{
|
||||
if (!String.IsNullOrEmpty (_dotnetPath))
|
||||
{
|
||||
return _dotnetPath;
|
||||
}
|
||||
|
||||
_dotnetPath = Environment.GetEnvironmentVariable (DotNetHostPathEnvironmentName);
|
||||
if (String.IsNullOrEmpty (_dotnetPath))
|
||||
{
|
||||
throw new InvalidOperationException ($"{DotNetHostPathEnvironmentName} is not set");
|
||||
}
|
||||
|
||||
return _dotnetPath;
|
||||
}
|
||||
}
|
||||
@@ -106,71 +105,98 @@ namespace ILLink.Tasks
|
||||
public string ILLinkPath {
|
||||
get {
|
||||
if (!String.IsNullOrEmpty (_illinkPath))
|
||||
{
|
||||
return _illinkPath;
|
||||
}
|
||||
|
||||
var taskDirectory = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);
|
||||
_illinkPath = Path.Combine (taskDirectory, "illink.dll");
|
||||
// The linker always runs on .NET Core, even when using desktop MSBuild to host ILLink.Tasks.
|
||||
_illinkPath = Path.Combine (Path.GetDirectoryName (taskDirectory), "netcoreapp2.0", "illink.dll");
|
||||
return _illinkPath;
|
||||
}
|
||||
set => _illinkPath = value;
|
||||
}
|
||||
|
||||
private static string Quote (string path)
|
||||
{
|
||||
return $"\"{path.TrimEnd('\\')}\"";
|
||||
}
|
||||
|
||||
protected override string GenerateCommandLineCommands ()
|
||||
{
|
||||
var args = new StringBuilder ();
|
||||
args.Append (ILLinkPath);
|
||||
|
||||
if (RootDescriptorFiles != null) {
|
||||
foreach (var rootFile in RootDescriptorFiles) {
|
||||
args.Append (" -x ").Append (rootFile.ItemSpec);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var assemblyItem in RootAssemblyNames) {
|
||||
args.Append (" -a ").Append (assemblyItem.ItemSpec);
|
||||
}
|
||||
|
||||
HashSet<string> directories = new HashSet<string> ();
|
||||
foreach (var assembly in AssemblyPaths) {
|
||||
var assemblyPath = assembly.ItemSpec;
|
||||
var dir = Path.GetDirectoryName (assemblyPath);
|
||||
if (!directories.Contains (dir)) {
|
||||
directories.Add (dir);
|
||||
args.Append (" -d ").Append (dir);
|
||||
}
|
||||
|
||||
string action = assembly.GetMetadata ("action");
|
||||
if ((action != null) && (action.Length > 0)) {
|
||||
args.Append (" -p ");
|
||||
args.Append (action);
|
||||
args.Append (" ").Append (Path.GetFileNameWithoutExtension (assemblyPath));
|
||||
}
|
||||
}
|
||||
|
||||
if (OutputDirectory != null) {
|
||||
args.Append (" -out ").Append (OutputDirectory.ItemSpec);
|
||||
}
|
||||
|
||||
if (ClearInitLocals) {
|
||||
args.Append (" -s ");
|
||||
// Version of ILLink.CustomSteps is passed as a workaround for msbuild issue #3016
|
||||
args.Append ("LLink.CustomSteps.ClearInitLocalsStep,ILLink.CustomSteps,Version=0.0.0.0:OutputStep");
|
||||
if ((ClearInitLocalsAssemblies != null) && (ClearInitLocalsAssemblies.Length > 0)) {
|
||||
args.Append (" -m ClearInitLocalsAssemblies ");
|
||||
args.Append (ClearInitLocalsAssemblies);
|
||||
}
|
||||
}
|
||||
|
||||
if (ExtraArgs != null) {
|
||||
args.Append (" ").Append (ExtraArgs);
|
||||
}
|
||||
|
||||
if (DumpDependencies)
|
||||
args.Append (" --dump-dependencies");
|
||||
|
||||
args.Append (Quote (ILLinkPath));
|
||||
return args.ToString ();
|
||||
}
|
||||
|
||||
protected override string GenerateResponseFileCommands ()
|
||||
{
|
||||
var args = new StringBuilder ();
|
||||
|
||||
if (RootDescriptorFiles != null) {
|
||||
foreach (var rootFile in RootDescriptorFiles)
|
||||
args.Append ("-x ").AppendLine (Quote (rootFile.ItemSpec));
|
||||
}
|
||||
|
||||
foreach (var assemblyItem in RootAssemblyNames)
|
||||
args.Append ("-a ").AppendLine (Quote (assemblyItem.ItemSpec));
|
||||
|
||||
HashSet<string> assemblyNames = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var assembly in AssemblyPaths) {
|
||||
var assemblyPath = assembly.ItemSpec;
|
||||
var assemblyName = Path.GetFileNameWithoutExtension (assemblyPath);
|
||||
|
||||
// If there are multiple paths with the same assembly name, only use the first one.
|
||||
if (!assemblyNames.Add (assemblyName))
|
||||
continue;
|
||||
|
||||
args.Append ("-reference ").AppendLine (Quote (assemblyPath));
|
||||
|
||||
string action = assembly.GetMetadata ("action");
|
||||
if ((action != null) && (action.Length > 0)) {
|
||||
args.Append ("-p ");
|
||||
args.Append (action);
|
||||
args.Append (" ").AppendLine (Quote (assemblyName));
|
||||
}
|
||||
}
|
||||
|
||||
if (ReferenceAssemblyPaths != null) {
|
||||
foreach (var assembly in ReferenceAssemblyPaths) {
|
||||
var assemblyPath = assembly.ItemSpec;
|
||||
var assemblyName = Path.GetFileNameWithoutExtension (assemblyPath);
|
||||
|
||||
// Don't process references for which we already have
|
||||
// implementation assemblies.
|
||||
if (assemblyNames.Contains (assemblyName))
|
||||
continue;
|
||||
|
||||
args.Append ("-reference ").AppendLine (Quote (assemblyPath));
|
||||
|
||||
// Treat reference assemblies as "skip". Ideally we
|
||||
// would not even look at the IL, but only use them to
|
||||
// resolve surface area.
|
||||
args.Append ("-p skip ").AppendLine (Quote (assemblyName));
|
||||
}
|
||||
}
|
||||
|
||||
if (OutputDirectory != null)
|
||||
args.Append ("-out ").AppendLine (Quote (OutputDirectory.ItemSpec));
|
||||
|
||||
if (ClearInitLocals) {
|
||||
args.Append ("-s ");
|
||||
// Version of ILLink.CustomSteps is passed as a workaround for msbuild issue #3016
|
||||
args.AppendLine ("ILLink.CustomSteps.ClearInitLocalsStep,ILLink.CustomSteps,Version=0.0.0.0:OutputStep");
|
||||
if ((ClearInitLocalsAssemblies != null) && (ClearInitLocalsAssemblies.Length > 0)) {
|
||||
args.Append ("-m ClearInitLocalsAssemblies ");
|
||||
args.AppendLine (ClearInitLocalsAssemblies);
|
||||
}
|
||||
}
|
||||
|
||||
if (ExtraArgs != null)
|
||||
args.AppendLine (ExtraArgs);
|
||||
|
||||
if (DumpDependencies)
|
||||
args.AppendLine ("--dump-dependencies");
|
||||
|
||||
return args.ToString ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
230
external/linker/src/ILLink.Tasks/README.md
vendored
230
external/linker/src/ILLink.Tasks/README.md
vendored
@@ -1,10 +1,83 @@
|
||||
# ILLink.Tasks
|
||||
|
||||
ILLink.Tasks is a package containing MSBuild tasks and targets that
|
||||
will run the linker to run during publish of a .NET Core app.
|
||||
ILLink.Tasks contains MSBuild tasks that run the linker for .NET Core. It runs illink.dll, built from the same [sources](../linker/) that are used to build monolinker.exe. ILLink.Tasks is shipped as part of the .NET Core 3.0 SDK.
|
||||
|
||||
ILLink.Tasks provides an MSBuild task called ILLink that makes it easy
|
||||
to run the linker from an MSBuild project file:
|
||||
Note: in previous versions of .NET Core, ILLink.Tasks was shipped as an external nuget package. This is no longer supported - please update to the latest 3.0 SDK and try the new experience!
|
||||
|
||||
## Usage
|
||||
|
||||
To use this tool, set `PublishTrimmed` to `true` in your project and publish a self-contained app:
|
||||
|
||||
```
|
||||
dotnet publish -r <rid> -c Release
|
||||
```
|
||||
|
||||
The publish output will include a subset of the framework libraries, depending on what the application code calls. For a "hello world" app, this reduces the size from ~68MB to ~28MB.
|
||||
|
||||
Applications or frameworks (including ASP<span />.NET Core and WPF) that use reflection or related dynamic features will often break when trimmed, because the linker does not know about this dynamic behavior, and can not determine in general which framework types will be required for reflection at runtime. To trim such apps, you will need to tell the linker about any types needed by reflection in your code, and in packages or frameworks that you depend on. Be sure to test your apps after trimming.
|
||||
|
||||
## How it works
|
||||
|
||||
The IL linker scans the IL of your application to detect which code is actually required, and trims unused framework libraries. This can significantly reduce the size of some apps. Typically small tool-like console apps benefit the most as they tend to use fairly small subsets of the framework, and are usually more amenable to trimming. Applications that use reflection may not work with this approach.
|
||||
|
||||
## Default behavior
|
||||
|
||||
By default, the linker will operate in a conservative mode that keeps
|
||||
all managed assemblies that aren't part of the framework (they are
|
||||
kept intact, and the linker simply copies them). This means that any reflection calls to non-framework code should continue to work. Reflection calls to code in the framework can potentially break if the target of the call is removed. Any framework assemblies that aren't predicted to be used at runtime will be removed from the publish output. Used framework assemblies will be kept entirely.
|
||||
|
||||
# Adding reflection roots
|
||||
|
||||
If your app or its dependencies use reflection, you may need to tell the linker to keep reflection targets explicitly. For example, dependency injection in ASP<span />.NET Core apps will activate
|
||||
types depending on what is present at runtime, and therefore may fail
|
||||
if the linker has removed assemblies that would otherwise be
|
||||
present. Similarly, WPF apps may call into framework code depending on
|
||||
the features used. If you know beforehand what your app will require
|
||||
at runtime, you can tell the linker about this in a few ways.
|
||||
|
||||
For example, an app may reflect over `System.IO.File`:
|
||||
```csharp
|
||||
Type file = System.Type.GetType("System.IO.File,System.IO.FileSystem");
|
||||
```
|
||||
|
||||
To ensure that this works with `PublishTrimmed=true`:
|
||||
|
||||
- You can include a direct reference to the required type in your code
|
||||
somewhere, for example by using `typeof(System.IO.File)`.
|
||||
|
||||
- You can tell the linker to explicitly keep an assembly by adding it
|
||||
to your csproj (use the assembly name *without* extension):
|
||||
|
||||
```xml
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="System.IO.FileSystem" />
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
- You can give the linker a more specific list of types/methods,
|
||||
etc. to include using an xml file, using the format described at
|
||||
http://github.com/mono/linker
|
||||
|
||||
`.csproj`:
|
||||
```xml
|
||||
<ItemGroup>
|
||||
<TrimmerRootDescriptor Include="TrimmerRoots.xml" />
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
`TrimmerRoots.xml`:
|
||||
```xml
|
||||
<linker>
|
||||
<assembly fullname="System.IO.FileSystem">
|
||||
<type fullname="System.IO.File" />
|
||||
</assembly>
|
||||
</linker>
|
||||
```
|
||||
|
||||
|
||||
# MSBuild task
|
||||
|
||||
The linker can be invoked as an MSBuild task, `ILLink`. We recommend not using the task directly, because the SDK has built-in logic that handles computing the right set of reference assemblies as inputs, incremental linking, and similar logic. If you would like to use the [advanced options](../linker/README.md), you can invoke the msbuild task directly and pass any extra arguments like this:
|
||||
|
||||
```xml
|
||||
<ILLink AssemblyPaths="@(AssemblyFilesToLink)"
|
||||
@@ -14,83 +87,31 @@ to run the linker from an MSBuild project file:
|
||||
ExtraArgs="-t -c link -l none" />
|
||||
```
|
||||
|
||||
For a description of the options that this task supports, see the
|
||||
For a full description of the inputs that this task supports, see the
|
||||
comments in [LinkTask.cs](LinkTask.cs).
|
||||
|
||||
|
||||
In addition, ILLink.Tasks contains MSBuild logic that makes the linker
|
||||
run automatically during `dotnet publish` for .NET Core apps. This
|
||||
will:
|
||||
# Building
|
||||
|
||||
- Determine the assemblies and options to pass to illink.
|
||||
- Remove unused native files from the publish output.
|
||||
|
||||
The full set of options is described below.
|
||||
|
||||
## Building
|
||||
To build ILLink.Tasks:
|
||||
|
||||
```
|
||||
linker> ./corebuild/dotnet.{sh/ps1} restore illink.sln
|
||||
linker> ./corebuild/dotnet.{sh/ps1} pack src/ILLink.Tasks/ILLink.Tasks.csproj
|
||||
linker> dotnet restore illink.sln
|
||||
linker> dotnet pack illink.sln
|
||||
```
|
||||
|
||||
The output package will be placed in
|
||||
`corebuild/integration/bin/nupkgs`. If you are building on unix, you
|
||||
will need to adjust
|
||||
[ILLink.Tasks.nuspec](ILLink.Tasks.nuspec). Replace
|
||||
the dll file includes with the following:
|
||||
To produce a package:
|
||||
```
|
||||
linker> ./eng/dotnet.{sh/ps1} pack illink.sln
|
||||
```
|
||||
|
||||
`<file src="netcoreapp2.0/**/*.dll" target="tools/netcoreapp2.0" />`
|
||||
In .NET Core 3.0, this package is shipped with the SDK.
|
||||
|
||||
## Using ILLink.Tasks
|
||||
|
||||
Add a package reference to the linker. Ensure that either the
|
||||
[dotnet-core](https://dotnet.myget.org/gallery/dotnet-core) myget feed
|
||||
or the path to the locally-built linker package path exists in the
|
||||
project's nuget.config. If using myget, you probably want to ensure
|
||||
that you're using the latest version available at
|
||||
https://dotnet.myget.org/feed/dotnet-core/package/nuget/ILLink.Tasks.
|
||||
|
||||
After adding the package, linking will be turned on during `dotnet
|
||||
publish`. The publish output will contain the linked assemblies.
|
||||
|
||||
## Default behavior
|
||||
|
||||
By default, the linker will operate in a conservative mode that keeps
|
||||
all managed assemblies that aren't part of the framework (they are
|
||||
kept intact, and the linker simply copies them). It also analyzes all
|
||||
non-framework assemblies to find and keep code used by them (they are
|
||||
roots for the analysis). This means that unanalyzed reflection calls
|
||||
within the app should continue to work after linking. Reflection calls
|
||||
to code in the framework can potentially break when using the linker,
|
||||
if the target of the call is removed.
|
||||
|
||||
For portable publish, framework assemblies usually do not get
|
||||
published with the app. In this case they will not be analyzed or
|
||||
linked.
|
||||
|
||||
For self-contained publish, framework assemblies are part of the
|
||||
publish output, and are analyzed by the linker. Any framework
|
||||
assemblies that aren't predicted to be used at runtime based on the
|
||||
linker analysis will be removed from the publish output. Used
|
||||
framework assemblies will be kept, and any used code within these
|
||||
assemblies will be compiled to native code. Unused parts of used
|
||||
framework assemblies are kept as IL, so that reflection calls will
|
||||
continue to work, with runtime JIT compilation.
|
||||
|
||||
Native dependencies that aren't referenced by any of the kept managed
|
||||
assemblies will be removed from the publish output as well.
|
||||
|
||||
## Caveats
|
||||
|
||||
You should make sure to test the publish output before deploying your
|
||||
code, because the linker can potentially break apps that use
|
||||
reflection.
|
||||
# Caveats
|
||||
|
||||
The linker does not analyze reflection calls, so any reflection
|
||||
targets outside of the kept assemblies will need to be rooted
|
||||
explicitly using either `LinkerRootAssemblies` or
|
||||
`LinkerRootDescriptors` (see below).
|
||||
explicitly (see above).
|
||||
|
||||
Sometimes an application may include multiple versions of the same
|
||||
assembly. This may happen when portable apps include platform-specific
|
||||
@@ -99,76 +120,3 @@ publish output. In such cases, the linker will pick one of the
|
||||
duplicate assemblies to analyze. This means that dependencies of the
|
||||
un-analyzed duplicates may not be included in the application, so you
|
||||
may need to root such dependencies manually.
|
||||
|
||||
## Options
|
||||
|
||||
The following MSBuild properties can be used to control the behavior
|
||||
of the linker, from the command-line (via `dotnet publish
|
||||
/p:PropertyName=PropertyValue`), or from the .csproj file (via
|
||||
`<PropertyName>PropertyValue</PropertyName>`). They are defined and
|
||||
used in
|
||||
[ILLink.Tasks.targets](ILLink.Tasks.targets).
|
||||
|
||||
- `LinkDuringPublish` (default `true`) - Set to `false` to disable
|
||||
linking.
|
||||
|
||||
- `ShowLinkerSizeComparison` (default `false`) - Set to `true` to
|
||||
print out a table showing the size impact of the linker.
|
||||
|
||||
- `RootAllApplicationAssemblies` (default `true`) - If `true`, all
|
||||
application assemblies are rooted by the linker. This means they are
|
||||
kept in their entirety, and analyzed for dependencies. If `false`,
|
||||
only the app dll's entry point is rooted.
|
||||
|
||||
- `LinkerRootAssemblies` - The set of assemblies to root. The default
|
||||
depends on the value of `RootAllApplicationAssemblies`. Additional
|
||||
assemblies can be rooted by adding them to this ItemGroup.
|
||||
|
||||
- `LinkerRootDescriptors` - The set of [xml descriptors](../linker#syntax-of-xml-descriptor)
|
||||
specifying additional roots within assemblies. The default is to
|
||||
include a generated descriptor that roots everything in the
|
||||
application assembly if `RootAllApplicationAssemblies` is
|
||||
`true`. Additional roots from descriptors can be included by adding
|
||||
the descriptor files to this ItemGroup.
|
||||
|
||||
- `ExtraLinkerArgs` - Extra arguments to pass to the linker. The
|
||||
default sets some flags that output symbols, tolerate resolution
|
||||
errors, log warnings, skip mono-specific localization assemblies,
|
||||
and keep type-forwarder assemblies. See
|
||||
[ILLink.Tasks.targets](ILLink.Tasks.targets).
|
||||
Setting this will override the defaults.
|
||||
|
||||
- Assembly actions: illink has the ability to specify an [action](../linker#actions-on-the-assemblies) to
|
||||
take per-assembly. ILLink.Tasks provides high-level switches that
|
||||
control the action to take for a set of assemblies. The set of
|
||||
managed files that make up the application are split into
|
||||
"application" and "platform" assemblies. The "platform" represents
|
||||
the .NET framework, while the "application" represents the rest of
|
||||
the application and its other dependencies. The assembly action can
|
||||
be set for each of these groups independently, for assemblies that
|
||||
are analyzed as used and as unused, with the following switches:
|
||||
|
||||
- `UsedApplicationAssemblyAction` - The default is to `Copy` any used
|
||||
application assemblies to the output, leaving them as-is.
|
||||
- `UnusedApplicationAssemblyAction` - The default is to `Delete` (not
|
||||
publish) unused application assemblies.
|
||||
- `UsedPlatformAssemblyAction` - For self-contained publish, the
|
||||
default is `AddBypassNGen`, which will add the BypassNGenAttribute
|
||||
to unused code in used platform assemblies. This causes the native
|
||||
compilation step to compile only parts of these assemblies that
|
||||
are used. For portable publish, the default is to `Skip` these,
|
||||
because the platform assemblies are generally not published with
|
||||
the app.
|
||||
- `UnusedPlatformAssemblyAction` - For self-contained publish, the
|
||||
default is to `Delete` (not publish) unused platform
|
||||
assemblies. For portable publish, the default is to `Skip`.
|
||||
|
||||
The full list of assembly actions is described in
|
||||
[AssemblyAction.cs](../linker/Linker/AssemblyAction.cs) Some
|
||||
combinations of actions may be disallowed if they do not make
|
||||
sense. For more details, see
|
||||
[SetAssemblyActions.cs](SetAssemblyActions.cs).
|
||||
|
||||
- `LinkerTrimNativeDeps` (default `true`) - If `true`, enable
|
||||
detection and removal of unused native dependencies. If `false`, all
|
||||
native dependencies are kept.
|
||||
|
||||
11
external/linker/src/ILLink.Tasks/Sdk/Sdk.props
vendored
11
external/linker/src/ILLink.Tasks/Sdk/Sdk.props
vendored
@@ -11,6 +11,15 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||
-->
|
||||
<Project ToolsVersion="14.0">
|
||||
|
||||
<UsingTask TaskName="ILLink.Tasks.ILLink" AssemblyFile="$(MSBuildThisFileDirectory)..\tools\netcoreapp2.0\ILLink.Tasks.dll" />
|
||||
<PropertyGroup>
|
||||
<_ILLinkTasksDirectoryRoot Condition=" '$(_ILLinkTasksDirectoryRoot)' == '' ">$(MSBuildThisFileDirectory)../tools/</_ILLinkTasksDirectoryRoot>
|
||||
<_ILLinkTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core' ">netcoreapp2.0</_ILLinkTasksTFM>
|
||||
<_ILLinkTasksTFM Condition=" '$(_ILLinkTasksTFM)' == '' ">net472</_ILLinkTasksTFM>
|
||||
<_ILLinkTasksDirectory>$(_ILLinkTasksDirectoryRoot)$(_ILLinkTasksTFM)/</_ILLinkTasksDirectory>
|
||||
<ILLinkTasksAssembly Condition=" '$(ILLinkTasksAssembly)' == '' ">$(_ILLinkTasksDirectory)ILLink.Tasks.dll</ILLinkTasksAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<UsingTask TaskName="ILLink.Tasks.ILLink" AssemblyFile="$(ILLinkTasksAssembly)" />
|
||||
<UsingTask TaskName="ILLink.Tasks.ComputeManagedAssemblies" AssemblyFile="$(ILLinkTasksAssembly)" />
|
||||
|
||||
</Project>
|
||||
|
||||
11
external/linker/src/ILLink.Tasks/Utils.cs
vendored
11
external/linker/src/ILLink.Tasks/Utils.cs
vendored
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
using Mono.Linker;
|
||||
|
||||
public static class Utils
|
||||
{
|
||||
@@ -13,14 +12,4 @@ public static class Utils
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsCrossgenedAssembly (string fileName)
|
||||
{
|
||||
try {
|
||||
ModuleDefinition module = ModuleDefinition.ReadModule (fileName);
|
||||
return module.IsCrossgened ();
|
||||
} catch (BadImageFormatException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
external/linker/src/linker/ILLink.props
vendored
27
external/linker/src/linker/ILLink.props
vendored
@@ -1,27 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- net46 build is disabled until cecil uses SDK-style projects. -->
|
||||
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
|
||||
<DefineConstants>$(DefineConstants);FEATURE_ILLINK</DefineConstants>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AssemblyName>illink</AssemblyName>
|
||||
<!-- OutputType is Exe in Mono.Linker.csproj, but it needs to be set before importing SDK targets. -->
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- When publishing illink as a dependency of ILLink.Tasks, we want
|
||||
to include files needed to run it as an application in the
|
||||
publish output. See https://github.com/dotnet/sdk/issues/1675. -->
|
||||
<Target Name="AddRuntimeDependenciesToContent"
|
||||
BeforeTargets="GetCopyToOutputDirectoryItems"
|
||||
DependsOnTargets="GenerateBuildDependencyFile;GenerateBuildRuntimeConfigurationFiles"
|
||||
Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
|
||||
<ItemGroup>
|
||||
<ContentWithTargetPath Include="$(ProjectDepsFilePath)" CopyToOutputDirectory="PreserveNewest" TargetPath="$(ProjectDepsFileName)" />
|
||||
<ContentWithTargetPath Include="$(ProjectRuntimeConfigFilePath)" CopyToOutputDirectory="PreserveNewest" TargetPath="$(ProjectRuntimeConfigFileName)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -45,33 +45,34 @@ namespace Mono.Linker.Steps {
|
||||
}
|
||||
}
|
||||
|
||||
void RewriteBodyToLinkedAway (MethodDefinition method)
|
||||
protected virtual void RewriteBodyToLinkedAway (MethodDefinition method)
|
||||
{
|
||||
method.ImplAttributes &= ~(MethodImplAttributes.AggressiveInlining | MethodImplAttributes.Synchronized);
|
||||
method.ImplAttributes |= MethodImplAttributes.NoInlining;
|
||||
|
||||
method.Body = CreateThrowLinkedAwayBody (method);
|
||||
ClearDebugInformation (method);
|
||||
|
||||
method.ClearDebugInformation();
|
||||
}
|
||||
|
||||
void RewriteBodyToStub (MethodDefinition method)
|
||||
protected virtual void RewriteBodyToStub (MethodDefinition method)
|
||||
{
|
||||
if (!method.IsIL)
|
||||
throw new NotImplementedException ();
|
||||
|
||||
method.Body = CreateStubBody (method);
|
||||
|
||||
ClearDebugInformation (method);
|
||||
method.ClearDebugInformation();
|
||||
}
|
||||
|
||||
void RewriteBodyToFalse (MethodDefinition method)
|
||||
protected virtual void RewriteBodyToFalse (MethodDefinition method)
|
||||
{
|
||||
if (!method.IsIL)
|
||||
throw new NotImplementedException ();
|
||||
|
||||
method.Body = CreateReturnFalseBody (method);
|
||||
|
||||
ClearDebugInformation (method);
|
||||
method.ClearDebugInformation();
|
||||
}
|
||||
|
||||
MethodBody CreateThrowLinkedAwayBody (MethodDefinition method)
|
||||
@@ -80,7 +81,7 @@ namespace Mono.Linker.Steps {
|
||||
var il = body.GetILProcessor ();
|
||||
|
||||
// import the method into the current assembly
|
||||
var ctor = Context.MarkedKnownMembers.NotSupportedExceptionCtorString;
|
||||
MethodReference ctor = Context.MarkedKnownMembers.NotSupportedExceptionCtorString;
|
||||
ctor = assembly.MainModule.ImportReference (ctor);
|
||||
|
||||
il.Emit (OpCodes.Ldstr, "Linked away");
|
||||
@@ -98,7 +99,7 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
var il = body.GetILProcessor ();
|
||||
if (method.IsInstanceConstructor ()) {
|
||||
var base_ctor = GetDefaultInstanceConstructor (method.DeclaringType.BaseType);
|
||||
var base_ctor = method.DeclaringType.BaseType.GetDefaultInstanceConstructor();
|
||||
base_ctor = assembly.MainModule.ImportReference (base_ctor);
|
||||
|
||||
il.Emit (OpCodes.Ldarg_0);
|
||||
@@ -130,33 +131,5 @@ namespace Mono.Linker.Steps {
|
||||
il.Emit (OpCodes.Ret);
|
||||
return body;
|
||||
}
|
||||
|
||||
static MethodReference GetDefaultInstanceConstructor (TypeReference type)
|
||||
{
|
||||
foreach (var m in type.GetMethods ()) {
|
||||
if (m.HasParameters)
|
||||
continue;
|
||||
|
||||
var definition = m.Resolve ();
|
||||
if (!definition.IsDefaultConstructor ())
|
||||
continue;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
static void ClearDebugInformation (MethodDefinition method)
|
||||
{
|
||||
// TODO: This always allocates, update when Cecil catches up
|
||||
var di = method.DebugInformation;
|
||||
di.SequencePoints.Clear ();
|
||||
if (di.Scope != null) {
|
||||
di.Scope.Variables.Clear ();
|
||||
di.Scope.Constants.Clear ();
|
||||
di.Scope = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
154
external/linker/src/linker/Linker.Steps/MarkStep.cs
vendored
154
external/linker/src/linker/Linker.Steps/MarkStep.cs
vendored
@@ -46,6 +46,7 @@ namespace Mono.Linker.Steps {
|
||||
protected Queue<AttributeProviderPair> _assemblyLevelAttributes;
|
||||
protected Queue<AttributeProviderPair> _lateMarkedAttributes;
|
||||
protected List<TypeDefinition> _typesWithInterfaces;
|
||||
protected List<MethodBody> _unreachableBodies;
|
||||
|
||||
public AnnotationStore Annotations {
|
||||
get { return _context.Annotations; }
|
||||
@@ -64,6 +65,7 @@ namespace Mono.Linker.Steps {
|
||||
_assemblyLevelAttributes = new Queue<AttributeProviderPair> ();
|
||||
_lateMarkedAttributes = new Queue<AttributeProviderPair> ();
|
||||
_typesWithInterfaces = new List<TypeDefinition> ();
|
||||
_unreachableBodies = new List<MethodBody> ();
|
||||
}
|
||||
|
||||
public virtual void Process (LinkContext context)
|
||||
@@ -72,6 +74,7 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
Initialize ();
|
||||
Process ();
|
||||
Complete ();
|
||||
}
|
||||
|
||||
void Initialize ()
|
||||
@@ -93,6 +96,13 @@ namespace Mono.Linker.Steps {
|
||||
}
|
||||
}
|
||||
|
||||
void Complete ()
|
||||
{
|
||||
foreach (var body in _unreachableBodies) {
|
||||
Annotations.SetAction (body.Method, MethodAction.ConvertToThrow);
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeType (TypeDefinition type)
|
||||
{
|
||||
if (type.HasNestedTypes) {
|
||||
@@ -188,6 +198,7 @@ namespace Mono.Linker.Steps {
|
||||
ProcessQueue ();
|
||||
ProcessVirtualMethods ();
|
||||
ProcessMarkedTypesWithInterfaces ();
|
||||
ProcessPendingBodies ();
|
||||
DoAdditionalProcessing ();
|
||||
}
|
||||
|
||||
@@ -242,6 +253,17 @@ namespace Mono.Linker.Steps {
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessPendingBodies ()
|
||||
{
|
||||
for (int i = 0; i < _unreachableBodies.Count; i++) {
|
||||
var body = _unreachableBodies [i];
|
||||
if (Annotations.IsInstantiated (body.Method.DeclaringType)) {
|
||||
MarkMethodBody (body);
|
||||
_unreachableBodies.RemoveAt (i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessVirtualMethod (MethodDefinition method)
|
||||
{
|
||||
var overrides = Annotations.GetOverrides (method);
|
||||
@@ -449,7 +471,7 @@ namespace Mono.Linker.Steps {
|
||||
continue;
|
||||
|
||||
if (signature == null) {
|
||||
MarkMethod (m);
|
||||
MarkIndirectlyCalledMethod (m);
|
||||
marked = true;
|
||||
continue;
|
||||
}
|
||||
@@ -469,7 +491,7 @@ namespace Mono.Linker.Steps {
|
||||
if (i < 0)
|
||||
continue;
|
||||
|
||||
MarkMethod (m);
|
||||
MarkIndirectlyCalledMethod (m);
|
||||
marked = true;
|
||||
}
|
||||
|
||||
@@ -813,6 +835,9 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
bool ProcessLazyAttributes ()
|
||||
{
|
||||
if (Annotations.HasMarkedAnyIndirectlyCalledMethods () && MarkDisablePrivateReflectionAttribute ())
|
||||
return true;
|
||||
|
||||
var startingQueueCount = _assemblyLevelAttributes.Count;
|
||||
if (startingQueueCount == 0)
|
||||
return false;
|
||||
@@ -1035,6 +1060,7 @@ namespace Mono.Linker.Steps {
|
||||
_typesWithInterfaces.Add (type);
|
||||
|
||||
if (type.HasMethods) {
|
||||
MarkMethodsIf (type.Methods, IsVirtualNeededByTypeDueToPreservedScope);
|
||||
if (ShouldMarkTypeStaticConstructor (type))
|
||||
MarkStaticConstructor (type);
|
||||
|
||||
@@ -1346,7 +1372,38 @@ namespace Mono.Linker.Steps {
|
||||
MarkType (constraint);
|
||||
}
|
||||
|
||||
bool IsVirtualAndHasPreservedParent (MethodDefinition method)
|
||||
bool IsVirtualNeededByTypeDueToPreservedScope (MethodDefinition method)
|
||||
{
|
||||
if (!method.IsVirtual)
|
||||
return false;
|
||||
|
||||
var base_list = Annotations.GetBaseMethods (method);
|
||||
if (base_list == null)
|
||||
return false;
|
||||
|
||||
foreach (MethodDefinition @base in base_list) {
|
||||
// Just because the type is marked does not mean we need interface methods.
|
||||
// if the type is never instantiated, interfaces will be removed
|
||||
if (@base.DeclaringType.IsInterface)
|
||||
continue;
|
||||
|
||||
// If the type is marked, we need to keep overrides of abstract members defined in assemblies
|
||||
// that are copied. However, if the base method is virtual, then we don't need to keep the override
|
||||
// until the type could be instantiated
|
||||
if (!@base.IsAbstract)
|
||||
continue;
|
||||
|
||||
if (IgnoreScope (@base.DeclaringType.Scope))
|
||||
return true;
|
||||
|
||||
if (IsVirtualNeededByTypeDueToPreservedScope (@base))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsVirtualNeededByInstantiatedTypeDueToPreservedScope (MethodDefinition method)
|
||||
{
|
||||
if (!method.IsVirtual)
|
||||
return false;
|
||||
@@ -1359,7 +1416,7 @@ namespace Mono.Linker.Steps {
|
||||
if (IgnoreScope (@base.DeclaringType.Scope))
|
||||
return true;
|
||||
|
||||
if (IsVirtualAndHasPreservedParent (@base))
|
||||
if (IsVirtualNeededByTypeDueToPreservedScope (@base))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1683,6 +1740,12 @@ namespace Mono.Linker.Steps {
|
||||
MarkMethod (method);
|
||||
}
|
||||
|
||||
protected void MarkIndirectlyCalledMethod (MethodDefinition method)
|
||||
{
|
||||
MarkMethod (method);
|
||||
Annotations.MarkIndirectlyCalledMethod (method);
|
||||
}
|
||||
|
||||
protected virtual MethodDefinition MarkMethod (MethodReference reference)
|
||||
{
|
||||
reference = GetOriginalMethod (reference);
|
||||
@@ -1841,7 +1904,7 @@ namespace Mono.Linker.Steps {
|
||||
foreach (var method in type.Methods) {
|
||||
if (method.IsFinalizer ())
|
||||
MarkMethod (method);
|
||||
else if (IsVirtualAndHasPreservedParent (method))
|
||||
else if (IsVirtualNeededByInstantiatedTypeDueToPreservedScope (method))
|
||||
MarkMethod (method);
|
||||
}
|
||||
|
||||
@@ -1887,23 +1950,47 @@ namespace Mono.Linker.Steps {
|
||||
break;
|
||||
|
||||
case MethodAction.ConvertToThrow:
|
||||
if (_context.MarkedKnownMembers.NotSupportedExceptionCtorString != null)
|
||||
break;
|
||||
|
||||
var nse = BCL.FindPredefinedType ("System", "NotSupportedException", _context);
|
||||
if (nse == null)
|
||||
throw new NotSupportedException ("Missing predefined 'System.NotSupportedException' type");
|
||||
|
||||
MarkType (nse);
|
||||
|
||||
var nseCtor = MarkMethodIf (nse.Methods, KnownMembers.IsNotSupportedExceptionCtorString);
|
||||
if (nseCtor == null)
|
||||
throw new MarkException ($"Could not find constructor on '{nse.FullName}'");
|
||||
|
||||
_context.MarkedKnownMembers.NotSupportedExceptionCtorString = nseCtor;
|
||||
MarkAndCacheConvertToThrowExceptionCtor ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void MarkAndCacheConvertToThrowExceptionCtor ()
|
||||
{
|
||||
if (_context.MarkedKnownMembers.NotSupportedExceptionCtorString != null)
|
||||
return;
|
||||
|
||||
var nse = BCL.FindPredefinedType ("System", "NotSupportedException", _context);
|
||||
if (nse == null)
|
||||
throw new NotSupportedException ("Missing predefined 'System.NotSupportedException' type");
|
||||
|
||||
MarkType (nse);
|
||||
|
||||
var nseCtor = MarkMethodIf (nse.Methods, KnownMembers.IsNotSupportedExceptionCtorString);
|
||||
if (nseCtor == null)
|
||||
throw new MarkException ($"Could not find constructor on '{nse.FullName}'");
|
||||
|
||||
_context.MarkedKnownMembers.NotSupportedExceptionCtorString = nseCtor;
|
||||
}
|
||||
|
||||
bool MarkDisablePrivateReflectionAttribute ()
|
||||
{
|
||||
if (_context.MarkedKnownMembers.DisablePrivateReflectionAttributeCtor != null)
|
||||
return false;
|
||||
|
||||
var nse = BCL.FindPredefinedType ("System.Runtime.CompilerServices", "DisablePrivateReflectionAttribute", _context);
|
||||
if (nse == null)
|
||||
throw new NotSupportedException ("Missing predefined 'System.Runtime.CompilerServices.DisablePrivateReflectionAttribute' type");
|
||||
|
||||
MarkType (nse);
|
||||
|
||||
var ctor = MarkMethodIf (nse.Methods, MethodDefinitionExtensions.IsDefaultConstructor);
|
||||
if (ctor == null)
|
||||
throw new MarkException ($"Could not find constructor on '{nse.FullName}'");
|
||||
|
||||
_context.MarkedKnownMembers.DisablePrivateReflectionAttributeCtor = ctor;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MarkBaseMethods (MethodDefinition method)
|
||||
{
|
||||
@@ -2036,6 +2123,12 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
protected virtual void MarkMethodBody (MethodBody body)
|
||||
{
|
||||
if (_context.IsOptimizationEnabled (CodeOptimizations.UnreachableBodies) && IsUnreachableBody (body)) {
|
||||
MarkAndCacheConvertToThrowExceptionCtor ();
|
||||
_unreachableBodies.Add (body);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (VariableDefinition var in body.Variables)
|
||||
MarkType (var.VariableType);
|
||||
|
||||
@@ -2053,6 +2146,14 @@ namespace Mono.Linker.Steps {
|
||||
PostMarkMethodBody (body);
|
||||
}
|
||||
|
||||
bool IsUnreachableBody (MethodBody body)
|
||||
{
|
||||
return !body.Method.IsStatic
|
||||
&& !Annotations.IsInstantiated (body.Method.DeclaringType)
|
||||
&& MethodBodyScanner.IsWorthConvertingToThrow (body);
|
||||
}
|
||||
|
||||
|
||||
partial void PostMarkMethodBody (MethodBody body);
|
||||
|
||||
void MarkInterfacesNeededByBodyStack (MethodBody body)
|
||||
@@ -2226,7 +2327,7 @@ namespace Mono.Linker.Steps {
|
||||
if ((bindingFlags == BindingFlags.Default || bindingFlags.IsSet(BindingFlags.Public) == method.IsPublic) && method.Name == ".ctor") {
|
||||
Tracer.Push ($"Reflection-{method}");
|
||||
try {
|
||||
MarkMethod (method);
|
||||
MarkIndirectlyCalledMethod (method);
|
||||
} finally {
|
||||
Tracer.Pop ();
|
||||
}
|
||||
@@ -2244,7 +2345,7 @@ namespace Mono.Linker.Steps {
|
||||
&& method.Name == name) {
|
||||
Tracer.Push ($"Reflection-{method}");
|
||||
try {
|
||||
MarkMethod (method);
|
||||
MarkIndirectlyCalledMethod (method);
|
||||
} finally {
|
||||
Tracer.Pop ();
|
||||
}
|
||||
@@ -2264,8 +2365,13 @@ namespace Mono.Linker.Steps {
|
||||
// It is not easy to reliably detect in the IL code whether the getter or setter (or both) are used.
|
||||
// Be conservative and mark everything for the property.
|
||||
MarkProperty (property);
|
||||
MarkMethodIfNotNull (property.GetMethod);
|
||||
MarkMethodIfNotNull (property.SetMethod);
|
||||
|
||||
if (property.GetMethod != null)
|
||||
MarkIndirectlyCalledMethod (property.GetMethod);
|
||||
|
||||
if (property.SetMethod != null)
|
||||
MarkIndirectlyCalledMethod (property.SetMethod);
|
||||
|
||||
} finally {
|
||||
Tracer.Pop ();
|
||||
}
|
||||
|
||||
@@ -155,7 +155,10 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
WriterParameters SaveSymbols (AssemblyDefinition assembly)
|
||||
{
|
||||
var parameters = new WriterParameters ();
|
||||
var parameters = new WriterParameters {
|
||||
DeterministicMvid = Context.DeterministicOutput
|
||||
};
|
||||
|
||||
if (!Context.LinkSymbols)
|
||||
return parameters;
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace Mono.Linker.Steps {
|
||||
context.Annotations.AddPreservedMethod (calendar, ctor);
|
||||
// we need to mark the type or the above won't be processed
|
||||
context.Annotations.Mark (calendar);
|
||||
context.Annotations.MarkIndirectlyCalledMethod (ctor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
67
external/linker/src/linker/Linker.Steps/ReflectionBlockedStep.cs
vendored
Normal file
67
external/linker/src/linker/Linker.Steps/ReflectionBlockedStep.cs
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Mono.Linker.Steps
|
||||
{
|
||||
public class ReflectionBlockedStep : BaseStep
|
||||
{
|
||||
AssemblyDefinition assembly;
|
||||
|
||||
protected override void ProcessAssembly (AssemblyDefinition assembly)
|
||||
{
|
||||
this.assembly = assembly;
|
||||
|
||||
foreach (var type in assembly.MainModule.Types)
|
||||
ProcessType (type);
|
||||
}
|
||||
|
||||
void ProcessType (TypeDefinition type)
|
||||
{
|
||||
if (!HasIndirectCallers (type)) {
|
||||
AddCustomAttribute (type);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// We mark everything, otherwise we would need to check full visibility
|
||||
// hierarchy (e.g. public method inside private type)
|
||||
//
|
||||
foreach (var method in type.Methods) {
|
||||
if (!Annotations.IsIndirectlyCalled (method)) {
|
||||
AddCustomAttribute (method);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var nested in type.NestedTypes)
|
||||
ProcessType (nested);
|
||||
}
|
||||
|
||||
bool HasIndirectCallers (TypeDefinition type)
|
||||
{
|
||||
foreach (var method in type.Methods) {
|
||||
if (Annotations.IsIndirectlyCalled (method))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type.HasNestedTypes) {
|
||||
foreach (var nested in type.NestedTypes) {
|
||||
if (HasIndirectCallers (nested))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddCustomAttribute (ICustomAttributeProvider caProvider)
|
||||
{
|
||||
// We are using DisableReflectionAttribute which is not exact match but it's quite
|
||||
// close to what we need and it already exists in the BCL
|
||||
MethodReference ctor = Context.MarkedKnownMembers.DisablePrivateReflectionAttributeCtor;
|
||||
ctor = assembly.MainModule.ImportReference (ctor);
|
||||
|
||||
var ca = new CustomAttribute (ctor);
|
||||
caProvider.CustomAttributes.Add (ca);
|
||||
Annotations.Mark (ca);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ namespace Mono.Linker.Steps
|
||||
|
||||
public bool FeatureCOM { get; set; }
|
||||
public bool FeatureETW { get; set; }
|
||||
public bool FeatureSRE { get; set; }
|
||||
|
||||
//
|
||||
// Manually overrides System.Globalization.Invariant mode
|
||||
@@ -57,6 +58,20 @@ namespace Mono.Linker.Steps
|
||||
ExcludeEventSourceImplementation (type);
|
||||
}
|
||||
|
||||
if (FeatureSRE) {
|
||||
if (type.Namespace == "System" && type.Name == "RuntimeType") {
|
||||
foreach (var method in type.Methods) {
|
||||
if (method.Name == "MakeTypeBuilderInstantiation") {
|
||||
Annotations.SetAction (method, MethodAction.ConvertToThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FeatureGlobalization)
|
||||
ExcludeGlobalization (type);
|
||||
|
||||
if (RemoveCustomAttributes (type)) {
|
||||
if (FeatureCOM && type.IsImport) {
|
||||
type.IsImport = false;
|
||||
@@ -76,6 +91,66 @@ namespace Mono.Linker.Steps
|
||||
ProcessType (nested);
|
||||
}
|
||||
|
||||
void ExcludeGlobalization (TypeDefinition type)
|
||||
{
|
||||
switch (type.Namespace) {
|
||||
case "System.Globalization":
|
||||
switch (type.Name) {
|
||||
case "CalendarData":
|
||||
foreach (var method in type.Methods) {
|
||||
switch (method.Name) {
|
||||
case "GetJapaneseEraNames":
|
||||
case "GetJapaneseEnglishEraNames":
|
||||
Annotations.SetAction (method, MethodAction.ConvertToThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "DateTimeFormatInfo":
|
||||
foreach (var method in type.Methods) {
|
||||
switch (method.Name) {
|
||||
case "PopulateSpecialTokenHashTable":
|
||||
case "GetJapaneseCalendarDTFI":
|
||||
case "GetTaiwanCalendarDTFI":
|
||||
case "IsJapaneseCalendar":
|
||||
case "TryParseHebrewNumber":
|
||||
Annotations.SetAction (method, MethodAction.ConvertToThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "System":
|
||||
switch (type.Name) {
|
||||
case "DateTimeFormat":
|
||||
foreach (var method in type.Methods) {
|
||||
switch (method.Name) {
|
||||
case "HebrewFormatDigits":
|
||||
case "FormatHebrewMonthName":
|
||||
Annotations.SetAction (method, MethodAction.ConvertToThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "DateTimeParse":
|
||||
foreach (var method in type.Methods) {
|
||||
switch (method.Name) {
|
||||
case "GetJapaneseCalendarDefaultInstance":
|
||||
case "GetTaiwanCalendarDefaultInstance":
|
||||
case "ProcessHebrewTerminalState":
|
||||
case "GetHebrewDayOfNM":
|
||||
case "MatchHebrewDigits":
|
||||
Annotations.SetAction (method, MethodAction.ConvertToThrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ExcludeEventSource (TypeDefinition type)
|
||||
{
|
||||
var annotations = Context.Annotations;
|
||||
@@ -100,7 +175,8 @@ namespace Mono.Linker.Steps
|
||||
continue;
|
||||
}
|
||||
|
||||
annotations.SetAction (method, MethodAction.ConvertToThrow);
|
||||
if (MethodBodyScanner.IsWorthConvertingToThrow (method.Body))
|
||||
annotations.SetAction (method, MethodAction.ConvertToThrow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +225,7 @@ namespace Mono.Linker.Steps
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!skip)
|
||||
if (!skip && MethodBodyScanner.IsWorthConvertingToThrow (method.Body))
|
||||
annotations.SetAction (method, MethodAction.ConvertToThrow);
|
||||
}
|
||||
}
|
||||
@@ -166,7 +242,8 @@ namespace Mono.Linker.Steps
|
||||
{
|
||||
foreach (var method in type.Methods)
|
||||
{
|
||||
annotations.SetAction(method, MethodAction.ConvertToThrow);
|
||||
if (MethodBodyScanner.IsWorthConvertingToThrow (method.Body))
|
||||
annotations.SetAction(method, MethodAction.ConvertToThrow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,7 @@ namespace Mono.Linker.Steps
|
||||
void MarkMethod (MethodDefinition method)
|
||||
{
|
||||
InternalMark (method);
|
||||
Annotations.MarkIndirectlyCalledMethod (method);
|
||||
Annotations.SetAction (method, MethodAction.Parse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,6 +434,7 @@ namespace Mono.Linker.Steps {
|
||||
Context.LogMessage ($"Duplicate preserve in {_xmlDocumentLocation} of {method.FullName}");
|
||||
|
||||
Annotations.Mark (method);
|
||||
Annotations.MarkIndirectlyCalledMethod (method);
|
||||
Tracer.AddDirectDependency (this, method);
|
||||
Annotations.SetAction (method, MethodAction.Parse);
|
||||
}
|
||||
|
||||
@@ -285,6 +285,9 @@ namespace Mono.Linker.Steps {
|
||||
if (type.HasCustomAttributes)
|
||||
SweepCustomAttributes (type);
|
||||
|
||||
if (type.HasGenericParameters)
|
||||
SweepCustomAttributeCollection (type.GenericParameters);
|
||||
|
||||
if (type.HasProperties)
|
||||
SweepCustomAttributeCollection (type.Properties);
|
||||
|
||||
@@ -312,8 +315,10 @@ namespace Mono.Linker.Steps {
|
||||
{
|
||||
for (int i = type.Interfaces.Count - 1; i >= 0; i--) {
|
||||
var iface = type.Interfaces [i];
|
||||
if (Annotations.IsMarked (iface))
|
||||
if (Annotations.IsMarked (iface)) {
|
||||
SweepCustomAttributes (iface);
|
||||
continue;
|
||||
}
|
||||
InterfaceRemoved (type, iface);
|
||||
type.Interfaces.RemoveAt (i);
|
||||
}
|
||||
@@ -398,13 +403,16 @@ namespace Mono.Linker.Steps {
|
||||
SweepDebugInfo (methods);
|
||||
|
||||
foreach (var method in methods) {
|
||||
if (method.HasGenericParameters)
|
||||
SweepCustomAttributeCollection (method.GenericParameters);
|
||||
|
||||
SweepCustomAttributes (method.MethodReturnType);
|
||||
|
||||
if (!method.HasParameters)
|
||||
continue;
|
||||
|
||||
foreach (var parameter in method.Parameters)
|
||||
SweepCustomAttributes (parameter);
|
||||
|
||||
SweepCustomAttributes (method.MethodReturnType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
external/linker/src/linker/Linker/Annotations.cs
vendored
20
external/linker/src/linker/Linker/Annotations.cs
vendored
@@ -55,6 +55,8 @@ namespace Mono.Linker {
|
||||
protected readonly HashSet<CustomAttribute> marked_attributes = new HashSet<CustomAttribute> ();
|
||||
readonly HashSet<TypeDefinition> marked_types_with_cctor = new HashSet<TypeDefinition> ();
|
||||
protected readonly HashSet<TypeDefinition> marked_instantiated = new HashSet<TypeDefinition> ();
|
||||
protected readonly HashSet<MethodDefinition> indirectly_called = new HashSet<MethodDefinition>();
|
||||
|
||||
|
||||
public AnnotationStore (LinkContext context) => this.context = context;
|
||||
|
||||
@@ -142,6 +144,24 @@ namespace Mono.Linker {
|
||||
return marked_attributes.Contains (attribute);
|
||||
}
|
||||
|
||||
public void MarkIndirectlyCalledMethod (MethodDefinition method)
|
||||
{
|
||||
if (!context.AddReflectionAnnotations)
|
||||
return;
|
||||
|
||||
indirectly_called.Add (method);
|
||||
}
|
||||
|
||||
public bool HasMarkedAnyIndirectlyCalledMethods ()
|
||||
{
|
||||
return indirectly_called.Count != 0;
|
||||
}
|
||||
|
||||
public bool IsIndirectlyCalled (MethodDefinition method)
|
||||
{
|
||||
return indirectly_called.Contains (method);
|
||||
}
|
||||
|
||||
public void MarkInstantiated (TypeDefinition type)
|
||||
{
|
||||
marked_instantiated.Add (type);
|
||||
|
||||
@@ -30,14 +30,7 @@ using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle ("Mono.Linker")]
|
||||
[assembly: AssemblyDescription ("Mono CIL Linker")]
|
||||
[assembly: AssemblyConfiguration ("")]
|
||||
[assembly: AssemblyProduct ("")]
|
||||
[assembly: AssemblyCopyright ("(C) 2006, Jb Evain")]
|
||||
[assembly: AssemblyCulture ("")]
|
||||
|
||||
[assembly: CLSCompliant (false)]
|
||||
[assembly: ComVisible (false)]
|
||||
|
||||
[assembly: AssemblyVersion ("0.2.0.0")]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user