Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorBernhard Urban <lewurm@gmail.com>2019-07-26 15:15:50 +0300
committermonojenkins <jo.shields+jenkins@xamarin.com>2019-07-26 15:15:50 +0300
commitb4c5d68c2852272b393d71e49e4cb30106b1ac79 (patch)
tree73c39f07e036b4c67a8bfed4e8ca405162e67862 /tools
parentddb1f31c9e09ee921b30661fd097b3f229a041ad (diff)
[android] switch to python offset tool (#15834)
[android] switch to python offset tool And drop C# tool. Fixes https://github.com/mono/mono/issues/9621
Diffstat (limited to 'tools')
-rw-r--r--tools/offsets-tool-py/offsets-tool.py39
-rw-r--r--tools/offsets-tool/.gitignore5
-rw-r--r--tools/offsets-tool/Makefile65
-rw-r--r--tools/offsets-tool/MonoAotOffsetsDumper.cs963
4 files changed, 33 insertions, 1039 deletions
diff --git a/tools/offsets-tool-py/offsets-tool.py b/tools/offsets-tool-py/offsets-tool.py
index 64fdaf92b64..c7cbc57e07f 100644
--- a/tools/offsets-tool-py/offsets-tool.py
+++ b/tools/offsets-tool-py/offsets-tool.py
@@ -7,6 +7,7 @@ import argparse
import clang.cindex
IOS_DEFINES = ["HOST_DARWIN", "TARGET_MACH", "MONO_CROSS_COMPILE", "USE_MONO_CTX", "_XOPEN_SOURCE"]
+ANDROID_DEFINES = ["HOST_ANDROID", "MONO_CROSS_COMPILE", "USE_MONO_CTX", "BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD"]
class Target:
def __init__(self, arch, platform, others):
@@ -52,7 +53,7 @@ class OffsetsTool:
sys.exit (1)
parser = argparse.ArgumentParser ()
- parser.add_argument ('--libclang-path', dest='libclang_path', help='path to directory where libclang.{so,dylib} lives')
+ parser.add_argument ('--libclang', dest='libclang', help='path to shared library of libclang.{so,dylib}')
parser.add_argument ('--emscripten-sdk', dest='emscripten_path', help='path to emscripten sdk')
parser.add_argument ('--outfile', dest='outfile', help='path to output file', required=True)
parser.add_argument ('--monodir', dest='mono_path', help='path to mono source tree', required=True)
@@ -61,8 +62,8 @@ class OffsetsTool:
parser.add_argument ('--sysroot=', dest='sysroot', help='path to sysroot headers of target')
args = parser.parse_args ()
- if not args.libclang_path or not os.path.isdir (args.libclang_path):
- print ("Libclang path '" + args.libclang_path + "' doesn't exist.", file=sys.stderr)
+ if not args.libclang or not os.path.isfile (args.libclang):
+ print ("Libclang '" + args.libclang + "' doesn't exist.", file=sys.stderr)
sys.exit (1)
if not os.path.isdir (args.mono_path):
print ("Mono directory '" + args.mono_path + "' doesn't exist.", file=sys.stderr)
@@ -74,6 +75,7 @@ class OffsetsTool:
self.sys_includes=[]
self.target = None
self.target_args = []
+ android_api_level = "-D__ANDROID_API=21"
if "wasm" in args.abi:
require_emscipten_path (args)
@@ -81,30 +83,55 @@ class OffsetsTool:
self.target = Target ("TARGET_WASM", None, [])
self.target_args += ["-target", args.abi]
+ # iOS
elif "arm-apple-darwin10" == args.abi:
require_sysroot (args)
self.target = Target ("TARGET_ARM", "TARGET_IOS", ["ARM_FPU_VFP", "HAVE_ARMV5"] + IOS_DEFINES)
self.target_args += ["-arch", "arm"]
self.target_args += ["-isysroot", args.sysroot]
-
elif "aarch64-apple-darwin10" == args.abi:
require_sysroot (args)
self.target = Target ("TARGET_ARM64", "TARGET_IOS", IOS_DEFINES)
self.target_args += ["-arch", "arm64"]
self.target_args += ["-isysroot", args.sysroot]
+ # watchOS
elif "armv7k-apple-darwin" == args.abi:
require_sysroot (args)
self.target = Target ("TARGET_ARM", "TARGET_WATCHOS", ["ARM_FPU_VFP", "HAVE_ARMV5"] + IOS_DEFINES)
self.target_args += ["-arch", "armv7k"]
self.target_args += ["-isysroot", args.sysroot]
-
elif "aarch64-apple-darwin10_ilp32" == args.abi:
require_sysroot (args)
self.target = Target ("TARGET_ARM64", "TARGET_WATCHOS", ["MONO_ARCH_ILP32"] + IOS_DEFINES)
self.target_args += ["-arch", "arm64_32"]
self.target_args += ["-isysroot", args.sysroot]
+ # Android
+ elif "i686-none-linux-android" == args.abi:
+ require_sysroot (args)
+ self.target = Target ("TARGET_X86", "TARGET_ANDROID", ANDROID_DEFINES)
+ self.target_args += ["--target=i386---android"]
+ self.target_args += ["-I", args.sysroot + "/usr/include/i686-linux-android"]
+ elif "x86_64-none-linux-android" == args.abi:
+ require_sysroot (args)
+ self.target = Target ("TARGET_AMD64", "TARGET_ANDROID", ANDROID_DEFINES)
+ self.target_args += ["--target=x86_64---android"]
+ self.target_args += ["-I", args.sysroot + "/usr/include/x86_64-linux-android"]
+ elif "armv7-none-linux-androideabi" == args.abi:
+ require_sysroot (args)
+ self.target = Target ("TARGET_ARM", "TARGET_ANDROID", ["ARM_FPU_VFP", "HAVE_ARMV5", "HAVE_ARMV6", "HAVE_ARMV7"] + ANDROID_DEFINES)
+ self.target_args += ["--target=arm---androideabi"]
+ self.target_args += ["-I", args.sysroot + "/usr/include/arm-linux-androideabi"]
+ elif "aarch64-v8a-linux-android" == args.abi:
+ require_sysroot (args)
+ self.target = Target ("TARGET_ARM64", "TARGET_ANDROID", ANDROID_DEFINES)
+ self.target_args += ["--target=aarch64---android"]
+ self.target_args += ["-I", args.sysroot + "/usr/include/aarch64-linux-android"]
+
+ if self.target.platform_define == "TARGET_ANDROID":
+ self.target_args += [android_api_level]
+ self.target_args += ["-isysroot", args.sysroot]
if not self.target:
print ("ABI '" + args.abi + "' is not supported.", file=sys.stderr)
@@ -189,7 +216,7 @@ class OffsetsTool:
for define in self.target.get_clang_args ():
clang_args.append ("-D" + define)
- clang.cindex.Config.set_library_path (args.libclang_path)
+ clang.cindex.Config.set_library_file (args.libclang)
for srcfile in srcfiles:
src = args.mono_path + "/" + srcfile
diff --git a/tools/offsets-tool/.gitignore b/tools/offsets-tool/.gitignore
deleted file mode 100644
index afc98f0d6b8..00000000000
--- a/tools/offsets-tool/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.stamp-clone-*
-CppSharp
-*.exe
-*.h
-*.exe.mdb
diff --git a/tools/offsets-tool/Makefile b/tools/offsets-tool/Makefile
deleted file mode 100644
index c974d0364ae..00000000000
--- a/tools/offsets-tool/Makefile
+++ /dev/null
@@ -1,65 +0,0 @@
-CPPSHARP_BASE_DIR = CppSharp
-
-ifeq ($(OS),Windows_NT)
- CPPSHARP_OS=windows
- ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
- CPPSHARP_ARCH=64
- else
- ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
- CPPSHARP_ARCH=64
- endif
- ifeq ($(PROCESSOR_ARCHITECTURE),x86)
- CPPSHARP_ARCH=32
- endif
- endif
-else
- UNAME_S := $(shell uname -s)
- ifeq ($(UNAME_S),Linux)
- CPPSHARP_OS=linux
- CPPSHARP_ARCH=64
- endif
- ifeq ($(UNAME_S),Darwin)
- CPPSHARP_OS=osx
- CPPSHARP_ARCH=64
- endif
-endif
-
-CPPSHARP_DIR = $(CPPSHARP_BASE_DIR)/$(CPPSHARP_OS)_$(CPPSHARP_ARCH)
-
-CPPSHARP_REFS = -r:$(CPPSHARP_DIR)/CppSharp.dll \
- -r:$(CPPSHARP_DIR)/CppSharp.AST.dll \
- -r:$(CPPSHARP_DIR)/CppSharp.Parser.dll \
- -r:$(CPPSHARP_DIR)/CppSharp.Parser.CSharp.dll \
- -r:$(CPPSHARP_DIR)/CppSharp.Generator.dll
-
-SRC_ROOT = ../..
-
-MONO_OPTIONS_SRC = $(SRC_ROOT)/mcs/class/Mono.Options/Mono.Options/Options.cs
-
-HASH=9dc880dd
-.stamp-clone-$(HASH):
- rm -Rf $(CPPSHARP_BASE_DIR)
- git clone -b $(HASH) --depth 1 git://github.com/xamarin/CppSharpBinaries.git $(CPPSHARP_BASE_DIR) && touch $@
-
-MonoAotOffsetsDumper.exe: .stamp-clone-$(HASH) MonoAotOffsetsDumper.cs $(MONO_OPTIONS_SRC)
- mcs MonoAotOffsetsDumper.cs /debug /nowarn:0436 $(MONO_OPTIONS_SRC) $(CPPSHARP_REFS)
-
-.PHONY: clean
-clean:
- rm MonoAotOffsetsDumper.exe
-
-dump: MonoAotOffsetsDumper.exe
- MONO_PATH=$(CPPSHARP_DIR) mono MonoAotOffsetsDumper.exe
-
-update:
- @if [ -f object-offsets.h ]; then rm object-offsets.h; fi;
- @for f in *.h; do \
- echo "Processing $$f.."; \
- echo "#include \"$$f\"" >> object-offsets1.h; \
- done
- @cp *.h ../mono/metadata
-
-gen-proj:
- $(CPPSHARP_DIR)/premake5 vs2012
-
-all: MonoAotOffsetsDumper.exe
diff --git a/tools/offsets-tool/MonoAotOffsetsDumper.cs b/tools/offsets-tool/MonoAotOffsetsDumper.cs
deleted file mode 100644
index e20df920f78..00000000000
--- a/tools/offsets-tool/MonoAotOffsetsDumper.cs
+++ /dev/null
@@ -1,963 +0,0 @@
-// -*- indent-tabs-mode:nil -*-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text.RegularExpressions;
-using CppSharp.AST;
-using CppSharp.AST.Extensions;
-using CppSharp.Parser;
-
-namespace CppSharp
-{
- /**
- * This tool dumps the offsets of structures used in the Mono VM needed
- * by the AOT compiler for cross-compiling code to target platforms
- * different than the host the compiler is being invoked on.
- */
- static class MonoAotOffsetsDumper
- {
- static string MonoDir = @"";
-
- static List<string> Abis = new List<string> ();
- static string OutputDir;
- static string OutputFile;
-
- static string AndroidNdkPath = @"";
- static string EmscriptenSdkPath = @"";
- static string TargetDir = @"";
- static bool GenIOS;
- static bool GenAndroid;
-
- public enum TargetPlatform
- {
- Android,
- iOS,
- WatchOS,
- OSX,
- WASM
- }
-
- public class Target
- {
- public Target()
- {
- Defines = new List<string>();
- Arguments = new List<string>();
- }
-
- public Target(Target target)
- {
- Platform = target.Platform;
- Triple = target.Triple;
- Build = target.Build;
- Defines = target.Defines;
- Arguments = target.Arguments;
- }
-
- public TargetPlatform Platform;
- public string Triple;
- public string Build;
- public List<string> Defines;
- public List<string> Arguments;
- };
-
- public static List<Target> Targets = new List<Target>();
-
- public static IEnumerable<Target> AndroidTargets
- {
- get { return Targets.Where ((t) => t.Platform == TargetPlatform.Android); }
- }
-
- public static IEnumerable<Target> DarwinTargets
- {
- get
- {
- return Targets.Where ((t) =>
- t.Platform == TargetPlatform.iOS ||
- t.Platform == TargetPlatform.WatchOS ||
- t.Platform == TargetPlatform.OSX);
- }
- }
-
- public static IEnumerable<Target> iOSTargets
- {
- get
- {
- return Targets.Where ((t) => t.Platform == TargetPlatform.iOS);
- }
- }
-
- public static void SetupAndroidTargets()
- {
- Targets.Add (new Target {
- Platform = TargetPlatform.Android,
- Triple = "i686-none-linux-android",
- Defines = { "TARGET_X86" }
- });
-
- Targets.Add (new Target {
- Platform = TargetPlatform.Android,
- Triple = "x86_64-none-linux-android",
- Defines = { "TARGET_AMD64" }
- });
-
- Targets.Add (new Target {
- Platform = TargetPlatform.Android,
- Triple = "armv5-none-linux-androideabi",
- Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5" }
- });
-
- Targets.Add (new Target {
- Platform = TargetPlatform.Android,
- Triple = "armv7-none-linux-androideabi",
- Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5", "HAVE_ARMV6",
- "HAVE_ARMV7"
- }
- });
-
- Targets.Add (new Target {
- Platform = TargetPlatform.Android,
- Triple = "aarch64-v8a-linux-android",
- Defines = { "TARGET_ARM64" }
- });
-
- /*Targets.Add(new Target {
- Platform = TargetPlatform.Android,
- Triple = "mipsel-none-linux-android",
- Defines = { "TARGET_MIPS", "__mips__" }
- });*/
-
- foreach (var target in AndroidTargets)
- target.Defines.AddRange (new string[] { "HOST_ANDROID",
- "TARGET_ANDROID", "MONO_CROSS_COMPILE", "USE_MONO_CTX",
- "BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD"
- });
- }
-
- public static void SetupiOSTargets()
- {
- Targets.Add(new Target {
- Platform = TargetPlatform.iOS,
- Triple = "arm-apple-darwin10",
- Build = "target7",
- Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5" }
- });
-
- Targets.Add(new Target {
- Platform = TargetPlatform.iOS,
- Triple = "aarch64-apple-darwin10",
- Build = "target64",
- Defines = { "TARGET_ARM64" }
- });
-
- foreach (var target in iOSTargets) {
- target.Defines.AddRange (new string[] { "HOST_DARWIN",
- "TARGET_IOS", "TARGET_MACH", "MONO_CROSS_COMPILE", "USE_MONO_CTX",
- "_XOPEN_SOURCE"
- });
- }
-
- Targets.Add(new Target {
- Platform = TargetPlatform.WatchOS,
- Triple = "armv7k-apple-darwin",
- Build = "targetwatch",
- Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5" }
- });
-
- Targets.Add(new Target {
- Platform = TargetPlatform.WatchOS,
- Triple = "armv7k-apple-darwin_ilp32", /* fake triple, aarch64-apple-darwin_ilp32 isn't recognized correctly */
- Build = "targetwatch64_32",
- Defines = { "TARGET_ARM64", "MONO_ARCH_ILP32", "MONO_CPPSHARP_HACK" }
- });
-
- foreach (var target in DarwinTargets) {
- target.Defines.AddRange (new string[] { "HOST_DARWIN",
- "TARGET_IOS", "TARGET_MACH", "MONO_CROSS_COMPILE", "USE_MONO_CTX",
- "_XOPEN_SOURCE"
- });
- }
- }
-
- public static void SetupOtherTargets()
- {
- if (Abis.Count != 1) {
- Console.WriteLine ("Exactly --abi= argument is required.");
- Environment.Exit (1);
- }
- string abi = Abis [0];
- if (abi == "i386-apple-darwin13.0.0") {
- Targets.Add(new Target {
- Platform = TargetPlatform.OSX,
- Triple = "i386-apple-darwin13.0.0",
- Build = "",
- Defines = { "TARGET_X86" },
- });
- } else if (abi == "wasm32-unknown-unknown") {
- Targets.Add(new Target {
- Platform = TargetPlatform.WASM,
- Triple = "wasm32-unknown-unknown",
- Build = "",
- Defines = { "TARGET_WASM" },
- });
- } else {
- Console.WriteLine ($"Unsupported abi: {abi}.");
- Environment.Exit (1);
- }
- }
-
- static bool GetParentSubDirectoryPath(string parent, out string subdir)
- {
- var directory = Directory.GetParent(Directory.GetCurrentDirectory());
-
- while (directory != null) {
- var path = Path.Combine(directory.FullName, parent);
-
- if (Directory.Exists (path)) {
- subdir = path;
- return true;
- }
-
- directory = directory.Parent;
- }
-
- subdir = null;
- return false;
- }
-
- public static int Main(string[] args)
- {
- ParseCommandLineArgs(args);
-
- if (GenAndroid)
- SetupAndroidTargets();
-
- if (GenIOS)
- SetupiOSTargets();
-
- if (Targets.Count == 0)
- SetupOtherTargets ();
-
- foreach (var target in Targets)
- {
- if (Abis.Any() && !Abis.Contains (target.Triple))
- continue;
-
- Console.WriteLine();
- Console.WriteLine("Processing triple: {0}", target.Triple);
-
- var options = new DriverOptions();
-
- var driver = new Driver(options);
-
- Setup(driver, target);
- driver.Setup();
-
- BuildParseOptions(driver, target);
- if (!driver.ParseCode())
- return 1;
-
- Dump(driver.Context.ASTContext, driver.Context.TargetInfo, target);
- }
- return 0;
- }
-
- static void BuildParseOptions(Driver driver, Target target)
- {
- foreach (var header in driver.Options.Headers)
- {
- var source = driver.Project.AddFile(header);
- source.Options = driver.BuildParserOptions(source);
-
- if (header.Contains ("mini"))
- continue;
-
- source.Options.AddDefines ("HAVE_SGEN_GC");
- source.Options.AddDefines ("HAVE_MOVING_COLLECTOR");
- source.Options.AddDefines("MONO_GENERATING_OFFSETS");
- }
- }
-
- static void ParseCommandLineArgs(string[] args)
- {
- var showHelp = false;
-
- var options = new Mono.Options.OptionSet () {
- { "abi=", "ABI triple to generate", v => Abis.Add(v) },
- { "o|out=", "output directory", v => OutputDir = v },
- { "outfile=", "output directory", v => OutputFile = v },
- { "android-ndk=", "Path to Android NDK", v => AndroidNdkPath = v },
- { "emscripten-sdk=", "Path to emscripten sdk", v => EmscriptenSdkPath = v },
- { "targetdir=", "Path to the directory containing the mono build", v =>TargetDir = v },
- { "mono=", "include directory", v => MonoDir = v },
- { "gen-ios", "generate iOS offsets", v => GenIOS = v != null },
- { "gen-android", "generate Android offsets", v => GenAndroid = v != null },
- { "h|help", "show this message and exit", v => showHelp = v != null },
- };
-
- try {
- options.Parse (args);
- }
- catch (Mono.Options.OptionException e) {
- Console.WriteLine (e.Message);
- Environment.Exit(0);
- }
-
- if (showHelp)
- {
- // Print usage and exit.
- Console.WriteLine("{0} <options>",
- AppDomain.CurrentDomain.FriendlyName);
- options.WriteOptionDescriptions (Console.Out);
- Environment.Exit(0);
- }
- }
-
- static void Setup(Driver driver, Target target)
- {
- var options = driver.Options;
- options.DryRun = true;
- options.LibraryName = "Mono";
-
- var parserOptions = driver.ParserOptions;
- parserOptions.Verbose = false;
- parserOptions.MicrosoftMode = false;
- parserOptions.AddArguments("-xc");
- parserOptions.AddArguments("-std=gnu99");
- parserOptions.AddDefines("CPPSHARP");
- parserOptions.AddDefines("MONO_GENERATING_OFFSETS");
-
- foreach (var define in target.Defines)
- parserOptions.AddDefines(define);
-
- SetupToolchainPaths(driver, target);
-
- SetupMono(driver, target);
- }
-
- static void SetupMono(Driver driver, Target target)
- {
- string targetBuild;
- switch (target.Platform) {
- case TargetPlatform.Android:
- if (string.IsNullOrEmpty (TargetDir)) {
- Console.Error.WriteLine ("The --targetdir= option is required when targeting android.");
- Environment.Exit (1);
- }
- if (string.IsNullOrEmpty (MonoDir)) {
- Console.Error.WriteLine ("The --mono= option is required when targeting android.");
- Environment.Exit (1);
- }
- if (string.IsNullOrEmpty(AndroidNdkPath)) {
- Console.WriteLine("The --android-ndk= option is required when targeting android");
- Environment.Exit (1);
- }
- if (Abis.Count != 1) {
- Console.Error.WriteLine ("Exactly one --abi= argument is required when targeting android.");
- Environment.Exit (1);
- }
- targetBuild = TargetDir;
- break;
- case TargetPlatform.WatchOS:
- case TargetPlatform.iOS: {
- if (string.IsNullOrEmpty (TargetDir)) {
- Console.Error.WriteLine ("The --targetdir= option is required when targeting ios.");
- Environment.Exit (1);
- }
- if (string.IsNullOrEmpty (MonoDir)) {
- Console.Error.WriteLine ("The --mono= option is required when targeting ios.");
- Environment.Exit (1);
- }
- targetBuild = TargetDir;
- break;
- }
- case TargetPlatform.OSX:
- case TargetPlatform.WASM:
- if (MonoDir == "") {
- Console.Error.WriteLine ("The --mono= option is required when targeting osx.");
- Environment.Exit (1);
- }
- if (!string.IsNullOrEmpty (TargetDir)) {
- targetBuild = TargetDir;
- } else {
- targetBuild = ".";
- }
- break;
- default:
- throw new ArgumentOutOfRangeException ();
- }
-
- if (!Directory.Exists(targetBuild))
- throw new Exception(string.Format("Could not find the target build directory: {0}", targetBuild));
-
- var includeDirs = new[]
- {
- targetBuild,
- Path.Combine(targetBuild, "mono", "eglib"),
- MonoDir,
- Path.Combine(MonoDir, "mono"),
- Path.Combine(MonoDir, "mono", "mini"),
- Path.Combine(MonoDir, "mono", "eglib")
- };
-
- foreach (var inc in includeDirs)
- driver.ParserOptions.AddIncludeDirs(inc);
-
- var filesToParse = new[]
- {
- Path.Combine(MonoDir, "mono", "metadata", "metadata-cross-helpers.c"),
- Path.Combine(MonoDir, "mono", "mini", "mini-cross-helpers.c"),
- };
-
- foreach (var file in filesToParse)
- driver.Options.Headers.Add(file);
- }
-
- static void SetupMSVC(Driver driver, string triple)
- {
- var parserOptions = driver.ParserOptions;
-
- parserOptions.Abi = Parser.AST.CppAbi.Microsoft;
- parserOptions.MicrosoftMode = true;
-
- var systemIncludeDirs = new[]
- {
- @"C:\Program Files (x86)\Windows Kits\8.1\Include\um",
- @"C:\Program Files (x86)\Windows Kits\8.1\Include\shared"
- };
-
- foreach (var inc in systemIncludeDirs)
- parserOptions.AddSystemIncludeDirs(inc);
-
- parserOptions.AddDefines("HOST_WIN32");
- }
-
- static void SetupToolchainPaths(Driver driver, Target target)
- {
- switch (target.Platform) {
- case TargetPlatform.Android:
- SetupAndroidNDK(driver, target);
- break;
- case TargetPlatform.iOS:
- case TargetPlatform.WatchOS:
- case TargetPlatform.OSX:
- SetupXcode(driver, target);
- break;
- case TargetPlatform.WASM:
- if (EmscriptenSdkPath == "") {
- Console.Error.WriteLine ("The --emscripten-sdk= option is required when targeting wasm.");
- Environment.Exit (1);
- }
- string include_dir = Path.Combine (EmscriptenSdkPath, "system", "include", "libc");
- if (!Directory.Exists (include_dir)) {
- Console.Error.WriteLine ($"emscripten include directory {include_dir} does not exist.");
- Environment.Exit (1);
- }
- var parserOptions = driver.ParserOptions;
- parserOptions.NoBuiltinIncludes = true;
- parserOptions.NoStandardIncludes = true;
- parserOptions.TargetTriple = target.Triple;
- parserOptions.AddSystemIncludeDirs(include_dir);
- break;
- default:
- throw new ArgumentOutOfRangeException ();
- }
- }
-
- static string GetArchFromTriple(string triple)
- {
- if (triple.Contains("mips"))
- return "mips";
-
- if (triple.Contains("arm64") || triple.Contains("aarch64"))
- return "arm64";
-
- if (triple.Contains("arm"))
- return "arm";
-
- if (triple.Contains("i686"))
- return "x86";
-
- if (triple.Contains("x86_64"))
- return "x86_64";
-
- throw new Exception("Unknown architecture from triple: " + triple);
- }
-
- static string GetXcodeToolchainPath()
- {
- var toolchains = Directory.EnumerateDirectories("/Applications", "Xcode*")
- .ToList();
- toolchains.Sort();
-
- var toolchainPath = toolchains.LastOrDefault();
- if (toolchainPath == null)
- throw new Exception("Could not find a valid Xcode SDK");
-
- return toolchainPath;
- }
-
- static string GetXcodeBuiltinIncludesFolder()
- {
- var toolchainPath = GetXcodeToolchainPath();
-
- var toolchains = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
- "Contents/Developer/Toolchains")).ToList();
- toolchains.Sort();
-
- toolchainPath = toolchains.LastOrDefault();
- if (toolchainPath == null)
- throw new Exception("Could not find a valid Xcode toolchain");
-
- var includePaths = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
- "usr/lib/clang")).ToList();
- var includePath = includePaths.LastOrDefault();
-
- if (includePath == null)
- throw new Exception("Could not find a valid Clang include folder");
-
- return Path.Combine(includePath, "include");
- }
-
- static string GetXcodeiOSIncludesFolder()
- {
- var toolchainPath = GetXcodeToolchainPath();
-
- var sdkPaths = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
- "Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs")).ToList();
- var sdkPath = sdkPaths.LastOrDefault();
-
- if (sdkPath == null)
- throw new Exception("Could not find a valid iPhone SDK");
-
- return Path.Combine(sdkPath, "usr/include");
- }
-
- static string GetXcodeOSXIncludesFolder()
- {
- var toolchainPath = GetXcodeToolchainPath();
-
- var sdkPaths = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
- "Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs")).ToList();
- var sdkPath = sdkPaths.LastOrDefault();
-
- if (sdkPath == null)
- throw new Exception("Could not find a valid OSX SDK");
-
- return Path.Combine(sdkPath, "usr/include");
- }
-
- static string GetXcodeWatchOSIncludesFolder()
- {
- var toolchainPath = GetXcodeToolchainPath();
-
- var sdkPaths = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
- "Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs")).ToList();
- var sdkPath = sdkPaths.LastOrDefault();
-
- if (sdkPath == null)
- throw new Exception("Could not find a valid WatchOS SDK");
-
- return Path.Combine(sdkPath, "usr/include");
- }
-
- static void SetupXcode(Driver driver, Target target)
- {
- var parserOptions = driver.ParserOptions;
-
- var builtinsPath = GetXcodeBuiltinIncludesFolder();
- string includePath;
-
- switch (target.Platform) {
- case TargetPlatform.iOS:
- includePath = GetXcodeiOSIncludesFolder();
- break;
- case TargetPlatform.WatchOS:
- includePath = GetXcodeWatchOSIncludesFolder();
- break;
- case TargetPlatform.OSX:
- includePath = GetXcodeOSXIncludesFolder();
- break;
- default:
- throw new ArgumentOutOfRangeException ();
- }
-
- parserOptions.AddSystemIncludeDirs(builtinsPath);
- parserOptions.AddSystemIncludeDirs(includePath);
-
- parserOptions.NoBuiltinIncludes = true;
- parserOptions.NoStandardIncludes = true;
- parserOptions.TargetTriple = target.Triple;
- }
-
- static string GetAndroidHostToolchainPath()
- {
- var toolchains = Directory.EnumerateDirectories(
- Path.Combine(AndroidNdkPath, "toolchains"), "llvm*").ToList();
- toolchains.Sort();
-
- var toolchainPath = toolchains.LastOrDefault();
- if (toolchainPath == null)
- throw new Exception("Could not find a valid NDK host toolchain");
-
- toolchains = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
- "prebuilt")).ToList();
- toolchains.Sort();
-
- toolchainPath = toolchains.LastOrDefault();
- if (toolchainPath == null)
- throw new Exception("Could not find a valid NDK host toolchain");
-
- return toolchainPath;
- }
-
- static string GetAndroidBuiltinIncludesFolder()
- {
- var toolchainPath = GetAndroidHostToolchainPath();
-
- string clangToolchainPath = Path.Combine(toolchainPath, "lib64", "clang");
- if (!Directory.Exists (clangToolchainPath))
- clangToolchainPath = Path.Combine(toolchainPath, "lib", "clang");
-
- string includePath = null;
- if (Directory.Exists (clangToolchainPath)) {
- var includePaths = Directory.EnumerateDirectories(clangToolchainPath).ToList();
- includePath = includePaths.LastOrDefault();
- }
- if (includePath == null)
- throw new Exception("Could not find a valid Clang include folder");
-
- return Path.Combine(includePath, "include");
- }
-
- static void SetupAndroidNDK(Driver driver, Target target)
- {
- var options = driver.Options;
- var parserOptions = driver.ParserOptions;
-
- var builtinsPath = GetAndroidBuiltinIncludesFolder();
- parserOptions.AddSystemIncludeDirs(builtinsPath);
-
- const int androidNdkApiLevel = 21;
-
- string arch = GetArchFromTriple(target.Triple);
- var toolchainPath = Path.Combine(AndroidNdkPath, "platforms",
- "android-" + androidNdkApiLevel, "arch-" + arch,
- "usr", "include");
-
- if (!Directory.Exists (toolchainPath)) {
- // Android NDK r17 and newer no longer have per-platform include directories, they instead use a
- // unified set of headers
- toolchainPath = Path.Combine (AndroidNdkPath, "sysroot", "usr", "include");
-
- // The unified headers require that the target API level is defined as a macro - that's how they
- // differentiate between native APIs available for the given API level
- parserOptions.AddDefines ($"__ANDROID_API__={androidNdkApiLevel}");
-
- // And they also need to point to the per-arch `asm` directory
- string asmTriple;
- switch (arch) {
- case "arm64":
- asmTriple = "aarch64-linux-android";
- break;
-
- case "arm":
- asmTriple = "arm-linux-androideabi";
- break;
-
- case "x86":
- asmTriple = "i686-linux-android";
- break;
-
- case "x86_64":
- asmTriple = "x86_64-linux-android";
- break;
-
- default:
- throw new Exception ($"Unsupported architecture {arch}");
- }
-
- parserOptions.AddSystemIncludeDirs (Path.Combine (toolchainPath, asmTriple));
- }
-
- parserOptions.AddSystemIncludeDirs(toolchainPath);
-
- parserOptions.NoBuiltinIncludes = true;
- parserOptions.NoStandardIncludes = true;
- parserOptions.TargetTriple = target.Triple;
- }
-
- static uint GetTypeAlign(ParserTargetInfo target, ParserIntType type)
- {
- switch (type)
- {
- case ParserIntType.SignedChar:
- case ParserIntType.UnsignedChar:
- return target.CharAlign;
- case ParserIntType.SignedShort:
- case ParserIntType.UnsignedShort:
- return target.ShortAlign;
- case ParserIntType.SignedInt:
- case ParserIntType.UnsignedInt:
- return target.IntAlign;
- case ParserIntType.SignedLong:
- case ParserIntType.UnsignedLong:
- return target.LongAlign;
- case ParserIntType.SignedLongLong:
- case ParserIntType.UnsignedLongLong:
- return target.LongLongAlign;
- default:
- throw new Exception("Type has no alignment");
- }
- }
-
- static uint GetTypeSize(ParserTargetInfo target, ParserIntType type)
- {
- switch (type)
- {
- case ParserIntType.SignedChar:
- case ParserIntType.UnsignedChar:
- return target.CharWidth;
- case ParserIntType.SignedShort:
- case ParserIntType.UnsignedShort:
- return target.ShortWidth;
- case ParserIntType.SignedInt:
- case ParserIntType.UnsignedInt:
- return target.IntWidth;
- case ParserIntType.SignedLong:
- case ParserIntType.UnsignedLong:
- return target.LongWidth;
- case ParserIntType.SignedLongLong:
- case ParserIntType.UnsignedLongLong:
- return target.LongLongWidth;
- default:
- throw new Exception("Type has no size");
- }
- }
-
- static string GetTargetPlatformDefine(TargetPlatform target)
- {
- switch (target) {
- case TargetPlatform.Android:
- return "TARGET_ANDROID";
- case TargetPlatform.iOS:
- return "TARGET_IOS";
- case TargetPlatform.WatchOS:
- return "TARGET_WATCHOS";
- case TargetPlatform.OSX:
- return "TARGET_OSX";
- case TargetPlatform.WASM:
- return "TARGET_WASM";
- default:
- throw new ArgumentOutOfRangeException ();
- }
- }
-
- static void Dump(ASTContext ctx, ParserTargetInfo targetInfo, Target target)
- {
- string targetFile;
-
- if (!string.IsNullOrEmpty (OutputFile)) {
- targetFile = OutputFile;
- } else {
- targetFile = target.Triple;
-
- if (!string.IsNullOrEmpty (OutputDir))
- targetFile = Path.Combine (OutputDir, targetFile);
-
- targetFile += ".h";
- }
-
- using (var writer = new StreamWriter(targetFile))
- //using (var writer = Console.Out)
- {
- writer.WriteLine("#ifndef USED_CROSS_COMPILER_OFFSETS");
- writer.WriteLine("#ifdef {0}", target.Defines[0]);
- writer.WriteLine ("#ifdef {0}", GetTargetPlatformDefine (target.Platform));
- writer.WriteLine("#ifndef HAVE_BOEHM_GC");
- writer.WriteLine("#define HAS_CROSS_COMPILER_OFFSETS");
- writer.WriteLine("#if defined (USE_CROSS_COMPILE_OFFSETS) || defined (MONO_CROSS_COMPILE)");
- writer.WriteLine("#if !defined (DISABLE_METADATA_OFFSETS)");
- writer.WriteLine("#define USED_CROSS_COMPILER_OFFSETS");
-
- DumpAligns(writer, targetInfo);
- DumpSizes(writer, targetInfo);
- DumpMetadataOffsets(writer, ctx, target);
-
- writer.WriteLine("#endif //disable metadata check");
-
- DumpJITOffsets(writer, ctx);
-
- writer.WriteLine("#endif //cross compiler checks");
- writer.WriteLine("#endif //gc check");
- writer.WriteLine("#endif //os check");
- writer.WriteLine("#endif //arch check");
- writer.WriteLine("#endif //USED_CROSS_COMPILER_OFFSETS check");
- }
-
- Console.WriteLine("Generated offsets file: {0}", targetFile);
- }
-
- static void DumpAligns(TextWriter writer, ParserTargetInfo target)
- {
- var aligns = new[]
- {
- new { Name = "gint8", Align = target.CharAlign},
- new { Name = "gint16", Align = target.ShortAlign},
- new { Name = "gint32", Align = target.IntAlign},
- new { Name = "gint64", Align = GetTypeAlign(target, target.Int64Type)},
- new { Name = "float", Align = target.FloatAlign},
- new { Name = "double", Align = target.DoubleAlign},
- new { Name = "gpointer", Align = GetTypeAlign(target, target.IntPtrType)},
- };
-
- // Write the alignment info for the basic types.
- foreach (var align in aligns)
- writer.WriteLine("DECL_ALIGN2({0},{1})", align.Name, align.Align / 8);
- }
-
- static void DumpSizes(TextWriter writer, ParserTargetInfo target)
- {
- var sizes = new[]
- {
- new { Name = "gint8", Size = target.CharWidth},
- new { Name = "gint16", Size = target.ShortWidth},
- new { Name = "gint32", Size = target.IntWidth},
- new { Name = "gint64", Size = GetTypeSize(target, target.Int64Type)},
- new { Name = "float", Size = target.FloatWidth},
- new { Name = "double", Size = target.DoubleWidth},
- new { Name = "gpointer", Size = GetTypeSize(target, target.IntPtrType)},
- };
-
- // Write the size info for the basic types.
- foreach (var size in sizes)
- writer.WriteLine("DECL_SIZE2({0},{1})", size.Name, size.Size / 8);
- }
-
- static Class GetClassFromTypedef(ITypedDecl typedef)
- {
- var type = typedef.Type.Desugar() as TagType;
- if (type == null)
- return null;
-
- var @class = type.Declaration as Class;
-
- return @class.IsIncomplete ?
- (@class.CompleteDeclaration as Class) : @class;
- }
-
- static void DumpClasses(TextWriter writer, ASTContext ctx, IEnumerable<string> types,
- bool optional = false)
- {
- foreach (var @struct in types)
- {
- var @class = ctx.FindCompleteClass(@struct);
- if (@class == null)
- @class = ctx.FindCompleteClass("_" + @struct);
-
- if (@class == null)
- {
- var typedef = ctx.FindTypedef(@struct).FirstOrDefault(
- decl => !decl.IsIncomplete);
-
- if (typedef != null)
- @class = GetClassFromTypedef(typedef);
- }
-
- if (@class == null && optional)
- continue;
-
- if (@class == null)
- throw new Exception("Expected to find struct definition for " + @struct);
-
- DumpStruct(writer, @class);
- }
- }
-
- static void DumpMetadataOffsets(TextWriter writer, ASTContext ctx, Target target)
- {
- var types = new List<string>
- {
- "MonoObject",
- "MonoClass",
- "MonoVTable",
- "MonoDelegate",
- "MonoInternalThread",
- "MonoMulticastDelegate",
- "MonoTransparentProxy",
- "MonoRealProxy",
- "MonoRemoteClass",
- "MonoArray",
- "MonoArrayBounds",
- "MonoSafeHandle",
- "MonoHandleRef",
- "MonoComInteropProxy",
- "MonoString",
- "MonoException",
- "MonoTypedRef",
- "MonoThreadsSync",
- "SgenThreadInfo",
- "SgenClientThreadInfo",
- "MonoProfilerCallContext"
- };
-
- DumpClasses(writer, ctx, types);
- }
-
- static void DumpJITOffsets(TextWriter writer, ASTContext ctx)
- {
- writer.WriteLine("#ifndef DISABLE_JIT_OFFSETS");
- writer.WriteLine("#define USED_CROSS_COMPILER_OFFSETS");
-
- var types = new[]
- {
- "MonoLMF",
- "MonoMethodRuntimeGenericContext",
- "MonoJitTlsData",
- "MonoGSharedVtMethodRuntimeInfo",
- "MonoContinuation",
- "MonoContext",
- "MonoDelegateTrampInfo",
- };
-
- DumpClasses(writer, ctx, types);
-
- var optionalTypes = new[]
- {
- "GSharedVtCallInfo",
- "SeqPointInfo",
- "DynCallArgs",
- "MonoLMFTramp",
- "CallContext",
- "MonoFtnDesc"
- };
-
- DumpClasses(writer, ctx, optionalTypes, optional: true);
-
- writer.WriteLine("#endif //disable jit check");
- }
-
- static void DumpStruct(TextWriter writer, Class @class)
- {
- var name = @class.Name;
- if (name.StartsWith ("_", StringComparison.Ordinal))
- name = name.Substring (1);
-
- writer.WriteLine ("DECL_SIZE2({0},{1})", name, @class.Layout.Size);
-
- foreach (var field in @class.Fields)
- {
- if (field.IsBitField) continue;
-
- if (name == "SgenThreadInfo" && field.Name == "regs")
- continue;
-
- var layout = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr);
-
- writer.WriteLine("DECL_OFFSET2({0},{1},{2})", name, field.Name,
- layout.Offset);
- }
- }
- }
-}