Skip to content

[release/10.0.1xx] [NativeAOT] set environment variables before the app .so is loaded#10768

Merged
jonathanpeppers merged 4 commits intorelease/10.0.1xxfrom
dev/peppers/backport-10709
Feb 5, 2026
Merged

[release/10.0.1xx] [NativeAOT] set environment variables before the app .so is loaded#10768
jonathanpeppers merged 4 commits intorelease/10.0.1xxfrom
dev/peppers/backport-10709

Conversation

@jonathanpeppers
Copy link
Member

Backport of: #10709

jonathanpeppers and others added 2 commits February 4, 2026 12:32
We lost a snippet that is present on main, causing this test to fail on `release/10.0.1xx`.
…10709)

Fixes: #10705

When a \NativeAOT\ application starts up, certain portions of the managed startup
sequence are executed on the shared library load but before the \JNI_OnLoad\
function is invoked by Android.

Both \MonoVM\ and \CoreCLR\ hosts set environment variables which may affect the
way the application behaves before they initialize the managed runtime. Those
variables are set from within native code, using data generated at application
build time.

Until now, the \NativeAOT\ host followed suit, but it appears that we need to
set certain variables (e.g. those related to running the startup hooks) before
the shared library is loaded.

The only location where we can do it is the \NativeAndroidRuntimeProvider\ Java
class which is responsible for, eventually, loading the application shared
library.

This commit makes our build process emit application environment variables into
a Java file that's compiled together with the \NativeAndroidRuntimeProvider\
class, at the same time removing those variables from the native code so that
we don't set the variables twice (a performance optimization, nothing more).

Testing shows that startup hooks are properly called with only the \DOTNET_STARTUP_HOOKS\
variable set, which wasn't previously the case.

Co-authored-by: Jonathan Peppers <[email protected]>
@jonathanpeppers jonathanpeppers force-pushed the dev/peppers/backport-10709 branch from 14bd4cb to 85e6c52 Compare February 4, 2026 19:29
@jonathanpeppers
Copy link
Member Author

These tests are passing now:

image

@jonathanpeppers jonathanpeppers marked this pull request as ready for review February 4, 2026 21:21
Copilot AI review requested due to automatic review settings February 4, 2026 21:21
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This is a backport of PR #10709 that fixes environment variable initialization for NativeAOT applications. The change moves environment variable setup from native code to Java code, ensuring variables are set before the application shared library is loaded. This fixes an issue where startup hooks were not being called properly in NativeAOT builds.

Changes:

  • Environment variables for NativeAOT are now generated as Java code and set from the NativeAotRuntimeProvider constructor
  • Native code generation tasks for NativeAOT no longer include environment variables (they're cleared)
  • Added test infrastructure to read and verify NativeAOT environment variables from generated Java source
  • Test adjustments to limit CoreCLR to 64-bit ABIs only

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
GenerateAdditionalProviderSources.cs Generates Java source code with environment variables for NativeAOT runtime
GenerateNativeApplicationConfigSources.cs Skips environment variable generation for NativeAOT runtime, adds them to Java instead
GenerateNativeAotEnvironmentAssemblerSources.cs Clears environment variables since they're now set in Java; removes unused Debug parameter
NativeAotEnvironmentVars.java New Java class template that sets environment variables using Os.setenv before library load
NativeAotRuntimeProvider.java Calls NativeAotEnvironmentVars.Initialize() in constructor to set variables early
Xamarin.Android.Common.targets Passes environment file data and related parameters to GenerateAdditionalProviderSources
Microsoft.Android.Sdk.NativeAOT.targets Removes unused Debug parameter from GenerateNativeAotEnvironmentAssemblerSources task
EnvironmentHelper.cs Adds test helper method to read and parse environment variables from generated Java source
InstallAndRunTests.cs Limits CoreCLR test to 64-bit ABIs only for practical performance reasons

Copilot AI added a commit that referenced this pull request Feb 4, 2026
…gging, and format string

Co-authored-by: jonathanpeppers <[email protected]>
grendello pushed a commit that referenced this pull request Feb 5, 2026
…bles support code (#10771)

This PR applies review feedback from the backport PR #10768 to the main branch, addressing three improvements to the NativeAOT environment variable handling:

**Changes:**
- Fixed Java string escaping in `EnvironmentBuilder.cs` to properly escape backslashes before quotes, preventing invalid Java string literals
- Added missing `$` prefix for string interpolation in a test assertion message in `EnvironmentHelper.cs`
- Enhanced error logging in `NativeAotEnvironmentVars.java` to include exception details when environment variable setting fails
@jonathanpeppers
Copy link
Member Author

Test failures are unrelated, merging.

@jonathanpeppers jonathanpeppers merged commit 3022950 into release/10.0.1xx Feb 5, 2026
1 of 2 checks passed
@jonathanpeppers jonathanpeppers deleted the dev/peppers/backport-10709 branch February 5, 2026 14:03
jonathanpeppers pushed a commit that referenced this pull request Feb 5, 2026
…bles support code (#10771)

This PR applies review feedback from the backport PR #10768 to the main branch, addressing three improvements to the NativeAOT environment variable handling:

**Changes:**
- Fixed Java string escaping in `EnvironmentBuilder.cs` to properly escape backslashes before quotes, preventing invalid Java string literals
- Added missing `$` prefix for string interpolation in a test assertion message in `EnvironmentHelper.cs`
- Enhanced error logging in `NativeAotEnvironmentVars.java` to include exception details when environment variable setting fails
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants