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
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
28 changes: 21 additions & 7 deletions dotnet/targets/Xamarin.Shared.Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@
_ResolveAppExtensionReferences;
_ExtendAppExtensionReferences;
_ComputeLinkerArguments;
_PrepareAssemblies;
_ComputeFrameworkFilesToPublish;
_ComputeDynamicLibrariesToPublish;
ComputeFilesToPublish;
Expand Down Expand Up @@ -729,7 +730,7 @@
<!--
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" />
Expand Down Expand Up @@ -1271,15 +1272,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/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. -->
<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
79 changes: 79 additions & 0 deletions msbuild/Xamarin.MacDev.Tasks/Tasks/PrepareAssemblies.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
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; } = "";
#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)); // FIXME: wrong for resource assemblies, at the very least.
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;
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;
}
}
}
}
4 changes: 1 addition & 3 deletions msbuild/Xamarin.MacDev.Tasks/Xamarin.MacDev.Tasks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\external\Xamarin.MacDev\Xamarin.MacDev\Xamarin.MacDev.csproj" />
<ProjectReference Include="..\..\tools\assembly-preparer\assembly-preparer.csproj" />
<ProjectReference Include="..\Xamarin.Localization.MSBuild\Xamarin.Localization.MSBuild.csproj">
<ReferenceSourceTarget>ProjectReference</ReferenceSourceTarget>
</ProjectReference>
Expand Down Expand Up @@ -70,9 +71,6 @@
</Target>

<ItemGroup>
<Compile Include="..\..\tools\common\ApplePlatform.cs">
<Link>ApplePlatform.cs</Link>
</Compile>
<Compile Include="..\..\tools\common\StringUtils.cs">
<Link>StringUtils.cs</Link>
</Compile>
Expand Down
43 changes: 43 additions & 0 deletions msbuild/Xamarin.Shared/Xamarin.Shared.targets
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Copyright (C) 2018 Microsoft. All rights reserved.
<UsingTask TaskName="Xamarin.MacDev.Tasks.PackLibraryResources" AssemblyFile="$(_TaskAssemblyName)" />
<UsingTask TaskName="Xamarin.MacDev.Tasks.ParseBundlerArguments" AssemblyFile="$(_TaskAssemblyName)" />
<UsingTask TaskName="Xamarin.MacDev.Tasks.ParseDeviceSpecificBuildInformation" AssemblyFile="$(_TaskAssemblyName)" />
<UsingTask TaskName="Xamarin.MacDev.Tasks.PrepareAssemblies" AssemblyFile="$(_TaskAssemblyName)" />
<UsingTask TaskName="Xamarin.MacDev.Tasks.PrepareNativeReferences" AssemblyFile="$(_TaskAssemblyName)" />
<UsingTask TaskName="Xamarin.MacDev.Tasks.PrepareResourceRules" AssemblyFile="$(_TaskAssemblyName)" />
<UsingTask TaskName="Xamarin.MacDev.Tasks.PropertyListEditor" AssemblyFile="$(_TaskAssemblyName)" />
Expand Down Expand Up @@ -3259,6 +3260,48 @@ Copyright (C) 2018 Microsoft. All rights reserved.

<Target Name="_BeforeCreateIpaForDistribution" Condition="'$(IsAppDistribution)' == 'true'" DependsOnTargets="$(_BeforeCreateIpaForDistributionDependsOn)" />

<PropertyGroup>
<PrepareAssemblies Condition="'$(PrepareAssemblies)' == ''">true</PrepareAssemblies>
</PropertyGroup>

<Target
Name="_PrepareAssembliesForPreparation"
DependsOnTargets="_ComputeAssembliesToPostprocessOnPublish"
>
<ItemGroup>
<_AssembliesToPrepare Include="@(ResolvedFileToPublish)" Condition="'%(ResolvedFileToPublish.PostprocessAssembly)' == 'true'" />
<!-- We implicitly pick up PDBs next to input assemblies. We will filter these out of the publish set. -->
<__PDBToPrepare Include="@(ResolvedFileToPublish)" Exclude="@(_AssembliesToPrepare->'%(RelativeDir)%(Filename).pdb')" />
<_PDBToPrepare Include="@(ResolvedFileToPublish)" Exclude="@(__PDBToLink)" />
</ItemGroup>
<PropertyGroup>
<PreparedAssembliesDirectory>$([MSBuild]::EnsureTrailingSlash('$(DeviceSpecificIntermediateOutputPath)prepared-assemblies'))</PreparedAssembliesDirectory>
</PropertyGroup>
</Target>

<!-- FIXME: "Outputs" calculation is wrong for resource assemblies (wrong directory) -->
<Target
Name="_PrepareAssemblies"
Condition="'$(PrepareAssemblies)' == 'true'"
Inputs="@(_AssembliesToPrepare)"
Outputs="@(_AssembliesToPrepare->'$(PreparedAssembliesDirectory)%(Filename)%(Extension)')"
DependsOnTargets="_PrepareAssembliesForPreparation;_ComputeAssembliesToPostprocessOnPublish"
>
<PrepareAssemblies
InputAssemblies="@(_AssembliesToPrepare)"
MakeReproPath="$(_PrepareAssembliesMakeReproPath)"
OutputDirectory="$(PreparedAssembliesDirectory)"
TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)"
>
<Output TaskParameter="OutputAssemblies" ItemName="_PreparedAssemblies" />
</PrepareAssemblies>

<ItemGroup>
<ResolvedFileToPublish Remove="@(_AssembliesToPrepare)" />
<ResolvedFileToPublish Include="@(_PreparedAssemblies)" />
</ItemGroup>
</Target>

<Target Name="CreateIpa" Condition="'$(_CanArchive)' == 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst'" DependsOnTargets="$(CreateIpaDependsOn)" />

<Import Project="$(MSBuildThisFileDirectory)Xamarin.Shared.ObjCBinding.targets" Condition="'$(IsBindingProject)' == 'true'" />
Expand Down
2 changes: 1 addition & 1 deletion src/ObjCRuntime/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
namespace Xamarin.Bundler {
#else
namespace ObjCRuntime {
Expand Down
2 changes: 1 addition & 1 deletion src/ObjCRuntime/ErrorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#nullable enable

#if MTOUCH || MMP || MMP_TEST || MTOUCH_TESTS
#if MTOUCH || MMP || MMP_TEST || MTOUCH_TESTS || ASSEMBLY_PREPARER
#define BUNDLER
#endif

Expand Down
20 changes: 10 additions & 10 deletions src/ObjCRuntime/Registrar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
using ObjCRuntime;
using Xamarin.Bundler;

#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
using Xamarin.Utils;
using TAssembly = Mono.Cecil.AssemblyDefinition;
using TType = Mono.Cecil.TypeReference;
Expand Down Expand Up @@ -93,7 +93,7 @@ public static List<ProductException> GetMT4127 (TMethod impl, List<TMethod> ifac
}

abstract partial class Registrar {
#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
public Application App { get; protected set; }
#endif

Expand Down Expand Up @@ -156,7 +156,7 @@ internal class ObjCType {

public bool IsCategory { get { return CategoryAttribute is not null; } }

#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
HashSet<ObjCType> all_protocols;
// This contains all protocols in the type hierarchy.
// Given a type T that implements a protocol with super protocols:
Expand Down Expand Up @@ -884,7 +884,7 @@ public Trampoline Trampoline {
if (trampoline != Trampoline.None)
return trampoline;

#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
throw ErrorHelper.CreateError (8018, Errors.MT8018);
#else
var mi = (System.Reflection.MethodInfo) Method;
Expand Down Expand Up @@ -1331,7 +1331,7 @@ internal static string AppKit {
}
#endif

#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
internal string AssemblyName {
get {
switch (App.Platform) {
Expand Down Expand Up @@ -1379,7 +1379,7 @@ public string PlatformAssembly {
}
}

#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
// "#if MTOUCH" code does not need locking when accessing 'types', because mtouch is single-threaded.
public Dictionary<TType, ObjCType> Types {
get { return types; }
Expand Down Expand Up @@ -2205,7 +2205,7 @@ ObjCType RegisterTypeUnsafe (TType type, ref List<Exception> exceptions)
}
} else {
TMethod method = null;
#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
method = attrib.Method;
#endif
var objcMethod = new ObjCMethod (this, objcType, method) {
Expand Down Expand Up @@ -2261,7 +2261,7 @@ ObjCType RegisterTypeUnsafe (TType type, ref List<Exception> exceptions)
FieldType = "@",
IsProperty = true,
IsStatic = IsStatic (property),
#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
Property = property,
#endif
}, ref exceptions);
Expand Down Expand Up @@ -2657,7 +2657,7 @@ protected string GetExportedTypeName (TType type)
string GetBoolEncoding ()
{
// map managed 'bool' to ObjC BOOL = 'unsigned char' in OSX and 32bit iOS architectures and 'bool' in 64bit iOS architectures
#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
switch (App.Platform) {
case ApplePlatform.iOS:
case ApplePlatform.TVOS:
Expand Down Expand Up @@ -2782,7 +2782,7 @@ protected void UnlockRegistrar ()
System.Threading.Monitor.Exit (types);
}

#if MTOUCH || MMP || BUNDLER
#if MTOUCH || MMP || BUNDLER || PRETRIM
internal static void NSLog (string format, params object [] args)
{
Console.WriteLine (format, args);
Expand Down
9 changes: 9 additions & 0 deletions tests/assembly-preparer/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
global using System.IO;

global using Mono.Cecil;
global using NUnit.Framework;

global using Xamarin;
global using Xamarin.Build;
global using Xamarin.Tests;
global using Xamarin.Utils;
5 changes: 5 additions & 0 deletions tests/assembly-preparer/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
TOP=../..
include $(TOP)/Make.config

run-tests:
$(DOTNET) test *.csproj
Loading
Loading