Skip to content

Commit

Permalink
[build] make TrimMode=full function like NativeAOT
Browse files Browse the repository at this point in the history
Context: dotnet/android#8805
Context: xamarin/xamarin-macios#20354

In .NET 9, we want .NET MAUI applications to be able to use the
`TrimMode=full` option to remove unused code from the application:

    <PropertyGroup Condition="'$(Configuration)' == 'Release'">
      <TrimMode>full</TrimMode>
    </PropertyGroup>

With all the trimming work done to support NativeAOT, we should toggle
the same options when `TrimMode=full` is used:

* `MauiStrictXamlCompilation=true`
* `MauiXamlRuntimeParsingSupport=false`
* `MauiShellSearchResultsRendererDisplayMemberNameSupported=false`
* `MauiQueryPropertyAttributeSupport=false`
* `MauiImplicitCastOperatorsUsageViaReflectionSupport=false`

With these set, the `dotnet new maui` project template *should* have
zero trimmer warnings when `TrimMode=full` is used. Developers can also
adjust these settings and respond to trimmer warnings in their own code.

I also updated `RunOnAndroid` and `RunOniOS` tests to verify that
project templates launch successfully with `TrimMode=full`.
  • Loading branch information
jonathanpeppers committed May 7, 2024
1 parent fd6be16 commit 4559dfc
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 24 deletions.
2 changes: 2 additions & 0 deletions docs/design/FeatureSwitches.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Certain features of MAUI can be enabled or disabled using feature switches. The easiest way to control the features is by putting the corresponding MSBuild property into the app's project file. Disabling unnecessary features can help reducing the app size when combined with the [`full` trimming mode](https://learn.microsoft.com/dotnet/core/deploying/trimming/trimming-options).

The following switches are toggled for applications running on Mono for `TrimMode=full` as well as NativeAOT.

| MSBuild Property Name | AppContext Setting | Description |
|-|-|-|
| MauiXamlRuntimeParsingSupport | Microsoft.Maui.RuntimeFeature.IsXamlRuntimeParsingSupported | When disabled, all XAML loading at runtime will throw an exception. This will affect usage of APIs such as the `LoadFromXaml` extension method. This feature can be safely turned off when all XAML resources are compiled using XamlC (see [XAML compilation](https://learn.microsoft.com/dotnet/maui/xaml/xamlc)). This feature is enabled by default for all configurations except for NativeAOT. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
<_MauiXamlCValidateOnly Condition="'$(Configuration)' == 'Debug' AND '$(_MauiForceXamlCForDebug)' != 'True'">True</_MauiXamlCValidateOnly>
<_MauiXamlCValidateOnly Condition="'$(BuildingForLiveUnitTesting)' == 'True' ">True</_MauiXamlCValidateOnly>

<MauiStrictXamlCompilation Condition="'$(MauiStrictXamlCompilation)' == '' and '$(PublishAot)' == 'true'">true</MauiStrictXamlCompilation>
<MauiStrictXamlCompilation Condition="'$(MauiStrictXamlCompilation)' == '' and ('$(PublishAot)' == 'true' or '$(TrimMode)' == 'full')">true</MauiStrictXamlCompilation>
<_MauiXamlCNoWarn>$(NoWarn)</_MauiXamlCNoWarn>
<_MauiXamlCNoWarn Condition="'$(MauiStrictXamlCompilation)' != 'true'">$(_MauiXamlCNoWarn);XC0022;XC0023</_MauiXamlCNoWarn>
</PropertyGroup>
Expand Down Expand Up @@ -212,11 +212,13 @@

<Target Name="_MauiPrepareForILLink" BeforeTargets="PrepareForILLink;_GenerateRuntimeConfigurationFilesInputCache">
<PropertyGroup>
<MauiXamlRuntimeParsingSupport Condition="'$(MauiXamlRuntimeParsingSupport)' == '' and '$(PublishAot)' == 'true'">false</MauiXamlRuntimeParsingSupport>
<MauiEnableIVisualAssemblyScanning Condition="'$(MauiEnableIVisualAssemblyScanning)' == ''">false</MauiEnableIVisualAssemblyScanning>
<MauiShellSearchResultsRendererDisplayMemberNameSupported Condition="'$(MauiShellSearchResultsRendererDisplayMemberNameSupported)' == '' and '$(PublishAot)' == 'true'">false</MauiShellSearchResultsRendererDisplayMemberNameSupported>
<MauiQueryPropertyAttributeSupport Condition="'$(MauiQueryPropertyAttributeSupport)' == '' and '$(PublishAot)' == 'true'">false</MauiQueryPropertyAttributeSupport>
<MauiImplicitCastOperatorsUsageViaReflectionSupport Condition="'$(MauiImplicitCastOperatorsUsageViaReflectionSupport)' == '' and '$(PublishAot)' == 'true'">false</MauiImplicitCastOperatorsUsageViaReflectionSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(PublishAot)' == 'true' or '$(TrimMode)' == 'full'">
<MauiXamlRuntimeParsingSupport Condition="'$(MauiXamlRuntimeParsingSupport)' == '' ">false</MauiXamlRuntimeParsingSupport>
<MauiShellSearchResultsRendererDisplayMemberNameSupported Condition="'$(MauiShellSearchResultsRendererDisplayMemberNameSupported)' == ''">false</MauiShellSearchResultsRendererDisplayMemberNameSupported>
<MauiQueryPropertyAttributeSupport Condition="'$(MauiQueryPropertyAttributeSupport)' == ''">false</MauiQueryPropertyAttributeSupport>
<MauiImplicitCastOperatorsUsageViaReflectionSupport Condition="'$(MauiImplicitCastOperatorsUsageViaReflectionSupport)' == ''">false</MauiImplicitCastOperatorsUsageViaReflectionSupport>
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="Microsoft.Maui.RuntimeFeature.IsXamlRuntimeParsingSupported"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,27 @@ public void AndroidTemplateTearDown()


[Test]
[TestCase("maui", DotNetPrevious, "Debug")]
[TestCase("maui", DotNetPrevious, "Release")]
[TestCase("maui", DotNetCurrent, "Debug")]
[TestCase("maui", DotNetCurrent, "Release")]
[TestCase("maui-blazor", DotNetPrevious, "Debug")]
[TestCase("maui-blazor", DotNetPrevious, "Release")]
[TestCase("maui-blazor", DotNetCurrent, "Debug")]
[TestCase("maui-blazor", DotNetCurrent, "Release")]
public void RunOnAndroid(string id, string framework, string config)
[TestCase("maui", DotNetPrevious, "Debug", null)]
[TestCase("maui", DotNetPrevious, "Release", null)]
[TestCase("maui", DotNetCurrent, "Debug", null)]
[TestCase("maui", DotNetCurrent, "Release", null)]
[TestCase("maui", DotNetCurrent, "Release", "full")]
[TestCase("maui-blazor", DotNetPrevious, "Debug", null)]
[TestCase("maui-blazor", DotNetPrevious, "Release", null)]
[TestCase("maui-blazor", DotNetCurrent, "Debug", null)]
[TestCase("maui-blazor", DotNetCurrent, "Release", null)]
[TestCase("maui-blazor", DotNetCurrent, "Release", "full")]
public void RunOnAndroid(string id, string framework, string config, string trimMode)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");

Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");

if (!string.IsNullOrEmpty(trimMode))
BuildProps.Add($"TrimMode={trimMode}");

AddInstrumentation(projectDir);

Assert.IsTrue(DotnetInternal.Build(projectFile, config, target: "Install", framework: $"{framework}-android", properties: BuildProps),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ public void AppleTemplateFxtTearDown()
}

[Test]
[TestCase("maui", "Debug", DotNetPrevious, "iossimulator-x64", RuntimeVariant.Mono)]
[TestCase("maui", "Release", DotNetPrevious, "iossimulator-x64", RuntimeVariant.Mono)]
[TestCase("maui", "Debug", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono)]
[TestCase("maui", "Release", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono)]
[TestCase("maui-blazor", "Debug", DotNetPrevious, "iossimulator-x64", RuntimeVariant.Mono)]
[TestCase("maui-blazor", "Release", DotNetPrevious, "iossimulator-x64", RuntimeVariant.Mono)]
[TestCase("maui-blazor", "Debug", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono)]
[TestCase("maui-blazor", "Release", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono)]
[TestCase("maui", "Release", DotNetCurrent, "iossimulator-x64", RuntimeVariant.NativeAOT)]
public void RunOniOS(string id, string config, string framework, string runtimeIdentifier, RuntimeVariant runtimeVariant)
[TestCase("maui", "Debug", DotNetPrevious, "iossimulator-x64", RuntimeVariant.Mono, null)]
[TestCase("maui", "Release", DotNetPrevious, "iossimulator-x64", RuntimeVariant.Mono, null)]
[TestCase("maui", "Debug", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono, null)]
[TestCase("maui", "Release", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono, null)]
[TestCase("maui", "Release", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono, "full")]
[TestCase("maui-blazor", "Debug", DotNetPrevious, "iossimulator-x64", RuntimeVariant.Mono, null)]
[TestCase("maui-blazor", "Release", DotNetPrevious, "iossimulator-x64", RuntimeVariant.Mono, null)]
[TestCase("maui-blazor", "Debug", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono, null)]
[TestCase("maui-blazor", "Release", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono, null)]
[TestCase("maui-blazor", "Release", DotNetCurrent, "iossimulator-x64", RuntimeVariant.Mono, "full")]
[TestCase("maui", "Release", DotNetCurrent, "iossimulator-x64", RuntimeVariant.NativeAOT, null)]
public void RunOniOS(string id, string config, string framework, string runtimeIdentifier, RuntimeVariant runtimeVariant, string trimMode)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Expand All @@ -52,6 +54,9 @@ public void RunOniOS(string id, string config, string framework, string runtimeI
buildProps.Add("IlcTreatWarningsAsErrors=false"); // TODO: Remove this once all warnings are fixed https://github.com/dotnet/maui/issues/19397
}

if (!string.IsNullOrEmpty(trimMode))
buildProps.Add($"TrimMode={trimMode}");

Assert.IsTrue(DotnetInternal.Build(projectFile, config, framework: $"{framework}-ios", properties: buildProps),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");

Expand Down

0 comments on commit 4559dfc

Please sign in to comment.