Skip to content

Trimmed assemblies should not contain sig and opt data #15605

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

Open
kerams opened this issue Jul 17, 2023 · 14 comments
Open

Trimmed assemblies should not contain sig and opt data #15605

kerams opened this issue Jul 17, 2023 · 14 comments
Labels
Area-AOT Everything related to AOT Feature Request

Comments

@kerams
Copy link
Contributor

kerams commented Jul 17, 2023

Is your feature request related to a problem? Please describe.

F# assemblies in a trimmed application contain signature and optimization data.

Describe the solution you'd like

These resources serve no purpose in a deployed application and should be stripped.

Describe alternatives you've considered

A post-build task that iterates over and modifies the emitted assemblies.

Additional context

8.0.100-preview.6.23330.14

@vzarytovskii
Copy link
Member

I don't think we want to be tied to specifics of trimming tasks implementation in FSharp.Build, what we can theoretically do, is generate the ILLink.Substitutions.xml file, however this can become very tricky very soon, if user wants a custom one.

So we probably want to:
a. Generate default ILLink.Substituions.xml
b. A way for user to opt-out, if they want a custom one.

@kerams does this sound feasible?

@kerams
Copy link
Contributor Author

kerams commented Jul 17, 2023

No clue, I know little about the trimming infrastructure.

@kerams
Copy link
Contributor Author

kerams commented Jul 17, 2023

In case anyone needs this, here's a snippet that removes the aforementioned resources on all F# assemblies using Mono.Cecil. Run it once trimming has completed.

for f in Directory.EnumerateFiles (serverDir, "*.dll") do
    use m = ModuleDefinition.ReadModule (f, ReaderParameters (ReadWrite = true))

    let toRemove =
        m.Resources
        |> Seq.filter (fun x -> x.Name.StartsWith "FSharpSignature" || x.Name.StartsWith "FSharpOptimization")
        |> Seq.toList

    if not toRemove.IsEmpty then
        for res in toRemove do
            m.Resources.Remove res |> ignore

        m.Write ()

@vzarytovskii
Copy link
Member

In case anyone needs this, here's a snippet that removes the aforementioned resources on all F# assemblies using Mono.Cecil. Run it once trimming has completed.

for f in Directory.EnumerateFiles (serverDir, "*.dll") do
    use m = ModuleDefinition.ReadModule (f, ReaderParameters (ReadWrite = true))

    let toRemove =
        m.Resources
        |> Seq.filter (fun x -> x.Name.StartsWith "FSharpSignature" || x.Name.StartsWith "FSharpOptimization")
        |> Seq.toList

    if not toRemove.IsEmpty then
        for res in toRemove do
            m.Resources.Remove res |> ignore

        m.Write ()

It is not needed, just create the xml file for your library, illink will trim it.

@kerams
Copy link
Contributor Author

kerams commented Jul 17, 2023

For every single referenced assembly, every time I add a new one? I don't think so :).

@vzarytovskii
Copy link
Member

For every single referenced assembly, every time I add a new one? I don't think so :).

For your assemblies, if you want trimming to be supported. We don't want to be trimming resources from anyone else's assemblies for sure.

@kerams
Copy link
Contributor Author

kerams commented Jul 17, 2023

I don't see why I would ever want to retain signature and optimization data when publishing, regardless of where an assembly comes from, or even if it is actually being trimmed. Feel free to close - I can just use that script.

@KevinRansom
Copy link
Member

I will fix it, it is a bug not a feature request.

@albertwoo
Copy link

When is this regression bug can be fixed? It’s been a year and this bug is in dotnet 9 now.

@vzarytovskii
Copy link
Member

I'm not convinced it's a bug. At best a missing feature. I am not aware whether it's planned for future or not.

@albertwoo
Copy link

But it behaves very different like before. For my projects or for my libraries consumers, it will be a bug.

@vzarytovskii
Copy link
Member

vzarytovskii commented Nov 13, 2024

But it behaves very different like before. For my projects or for my libraries consumers, it will be a bug.

Just to reiterate - these resources are essential for nuget libraries, compiler uses them to do optimizations, inlining, get additional type and nullness information.

For published apps, they aren't trimmed, and never were (unless you explicitly list them in the xml file, as I suggested in the other issue), because ILLink is not aware of them, there has to be a dedicated support on ILLink side or we shall generate it in FSharp.Build (or there should be another way of telling trimmer to get rid of them), but we have to be very careful in what we trim by default, since it can affect library authors significantly.

@KevinRansom @T-Gro we need to figure out what would be the best by-default behaviour for both libraries and published apps, I think that

  1. For libraries, nothing should be trimmed, as this data is essential for compiler when library is consumed from nuget/reference project
  2. For publishing (i.e. standalone apps), I think there should be some way of letting trimmer know we don't need this data (since it's not needed at runtime).

@vitek-karas Is there a way to tell trimmer (via some properties perhaps) that certain resource for given assembly is not needed? Or is .xml file the only way?

@vitek-karas
Copy link
Member

The feature where trimmer can remove resources from assemblies is not official functionality - we use it internally to make some things smaller, but it's not meant (at least yet) to be a general feature. It is currently only available via XML files and I haven't seen any plan to make it more prominent.

@sbomer for more context.

I think the best solution for F# would be to inject the XML into the dll when it compiles it. Libraries themselves are never trimmed, trimming only happens during a publish of the final app, so the XML only triggers during app build. That is if we are OK for FSharp to take a dependency on this functionality (which is not meant to be a public contract yet). But I'll let @sbomer comment on this, he's the owner right now.

@Numpsy
Copy link

Numpsy commented Apr 21, 2025

Looking around at the linker I see this: https://github.com/dotnet/runtime/blob/d9c4c3e73dcf09435a3cc1cabb23584c9f24b504/src/tools/illink/src/linker/Linker.Steps/RemoveResourcesStep.cs#L35 which seems to have come about as a a result of dotnet/linker#329, and I wonder if there is a reason to treat compressed and not-compressed data differently, or is it just an accident due to the compressed names starting with 'FSharpSignatureCompressed' instead of 'FSharpSignatureData' ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-AOT Everything related to AOT Feature Request
Projects
Status: New
Development

No branches or pull requests

7 participants