Skip to content

Commit

Permalink
[dotnet] Delay computing trimming options until MAUI has had a chance…
Browse files Browse the repository at this point in the history
… to change the default. (#20970)

See comment in code for a deeper explanation.

Partial fix for https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2053707.

---------

Co-authored-by: Alex Soto <[email protected]>
  • Loading branch information
rolfbjarne and dalexsoto authored Aug 7, 2024
1 parent 47137d6 commit 7e54b16
Show file tree
Hide file tree
Showing 79 changed files with 2,071 additions and 27 deletions.
1 change: 1 addition & 0 deletions dotnet/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ $(1)_NUGET_TARGETS = \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Xamarin.Shared.Sdk.Publish.targets \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Xamarin.Shared.Sdk.TargetFrameworkInference.props \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Xamarin.Shared.Sdk.props \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Xamarin.Shared.Sdk.Trimming.props \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Xamarin.Shared.Sdk.targets \

endef
Expand Down
73 changes: 73 additions & 0 deletions dotnet/targets/Xamarin.Shared.Sdk.Trimming.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<!--
We have a few requirements when computing trimming properties:
1. We must give MAUI a change to set MtouchLink, which they do in Microsoft.Maui.Controls.iOS.targets
2. We must set SuppressTrimAnalysisWarnings before Microsoft.NET.ILLink.targets is included.
1: Microsoft.Maui.Controls.iOS.targets is included like this:
a) Sdks/Microsoft.NET.Sdk/Sdk/Sdk.targets
b) Microsoft.CSharp.targets
c) Microsoft.CSharp.CurrentVersion.targets
d) Microsoft.Common.targets
e) <project path>/obj/*.csproj.nuget.g.targets
f) packages/microsoft.maui.controls.build.tasks/<version>/buildTransitive/net6.0-ios10.0/Microsoft.Maui.Controls.Build.Tasks.targets
g) packages/microsoft.maui.controls.build.tasks/<version>/buildTransitive/Microsoft.Maui.Controls.Build.Tasks.targets
h) packages/microsoft.maui.controls.build.tasks/<version>/buildTransitive/netstandard2.0/Microsoft.Maui.Controls.Build.Tasks.targets
i) packages/packages/microsoft.maui.controls.build.tasks/<version>/buildTransitive/netstandard2.0/Microsoft.Maui.Controls.Build.Tasks.Before.targets
j) packages/packages/microsoft.maui.controls.build.tasks/<version>/buildTransitive/net6.0-ios10.0/Microsoft.Maui.Controls.iOS.targets
2: Microsoft.NET.ILLink.targets is included like this:
a) Sdks/Microsoft.NET.Sdk/Sdk/Sdk.targets
b) Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets
c) packages/microsoft.net.illink.tasks/<version>/build/Microsoft.NET.ILLink.targets
* Microsoft.NET.Sdk.targets is loaded right after
Microsoft.CSharp.targets, and Microsoft.NET.Sdk.targets doesn't
provide any customization points, so we can't inject logic in
Microsoft.NET.Sdk.targets before Microsoft.NET.ILLink.targets is
loaded.
* However, Microsoft.Common.targets has a few customization points
that are loaded after build logic from NuGets is loaded (aka
Microsoft.Maui.Controls.iOS.targets), of which
CustomBeforeDirectoryBuildTargets and
CustomAfterDirectoryBuildTargets seem to fit. I chose
CustomAfterDirectoryBuildTargets because that makes it possible to
set MtouchLink/LinkMode in Directory.Build.targets files if people
wants to do so.
-->

<!-- Since we know if we're building for a simulator or not, we can determine the default trimming behavior -->
<PropertyGroup Condition="'$(TrimMode)' != ''">
<!-- If TrimMode is set, then that's the default link mode -->
<_DefaultLinkMode>TrimMode</_DefaultLinkMode>
</PropertyGroup>
<PropertyGroup Condition="'$(TrimMode)' == ''">
<!-- Linking is always on for all assemblies when using NativeAOT - this is because we need to modify all assemblies in the linker for them to be compatible with NativeAOT -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' == 'true'">Full</_DefaultLinkMode>

<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'macOS'">None</_DefaultLinkMode> <!-- Linking is off by default for macOS apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' == 'Release'">SdkOnly</_DefaultLinkMode> <!-- Default linking is on for release builds for Mac Catalyst apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' != 'Release'">None</_DefaultLinkMode> <!-- Default linking is off for non-release builds for Mac Catalyst apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' == 'true'">None</_DefaultLinkMode> <!-- Linking is off by default in the simulator -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' != 'true'">SdkOnly</_DefaultLinkMode> <!-- Linking is SdkOnly for iOS/tvOS/watchOS apps on device -->
</PropertyGroup>
<PropertyGroup>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' == 'macOS'">$(LinkMode)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' != 'macOS'">$(MtouchLink)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == ''">$(_DefaultLinkMode)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' == 'macOS'">None</_LinkMode> <!-- Linking is off by default for macOS apps -->
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' != 'macOS'">SdkOnly</_LinkMode> <!-- Default linking is SdkOnly for iOS/tvOS/watchOS apps -->

<!-- TrimMode specifies what the linker will do with framework assemblies -->
<TrimMode Condition="'$(_LinkMode)' == 'TrimMode'">$(TrimMode)</TrimMode>
<TrimMode Condition="'$(_LinkMode)' == 'None'">copy</TrimMode>
<TrimMode Condition="'$(_LinkMode)' == 'SdkOnly'">partial</TrimMode>
<TrimMode Condition="'$(_LinkMode)' == 'Full'">full</TrimMode>
<!-- For None link mode we also need to set TrimMode for all assemblies. This is done later -->
</PropertyGroup>
</Project>
29 changes: 2 additions & 27 deletions dotnet/targets/Xamarin.Shared.Sdk.props
Original file line number Diff line number Diff line change
Expand Up @@ -143,34 +143,9 @@
<_SdkIsSimulator Condition="'$(_SdkIsSimulator)' == ''">false</_SdkIsSimulator>
</PropertyGroup>

<!-- Since we know if we're building for a simulator or not, we can determine the default trimming behavior -->
<PropertyGroup Condition="'$(TrimMode)' != ''">
<!-- If TrimMode is set, then that's the default link mode -->
<_DefaultLinkMode>TrimMode</_DefaultLinkMode>
</PropertyGroup>
<PropertyGroup Condition="'$(TrimMode)' == ''">
<!-- Linking is always on for all assemblies when using NativeAOT - this is because we need to modify all assemblies in the linker for them to be compatible with NativeAOT -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' == 'true'">Full</_DefaultLinkMode>

<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'macOS'">None</_DefaultLinkMode> <!-- Linking is off by default for macOS apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' == 'Release'">SdkOnly</_DefaultLinkMode> <!-- Default linking is on for release builds for Mac Catalyst apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' != 'Release'">None</_DefaultLinkMode> <!-- Default linking is off for non-release builds for Mac Catalyst apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' == 'true'">None</_DefaultLinkMode> <!-- Linking is off by default in the simulator -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' != 'true'">SdkOnly</_DefaultLinkMode> <!-- Linking is SdkOnly for iOS/tvOS/watchOS apps on device -->
</PropertyGroup>
<PropertyGroup>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' == 'macOS'">$(LinkMode)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' != 'macOS'">$(MtouchLink)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == ''">$(_DefaultLinkMode)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' == 'macOS'">None</_LinkMode> <!-- Linking is off by default for macOS apps -->
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' != 'macOS'">SdkOnly</_LinkMode> <!-- Default linking is SdkOnly for iOS/tvOS/watchOS apps -->

<!-- TrimMode specifies what the linker will do with framework assemblies -->
<TrimMode Condition="'$(_LinkMode)' == 'TrimMode'">$(TrimMode)</TrimMode>
<TrimMode Condition="'$(_LinkMode)' == 'None'">copy</TrimMode>
<TrimMode Condition="'$(_LinkMode)' == 'SdkOnly'">partial</TrimMode>
<TrimMode Condition="'$(_LinkMode)' == 'Full'">full</TrimMode>
<!-- For None link mode we also need to set TrimMode for all assemblies. This is done later -->
<!-- See Xamarin.Shared.Sdk.Trimming.props for an explanation why we use CustomAfterDirectoryBuildTargets to compute trimming options -->
<CustomAfterDirectoryBuildTargets>$(CustomAfterDirectoryBuildTargets);$(MSBuildThisFileDirectory)Xamarin.Shared.Sdk.Trimming.props</CustomAfterDirectoryBuildTargets>
</PropertyGroup>

<!-- We're never using any app hosts -->
Expand Down
27 changes: 27 additions & 0 deletions tests/common/DotNet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,33 @@ public static ExecutionResult AssertNew (string outputDirectory, string template
return new ExecutionResult (output, output, rv.ExitCode);
}

public static ExecutionResult InstallWorkload (params string [] workloads)
{
var args = new List<string> ();
args.Add ("workload");
args.Add ("install");
args.AddRange (workloads);
args.Add ("-v");
args.Add ("diag");
args.Add ("--skip-manifest-update");

var env = new Dictionary<string, string?> ();
env ["MSBuildSDKsPath"] = null;
env ["MSBUILD_EXE_PATH"] = null;

var output = new StringBuilder ();
var rv = Execution.RunWithStringBuildersAsync (Executable, args, env, output, output, Console.Out, workingDirectory: Configuration.SourceRoot, timeout: TimeSpan.FromMinutes (10)).Result;
if (rv.ExitCode != 0) {
var msg = new StringBuilder ();
msg.AppendLine ($"'dotnet workload install' failed with exit code {rv.ExitCode}");
msg.AppendLine ($"Full command: {Executable} {StringUtils.FormatArguments (args)}");
msg.AppendLine (output.ToString ());
Console.WriteLine (msg);
Assert.Fail (msg.ToString ());
}
return new ExecutionResult (output, output, rv.ExitCode);
}

public static ExecutionResult InstallTool (string tool, string path)
{
var installed = ExecuteCommand (Executable, "tool", "list", "--tool-path", path);
Expand Down
14 changes: 14 additions & 0 deletions tests/dotnet/MyMauiApp/MacCatalyst/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyMauiApp"
x:Class="MyMauiApp.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
10 changes: 10 additions & 0 deletions tests/dotnet/MyMauiApp/MacCatalyst/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace MyMauiApp;

public partial class App : Application {
public App ()
{
InitializeComponent ();

MainPage = new AppShell ();
}
}
15 changes: 15 additions & 0 deletions tests/dotnet/MyMauiApp/MacCatalyst/AppShell.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MyMauiApp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyMauiApp"
Shell.FlyoutBehavior="Disabled"
Title="MyMauiApp">

<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />

</Shell>
8 changes: 8 additions & 0 deletions tests/dotnet/MyMauiApp/MacCatalyst/AppShell.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace MyMauiApp;

public partial class AppShell : Shell {
public AppShell ()
{
InitializeComponent ();
}
}
36 changes: 36 additions & 0 deletions tests/dotnet/MyMauiApp/MacCatalyst/MainPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.MainPage">

<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Image
Source="dotnet_bot.png"
HeightRequest="185"
Aspect="AspectFit"
SemanticProperties.Description="dot net bot in a race car number eight" />

<Label
Text="Hello, World!"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />

<Label
Text="Welcome to &#10;.NET Multi-platform App UI"
Style="{StaticResource SubHeadline}"
SemanticProperties.HeadingLevel="Level2"
SemanticProperties.Description="Welcome to dot net Multi platform App U I" />

<Button
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Fill" />
</VerticalStackLayout>
</ScrollView>

</ContentPage>
23 changes: 23 additions & 0 deletions tests/dotnet/MyMauiApp/MacCatalyst/MainPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace MyMauiApp;

public partial class MainPage : ContentPage {
int count = 0;

public MainPage ()
{
InitializeComponent ();
}

private void OnCounterClicked (object sender, EventArgs e)
{
count++;

if (count == 1)
CounterBtn.Text = $"Clicked {count} time";
else
CounterBtn.Text = $"Clicked {count} times";

SemanticScreenReader.Announce (CounterBtn.Text);
}
}

1 change: 1 addition & 0 deletions tests/dotnet/MyMauiApp/MacCatalyst/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../shared.mk
22 changes: 22 additions & 0 deletions tests/dotnet/MyMauiApp/MacCatalyst/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.Extensions.Logging;

namespace MyMauiApp;

public static class MauiProgram {
public static MauiApp CreateMauiApp ()
{
var builder = MauiApp.CreateBuilder ();
builder
.UseMauiApp<App> ()
.ConfigureFonts (fonts => {
fonts.AddFont ("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont ("OpenSans-Semibold.ttf", "OpenSansSemibold");
});

#if DEBUG
builder.Logging.AddDebug();
#endif

return builder.Build ();
}
}
8 changes: 8 additions & 0 deletions tests/dotnet/MyMauiApp/MacCatalyst/MyMauiApp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net$(BundledNETCoreAppTargetFrameworkVersion)-maccatalyst</TargetFrameworks>
</PropertyGroup>

<Import Project="../shared.csproj" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Android.App;
using Android.Content.PM;
using Android.OS;

namespace MyMauiApp;

[Activity (Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Android.App;
using Android.Runtime;

namespace MyMauiApp;

[Application]
public class MainApplication : MauiApplication {
public MainApplication (IntPtr handle, JniHandleOwnership ownership)
: base (handle, ownership)
{
}

protected override MauiApp CreateMauiApp () => MauiProgram.CreateMauiApp ();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#512BD4</color>
<color name="colorPrimaryDark">#2B0B98</color>
<color name="colorAccent">#2B0B98</color>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Foundation;

namespace MyMauiApp;

[Register ("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate {
protected override MauiApp CreateMauiApp () => MauiProgram.CreateMauiApp ();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<!-- See https://aka.ms/maui-publish-app-store#add-entitlements for more information about adding entitlements.-->
<dict>
<!-- App Sandbox must be enabled to distribute a MacCatalyst app through the Mac App Store. -->
<key>com.apple.security.app-sandbox</key>
<true/>
<!-- When App Sandbox is enabled, this value is required to open outgoing network connections. -->
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>

Loading

8 comments on commit 7e54b16

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

Please sign in to comment.