-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Expose managed Main with NativeAOT when compiling the application as a static library #81097
Comments
Tagging subscribers to 'os-ios': @steveisok, @akoeplinger Issue DetailsDescriptionIn order to integrate Xamarin and NativeAOT when targeting iOS platforms the following scenario is used:
However, if the application is compiled as a static library with the ILCompiler, the managed Main method is not exposed to the native world. To workaround this limitation, one could change the source code of the application and add a method with
|
I haven't tested it, but I think it should possible today. Which symbols to keep in static library scenario is up to the final linkage which in our case is left to the end-user (and we don't provide supporting script / build steps today: #70277). With |
@am11 I was more referring to how ILCompiler compiles a native library vs an executable and the symbols it exposes via corresponding
That being said, an executable compiled as a native library will not have its managed Main method exposed (and no way to pass parameters to it). |
There are number of things that happen around Main. For example, the arguments passed to Main are stored so that they can be also retrieved via I assume that you want some or all of these to be included in the Main method wrapper. Is that right? We should agree on the details like this before you proceed with implementation, so that it does not have to be reworked. |
In case it's helpful, the approach I took for my proof-of-concept was to generate both the library and main method entry points in ILC. I then used the library version of bootstrapper to enable The managed main in this proof of concept still contains all those features Jan mentions, so I'm not sure its what you want. |
@jkotas from the mentioned set of features around managed Main, what does ILC support by exposing @AustinWise thank you, that looks like something we would want. |
All of them and more. The IL code for runtime/src/coreclr/tools/aot/ILCompiler.Compiler/IL/Stubs/StartupCode/StartupCodeMainMethod.cs Line 62 in ab2d195
I do not think you want the full existing |
I agree with what Jan wrote, we don't want to run both the library startup code and EXE startup code at the same time - they would run the same things twice. However, we could go with something similar to what @AustinWise suggested in #81097 (comment). (We just need to address the double execution.) On a high level: The
On the other hand,
One simple solution based on @AustinWise commit would be to add a bool flag to
If this is not desirable, we'll need to come up with some other ordering. I think it mainly depends on when do we want to run module initializers. |
Thank you for the detailed explanation.
This approach sounds good to me. @rolfbjarne what do you think? |
Yes, I think that sounds good too. |
@AustinWise, would you be interested in taking over this issue? |
Sure, I can create a PR. |
thanks a lot! I have assigned the issue to you, and let me know if you need any help, I would gladly assist if needed. |
I created #81873 with my changes. I was not sure how this should fit into the larger build system, so I made the ILC parts flexible. |
) This PR adds a new flag to ILC, `--splitinit` . 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
Closed via: #81873 |
Description
In order to integrate Xamarin and NativeAOT when targeting iOS platforms the following scenario is used:
However, if the application is compiled as a static library with the ILCompiler, the managed Main method is not exposed to the native world.
To workaround this limitation, one could change the source code of the application and add a method with
UnmanagedCallersOnlyAttribute
that wraps the Main, but if we consider the experience of the end-user, there should be an automatic way of injecting the required code which would make the transition to NativeAOT seamless.The text was updated successfully, but these errors were encountered: