[Mono.Android] Compile RuntimeFeature into a single assembly to avoid conflict warnings#11669
Conversation
`Microsoft.Android.Runtime.RuntimeFeature` was compiled into both
`Mono.Android.Runtime.dll` and `Mono.Android.dll`. Because `Mono.Android`
references `Mono.Android.Runtime` (which exposes its internals to
`Mono.Android` via `InternalsVisibleTo`), building `Mono.Android.dll`
emitted 58 `CS0436` warnings:
warning CS0436: The type 'RuntimeFeature' in
'src/Mono.Android/Microsoft.Android.Runtime/RuntimeFeature.cs' conflicts
with the imported type 'RuntimeFeature' in 'Mono.Android.Runtime'.
Compile `RuntimeFeature.cs` only into `Mono.Android.Runtime.dll` (the
lower-level assembly that already owns it) and let the other assemblies use
it through `InternalsVisibleTo`:
* Remove the duplicate `<Compile Include="...RuntimeFeature.cs" />` from
`Mono.Android.csproj`.
* Grant `Mono.Android.Runtime` internals to
`Microsoft.Android.Runtime.NativeAOT` and `Mono.Android.NET-Tests`, which
previously accessed `RuntimeFeature` through `Mono.Android.dll`.
* Once `RuntimeFeature` is only imported (no longer source-compiled) into
`Mono.Android`, the unqualified name `RuntimeFeature` becomes ambiguous
with `System.Runtime.CompilerServices.RuntimeFeature`. Add
`using RuntimeFeature = Microsoft.Android.Runtime.RuntimeFeature;` to the
three affected files, matching the alias already used in `JNIEnvInit.cs`.
`Microsoft.Android.Runtime.RuntimeFeature` is now defined in exactly one
assembly (`Mono.Android.Runtime.dll`), and the 58 `CS0436` warnings are gone.
This is a focused subset of #11625 that addresses only the `RuntimeFeature`
duplication, without that PR's class rename or unrelated warning cleanups.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR removes the duplicate compilation of Microsoft.Android.Runtime.RuntimeFeature into Mono.Android.dll, ensuring it is defined only in Mono.Android.Runtime.dll to eliminate CS0436 type-conflict warnings and avoid CS0104 ambiguity with System.Runtime.CompilerServices.RuntimeFeature.
Changes:
- Stop compiling
Microsoft.Android.Runtime/RuntimeFeature.csintoMono.Android.dll(leaving it only inMono.Android.Runtime.dll). - Add
InternalsVisibleToentries inMono.Android.RuntimeforMicrosoft.Android.Runtime.NativeAOTandMono.Android.NET-Tests. - Disambiguate
RuntimeFeatureusage viausing RuntimeFeature = Microsoft.Android.Runtime.RuntimeFeature;in the affected source files.
Show a summary per file
| File | Description |
|---|---|
| src/Mono.Android/Mono.Android.csproj | Removes duplicate Compile entry for RuntimeFeature.cs to prevent cross-assembly type conflicts. |
| src/Mono.Android/Java.Interop/TypeManager.cs | Adds RuntimeFeature type alias to avoid CS0104 ambiguity. |
| src/Mono.Android/Android.Runtime/JNIEnv.cs | Adds RuntimeFeature type alias to avoid CS0104 ambiguity (while still using BCL RuntimeFeature fully-qualified). |
| src/Mono.Android/Android.Runtime/AndroidRuntime.cs | Adds RuntimeFeature type alias to avoid CS0104 ambiguity. |
| src/Mono.Android.Runtime/Properties/AssemblyInfo.cs.in | Grants internals access to NativeAOT and test assemblies now that RuntimeFeature is owned by Mono.Android.Runtime. |
Copilot's findings
- Files reviewed: 5/5 changed files
- Comments generated: 0
|
@copilot we definitely changed something that affects the numbers of warnings and how our tests filter them. For example, this test is now failing: I want to |
…adjust warning totals Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
…HasTrimmerWarnings Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Addressed in commits Changes made:
Validation:
|
|
@copilot now fix the underlying issues:
|
…nt CI output Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
... Fixed in I pulled the current AZDO build logs for build
This covers the MonoVM failure you pasted plus the corresponding CoreCLR failures seen in the same CI logs. |
Moving RuntimeFeature into Mono.Android.Runtime made the IsNativeAotRuntime guard in JNIEnvInit.Initialize a cross-assembly feature switch, so ILLink no longer eliminates Initialize under NativeAOT. Initialize is force-preserved by the ILLink descriptor and contains a [LibraryImport] to xamarin_app_init, which becomes a direct native reference (xa-internal-api is a DirectPInvoke). That symbol is only defined by the MonoVM/CoreCLR marshal methods native code, which is never generated for NativeAOT, so the link failed with XA3007 "undefined symbol: xamarin_app_init". Emit a no-op xamarin_app_init definition into the NativeAOT jni-init assembler source so the linker can resolve the reference. Initialize is never invoked under NativeAOT (InitializeNativeAotRuntime is used instead), so the no-op is safe. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…timefeature-single-assembly
Enable ILLink to process Mono.Android.Runtime.dll so RuntimeFeature feature switches can be folded when referenced from Mono.Android during partial trimming. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update BuildHasTrimmerWarnings counts after marking Mono.Android.Runtime trimmable removes the extra CoreCLR warning. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mono.Android.Runtime is now trimmable, so RuntimeFeature switches can fold the unreachable JNIEnvInit.Initialize body for NativeAOT and the jni-init assembler no longer needs to emit a no-op xamarin_app_init definition. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the RuntimeFeature single-assembly PR focused by moving the BuildHasTrimmerWarnings diagnostics change to a separate PR and dropping the leftover LlvmIrGeneratorTests using change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| [assembly: AssemblyTitle ("Mono.Android.Runtime.dll")] | ||
| [assembly: AssemblyProduct (".NET for Android")] | ||
| [assembly: AssemblyCompany ("Microsoft Corporation")] | ||
| [assembly: AssemblyMetadata ("IsTrimmable", "True")] |
There was a problem hiding this comment.
Should we actually set the IsTrimmable=true MSBuild property, so we get the analyzers, too?
There was a problem hiding this comment.
We'll need to switch to $(GenerateAssemblyInfo)=true. I'll look into what other changes that will require tomorrow.
There was a problem hiding this comment.
I moved the attributes to MSBuild properties. please take another look.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers
left a comment
There was a problem hiding this comment.
Verified the migration from AssemblyInfo.cs.in to MSBuild GenerateAssemblyInfo by extracting the produced Mono.Android.Runtime.dll from the CI build (build 1496564, Microsoft.Android.Runtime.37.android...gh11669.0.nupkg) and reading its assembly manifest directly.
All original assembly attributes are preserved:
AssemblyTitle=Mono.Android.Runtime.dllAssemblyProduct=.NET for AndroidAssemblyCompany=Microsoft CorporationAssemblyInformationalVersion=37.0.0.0; git-rev-head:...; git-branch:...(same format as before, no+shasuffix thanks toIncludeSourceRevisionInInformationalVersion=false)TargetPlatform=Android37.0SupportedOSPlatform=Android24.0InternalsVisibleTo→Mono.Android(correct public key)
Intended additions look correct:
InternalsVisibleTo→Microsoft.Android.Runtime.NativeAOTandMono.Android.NET-Tests(needed now thatRuntimeFeaturelives in this assembly)IsTrimmablemetadata from the new<IsTrimmable>true</IsTrimmable>
Correctly suppressed via the new Generate*Attribute=false properties: no AssemblyConfiguration, AssemblyFileVersion, AssemblyVersion, or RepositoryUrl attributes. Signing/identity is unchanged (PublicKey flag, product.snk, version 0.0.0.0 — matching prior behavior).
LGTM. 👍
Summary
Microsoft.Android.Runtime.RuntimeFeaturewas compiled into two assemblies:Mono.Android.Runtime.dll(src/Mono.Android.Runtime/Mono.Android.Runtime.csproj)Mono.Android.dll(src/Mono.Android/Mono.Android.csproj)Because
Mono.AndroidreferencesMono.Android.Runtime, compilingMono.Android.dllemitted duplicate-type warnings like:This PR makes
RuntimeFeaturelive in exactly one assembly:Mono.Android.Runtime.dll.Changes
Mono.Android.csproj— removes the duplicate<Compile>ofRuntimeFeature.cs, so the type is no longer compiled intoMono.Android.dll.AndroidRuntime.cs,JNIEnv.cs,TypeManager.cs— addsusing RuntimeFeature = Microsoft.Android.Runtime.RuntimeFeature;because onceRuntimeFeatureis imported instead of source-compiled intoMono.Android, the bare name conflicts withSystem.Runtime.CompilerServices.RuntimeFeature.Mono.Android.Runtime.csproj/Mono.Android.Runtime.targets— migrates assembly metadata from the hand-writtenProperties/AssemblyInfo.cs.intemplate to MSBuildGenerateAssemblyInfo:Properties/AssemblyInfo.cs.inand the_BuildAssemblyInfo_cstarget (which ranReplaceFileContentson the template) fromMono.Android.Runtime.targets.<GenerateAssemblyInfo>true</GenerateAssemblyInfo>withGenerateAssemblyConfigurationAttribute,GenerateAssemblyFileVersionAttribute,GenerateAssemblyVersionAttribute,GenerateRepositoryUrlAttribute, andIncludeSourceRevisionInInformationalVersionall set tofalseso no new attributes are introduced vs. the old template.AssemblyTitle,Product,Company, and theInternalsVisibleToitems. A new_SetGeneratedAssemblyInfoPropertiestarget (beforeGetAssemblyAttributes) suppliesInformationalVersion,TargetPlatformIdentifier/TargetPlatformVersion, andSupportedOSPlatformVersionfrom the existingGetXAVersionInfoversion info.InternalsVisibleToforMicrosoft.Android.Runtime.NativeAOTandMono.Android.NET-Tests, which previously reachedRuntimeFeaturethroughMono.Android.dll.Mono.Android.Runtime.dlltrimmable with<IsTrimmable>true</IsTrimmable>. This keeps the cross-assemblyRuntimeFeaturefeature switches visible to ILLink in partial-trimmed apps.Why
IsTrimmableis neededMoving
RuntimeFeatureintoMono.Android.Runtime.dllmakesMono.Android.dllconsume feature-switch properties across an assembly boundary. In partial trimming, ILLink only substitutes feature-switch getters in assemblies it processes. Without markingMono.Android.Runtime.dlltrimmable, some runtime-specific branches stayed live, causing the CoreCLR APK size-regression test to fail.Marking
Mono.Android.Runtime.dlltrimmable lets ILLink fold thoseRuntimeFeatureguards again.Relationship to #11625
This is a focused subset of #11625. It intentionally avoids the broader class rename (
RuntimeFeature→AndroidRuntimeFeature) and resolves the resultingCS0104ambiguity with localusingaliases instead.Follow-up
The
BuildHasTrimmerWarningsdiagnostic improvement was split out into #11981 so this PR remains focused on theRuntimeFeaturesingle-assembly change.Verification
Latest PR validation: dotnet-android #1496564 ✅
The produced
Mono.Android.Runtime.dllfrom that build was inspected to confirm theGenerateAssemblyInfomigration is faithful — all attributes from the oldAssemblyInfo.cs.in(AssemblyTitle,Product,Company,AssemblyInformationalVersion,TargetPlatform=Android37.0,SupportedOSPlatform=Android24.0,InternalsVisibleToforMono.Android) are present, the newInternalsVisibleTo(NativeAOT, NET-Tests) andIsTrimmablemetadata are added, and no unexpected attributes (AssemblyConfiguration,AssemblyFileVersion,AssemblyVersion,RepositoryUrl) were introduced.