Skip to content

Commit 5f66199

Browse files
committed
[WIP] runtime pack library dirs discovery
1 parent cea7432 commit 5f66199

File tree

2 files changed

+114
-5
lines changed

2 files changed

+114
-5
lines changed

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ _ResolveAssemblies MSBuild target.
1212

1313
<UsingTask TaskName="Xamarin.Android.Tasks.ProcessAssemblies" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
1414
<UsingTask TaskName="Xamarin.Android.Tasks.ProcessNativeLibraries" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
15+
<UsingTask TaskName="Xamarin.Android.Tasks.ProcessRuntimePackLibraryDirectories" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
1516
<UsingTask TaskName="Xamarin.Android.Tasks.StripNativeLibraries" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
1617

1718
<!-- HACK: workaround for: https://github.com/dotnet/sdk/issues/25679 -->
@@ -114,8 +115,19 @@ _ResolveAssemblies MSBuild target.
114115
<Output TaskParameter="TargetOutputs" ItemName="ResolvedFileToPublish" />
115116
</MSBuild>
116117

118+
<!-- This must be done as early as possible, so the runtime libraries location is known to all
119+
the tasks that need it and so that the shared library files that are never to be packaged
120+
are never taken into consideration in any context.
121+
-->
122+
<ProcessRuntimePackLibraryDirectories
123+
Condition=" '$(_AndroidRuntime)' != 'NativeAOT' "
124+
ResolvedFilesToPublish="@(ResolvedFileToPublish)">
125+
<Output TaskParameter="RuntimePackLibraryDirectories" ItemName="_RuntimePackLibraryDirectory" />
126+
<Output TaskParameter="NativeLibrariesToRemove" ItemName="_NativeLibraryToRemove" />
127+
</ProcessRuntimePackLibraryDirectories>
128+
117129
<ItemGroup>
118-
<ResolvedFileToPublish Include="@(_AddSharedLibrariesClrHack)" />
130+
<ResolvedFileToPublish Remove="@(_NativeLibraryToRemove)" />
119131
</ItemGroup>
120132

121133
<!-- Properties produced by the inner build in Microsoft.Android.Sdk.ILLink.targets -->
@@ -131,10 +143,6 @@ _ResolveAssemblies MSBuild target.
131143
<_ResolvedJavaLibraries Include="@(ResolvedFileToPublish)" Condition=" '%(ResolvedFileToPublish.Extension)' == '.jar' " />
132144
</ItemGroup>
133145

134-
<ItemGroup>
135-
<ResolvedFileToPublish Remove="@(_ResolvedArchiveDSOStub)" />
136-
</ItemGroup>
137-
138146
<!-- All assemblies must be per-RID, thus no `->Distinct()` on `InputAssemblies` or `ResolvedSymbols` items -->
139147
<ProcessAssemblies
140148
RuntimeIdentifiers="@(_RIDs)"
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#nullable enable
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
7+
using Microsoft.Build.Utilities;
8+
using Microsoft.Build.Framework;
9+
using Microsoft.Android.Build.Tasks;
10+
11+
namespace Xamarin.Android.Tasks;
12+
13+
public class ProcessRuntimePackLibraryDirectories : AndroidTask
14+
{
15+
public override string TaskPrefix => "FRPLD";
16+
17+
static readonly HashSet<string> NativeLibraryNames = new (StringComparer.OrdinalIgnoreCase) {
18+
"libarchive-dso-stub.so",
19+
"libc.so",
20+
"libdl.so",
21+
"liblog.so",
22+
"libm.so",
23+
"libz.so",
24+
};
25+
26+
[Required]
27+
public ITaskItem[] ResolvedFilesToPublish { get; set; } = Array.Empty<ITaskItem> ();
28+
29+
[Output]
30+
public ITaskItem[] RuntimePackLibraryDirectories { get; set; } = Array.Empty<ITaskItem> ();
31+
32+
[Output]
33+
public ITaskItem[] NativeLibrariesToRemove { get; set; } = Array.Empty<ITaskItem> ();
34+
35+
public override bool RunTask ()
36+
{
37+
var libDirs = new List<ITaskItem> ();
38+
var librariesToRemove = new List<ITaskItem> ();
39+
var seenRIDs = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
40+
41+
foreach (ITaskItem item in ResolvedFilesToPublish) {
42+
if (!IsInSupportedRuntimePack (item)) {
43+
continue;
44+
}
45+
46+
string? fileName = Path.GetFileName (item.ItemSpec);
47+
if (String.IsNullOrEmpty (fileName) || !NativeLibraryNames.Contains (fileName)) {
48+
continue;
49+
}
50+
51+
string? rid = item.GetMetadata ("RuntimeIdentifier");
52+
if (String.IsNullOrEmpty (rid)) {
53+
Log.LogDebugMessage ($"Ignoring item '{item}' because it contains no runtime identifier metadata");
54+
continue;
55+
}
56+
57+
if (!seenRIDs.Contains (rid)) {
58+
string? dirName = Path.GetDirectoryName (item.ItemSpec);
59+
if (String.IsNullOrEmpty (dirName)) {
60+
Log.LogDebugMessage ($"Item '{item}' path doesn't contain full file path");
61+
} else {
62+
libDirs.Add (MakeLibDirItem (item, dirName));
63+
}
64+
seenRIDs.Add (rid);
65+
Log.LogDebugMessage ($"Discovered runtime pack library directory for '{rid}': {dirName}");
66+
}
67+
68+
librariesToRemove.Add (item);
69+
Log.LogDebugMessage ($"Item '{item}' will be removed from the set of native libraries to publish");
70+
}
71+
72+
RuntimePackLibraryDirectories = libDirs.ToArray ();
73+
NativeLibrariesToRemove = librariesToRemove.ToArray ();
74+
75+
return !Log.HasLoggedErrors;
76+
}
77+
78+
ITaskItem MakeLibDirItem (ITaskItem sourceItem, string dir)
79+
{
80+
var ret = new TaskItem (dir);
81+
sourceItem.CopyMetadataTo (ret);
82+
83+
// These make no sense for directories, remove just to be safe
84+
ret.RemoveMetadata ("CopyLocal");
85+
ret.RemoveMetadata ("CopyToPublishDirectory");
86+
ret.RemoveMetadata ("DestinationSubPath");
87+
ret.RemoveMetadata ("RelativePath");
88+
return ret;
89+
}
90+
91+
bool IsInSupportedRuntimePack (ITaskItem item)
92+
{
93+
string? NuGetPackageId = item.GetMetadata ("NuGetPackageId");
94+
if (String.IsNullOrEmpty (NuGetPackageId)) {
95+
return false;
96+
}
97+
98+
return NuGetPackageId.StartsWith ("Microsoft.Android.Runtime.CoreCLR.", StringComparison.OrdinalIgnoreCase) ||
99+
NuGetPackageId.StartsWith ("Microsoft.Android.Runtime.Mono.", StringComparison.OrdinalIgnoreCase);
100+
}
101+
}

0 commit comments

Comments
 (0)