Skip to content

Improve how trimmer finds out about native->managed dependencies in CoreLib #51991

Open

Description

@vitek-karas

There are lot of managed methods in System.Private.CoreLib which are called from the runtime native code. These are dependencies which trimming tools like ILLinker can't automatically detect. For this purpose CoreLib includes ILLink.Descriptors.xml file embedded in it to "root" all of these methods (and fields).

Currently parts of this file are created manually in CoreCLR and Shared. The rest is generated from C++ header files. The generation happens in a custom target which uses a custom task. These parse the corelib.h and coupe of other headers.

Existing problems with this approach:

  • Relatively hard to maintain - lot of different pieces have to work
  • Manual parsing of C++ headers is very limited and can easily break
  • Adding new functionality is inconsistent and makes the whole system even more fragile
    • Make the custom parser understand ifdefs
    • Introduce ability to conditionally root things based on feature switches

Potential improvements

Use C++ preprocessor

Instead of custom parsing the C++ headers, run them through a real C++ preprocessor with custom definitions of the macros. Produce easily parseable output (for example XML) which is then consumed by the custom task to produce the descriptor. This is relatively tricky to implement though:

  • We can't really run it during coreclr build - it would mean that building CoreLib requires output from CoreCLR build - which is a new dependency and the infra team really doesn't like this (it would also mean that dotnet build on CoreLib would basically never work fully).
  • Running CMake from CoreLib build is a possibility, but it's complex and probably slow (we already have 3 places we start native build pipeline in the runtime repo, this would introduce a new one - while we're trying hard to go down to just 1 place ideally).
  • That leaves running the preprocessor directly (without CMake) from the CoreLib build. This is probably not that hard since we have scripts to find the compiler path - Windows to get cl.exe on PATH, Linux, macOS to get clang path into CC/CXX. That said it's still not exactly easy as we would be adding a new thing into the pipeline for CoreLib - the risk here is that we have to construct the compiler command line by hand - making that work on all the platforms could be time consuming.
    • This also comes with a downside - we would not run it in the same environment as within CoreCLR build, for example we would have to propagate the defines manually.

It would remove the custom parser and greatly reduce fragility around C++ headers. It would also make it easier to add new features (like the feature switches)

Move away from descriptors and use attributes

Ideally we should move away from the descriptor XML files. Instead replace them with attributes in managed code. We could use DynamicDependencyAttribute, or potentially even introduce a new one.
If combined with moving some key parts from native to managed it could also make the whole product easier to trim (with greater size wins).

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Apr 28, 2021
  2. eerhardt commented on Apr 28, 2021

    @eerhardt
    Member

    Move away from descriptors and use attributes

    I think this makes the most sense, honestly. It also helps document "this managed code is called from the runtime". Plus it resolves all the "this member in the ILLink.Descriptors.xml file doesn't exist in the x86/Linux/arm/etc version of System.Private.CoreLib" issues we have. The attribute we use doesn't even have to be public, as it should only ever be used in CoreLib.

  3. eerhardt commented on Apr 28, 2021

    @eerhardt
    Member

    Another benefit - it will work for Mono as well (which doesn't use the C++ header parsing that coreclr does).

  4. jkotas commented on Apr 28, 2021

    @jkotas
    Member

    Yes, Mono is on the DynamicDependencyAttribute plan already. I do not see a need for new attribute. The existing attributes should be sufficient.

  5. danmoseley commented on Apr 28, 2021

    @danmoseley
    Contributor

    Agreed, just for completeness another possibility could have been check in the preprocessed output and compare during the coreclr build, asmmeta style. (No I don't think that's a good idea)

  6. MichalStrehovsky commented on Apr 29, 2021

    @MichalStrehovsky
    Member

    which is a new dependency and the infra team really doesn't like this

    I think the libraries team would object the most to that - CoreLib is a reference of several assemblies in src/libraries - it would mean one can't build libraries without building CoreCLR.

  7. added this to the 7.0.0 milestone on Jul 9, 2021
  8. removed
    untriagedNew issue has not been triaged by the area owner
    on Jul 9, 2021
  9. modified the milestones: 7.0.0, Future on Jul 28, 2022
  10. dotnet-policy-service commented on Apr 15, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @agocke, @elinor-fung
    See info in area-owners.md if you want to be subscribed.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    • Status
      No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions