Skip to content

Commit aeae253

Browse files
committed
Stop using dlopen/dlsym to load Mono symbols
Since the dawn of time `Xamarin.Android` (nee `MonoAndroid`) used `dlopen/dlsym` to load Mono runtime symbols that were required for the managed applications to work on Android. This was done due to the fact that there had been no way to reliably load shared libraries referenced by the XA runtime in earlier versions of Android. However, thanks to the recent switch to API level 16 as our lowest supported level, we are now able to simply preload the shared libraries we depend on and, thus, allow the system linker to resolve all the symbols when loading `libmonodroid.so`. This, in turn, means we can now directly link `libmonosgen-2.0` on all target platforms (including all of the supported host operating systems) and, what's also very important, include Mono headers directly in our source. This makes sure we don't divert in definitions of various macros and functions that we use accross our runtime and that we continue to work with any version of Mono shipped in the Mono SDK archives. This commit removes all traces of the `DylibMono` class and it also renames all the C++ header files to have the `.hh` extension, to mirror the `.cc` source file convention and cleary mark the C++ headers as such, as opposed to the handful of C headers (`.h`) we have in our tree.
1 parent 694617e commit aeae253

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1009
-2208
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
[submodule "external/Java.Interop"]
1010
path = external/Java.Interop
1111
url = https://github.com/xamarin/java.interop.git
12-
branch = master
12+
branch = drop-dylibmono
1313
[submodule "external/libzip"]
1414
path = external/libzip
1515
url = https://github.com/nih-at/libzip.git

Configuration.props

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
<MakeConcurrency Condition=" '$(MakeConcurrency)' == '' And '$(HostCpuCount)' != '' ">-j$(HostCpuCount)</MakeConcurrency>
6161
<ManagedRuntime Condition=" '$(ManagedRuntime)' == '' And '$(OS)' != 'Windows_NT' ">mono</ManagedRuntime>
6262
<ManagedRuntimeArgs Condition=" '$(ManagedRuntimeArgs)' == '' And '$(ManagedRuntime)' == 'mono' ">--debug=casts</ManagedRuntimeArgs>
63-
<MonoSgenBridgeVersion Condition=" '$(MonoSgenBridgeVersion)' == '' ">5</MonoSgenBridgeVersion>
6463
<HOME Condition=" '$(HOME)' == '' ">$(USERPROFILE)</HOME>
6564
<AndroidPreviousFrameworkVersion Condition=" '$(AndroidPreviousFrameworkVersion)' == '' ">v1.0</AndroidPreviousFrameworkVersion>
6665
<AndroidToolchainCacheDirectory Condition=" '$(AndroidToolchainCacheDirectory)' == '' ">$(HOME)\android-archives</AndroidToolchainCacheDirectory>

build-tools/scripts/PrepareWindows.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<_XAPrepareStandardArgs Condition=" '$(RunningOnCI)' == 'true' ">--no-emoji --run-mode=CI -a -v:d</_XAPrepareStandardArgs>
88
<_XAPrepareStandardArgs Condition=" '$(XA_FORCE_COMPONENT_REFRESH)' == 'true' ">$(_XAPrepareStandardArgs) -refresh</_XAPrepareStandardArgs>
99
<_XAPrepareBundleArgs Condition=" '$(BundleRootPath)' != '' ">--bundle-path=&quot;$(BundleRootPath)&quot;</_XAPrepareBundleArgs>
10+
<_XAPrepareBundleArgs Condition=" '$(RunMode)' == 'CI' ">$(_XAPrepareBundleArgs) -v:d</_XAPrepareBundleArgs>
1011
</PropertyGroup>
1112
<Import Project="$(_TopDir)\Configuration.props" />
1213
<Target Name="_BuildXAPrepare">

build-tools/xaprepare/xaprepare/Application/RuntimeFileType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ enum RuntimeFileType
55
Other,
66
Binary,
77
StrippableBinary,
8+
SdkHeader,
89
}
910
}

build-tools/xaprepare/xaprepare/Application/Utilities.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ public static void DeleteDirectoryWithRetry (string directoryPath, bool recursiv
574574
return;
575575
} catch (IOException e) {
576576
ex = e;
577-
} catch (UnauthorizedAccessException e) {
577+
} catch (UnauthorizedAccessException e) {
578578
ex = e;
579579
tryResetFilePermissions = true;
580580
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@ partial class Defaults
2121

2222
partial class Paths
2323
{
24+
const string LibMonoSgenBaseName = "libmonosgen-2.0";
25+
2426
public const string MonoCrossRuntimeInstallPath = "Darwin";
2527
public const string NdkToolchainOSTag = "darwin-x86_64";
28+
public static readonly string UnstrippedLibMonoSgenName = $"{LibMonoSgenBaseName}.d{Defaults.NativeLibraryExtension}";
29+
public static readonly string StrippedLibMonoSgenName = $"{LibMonoSgenBaseName}{Defaults.NativeLibraryExtension}";
2630
}
2731
}
2832
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ partial class Paths
1515

1616
public static string BCLTestsSourceDir => GetCachedPath (ref bclTestsSourceDir, () => Path.Combine (MonoProfileDir, "tests"));
1717
public static string BCLAssembliesSourceDir => MonoProfileDir;
18+
public static string HostRuntimeDir => GetCachedPath (ref hostRuntimeDir, () => Path.Combine (XAInstallPrefix, "xbuild", "Xamarin", "Android", "lib", $"host-{ctx.OS.Type}"));
1819

1920
public static readonly string MonoRuntimeHostMingwNativeLibraryPrefix = Path.Combine ("..", "bin");
21+
22+
static string hostRuntimeDir;
2023
}
2124
}
2225
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ public static partial class Paths
257257
public static readonly string ExternalXamarinAndroidToolsSln = Path.Combine (ExternalDir, "xamarin-android-tools", "Xamarin.Android.Tools.sln");
258258
public static readonly string MxeSourceDir = Path.Combine (ExternalDir, "mxe");
259259
public static readonly string MonoSDKSRelativeOutputDir = Path.Combine ("sdks", "out");
260+
public static readonly string MonoSDKRelativeIncludeSourceDir = Path.Combine ("include", "mono-2.0", "mono");
260261
public static readonly string RuntimeInstallRelativeLibDir = "lib";
261262
public static readonly string PackageImageDependenciesTemplate = Path.Combine (BuildToolsScriptsDir, "prepare-image-dependencies.sh.in");
262263
public static readonly string PackageImageDependenciesOutput = Path.Combine (BuildPaths.XamarinAndroidSourceRoot, "prepare-image-dependencies.sh");
@@ -268,6 +269,7 @@ public static partial class Paths
268269
public static string MonoSDKSOutputDir => GetCachedPath (ref monoSDKsOutputDir, () => Path.Combine (MonoSourceFullPath, MonoSDKSRelativeOutputDir));
269270
public static string MonoProfileDir => GetCachedPath (ref monoProfileDir, () => Path.Combine (MonoSDKSOutputDir, "android-bcl", "monodroid"));
270271
public static string MonoProfileToolsDir => GetCachedPath (ref monoProfileToolsDir, () => Path.Combine (MonoSDKSOutputDir, "android-bcl", "monodroid_tools"));
272+
public static string MonoSDKIncludeDestinationDir => GetCachedPath (ref monoSDKSIncludeDestDir, () => Path.Combine (OutputIncludeDir, "mono-2.0", "mono"));
271273

272274
public static string BCLFacadeAssembliesSourceDir => GetCachedPath (ref bclFacadeAssembliesSourceDir, () => Path.Combine (BCLAssembliesSourceDir, "Facades"));
273275
public static string BCLHostAssembliesSourceDir => BCLAssembliesSourceDir;
@@ -409,6 +411,7 @@ static string GetCachedPath (ref string variable, Func<string> creator)
409411
static string installBCLDesignerDir;
410412
static string monoAndroidFrameworksRootDir;
411413
static string externalJavaInteropDir;
414+
static string monoSDKSIncludeDestDir;
412415
}
413416
}
414417
}
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
6+
namespace Xamarin.Android.Prepare
7+
{
8+
partial class Runtimes
9+
{
10+
static Context ctx => Context.Instance;
11+
12+
static string GetMonoUtilitySourcePath (string utilityName)
13+
{
14+
return Path.Combine (Configurables.Paths.MonoProfileToolsDir, utilityName);
15+
}
16+
17+
static string GetLlvmOutputSourcePath (Runtime runtime)
18+
{
19+
var llvmRuntime = EnsureRuntimeType<LlvmRuntime> (runtime, "LLVM");
20+
return Path.Combine (GetLlvmInputDir (runtime), "bin");
21+
}
22+
23+
static string GetLlvmOutputDestinationPath (Runtime runtime)
24+
{
25+
var llvmRuntime = EnsureRuntimeType<LlvmRuntime> (runtime, "LLVM");
26+
return llvmRuntime.InstallPath;
27+
}
28+
29+
static string GetMonoPosixHelperOutputSourcePath (Runtime runtime)
30+
{
31+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
32+
return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputMonoPosixHelperFilename}{monoRuntime.NativeLibraryExtension}");
33+
}
34+
35+
static string GetMonoPosixHelperOutputDestinationPath (Runtime runtime, bool debug)
36+
{
37+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
38+
return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputMonoPosixHelperFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}");
39+
}
40+
41+
static string GetMonoBtlsOutputSourcePath (Runtime runtime)
42+
{
43+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
44+
return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputMonoBtlsFilename}{monoRuntime.NativeLibraryExtension}");
45+
}
46+
47+
static string GetMonoBtlsOutputDestinationPath (Runtime runtime, bool debug)
48+
{
49+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
50+
return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputMonoBtlsFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}");
51+
}
52+
53+
static string GetAotProfilerOutputSourcePath (Runtime runtime)
54+
{
55+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
56+
return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputAotProfilerFilename}{monoRuntime.NativeLibraryExtension}");
57+
}
58+
59+
static string GetAotProfilerOutputDestinationPath (Runtime runtime, bool debug)
60+
{
61+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
62+
return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputAotProfilerFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}");
63+
}
64+
65+
static string GetProfilerOutputSourcePath (Runtime runtime)
66+
{
67+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
68+
return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputProfilerFilename}{monoRuntime.NativeLibraryExtension}");
69+
}
70+
71+
static string GetProfilerOutputDestinationPath (Runtime runtime, bool debug)
72+
{
73+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
74+
return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputProfilerFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}");
75+
}
76+
77+
static string GetCrossRuntimeOutputSourcePath (Runtime runtime)
78+
{
79+
var crossRuntime = EnsureRuntimeType<MonoCrossRuntime> (runtime, "cross compilation");
80+
return Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), "bin", $"{crossRuntime.ExePrefix}mono-sgen{crossRuntime.ExeSuffix}");
81+
}
82+
83+
static string GetCrossRuntimeOutputDestinationPath (Runtime runtime, bool debug)
84+
{
85+
var crossRuntime = EnsureRuntimeType<MonoCrossRuntime> (runtime, "cross compilation");
86+
string runtimeName = $"{crossRuntime.CrossMonoName}{GetDebugInfix (debug)}{crossRuntime.ExeSuffix}";
87+
if (String.IsNullOrEmpty (crossRuntime.InstallPath))
88+
return runtimeName;
89+
90+
return Path.Combine (crossRuntime.InstallPath, runtimeName);
91+
}
92+
93+
static string GetRuntimeOutputSourcePath (Runtime runtime)
94+
{
95+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
96+
return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"{monoRuntime.OutputRuntimeFilename}{monoRuntime.NativeLibraryExtension}");
97+
}
98+
99+
static string GetRuntimeOutputDestinationPath (Runtime runtime, bool debug)
100+
{
101+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
102+
return Path.Combine (GetRuntimeOutputDir (runtime), $"{monoRuntime.OutputRuntimeFilename}{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}");
103+
}
104+
105+
static string GetMonoNativeOutputSourcePath (Runtime runtime)
106+
{
107+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
108+
if (IsAbi (runtime, AbiNames.HostJit.Darwin))
109+
return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"libmono-native-compat{monoRuntime.NativeLibraryExtension}");
110+
111+
return Path.Combine (GetAndroidInputLibDir (runtime), monoRuntime.NativeLibraryDirPrefix, $"libmono-native{monoRuntime.NativeLibraryExtension}");
112+
}
113+
114+
static string GetMonoNativeOutputDestinationPath (Runtime runtime, bool debug)
115+
{
116+
var monoRuntime = EnsureRuntimeType<MonoRuntime> (runtime, "Mono");
117+
return Path.Combine (GetRuntimeOutputDir (runtime), $"libmono-native{GetDebugInfix (debug)}{monoRuntime.NativeLibraryExtension}");
118+
}
119+
120+
static string GetDebugInfix (bool debug)
121+
{
122+
return debug ? Configurables.Defaults.DebugBinaryInfix : String.Empty;
123+
}
124+
125+
static bool IsHostOrTargetRuntime (Runtime runtime)
126+
{
127+
return IsRuntimeType<MonoJitRuntime> (runtime) || IsRuntimeType<MonoHostRuntime> (runtime);
128+
}
129+
130+
static T EnsureRuntimeType<T> (Runtime runtime, string typeName) where T: Runtime
131+
{
132+
var ret = runtime.As<T> ();
133+
if (ret == null)
134+
throw new InvalidOperationException ($"Runtime {runtime.Name} is not a {typeName} runtime");
135+
136+
return ret;
137+
}
138+
139+
static bool IsRuntimeType <T> (Runtime runtime) where T: Runtime
140+
{
141+
return runtime.As<T>() != null;
142+
}
143+
144+
static bool IsWindowsRuntime (Runtime runtime)
145+
{
146+
return String.Compare (runtime.ExeSuffix, Configurables.Defaults.WindowsExecutableSuffix, StringComparison.Ordinal) == 0;
147+
}
148+
149+
static bool IsAbi (Runtime runtime, string abiName, params string[] furtherAbiNames)
150+
{
151+
if (ExpectedAbi (abiName))
152+
return true;
153+
154+
if (furtherAbiNames == null)
155+
return false;
156+
157+
foreach (string a in furtherAbiNames) {
158+
if (ExpectedAbi (a))
159+
return true;
160+
}
161+
162+
return false;
163+
164+
bool ExpectedAbi (string abi)
165+
{
166+
if (String.IsNullOrEmpty (abi))
167+
return false;
168+
169+
return String.Compare (abi, runtime.Name ?? String.Empty, StringComparison.Ordinal) == 0;
170+
}
171+
}
172+
173+
static string GetLlvmInputDir (Runtime runtime)
174+
{
175+
return GetLlvmInputRootDir (runtime);
176+
}
177+
178+
static string GetLlvmInputRootDir (Runtime runtime)
179+
{
180+
return Path.Combine (Configurables.Paths.MonoSDKSRelativeOutputDir, $"llvm-{runtime.PrefixedName}");
181+
}
182+
183+
static string GetAndroidInputLibDir (Runtime runtime)
184+
{
185+
return Path.Combine (MonoRuntimesHelpers.GetRootDir (runtime), "lib");
186+
}
187+
188+
static string GetRuntimeOutputDir (Runtime runtime)
189+
{
190+
return Path.Combine (Configurables.Paths.RuntimeInstallRelativeLibDir, runtime.PrefixedName);
191+
}
192+
193+
static bool IsLlvmRuntimeEnabled (Context ctx, string llvmAbi)
194+
{
195+
bool enabled = false;
196+
bool windows = ctx.IsLlvmWindowsAbi (llvmAbi);
197+
bool is64Bit = ctx.Is64BitLlvmAbi (llvmAbi);
198+
199+
HashSet<string> targets;
200+
if (windows)
201+
targets = is64Bit ? AbiNames.All64BitWindowsAotAbis : AbiNames.All32BitWindowsAotAbis;
202+
else
203+
targets = is64Bit ? AbiNames.All64BitHostAotAbis : AbiNames.All32BitHostAotAbis;
204+
205+
foreach (string target in targets) {
206+
if (Context.Instance.IsTargetAotAbiEnabled (target)) {
207+
enabled = true;
208+
break;
209+
}
210+
}
211+
212+
return enabled && (!is64Bit || Context.Instance.OS.Is64Bit);
213+
}
214+
215+
public Runtimes ()
216+
{
217+
Context c = ctx;
218+
foreach (Runtime runtime in Items) {
219+
runtime.Init (c);
220+
}
221+
222+
DesignerHostBclFilesToInstall = new List<BclFile> ();
223+
DesignerWindowsBclFilesToInstall = new List<BclFile> ();
224+
225+
PopulateDesignerBclFiles (DesignerHostBclFilesToInstall, DesignerWindowsBclFilesToInstall);
226+
}
227+
228+
List<BclFile> BclToDesigner (BclFileTarget ignoreForTarget)
229+
{
230+
return BclFilesToInstall.Where (bf => ShouldIncludeDesignerBcl (bf)).Select (bf => new BclFile (bf.Name, bf.Type, excludeDebugSymbols: true, version: bf.Version, target: ignoreForTarget)).ToList ();
231+
232+
bool ShouldIncludeDesignerBcl (BclFile bf)
233+
{
234+
if (DesignerIgnoreFiles == null || !DesignerIgnoreFiles.TryGetValue (bf.Name, out (BclFileType Type, BclFileTarget Target) bft)) {
235+
return true;
236+
}
237+
238+
if (bf.Type != bft.Type || bft.Target != ignoreForTarget)
239+
return true;
240+
241+
Log.Instance.DebugLine ($"BCL file {bf.Name} will NOT be included in the installed Designer BCL files ({ignoreForTarget})");
242+
return false;
243+
}
244+
}
245+
246+
partial void PopulateDesignerBclFiles (List<BclFile> designerHostBclFilesToInstall, List<BclFile> designerWindowsBclFilesToInstall);
247+
248+
List<BundleItem> bundleItems;
249+
}
250+
}

0 commit comments

Comments
 (0)