You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Android build and export for the mono module
This commit is contained in:
@@ -1,15 +1,30 @@
|
||||
import imp
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from SCons.Script import BoolVariable, Dir, Environment, Variables
|
||||
from SCons.Script import Dir, Environment
|
||||
|
||||
if os.name == 'nt':
|
||||
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=''):
|
||||
if not extension.startswith('.'):
|
||||
extension = '.' + extension
|
||||
@@ -20,47 +35,55 @@ def find_file_in_dir(directory, files, prefix='', extension=''):
|
||||
|
||||
|
||||
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):
|
||||
os.mkdir(dst_dir)
|
||||
|
||||
copyfile(src_path, dst_path)
|
||||
copy(src_path, dst_dir)
|
||||
|
||||
|
||||
def configure(env, env_mono):
|
||||
from SCons.Script import BoolVariable, PathVariable, 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('copy_mono_root', 'Make a copy of the mono installation directory to bundle with the editor', False))
|
||||
envvars.Update(env)
|
||||
|
||||
bits = env['bits']
|
||||
is_android = env['platform'] == 'android'
|
||||
|
||||
tools_enabled = env['tools']
|
||||
mono_static = env['mono_static']
|
||||
copy_mono_root = env['copy_mono_root']
|
||||
|
||||
mono_prefix = env['mono_prefix']
|
||||
|
||||
mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
|
||||
|
||||
if env['platform'] == 'windows':
|
||||
mono_root = ''
|
||||
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 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 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':
|
||||
mono_root = mono_prefix
|
||||
|
||||
if not mono_root and os.name == 'nt':
|
||||
mono_root = monoreg.find_mono_root_dir(bits)
|
||||
|
||||
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)
|
||||
|
||||
@@ -113,21 +136,18 @@ def configure(env, env_mono):
|
||||
if not mono_dll_name:
|
||||
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:
|
||||
is_apple = (sys.platform == 'darwin' or "osxcross" in env)
|
||||
|
||||
sharedlib_ext = '.dylib' if is_apple else '.so'
|
||||
|
||||
mono_root = ''
|
||||
mono_root = mono_prefix
|
||||
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:
|
||||
# Try with some known directories under OSX
|
||||
@@ -142,7 +162,8 @@ def configure(env, env_mono):
|
||||
if not mono_root and mono_static:
|
||||
mono_root = pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext)
|
||||
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:
|
||||
print('Found Mono root directory: ' + mono_root)
|
||||
@@ -174,6 +195,8 @@ def configure(env, env_mono):
|
||||
|
||||
if is_apple:
|
||||
env.Append(LIBS=['iconv', 'pthread'])
|
||||
elif is_android:
|
||||
env.Append(LIBS=['m', 'dl'])
|
||||
else:
|
||||
env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
|
||||
|
||||
@@ -183,7 +206,7 @@ def configure(env, env_mono):
|
||||
if not mono_so_name:
|
||||
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:
|
||||
assert not mono_static
|
||||
|
||||
@@ -196,9 +219,6 @@ def configure(env, env_mono):
|
||||
env.ParseConfig('pkg-config monosgen-2 --libs')
|
||||
env_mono.ParseConfig('pkg-config monosgen-2 --cflags')
|
||||
|
||||
mono_lib_path = ''
|
||||
mono_so_name = ''
|
||||
|
||||
tmpenv = Environment()
|
||||
tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
|
||||
tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L')
|
||||
@@ -213,11 +233,13 @@ def configure(env, env_mono):
|
||||
if not mono_so_name:
|
||||
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')
|
||||
|
||||
if not tools_enabled:
|
||||
if not tools_enabled and not is_android:
|
||||
if not mono_root:
|
||||
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 = ''
|
||||
|
||||
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)
|
||||
else:
|
||||
assert False
|
||||
@@ -256,12 +278,13 @@ def make_template_dir(env, mono_root):
|
||||
|
||||
# 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_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):
|
||||
@@ -285,7 +308,7 @@ def copy_mono_root_files(env, mono_root):
|
||||
|
||||
# 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
|
||||
|
||||
@@ -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, '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, '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, '*')):
|
||||
if os.path.isfile(file):
|
||||
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
|
||||
|
||||
def copy_if_exists(src, dst):
|
||||
if os.path.isfile(src):
|
||||
copy(src, dst)
|
||||
|
||||
platform = env['platform']
|
||||
|
||||
if platform == 'windows':
|
||||
target_mono_bin_dir = os.path.join(target_mono_root_dir, 'bin')
|
||||
|
||||
if not os.path.isdir(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:
|
||||
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):
|
||||
os.makedirs(target_mono_lib_dir)
|
||||
|
||||
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):
|
||||
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))
|
||||
if mono_version >= LooseVersion('5.12.0'):
|
||||
env.Append(CPPFLAGS=['-DHAS_PENDING_EXCEPTIONS'])
|
||||
|
||||
Reference in New Issue
Block a user