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

[NativeAOT] Add ability to generate library and exe entry points #81873

Merged
merged 7 commits into from
Feb 15, 2023

Conversation

AustinWise
Copy link
Contributor

@AustinWise AustinWise commented Feb 9, 2023

This PR adds a new flag to ILC, --split-exe-initalization . The flag splits the initialization that is normally done for executable into two parts. The __managed__Startup function runs classlib and module initializers. The __managed__Main function performs the remaining initialization and executes the entry-point of the managed application.

The use case for this is to allow calling UnamanagedCallersOnly functions before the managed main function. Running on iOS is the first use case for this feature (#80905).

It was not clear to me how to fit this into the larger NativeAot build system. Should this be thought of as "a static library that also has a __managed__Main compiled in" or as "an executable that splits its initialization into two parts"? So I added support to ILC for both cases: compiling with the --nativelib flag and without it.

Lastly, I added some build integration the "an executable that splits its initialization into two parts" case, along with test. The idea is the user sets the CustomNativeMain property in their project. They are then responsible for providing a NativeLibrary item pointing to an object file containing their native main function. At runtime, when they call their first managed function, NativeAOT initialization will run. This includes calling __managed__Main, so the user cannot forget to initialize the runtime.

Related issues: #81097 #77957

@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Feb 9, 2023
@ghost
Copy link

ghost commented Feb 9, 2023

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

Issue Details

This PR adds a new flag to ILC, --split-exe-initalization . The flag splits the initialization that is normally done for executable into two parts. The __managed__Startup function runs classlib and module initializers. The __managed__Main function performs the remaining initialization and executes the entry-point of the managed application.

The use case for this is to allow calling UnamanagedCallersOnly functions before the managed main function. Running on iOS is the first use case for this feature (#80905).

It was not clear to me how to fit this into the larger NativeAot build system. Should this sort of use be thought of a "a static library that also has a __managed__Main compiled in" or as "an executable that splits its initialization into two parts"? So I added support to ILC for both cases: compiling with the --nativelib flag and without it.

Lastly, I added an example of what the build integration could looks like for the "an executable that splits its initialization into two parts" case, along with test. This can be reverted if it's not the right direction.

Related issues: #81097 #77957

Author: AustinWise
Assignees: -
Labels:

community-contribution, area-NativeAOT-coreclr

Milestone: -

@ivanpovazan ivanpovazan changed the title NativeAot] Add ability to generate library and exe entry points [NativeAot] Add ability to generate library and exe entry points Feb 9, 2023
@ivanpovazan ivanpovazan changed the title [NativeAot] Add ability to generate library and exe entry points [NativeAOT] Add ability to generate library and exe entry points Feb 9, 2023
Copy link
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good otherwise, thanks!

A coding error is more likely to run the Module Initializer twice
than the cctor.
And fix some spelling in the variable name.
And change values that are added up so they are not multiples of each other
@MichalStrehovsky
Copy link
Member

The (Build CoreCLR Tools Unit Tests linux x64 checked) failure is real. Otherwise looks good to merge, thanks!

src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs(65,30): error CS7036: (NETCORE_ENGINEERING_TELEMETRY=Build) There is no argument given that corresponds to the required parameter 'generateLibraryAndModuleInitializers' of 'MainMethodRootProvider.MainMethodRootProvider(EcmaModule, IReadOnlyCollection<MethodDesc>, bool)'

@ivanpovazan
Copy link
Member

LGTM as well, thank you @AustinWise very much!

Let me know if you need help fixing the remaining test failure.
Once we get that fixed, we can merge this.

As a follow-up, we should also update the documentation here: https://github.com/dotnet/samples/blob/main/core/nativeaot/NativeLibrary/README.md

@AustinWise
Copy link
Contributor Author

Opps, I missed that test. It should be fixed now.

As a follow-up, we should also update the documentation here: https://github.com/dotnet/samples/blob/main/core/nativeaot/NativeLibrary/README.md

Sure, I can follow up with a sample based on the unit test.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-NativeAOT-coreclr community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants