[dotnet] Fix inlined-dlfcn native symbol generation when the trimmer is skipped - #25999
Conversation
…is skipped When PrepareAssemblies + PostProcessAssemblies are enabled and the trimmer is skipped (_CanSkipTrimmer), its output directory (IntermediateLinkDir) is empty, so _ComputeTrimmedAssemblies found no assemblies to scan and the inlined-dlfcn native symbols were never collected, resulting in undefined native symbols at link time. Collect the assemblies to scan from @(ResolvedFileToPublish) (the same source every other target uses) instead of the trimmer's output directory. This works whether or not the trimmer ran: when it's skipped the published assemblies are the final ones, and when it did run they're derived from the trimmed output, so the surviving symbol set is identical (verified against a normal trimmed build). Since @(ResolvedFileToPublish) can also contain native libraries with a managed extension (e.g. a native 'NativeLibrary.dll'), harden CollectPostILTrimInformation to skip files that aren't managed assemblies (Cecil throws BadImageFormatException on those). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…prepare-assemblies issue Add a 'dontlink|prepare-assemblies|inline-dlfcn-methods-compat' variation for monotouch-test that exercises the inlined-dlfcn native symbol generation when the trimmer is skipped. This scenario only needs explicit coverage on .NET 10: there iOS defaults to MonoVM, which links the SDK by default, so the trimmer isn't skipped unless linking is explicitly disabled and InlineDlfcnMethods is enabled. On .NET 11+ iOS defaults to CoreCLR (which doesn't link) and InlineDlfcnMethods is enabled by default, so the plain 'prepare-assemblies' variation already covers it; the new variation is therefore ignored on .NET 11+. Also add a 'dontlink' test variation (MtouchLink/LinkMode = None) to compose this configuration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Fixes a build-time regression where inlined-dlfcn native symbols aren’t generated when PrepareAssemblies + PostProcessAssemblies are enabled and the trimmer is skipped (empty IntermediateLinkDir), which can otherwise lead to undefined _xamarin_Dlfcn_*_Native symbols at native link time.
Changes:
- Update
_ComputeTrimmedAssembliesto scan assemblies from@(ResolvedFileToPublish)instead of$(IntermediateLinkDir). - Harden
CollectPostILTrimInformationto skip non-managed.dllinputs (catchBadImageFormatException). - Add a reusable
dontlinktest variation and introduce a new monotouch-test Jenkins variation intended to cover the “trimmer skipped” scenario.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tests/xharness/Jenkins/TestVariationsFactory.cs | Adds a monotouch-test variation to exercise PrepareAssemblies + inline-dlfcn with trimming disabled (currently missing PostProcessAssemblies). |
| tests/common/test-variations.csproj | Adds dontlink variation for disabling trimming/linking in tests (suggest adding postprocess-assemblies too). |
| msbuild/Xamarin.MacDev.Tasks/Tasks/CollectPostILTrimInformation.cs | Skips non-managed .dll inputs to avoid Cecil BadImageFormatException when scanning publish items. |
| dotnet/targets/Xamarin.Shared.Sdk.targets | Switches post-trim symbol collection input from IntermediateLinkDir to @(ResolvedFileToPublish) to work even when the trimmer is skipped. |
✅ 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 |
🚀 [CI Build #9363c10] 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 |
When
PrepareAssemblies+PostProcessAssembliesare enabled and the trimmer is skipped (_CanSkipTrimmer), its output directory (IntermediateLinkDir) is empty, so_ComputeTrimmedAssembliesfound no assemblies to scan. As a result_CollectPostILTrimInformationcollected no inlined-dlfcn native symbols and no native code was generated for them, causing undefined native symbols (_xamarin_Dlfcn_*_Native) at link time.Fix
@(ResolvedFileToPublish)(the same source every other target uses) instead of the trimmer's output directory. This works whether or not the trimmer ran: when it's skipped the published assemblies are the final ones, and when it did run they're derived from the trimmed output, so the surviving symbol set is identical (verified against a normal trimmed build).CollectPostILTrimInformationto skip files that aren't managed assemblies, since@(ResolvedFileToPublish)can contain native libraries with a managed extension (e.g. a nativeNativeLibrary.dll), which make Cecil throwBadImageFormatException.Test
Add a
dontlink|prepare-assemblies|inline-dlfcn-methods-compatvariation for monotouch-test that reproduces the issue. This only needs explicit coverage on .NET 10: there iOS defaults to MonoVM, which links the SDK by default, so the trimmer isn't skipped unless linking is explicitly disabled andInlineDlfcnMethodsis enabled. On .NET 11+ iOS defaults to CoreCLR (which doesn't link) andInlineDlfcnMethodsis enabled by default, so the plainprepare-assembliesvariation already covers it — the new variation is therefore ignored on .NET 11+. A reusabledontlinktest variation is also added.🤖 Pull request created by Copilot