Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trimming default WPF app breaks it #14261

Closed
vitek-karas opened this issue Oct 21, 2020 · 6 comments
Closed

Trimming default WPF app breaks it #14261

vitek-karas opened this issue Oct 21, 2020 · 6 comments
Assignees

Comments

@vitek-karas
Copy link
Member

vitek-karas commented Oct 21, 2020

dotnet new wpf
dotnet publish -r win-x64 /p:PublishTrimmed=true
run the app

Running the app "does nothing" no window shows up.

Note that this is a regression from 3.1 where this worked.

Used: 5.0.100-rtm.20515.8 SDK

@DavidZidar
Copy link

I am looking for guidance on how to publish a WPF app using PublishTrimmed, I am fine with manually adding TrimmerRootAssembly entries to my project but I need to know which ones to add.

@vitek-karas
Copy link
Member Author

This is probably a combination of linker changes (being more precise) and WPF changes.

System.Runtime

It's referenced from code which linker doesn't see, because the module .cctor for PresentationCore contains code like:
Assembly.GetExecutingAssembly().GetType(...).GetMethod(...).Invoke() - linker doesn't recognize this pattern and won't follow it, even though it's fully hardcoded values.

Note that this is injected via ILDASM/ILASM from this file https://github.com/dotnet/wpf/blob/master/eng/WpfArcadeSdk/tools/InjectModuleInitializer/ModuleInitializer.il

System.Runtime.Extensions

It's referenced from the C++/CLI assembly DirectWriterForwarder.
It should probably be added to https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/PresentationCore/ILLinkTrim.xml

System.Diagnostics.Debug

Again referenced from DirectWriterFormatter
It's already listed in https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/PresentationCore/ILLinkTrim.xml so either it's not correctly embedded or linker doesn't read it right.

So as a workaround I added:

  <ItemGroup>
    <TrimmerRootAssembly Include="System.Runtime"/>
    <TrimmerRootAssembly Include="System.Runtime.Extensions"/>
    <TrimmerRootAssembly Include="System.Diagnostics.Debug"/>
  </ItemGroup>

To the project and now the empty template app works (checked that there are no exceptions at runtime either).
That doesn't mean that once the app starts actually doing something it won't fail on other assemblies missing.

The size savings are interesting but not amazing. Untrimmed size: 148MB, trimmed size: 91MB.

@jkotas
Copy link
Member

jkotas commented Nov 26, 2020

Note that this is injected via ILDASM/ILASM from this file

This should be replaced by the proper C# module initializer now that that C# can emit them.

@vitek-karas
Copy link
Member Author

I just tried using the module initializer and it fixes the problem with that part of the code https://github.com/vitek-karas/wpf/tree/UseModuleInit. But it uncovers another problem:

  • The module initializer has a direct reference to DirectWriterForwarder which is a C++/CLI assembly
  • SDK detects this and doesn't pass the assembly to the linker as one of the inputs, but linker will find it out anyway (probing) and will process it.
  • But it seems linker runs it through Cecil (roundtrip) which changes the assembly. It's unclear how much of the assembly actually survives the linking in a working state. The assembly is smaller by about 30KB and looking at it in ILSpy it looks different.

@agocke
Copy link
Member

agocke commented Mar 23, 2021

Closing as dup of dotnet/wpf#3811

@vatsan-madhavan
Copy link
Member

vatsan-madhavan commented Mar 31, 2021

This should be replaced by the proper C# module initializer now that that C# can emit them.

👍

Replacing this infrastructure is exactly why @rladuca and I pushed for the C# module-initializer feature (along with many others for many other good reasons). This should absolutely be changed in .NET 6. The ILASM/ILDASM trick is ok for now, but it's meta-stable at best.

/cc @SamBent @ryalanms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants