[Browser][CoreCLR] publish+workload should not trigger native relink unless there is new UCO/PInvoke
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
## Problem
For a trimmed `Release` nested publish (all library-test legs, and any published Browser CoreCLR app), `WasmBuildNative` defaults to `true` in `_CoreCLRSetWasmBuildNativeDefaults` (`src/mono/browser/build/BrowserWasmApp.CoreCLR.targets`):
```xml
false
true
```
This triggers a full `emcc` relink of `dotnet.native.wasm` **and** the `ManagedToNativeGenerator` scan of the entire bundled managed closure.
But the relink only bakes **app-contributed** reverse thunks / module imports. The runtime pack already ships every framework `[UnmanagedCallersOnly]` reverse thunk and P/Invoke table. So when the app adds:
- no `[UnmanagedCallersOnly]` / `[JSExport]` callbacks,
- no `[WasmImportLinkage]` P/Invokes, and
- no `NativeFileReference` / `NativeLibrary`,
…the relinked `dotnet.native.wasm` is effectively identical to the pack's, and both the relink and the scan are wasted work.
### Side effects of the unnecessary relink
- Large build-time cost per test/app (`emcc` relink).
- The closure scan surfaces `WASM0066` for every foreign-platform `DllImport` in the closure (`kernel32`, `ntdll`, `advapi32`, `Security.framework`, `libsecret`, `libc`, …). These are correctly handled at runtime (throw-if-called), but fail the build under warn-as-error.
## Proposed solution
Make the relink **demand-driven**:
1. Add a cheap detection pass over the **app's own assemblies** (not the whole framework closure) for:
- `[UnmanagedCallersOnly]` / `[JSExport]` callbacks, and
- `[WasmImportLinkage]` P/Invokes.
2. Gate `WasmBuildNative` on `(that detection) OR (NativeFileReference/NativeLibrary present)`. The `NativeFileReference` / `NativeLibrary` trigger already exists; this replaces the coarse `Configuration == Release` heuristic with a real "does the app add native surface?" signal.
The detection can reuse `PInvokeCollector` restricted to the app's assemblies, or a lighter attribute-only metadata check — scanning only the app assemblies is sufficient because the pack already contains all framework thunks.
### Where
- `src/mono/browser/build/BrowserWasmApp.CoreCLR.targets` — `_CoreCLRSetWasmBuildNativeDefaults`, `_CoreCLRGenerateManagedToNative`.
- `src/tasks/WasmAppBuilder/coreclr/PInvokeCollector.cs`.
- The WASI sibling `src/mono/wasi/build/WasiApp.CoreCLR.targets` has the same shape and should get the same treatment.
> [!NOTE]
> This issue was drafted with GitHub Copilot.
Contributor guide
Assessment
This issue has not been assessed yet.