Skip to content

Commit 63b78d5

Browse files
committed
Some progress, still ways to go.
1 parent 3d367c1 commit 63b78d5

File tree

6 files changed

+152
-22
lines changed

6 files changed

+152
-22
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ projects that use the Microsoft.Android framework in .NET 6+.
7474

7575
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\crtbegin_so.o') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\crtbegin_so.o" />
7676
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\crtend_so.o') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\crtend_so.o" />
77+
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libc++_static.a') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libc++_static.a" />
78+
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libc++abi.a') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libc++abi.a" />
7779
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libclang_rt.builtins-aarch64-android.a') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libclang_rt.builtins-aarch64-android.a" />
7880
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libclang_rt.builtins-x86_64-android.a') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libclang_rt.builtins-x86_64-android.a" />
7981
</ItemGroup>

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,14 +190,10 @@ bool CopyRedistributableFiles (Context context)
190190

191191
foreach (var kvp in Configurables.Defaults.AndroidToolchainPrefixes) {
192192
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-
193+
string abiDir = Path.Combine (Configurables.Paths.AndroidToolchainSysrootLibDirectory, kvp.Value);
194+
string crtFilesPath = Path.Combine (abiDir, BuildAndroidPlatforms.NdkMinimumAPI.ToString (CultureInfo.InvariantCulture));
200195
string clangArch = Configurables.Defaults.AbiToClangArch[abi];
196+
201197
CopyFile (abi, crtFilesPath, "crtbegin_so.o");
202198
CopyFile (abi, crtFilesPath, "crtend_so.o");
203199
CopyFile (abi, clangLibPath, $"libclang_rt.builtins-{clangArch}-android.a");
@@ -207,6 +203,9 @@ bool CopyRedistributableFiles (Context context)
207203
clangArch = "i386";
208204
}
209205

206+
CopyFile (abi, abiDir, "libc++_static.a");
207+
CopyFile (abi, abiDir, "libc++abi.a");
208+
210209
// Remove once https://github.com/dotnet/runtime/pull/107615 is merged and released
211210
CopyFile (abi, Path.Combine (clangLibPath, clangArch), "libunwind.a");
212211
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ Contains code to build and link the native runtime at application build time.
2828
<GetNativeRuntimeComponents
2929
MonoComponents="@(_MonoComponent)"
3030
ResolvedNativeObjectFiles="@(_ResolvedNativeObjectFile)"
31-
ResolvedNativeArchives="@(_ResolvedNativeArchive)">
31+
ResolvedNativeArchives="@(_ResolvedNativeArchive)"
32+
HackLocalClrRepoPath="$(_HackLocalClrRuntimePath)">
3233
<Output TaskParameter="NativeArchives" ItemName="_SelectedNativeArchive" />
3334
<Output TaskParameter="RequiredLibraries" ItemName="_RequiredLinkLibraries" />
3435
<Output TaskParameter="LinkStartFiles" ItemName="_NativeLinkStartFiles" />

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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ public class GetNativeRuntimeComponents : AndroidTask
2020
[Required]
2121
public ITaskItem[] ResolvedNativeObjectFiles { get; set; }
2222

23+
[Required]
24+
public string HackLocalClrRepoPath { get; set; }
25+
2326
[Output]
2427
public ITaskItem[] NativeArchives { get; set; }
2528

@@ -60,6 +63,28 @@ public override bool RunTask ()
6063
MakeLibItem (symbolName, symbolsToExport, uniqueAbis);
6164
}
6265
}
66+
67+
// HACK! START: until CoreCLR runtime pack has the necessary .a archives
68+
var discoveredItemNames = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
69+
foreach (ITaskItem item in archives) {
70+
discoveredItemNames.Add (Path.GetFileName (item.ItemSpec));
71+
}
72+
73+
Log.LogWarning ("[HACK] Looking for native archives which require CoreCLR hack");
74+
foreach (NativeRuntimeComponents.Archive archiveItem in components.KnownArchives) {
75+
if (!archiveItem.Include || !archiveItem.NeedsClrHack) {
76+
continue;
77+
}
78+
79+
Log.LogDebugMessage ($" [HACK] archive {archiveItem.Name}");
80+
if (discoveredItemNames.Contains (archiveItem.Name)) {
81+
Log.LogDebugMessage (" [HACK] already found elsewhere");
82+
continue;
83+
}
84+
HackMakeArchiveItem (archiveItem, archives, uniqueAbis);
85+
}
86+
// HACK! END
87+
6388
NativeArchives = archives.ToArray ();
6489
NativeSymbolsToExport = symbolsToExport.ToArray ();
6590

@@ -132,4 +157,70 @@ ITaskItem DoMakeItem (string msbuildItemName, ITaskItem sourceItem, HashSet<stri
132157

133158
return ret;
134159
}
160+
161+
void HackMakeArchiveItem (NativeRuntimeComponents.Archive archive, List<ITaskItem> archives, HashSet<string> uniqueAbis)
162+
{
163+
var relativeArtifactPaths = new List<(string path, string abi)> ();
164+
string archiveName = Path.GetFileName (archive.Name);
165+
string commonClrObjDir = Path.Combine ("artifacts", "obj", "coreclr");
166+
167+
if (IsArchive ("libcoreclr.a")) {
168+
archiveName = "libcoreclr_static.a";
169+
MakeRelativeArtifactPaths ((string clrArch) => Path.Combine (commonClrObjDir, $"android.{clrArch}.Release", "dlls", "mscoree", "coreclr"));
170+
} else if (IsArchive ("libcoreclrpal.a")) {
171+
MakeRelativeArtifactPaths ((string clrArch) => Path.Combine (commonClrObjDir, $"android.{clrArch}.Release", "pal", "src"));
172+
} else if (IsArchive ("libminipal.a")) {
173+
MakeRelativeArtifactPaths ((string clrArch) => Path.Combine (commonClrObjDir, $"android.{clrArch}.Release", "shared_minipal"));
174+
} else if (IsArchive ("libcoreclrminipal.a")) {
175+
MakeRelativeArtifactPaths ((string clrArch) => Path.Combine (commonClrObjDir, $"android.{clrArch}.Release", "minipal", "Unix"));
176+
} else if (IsArchive ("libgc_pal.a")) {
177+
MakeRelativeArtifactPaths ((string clrArch) => Path.Combine (commonClrObjDir, $"android.{clrArch}.Release", "gc", "unix"));
178+
} else if (IsArchive ("libeventprovider.a")) {
179+
MakeRelativeArtifactPaths ((string clrArch) => Path.Combine (commonClrObjDir, $"android.{clrArch}.Release", "pal", "src", "eventprovider", "dummyprovider"));
180+
} else if (IsArchive ("libnativeresourcestring.a")) {
181+
MakeRelativeArtifactPaths ((string clrArch) => Path.Combine (commonClrObjDir, $"android.{clrArch}.Release", "pal", "nativeresources"));
182+
} else {
183+
foreach (string abi in uniqueAbis) {
184+
string clrArch = GetClrArch (abi);
185+
relativeArtifactPaths.Add ((Path.Combine ("artifacts", "bin", $"microsoft.netcore.app.runtime.android-{clrArch}", "Release", "runtimes", $"android-{clrArch}", "native"), abi));
186+
}
187+
}
188+
189+
foreach ((string relPath, string abi) in relativeArtifactPaths) {
190+
string filePath = Path.Combine (HackLocalClrRepoPath, relPath, archiveName);
191+
if (!File.Exists (filePath)) {
192+
Log.LogWarning ($" [HACK] file {filePath} not found");
193+
continue;
194+
}
195+
Log.LogWarning ($" [HACK] adding runtime component '{filePath}'");
196+
var tempItem = new TaskItem (filePath);
197+
tempItem.SetMetadata (KnownMetadata.Abi, abi);
198+
tempItem.SetMetadata (KnownMetadata.RuntimeIdentifier, MonoAndroidHelper.AbiToRid (abi));
199+
ITaskItem newItem = DoMakeItem ("_ResolvedNativeArchive", tempItem, uniqueAbis);
200+
newItem.SetMetadata (KnownMetadata.NativeLinkWholeArchive, archive.WholeArchive.ToString ());
201+
if (archive.DontExportSymbols) {
202+
newItem.SetMetadata (KnownMetadata.NativeDontExportSymbols, "true");
203+
}
204+
archives.Add (newItem);
205+
}
206+
207+
string GetClrArch (string abi)
208+
{
209+
return abi switch {
210+
"arm64-v8a" => "arm64",
211+
"x86_64" => "x64",
212+
_ => throw new NotSupportedException ($"ABI {abi} is not supported for CoreCLR")
213+
};
214+
}
215+
216+
void MakeRelativeArtifactPaths (Func<string, string> create)
217+
{
218+
foreach (string abi in uniqueAbis) {
219+
string clrArch = GetClrArch (abi);
220+
relativeArtifactPaths.Add ((create (clrArch), abi));
221+
}
222+
}
223+
224+
bool IsArchive (string name) => String.Compare (name, archiveName, StringComparison.OrdinalIgnoreCase) == 0;
225+
}
135226
}

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

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,17 @@ internal class Archive
1515
public readonly bool WholeArchive;
1616
public bool DontExportSymbols { get; set; }
1717
public HashSet<string>? SymbolsToPreserve { get; set; }
18+
public readonly bool NeedsClrHack;
1819

1920
Func<Archive, bool> shouldInclude;
2021

21-
public Archive (string name, Func<Archive, bool>? include = null, bool wholeArchive = false, string? jniOnLoadName = null)
22+
public Archive (string name, Func<Archive, bool>? include = null, bool wholeArchive = false, string? jniOnLoadName = null, bool needsClrHack = false)
2223
{
2324
Name = name;
2425
shouldInclude = include == null ? ((Archive arch) => true) : include;
2526
WholeArchive = wholeArchive;
2627
JniOnLoadName = jniOnLoadName;
28+
NeedsClrHack = needsClrHack;
2729
}
2830
}
2931

@@ -44,7 +46,7 @@ public AndroidArchive (string name, bool wholeArchive = false)
4446
sealed class BclArchive : Archive
4547
{
4648
public BclArchive (string name, bool wholeArchive = false, string? jniOnLoadName = null)
47-
: base (name, wholeArchive: wholeArchive, jniOnLoadName: jniOnLoadName)
49+
: base (name, wholeArchive: wholeArchive, jniOnLoadName: jniOnLoadName, needsClrHack: true)
4850
{
4951
DontExportSymbols = true;
5052
}
@@ -57,16 +59,40 @@ public BclArchive (string name, bool wholeArchive = false, string? jniOnLoadName
5759
public readonly List<string> LinkStartFiles;
5860
public readonly List<string> LinkEndFiles;
5961

62+
// LINK_LIBRARIES = pal/src/eventprovider/dummyprovider/libeventprovider.a -llog nativeresources/libnativeresourcestring.a shared_minipal/libminipal.a -ldl -latomic -lm
6063
public NativeRuntimeComponents (ITaskItem[] monoComponents)
6164
{
6265
this.monoComponents = monoComponents;
6366
KnownArchives = new () {
6467
// CoreCLR runtime + BCL
65-
new Archive ("libmonosgen-2.0.a") {
68+
new Archive ("libcoreclr.a", needsClrHack: true) {
6669
DontExportSymbols = true,
6770
},
71+
new Archive ("libcoreclrminipal.a", needsClrHack: true) {
72+
DontExportSymbols = true,
73+
},
74+
new Archive ("libgc_pal.a", needsClrHack: true) {
75+
DontExportSymbols = true,
76+
},
77+
new Archive ("libcoreclrpal.a", wholeArchive: true, needsClrHack: true) {
78+
DontExportSymbols = true,
79+
},
80+
new Archive ("libeventprovider.a", needsClrHack: true) {
81+
DontExportSymbols = true,
82+
},
83+
new Archive ("libnativeresourcestring.a", needsClrHack: true) {
84+
DontExportSymbols = true,
85+
},
86+
new Archive ("libminipal.a", needsClrHack: true) {
87+
DontExportSymbols = true,
88+
},
89+
new Archive ("libbrotlicommon.a", needsClrHack: true),
90+
new Archive ("libbrotlidec.a", needsClrHack: true),
91+
new Archive ("libbrotlienc.a", needsClrHack: true),
92+
6893
new BclArchive ("libSystem.Globalization.Native.a"),
6994
new BclArchive ("libSystem.IO.Compression.Native.a"),
95+
new BclArchive ("libSystem.IO.Ports.Native.a"),
7096
new BclArchive ("libSystem.Native.a"),
7197
new BclArchive ("libSystem.Security.Cryptography.Native.Android.a", jniOnLoadName: "AndroidCryptoNative_InitLibraryOnLoad") {
7298
SymbolsToPreserve = new (StringComparer.Ordinal) {
@@ -101,6 +127,14 @@ public NativeRuntimeComponents (ITaskItem[] monoComponents)
101127
new ClangBuiltinsArchive ("i686"),
102128
new ClangBuiltinsArchive ("x86_64"),
103129

130+
// C++ standard library
131+
new Archive ("libc++_static.a") {
132+
DontExportSymbols = true,
133+
},
134+
new Archive ("libc++abi.a") {
135+
DontExportSymbols = true,
136+
},
137+
104138
// Remove once https://github.com/dotnet/runtime/pull/107615 is merged and released
105139
new Archive ("libunwind.a") {
106140
DontExportSymbols = true,

src/native/clr/include/runtime-base/internal-pinvokes.hh

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
#include <xamarin-app.hh>
66
#include "logger.hh"
77

8-
int _monodroid_gref_get () noexcept;
9-
void _monodroid_gref_log (const char *message) noexcept;
10-
int _monodroid_gref_log_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) noexcept;
11-
void _monodroid_gref_log_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) noexcept;
12-
const char* clr_typemap_managed_to_java (const char *typeName, const uint8_t *mvid) noexcept;
13-
bool clr_typemap_java_to_managed (const char *java_type_name, char const** assembly_name, uint32_t *managed_type_token_id) noexcept;
14-
void monodroid_log (xamarin::android::LogLevel level, LogCategories category, const char *message) noexcept;
15-
char* monodroid_TypeManager_get_java_class_name (jclass klass) noexcept;
16-
void monodroid_free (void *ptr) noexcept;
17-
const char* _monodroid_lookup_replacement_type (const char *jniSimpleReference);
18-
const JniRemappingReplacementMethod* _monodroid_lookup_replacement_method_info (const char *jniSourceType, const char *jniMethodName, const char *jniMethodSignature);
8+
extern "C" {
9+
int _monodroid_gref_get () noexcept;
10+
void _monodroid_gref_log (const char *message) noexcept;
11+
int _monodroid_gref_log_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) noexcept;
12+
void _monodroid_gref_log_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) noexcept;
13+
const char* clr_typemap_managed_to_java (const char *typeName, const uint8_t *mvid) noexcept;
14+
bool clr_typemap_java_to_managed (const char *java_type_name, char const** assembly_name, uint32_t *managed_type_token_id) noexcept;
15+
void monodroid_log (xamarin::android::LogLevel level, LogCategories category, const char *message) noexcept;
16+
char* monodroid_TypeManager_get_java_class_name (jclass klass) noexcept;
17+
void monodroid_free (void *ptr) noexcept;
18+
const char* _monodroid_lookup_replacement_type (const char *jniSimpleReference);
19+
const JniRemappingReplacementMethod* _monodroid_lookup_replacement_method_info (const char *jniSourceType, const char *jniMethodName, const char *jniMethodSignature);
20+
}
21+

0 commit comments

Comments
 (0)