|
@@ -1,15 +1,30 @@
|
|
import imp
|
|
import imp
|
|
import os
|
|
import os
|
|
|
|
+import os.path
|
|
import sys
|
|
import sys
|
|
import subprocess
|
|
import subprocess
|
|
|
|
|
|
from distutils.version import LooseVersion
|
|
from distutils.version import LooseVersion
|
|
-from SCons.Script import BoolVariable, Dir, Environment, Variables
|
|
|
|
|
|
+from SCons.Script import Dir, Environment
|
|
|
|
|
|
if os.name == 'nt':
|
|
if os.name == 'nt':
|
|
from . import mono_reg_utils as monoreg
|
|
from . import mono_reg_utils as monoreg
|
|
|
|
|
|
|
|
|
|
|
|
+android_arch_dirs = {
|
|
|
|
+ 'armv7': 'armeabi-v7a',
|
|
|
|
+ 'arm64v8': 'arm64-v8a',
|
|
|
|
+ 'x86': 'x86',
|
|
|
|
+ 'x86_64': 'x86_64'
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def get_android_out_dir(env):
|
|
|
|
+ return os.path.join(Dir('#platform/android/java/libs').abspath,
|
|
|
|
+ 'release' if env['target'] == 'release' else 'debug',
|
|
|
|
+ android_arch_dirs[env['android_arch']])
|
|
|
|
+
|
|
|
|
+
|
|
def find_file_in_dir(directory, files, prefix='', extension=''):
|
|
def find_file_in_dir(directory, files, prefix='', extension=''):
|
|
if not extension.startswith('.'):
|
|
if not extension.startswith('.'):
|
|
extension = '.' + extension
|
|
extension = '.' + extension
|
|
@@ -20,47 +35,55 @@ def find_file_in_dir(directory, files, prefix='', extension=''):
|
|
|
|
|
|
|
|
|
|
def copy_file(src_dir, dst_dir, name):
|
|
def copy_file(src_dir, dst_dir, name):
|
|
- from shutil import copyfile
|
|
|
|
|
|
+ from shutil import copy
|
|
|
|
|
|
- src_path = os.path.join(src_dir, name)
|
|
|
|
- dst_path = os.path.join(dst_dir, name)
|
|
|
|
|
|
+ src_path = os.path.join(Dir(src_dir).abspath, name)
|
|
|
|
+ dst_dir = Dir(dst_dir).abspath
|
|
|
|
|
|
if not os.path.isdir(dst_dir):
|
|
if not os.path.isdir(dst_dir):
|
|
os.mkdir(dst_dir)
|
|
os.mkdir(dst_dir)
|
|
|
|
|
|
- copyfile(src_path, dst_path)
|
|
|
|
|
|
+ copy(src_path, dst_dir)
|
|
|
|
|
|
|
|
|
|
def configure(env, env_mono):
|
|
def configure(env, env_mono):
|
|
|
|
+ from SCons.Script import BoolVariable, PathVariable, Variables
|
|
|
|
+
|
|
envvars = Variables()
|
|
envvars = Variables()
|
|
|
|
+ envvars.Add(PathVariable('mono_prefix', 'Path to the mono installation directory for the target platform and architecture', '', PathVariable.PathAccept))
|
|
envvars.Add(BoolVariable('mono_static', 'Statically link mono', False))
|
|
envvars.Add(BoolVariable('mono_static', 'Statically link mono', False))
|
|
envvars.Add(BoolVariable('copy_mono_root', 'Make a copy of the mono installation directory to bundle with the editor', False))
|
|
envvars.Add(BoolVariable('copy_mono_root', 'Make a copy of the mono installation directory to bundle with the editor', False))
|
|
envvars.Update(env)
|
|
envvars.Update(env)
|
|
|
|
|
|
bits = env['bits']
|
|
bits = env['bits']
|
|
|
|
+ is_android = env['platform'] == 'android'
|
|
|
|
|
|
tools_enabled = env['tools']
|
|
tools_enabled = env['tools']
|
|
mono_static = env['mono_static']
|
|
mono_static = env['mono_static']
|
|
copy_mono_root = env['copy_mono_root']
|
|
copy_mono_root = env['copy_mono_root']
|
|
|
|
|
|
|
|
+ mono_prefix = env['mono_prefix']
|
|
|
|
+
|
|
mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
|
|
mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
|
|
|
|
|
|
|
|
+ if is_android and not env['android_arch'] in android_arch_dirs:
|
|
|
|
+ raise RuntimeError('This module does not support for the specified \'android_arch\': ' + env['android_arch'])
|
|
|
|
+
|
|
|
|
+ if is_android and tools_enabled:
|
|
|
|
+ # TODO: Implement this. We have to add the data directory to the apk, concretely the Api and Tools folders.
|
|
|
|
+ raise RuntimeError('This module does not currently support building for android with tools enabled')
|
|
|
|
+
|
|
|
|
+ if (os.getenv('MONO32_PREFIX') or os.getenv('MONO64_PREFIX')) and not mono_prefix:
|
|
|
|
+ print("WARNING: The environment variables 'MONO32_PREFIX' and 'MONO64_PREFIX' are deprecated; use the 'mono_prefix' SCons parameter instead")
|
|
|
|
+
|
|
if env['platform'] == 'windows':
|
|
if env['platform'] == 'windows':
|
|
- mono_root = ''
|
|
|
|
|
|
+ mono_root = mono_prefix
|
|
|
|
|
|
- if bits == '32':
|
|
|
|
- if os.getenv('MONO32_PREFIX'):
|
|
|
|
- mono_root = os.getenv('MONO32_PREFIX')
|
|
|
|
- elif os.name == 'nt':
|
|
|
|
- mono_root = monoreg.find_mono_root_dir(bits)
|
|
|
|
- else:
|
|
|
|
- if os.getenv('MONO64_PREFIX'):
|
|
|
|
- mono_root = os.getenv('MONO64_PREFIX')
|
|
|
|
- elif os.name == 'nt':
|
|
|
|
- mono_root = monoreg.find_mono_root_dir(bits)
|
|
|
|
|
|
+ if not mono_root and os.name == 'nt':
|
|
|
|
+ mono_root = monoreg.find_mono_root_dir(bits)
|
|
|
|
|
|
if not mono_root:
|
|
if not mono_root:
|
|
- raise RuntimeError('Mono installation directory not found')
|
|
|
|
|
|
+ raise RuntimeError("Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter")
|
|
|
|
|
|
print('Found Mono root directory: ' + mono_root)
|
|
print('Found Mono root directory: ' + mono_root)
|
|
|
|
|
|
@@ -113,21 +136,18 @@ def configure(env, env_mono):
|
|
if not mono_dll_name:
|
|
if not mono_dll_name:
|
|
raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path)
|
|
raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path)
|
|
|
|
|
|
- copy_file(mono_bin_path, 'bin', mono_dll_name + '.dll')
|
|
|
|
|
|
+ copy_file(mono_bin_path, '#bin', mono_dll_name + '.dll')
|
|
else:
|
|
else:
|
|
is_apple = (sys.platform == 'darwin' or "osxcross" in env)
|
|
is_apple = (sys.platform == 'darwin' or "osxcross" in env)
|
|
|
|
|
|
sharedlib_ext = '.dylib' if is_apple else '.so'
|
|
sharedlib_ext = '.dylib' if is_apple else '.so'
|
|
|
|
|
|
- mono_root = ''
|
|
|
|
|
|
+ mono_root = mono_prefix
|
|
mono_lib_path = ''
|
|
mono_lib_path = ''
|
|
|
|
+ mono_so_name = ''
|
|
|
|
|
|
- if bits == '32':
|
|
|
|
- if os.getenv('MONO32_PREFIX'):
|
|
|
|
- mono_root = os.getenv('MONO32_PREFIX')
|
|
|
|
- else:
|
|
|
|
- if os.getenv('MONO64_PREFIX'):
|
|
|
|
- mono_root = os.getenv('MONO64_PREFIX')
|
|
|
|
|
|
+ if not mono_root and is_android:
|
|
|
|
+ raise RuntimeError("Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter")
|
|
|
|
|
|
if not mono_root and is_apple:
|
|
if not mono_root and is_apple:
|
|
# Try with some known directories under OSX
|
|
# Try with some known directories under OSX
|
|
@@ -142,7 +162,8 @@ def configure(env, env_mono):
|
|
if not mono_root and mono_static:
|
|
if not mono_root and mono_static:
|
|
mono_root = pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext)
|
|
mono_root = pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext)
|
|
if not mono_root:
|
|
if not mono_root:
|
|
- raise RuntimeError('Building with mono_static=yes, but failed to find the mono prefix with pkg-config. Specify one manually')
|
|
|
|
|
|
+ raise RuntimeError("Building with mono_static=yes, but failed to find the mono prefix with pkg-config; " + \
|
|
|
|
+ "specify one manually with the 'mono_prefix' SCons parameter")
|
|
|
|
|
|
if mono_root:
|
|
if mono_root:
|
|
print('Found Mono root directory: ' + mono_root)
|
|
print('Found Mono root directory: ' + mono_root)
|
|
@@ -174,6 +195,8 @@ def configure(env, env_mono):
|
|
|
|
|
|
if is_apple:
|
|
if is_apple:
|
|
env.Append(LIBS=['iconv', 'pthread'])
|
|
env.Append(LIBS=['iconv', 'pthread'])
|
|
|
|
+ elif is_android:
|
|
|
|
+ env.Append(LIBS=['m', 'dl'])
|
|
else:
|
|
else:
|
|
env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
|
|
env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
|
|
|
|
|
|
@@ -183,7 +206,7 @@ def configure(env, env_mono):
|
|
if not mono_so_name:
|
|
if not mono_so_name:
|
|
raise RuntimeError('Could not find mono shared library in: ' + mono_lib_path)
|
|
raise RuntimeError('Could not find mono shared library in: ' + mono_lib_path)
|
|
|
|
|
|
- copy_file(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext)
|
|
|
|
|
|
+ copy_file(mono_lib_path, '#bin', 'lib' + mono_so_name + sharedlib_ext)
|
|
else:
|
|
else:
|
|
assert not mono_static
|
|
assert not mono_static
|
|
|
|
|
|
@@ -196,9 +219,6 @@ def configure(env, env_mono):
|
|
env.ParseConfig('pkg-config monosgen-2 --libs')
|
|
env.ParseConfig('pkg-config monosgen-2 --libs')
|
|
env_mono.ParseConfig('pkg-config monosgen-2 --cflags')
|
|
env_mono.ParseConfig('pkg-config monosgen-2 --cflags')
|
|
|
|
|
|
- mono_lib_path = ''
|
|
|
|
- mono_so_name = ''
|
|
|
|
-
|
|
|
|
tmpenv = Environment()
|
|
tmpenv = Environment()
|
|
tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
|
|
tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
|
|
tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L')
|
|
tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L')
|
|
@@ -213,11 +233,13 @@ def configure(env, env_mono):
|
|
if not mono_so_name:
|
|
if not mono_so_name:
|
|
raise RuntimeError('Could not find mono shared library in: ' + str(tmpenv['LIBPATH']))
|
|
raise RuntimeError('Could not find mono shared library in: ' + str(tmpenv['LIBPATH']))
|
|
|
|
|
|
- copy_file(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext)
|
|
|
|
|
|
+ if not mono_static:
|
|
|
|
+ libs_output_dir = get_android_out_dir(env) if is_android else '#bin'
|
|
|
|
+ copy_file(mono_lib_path, libs_output_dir, 'lib' + mono_so_name + sharedlib_ext)
|
|
|
|
|
|
env.Append(LINKFLAGS='-rdynamic')
|
|
env.Append(LINKFLAGS='-rdynamic')
|
|
|
|
|
|
- if not tools_enabled:
|
|
|
|
|
|
+ if not tools_enabled and not is_android:
|
|
if not mono_root:
|
|
if not mono_root:
|
|
mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
|
|
mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
|
|
|
|
|
|
@@ -241,7 +263,7 @@ def make_template_dir(env, mono_root):
|
|
|
|
|
|
template_dir_name = ''
|
|
template_dir_name = ''
|
|
|
|
|
|
- if platform in ['windows', 'osx', 'x11']:
|
|
|
|
|
|
+ if platform in ['windows', 'osx', 'x11', 'android']:
|
|
template_dir_name = 'data.mono.%s.%s.%s' % (platform, env['bits'], target)
|
|
template_dir_name = 'data.mono.%s.%s.%s' % (platform, env['bits'], target)
|
|
else:
|
|
else:
|
|
assert False
|
|
assert False
|
|
@@ -256,12 +278,13 @@ def make_template_dir(env, mono_root):
|
|
|
|
|
|
# Copy etc/mono/
|
|
# Copy etc/mono/
|
|
|
|
|
|
- template_mono_config_dir = os.path.join(template_mono_root_dir, 'etc', 'mono')
|
|
|
|
- copy_mono_etc_dir(mono_root, template_mono_config_dir, env['platform'])
|
|
|
|
|
|
+ if platform != 'android':
|
|
|
|
+ template_mono_config_dir = os.path.join(template_mono_root_dir, 'etc', 'mono')
|
|
|
|
+ copy_mono_etc_dir(mono_root, template_mono_config_dir, env['platform'])
|
|
|
|
|
|
# Copy the required shared libraries
|
|
# Copy the required shared libraries
|
|
|
|
|
|
- copy_mono_shared_libs(mono_root, template_mono_root_dir, env['platform'])
|
|
|
|
|
|
+ copy_mono_shared_libs(env, mono_root, template_mono_root_dir)
|
|
|
|
|
|
|
|
|
|
def copy_mono_root_files(env, mono_root):
|
|
def copy_mono_root_files(env, mono_root):
|
|
@@ -285,7 +308,7 @@ def copy_mono_root_files(env, mono_root):
|
|
|
|
|
|
# Copy the required shared libraries
|
|
# Copy the required shared libraries
|
|
|
|
|
|
- copy_mono_shared_libs(mono_root, editor_mono_root_dir, env['platform'])
|
|
|
|
|
|
+ copy_mono_shared_libs(env, mono_root, editor_mono_root_dir)
|
|
|
|
|
|
# Copy framework assemblies
|
|
# Copy framework assemblies
|
|
|
|
|
|
@@ -332,39 +355,55 @@ def copy_mono_etc_dir(mono_root, target_mono_config_dir, platform):
|
|
copy_tree(os.path.join(mono_etc_dir, '2.0'), os.path.join(target_mono_config_dir, '2.0'))
|
|
copy_tree(os.path.join(mono_etc_dir, '2.0'), os.path.join(target_mono_config_dir, '2.0'))
|
|
copy_tree(os.path.join(mono_etc_dir, '4.0'), os.path.join(target_mono_config_dir, '4.0'))
|
|
copy_tree(os.path.join(mono_etc_dir, '4.0'), os.path.join(target_mono_config_dir, '4.0'))
|
|
copy_tree(os.path.join(mono_etc_dir, '4.5'), os.path.join(target_mono_config_dir, '4.5'))
|
|
copy_tree(os.path.join(mono_etc_dir, '4.5'), os.path.join(target_mono_config_dir, '4.5'))
|
|
- copy_tree(os.path.join(mono_etc_dir, 'mconfig'), os.path.join(target_mono_config_dir, 'mconfig'))
|
|
|
|
|
|
+ if os.path.isdir(os.path.join(mono_etc_dir, 'mconfig')):
|
|
|
|
+ copy_tree(os.path.join(mono_etc_dir, 'mconfig'), os.path.join(target_mono_config_dir, 'mconfig'))
|
|
|
|
|
|
for file in glob(os.path.join(mono_etc_dir, '*')):
|
|
for file in glob(os.path.join(mono_etc_dir, '*')):
|
|
if os.path.isfile(file):
|
|
if os.path.isfile(file):
|
|
copy(file, target_mono_config_dir)
|
|
copy(file, target_mono_config_dir)
|
|
|
|
|
|
|
|
|
|
-def copy_mono_shared_libs(mono_root, target_mono_root_dir, platform):
|
|
|
|
|
|
+def copy_mono_shared_libs(env, mono_root, target_mono_root_dir):
|
|
from shutil import copy
|
|
from shutil import copy
|
|
|
|
|
|
|
|
+ def copy_if_exists(src, dst):
|
|
|
|
+ if os.path.isfile(src):
|
|
|
|
+ copy(src, dst)
|
|
|
|
+
|
|
|
|
+ platform = env['platform']
|
|
|
|
+
|
|
if platform == 'windows':
|
|
if platform == 'windows':
|
|
target_mono_bin_dir = os.path.join(target_mono_root_dir, 'bin')
|
|
target_mono_bin_dir = os.path.join(target_mono_root_dir, 'bin')
|
|
|
|
|
|
if not os.path.isdir(target_mono_bin_dir):
|
|
if not os.path.isdir(target_mono_bin_dir):
|
|
os.makedirs(target_mono_bin_dir)
|
|
os.makedirs(target_mono_bin_dir)
|
|
|
|
|
|
- copy(os.path.join(mono_root, 'bin', 'MonoPosixHelper.dll'), os.path.join(target_mono_bin_dir, 'MonoPosixHelper.dll'))
|
|
|
|
|
|
+ copy(os.path.join(mono_root, 'bin', 'MonoPosixHelper.dll'), target_mono_bin_dir)
|
|
else:
|
|
else:
|
|
- target_mono_lib_dir = os.path.join(target_mono_root_dir, 'lib')
|
|
|
|
|
|
+ target_mono_lib_dir = get_android_out_dir(env) if platform == 'android' else os.path.join(target_mono_root_dir, 'lib')
|
|
|
|
|
|
if not os.path.isdir(target_mono_lib_dir):
|
|
if not os.path.isdir(target_mono_lib_dir):
|
|
os.makedirs(target_mono_lib_dir)
|
|
os.makedirs(target_mono_lib_dir)
|
|
|
|
|
|
if platform == 'osx':
|
|
if platform == 'osx':
|
|
- copy(os.path.join(mono_root, 'lib', 'libMonoPosixHelper.dylib'), os.path.join(target_mono_lib_dir, 'libMonoPosixHelper.dylib'))
|
|
|
|
- elif platform == 'x11':
|
|
|
|
- copy(os.path.join(mono_root, 'lib', 'libmono-btls-shared.so'), os.path.join(target_mono_lib_dir, 'libmono-btls-shared.so'))
|
|
|
|
- copy(os.path.join(mono_root, 'lib', 'libMonoPosixHelper.so'), os.path.join(target_mono_lib_dir, 'libMonoPosixHelper.so'))
|
|
|
|
|
|
+ # TODO: Make sure nothing is missing
|
|
|
|
+ copy(os.path.join(mono_root, 'lib', 'libMonoPosixHelper.dylib'), target_mono_lib_dir)
|
|
|
|
+ elif platform == 'x11' or platform == 'android':
|
|
|
|
+ lib_file_names = [lib_name + '.so' for lib_name in [
|
|
|
|
+ 'libmono-btls-shared', 'libmono-ee-interp', 'libmono-native', 'libMonoPosixHelper',
|
|
|
|
+ 'libmono-profiler-aot', 'libmono-profiler-coverage', 'libmono-profiler-log', 'libMonoSupportW'
|
|
|
|
+ ]]
|
|
|
|
+
|
|
|
|
+ for lib_file_name in lib_file_names:
|
|
|
|
+ copy_if_exists(os.path.join(mono_root, 'lib', lib_file_name), target_mono_lib_dir)
|
|
|
|
|
|
|
|
|
|
def configure_for_mono_version(env, mono_version):
|
|
def configure_for_mono_version(env, mono_version):
|
|
if mono_version is None:
|
|
if mono_version is None:
|
|
- raise RuntimeError('Mono JIT compiler version not found')
|
|
|
|
|
|
+ if os.getenv('MONO_VERSION'):
|
|
|
|
+ mono_version = os.getenv('MONO_VERSION')
|
|
|
|
+ else:
|
|
|
|
+ raise RuntimeError("Mono JIT compiler version not found; specify one manually with the 'MONO_VERSION' environment variable")
|
|
print('Found Mono JIT compiler version: ' + str(mono_version))
|
|
print('Found Mono JIT compiler version: ' + str(mono_version))
|
|
if mono_version >= LooseVersion('5.12.0'):
|
|
if mono_version >= LooseVersion('5.12.0'):
|
|
env.Append(CPPFLAGS=['-DHAS_PENDING_EXCEPTIONS'])
|
|
env.Append(CPPFLAGS=['-DHAS_PENDING_EXCEPTIONS'])
|