Skip to content

Compose DOTNET_STARTUP_HOOKS across all Android environment sources instead of overwriting#11187

Draft
Copilot wants to merge 6 commits intomainfrom
copilot/fix-dotnet-startup-hooks
Draft

Compose DOTNET_STARTUP_HOOKS across all Android environment sources instead of overwriting#11187
Copilot wants to merge 6 commits intomainfrom
copilot/fix-dotnet-startup-hooks

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 22, 2026

DOTNET_STARTUP_HOOKS was being rewritten from @(RuntimeEnvironmentVariable) only, which could drop values coming from @(AndroidEnvironment) files. This change keeps startup hook composition explicit and ensures final environment generation merges all sources without duplicate-effective definitions.

  • Use a single startup-hook item flow

    • _ComposeDotNetStartupHooks in Xamarin.Android.Common.targets now builds @(_AndroidDotnetStartupHooksDistinct) from:
      • internal contributors via @(_AndroidDotnetStartupHooks)
      • existing @(RuntimeEnvironmentVariable) entries for DOTNET_STARTUP_HOOKS
    • DOTNET_STARTUP_HOOKS is removed from @(RuntimeEnvironmentVariable) and startup hooks are carried via @(_AndroidDotnetStartupHooksDistinct).
  • Generate environment file from composed hooks

    • _GenerateEnvironmentFiles writes DOTNET_STARTUP_HOOKS=... from @(_AndroidDotnetStartupHooksDistinct, ':') into __environment__.txt.
  • Pass startup hooks into environment-producing tasks

    • Added DotNetStartupHooks task input and wired it from @(_AndroidDotnetStartupHooksDistinct) for:
      • GenerateNativeApplicationConfigSources
      • GenerateAdditionalProviderSources
      • GenerateNativeAotEnvironmentAssemblerSources
  • Merge at consolidation point

    • EnvironmentBuilder now accepts explicit startup hooks via AddDotNetStartupHooks(...).
    • It merges those with any DOTNET_STARTUP_HOOKS found while parsing @(AndroidEnvironment) / @(LibraryEnvironments) using colon-separated dedupe.
  • Hot Reload behavior remains compatible

    • _AndroidConfigureHotReloadEnvironment continues contributing normalized startup hook assembly names to @(_AndroidDotnetStartupHooks) and keeps RuntimeHostConfigurationOption behavior unchanged.
  • Focused test coverage

    • EnvironmentContentTests verifies final DOTNET_STARTUP_HOOKS contains values from both RuntimeEnvironmentVariable and AndroidEnvironment.
<ItemGroup>
  <_AndroidStartupHooksFromRuntimeEnvironmentVariable Include="@(RuntimeEnvironmentVariable->WithMetadataValue('Identity', 'DOTNET_STARTUP_HOOKS'))" />
  <_AndroidDotnetStartupHooks Include="@(_AndroidStartupHooksFromRuntimeEnvironmentVariable->'%(Value)')" />
</ItemGroup>

<RemoveDuplicates Inputs="@(_AndroidDotnetStartupHooks)">
  <Output TaskParameter="Filtered" ItemName="_AndroidDotnetStartupHooksDistinct" />
</RemoveDuplicates>

<ItemGroup>
  <RuntimeEnvironmentVariable Remove="DOTNET_STARTUP_HOOKS" />
</ItemGroup>
envBuilder.Read (Environments);
envBuilder.AddDotNetStartupHooks (DotNetStartupHooks);

Copilot AI and others added 2 commits April 22, 2026 21:21
Agent-Logs-Url: https://github.com/dotnet/android/sessions/a0bba47d-8a89-476b-b420-c6c5e6914563

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix overwriting of DOTNET_STARTUP_HOOKS from AndroidEnvironment files Compose DOTNET_STARTUP_HOOKS across all Android environment sources instead of overwriting Apr 22, 2026
Copilot AI requested a review from simonrozsival April 22, 2026 21:35
Copy link
Copy Markdown
Member

@simonrozsival simonrozsival left a comment

Choose a reason for hiding this comment

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

@copilot address my questions

</Target>

<Target Name="_GenerateEnvironmentFiles" DependsOnTargets="_AndroidConfigureHotReloadEnvironment">
<Target Name="_ComposeDotNetStartupHooks"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This target does not have Inputs and Outputs, should it have them?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good question. I kept _ComposeDotNetStartupHooks without Inputs/Outputs intentionally because it only transforms in-memory MSBuild items/properties for the current build graph; persisting incremental state there could skip needed recomposition. I also moved the final cross-file merge to EnvironmentBuilder in 120aedf, so this target stays lightweight and order-safe.

Comment on lines +1600 to +1602
<ReadLinesFromFile File="%(_AndroidEnvironmentStartupHookFiles.Identity)">
<Output TaskParameter="Lines" ItemName="_AndroidEnvironmentStartupHookLines" />
</ReadLinesFromFile>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If I understand it correctly, we will leave the original DOTNET_STARTUP_HOOKS values in the env files? Doesn't this mean that we will have multiple definitions of DOTNET_STARTUP_HOOKS in the final list of environment variables? Shouldn't we move the merging logic to the GenerateAdditionalProviderSources or EnvironmentBuilder or some other place where we eventually merge all the environment variables into a single list of definitions?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right. I changed this in 120aedf: _ComposeDotNetStartupHooks no longer reads @(AndroidEnvironment)/@(LibraryEnvironments) lines, and EnvironmentBuilder now merges repeated DOTNET_STARTUP_HOOKS definitions while parsing the final environment inputs. This moves merging to the consolidation point and avoids duplicate final definitions.

Agent-Logs-Url: https://github.com/dotnet/android/sessions/eaf7b02c-a819-4e2f-8bd5-fedfee6f1931

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 23, 2026

@copilot address my questions

Addressed in 120aedf. I answered both review questions and updated the implementation so final DOTNET_STARTUP_HOOKS merging happens in EnvironmentBuilder (the environment consolidation point), while _ComposeDotNetStartupHooks only prepares runtime/internal contributions.

Copy link
Copy Markdown
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

@copilot can you simplify the changes here?

  • Use the @(_AndroidDotnetStartupHooks) item group throughout, pass it into the task that writes environment variables
  • Clear startup hooks from @(RuntimeEnvironmentVariable), and rely on @(_AndroidDotnetStartupHooks)
  • The task that writes environment variables merges @(_AndroidDotnetStartupHooks) and any found from @(AndroidEnvironment) files

Copilot AI and others added 2 commits April 29, 2026 20:23
Agent-Logs-Url: https://github.com/dotnet/android/sessions/f4947bfc-48c4-4b7a-ab89-4760d3d73354

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/android/sessions/f4947bfc-48c4-4b7a-ab89-4760d3d73354

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 29, 2026

@copilot can you simplify the changes here?

  • Use the @(_AndroidDotnetStartupHooks) item group throughout, pass it into the task that writes environment variables
  • Clear startup hooks from `@(Runti...

Done in 56b9467 (building on 22ec383). I simplified the flow to keep startup hooks in @(_AndroidDotnetStartupHooks)/@(_AndroidDotnetStartupHooksDistinct), remove DOTNET_STARTUP_HOOKS from @(RuntimeEnvironmentVariable), pass the startup-hook items into the environment-producing tasks, and merge them with hooks from @(AndroidEnvironment)/@(LibraryEnvironments) in EnvironmentBuilder.

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.

DOTNET_STARTUP_HOOKS from @(AndroidEnvironment) files is silently overwritten

3 participants