Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion corebuild/integration/ILLink.Tasks/ILLink.Tasks.targets
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@
the future we will want to generate these depending on the
scenario in which the linker is invoked. -->
<PropertyGroup>
<ExtraLinkerArgs Condition=" '$(ExtraLinkerArgs)' == '' ">-t -l none -b true</ExtraLinkerArgs>
<ExtraLinkerArgs Condition=" '$(ExtraLinkerArgs)' == '' ">-t -l none -b true --skip-unresolved true</ExtraLinkerArgs>
</PropertyGroup>
<ILLink AssemblyPaths="@(_ManagedAssembliesToLink)"
RootAssemblyNames="@(LinkerRootAssemblies)"
Expand Down
8 changes: 2 additions & 6 deletions linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,9 @@ void Process ()

if (!isForwarder)
continue;
TypeDefinition type = null;
try {
type = exported.Resolve ();
}
catch (AssemblyResolutionException) {
TypeDefinition type = exported.Resolve ();
if (type == null)
continue;
}
if (!Annotations.IsMarked (type))
continue;
Tracer.Push (type);
Expand Down
7 changes: 1 addition & 6 deletions linker/Linker.Steps/ResolveFromAssemblyStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,7 @@ public static void ProcessLibrary (LinkContext context, AssemblyDefinition assem

if (!isForwarder)
continue;
TypeDefinition resolvedExportedType = null;
try {
resolvedExportedType = exported.Resolve ();
} catch (AssemblyResolutionException) {
continue;
}
TypeDefinition resolvedExportedType = exported.Resolve ();

if (resolvedExportedType == null) {
//
Expand Down
7 changes: 1 addition & 6 deletions linker/Linker.Steps/ResolveFromXmlStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,7 @@ void MatchExportedType (ExportedType exportedType, ModuleDefinition module, Rege
{
if (regex.Match (exportedType.FullName).Success) {
MarkingHelpers.MarkExportedType (exportedType, module);
TypeDefinition type = null;
try {
type = exportedType.Resolve ();
}
catch (AssemblyResolutionException) {
}
TypeDefinition type = exportedType.Resolve ();
if (type != null) {
ProcessType (type, nav);
}
Expand Down
8 changes: 2 additions & 6 deletions linker/Linker.Steps/SweepStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,9 @@ void SweepReferences (AssemblyDefinition assembly, AssemblyDefinition target)
var references = assembly.MainModule.AssemblyReferences;
for (int i = 0; i < references.Count; i++) {
var reference = references [i];
AssemblyDefinition r = null;
try {
r = Context.Resolver.Resolve (reference);
}
catch (AssemblyResolutionException) {
AssemblyDefinition r = Context.Resolver.Resolve (reference);
if (r == null)
continue;
}
if (!AreSameReference (r.Name, target.Name))
continue;

Expand Down
33 changes: 29 additions & 4 deletions linker/Linker/AssemblyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public class AssemblyResolver : BaseAssemblyResolver {
#endif

readonly Dictionary<string, AssemblyDefinition> _assemblies;
HashSet<string> _unresolvedAssemblies;
bool _ignoreUnresolved;
LinkContext _context;

public IDictionary<string, AssemblyDefinition> AssemblyCache {
get { return _assemblies; }
Expand All @@ -55,12 +58,32 @@ public AssemblyResolver (Dictionary<string, AssemblyDefinition> assembly_cache)
_assemblies = assembly_cache;
}

public bool IgnoreUnresolved {
get { return _ignoreUnresolved; }
set { _ignoreUnresolved = value; }
}

public LinkContext Context {
get { return _context; }
set { _context = value; }
}

public override AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be better to pass LinkContext Context as the parameter

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that the Resolve method signature is part of IAssemblyResolver, defined in cecil. I want warnings to be logged when an assembly can't be resolved while trying to resolve TypeReferences to TypeDefinitions using cecil, for example. Do you have any suggestions?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I see

{
AssemblyDefinition asm;
if (!_assemblies.TryGetValue (name.Name, out asm)) {
asm = base.Resolve (name, parameters);
_assemblies [asm.Name.Name] = asm;
AssemblyDefinition asm = null;
if (!_assemblies.TryGetValue (name.Name, out asm) && (_unresolvedAssemblies == null || !_unresolvedAssemblies.Contains (name.Name))) {
try {
asm = base.Resolve (name, parameters);
_assemblies [name.Name] = asm;
} catch (AssemblyResolutionException) {
if (!_ignoreUnresolved)
throw;

_context.LogMessage ($"warning: unresolved assembly {name.Name}");
if (_unresolvedAssemblies == null)
_unresolvedAssemblies = new HashSet<string> ();
_unresolvedAssemblies.Add (name.Name);
}
}

return asm;
Expand All @@ -80,6 +103,8 @@ protected override void Dispose (bool disposing)
}

_assemblies.Clear ();
if (_unresolvedAssemblies != null)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just set it to null

_unresolvedAssemblies.Clear ();
}
}
}
6 changes: 4 additions & 2 deletions linker/Linker/Driver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ public void Run (ILogger customLogger = null)
Usage ("Option is too short");

if (token == "--skip-unresolved") {
context.IgnoreUnresolved = bool.Parse (GetParam ());
bool ignoreUnresolved = bool.Parse (GetParam ());
context.IgnoreUnresolved = ignoreUnresolved;
context.Resolver.IgnoreUnresolved = ignoreUnresolved;
continue;
}

Expand Down Expand Up @@ -343,7 +345,7 @@ static void Usage (string msg)

Console.WriteLine (" --about About the {0}", _linker);
Console.WriteLine (" --version Print the version number of the {0}", _linker);
Console.WriteLine (" --skip-unresolved Ignore unresolved types and methods (true or false)");
Console.WriteLine (" --skip-unresolved Ignore unresolved types, methods, and assemblies (true or false)");
Console.WriteLine (" --dependencies-file Specify the dependencies file path, if unset the default path is used: <output directory>/linker-dependencies.xml.gz");
Console.WriteLine (" --dump-dependencies Dump dependencies for the linker analyzer tool");
Console.WriteLine (" --reduced-tracing Reduces dependency output related to assemblies that will not be modified");
Expand Down
11 changes: 5 additions & 6 deletions linker/Linker/LinkContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ public LinkContext (Pipeline pipeline, AssemblyResolver resolver, ReaderParamete
{
_pipeline = pipeline;
_resolver = resolver;
_resolver.Context = this;
_actions = new Dictionary<string, AssemblyAction> ();
_parameters = new Dictionary<string, string> ();
_readerParameters = readerParameters;
Expand Down Expand Up @@ -208,7 +209,7 @@ public AssemblyDefinition Resolve (IMetadataScope scope)
try {
AssemblyDefinition assembly = _resolver.Resolve (reference, _readerParameters);

if (SeenFirstTime (assembly)) {
if (assembly != null && SeenFirstTime (assembly)) {
SafeReadSymbols (assembly);
SetAction (assembly);
}
Expand Down Expand Up @@ -248,11 +249,9 @@ public virtual ICollection<AssemblyDefinition> ResolveReferences (AssemblyDefini
{
List<AssemblyDefinition> references = new List<AssemblyDefinition> ();
foreach (AssemblyNameReference reference in assembly.MainModule.AssemblyReferences) {
try {
references.Add (Resolve (reference));
}
catch (AssemblyResolutionException) {
}
AssemblyDefinition definition = Resolve (reference);
if (definition != null)
references.Add (definition);
}
return references;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace Mono.Linker.Tests.Cases.Expectations.Metadata {
public sealed class SkipUnresolvedAttribute : BaseMetadataAttribute {
public readonly bool Value;

public SkipUnresolvedAttribute (bool value)
{
Value = value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<Compile Include="Metadata\NotATestCaseAttribute.cs" />
<Compile Include="Metadata\ReferenceAttribute.cs" />
<Compile Include="Metadata\SandboxDependencyAttribute.cs" />
<Compile Include="Metadata\SkipUnresolvedAttribute.cs" />
<Compile Include="Assertions\KeptBaseTypeAttribute.cs" />
<Compile Include="Assertions\KeptInterfaceAttribute.cs" />
<Compile Include="Assertions\KeptAttributeAttribute.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Mono.Linker.Tests.Cases.TypeForwarding
{
[SkipUnresolved (true)]
[Define ("IL_ASSEMBLY_AVAILABLE")]
[SetupCompileBefore ("TypeForwarderMissingReference.dll", new [] { "Dependencies/TypeForwarderMissingReference.il" })]
[SetupLinkerAction ("link", "TypeForwarderMissingReference.dll")]
Expand Down
10 changes: 10 additions & 0 deletions linker/Tests/TestCasesRunner/LinkerArgumentBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ public virtual void AddAssemblyAction (string action, string assembly)
Append (assembly);
}

public virtual void AddSkipUnresolved (bool skipUnresolved)
{
if (skipUnresolved) {
Append ("--skip-unresolved");
Append ("true");
}
}

public string [] ToArgs ()
{
return _arguments.ToArray ();
Expand Down Expand Up @@ -108,6 +116,8 @@ public virtual void ProcessOptions (TestCaseLinkerOptions options)
if (!string.IsNullOrEmpty (options.LinkSymbols))
AddLinkSymbols (options.LinkSymbols);

AddSkipUnresolved (options.SkipUnresolved);

// Unity uses different argument format and needs to be able to translate to their format. In order to make that easier
// we keep the information in flag + values format for as long as we can so that this information doesn't have to be parsed out of a single string
foreach (var additionalArgument in options.AdditionalArguments)
Expand Down
1 change: 1 addition & 0 deletions linker/Tests/TestCasesRunner/TestCaseLinkerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class TestCaseLinkerOptions
public bool IncludeBlacklistStep;
public string KeepTypeForwarderOnlyAssemblies;
public string LinkSymbols;
public bool SkipUnresolved;

public List<KeyValuePair<string, string[]>> AdditionalArguments = new List<KeyValuePair<string, string[]>> ();
}
Expand Down
3 changes: 2 additions & 1 deletion linker/Tests/TestCasesRunner/TestCaseMetadaProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public virtual TestCaseLinkerOptions GetLinkerOptions ()
IncludeBlacklistStep = GetOptionAttributeValue (nameof (IncludeBlacklistStepAttribute), false),
KeepTypeForwarderOnlyAssemblies = GetOptionAttributeValue (nameof (KeepTypeForwarderOnlyAssembliesAttribute), string.Empty),
LinkSymbols = GetOptionAttributeValue (nameof (SetupLinkerLinkSymbolsAttribute), string.Empty),
CoreAssembliesAction = GetOptionAttributeValue<string> (nameof (SetupLinkerCoreActionAttribute), null)
CoreAssembliesAction = GetOptionAttributeValue<string> (nameof (SetupLinkerCoreActionAttribute), null),
SkipUnresolved = GetOptionAttributeValue (nameof (SkipUnresolvedAttribute), false)
};

foreach (var assemblyAction in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkerActionAttribute)))
Expand Down