Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<NUnitPackageVersion>4.4.0</NUnitPackageVersion>
<NUnitConsoleRunnerPackageVersion>3.22.0</NUnitConsoleRunnerPackageVersion>
<NUnit3TestAdapterPackageVersion>6.1.0</NUnit3TestAdapterPackageVersion>
<NUnitAnalyzersPackageVersion>4.11.2</NUnitAnalyzersPackageVersion>
<NUnitXmlTestLoggerPackageVersion>3.1.15</NUnitXmlTestLoggerPackageVersion>
<MicrosoftNETTestSdkPackageVersion>18.0.1</MicrosoftNETTestSdkPackageVersion>
<!-- Fix transient dependency issue found by component governance 4.7.0 -> 4.7.2 brought by Microsoft.Build package -->
Expand Down
2 changes: 0 additions & 2 deletions builds/Versions-MacCatalyst.plist.in
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@
<key>Optimizations</key>
<dict>
<!-- The key is the value to be passed to mtouch. The string is a very short description. Any IDE UI should also point to the documentation for the optimizations. -->
<key>inline-intptr-size</key>
<string>Inline IntPtr.Size</string>
<key>inline-runtime-arch</key>
<string>Inline NSObject.IsDirectBinding</string>
<key>dead-code-elimination</key>
Expand Down
2 changes: 0 additions & 2 deletions builds/Versions-iOS.plist.in
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,6 @@
<key>Optimizations</key>
<dict>
<!-- The key is the value to be passed to mtouch. The string is a very short description. Any IDE UI should also point to the documentation for the optimizations. -->
<key>inline-intptr-size</key>
<string>Inline IntPtr.Size</string>
<key>inline-runtime-arch</key>
<string>Inline NSObject.IsDirectBinding</string>
<key>dead-code-elimination</key>
Expand Down
2 changes: 0 additions & 2 deletions builds/Versions-macOS.plist.in
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@
<key>Optimizations</key>
<dict>
<!-- The key is the value to be passed to mmp. The string is a very short description. Any IDE UI should also point to the documentation for the optimizations. -->
<key>inline-intptr-size</key>
<string>Inline IntPtr.Size</string>
<key>inline-runtime-arch</key>
<string>Inline Runtime.Arch</string>
<key>inline-isdirectbinding</key>
Expand Down
2 changes: 0 additions & 2 deletions builds/Versions-tvOS.plist.in
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@
<key>Optimizations</key>
<dict>
<!-- The key is the value to be passed to mtouch. The string is a very short description. Any IDE UI should also point to the documentation for the optimizations. -->
<key>inline-intptr-size</key>
<string>Inline IntPtr.Size</string>
<key>inline-runtime-arch</key>
<string>Inline NSObject.IsDirectBinding</string>
<key>dead-code-elimination</key>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Mono.Cecil;

#nullable disable

namespace Mono.Linker {
public static class MethodDefinitionExtensions {
public static bool IsDefaultConstructor (this MethodDefinition method)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
using Mono.Cecil;
using Mono.Cecil.Cil;

#nullable disable

namespace Mono.Tuner {

public static class MethodBodyRocks {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

using Mono.Linker;

#nullable disable

namespace Mono.Tuner {

public static partial class Extensions {
Expand Down
50 changes: 0 additions & 50 deletions docs/website/optimizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,44 +47,6 @@ The default behavior can be overridden by passing `--optimize=[+|-]remove-uithre

[1]: /dotnet/api/UIKit.UIApplication.EnsureUIThread

## Inline IntPtr.Size

Inlines the constant value of `IntPtr.Size` according to the target platform.

This optimization will change the following type of code:

```csharp
if (IntPtr.Size == 8) {
Console.WriteLine ("64-bit platform");
} else {
Console.WriteLine ("32-bit platform");
}
```

into the following (when building for a 64-bit platform):

```csharp
if (8 == 8) {
Console.WriteLine ("64-bit platform");
} else {
Console.WriteLine ("32-bit platform");
}
```

This optimization requires the linker to be enabled, and is only applied to
methods with the `[BindingImpl (BindingImplOptions.Optimizable)]` attribute.

By default it's enabled if targeting a single architecture, or for the
platform assembly (**Xamarin.iOS.dll**, **Xamarin.TVOS.dll**,
**Xamarin.WatchOS.dll** or **Xamarin.Mac.dll**).

If targeting multiple architectures, this optimization will create different
assemblies for the 32-bit version and the 64-bit version of the app, and both
versions will have to be included in the app, effectively increasing the final
app size instead of decreasing it.

The default behavior can be overridden by passing `--optimize=[+|-]inline-intptr-size` to mtouch/mmp.

## Inline NSObject.IsDirectBinding

`NSObject.IsDirectBinding` is an instance property that determines whether a
Expand Down Expand Up @@ -254,24 +216,12 @@ the binding code for `NFCIso15693ReadMultipleBlocksConfiguration.Range`):
NSRange ret;
if (IsDirectBinding) {
if (Runtime.Arch == Arch.DEVICE) {
if (IntPtr.Size == 8) {
ret = global::ObjCRuntime.Messaging.NSRange_objc_msgSend (this.Handle, Selector.GetHandle ("range"));
} else {
global::ObjCRuntime.Messaging.NSRange_objc_msgSend_stret (out ret, this.Handle, Selector.GetHandle ("range"));
}
} else if (IntPtr.Size == 8) {
ret = global::ObjCRuntime.Messaging.NSRange_objc_msgSend (this.Handle, Selector.GetHandle ("range"));
} else {
ret = global::ObjCRuntime.Messaging.NSRange_objc_msgSend (this.Handle, Selector.GetHandle ("range"));
}
} else {
if (Runtime.Arch == Arch.DEVICE) {
if (IntPtr.Size == 8) {
ret = global::ObjCRuntime.Messaging.NSRange_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("range"));
} else {
global::ObjCRuntime.Messaging.NSRange_objc_msgSendSuper_stret (out ret, this.SuperHandle, Selector.GetHandle ("range"));
}
} else if (IntPtr.Size == 8) {
ret = global::ObjCRuntime.Messaging.NSRange_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("range"));
} else {
ret = global::ObjCRuntime.Messaging.NSRange_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("range"));
Expand Down
32 changes: 23 additions & 9 deletions dotnet/targets/Xamarin.Shared.Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@
_ResolveAppExtensionReferences;
_ExtendAppExtensionReferences;
_ComputeLinkerArguments;
_PrepareAssemblies;
_ComputeFrameworkFilesToPublish;
_ComputeDynamicLibrariesToPublish;
ComputeFilesToPublish;
Expand Down Expand Up @@ -730,13 +731,13 @@
<!--
IMarkHandlers which run during Mark
-->
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true'" Type="Xamarin.Linker.Steps.PreserveBlockCodeHandler" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true' And '$(PrepareAssemblies)' != 'true'" Type="Xamarin.Linker.Steps.PreserveBlockCodeHandler" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true'" Type="Xamarin.Linker.OptimizeGeneratedCodeHandler" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true'" Type="Xamarin.Linker.BackingFieldDelayHandler" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true'" Type="Xamarin.Linker.MarkIProtocolHandler" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true' And '$(PrepareAssemblies)' != 'true'" Type="Xamarin.Linker.MarkIProtocolHandler" />
<!-- MarkDispatcher substeps will run for all marked assemblies. -->
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true'" Type="Xamarin.Linker.Steps.MarkDispatcher" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true'" Type="Xamarin.Linker.Steps.PreserveSmartEnumConversionsHandler" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true' And '$(PrepareAssemblies)' != 'true'" Type="Xamarin.Linker.Steps.PreserveSmartEnumConversionsHandler" />

<!--
pre-sweep custom steps
Expand Down Expand Up @@ -1309,15 +1310,28 @@
</ItemGroup>
</Target>

<!-- https://github.com/dotnet/macios/issues/19037 -->
<!-- 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.
So here we set RootMode=Library for these cases. -->
<Target Name="_FixRootAssemblyForAppExtensions" AfterTargets="PrepareForILLink" Condition="'$(IsAppExtension)' == 'true'">
<ItemGroup>
<Target Name="_PostPrepareForILLinkFixups" AfterTargets="PrepareForILLink">
<ItemGroup Condition="'$(IsAppExtension)' == 'true'">
<!-- https://github.com/xamarin/xamarin-macios/issues/19037 -->
<!-- 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.
So here we set RootMode=Library for these cases. -->
<TrimmerRootAssembly Update="@(TrimmerRootAssembly)" Condition=" '%(TrimmerRootAssembly.RootMode)' == 'EntryPoint' " RootMode="Library" />
</ItemGroup>
<!-- If $(IntermediateAssembly) was modified by the AssemblyPreparer task, then we must update the TrimmerRootAssembly item group to point to the updated version of the intermediate assembly. -->
<!-- It turned out a bit complicated, because we want to preserve any existing metadata on the items in the TrimmerRootAssembly item group. -->
<ItemGroup>
<PreparedIntermediateAssembly Include="@(ResolvedFileToPublish)" Condition="'%(ResolvedFileToPublish.BeforePrepareAssembliesPath)' == '@(IntermediateAssembly)'" />
</ItemGroup>
<PropertyGroup>
<_IntermediateAssemblyProperty>@(IntermediateAssembly)</_IntermediateAssemblyProperty>
<_PreparedIntermediateAssemblyProperty>@(PreparedIntermediateAssembly->WithMetadataValue('BeforePrepareAssembliesPath','$(_IntermediateAssemblyProperty)'))</_PreparedIntermediateAssemblyProperty>
</PropertyGroup>
<ItemGroup Condition="@(PreparedIntermediateAssembly->Count()) &gt; 0">
<_PreparedRootedIntermediateAssembly Include="@(TrimmerRootAssembly->'$(_PreparedIntermediateAssemblyProperty)')" Condition="'%(Identity)' == '$(_IntermediateAssemblyProperty)'" />
<TrimmerRootAssembly Remove="@(IntermediateAssembly)" />
<TrimmerRootAssembly Include="@(_PreparedRootedIntermediateAssembly)" />
</ItemGroup>
</Target>

<Target Name="_CreateAOTDedupAssembly"
Condition="'$(_IsDedupEnabled)' == 'true'"
DependsOnTargets="_ComputeManagedAssemblyToLink"
Expand Down
1 change: 1 addition & 0 deletions msbuild/ILMerge.targets
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<MergedAssemblies Include="@(ReferenceDependencyPaths)" Condition="'%(FileName)' == 'AssemblyStripper'" />
<MergedAssemblies Include="@(ReferencePath)" Condition="'%(FileName)' == 'MonoTargetsTasks'" />
<MergedAssemblies Include="@(ReferencePath)" Condition="'%(FileName)' == 'Xamarin.MacDev'" />
<MergedAssemblies Include="@(ReferencePath)" Condition="'%(FileName)' == 'assembly-preparer'" />
<MergedAssemblies Include="@(ReferencePath)" Condition="'%(FileName)' == 'DotNetZip'" />
<MergedAssemblies Include="@(ReferencePath)" Condition="'%(FileName)' == 'ILLink.Tasks'" />
<MergedAssemblies Include="@(ReferencePath)" Condition="'%(FileName)' == 'ILStrip'" />
Expand Down
4 changes: 2 additions & 2 deletions msbuild/Xamarin.MacDev.Tasks/ErrorHelper.msbuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
#nullable enable

namespace Xamarin.Bundler {
public static partial class ErrorHelper {
public static ApplePlatform Platform;
static partial class ErrorHelper {
public static ApplePlatform Platform = ApplePlatform.None;

internal static string Prefix {
get {
Expand Down
83 changes: 83 additions & 0 deletions msbuild/Xamarin.MacDev.Tasks/Tasks/PrepareAssemblies.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

using Xamarin.Build;
using Xamarin.Utils;

#nullable enable

namespace Xamarin.MacDev.Tasks {
public class PrepareAssemblies : XamarinTask {
const string ErrorPrefix = "AP";

#region Inputs
[Required]
public ITaskItem [] InputAssemblies { get; set; } = [];

public string MakeReproPath { get; set; } = "";

public string OutputDirectory { get; set; } = "";

[Required]
public string Registrar { get; set; } = "";
#endregion

#region Outputs
[Output]
public ITaskItem [] OutputAssemblies { get; set; } = [];
#endregion

Dictionary<AssemblyPreparerInfo, ITaskItem> map = new ();

AssemblyPreparerInfo GetAssemblyInfo (ITaskItem item)
{
var inputPath = item.ItemSpec;
var outputPath = Path.Combine (OutputDirectory, Path.GetFileName (inputPath));
var rv = new AssemblyPreparerInfo (inputPath, outputPath);
map [rv] = item;
return rv;
}

public override bool Execute ()
{
try {
var infos = InputAssemblies.Select (GetAssemblyInfo).ToArray ();
using var preparer = new AssemblyPreparer (infos, Platform);
preparer.MakeReproPath = MakeReproPath;
preparer.SetRegistrar (Registrar);
var rv = preparer.Prepare (out var exceptions);

foreach (var pe in exceptions) {
if (pe.Error) {
Log.LogError (null, $"{ErrorPrefix}{pe.Code}", null, pe.FileName ?? "MSBuild", 0, 0, 0, 0, message: pe.Message);
Exception? ie = pe.InnerException;
while (ie is not null) {
Log.LogMessage (MessageImportance.Low, "Inner exception: {0}\n{1}", ie.Message, ie.StackTrace);
ie = ie.InnerException;
}
} else {
Log.LogWarning (null, $"{ErrorPrefix}{pe.Code}", null, pe.FileName ?? "MSBuild", 0, 0, 0, 0, message: pe.Message);
}
}

OutputAssemblies = preparer.Assemblies.Select (v => {
var item = map [v];
item.ItemSpec = v.OutputPath;
item.SetMetadata ("BeforePrepareAssembliesPath", v.InputPath);
return item;
}).ToArray ();
return rv && !Log.HasLoggedErrors;
} catch (Exception e) {
Log.LogError ("Unexpected error while preparing assemblies: {0}", e);
return false;
}
}
}
}
Loading
Loading