[msbuild] Generate C code for runtimeconfig properties (CoreCLR). Fixes #26334 - #26335
Conversation
…reCLR For CoreCLR, generate C arrays for the runtimeconfig.json 'configProperties' in the app's generated main (assigned to globals defined in libxamarin) instead of producing the binary runtimeconfig format, shipping it in the bundle, and mmap+decoding it at startup. MonoVM still needs the binary blob (for monovm_runtimeconfig_initialize) and NativeAOT doesn't call xamarin_bridge_vm_initialize, so both keep the previous behaviour. - runtime: add xamarin_runtime_config_property_count/keys/values globals (runtime.m + main.h) and rewrite xamarin_bridge_compute_properties (coreclr-bridge.m) to use them; drop the now-unused mmap/decode helpers. - linker: GenerateMainStep parses runtimeOptions.configProperties from the merged runtimeconfig.json (value stringification matching dotnet/runtime's RuntimeConfigParser) with a reserved-property check, and Target.cs emits the C arrays + global assignment for CoreCLR. The merged json path is passed to the linker via RuntimeConfigurationFilePath. - msbuild: for CoreCLR skip RuntimeConfigParserTask and don't ship/merge runtimeconfig.bin; hand the merged json to the linker and leave xamarin_runtime_configuration_name NULL. - tests: new RuntimeConfigurationTest (property baked into the generated main, no runtimeconfig.bin for CoreCLR), gate the BundleStructureTest expectation, and drop runtimeconfig.bin from the CoreCLR app-size expectation files. Fixes #26334 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
NativeAOT never reads runtimeconfig.bin at runtime: the only reader is monovm-bridge.m (compiled only when CORECLR_RUNTIME is not defined) and xamarin_bridge_compute_properties (only called from xamarin_bridge_vm_initialize, which is #if !defined(NATIVEAOT)). NativeAOT builds are compiled with -DCORECLR_RUNTIME -DNATIVEAOT, so neither applies - the runtime configuration is embedded into the executable by the ILC compiler at publish time instead. So only MonoVM actually needs the binary runtimeconfig format. Change the gating from '!= CoreCLR' to '== MonoVM' so NativeAOT, like CoreCLR, no longer produces or ships runtimeconfig.bin. Drop it from the NativeAOT app-size expectation files. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Replace the postfix '!' null-forgiving operator (banned by repo rules) with direct null-narrowing checks in Target.cs and a null-coalescing fallback in GenerateMainStep.cs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 81ba6c1d-1061-43f4-8064-c81f5a181e2f
There was a problem hiding this comment.
Pull request overview
This PR removes the need to generate/ship/decode runtimeconfig.bin for CoreCLR (and avoids shipping it for NativeAOT), by baking runtimeOptions.configProperties into the generated main.*.mm as compiled-in C arrays and exposing them to the CoreCLR bridge via new xamarin_runtime_config_property_* globals.
Changes:
- Linker reads merged
runtimeconfig.merged.jsonand storesconfigPropertieson theApplicationmodel for CoreCLR, rejecting reserved keys/unsupported value kinds. - Main generator emits
static const char*arrays for runtimeconfig property keys/values and assigns them to new runtime globals duringxamarin_setup_impl. - Runtime CoreCLR bridge now builds the
coreclr_initializeproperty arrays from the baked-in globals (nommap/decode), and MSBuild/tests stop expecting/shippingruntimeconfig.binexcept for MonoVM.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/dotnet-linker/Steps/GenerateMainStep.cs | Parses merged runtimeconfig JSON for CoreCLR and populates Application.RuntimeConfigProperties; enforces reserved keys/unsupported kinds. |
| tools/dotnet-linker/LinkerConfiguration.cs | Adds RuntimeConfigurationFilePath passthrough from MSBuild to the linker. |
| tools/dotnet-linker/Compat.cs | Adds Application.RuntimeConfigProperties storage for CoreCLR main generation. |
| tools/common/Target.cs | Emits C arrays for runtimeconfig properties into generated main.*.mm and assigns new runtime globals. |
| runtime/xamarin/main.h | Declares new xamarin_runtime_config_property_* globals. |
| runtime/runtime.m | Defines new runtimeconfig property globals (assigned by generated main). |
| runtime/coreclr-bridge.m | Replaces runtimeconfig.bin mmap/decode path with copying from baked-in globals. |
| dotnet/targets/Xamarin.Shared.Sdk.targets | Gates runtimeconfig.bin generation/shipping to MonoVM; passes merged JSON path to linker for CoreCLR. |
| tests/dotnet/UnitTests/RuntimeConfigurationTest.cs | New unit test verifying CoreCLR properties are baked into generated main and no runtimeconfig.bin is shipped. |
| tests/dotnet/UnitTests/BundleStructureTest.cs | Updates expected bundle contents: CoreCLR no longer ships runtimeconfig.bin. |
| tests/dotnet/UnitTests/expected/-NativeAOT-size.txt | Updates size baselines to reflect runtimeconfig.bin no longer being shipped for NativeAOT. |
| tests/dotnet/UnitTests/expected/-CoreCLR-size.txt | Updates size baselines to reflect runtimeconfig.bin no longer being shipped for CoreCLR. |
- Emit the runtimeconfig C arrays sorted by key so the generated main is deterministic regardless of the dictionary's enumeration order. - Fail the build (error 2323) when 'runtimeOptions.configProperties' is present but isn't a JSON object, instead of silently ignoring the configuration. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 81ba6c1d-1061-43f4-8064-c81f5a181e2f
This comment has been minimized.
This comment has been minimized.
✅ API diff for current PR / commitNET (empty diffs)✅ API diff vs stableNET (empty diffs)ℹ️ Generator diffGenerator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes) Pipeline on Agent |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
🚀 [CI Build #9d7a954] Test results 🚀Test results✅ All tests passed on VSTS: test results. 🎉 All 203 tests passed 🎉 Tests counts✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download macOS tests✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download Linux Build VerificationPipeline on Agent |
For CoreCLR-based apps we currently produce the binary
runtimeconfig.bin, ship it in the app bundle, thenmmapand decode it at startup to feed theconfigPropertiesintocoreclr_initialize. That's an extra file to ship and extra decoding work at launch, for data that is fully known at build time.This bakes the runtimeconfig.json
configPropertiesdirectly into the app as compiled-in C arrays (emitted into the generatedmain.mmand assigned to newxamarin_runtime_config_property_*globals in libxamarin).xamarin_bridge_compute_propertiesnow reads those globals instead of locating, mmapping and decodingruntimeconfig.bin, and the mobile-runtimeconfig decode helpers are removed.Approach
xamarin_runtime_config_property_count/keys/valuesglobals inruntime.m(assigned from the app's generated main, same pattern asxamarin_runtime_configuration_name), and rewritexamarin_bridge_compute_propertiesincoreclr-bridge.mto copy from them.GenerateMainStepparsesruntimeOptions.configPropertiesfrom the merged runtimeconfig.json for CoreCLR (matching the value stringification done by dotnet/runtime'sRuntimeConfigParserTask), rejects reserved properties (error 2322) and unsupported value kinds (error 2321), andTarget.csemits the C arrays plus the global assignment inxamarin_setup_impl.runtimeconfig.bin, so it stops shipping the unused file too.MonoVM is unchanged: it still needs the blob for
monovm_runtimeconfig_initialize.Notes
dev/rolf/runtimeconfig-dev-json); review that one first.Fixes: #26334
🤖 Pull request created by Copilot