dotnet / linker

387 stars 126 forks source link

Missing predefined 'System.NotSupportedException' type when linking library #3145

Open madelson opened 1 year ago

madelson commented 1 year ago

I'm trying to use the illink cli to reduce the size of a set of assemblies I've converted from Java with IKVM in order to (hopefully) ship them as a small library.

When I run the linker on my project bin directory, I get these errors:

ILLink: error IL1009: Assembly reference 'System.Runtime' could not be resolved.
ILLink: error IL1040: Type 'System.Object' reference could not be resolved.
ILLink: error IL1040: Type 'System.String' reference could not be resolved.
ILLink: error IL1007: Missing predefined 'System.NotSupportedException' type".

I added the --skip-unresolved flag, but I still get this error:

ILLink: error IL1007: Missing predefined 'System.NotSupportedException' type".

Is this expected?

vitek-karas commented 1 year ago

Not exactly expected, but not surprising. We mainly test scenarios which are exercised via the .NET SDK. Invocation of illink directly from the command line is effectively unsupported. So it's surprised if there's a regression or some specific thing not working.

For this specific case you can workaround it by passing in --disable-opt unreachablebodies.

That said, why are you hitting so many unresolved symbols? Why not pass all the required assemblies as references via -reference ?

madelson commented 1 year ago

Thanks for your quick response @vitek-karas !

For this specific case you can workaround it by passing in --disable-opt unreachablebodies.

This does seem to work. Thanks! Still need to test if the trimmed assemblies are functional, but at least the linker is succeeding!

That said, why are you hitting so many unresolved symbols?

I'd love to know the answer to this question as well. This is my first time using the linker, so I may be doing something dumb. I have a .NET 6 class library with an IKVM <MavenReference> generating a bunch of .NET dlls in my bin directory.

I'm running illink like this:

> cd MyProject/bin/Debug/net6.0
> dotnet /c/Program\ Files/dotnet/sdk/7.0.100/Sdks/Microsoft.NET.ILLink.Tasks/tools/net7.0/illink.dll -a ./MyProject.dll visible -d . && echo success

This fails, but when I add both --skip-unresolved and --disable-opt unreachablebodies it succeeds (although there are many instances of Trim analysis warning IL2117).

Why not pass all the required assemblies as references via -reference ?

I don't see that option documented here so I'm not sure how to use it. I tried passing -reference System.Runtime but that didn't seem to do anything. Maybe I need to pass the path to the assembly file wherever it lives in the dotnet installation?

vitek-karas commented 1 year ago

The -reference takes a file path.

The doc you refer to is kind of a "what we needed at one point" and definitely needs some love to bring up to par.

Probably the best inspiration for what you're trying to do would be to play with the dotnet/runtime repo. If you build the libraries - so something like build Clr+Libs /bl open the binlog and search for $task ILLink - don't look at the sfx and oob ones, but pick one of the assemblies. In there we run the linker to trim a single library.

As noted above, this mode is not really supported - as in, we try to make it to work, but the only config where we guanartee it works in are the cases in runtime repo.