[mono][ios] Drop marshal-ilgen from iOS builds if it is not needed (#88903)
authorJan Dupej <109523496+jandupej@users.noreply.github.com>
Mon, 24 Jul 2023 15:48:12 +0000 (17:48 +0200)
committerGitHub <noreply@github.com>
Mon, 24 Jul 2023 15:48:12 +0000 (17:48 +0200)
* MarshallingPInvokeScanner is applied to Apple toolchains.

* HelloiOS example uses simpler string marshaling.

* Removing marshal-ilgen from HelloWorld.

* Runtime components and runtime library paths are now decided in the correct order relative to building the native runtime.

* RuntimeComponents is manipulated through an ItemGroup.

* Cleaned up commented old code.

* Reordered runtime components section.

* Addressed more feedback.

src/mono/msbuild/apple/build/AppleBuild.props
src/mono/msbuild/apple/build/AppleBuild.targets
src/mono/sample/iOS/Program.cs
src/mono/sample/iOS/Program.csproj

index 75426eb..9ce0696 100644 (file)
@@ -26,6 +26,8 @@
         _InitializeCommonProperties;
         _BeforeAppleBuild;
         _AppleResolveReferences;
+        _ScanAssembliesDecideLightweightMarshaler;
+        $(_ProcessRuntimeComponentsForLibraryMode);
         _AppleAotCompile;
         _BuildNativeLibrary;
         _AppleGenerateAppBundle;
index d2e8520..a816d96 100644 (file)
@@ -4,7 +4,7 @@
     <AppleGenerateAppBundle Condition="'$(AppleGenerateAppBundle)' == ''">true</AppleGenerateAppBundle>
     <!-- Unable to properly integrate nativelib into app build, so not supported for now. -->
     <AppleGenerateAppBundle Condition="'$(_IsLibraryMode)' == 'true'">false</AppleGenerateAppBundle>
-
+    <_ProcessRuntimeComponentsForLibraryMode Condition="'$(_IsLibraryMode)' == 'true'">_ProcessRuntimeComponentsForLibraryMode</_ProcessRuntimeComponentsForLibraryMode>
     <EnableDefaultAssembliesToBundle Condition="'$(EnableDefaultAssembliesToBundle)' == ''">false</EnableDefaultAssembliesToBundle>
   </PropertyGroup>
 
@@ -14,6 +14,8 @@
   <UsingTask Condition="'$(RunAOTCompilation)' == 'true'"
              TaskName="ILStrip"
              AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />
+  <UsingTask TaskName="MonoTargetsTasks.MarshalingPInvokeScanner" 
+             AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />
 
   <Target Name="_CleanPublish" 
           BeforeTargets="Build">
     <ItemGroup>
       <_CommonLinkerArgs Condition="'$(_IsLibraryMode)' == 'true' and '$(TargetOS)' != 'tvos' and '$(TargetOS)' != 'tvossimulator'" Include="-framework GSS" />
     </ItemGroup>
-
-    <PropertyGroup>
-      <RuntimeComponents Condition="'$(RuntimeComponents)' == ''">marshal-ilgen</RuntimeComponents>
-    </PropertyGroup>
-
-    <ItemGroup Condition="'$(_IsLibraryMode)' == 'true'">
-      <!-- add all non stub libs first -->
-      <!-- if runtimecompoents is empty, exclude -static.a and include -stub-static.a instead -->
-      <!-- if runtimecomponents is *, we're ok because all -static.a is included -->
-      <!-- if runtimecomponents is a list, add to items and only pull in -static.a -->
-
-      <_UsedComponents 
-        Condition="'$(RuntimeComponents)' != '' and '$(RuntimeComponents)' != '*'"
-        Include="$(RuntimeComponents)" />
-
-      <_RuntimeLibraries 
-        Include="$(AppleBuildDir)\*-stub-static.a" />
-      <_RuntimeLibraries 
-        Include="$(AppleBuildDir)\*.a"
-        Exclude="$(AppleBuildDir)\*-static.a" />
-
-      <_RuntimeLibraries Remove="$(AppleBuildDir)\libmono-component-%(_UsedComponents.Identity)-stub-static.a" />
-      <_RuntimeLibraries Include="$(AppleBuildDir)\libmono-component-%(_UsedComponents.Identity)-static.a" />
-    </ItemGroup>
   </Target>
 
   <Target Name="_BeforeAppleBuild">
     </ItemGroup>
   </Target>
 
+  <Target Name="_ScanAssembliesDecideLightweightMarshaler" DependsOnTargets="_AppleResolveReferences">
+    <PropertyGroup Condition="'$(RuntimeComponents)'=='*'">
+      <ForceAllComponents>true</ForceAllComponents>
+    </PropertyGroup>
+
+    <ItemGroup Condition="'$(ForceAllComponents)'!='true'">
+      <RuntimeComponentList Include="$(RuntimeComponents)" />
+      <AssembliesToScan Include="@(_AssembliesToBundleInternal)" />
+    </ItemGroup>
+
+    <MarshalingPInvokeScanner Assemblies ="@(AssembliesToScan)" Condition="'$(ForceAllComponents)'!='true'">
+      <Output TaskParameter="IncompatibleAssemblies" ItemName="MonoLightweightMarshallerIncompatibleAssemblies" />
+    </MarshalingPInvokeScanner>
+
+    <ItemGroup Condition="'@(MonoLightweightMarshallerIncompatibleAssemblies->Count())' > 0">
+      <RuntimeComponentList Include="marshal-ilgen" KeepDuplicates="false"/>
+    </ItemGroup>
+    <ItemGroup Condition="'@(MonoLightweightMarshallerIncompatibleAssemblies->Count())' == 0">
+      <RuntimeComponentList Remove="marshal-ilgen" />
+    </ItemGroup>
+
+    <PropertyGroup Condition="'$(ForceAllComponents)'!='true'">
+      <RuntimeComponents>@(RuntimeComponentList)</RuntimeComponents>
+    </PropertyGroup>
+  </Target>
+
+  <Target Name="_ProcessRuntimeComponentsForLibraryMode" DependsOnTargets="_ScanAssembliesDecideLightweightMarshaler" BeforeTargets="_BuildNativeLibrary">
+    <ItemGroup>
+      <!-- add all non stub libs first -->
+      <!-- if runtimecompoents is empty, exclude -static.a and include -stub-static.a instead -->
+      <!-- if runtimecomponents is *, we're ok because all -static.a is included -->
+      <!-- if runtimecomponents is a list, add to items and only pull in -static.a -->
+
+      <_UsedComponents 
+        Condition="'$(RuntimeComponents)' != '' and '$(RuntimeComponents)' != '*'"
+        Include="$(RuntimeComponents)" />
+
+      <_RuntimeLibraries Include="$(AppleBuildDir)\*.a" Exclude="$(AppleBuildDir)\libmono-component-*.a" />
+      <_RuntimeLibraries Include="$(AppleBuildDir)\libmono-component-*-stub-static.a" />
+      <_RuntimeLibraries Remove="$(AppleBuildDir)\libmono-component-%(_UsedComponents.Identity)-stub-static.a" />
+      <_RuntimeLibraries Include="$(AppleBuildDir)\libmono-component-%(_UsedComponents.Identity)-static.a" />
+    </ItemGroup>
+  </Target>
+
   <Target Name="_AppleAotCompile"
           Condition="'$(RunAOTCompilation)' == 'true'">
 
index 1c9839a..54cddc3 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System;
+using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Runtime.InteropServices;
@@ -10,18 +11,31 @@ public static class Program
 {
     // Defined in main.m
     [DllImport("__Internal")]
-    private static extern void ios_set_text(string value);
+    unsafe private static extern void ios_set_text(byte* value);
 
     [DllImport("__Internal")]
     unsafe private static extern void ios_register_button_click(delegate* unmanaged<void> callback);
 
     private static int counter = 0;
 
+    private static void SetText(string txt)
+    {
+        byte[] ascii = ASCIIEncoding.ASCII.GetBytes(txt);
+        
+        unsafe 
+        {
+            fixed (byte* asciiPtr = ascii)
+            {
+                ios_set_text(asciiPtr);
+            }
+        }
+    }
+
     // Called by native code, see main.m
     [UnmanagedCallersOnly]
     private static void OnButtonClick()
     {
-        ios_set_text("OnButtonClick! #" + counter++);
+        SetText("OnButtonClick! #" + counter++);
     }
 
 #if CI_TEST
@@ -39,7 +53,7 @@ public static class Program
         for (int i = 0; i < msg.Length; i++)
         {
             // a kind of an animation
-            ios_set_text(msg.Substring(0, i + 1));
+            SetText(msg.Substring(0, i + 1));
             await Task.Delay(100);
         }
 
index 9a77237..f7b0306 100644 (file)
@@ -31,9 +31,9 @@
 
   <Target Name="BuildAppBundle" AfterTargets="$(BuildAppBundleAfterTargets)" DependsOnTargets="$(BuildAppBundleDependsOnTargets)"/>
   <Target Name="_SetAppleGenerateAppBundleProps" Condition="'$(TargetOS)' != 'ios' and '$(ArchiveTests)' != 'true'" BeforeTargets="_AppleGenerateAppBundle">
-    <PropertyGroup>
-      <RuntimeComponents>diagnostics_tracing;marshal-ilgen</RuntimeComponents>
-    </PropertyGroup>
+    <ItemGroup>
+      <RuntimeComponents Include="diagnostics_tracing" />
+    </ItemGroup>
   </Target>
 
   <Target Name="RunAppBundle"