mirror of
https://github.com/Relintai/godot-mono-builds.git
synced 2024-11-20 10:57:28 +01:00
Add iOS build script and fix builds with OSXCROSS
This commit is contained in:
parent
9670946cf5
commit
e8ce81bf23
29
README.md
29
README.md
@ -7,6 +7,8 @@ This repository contains scripts for building the Mono runtime to use with Godot
|
||||
|
||||
These scripts are based on the Mono [sdks](https://github.com/mono/mono/tree/master/sdks) makefiles, with some changes to work well with Godot. Some platforms or targets depend on files from the `sdks` directory in the Mono source repository. This directory may be missing from tarballs. If that's the case, cloning the git repository may be needed. [This table](https://www.mono-project.com/docs/about-mono/versioning/#mono-source-versioning) can be used to determine the branch for a specific version of Mono.
|
||||
|
||||
Some patches need to be applied to the Mono sources before building. This can be done by running `python ./patch_mono.py`.
|
||||
|
||||
Run `python SCRIPT.py --help` for the full list of command line options.
|
||||
|
||||
By default, the scripts will install the resulting files to `$HOME/mono-installs`.
|
||||
@ -22,7 +24,7 @@ export MONO_SOURCE_ROOT=$HOME/git/mono
|
||||
|
||||
### Notes
|
||||
- Python 3.7 or higher is required.
|
||||
- Cross-compiling for macOS via osxcross is not yet supported.
|
||||
- OSXCROSS is supported expect for building the Mono cross-compilers.
|
||||
- Building on Windows is not supported. It's possible to use Cygwin or WSL (Windows Subsystem for Linux) but this hasn't been tested.
|
||||
|
||||
## Desktop
|
||||
@ -45,8 +47,6 @@ _AOT cross-compilers for desktop platforms cannot be built with these scripts ye
|
||||
|
||||
## Android
|
||||
|
||||
Some patches may need to be applied to the Mono sources before building for Android. This can be done by running `./patch_mono.py`.
|
||||
|
||||
```bash
|
||||
# These are the default values. This step can be omitted if SDK and NDK root are in this location.
|
||||
export ANDROID_SDK_ROOT=$HOME/Android/Sdk
|
||||
@ -67,6 +67,26 @@ export ANDROID_NDK_ROOT=$ANDROID_SDK_ROOT/ndk-bundle
|
||||
|
||||
The option `--target=all-runtime` is a shortcut for `--target=armeabi-v7a --target=x86 --target=arm64-v8a --target=x86_64`. The equivalent applies for `all-cross` and `all-cross-win`.
|
||||
|
||||
# iOS
|
||||
|
||||
```bash
|
||||
# Build the runtime for the iPhone simulator.
|
||||
./ios.py configure --target=x86_64
|
||||
./ios.py make --target=x86_64
|
||||
|
||||
# Build the runtime for the iPhone device.
|
||||
./ios.py configure --target=arm64
|
||||
./ios.py make --target=arm64
|
||||
|
||||
# Build the AOT cross-compiler targeting the iPhone device.
|
||||
./ios.py configure --target=cross-arm64
|
||||
./ios.py make --target=cross-arm64
|
||||
```
|
||||
|
||||
The runtime can also be built an OSXCROSS iOS toolchain. The `--ios-toolchain` and `--ios-sdk` options
|
||||
are the equivalent of the Godot SCons options `IPHONEPATH` and `IPHONESDK` respectively.
|
||||
The cross compiler cannot be built with OSXCROSS yet.
|
||||
|
||||
## WebAssembly
|
||||
|
||||
Just like with Godot, an active Emscripten SDK is needed for building the Mono WebAssembly runtime.
|
||||
@ -93,6 +113,9 @@ _AOT cross-compilers for WebAssembly cannot be built with this script yet._
|
||||
# Build the Android BCL.
|
||||
./bcl.py make --product=android
|
||||
|
||||
# Build the iOS BCL.
|
||||
./bcl.py make --product=ios
|
||||
|
||||
# Build the WebAssembly BCL.
|
||||
./bcl.py make --product=wasm
|
||||
```
|
||||
|
21
android.py
21
android.py
@ -173,11 +173,16 @@ def setup_android_target_template(env: dict, opts: AndroidOpts, target: str):
|
||||
# permission denied. Therefore we just override 'MONO_RELOC_LIBDIR' here to avoid the relocation.
|
||||
CPPFLAGS += ['-DMONO_RELOC_LIBDIR=\\\".\\\"']
|
||||
|
||||
CFLAGS += ['-fstack-protector']
|
||||
CFLAGS += ['-DMONODROID=1'] if opts.with_monodroid else []
|
||||
CFLAGS += [
|
||||
'-fstack-protector',
|
||||
'-DMONODROID=1'
|
||||
]
|
||||
CFLAGS += ['-D__ANDROID_API__=' + api] if android_new_ndk else []
|
||||
CXXFLAGS += ['-fstack-protector']
|
||||
CXXFLAGS += ['-DMONODROID=1'] if opts.with_monodroid else []
|
||||
|
||||
CXXFLAGS += [
|
||||
'-fstack-protector',
|
||||
'-DMONODROID=1'
|
||||
]
|
||||
CXXFLAGS += ['-D__ANDROID_API__=' + api] if android_new_ndk else []
|
||||
|
||||
CPPFLAGS += ['-I%s/sysroot/usr/include' % toolchain_path]
|
||||
@ -210,7 +215,7 @@ def setup_android_target_template(env: dict, opts: AndroidOpts, target: str):
|
||||
'--with-btls-android-api=%s' % api,
|
||||
]
|
||||
|
||||
CONFIGURE_FLAGS += ['--enable-monodroid'] if opts.with_monodroid else []
|
||||
CONFIGURE_FLAGS += ['--enable-monodroid']
|
||||
CONFIGURE_FLAGS += ['--with-btls-android-ndk-asm-workaround'] if android_new_ndk else []
|
||||
|
||||
CONFIGURE_FLAGS += [
|
||||
@ -282,7 +287,7 @@ def get_android_libclang_path(opts):
|
||||
def setup_android_cross_template(env: dict, opts: AndroidOpts, target: str, host_arch: str):
|
||||
def get_host_triple():
|
||||
if sys.platform == 'darwin':
|
||||
return '%s-apple-darwin10' % host_arch
|
||||
return '%s-apple-darwin11' % host_arch
|
||||
elif sys.platform in ['linux', 'linux2']:
|
||||
return '%s-linux-gnu' % host_arch
|
||||
assert False
|
||||
@ -319,7 +324,7 @@ def setup_android_cross_template(env: dict, opts: AndroidOpts, target: str, host
|
||||
|
||||
CXXFLAGS = []
|
||||
CXXFLAGS += ['-DDEBUG_CROSS'] if not opts.release else []
|
||||
CXXFLAGS += ['-mmacosx-version-min=10.9 -stdlib=libc++'] if is_darwin else []
|
||||
CXXFLAGS += ['-mmacosx-version-min=10.9', '-stdlib=libc++'] if is_darwin else []
|
||||
|
||||
env['_android-%s_CXXFLAGS' % target] = CXXFLAGS
|
||||
|
||||
@ -469,7 +474,6 @@ def make(opts: AndroidOpts, product: str, target: str):
|
||||
|
||||
def clean(opts: AndroidOpts, product: str, target: str):
|
||||
rm_rf(
|
||||
path_join(opts.configure_dir, 'toolchains', '%s-%s' % (product, target)),
|
||||
path_join(opts.configure_dir, '%s-%s-%s' % (product, target, opts.configuration)),
|
||||
path_join(opts.configure_dir, '%s-%s-%s.config.cache' % (product, target, opts.configuration)),
|
||||
path_join(opts.install_dir, '%s-%s-%s' % (product, target, opts.configuration))
|
||||
@ -517,7 +521,6 @@ def main(raw_args):
|
||||
parser.add_argument('--android-ndk', default=android_ndk_default, help=default_help)
|
||||
parser.add_argument('--android-api-version', default='18', help=default_help)
|
||||
parser.add_argument('--android-cmake-version', default='autodetect', help=default_help)
|
||||
parser.add_argument('--with-monodroid', type=custom_bool, default=True, help=default_help)
|
||||
|
||||
cmd_utils.add_runtime_arguments(parser, default_help)
|
||||
|
||||
|
7
bcl.py
7
bcl.py
@ -11,17 +11,19 @@ from options import *
|
||||
from os_utils import *
|
||||
|
||||
|
||||
product_values = ['desktop', 'desktop-win32', 'android', 'wasm']
|
||||
product_values = ['desktop', 'desktop-win32', 'android', 'ios', 'wasm']
|
||||
profiles_table = {
|
||||
'desktop': ['net_4_x'],
|
||||
'desktop-win32': ['net_4_x'],
|
||||
'android': ['monodroid', 'monodroid_tools'],
|
||||
'ios': ['monotouch', 'monotouch_runtime', 'monotouch_tools'],
|
||||
'wasm': ['wasm', 'wasm_tools']
|
||||
}
|
||||
test_profiles_table = {
|
||||
'desktop': [],
|
||||
'desktop-win32': [],
|
||||
'android': ['monodroid', 'monodroid_tools'],
|
||||
'ios': ['monotouch'],
|
||||
'wasm': ['wasm']
|
||||
}
|
||||
|
||||
@ -94,9 +96,6 @@ def make_product(opts: BclOpts, product: str):
|
||||
|
||||
mkdir_p(install_dir)
|
||||
|
||||
for profile in profiles:
|
||||
mkdir_p('%s/%s' % (install_dir, profile))
|
||||
|
||||
make_args = ['-C', build_dir, '-C', 'runtime', 'all-mcs', 'build_profiles=%s' % ' '.join(profiles)]
|
||||
make_args += ['V=1'] if opts.verbose_make else []
|
||||
|
||||
|
80
desktop.py
Normal file → Executable file
80
desktop.py
Normal file → Executable file
@ -44,14 +44,10 @@ def is_cross_compiling(target_platform: str) -> bool:
|
||||
(sys.platform in ['linux', 'linux2', 'cygwin'] and target_platform != 'linux')
|
||||
|
||||
|
||||
def get_osxcross_sdk(target, osxcross_bin):
|
||||
osxcross_sdk = os.environ.get('OSXCROSS_SDK', 14)
|
||||
def get_osxcross_sdk(osxcross_bin, arch):
|
||||
osxcross_sdk = os.environ.get('OSXCROSS_SDK', 18)
|
||||
|
||||
name_fmt = path_join(osxcross_bin, target + '-apple-darwin%s-%s')
|
||||
|
||||
if not 'OSXCROSS_SDK' in os.environ and not os.path.isfile(name_fmt % (osxcross_sdk, 'ar')):
|
||||
# Default 14 wasn't it, try 15
|
||||
osxcross_sdk = 15
|
||||
name_fmt = path_join(osxcross_bin, arch + '-apple-darwin%s-%s')
|
||||
|
||||
if not os.path.isfile(name_fmt % (osxcross_sdk, 'ar')):
|
||||
raise BuildError('Specify a valid osxcross SDK with the environment variable \'OSXCROSS_SDK\'')
|
||||
@ -64,16 +60,24 @@ def setup_desktop_template(env: dict, opts: DesktopOpts, product: str, target_pl
|
||||
|
||||
CONFIGURE_FLAGS = [
|
||||
'--disable-boehm',
|
||||
'--disable-iconv',
|
||||
'--disable-mcs-build',
|
||||
'--disable-nls',
|
||||
'--enable-dynamic-btls',
|
||||
'--enable-maintainer-mode',
|
||||
'--with-sigaltstack=yes',
|
||||
'--with-tls=pthread',
|
||||
'--without-ikvm-native'
|
||||
]
|
||||
|
||||
if target_platform == 'windows':
|
||||
CONFIGURE_FLAGS += [
|
||||
'--with-libgdiplus=%s' % opts.mxe_prefix
|
||||
]
|
||||
else:
|
||||
CONFIGURE_FLAGS += [
|
||||
'--disable-iconv',
|
||||
'--disable-nls',
|
||||
'--enable-dynamic-btls',
|
||||
'--with-sigaltstack=yes',
|
||||
]
|
||||
|
||||
if target_platform == 'windows':
|
||||
mxe_bin = path_join(opts.mxe_prefix, 'bin')
|
||||
|
||||
@ -92,27 +96,28 @@ def setup_desktop_template(env: dict, opts: DesktopOpts, product: str, target_pl
|
||||
env['_%s-%s_STRIP' % (product, target)] = name_fmt % 'strip'
|
||||
|
||||
CONFIGURE_FLAGS += [
|
||||
'--enable-static-gcc-libs'
|
||||
#'--enable-static-gcc-libs'
|
||||
]
|
||||
elif target_platform == 'osx' and 'OSXCROSS_ROOT' in os.environ:
|
||||
osxcross_root = os.environ['OSXCROSS_ROOT']
|
||||
osxcross_bin = path_join(osxcross_root, 'target', 'bin')
|
||||
osxcross_sdk = get_osxcross_sdk(target, osxcross_bin)
|
||||
elif target_platform == 'osx':
|
||||
if is_cross_compiling(target_platform):
|
||||
osxcross_root = os.environ['OSXCROSS_ROOT']
|
||||
osxcross_bin = path_join(osxcross_root, 'target', 'bin')
|
||||
osxcross_sdk = get_osxcross_sdk(osxcross_bin, arch=target)
|
||||
|
||||
env['_%s-%s_PATH' % (product, target)] = osxcross_bin
|
||||
env['_%s-%s_PATH' % (product, target)] = osxcross_bin
|
||||
|
||||
name_fmt = path_join(osxcross_bin, target + ('-apple-darwin%s-' % osxcross_sdk) + '%s')
|
||||
name_fmt = path_join(osxcross_bin, target + ('-apple-darwin%s-' % osxcross_sdk) + '%s')
|
||||
|
||||
env['_%s-%s_AR' % (product, target)] = name_fmt % 'ar'
|
||||
env['_%s-%s_AS' % (product, target)] = name_fmt % 'as'
|
||||
env['_%s-%s_CC' % (product, target)] = name_fmt % 'cc'
|
||||
env['_%s-%s_CXX' % (product, target)] = name_fmt % 'c++'
|
||||
env['_%s-%s_LD' % (product, target)] = name_fmt % 'ld'
|
||||
env['_%s-%s_RANLIB' % (product, target)] = name_fmt % 'ranlib'
|
||||
env['_%s-%s_CMAKE' % (product, target)] = name_fmt % 'cmake'
|
||||
env['_%s-%s_STRIP' % (product, target)] = name_fmt % 'strip'
|
||||
else:
|
||||
env['_%s-%s_CC' % (product, target)] = 'cc'
|
||||
env['_%s-%s_AR' % (product, target)] = name_fmt % 'ar'
|
||||
env['_%s-%s_AS' % (product, target)] = name_fmt % 'as'
|
||||
env['_%s-%s_CC' % (product, target)] = name_fmt % 'clang'
|
||||
env['_%s-%s_CXX' % (product, target)] = name_fmt % 'clang++'
|
||||
env['_%s-%s_LD' % (product, target)] = name_fmt % 'ld'
|
||||
env['_%s-%s_RANLIB' % (product, target)] = name_fmt % 'ranlib'
|
||||
env['_%s-%s_CMAKE' % (product, target)] = name_fmt % 'cmake'
|
||||
env['_%s-%s_STRIP' % (product, target)] = name_fmt % 'strip'
|
||||
else:
|
||||
env['_%s-%s_CC' % (product, target)] = 'cc'
|
||||
|
||||
env['_%s-%s_CONFIGURE_FLAGS' % (product, target)] = CONFIGURE_FLAGS
|
||||
|
||||
@ -122,19 +127,14 @@ def setup_desktop_template(env: dict, opts: DesktopOpts, product: str, target_pl
|
||||
|
||||
|
||||
def strip_libs(opts: DesktopOpts, product: str, target_platform: str, target: str):
|
||||
if is_cross_compiling(target_platform):
|
||||
if target_platform == 'windows':
|
||||
mxe_bin = path_join(opts.mxe_prefix, 'bin')
|
||||
name_fmt = path_join(mxe_bin, target + '-w64-mingw32-%s')
|
||||
strip = name_fmt % 'strip'
|
||||
elif target_platform == 'osx':
|
||||
assert 'OSXCROSS_ROOT' in os.environ
|
||||
osxcross_root = os.environ['OSXCROSS_ROOT']
|
||||
osxcross_bin = path_join(osxcross_bin, 'target', 'bin')
|
||||
osxcross_sdk = get_osxcross_sdk(target, osxcross_bin)
|
||||
if target_platform == 'osx':
|
||||
# 'strip' doesn't support '--strip-unneeded' on macOS
|
||||
return
|
||||
|
||||
name_fmt = path_join(osxcross_bin, target + ('-apple-darwin%s-' % osxcross_sdk) + '%s')
|
||||
strip = name_fmt % 'strip'
|
||||
if is_cross_compiling(target_platform) and target_platform == 'windows':
|
||||
mxe_bin = path_join(opts.mxe_prefix, 'bin')
|
||||
name_fmt = path_join(mxe_bin, target + '-w64-mingw32-%s')
|
||||
strip = name_fmt % 'strip'
|
||||
else:
|
||||
strip = 'strip'
|
||||
|
||||
|
14
files/patches/mono_ios_asl_log_deprecated.diff
Normal file
14
files/patches/mono_ios_asl_log_deprecated.diff
Normal file
@ -0,0 +1,14 @@
|
||||
diff --git a/mono/utils/mono-log-darwin.c b/mono/utils/mono-log-darwin.c
|
||||
index 3cb127bad59..30ff5edc307 100644
|
||||
--- a/mono/utils/mono-log-darwin.c
|
||||
+++ b/mono/utils/mono-log-darwin.c
|
||||
@@ -5,7 +5,8 @@
|
||||
*/
|
||||
#include <config.h>
|
||||
|
||||
-#if defined(HOST_WATCHOS) && (__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0)
|
||||
+#if (defined(HOST_WATCHOS) && (__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0)) \
|
||||
+ || (defined(HOST_IOS) && (__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 100000))
|
||||
/* emitted by clang:
|
||||
* > /Users/lewurm/work/mono-watch4/mono/utils/mono-log-darwin.c:35:2: error: 'asl_log' is \
|
||||
* > deprecated: first deprecated in watchOS 3.0 - os_log(3) has replaced \
|
508
ios.py
Executable file
508
ios.py
Executable file
@ -0,0 +1,508 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
from os.path import join as path_join
|
||||
|
||||
from options import *
|
||||
from os_utils import *
|
||||
import runtime
|
||||
|
||||
|
||||
this_script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
device_targets = ['armv7', 'arm64']
|
||||
sim_targets = ['i386', 'x86_64']
|
||||
cross_targets = ['cross-armv7', 'cross-arm64']
|
||||
|
||||
|
||||
def is_cross(target) -> bool:
|
||||
return target in cross_targets
|
||||
|
||||
|
||||
class iOSTargetTable:
|
||||
archs = {
|
||||
'armv7': 'arm',
|
||||
'arm64': 'arm64',
|
||||
'i386': 'i386',
|
||||
'x86_64': 'x86_64'
|
||||
}
|
||||
|
||||
host_triples = {
|
||||
'armv7': 'arm-apple-darwin11',
|
||||
'arm64': 'aarch64-apple-darwin11',
|
||||
'i386': 'i386-apple-darwin11',
|
||||
'x86_64': 'x86_64-apple-darwin11'
|
||||
}
|
||||
|
||||
osxcross_tool_triples = {
|
||||
'armv7': 'arm-apple-darwin11', # TODO: ?
|
||||
'arm64': 'arm-apple-darwin11',
|
||||
'i386': 'i386-apple-darwin11', # TODO: ?
|
||||
'x86_64': 'x86_64-apple-darwin11'
|
||||
}
|
||||
|
||||
|
||||
def setup_ios_device_template(env: dict, opts: iOSOpts, target: str):
|
||||
ios_sysroot_path = opts.ios_sdk_path
|
||||
|
||||
if not ios_sysroot_path and sys.platform == 'darwin':
|
||||
# Auto-detect on macOS
|
||||
ios_sysroot_path = xcrun_find_sdk('iphoneos')
|
||||
|
||||
if not ios_sysroot_path:
|
||||
raise RuntimeError('Cannot find iOS SDK; specify one manually with \'--ios-sdk\'.')
|
||||
|
||||
sysroot_flags = ['-isysroot', ios_sysroot_path, '-miphoneos-version-min=%s' % opts.ios_version_min]
|
||||
|
||||
arch = iOSTargetTable.archs[target]
|
||||
host_triple = iOSTargetTable.host_triples[target]
|
||||
osxcross_tool_triple = iOSTargetTable.osxcross_tool_triples[target]
|
||||
|
||||
tools_path = path_join(opts.ios_toolchain_path, 'usr', 'bin')
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
name_fmt = path_join(tools_path, osxcross_tool_triple + '-%s')
|
||||
else:
|
||||
name_fmt = path_join(tools_path, '%s')
|
||||
|
||||
AR = name_fmt % 'ar'
|
||||
AS = name_fmt % 'as'
|
||||
CC = name_fmt % 'clang'
|
||||
CXX = name_fmt % 'clang++'
|
||||
LD = name_fmt % 'ld'
|
||||
RANLIB = name_fmt % 'ranlib'
|
||||
STRIP = name_fmt % 'strip'
|
||||
|
||||
ccache_path = os.environ.get('CCACHE', '')
|
||||
if ccache_path:
|
||||
CC = '%s %s' % (ccache_path, CC)
|
||||
CXX = '%s %s' % (ccache_path, CXX)
|
||||
|
||||
AC_VARS = [
|
||||
'ac_cv_c_bigendian=no',
|
||||
'ac_cv_func_fstatat=no',
|
||||
'ac_cv_func_readlinkat=no',
|
||||
'ac_cv_func_getpwuid_r=no',
|
||||
'ac_cv_func_posix_getpwuid_r=yes',
|
||||
'ac_cv_header_curses_h=no',
|
||||
'ac_cv_header_localcharset_h=no',
|
||||
'ac_cv_header_sys_user_h=no',
|
||||
'ac_cv_func_getentropy=no',
|
||||
'ac_cv_func_futimens=no',
|
||||
'ac_cv_func_utimensat=no',
|
||||
'ac_cv_func_shm_open_working_with_mmap=no',
|
||||
'mono_cv_sizeof_sunpath=104',
|
||||
'mono_cv_uscore=yes'
|
||||
]
|
||||
|
||||
bitcode_marker = env.get('ios-%s_BITCODE_MARKER' % target, '')
|
||||
|
||||
CFLAGS = sysroot_flags + [
|
||||
'-arch %s' % arch,
|
||||
'-Wl,-application_extension',
|
||||
'-fexceptions'
|
||||
]
|
||||
CFLAGS += [bitcode_marker] if bitcode_marker else []
|
||||
|
||||
CXXFLAGS = sysroot_flags + [
|
||||
'-arch %s' % arch,
|
||||
'-Wl,-application_extension'
|
||||
]
|
||||
CXXFLAGS += [bitcode_marker] if bitcode_marker else []
|
||||
|
||||
CPPFLAGS = sysroot_flags + [
|
||||
'-DMONOTOUCH=1',
|
||||
'-arch %s' % arch,
|
||||
'-DSMALL_CONFIG', '-D_XOPEN_SOURCE', '-DHOST_IOS', '-DHAVE_LARGE_FILE_SUPPORT=1'
|
||||
]
|
||||
|
||||
LDFLAGS = [
|
||||
'-Wl,-no_weak_imports',
|
||||
'-arch %s' % arch,
|
||||
'-framework', 'CoreFoundation',
|
||||
'-lobjc', '-lc++'
|
||||
]
|
||||
|
||||
CONFIGURE_FLAGS = [
|
||||
'--disable-boehm',
|
||||
'--disable-btls',
|
||||
'--disable-executables',
|
||||
'--disable-icall-tables',
|
||||
'--disable-iconv',
|
||||
'--disable-mcs-build',
|
||||
'--disable-nls',
|
||||
'--disable-visibility-hidden',
|
||||
'--enable-dtrace=no',
|
||||
'--enable-icall-export',
|
||||
'--enable-maintainer-mode',
|
||||
'--enable-minimal=ssa,com,interpreter,jit,portability,assembly_remapping,attach,verifier,' +
|
||||
'full_messages,appdomains,security,sgen_remset,sgen_marksweep_par,sgen_marksweep_fixed,' +
|
||||
'sgen_marksweep_fixed_par,sgen_copying,logging,remoting,shared_perfcounters,gac',
|
||||
'--enable-monotouch',
|
||||
# We don't need this. Comment it so we don't have to call 'mono_gc_init_finalizer_thread' from Godot.
|
||||
#'--with-lazy-gc-thread-creation=yes',
|
||||
'--with-tls=pthread',
|
||||
'--without-ikvm-native',
|
||||
'--without-sigaltstack',
|
||||
'--disable-cooperative-suspend',
|
||||
'--disable-hybrid-suspend',
|
||||
'--disable-crash-reporting'
|
||||
]
|
||||
|
||||
env['_ios-%s_AR' % target] = AR
|
||||
env['_ios-%s_AS' % target] = AS
|
||||
env['_ios-%s_CC' % target] = CC
|
||||
env['_ios-%s_CXX' % target] = CXX
|
||||
env['_ios-%s_LD' % target] = LD
|
||||
env['_ios-%s_RANLIB' % target] = RANLIB
|
||||
env['_ios-%s_STRIP' % target] = STRIP
|
||||
|
||||
env['_ios-%s_AC_VARS' % target] = AC_VARS
|
||||
env['_ios-%s_CFLAGS' % target] = CFLAGS
|
||||
env['_ios-%s_CXXFLAGS' % target] = CXXFLAGS
|
||||
env['_ios-%s_CPPFLAGS' % target] = CPPFLAGS
|
||||
env['_ios-%s_LDFLAGS' % target] = LDFLAGS
|
||||
env['_ios-%s_CONFIGURE_FLAGS' % target] = CONFIGURE_FLAGS
|
||||
|
||||
# Runtime template
|
||||
runtime.setup_runtime_template(env, opts, 'ios', target, host_triple)
|
||||
|
||||
|
||||
def setup_ios_simulator_template(env: dict, opts: iOSOpts, target: str):
|
||||
ios_sysroot_path = opts.ios_sdk_path
|
||||
|
||||
if not ios_sysroot_path and sys.platform == 'darwin':
|
||||
# Auto-detect on macOS
|
||||
ios_sysroot_path = xcrun_find_sdk('iphonesimulator')
|
||||
|
||||
if not ios_sysroot_path:
|
||||
raise RuntimeError('Cannot find iOS SDK; specify one manually with \'--ios-sdk\'.')
|
||||
|
||||
sysroot_flags = ['-isysroot', ios_sysroot_path, '-miphoneos-version-min=%s' % opts.ios_version_min]
|
||||
|
||||
arch = iOSTargetTable.archs[target]
|
||||
host_triple = iOSTargetTable.host_triples[target]
|
||||
osxcross_tool_triple = iOSTargetTable.osxcross_tool_triples[target]
|
||||
|
||||
tools_path = path_join(opts.ios_toolchain_path, 'usr', 'bin')
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
name_fmt = path_join(tools_path, osxcross_tool_triple + '-%s')
|
||||
else:
|
||||
name_fmt = path_join(tools_path, '%s')
|
||||
|
||||
AR = name_fmt % 'ar'
|
||||
AS = name_fmt % 'as'
|
||||
CC = name_fmt % 'clang'
|
||||
CXX = name_fmt % 'clang++'
|
||||
LD = name_fmt % 'ld'
|
||||
RANLIB = name_fmt % 'ranlib'
|
||||
STRIP = name_fmt % 'strip'
|
||||
|
||||
ccache_path = os.environ.get('CCACHE', '')
|
||||
if ccache_path:
|
||||
CC = '%s %s' % (ccache_path, CC)
|
||||
CXX = '%s %s' % (ccache_path, CXX)
|
||||
|
||||
AC_VARS = [
|
||||
'ac_cv_func_clock_nanosleep=no',
|
||||
'ac_cv_func_fstatat=no',
|
||||
'ac_cv_func_readlinkat=no',
|
||||
'ac_cv_func_system=no',
|
||||
'ac_cv_func_getentropy=no',
|
||||
'ac_cv_func_futimens=no',
|
||||
'ac_cv_func_utimensat=no',
|
||||
'ac_cv_func_shm_open_working_with_mmap=no',
|
||||
'mono_cv_uscore=yes'
|
||||
]
|
||||
|
||||
CFLAGS = sysroot_flags + [
|
||||
'-arch %s' % arch,
|
||||
'-Wl,-application_extension'
|
||||
]
|
||||
|
||||
CXXFLAGS = sysroot_flags + [
|
||||
'-arch %s' % arch,
|
||||
'-Wl,-application_extension'
|
||||
]
|
||||
|
||||
CPPFLAGS = sysroot_flags + [
|
||||
'-DMONOTOUCH=1',
|
||||
'-arch %s' % arch,
|
||||
'-Wl,-application_extension',
|
||||
'-DHOST_IOS'
|
||||
]
|
||||
|
||||
LDFLAGS = []
|
||||
|
||||
CONFIGURE_FLAGS = [
|
||||
'--disable-boehm',
|
||||
'--disable-btls',
|
||||
'--disable-executables',
|
||||
'--disable-iconv',
|
||||
'--disable-mcs-build',
|
||||
'--disable-nls',
|
||||
'--disable-visibility-hidden',
|
||||
'--enable-maintainer-mode',
|
||||
'--enable-minimal=com,remoting,shared_perfcounters,gac',
|
||||
'--enable-monotouch',
|
||||
'--with-tls=pthread',
|
||||
'--without-ikvm-native',
|
||||
'--disable-cooperative-suspend',
|
||||
'--disable-hybrid-suspend',
|
||||
'--disable-crash-reporting'
|
||||
]
|
||||
|
||||
env['_ios-%s_AR' % target] = AR
|
||||
env['_ios-%s_AS' % target] = AS
|
||||
env['_ios-%s_CC' % target] = CC
|
||||
env['_ios-%s_CXX' % target] = CXX
|
||||
env['_ios-%s_LD' % target] = LD
|
||||
env['_ios-%s_RANLIB' % target] = RANLIB
|
||||
env['_ios-%s_STRIP' % target] = STRIP
|
||||
|
||||
env['_ios-%s_AC_VARS' % target] = AC_VARS
|
||||
env['_ios-%s_CFLAGS' % target] = CFLAGS
|
||||
env['_ios-%s_CXXFLAGS' % target] = CXXFLAGS
|
||||
env['_ios-%s_CPPFLAGS' % target] = CPPFLAGS
|
||||
env['_ios-%s_LDFLAGS' % target] = LDFLAGS
|
||||
env['_ios-%s_CONFIGURE_FLAGS' % target] = CONFIGURE_FLAGS
|
||||
|
||||
# Runtime template
|
||||
runtime.setup_runtime_template(env, opts, 'ios', target, host_triple)
|
||||
|
||||
|
||||
class iOSCrossTable:
|
||||
target_triples = {
|
||||
'cross-armv7': 'arm-apple-darwin',
|
||||
'cross-arm64': 'aarch64-apple-darwin'
|
||||
}
|
||||
|
||||
device_targets = {
|
||||
'cross-armv7': 'armv7',
|
||||
'cross-arm64': 'arm64'
|
||||
}
|
||||
|
||||
# 'darwin10' is hard-coded in 'offsets-tool.py', hence why we use 'darwin10' here
|
||||
offsets_dumper_abis = {
|
||||
'cross-armv7': 'arm-apple-darwin10',
|
||||
'cross-arm64': 'aarch64-apple-darwin10'
|
||||
}
|
||||
|
||||
|
||||
def get_osxcross_sdk(osxcross_bin, arch):
|
||||
osxcross_sdk = os.environ.get('OSXCROSS_SDK', 18)
|
||||
|
||||
name_fmt = path_join(osxcross_bin, arch + '-apple-darwin%s-%s')
|
||||
|
||||
if not os.path.isfile(name_fmt % (osxcross_sdk, 'ar')):
|
||||
raise BuildError('Specify a valid osxcross SDK with the environment variable \'OSXCROSS_SDK\'')
|
||||
|
||||
return osxcross_sdk
|
||||
|
||||
|
||||
def setup_ios_cross_template(env: dict, opts: iOSOpts, target: str, host_arch: str):
|
||||
target_triple = iOSCrossTable.target_triples[target]
|
||||
device_target = iOSCrossTable.device_targets[target]
|
||||
offsets_dumper_abi = iOSCrossTable.offsets_dumper_abis[target]
|
||||
host_triple = '%s-apple-darwin11' % host_arch
|
||||
|
||||
is_sim = device_target in sim_targets
|
||||
|
||||
ios_sysroot_path = opts.ios_sdk_path
|
||||
|
||||
if not ios_sysroot_path and sys.platform == 'darwin':
|
||||
# Auto-detect on macOS
|
||||
ios_sysroot_path = xcrun_find_sdk('iphonesimulator' if is_sim else 'iphoneos')
|
||||
|
||||
if not ios_sysroot_path:
|
||||
raise RuntimeError('Cannot find iOS SDK; specify one manually with \'--ios-sdk\'.')
|
||||
|
||||
osx_sysroot_path = opts.osx_sdk_path
|
||||
|
||||
if not osx_sysroot_path and sys.platform == 'darwin':
|
||||
# Auto-detect on macOS
|
||||
osx_sysroot_path = xcrun_find_sdk('macosx')
|
||||
|
||||
if not osx_sysroot_path:
|
||||
raise RuntimeError('Cannot find MacOSX SDK; specify one manually with \'--osx-sdk\'.')
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
if not 'OSXCROSS_ROOT' in os.environ:
|
||||
raise RuntimeError('The \'OSXCROSS_ROOT\' environment variable is required for cross-compiling to macOS')
|
||||
|
||||
osxcross_root = os.environ['OSXCROSS_ROOT']
|
||||
osxcross_bin = path_join(osxcross_root, 'target', 'bin')
|
||||
osxcross_sdk = get_osxcross_sdk(osxcross_bin, arch=host_arch)
|
||||
|
||||
env['_ios-%s_PATH' % target] = osxcross_bin
|
||||
|
||||
name_fmt = path_join(osxcross_bin, target + ('-apple-darwin%s-' % osxcross_sdk) + '%s')
|
||||
else:
|
||||
tools_path = path_join(opts.osx_toolchain_path, 'usr', 'bin')
|
||||
name_fmt = path_join(tools_path, '%s')
|
||||
|
||||
env['_ios-%s_AR' % target] = name_fmt % 'ar'
|
||||
env['_ios-%s_AS' % target] = name_fmt % 'as'
|
||||
env['_ios-%s_CC' % target] = name_fmt % 'clang'
|
||||
env['_ios-%s_CXX' % target] = name_fmt % 'clang++'
|
||||
env['_ios-%s_LD' % target] = name_fmt % 'ld'
|
||||
env['_ios-%s_RANLIB' % target] = name_fmt % 'ranlib'
|
||||
env['_ios-%s_STRIP' % target] = name_fmt % 'strip'
|
||||
|
||||
libclang = path_join(opts.ios_toolchain_path, 'usr', 'lib', 'libclang.dylib') if sys.platform == 'darwin' else os.environ['LIBCLANG_PATH']
|
||||
|
||||
env['_ios-%s_OFFSETS_DUMPER_ARGS' % target] = [
|
||||
'--libclang=%s' % libclang,
|
||||
'--sysroot=%s' % ios_sysroot_path
|
||||
]
|
||||
|
||||
AC_VARS = ['ac_cv_func_shm_open_working_with_mmap=no']
|
||||
|
||||
CFLAGS = ['-isysroot', osx_sysroot_path, '-mmacosx-version-min=10.9', '-Qunused-arguments']
|
||||
CXXFLAGS = ['-isysroot', osx_sysroot_path, '-mmacosx-version-min=10.9', '-Qunused-arguments', '-stdlib=libc++']
|
||||
CPPFLAGS = ['-DMONOTOUCH=1']
|
||||
LDFLAGS = ['-stdlib=libc++']
|
||||
|
||||
CONFIGURE_FLAGS = [
|
||||
'--disable-boehm',
|
||||
'--disable-btls',
|
||||
'--disable-iconv',
|
||||
'--disable-libraries',
|
||||
'--disable-mcs-build',
|
||||
'--disable-nls',
|
||||
'--enable-dtrace=no',
|
||||
'--enable-icall-symbol-map',
|
||||
'--enable-minimal=com,remoting',
|
||||
'--enable-monotouch',
|
||||
'--disable-crash-reporting'
|
||||
]
|
||||
|
||||
env['_ios-%s_AC_VARS' % target] = AC_VARS
|
||||
env['_ios-%s_CFLAGS' % target] = CFLAGS
|
||||
env['_ios-%s_CXXFLAGS' % target] = CXXFLAGS
|
||||
env['_ios-%s_CPPFLAGS' % target] = CPPFLAGS
|
||||
env['_ios-%s_LDFLAGS' % target] = LDFLAGS
|
||||
env['_ios-%s_CONFIGURE_FLAGS' % target] = CONFIGURE_FLAGS
|
||||
|
||||
# Runtime cross template
|
||||
runtime.setup_runtime_cross_template(env, opts, 'ios', target, host_triple, target_triple, device_target, 'llvm64', offsets_dumper_abi)
|
||||
|
||||
|
||||
def strip_libs(opts: iOSOpts, product: str, target: str):
|
||||
# 'strip' doesn't support '--strip-unneeded' on macOS
|
||||
return
|
||||
|
||||
|
||||
def configure(opts: iOSOpts, product: str, target: str):
|
||||
env = {}
|
||||
|
||||
is_sim = target in sim_targets
|
||||
|
||||
if is_cross(target):
|
||||
import llvm
|
||||
|
||||
llvm.make(opts, 'llvm64')
|
||||
setup_ios_cross_template(env, opts, target, host_arch='x86_64')
|
||||
else:
|
||||
if is_sim:
|
||||
setup_ios_simulator_template(env, opts, target)
|
||||
else:
|
||||
setup_ios_device_template(env, opts, target)
|
||||
|
||||
if not os.path.isfile(path_join(opts.mono_source_root, 'configure')):
|
||||
runtime.run_autogen(opts)
|
||||
|
||||
runtime.run_configure(env, opts, product, target)
|
||||
|
||||
|
||||
def make(opts: iOSOpts, product: str, target: str):
|
||||
env = {}
|
||||
|
||||
build_dir = path_join(opts.configure_dir, '%s-%s-%s' % (product, target, opts.configuration))
|
||||
|
||||
make_args = ['-C', build_dir]
|
||||
make_args += ['V=1'] if opts.verbose_make else []
|
||||
|
||||
run_command('make', args=make_args, name='make')
|
||||
run_command('make', args=['-C', '%s/mono' % build_dir, 'install'], name='make install mono')
|
||||
run_command('make', args=['-C', '%s/support' % build_dir, 'install'], name='make install support')
|
||||
run_command('make', args=['-C', '%s/data' % build_dir, 'install'], name='make install data')
|
||||
|
||||
if opts.strip_libs and not is_cross(target):
|
||||
strip_libs(opts, product, target)
|
||||
|
||||
|
||||
def clean(opts: iOSOpts, product: str, target: str):
|
||||
rm_rf(
|
||||
path_join(opts.configure_dir, '%s-%s-%s' % (product, target, opts.configuration)),
|
||||
path_join(opts.configure_dir, '%s-%s-%s.config.cache' % (product, target, opts.configuration)),
|
||||
path_join(opts.install_dir, '%s-%s-%s' % (product, target, opts.configuration))
|
||||
)
|
||||
|
||||
|
||||
def main(raw_args):
|
||||
import cmd_utils
|
||||
from cmd_utils import custom_bool
|
||||
from collections import OrderedDict
|
||||
from typing import Callable
|
||||
|
||||
target_shortcuts = {
|
||||
'all-device': device_targets,
|
||||
'all-sim': sim_targets,
|
||||
'all-cross': cross_targets
|
||||
}
|
||||
|
||||
target_values = device_targets + sim_targets + cross_targets + list(target_shortcuts)
|
||||
|
||||
actions = OrderedDict()
|
||||
actions['configure'] = configure
|
||||
actions['make'] = make
|
||||
actions['clean'] = clean
|
||||
|
||||
parser = cmd_utils.build_arg_parser(description='Builds the Mono runtime for iOS')
|
||||
|
||||
default_help = 'default: %(default)s'
|
||||
|
||||
default_ios_toolchain = '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain'
|
||||
default_osx_toolchain = '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain'
|
||||
default_ios_version_min = '10.0' # Same as Godot
|
||||
|
||||
parser.add_argument('action', choices=['configure', 'make', 'clean'])
|
||||
parser.add_argument('--target', choices=target_values, action='append', required=True)
|
||||
parser.add_argument('--ios-toolchain', default=default_ios_toolchain, help=default_help)
|
||||
parser.add_argument('--ios-sdk', default='', help=default_help)
|
||||
parser.add_argument('--ios-version-min', default=default_ios_version_min, help=default_help)
|
||||
parser.add_argument('--osx-toolchain', default=default_osx_toolchain, help=default_help)
|
||||
parser.add_argument('--osx-sdk', default='', help=default_help)
|
||||
|
||||
cmd_utils.add_runtime_arguments(parser, default_help)
|
||||
|
||||
args = parser.parse_args(raw_args)
|
||||
|
||||
input_action = args.action
|
||||
input_targets = args.target
|
||||
|
||||
opts = ios_opts_from_args(args)
|
||||
|
||||
targets = cmd_utils.expand_input_targets(input_targets, target_shortcuts)
|
||||
|
||||
if not os.path.isdir(opts.mono_source_root):
|
||||
print('Mono sources directory not found: ' + opts.mono_source_root)
|
||||
sys.exit(1)
|
||||
|
||||
action = actions[input_action]
|
||||
|
||||
try:
|
||||
for target in targets:
|
||||
action(opts, 'ios', target)
|
||||
except BuildError as e:
|
||||
sys.exit(e.message)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from sys import argv
|
||||
main(argv[1:])
|
12
llvm.py
12
llvm.py
@ -8,6 +8,9 @@ from options import *
|
||||
from os_utils import *
|
||||
|
||||
|
||||
# TODO: OSXCROSS
|
||||
|
||||
|
||||
target_values = ['llvm32', 'llvm64', 'llvmwin32', 'llvmwin64']
|
||||
mxe_targets = {
|
||||
'llvmwin32': {'arch': 'i686', 'mxe': 'mxe-Win32'},
|
||||
@ -73,6 +76,15 @@ def make(opts: BaseOpts, target: str):
|
||||
|
||||
make_args += ['V=1'] if opts.verbose_make else []
|
||||
|
||||
# IMPORTANT: We must specify the jobs count for this Makefile.
|
||||
# The Makefile itself runs Make as well with the '-j' option, which tells it to spawn as many jobs as possible.
|
||||
# This can result in errors like 'posix_spawn failed: Resource temporarily unavailable' on macOS due to the process limit.
|
||||
# The job count seems to be inherited from the parent Make process, so that fixes the issue.
|
||||
make_args += ['-j', opts.jobs]
|
||||
|
||||
if not find_executable('cmake') and not 'CMAKE' in os.environ:
|
||||
print('WARNING: Cannot find CMake. Required by the llvm Makefile.')
|
||||
|
||||
run_command('make', args=make_args, name='make')
|
||||
|
||||
touch(stamp_file)
|
||||
|
22
options.py
Normal file → Executable file
22
options.py
Normal file → Executable file
@ -25,12 +25,20 @@ class AndroidOpts(RuntimeOpts):
|
||||
android_toolchains_prefix: str
|
||||
android_sdk_root: str
|
||||
android_ndk_root: str
|
||||
with_monodroid: bool
|
||||
android_api_version: str
|
||||
android_cmake_version: str
|
||||
toolchain_name_fmt: str = '%s-api%s-clang'
|
||||
|
||||
|
||||
@dataclass
|
||||
class iOSOpts(RuntimeOpts):
|
||||
ios_toolchain_path: str
|
||||
ios_sdk_path: str
|
||||
ios_version_min: str
|
||||
osx_toolchain_path: str
|
||||
osx_sdk_path: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class DesktopOpts(RuntimeOpts):
|
||||
with_llvm: bool
|
||||
@ -72,12 +80,22 @@ def android_opts_from_args(args):
|
||||
android_toolchains_prefix = abspath(args.toolchains_prefix),
|
||||
android_sdk_root = abspath(args.android_sdk),
|
||||
android_ndk_root = abspath(args.android_ndk),
|
||||
with_monodroid = args.with_monodroid,
|
||||
android_api_version = args.android_api_version,
|
||||
android_cmake_version = args.android_cmake_version
|
||||
)
|
||||
|
||||
|
||||
def ios_opts_from_args(args):
|
||||
return iOSOpts(
|
||||
**vars(runtime_opts_from_args(args)),
|
||||
ios_toolchain_path = abspath(args.ios_toolchain),
|
||||
ios_sdk_path = abspath(args.ios_sdk) if args.ios_sdk else '',
|
||||
ios_version_min = args.ios_version_min,
|
||||
osx_toolchain_path = abspath(args.osx_toolchain),
|
||||
osx_sdk_path = abspath(args.osx_sdk) if args.ios_sdk else ''
|
||||
)
|
||||
|
||||
|
||||
def bcl_opts_from_args(args):
|
||||
return BclOpts(
|
||||
**vars(base_opts_from_args(args)),
|
||||
|
15
os_utils.py
Normal file → Executable file
15
os_utils.py
Normal file → Executable file
@ -32,13 +32,17 @@ def run_command(command, args=[], cwd=None, env=None, name='command'):
|
||||
raise BuildError('\'%s\' exited with error code: %s' % (name, e.returncode))
|
||||
|
||||
|
||||
print_env_sh_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'print_env.sh')
|
||||
|
||||
|
||||
def source(script: str, cwd=None) -> dict:
|
||||
popen_args = {}
|
||||
if cwd is not None:
|
||||
popen_args['cwd'] = cwd
|
||||
|
||||
import subprocess
|
||||
proc = subprocess.Popen('bash -c \'source %s; env -0\'' % script, stdout=subprocess.PIPE, shell=True, **popen_args)
|
||||
cmd = 'bash -c \'source %s; bash %s\'' % (script, print_env_sh_path)
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, **popen_args)
|
||||
output = proc.communicate()[0]
|
||||
return dict(line.split('=', 1) for line in output.decode().split('\x00') if line)
|
||||
|
||||
@ -135,3 +139,12 @@ def globs(pathnames, dirpath='.'):
|
||||
for pathname in pathnames:
|
||||
files.extend(glob.glob(os.path.join(dirpath, pathname)))
|
||||
return files
|
||||
|
||||
|
||||
def xcrun_find_sdk(sdk_name):
|
||||
import subprocess
|
||||
xcrun_output = subprocess.check_output(['xcrun', '--sdk', sdk_name, '--show-sdk-path']).decode().strip()
|
||||
if xcrun_output.startswith('xcrun: error: SDK "%s" cannot be located' % sdk_name):
|
||||
return ''
|
||||
sdk_path = xcrun_output
|
||||
return sdk_path
|
||||
|
@ -28,7 +28,8 @@ def main(raw_args):
|
||||
patches = [
|
||||
'fix-mono-android-tkill.diff',
|
||||
'mono-dbg-agent-clear-tls-instead-of-abort.diff',
|
||||
'bcl-profile-platform-override.diff'
|
||||
'bcl-profile-platform-override.diff',
|
||||
'mono_ios_asl_log_deprecated.diff'
|
||||
]
|
||||
|
||||
from subprocess import Popen
|
||||
|
13
print_env.sh
Executable file
13
print_env.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This is used in python to get the export environment variables from bash's 'source' command.
|
||||
|
||||
# The 'env' command option '-0' separates the 'name=value' results by 'null' instead of line breaks.
|
||||
# This is required to parse the output because a variable value can contain line breaks as well.
|
||||
# Unfortunately, the '-0' option is not supported on some platforms like macOS,
|
||||
# hence why we need this script to print the environment variables instead.
|
||||
|
||||
unset IFS
|
||||
for var in $(compgen -e); do
|
||||
printf "$var=${!var}\0"
|
||||
done
|
Loading…
Reference in New Issue
Block a user