Skip to content

Commit 5f67945

Browse files
authored
[dotnet] Work around an expectation mismatch between ILLink and library projects. Fixes #19037. (#19049)
ILLink doesn't handle library projects the way we need: the library is automatically treated as a root assembly, with the entry point as the root. This doesn't work, because library projects don't have an entry point. In earlier versions of .NET (and Xamarin), we'd solved this by a custom linker step that would manually root everything that needed to be rooted, but that doesn't work anymore because we hit this sanity check in ILLink: > ILLink : error IL1034: Root assembly 'MyExtension, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have entry point. Technically this happens because the library project is configured as a root assembly, where the entry point is the root point (and in that regards the sanity check is rather sane). The best solution would be if we could just treat the library assembly as any other assembly, and manually root it in our custom linker steps - but the custom linker step we have for this kind of rooting will only iterate over types in assemblies that are already marked somehow, and that's not necessarily the case for app extension projects - the end result is that the entire app extension assembly is linked away. A close runner-up as the second best solution is to provide the API that needs to be rooted as an xml file to the linker. This works, but we currently don't have the infrastructure in the code to generate this xml file before running the linker (it would be a rather major undertaking). This work is tentatively scheduled for .NET 9 (#17693). So I went for the third option: set RootMode="Library" for the library assembly. I'm not sure exactly what that means ILLink will mark, but as long as _anything_ is marked, our custom linker step will run. This seems like an acceptable workaround until we can implement the previous solution. Fixes #19037.
1 parent 5ed8fe8 commit 5f67945

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

dotnet/targets/Xamarin.Shared.Sdk.targets

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,15 @@
11641164
</ItemGroup>
11651165
</Target>
11661166

1167+
<!-- https://github.com/xamarin/xamarin-macios/issues/19037 -->
1168+
<!-- The trimmer will set the RootMode for the current assembly to 'EntryPoint', but that doesn't work for app extension projects, because those are library projects that don't have entry points.
1169+
So here we set RootMode=Library for these cases. -->
1170+
<Target Name="_FixRootAssemblyForAppExtensions" AfterTargets="PrepareForILLink" Condition="'$(IsAppExtension)' == 'true'">
1171+
<ItemGroup>
1172+
<TrimmerRootAssembly Update="@(TrimmerRootAssembly)" Condition=" '%(TrimmerRootAssembly.RootMode)' == 'EntryPoint' " RootMode="Library" />
1173+
</ItemGroup>
1174+
</Target>
1175+
11671176
<Target Name="_CreateAOTDedupAssembly"
11681177
Condition="'$(_RunAotCompiler)' == 'true' And '$(IsMacEnabled)' == 'true'"
11691178
DependsOnTargets="_ComputeManagedAssemblyToLink"

tests/dotnet/UnitTests/ProjectTest.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,24 @@ public void BuildProjectsWithExtensionsAndFrameworks (ApplePlatform platform)
10091009
ExecuteWithMagicWordAndAssert (platform, runtimeIdentifiers, appExecutable);
10101010
}
10111011

1012+
1013+
[TestCase (ApplePlatform.iOS)]
1014+
[TestCase (ApplePlatform.TVOS)]
1015+
[TestCase (ApplePlatform.MacOSX)]
1016+
// [TestCase ("MacCatalyst", "")] - No extension support yet
1017+
public void BuildTrimmedExtensionProject (ApplePlatform platform)
1018+
{
1019+
Configuration.IgnoreIfIgnoredPlatform (platform);
1020+
var project_path = GetProjectPath ("ExtensionProject", platform: platform);
1021+
1022+
Clean (project_path);
1023+
1024+
var properties = GetDefaultProperties ();
1025+
properties ["MtouchLink"] = "Full";
1026+
properties ["LinkMode"] = "Full";
1027+
DotNet.AssertBuild (project_path, properties);
1028+
}
1029+
10121030
[TestCase (ApplePlatform.iOS, "iossimulator-x64;iossimulator-arm64")]
10131031
[TestCase (ApplePlatform.TVOS, "tvossimulator-x64")]
10141032
[TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")]

0 commit comments

Comments
 (0)