Skip to content

Commit 442fe5f

Browse files
committed
First steps towards native runtime linking at app build time
1 parent 77f5fdd commit 442fe5f

File tree

5 files changed

+144
-5
lines changed

5 files changed

+144
-5
lines changed

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.After.targets

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ This file is imported *after* the Microsoft.NET.Sdk/Sdk.targets.
2323
<Import Project="Microsoft.Android.Sdk.Aot.targets" Condition=" '$(AndroidApplication)' == 'true' " />
2424
<Import Project="Microsoft.Android.Sdk.Application.targets" Condition=" '$(AndroidApplication)' == 'true' " />
2525
<Import Project="Microsoft.Android.Sdk.AssemblyResolution.targets" />
26+
27+
<!-- This one must be imported after `Microsoft.Android.Sdk.AssemblyResolution.targets` -->
28+
<Import Project="Microsoft.Android.Sdk.NativeRuntime.targets" Condition=" '$(AndroidApplication)' == 'true' " />
2629
<Import Project="Microsoft.Android.Sdk.ILLink.targets" />
2730
<Import Project="Microsoft.Android.Sdk.ProjectCapabilities.targets" />
2831
<Import Project="Microsoft.Android.Sdk.Publish.targets" />

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,17 @@ _ResolveAssemblies MSBuild target.
212212
</ItemGroup>
213213
</Target>
214214

215-
<Target Name="_IncludeNativeSystemLibraries">
215+
<Target Name="_PrepareMonoComponentItems">
216+
<ItemGroup>
217+
<_MonoComponent Condition=" '$(AndroidEnableProfiler)' == 'true' " Include="diagnostics_tracing" />
218+
<_MonoComponent Condition=" '$(AndroidUseInterpreter)' == 'true' " Include="hot_reload" />
219+
<_MonoComponent Condition=" '$(AndroidIncludeDebugSymbols)' == 'true' " Include="debugger" />
220+
<_MonoComponent Condition=" '$(_AndroidExcludeMarshalIlgenComponent)' != 'true' " Include="marshal-ilgen" />
221+
</ItemGroup>
222+
</Target>
223+
224+
<Target Name="_IncludeNativeSystemLibraries"
225+
DependsOnTargets="_PrepareMonoComponentItems">
216226
<PropertyGroup>
217227
<_AndroidIncludeSystemGlobalizationNative Condition=" '$(_AndroidIncludeSystemGlobalizationNative)' == '' ">true</_AndroidIncludeSystemGlobalizationNative>
218228
<_AndroidEnableNativeStackTracing Condition=" '$(_AndroidEnableNativeStackTracing)' == ''">false</_AndroidEnableNativeStackTracing>
@@ -221,10 +231,6 @@ _ResolveAssemblies MSBuild target.
221231
<_ResolvedNativeLibraries Include="@(ResolvedFileToPublish)" Condition=" '%(ResolvedFileToPublish.Extension)' == '.so' " />
222232
</ItemGroup>
223233
<ItemGroup>
224-
<_MonoComponent Condition=" '$(AndroidEnableProfiler)' == 'true' " Include="diagnostics_tracing" />
225-
<_MonoComponent Condition=" '$(AndroidUseInterpreter)' == 'true' " Include="hot_reload" />
226-
<_MonoComponent Condition=" '$(AndroidIncludeDebugSymbols)' == 'true' " Include="debugger" />
227-
<_MonoComponent Condition=" '$(_AndroidExcludeMarshalIlgenComponent)' != 'true' " Include="marshal-ilgen" />
228234
<!-- Filename without extension -->
229235
<_ExcludedNativeLibraries Condition=" '$(_AndroidIncludeSystemGlobalizationNative)' != 'true' " Include="libSystem.Globalization.Native" />
230236
<_ExcludedNativeLibraries Condition=" '$(_AndroidEnableNativeStackTracing)' != 'true' " Include="libxamarin-native-tracing" />

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
When changing this default, change the value of `DefaultZipAlignment` in `src/Xamarin.Android.Build.Tasks/Tasks/AndroidZipAlign.cs` as well
5555
-->
5656
<_AndroidZipAlignment Condition=" '$(_AndroidZipAlignment)' == '' ">4</_AndroidZipAlignment>
57+
58+
<!-- Native runtime -->
59+
<_AndroidEnableNativeRuntimeLinking Condition=" '$(_AndroidEnableNativeRuntimeLinking)' == '' and '$(AndroidIncludeDebugSymbols)' != 'true' ">true</_AndroidEnableNativeRuntimeLinking>
5760
</PropertyGroup>
5861

5962
<!-- User-facing configuration-specific defaults -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!--
2+
***********************************************************************************************
3+
Microsoft.Android.Sdk.NativeRuntime.targets
4+
5+
Contains code to build and link the native runtime at application build time.
6+
7+
***********************************************************************************************
8+
-->
9+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
10+
<UsingTask TaskName="Xamarin.Android.Tasks.LinkNativeRuntime" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
11+
12+
<PropertyGroup>
13+
<_EnableNativeRuntimeLinking
14+
</PropertyGroup>
15+
16+
<Target Name="_LinkNativeRuntime"
17+
DependsOnTargets="_PrepareMonoComponentItems"
18+
Condition=" '$(_AndroidEnableNativeRuntimeLinking)' == 'true' ">
19+
<LinkNativeRuntime
20+
MonoComponents="@(_MonoComponent)"
21+
AndroidBinUtilsDirectory="$(AndroidBinUtilsDirectory)"
22+
/>
23+
</Target>
24+
</Project>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.IO;
5+
using System.Text;
6+
using System.Threading;
7+
8+
using Microsoft.Build.Framework;
9+
using Microsoft.Build.Utilities;
10+
11+
using Xamarin.Android.Tools;
12+
using Xamarin.Build;
13+
using Microsoft.Android.Build.Tasks;
14+
15+
namespace Xamarin.Android.Tasks;
16+
17+
public class LinkNativeRuntime : AndroidAsyncTask
18+
{
19+
class Archive
20+
{
21+
public readonly string Name;
22+
public readonly Func<Archive, bool> Include = (Archive) => true;
23+
24+
public Archive (string name, Func<Archive, bool>? include = null)
25+
{
26+
Name = name;
27+
if (include != null) {
28+
Include = include;
29+
}
30+
}
31+
}
32+
33+
class MonoComponentArchive : Archive
34+
{
35+
public readonly string ComponentName;
36+
37+
public MonoComponentArchive (string name, string componentName, Func<Archive, bool> include)
38+
: base (name, include)
39+
{
40+
ComponentName = componentName;
41+
}
42+
}
43+
44+
readonly List<Archive> KnownArchives;
45+
46+
public override string TaskPrefix => "LNR";
47+
48+
public ITaskItem[] MonoComponents { get; set; }
49+
50+
[Required]
51+
public string AndroidBinUtilsDirectory { get; set; }
52+
53+
public LinkNativeRuntime ()
54+
{
55+
KnownArchives = new () {
56+
new MonoComponentArchive ("libmono-component-diagnostics_tracing-static.a", "diagnostics_tracing", MonoComponentPresent),
57+
new MonoComponentArchive ("libmono-component-diagnostics_tracing-stub-static.a", "diagnostics_tracing", MonoComponentAbsent),
58+
new MonoComponentArchive ("libmono-component-marshal-ilgen-static.a", "marshal-ilgen", MonoComponentPresent),
59+
new MonoComponentArchive ("libmono-component-marshal-ilgen-stub-static.a", "marshal-ilgen", MonoComponentAbsent),
60+
61+
new Archive ("libmonosgen-2.0.a"),
62+
new Archive ("libSystem.Globalization.Native.a"),
63+
new Archive ("libSystem.IO.Compression.Native.a"),
64+
new Archive ("libSystem.Native.a"),
65+
new Archive ("libSystem.Security.Cryptography.Native.Android.a"),
66+
};
67+
}
68+
69+
public override System.Threading.Tasks.Task RunTaskAsync ()
70+
{
71+
throw new NotImplementedException ();
72+
}
73+
74+
bool MonoComponentExists (Archive archive)
75+
{
76+
if (MonoComponents == null || MonoComponents.Length == 0) {
77+
return false;
78+
}
79+
80+
var mcArchive = archive as MonoComponentArchive;
81+
if (mcArchive == null) {
82+
throw new ArgumentException (nameof (archive), "Must be an instance of MonoComponentArchive");
83+
}
84+
85+
foreach (ITaskItem item in MonoComponents) {
86+
if (String.Compare (item.ItemSpec, mcArchive.ComponentName, StringComparison.OrdinalIgnoreCase) == 0) {
87+
return true;
88+
}
89+
}
90+
91+
return false;
92+
}
93+
94+
bool MonoComponentAbsent (Archive archive)
95+
{
96+
return !MonoComponentExists (archive);
97+
}
98+
99+
bool MonoComponentPresent (Archive archive)
100+
{
101+
return MonoComponentExists (archive);
102+
}
103+
}

0 commit comments

Comments
 (0)