Repository navigation
DOTNET_STARTUP_HOOKS from @(AndroidEnvironment) files is silently overwritten #11186
Description
Description
Both the HotReload targets (Microsoft.Android.Sdk.HotReload.targets) and the trimmable typemap targets (Microsoft.Android.Sdk.TypeMap.Trimmable.targets) compose DOTNET_STARTUP_HOOKS only from @(RuntimeEnvironmentVariable) items. However, users can also declare environment variables via @(AndroidEnvironment) text files:
DOTNET_STARTUP_HOOKS=MyStartupHook.dll
When the build targets run, they do:
<RuntimeEnvironmentVariable Remove="DOTNET_STARTUP_HOOKS" />
<RuntimeEnvironmentVariable Include="DOTNET_STARTUP_HOOKS" Value="..." />This replaces the @(RuntimeEnvironmentVariable) value but never reads or merges values from @(AndroidEnvironment) files. The user's startup hook is silently dropped.
Affected targets
_AndroidConfigureHotReloadEnvironmentinMicrosoft.Android.Sdk.HotReload.targets(L48-49) — replacesDOTNET_STARTUP_HOOKSwithout composing._ConfigureTrimmableTypeMapStartupHookinMicrosoft.Android.Sdk.TypeMap.Trimmable.targets(PR [TrimmableTypeMap] Per-assembly typemap universes with startup hook initialization #11181) — composes@(RuntimeEnvironmentVariable)entries but ignores@(AndroidEnvironment)files.
Expected behavior
All DOTNET_STARTUP_HOOKS values — regardless of source — should be merged (colon-separated) into the final environment written to the app.
Suggested approach
Introduce a new @(_AndroidDotnetStartupHooks) item group as the single collection point. A target running before _GenerateEnvironmentFiles merges all three sources:
@(_AndroidDotnetStartupHooks)— internal contributors (HotReload, trimmable typemap) append their assembly names here instead of directly manipulating@(RuntimeEnvironmentVariable)@(RuntimeEnvironmentVariable)(filtered forDOTNET_STARTUP_HOOKS) — values passed in externally, e.g. bydotnet watch@(AndroidEnvironment)files — parsed forDOTNET_STARTUP_HOOKS=...lines
The target then:
- Removes any
DOTNET_STARTUP_HOOKSfrom@(RuntimeEnvironmentVariable) - Strips
DOTNET_STARTUP_HOOKS=...lines from@(AndroidEnvironment)file content (or leaves them and deduplicates — TBD) - Joins all collected values with
:into a single@(RuntimeEnvironmentVariable)entry
This approach:
- Eliminates the fragile remove-then-add pattern each contributor currently does
- Makes composition order-independent — no target needs to know about other contributors
- Avoids duplicates naturally (items are distinct assembly names)
- Starts as private (
_prefix) with the option to make it public and documented later
Context
Discussed in #11181 (comment)
Activity