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

Support IL Trimming for projection assemblies #373

Closed
Scottj1s opened this issue Aug 25, 2020 · 15 comments
Closed

Support IL Trimming for projection assemblies #373

Scottj1s opened this issue Aug 25, 2020 · 15 comments
Labels
performance Related to performance work
Milestone

Comments

@Scottj1s
Copy link
Member

Scottj1s commented Aug 25, 2020

Proposal: Support for trimmable (ILLink) assemblies

Summary

Trimming is a great feature introduced with .NET 5, but CsWinRT does not yet support it. This should be fixed, so assembly sizes can be reduced.

Rationale

Trimming with ILLink provides great results when publishing self contained applications. I have reduced the size of the Microsoft.Windows.SDK.NET assembly by a factor of 45, taking it from 25mb to 0.55mb! I see the same great result in other projected libraries as well.

Since WinUI is using CoreCLR, trimming will be an important tool to keep assemblies small. Same goes for Xamarin apps using the desktop SDK.

Important Notes

Issues encountered so far:

  • Internal constructors, used by internal factories, are incorrectly trimmed.
  • Missing interfaces and types in the ABI namespace. Perhaps an explicit interface implementation could fix this.

As you can expect, the reflection-based factories in the ABI namespace quickly break, however, these types can manually be preserved by whitelisting them using a TrimmerRootDescriptor.

ILLink can be enabled by specifying the following properties:

<PublishTrimmed>true</PublishTrimmed>
<TrimMode>link</TrimMode>

To whitelist the Windows SDK for trimming:

<ItemGroup>
    <ManagedAssemblyToLink Condition="'%(Filename)' == 'Microsoft.Windows.SDK.NET'">
        <IsTrimmable>true</IsTrimmable>
    </ManagedAssemblyToLink>
</ItemGroup>

Further reading: https://github.com/mono/linker/blob/main/docs/data-formats.md

@Scottj1s Scottj1s added the performance Related to performance work label Aug 25, 2020
@AdamBraden AdamBraden added this to the Future milestone Oct 9, 2020
@angelazhangmsft angelazhangmsft modified the milestones: Future, NET5 vNext Mar 11, 2021
@angelazhangmsft
Copy link
Contributor

angelazhangmsft commented Mar 11, 2021

C#/Win32 ask for C#/WinRT (.NET 6 timeframe) - IL Trimming could remove baggage from the TFM.

cc @mikebattista

@mikebattista
Copy link

Thanks Angela. As we integrate more support in the TFMs for things like C#/Win32, we don't want apps to then have to carry around baggage for things they may not even be using. Pay for play is definitely the right model here, so leveraging assembly trimming for that would benefit C#/WinRT customers as well as C#/Win32 customers. It would be a great story to say that setting your TFM gets you access to all Windows APIs without any baggage. You only pay for what you use.

@angelazhangmsft angelazhangmsft modified the milestones: NET5 vNext, Future Apr 5, 2021
@jkoritzinsky
Copy link
Member

After speaking with the IL linker team, it looks like there's a few things we'll need:

  1. Reference and look up ABI.* and ABI.Impl.* types via attributes instead of using Type.GetType (we'll need to keep Type.GetType as a fallback for back-compat)
  2. Annotate the generated code and WinRT.Runtime with linker dataflow annotations and warning suppressions as needed. CsWinRT needs to be careful to manually propagate the linker annotations on methods and types called via reflection with MakeGenericType and MakeGenericMethod so the annotations don't get lost in the process.

@angelazhangmsft angelazhangmsft changed the title Harden winrt.runtime.dll, projection output to enable IL trimming Support IL Trimming for projection assemblies Nov 4, 2021
@snickler
Copy link

snickler commented Nov 5, 2021

Hi all,

Has there been updates on this effort? With. NET 6 coming out next week and especially the focus on NativeAOT in .NET 7, the lack of IL Trimming means that those migrating away from. NET Native and UWP will have to deal with larger binaries.

@angelazhangmsft
Copy link
Contributor

@snickler - This is a priority for the C#/WinRT team. It is penciled in for spring 2022, but we are doing another planning review before then, so things may change.

@riverar
Copy link

riverar commented Jan 10, 2022

Please continue to target .NET 6.0 with your efforts as that is now LTS.

@Balkoth
Copy link

Balkoth commented Feb 18, 2022

I am hoping this is coming soon, because a small 700KB WinForms app, was bloated to a 60MB WindowsAppADK app.

@Samuel12321
Copy link

@angelazhangmsft any updates of progress or current roadmap?

@CXCubeHD
Copy link

CXCubeHD commented Sep 2, 2022

I also find that IL Trimming should have more development, since IL Trimming in NativeAOT is a requirement. My project depends on whether this will or won't be supported. Right now I am limited to a very small amount of APIs.

WinUI3 is also very dependend on that so it would be highly appreciated if there was more development regarding that issue.

@mikebattista
Copy link

There's been good progress on the C#/WinRT front. @manodasanW can comment on that.

@CXCubeHD
Copy link

CXCubeHD commented Sep 3, 2022

That sounds great ^^

@manodasanW
Copy link
Member

With CsWinRT 2.0, IL trimming is now supported. The Windows SDK projection has been updated to use that version and mark it as trimmable which is available in .NET SDK 6.0.109, 6.0.304 or 6.0.401 or later. Similarly, WinAppSDK 1.2 preview 2 has also been updated to use that CsWinRT version and mark its C#/WinRT projection assemblies trimmable.

Application on those versions can enable PublishedTrimmed in their publish profile and see improvements to their app's disk footprint. You should make sure to thoroughly test your application with trimming enabled to ensure any necessary types didn't get trimmed or result in a change in behaviour.

@manodasanW manodasanW modified the milestones: Future, Release 2.0.0 Oct 19, 2022
@hez2010
Copy link
Contributor

hez2010 commented Oct 23, 2022

Seems that it still doesn't work. We are getting 0xc000027b in Microsoft.UI.Xaml.dll after enabling trimming (TrimMode=link).

@manodasanW
Copy link
Member

@hez2010 0xc000027b indicates a stowed exception and we will need to figure out what the actual exception was. Have you been able to run your trimmed app under a debugger and see if you see any exceptions thrown and get the stacks for them? That should help figure out where the issue is.

@hez2010
Copy link
Contributor

hez2010 commented Jan 2, 2023

I first encountered "failure to parse XAML", but it turned out to be the CommunityToolkit isn't compatible with trimming. After rooting all CommunityToolkit assemblies, I encountered 0xc0000005 due to "class is not registered":

onecore\com\combase\objact\objact.cxx(4070)\combase.dll!00007FFBAAFE5175: (caller: 00007FFBAAFECEBA) ReturnHr(7) tid(44bc) 80040154 クラスが登録されていません
(7638.2018): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries
windows_storage!CShellLibrary::_GetFirstMatchingFolder+0x49:
00007ffb`a745d089 488b4008        mov     rax,qword ptr [rax+8] ds:00000000`00000008=????????????????
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries
Unable to read dynamic function table entries

The exception happened at https://dev.azure.com/microsoft/OS/_apis/git/repositories/os.2020/items?path=/onecore/com/combase/objact/objact.cxx&versionDescriptor.versionType=commit&versionDescriptor.version=791ab59ca0476c59ad47a3cb5e6f0730e26425ba&versionDescriptor.options=none&download=true&api-version=2.0, but apparently I don't have any access to Microsoft internal code.

Stacktrace:

image

It may not be caused by WinAppSDK/CsWinRT (because we are also using COM interop). Will post an update if I have further information.

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

No branches or pull requests