Skip to content

Commit 2bff511

Browse files
committed
Moar linking ahead
1 parent 31419d8 commit 2bff511

File tree

7 files changed

+115
-3
lines changed

7 files changed

+115
-3
lines changed

build-tools/create-packs/Microsoft.Android.Runtime.proj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ projects that use the Microsoft.Android framework in .NET 6+.
4949
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libxa-shared-bits-release.a" />
5050
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libmono-android.release-static-release.a" />
5151
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libpinvoke-override-dynamic-release.a" />
52+
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\crtbegin_so.o" />
53+
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\crtend_so.o" />
54+
<_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libclang_rt.builtins-*-android.a" />
5255
<FrameworkListFileClass Include="@(_AndroidRuntimePackAssemblies->'%(Filename)%(Extension)')" Profile="Android" />
5356
<FrameworkListFileClass Include="@(_AndroidRuntimePackAssets->'%(Filename)%(Extension)')" Profile="Android" />
5457
</ItemGroup>

build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,37 @@ public static partial class Defaults
146146
{ "x86_64", "x86_64-linux-android" },
147147
};
148148

149+
public static readonly Dictionary<string, string> AbiToRID = new (StringComparer.Ordinal) {
150+
{ "armeabi-v7a", "android-arm" },
151+
{ "arm64-v8a", "android-arm64" },
152+
{ "x86", "android-x86" },
153+
{ "x86_64", "android-x64" },
154+
};
155+
156+
public static readonly Dictionary<string, string> AbiToClangArch = new (StringComparer.Ordinal) {
157+
{ "armeabi-v7a", "arm" },
158+
{ "arm64-v8a", "aarch64" },
159+
{ "x86", "i686" },
160+
{ "x86_64", "x86_64" },
161+
};
162+
163+
/// <summary>
164+
/// Used in rules.mk generator. Files to include in the XA bundle archives.
165+
/// </summary>
166+
public static readonly List <string> BundleZipsInclude = new List <string> {
167+
"$(ZIP_OUTPUT_BASENAME)/THIRD-PARTY-NOTICES.TXT",
168+
"$(ZIP_OUTPUT_BASENAME)/bin/Debug",
169+
"$(ZIP_OUTPUT_BASENAME)/bin/Release",
170+
};
171+
172+
/// <summary>
173+
/// Used in rules.mk generator. Files to exclude from the XA bundle archives. Must be syntactically
174+
/// correct for GNU Make.
175+
/// </summary>
176+
public static readonly List <string> BundleZipsExclude = new List <string> {
177+
"$(ZIP_OUTPUT_BASENAME)/bin/*/bundle-*.zip"
178+
};
179+
149180
public static readonly List <NDKTool> NDKTools = new List<NDKTool> {
150181
// Tools prefixed with architecture triple
151182
new NDKTool (name: "as", prefixed: true),
@@ -220,6 +251,7 @@ public static partial class Paths
220251
// Other
221252
public static string AndroidNdkDirectory => ctx.Properties.GetRequiredValue (KnownProperties.AndroidNdkDirectory);
222253
public static string AndroidToolchainRootDirectory => GetCachedPath (ref androidToolchainRootDirectory, () => Path.Combine (AndroidNdkDirectory, "toolchains", "llvm", "prebuilt", NdkToolchainOSTag));
254+
public static string AndroidClangRootDirectory => GetCachedPath (ref androidClangRootDirectory, () => Path.Combine (AndroidToolchainRootDirectory, "lib", "clang"));
223255
public static string AndroidToolchainBinDirectory => GetCachedPath (ref androidToolchainBinDirectory, () => Path.Combine (AndroidToolchainRootDirectory, "bin"));
224256
public static string AndroidToolchainSysrootLibDirectory => GetCachedPath (ref androidToolchainSysrootLibDirectory, () => Path.Combine (AndroidToolchainRootDirectory, "sysroot", "usr", "lib"));
225257
public static string WindowsBinutilsInstallDir => GetCachedPath (ref windowsBinutilsInstallDir, () => Path.Combine (InstallMSBuildDir, "binutils"));
@@ -264,6 +296,7 @@ static string GetCachedPath (ref string? variable, Func<string> creator)
264296
static string? buildBinDir;
265297
static string? binDir;
266298
static string? androidToolchainRootDirectory;
299+
static string? androidClangRootDirectory;
267300
static string? androidToolchainBinDirectory;
268301
static string? androidToolchainSysrootLibDirectory;
269302
static string? installMSBuildDir;

build-tools/xaprepare/xaprepare/Steps/Step_Android_SDK_NDK.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4+
using System.Globalization;
45
using System.IO;
56
using System.Linq;
67
using System.Threading.Tasks;
@@ -151,13 +152,73 @@ bool AcceptLicenses (Context context, string sdkRoot)
151152

152153
bool GatherNDKInfo (Context context)
153154
{
155+
if (!CopyRedistributableFiles (context)) {
156+
return false;
157+
}
158+
154159
// Ignore NDK property setting if not installing the NDK
155160
if (!DependencyTypeToInstall.HasFlag (AndroidToolchainComponentType.BuildDependency))
156161
return true;
157162
else
158163
return context.BuildInfo.GatherNDKInfo (context);
159164
}
160165

166+
bool CopyRedistributableFiles (Context context)
167+
{
168+
string androidVersionPath = Path.Combine (Configurables.Paths.AndroidToolchainRootDirectory, "AndroidVersion.txt");
169+
if (!File.Exists (androidVersionPath)) {
170+
throw new InvalidOperationException ($"Android version file '{androidVersionPath}' not found");
171+
}
172+
173+
string[]? lines = File.ReadAllLines (androidVersionPath);
174+
if (lines == null || lines.Length < 1) {
175+
throw new InvalidOperationException ($"Unknown format of Android version file '{androidVersionPath}'");
176+
}
177+
178+
// First line is (should be) the LLVM version, we need just the main release number
179+
string[] llvmVersion = lines[0].Split ('.');
180+
if (llvmVersion.Length < 3) {
181+
throw new InvalidOperationException ($"Unknown LLVM version format for '{lines[0]}'");
182+
}
183+
184+
string clangLibPath = Path.Combine (
185+
Configurables.Paths.AndroidClangRootDirectory,
186+
llvmVersion[0],
187+
"lib",
188+
"linux"
189+
);
190+
191+
foreach (var kvp in Configurables.Defaults.AndroidToolchainPrefixes) {
192+
string abi = kvp.Key;
193+
194+
string crtFilesPath = Path.Combine (
195+
Configurables.Paths.AndroidToolchainSysrootLibDirectory,
196+
kvp.Value,
197+
BuildAndroidPlatforms.NdkMinimumAPI.ToString (CultureInfo.InvariantCulture)
198+
);
199+
200+
CopyFile (abi, crtFilesPath, "crtbegin_so.o");
201+
CopyFile (abi, crtFilesPath, "crtend_so.o");
202+
CopyFile (abi, clangLibPath, $"libclang_rt.builtins-{Configurables.Defaults.AbiToClangArch[abi]}-android.a");
203+
}
204+
205+
return true;
206+
207+
void CopyFile (string abi, string sourceDir, string fileName)
208+
{
209+
Log.StatusLine ($" {context.Characters.Bullet} Copying NDK redistributable: ", $"{fileName} ({abi})", tailColor: ConsoleColor.White);
210+
string rid = Configurables.Defaults.AbiToRID [abi];
211+
string outputDir = Path.Combine (
212+
context.Properties.GetRequiredValue (KnownProperties.MicrosoftAndroidSdkOutDir),
213+
"lib",
214+
rid
215+
);
216+
217+
string sourceFile = Path.Combine (sourceDir, fileName);
218+
Utilities.CopyFileToDir (sourceFile, outputDir);
219+
}
220+
}
221+
161222
void CheckPackageStatus (Context context, string packageCacheDir, AndroidPackage pkg, List <AndroidPackage> toDownload)
162223
{
163224
Log.StatusLine ($" {context.Characters.Bullet} Installing ", pkg.Component.Name, tailColor: ConsoleColor.White);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ Contains code to build and link the native runtime at application build time.
2020

2121
<ItemGroup>
2222
<_ResolvedNativeArchive Include="@(ResolvedFileToPublish)" Condition=" '%(ResolvedFileToPublish.Extension)' == '.a' " />
23+
<_ResolvedNativeObjectFile Include="@(ResolvedFileToPublish)" Condition=" '%(ResolvedFileToPublish.Extension)' == '.o' " />
2324
<_ApplicationSharedLibrary Include="@(_UnifiedNativeRuntime)" />
2425
</ItemGroup>
2526

2627
<GetNativeRuntimeComponents
2728
MonoComponents="@(_MonoComponent)"
29+
ResolvedNativeObjectFiles="@(_ResolvedNativeObjectFile)"
2830
ResolvedNativeArchives="@(_ResolvedNativeArchive)">
2931
<Output TaskParameter="NativeArchives" ItemName="_SelectedNativeArchive" />
3032
<Output TaskParameter="RequiredLibraries" ItemName="_RequiredLinkLibraries" />

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public class GetNativeRuntimeComponents : AndroidTask
1717
[Required]
1818
public ITaskItem[] ResolvedNativeArchives { get; set; }
1919

20+
[Required]
21+
public ITaskItem[] ResolvedNativeObjectFiles { get; set; }
22+
2023
[Output]
2124
public ITaskItem[] NativeArchives { get; set; }
2225

@@ -28,6 +31,7 @@ public override bool RunTask ()
2831
var components = new NativeRuntimeComponents (MonoComponents);
2932
var uniqueAbis = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
3033
var archives = new List<ITaskItem> ();
34+
3135
foreach (NativeRuntimeComponents.Archive archiveItem in components.KnownArchives) {
3236
if (!archiveItem.Include) {
3337
continue;

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,18 @@ class NativeLinker
1919
// TODO: need to enable zstd in binutils build
2020
// "--compress-debug-sections=zstd",
2121
// TODO: test the commented-out flags
22-
// "--gc-sections",
22+
"--gc-sections",
2323
// "--icf=safe",
2424
// "--lto=full|thin",
2525
"--export-dynamic",
2626
"-z relro",
2727
"-z noexecstack",
28+
"-z max-page-size=16384",
2829
"--enable-new-dtags",
29-
"--build-id",
30+
"--build-id=sha1",
3031
"--warn-shared-textrel",
31-
"--fatal-warnings"
32+
"--fatal-warnings",
33+
"--no-rosegment"
3234
};
3335

3436
readonly List<string> extraArgs = new ();
@@ -160,6 +162,10 @@ void WriteFilesToResponseFile (StreamWriter sw, List<ITaskItem> files)
160162
sw.Write ("--whole-archive ");
161163
}
162164
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)));
163169
if (wholeArchive) {
164170
sw.Write (" --no-whole-archive");
165171
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ public NativeRuntimeComponents (ITaskItem[] monoComponents)
9191
"m",
9292
"z",
9393
"log",
94+
95+
// Atomic is a static library in clang, need to investigate if it's really needed
96+
// "atomic",
9497
};
9598
}
9699

0 commit comments

Comments
 (0)