Skip to content

Commit 51c32fc

Browse files
committed
Unified runtime is properly linked now
There are not unresolved symbols, the library loads. Application won't run, as we still don't have changes to our C++ runtime which make it ready to resolve p/invokes, and other symbols, properly in the new unified shared library.
1 parent 2bff511 commit 51c32fc

File tree

6 files changed

+98
-24
lines changed

6 files changed

+98
-24
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Contains code to build and link the native runtime at application build time.
3030
ResolvedNativeArchives="@(_ResolvedNativeArchive)">
3131
<Output TaskParameter="NativeArchives" ItemName="_SelectedNativeArchive" />
3232
<Output TaskParameter="RequiredLibraries" ItemName="_RequiredLinkLibraries" />
33+
<Output TaskParameter="LinkStartFiles" ItemName="_NativeLinkStartFiles" />
34+
<Output TaskParameter="LinkEndFiles" ItemName="_NativeLinkEndFiles" />
3335
</GetNativeRuntimeComponents>
3436
</Target>
3537

@@ -44,6 +46,8 @@ Contains code to build and link the native runtime at application build time.
4446
IntermediateOutputPath="$(IntermediateOutputPath)"
4547
NativeArchives="@(_SelectedNativeArchive)"
4648
NativeObjectFiles="@(_NativeAssemblyTarget)"
49+
NativeLinkStartFiles="@(_NativeLinkStartFiles)"
50+
NativeLinkEndFiles="@(_NativeLinkEndFiles)"
4751
LinkLibraries="@(_RequiredLinkLibraries)"
4852
OutputRuntimes="@(_UnifiedNativeRuntime)"
4953
SupportedAbis="@(_BuildTargetAbis)"

src/Xamarin.Android.Build.Tasks/Tasks/GetNativeRuntimeComponents.cs

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ public class GetNativeRuntimeComponents : AndroidTask
2626
[Output]
2727
public ITaskItem[] RequiredLibraries { get; set; }
2828

29+
[Output]
30+
public ITaskItem[] LinkStartFiles { get; set; }
31+
32+
[Output]
33+
public ITaskItem[] LinkEndFiles { get; set; }
34+
2935
public override bool RunTask ()
3036
{
3137
var components = new NativeRuntimeComponents (MonoComponents);
@@ -36,20 +42,32 @@ public override bool RunTask ()
3642
if (!archiveItem.Include) {
3743
continue;
3844
}
39-
MakeItems (archiveItem, archives, uniqueAbis);
45+
MakeArchiveItem (archiveItem, archives, uniqueAbis);
4046
}
4147
NativeArchives = archives.ToArray ();
4248

43-
var libraries = new List<ITaskItem> ();
49+
var items = new List<ITaskItem> ();
4450
foreach (string lib in components.NativeLibraries) {
45-
MakeLibraryItems (lib, libraries, uniqueAbis);
51+
MakeLibItem (lib, items, uniqueAbis);
4652
}
47-
RequiredLibraries = libraries.ToArray ();
53+
RequiredLibraries = items.ToArray ();
54+
55+
items = new List<ITaskItem> ();
56+
foreach (string startFile in components.LinkStartFiles) {
57+
MakeFileItem ("_NativeLinkStartFiles", startFile, ResolvedNativeObjectFiles, items, uniqueAbis);
58+
}
59+
LinkStartFiles = items.ToArray ();
60+
61+
items = new List<ITaskItem> ();
62+
foreach (string endFile in components.LinkEndFiles) {
63+
MakeFileItem ("_NativeLinkEndFiles", endFile, ResolvedNativeObjectFiles, items, uniqueAbis);
64+
}
65+
LinkEndFiles = items.ToArray ();
4866

4967
return !Log.HasLoggedErrors;
5068
}
5169

52-
void MakeLibraryItems (string libName, List<ITaskItem> libraries, HashSet<string> uniqueAbis)
70+
void MakeLibItem (string libName, List<ITaskItem> libraries, HashSet<string> uniqueAbis)
5371
{
5472
foreach (string abi in uniqueAbis) {
5573
var item = new TaskItem (libName);
@@ -58,24 +76,37 @@ void MakeLibraryItems (string libName, List<ITaskItem> libraries, HashSet<string
5876
}
5977
}
6078

61-
void MakeItems (NativeRuntimeComponents.Archive archive, List<ITaskItem> archives, HashSet<string> uniqueAbis)
79+
void MakeFileItem (string msbuildItemName, string fileName, ITaskItem[] inputItems, List<ITaskItem> outputItems, HashSet<string> uniqueAbis)
80+
{
81+
foreach (ITaskItem item in inputItems) {
82+
string name = Path.GetFileName (item.ItemSpec);
83+
if (String.Compare (name, fileName, StringComparison.OrdinalIgnoreCase) == 0) {
84+
outputItems.Add (DoMakeItem (msbuildItemName, item, uniqueAbis));
85+
}
86+
}
87+
}
88+
89+
void MakeArchiveItem (NativeRuntimeComponents.Archive archive, List<ITaskItem> archives, HashSet<string> uniqueAbis)
6290
{
6391
foreach (ITaskItem resolvedArchive in ResolvedNativeArchives) {
6492
string fileName = Path.GetFileName (resolvedArchive.ItemSpec);
6593
if (String.Compare (fileName, archive.Name, StringComparison.OrdinalIgnoreCase) == 0) {
66-
archives.Add (DoMakeItem (resolvedArchive));
94+
ITaskItem newItem = DoMakeItem ("_ResolvedNativeArchive", resolvedArchive, uniqueAbis);
95+
newItem.SetMetadata (KnownMetadata.LinkWholeArchive, archive.WholeArchive.ToString ());
96+
archives.Add (newItem);
6797
}
6898
}
99+
}
69100

70-
ITaskItem DoMakeItem (ITaskItem resolved)
71-
{
72-
var ret = new TaskItem (resolved.ItemSpec);
73-
string abi = MonoAndroidHelper.RidToAbi (resolved.GetRequiredMetadata ("_ResolvedNativeArchive", "RuntimeIdentifier", Log));
74-
uniqueAbis.Add (abi);
75-
ret.SetMetadata (KnownMetadata.Abi, abi);
76-
ret.SetMetadata (KnownMetadata.LinkWholeArchive, archive.WholeArchive.ToString ());
77-
78-
return ret;
79-
}
101+
ITaskItem DoMakeItem (string msbuildItemName, ITaskItem sourceItem, HashSet<string> uniqueAbis)
102+
{
103+
var ret = new TaskItem (sourceItem.ItemSpec);
104+
string rid = sourceItem.GetRequiredMetadata (msbuildItemName, KnownMetadata.RuntimeIdentifier, Log);
105+
string abi = MonoAndroidHelper.RidToAbi (rid);
106+
uniqueAbis.Add (abi);
107+
ret.SetMetadata (KnownMetadata.Abi, abi);
108+
ret.SetMetadata (KnownMetadata.RuntimeIdentifier, rid);
109+
110+
return ret;
80111
}
81112
}

src/Xamarin.Android.Build.Tasks/Tasks/LinkNativeRuntime.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ public class LinkNativeRuntime : AsyncTask
3030
[Required]
3131
public ITaskItem[] NativeObjectFiles { get; set; }
3232

33+
[Required]
34+
public ITaskItem[] NativeLinkStartFiles { get; set; }
35+
36+
[Required]
37+
public ITaskItem[] NativeLinkEndFiles { get; set; }
38+
3339
[Required]
3440
public ITaskItem[] OutputRuntimes { get; set; }
3541

@@ -60,7 +66,9 @@ void LinkRuntime (ITaskItem abiItem)
6066
outputRuntime,
6167
GetAbiItems (NativeObjectFiles, "_NativeAssemblyTarget", abi),
6268
GetAbiItems (NativeArchives, "_SelectedNativeArchive", abi),
63-
GetAbiItems (LinkLibraries, "_RequiredLinkLibraries", abi)
69+
GetAbiItems (LinkLibraries, "_RequiredLinkLibraries", abi),
70+
GetAbiItems (NativeLinkStartFiles, "_NativeLinkStartFiles", abi),
71+
GetAbiItems (NativeLinkEndFiles, "_NativeLinkEndFiles", abi)
6472
);
6573
}
6674

src/Xamarin.Android.Build.Tasks/Utilities/KnownMetadata.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ static class KnownMetadata
44
{
55
public const string Abi = "Abi";
66
public const string LinkWholeArchive = "LinkWholeArchive";
7+
public const string RuntimeIdentifier = "RuntimeIdentifier";
78
}

src/Xamarin.Android.Build.Tasks/Utilities/NativeLinker.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,16 @@ public NativeLinker (TaskLoggingHelper log, string abi, string soname, string bi
9999
extraArgs.Add ($"-L {MonoAndroidHelper.QuoteFileNameArgument (runtimeLibsDir)}");
100100
}
101101

102-
public bool Link (ITaskItem outputLibraryPath, List<ITaskItem> objectFiles, List<ITaskItem> archives, List<ITaskItem> libraries)
102+
public bool Link (ITaskItem outputLibraryPath, List<ITaskItem> objectFiles, List<ITaskItem> archives, List<ITaskItem> libraries,
103+
List<ITaskItem> linkStartFiles, List<ITaskItem> linkEndFiles)
103104
{
104105
log.LogDebugMessage ($"Linking: {outputLibraryPath}");
105106
EnsureCorrectAbi (outputLibraryPath);
106107
EnsureCorrectAbi (objectFiles);
107108
EnsureCorrectAbi (archives);
108109
EnsureCorrectAbi (libraries);
110+
EnsureCorrectAbi (linkStartFiles);
111+
EnsureCorrectAbi (linkEndFiles);
109112

110113
Directory.CreateDirectory (Path.GetDirectoryName (outputLibraryPath.ItemSpec));
111114

@@ -124,13 +127,15 @@ public bool Link (ITaskItem outputLibraryPath, List<ITaskItem> objectFiles, List
124127
sw.WriteLine ("-s");
125128
}
126129

130+
WriteFilesToResponseFile (sw, linkStartFiles);
127131
WriteFilesToResponseFile (sw, objectFiles);
128132
WriteFilesToResponseFile (sw, archives);
129133

130134
foreach (ITaskItem libItem in libraries) {
131135
sw.WriteLine ($"-l{libItem.ItemSpec}");
132136
}
133137

138+
WriteFilesToResponseFile (sw, linkEndFiles);
134139
sw.Flush ();
135140
}
136141

@@ -162,10 +167,10 @@ void WriteFilesToResponseFile (StreamWriter sw, List<ITaskItem> files)
162167
sw.Write ("--whole-archive ");
163168
}
164169
sw.Write (MonoAndroidHelper.QuoteFileNameArgument (file.ItemSpec));
165-
string abi = file.GetMetadata ("Abi") ?? String.Empty;
166-
string destDir = Path.Combine ("/tmp/t", abi);
167-
Directory.CreateDirectory (destDir);
168-
File.Copy (file.ItemSpec, Path.Combine (destDir, Path.GetFileName (file.ItemSpec)));
170+
// string abi = file.GetMetadata ("Abi") ?? String.Empty;
171+
// string destDir = Path.Combine ("/tmp/t", abi);
172+
// Directory.CreateDirectory (destDir);
173+
// File.Copy (file.ItemSpec, Path.Combine (destDir, Path.GetFileName (file.ItemSpec)));
169174
if (wholeArchive) {
170175
sw.Write (" --no-whole-archive");
171176
}

src/Xamarin.Android.Build.Tasks/Utilities/NativeRuntimeComponents.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,21 @@ public MonoComponentArchive (string name, string componentName, Func<Archive, bo
3434
}
3535
}
3636

37+
sealed class ClangBuiltinsArchive : Archive
38+
{
39+
public ClangBuiltinsArchive (string clangAbi)
40+
: base ($"libclang_rt.builtins-{clangAbi}-android.a")
41+
{}
42+
}
43+
3744
class AndroidArchive : Archive
3845
{
3946
public AndroidArchive (string name)
4047
: base (name, wholeArchive: true)
4148
{}
4249
}
4350

44-
class BclArchive : Archive
51+
sealed class BclArchive : Archive
4552
{
4653
public BclArchive (string name, bool wholeArchive = true)
4754
: base (name, wholeArchive: wholeArchive)
@@ -52,6 +59,8 @@ public BclArchive (string name, bool wholeArchive = true)
5259

5360
public readonly List<Archive> KnownArchives;
5461
public readonly List<string> NativeLibraries;
62+
public readonly List<string> LinkStartFiles;
63+
public readonly List<string> LinkEndFiles;
5564

5665
public NativeRuntimeComponents (ITaskItem[] monoComponents)
5766
{
@@ -81,6 +90,12 @@ public NativeRuntimeComponents (ITaskItem[] monoComponents)
8190
new AndroidArchive ("libxa-lz4-release.a"),
8291
new AndroidArchive ("libxa-shared-bits-release.a"),
8392
new AndroidArchive ("libmono-android.release-static-release.a"),
93+
94+
// LLVM clang built-ins archives
95+
new ClangBuiltinsArchive ("aarch64"),
96+
new ClangBuiltinsArchive ("arm"),
97+
new ClangBuiltinsArchive ("i686"),
98+
new ClangBuiltinsArchive ("x86_64"),
8499
};
85100

86101
// Just the base names of libraries to link into the unified runtime. Must have all the dependencies of all the static archives we
@@ -95,6 +110,16 @@ public NativeRuntimeComponents (ITaskItem[] monoComponents)
95110
// Atomic is a static library in clang, need to investigate if it's really needed
96111
// "atomic",
97112
};
113+
114+
// Files that will be linked before any other object/archive/library files
115+
LinkStartFiles = new () {
116+
"crtbegin_so.o",
117+
};
118+
119+
// Files that will be linked after any other object/archive/library files
120+
LinkEndFiles = new () {
121+
"crtend_so.o",
122+
};
98123
}
99124

100125
bool MonoComponentExists (Archive archive)

0 commit comments

Comments
 (0)