2019-03-01 21:51:20 +01:00
|
|
|
import os
|
2019-05-20 18:34:35 +02:00
|
|
|
import os.path
|
2019-03-01 21:51:20 +01:00
|
|
|
import sys
|
|
|
|
import subprocess
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
from SCons.Script import Dir, Environment
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
if os.name == 'nt':
|
|
|
|
from . import mono_reg_utils as monoreg
|
|
|
|
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
android_arch_dirs = {
|
|
|
|
'armv7': 'armeabi-v7a',
|
|
|
|
'arm64v8': 'arm64-v8a',
|
|
|
|
'x86': 'x86',
|
|
|
|
'x86_64': 'x86_64'
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def get_android_out_dir(env):
|
2019-09-03 02:31:51 +02:00
|
|
|
return os.path.join(Dir('#platform/android/java/lib/libs').abspath,
|
2019-05-20 18:34:35 +02:00
|
|
|
'release' if env['target'] == 'release' else 'debug',
|
|
|
|
android_arch_dirs[env['android_arch']])
|
|
|
|
|
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
def find_name_in_dir_files(directory, names, prefixes=[''], extensions=['']):
|
|
|
|
for extension in extensions:
|
|
|
|
if extension and not extension.startswith('.'):
|
|
|
|
extension = '.' + extension
|
|
|
|
for prefix in prefixes:
|
|
|
|
for curname in names:
|
|
|
|
if os.path.isfile(os.path.join(directory, prefix + curname + extension)):
|
|
|
|
return curname
|
|
|
|
return ''
|
|
|
|
|
|
|
|
|
|
|
|
def find_file_in_dir(directory, names, prefixes=[''], extensions=['']):
|
|
|
|
for extension in extensions:
|
|
|
|
if extension and not extension.startswith('.'):
|
|
|
|
extension = '.' + extension
|
|
|
|
for prefix in prefixes:
|
|
|
|
for curname in names:
|
|
|
|
filename = prefix + curname + extension
|
|
|
|
if os.path.isfile(os.path.join(directory, filename)):
|
|
|
|
return filename
|
2019-03-01 21:51:20 +01:00
|
|
|
return ''
|
|
|
|
|
|
|
|
|
2020-03-11 01:34:10 +01:00
|
|
|
def copy_file(src_dir, dst_dir, src_name, dst_name=''):
|
2019-05-20 18:34:35 +02:00
|
|
|
from shutil import copy
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-03-11 01:34:10 +01:00
|
|
|
src_path = os.path.join(Dir(src_dir).abspath, src_name)
|
2019-05-20 18:34:35 +02:00
|
|
|
dst_dir = Dir(dst_dir).abspath
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
if not os.path.isdir(dst_dir):
|
2019-07-03 17:41:07 +02:00
|
|
|
os.makedirs(dst_dir)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-03-11 01:34:10 +01:00
|
|
|
if dst_name:
|
|
|
|
copy(src_path, os.path.join(dst_dir, dst_name))
|
|
|
|
else:
|
|
|
|
copy(src_path, dst_dir)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
|
2019-11-10 17:10:38 +01:00
|
|
|
def is_desktop(platform):
|
|
|
|
return platform in ['windows', 'osx', 'x11', 'server', 'uwp', 'haiku']
|
|
|
|
|
|
|
|
|
|
|
|
def is_unix_like(platform):
|
2020-03-11 01:34:10 +01:00
|
|
|
return platform in ['osx', 'x11', 'server', 'android', 'haiku', 'iphone']
|
2019-11-10 17:10:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
def module_supports_tools_on(platform):
|
2020-03-11 01:34:10 +01:00
|
|
|
return platform not in ['android', 'javascript', 'iphone']
|
2019-11-10 17:10:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
def find_wasm_src_dir(mono_root):
|
|
|
|
hint_dirs = [
|
|
|
|
os.path.join(mono_root, 'src'),
|
|
|
|
os.path.join(mono_root, '../src'),
|
|
|
|
]
|
|
|
|
for hint_dir in hint_dirs:
|
|
|
|
if os.path.isfile(os.path.join(hint_dir, 'driver.c')):
|
|
|
|
return hint_dir
|
|
|
|
return ''
|
|
|
|
|
|
|
|
|
2019-03-01 22:00:39 +01:00
|
|
|
def configure(env, env_mono):
|
2019-03-01 21:51:20 +01:00
|
|
|
bits = env['bits']
|
2019-05-20 18:34:35 +02:00
|
|
|
is_android = env['platform'] == 'android'
|
2019-11-10 17:10:38 +01:00
|
|
|
is_javascript = env['platform'] == 'javascript'
|
2020-03-11 01:34:10 +01:00
|
|
|
is_ios = env['platform'] == 'iphone'
|
|
|
|
is_ios_sim = is_ios and env['arch'] in ['x86', 'x86_64']
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
tools_enabled = env['tools']
|
|
|
|
mono_static = env['mono_static']
|
|
|
|
copy_mono_root = env['copy_mono_root']
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
mono_prefix = env['mono_prefix']
|
|
|
|
|
2019-03-01 21:51:20 +01:00
|
|
|
mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
|
|
|
|
|
2019-07-03 09:44:53 +02:00
|
|
|
is_travis = os.environ.get('TRAVIS') == 'true'
|
|
|
|
|
|
|
|
if is_travis:
|
|
|
|
# Travis CI may have a Mono version lower than 5.12
|
|
|
|
env_mono.Append(CPPDEFINES=['NO_PENDING_EXCEPTIONS'])
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
if is_android and not env['android_arch'] in android_arch_dirs:
|
2019-11-10 17:10:38 +01:00
|
|
|
raise RuntimeError('This module does not support the specified \'android_arch\': ' + env['android_arch'])
|
2019-05-20 18:34:35 +02:00
|
|
|
|
2019-11-10 17:10:38 +01:00
|
|
|
if tools_enabled and not module_supports_tools_on(env['platform']):
|
|
|
|
# TODO:
|
|
|
|
# Android: 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 this platform with tools enabled')
|
2019-05-20 18:34:35 +02:00
|
|
|
|
2019-07-03 17:41:07 +02:00
|
|
|
if is_android and mono_static:
|
2020-03-11 01:34:10 +01:00
|
|
|
# FIXME: When static linking and doing something that requires libmono-native, we get a dlopen error as 'libmono-native'
|
|
|
|
# seems to depend on 'libmonosgen-2.0'. Could be fixed by re-directing to '__Internal' with a dllmap or in the dlopen hook.
|
|
|
|
raise RuntimeError('Statically linking Mono is not currently supported for this platform')
|
2019-07-03 17:41:07 +02:00
|
|
|
|
2020-03-11 01:34:10 +01:00
|
|
|
if not mono_static and (is_javascript or is_ios):
|
|
|
|
raise RuntimeError('Dynamically linking Mono is not currently supported for this platform')
|
2019-11-10 17:10:38 +01:00
|
|
|
|
|
|
|
if not mono_prefix and (os.getenv('MONO32_PREFIX') or os.getenv('MONO64_PREFIX')):
|
2019-05-20 18:34:35 +02:00
|
|
|
print("WARNING: The environment variables 'MONO32_PREFIX' and 'MONO64_PREFIX' are deprecated; use the 'mono_prefix' SCons parameter instead")
|
|
|
|
|
2020-03-11 01:34:10 +01:00
|
|
|
# Although we don't support building with tools for any platform where we currently use static AOT,
|
|
|
|
# if these are supported in the future, we won't be using static AOT for them as that would be
|
|
|
|
# too restrictive for the editor. These builds would probably be made to only use the interpreter.
|
|
|
|
mono_aot_static = (is_ios and not is_ios_sim) and not env['tools']
|
|
|
|
|
|
|
|
# Static AOT is only supported on the root domain
|
|
|
|
mono_single_appdomain = mono_aot_static
|
|
|
|
|
|
|
|
if mono_single_appdomain:
|
|
|
|
env_mono.Append(CPPDEFINES=['GD_MONO_SINGLE_APPDOMAIN'])
|
|
|
|
|
|
|
|
if (env['tools'] or env['target'] != 'release') and not mono_single_appdomain:
|
|
|
|
env_mono.Append(CPPDEFINES=['GD_MONO_HOT_RELOAD'])
|
|
|
|
|
2019-03-01 21:51:20 +01:00
|
|
|
if env['platform'] == 'windows':
|
2019-05-20 18:34:35 +02:00
|
|
|
mono_root = mono_prefix
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
if not mono_root and os.name == 'nt':
|
|
|
|
mono_root = monoreg.find_mono_root_dir(bits)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
if not mono_root:
|
2019-05-20 18:34:35 +02:00
|
|
|
raise RuntimeError("Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter")
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
print('Found Mono root directory: ' + mono_root)
|
|
|
|
|
|
|
|
mono_lib_path = os.path.join(mono_root, 'lib')
|
|
|
|
|
|
|
|
env.Append(LIBPATH=mono_lib_path)
|
2019-04-30 13:12:02 +02:00
|
|
|
env_mono.Prepend(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0'))
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
lib_suffixes = ['.lib']
|
|
|
|
|
|
|
|
if not env.msvc:
|
|
|
|
# MingW supports both '.a' and '.lib'
|
|
|
|
lib_suffixes.insert(0, '.a')
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2019-11-28 23:42:37 +01:00
|
|
|
if mono_static:
|
2019-03-01 21:51:20 +01:00
|
|
|
if env.msvc:
|
|
|
|
mono_static_lib_name = 'libmono-static-sgen'
|
|
|
|
else:
|
|
|
|
mono_static_lib_name = 'libmonosgen-2.0'
|
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
mono_static_lib_file = find_file_in_dir(mono_lib_path, [mono_static_lib_name], extensions=lib_suffixes)
|
|
|
|
|
|
|
|
if not mono_static_lib_file:
|
2019-03-01 21:51:20 +01:00
|
|
|
raise RuntimeError('Could not find static mono library in: ' + mono_lib_path)
|
|
|
|
|
|
|
|
if env.msvc:
|
2020-02-22 19:27:14 +01:00
|
|
|
env.Append(LINKFLAGS=mono_static_lib_file)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
env.Append(LINKFLAGS='Mincore.lib')
|
|
|
|
env.Append(LINKFLAGS='msvcrt.lib')
|
|
|
|
env.Append(LINKFLAGS='LIBCMT.lib')
|
|
|
|
env.Append(LINKFLAGS='Psapi.lib')
|
2019-03-01 21:51:20 +01:00
|
|
|
else:
|
2020-02-22 19:27:14 +01:00
|
|
|
mono_static_lib_file_path = os.path.join(mono_lib_path, mono_static_lib_file)
|
|
|
|
env.Append(LINKFLAGS=['-Wl,-whole-archive', mono_static_lib_file_path, '-Wl,-no-whole-archive'])
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2019-08-12 22:30:57 +02:00
|
|
|
env.Append(LIBS=['psapi'])
|
|
|
|
env.Append(LIBS=['version'])
|
2019-03-01 21:51:20 +01:00
|
|
|
else:
|
2020-02-22 19:27:14 +01:00
|
|
|
mono_lib_name = find_name_in_dir_files(mono_lib_path, mono_lib_names, prefixes=['', 'lib'], extensions=lib_suffixes)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
if not mono_lib_name:
|
|
|
|
raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
|
|
|
|
|
|
|
|
if env.msvc:
|
2020-02-22 19:27:14 +01:00
|
|
|
env.Append(LINKFLAGS=mono_lib_name + '.lib')
|
2019-03-01 21:51:20 +01:00
|
|
|
else:
|
2019-08-12 22:30:57 +02:00
|
|
|
env.Append(LIBS=[mono_lib_name])
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
mono_bin_path = os.path.join(mono_root, 'bin')
|
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
mono_dll_file = find_file_in_dir(mono_bin_path, mono_lib_names, prefixes=['', 'lib'], extensions=['.dll'])
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
if not mono_dll_file:
|
2019-03-01 21:51:20 +01:00
|
|
|
raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path)
|
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
copy_file(mono_bin_path, '#bin', mono_dll_file)
|
2019-03-01 21:51:20 +01:00
|
|
|
else:
|
2020-03-05 09:00:41 +01:00
|
|
|
is_apple = env['platform'] in ['osx', 'iphone']
|
2020-03-11 01:34:10 +01:00
|
|
|
is_macos = is_apple and not is_ios
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
sharedlib_ext = '.dylib' if is_apple else '.so'
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
mono_root = mono_prefix
|
2019-03-01 21:51:20 +01:00
|
|
|
mono_lib_path = ''
|
2020-02-22 19:27:14 +01:00
|
|
|
mono_so_file = ''
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-03-11 01:34:10 +01:00
|
|
|
if not mono_root and (is_android or is_javascript or is_ios):
|
2019-05-20 18:34:35 +02:00
|
|
|
raise RuntimeError("Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter")
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-03-11 01:34:10 +01:00
|
|
|
if not mono_root and is_macos:
|
2019-03-01 21:51:20 +01:00
|
|
|
# Try with some known directories under OSX
|
|
|
|
hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current', '/usr/local/var/homebrew/linked/mono']
|
|
|
|
for hint_dir in hint_dirs:
|
|
|
|
if os.path.isdir(hint_dir):
|
|
|
|
mono_root = hint_dir
|
|
|
|
break
|
|
|
|
|
|
|
|
# We can't use pkg-config to link mono statically,
|
|
|
|
# but we can still use it to find the mono root directory
|
|
|
|
if not mono_root and mono_static:
|
|
|
|
mono_root = pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext)
|
|
|
|
if not mono_root:
|
2019-05-20 18:34:35 +02:00
|
|
|
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")
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-03-11 01:34:10 +01:00
|
|
|
if is_ios and not is_ios_sim:
|
|
|
|
env_mono.Append(CPPDEFINES=['IOS_DEVICE'])
|
|
|
|
|
2019-03-01 21:51:20 +01:00
|
|
|
if mono_root:
|
|
|
|
print('Found Mono root directory: ' + mono_root)
|
|
|
|
|
|
|
|
mono_lib_path = os.path.join(mono_root, 'lib')
|
|
|
|
|
2019-11-10 17:10:38 +01:00
|
|
|
env.Append(LIBPATH=[mono_lib_path])
|
2019-04-30 13:12:02 +02:00
|
|
|
env_mono.Prepend(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0'))
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
mono_lib = find_name_in_dir_files(mono_lib_path, mono_lib_names, prefixes=['lib'], extensions=['.a'])
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
if not mono_lib:
|
|
|
|
raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
|
|
|
|
|
2019-07-03 09:16:20 +02:00
|
|
|
env_mono.Append(CPPDEFINES=['_REENTRANT'])
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
if mono_static:
|
2019-12-04 15:07:00 +01:00
|
|
|
env.Append(LINKFLAGS=['-rdynamic'])
|
|
|
|
|
2019-03-01 21:51:20 +01:00
|
|
|
mono_lib_file = os.path.join(mono_lib_path, 'lib' + mono_lib + '.a')
|
|
|
|
|
|
|
|
if is_apple:
|
2020-03-11 01:34:10 +01:00
|
|
|
if is_macos:
|
|
|
|
env.Append(LINKFLAGS=['-Wl,-force_load,' + mono_lib_file])
|
|
|
|
else:
|
|
|
|
arch = env['arch']
|
|
|
|
def copy_mono_lib(libname_wo_ext):
|
|
|
|
copy_file(mono_lib_path, '#bin', libname_wo_ext + '.a', '%s.iphone.%s.a' % (libname_wo_ext, arch))
|
|
|
|
|
|
|
|
# Copy Mono libraries to the output folder. These are meant to be bundled with
|
|
|
|
# the export templates and added to the Xcode project when exporting a game.
|
|
|
|
copy_mono_lib('lib' + mono_lib)
|
|
|
|
copy_mono_lib('libmono-native')
|
|
|
|
copy_mono_lib('libmono-profiler-log')
|
|
|
|
|
|
|
|
if not is_ios_sim:
|
|
|
|
copy_mono_lib('libmono-ee-interp')
|
|
|
|
copy_mono_lib('libmono-icall-table')
|
|
|
|
copy_mono_lib('libmono-ilgen')
|
2019-03-01 21:51:20 +01:00
|
|
|
else:
|
2019-11-10 17:10:38 +01:00
|
|
|
assert is_desktop(env['platform']) or is_android or is_javascript
|
2019-03-01 21:51:20 +01:00
|
|
|
env.Append(LINKFLAGS=['-Wl,-whole-archive', mono_lib_file, '-Wl,-no-whole-archive'])
|
2019-11-10 17:10:38 +01:00
|
|
|
|
|
|
|
if is_javascript:
|
|
|
|
env.Append(LIBS=['mono-icall-table', 'mono-native', 'mono-ilgen', 'mono-ee-interp'])
|
|
|
|
|
|
|
|
wasm_src_dir = os.path.join(mono_root, 'src')
|
|
|
|
if not os.path.isdir(wasm_src_dir):
|
|
|
|
raise RuntimeError('Could not find mono wasm src directory')
|
|
|
|
|
|
|
|
# Ideally this should be defined only for 'driver.c', but I can't fight scons for another 2 hours
|
|
|
|
env_mono.Append(CPPDEFINES=['CORE_BINDINGS'])
|
|
|
|
|
|
|
|
env_mono.add_source_files(env.modules_sources, [
|
|
|
|
os.path.join(wasm_src_dir, 'driver.c'),
|
|
|
|
os.path.join(wasm_src_dir, 'zlib-helper.c'),
|
|
|
|
os.path.join(wasm_src_dir, 'corebindings.c')
|
|
|
|
])
|
|
|
|
|
|
|
|
env.Append(LINKFLAGS=[
|
|
|
|
'--js-library', os.path.join(wasm_src_dir, 'library_mono.js'),
|
|
|
|
'--js-library', os.path.join(wasm_src_dir, 'binding_support.js'),
|
|
|
|
'--js-library', os.path.join(wasm_src_dir, 'dotnet_support.js')
|
|
|
|
])
|
2019-03-01 21:51:20 +01:00
|
|
|
else:
|
|
|
|
env.Append(LIBS=[mono_lib])
|
|
|
|
|
2020-03-11 01:34:10 +01:00
|
|
|
if is_macos:
|
2019-03-01 21:51:20 +01:00
|
|
|
env.Append(LIBS=['iconv', 'pthread'])
|
2019-05-20 18:34:35 +02:00
|
|
|
elif is_android:
|
2019-07-03 17:41:07 +02:00
|
|
|
pass # Nothing
|
2020-03-11 01:34:10 +01:00
|
|
|
elif is_ios:
|
|
|
|
pass # Nothing, linking is delegated to the exported Xcode project
|
2019-11-10 17:10:38 +01:00
|
|
|
elif is_javascript:
|
|
|
|
env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
|
2019-03-01 21:51:20 +01:00
|
|
|
else:
|
|
|
|
env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
|
|
|
|
|
|
|
|
if not mono_static:
|
2020-02-22 19:27:14 +01:00
|
|
|
mono_so_file = find_file_in_dir(mono_lib_path, mono_lib_names, prefixes=['lib'], extensions=[sharedlib_ext])
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
if not mono_so_file:
|
2019-03-01 21:51:20 +01:00
|
|
|
raise RuntimeError('Could not find mono shared library in: ' + mono_lib_path)
|
|
|
|
else:
|
|
|
|
assert not mono_static
|
|
|
|
|
|
|
|
# TODO: Add option to force using pkg-config
|
|
|
|
print('Mono root directory not found. Using pkg-config instead')
|
|
|
|
|
2019-03-01 22:00:39 +01:00
|
|
|
env.ParseConfig('pkg-config monosgen-2 --libs')
|
|
|
|
env_mono.ParseConfig('pkg-config monosgen-2 --cflags')
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
tmpenv = Environment()
|
|
|
|
tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
|
|
|
|
tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L')
|
|
|
|
|
|
|
|
for hint_dir in tmpenv['LIBPATH']:
|
2020-02-22 19:27:14 +01:00
|
|
|
file_found = find_file_in_dir(hint_dir, mono_lib_names, prefixes=['lib'], extensions=[sharedlib_ext])
|
|
|
|
if file_found:
|
2019-03-01 21:51:20 +01:00
|
|
|
mono_lib_path = hint_dir
|
2020-02-22 19:27:14 +01:00
|
|
|
mono_so_file = file_found
|
2019-03-01 21:51:20 +01:00
|
|
|
break
|
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
if not mono_so_file:
|
2019-03-01 21:51:20 +01:00
|
|
|
raise RuntimeError('Could not find mono shared library in: ' + str(tmpenv['LIBPATH']))
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
if not mono_static:
|
|
|
|
libs_output_dir = get_android_out_dir(env) if is_android else '#bin'
|
2020-02-22 19:27:14 +01:00
|
|
|
copy_file(mono_lib_path, libs_output_dir, mono_so_file)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2019-11-10 17:10:38 +01:00
|
|
|
if not tools_enabled:
|
|
|
|
if is_desktop(env['platform']):
|
|
|
|
if not mono_root:
|
|
|
|
mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
|
2019-03-01 21:51:20 +01:00
|
|
|
|
2019-11-10 17:10:38 +01:00
|
|
|
make_template_dir(env, mono_root)
|
|
|
|
elif is_android:
|
|
|
|
# Compress Android Mono Config
|
|
|
|
from . import make_android_mono_config
|
2019-12-04 15:07:00 +01:00
|
|
|
module_dir = os.getcwd()
|
|
|
|
config_file_path = os.path.join(module_dir, 'build_scripts', 'mono_android_config.xml')
|
2019-11-10 17:10:38 +01:00
|
|
|
make_android_mono_config.generate_compressed_config(config_file_path, 'mono_gd/')
|
2019-07-03 17:41:07 +02:00
|
|
|
|
2019-11-10 17:10:38 +01:00
|
|
|
# Copy the required shared libraries
|
|
|
|
copy_mono_shared_libs(env, mono_root, None)
|
|
|
|
elif is_javascript:
|
|
|
|
pass # No data directory for this platform
|
2020-03-11 01:34:10 +01:00
|
|
|
elif is_ios:
|
|
|
|
pass # No data directory for this platform
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
if copy_mono_root:
|
|
|
|
if not mono_root:
|
|
|
|
mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
|
|
|
|
|
|
|
|
if tools_enabled:
|
|
|
|
copy_mono_root_files(env, mono_root)
|
|
|
|
else:
|
2019-11-10 17:10:38 +01:00
|
|
|
print("Ignoring option: 'copy_mono_root'; only available for builds with 'tools' enabled.")
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
def make_template_dir(env, mono_root):
|
|
|
|
from shutil import rmtree
|
|
|
|
|
|
|
|
platform = env['platform']
|
|
|
|
target = env['target']
|
|
|
|
|
|
|
|
template_dir_name = ''
|
|
|
|
|
2019-11-10 17:10:38 +01:00
|
|
|
assert is_desktop(platform)
|
|
|
|
|
|
|
|
template_dir_name = 'data.mono.%s.%s.%s' % (platform, env['bits'], target)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
output_dir = Dir('#bin').abspath
|
|
|
|
template_dir = os.path.join(output_dir, template_dir_name)
|
|
|
|
|
|
|
|
template_mono_root_dir = os.path.join(template_dir, 'Mono')
|
|
|
|
|
|
|
|
if os.path.isdir(template_mono_root_dir):
|
|
|
|
rmtree(template_mono_root_dir) # Clean first
|
|
|
|
|
|
|
|
# Copy etc/mono/
|
|
|
|
|
2019-07-03 17:41:07 +02:00
|
|
|
template_mono_config_dir = os.path.join(template_mono_root_dir, 'etc', 'mono')
|
2019-11-10 17:10:38 +01:00
|
|
|
copy_mono_etc_dir(mono_root, template_mono_config_dir, platform)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
# Copy the required shared libraries
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
copy_mono_shared_libs(env, mono_root, template_mono_root_dir)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
def copy_mono_root_files(env, mono_root):
|
|
|
|
from glob import glob
|
|
|
|
from shutil import copy
|
|
|
|
from shutil import rmtree
|
|
|
|
|
|
|
|
if not mono_root:
|
|
|
|
raise RuntimeError('Mono installation directory not found')
|
|
|
|
|
|
|
|
output_dir = Dir('#bin').abspath
|
|
|
|
editor_mono_root_dir = os.path.join(output_dir, 'GodotSharp', 'Mono')
|
|
|
|
|
|
|
|
if os.path.isdir(editor_mono_root_dir):
|
|
|
|
rmtree(editor_mono_root_dir) # Clean first
|
|
|
|
|
|
|
|
# Copy etc/mono/
|
|
|
|
|
|
|
|
editor_mono_config_dir = os.path.join(editor_mono_root_dir, 'etc', 'mono')
|
|
|
|
copy_mono_etc_dir(mono_root, editor_mono_config_dir, env['platform'])
|
|
|
|
|
|
|
|
# Copy the required shared libraries
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
copy_mono_shared_libs(env, mono_root, editor_mono_root_dir)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
# Copy framework assemblies
|
|
|
|
|
|
|
|
mono_framework_dir = os.path.join(mono_root, 'lib', 'mono', '4.5')
|
|
|
|
mono_framework_facades_dir = os.path.join(mono_framework_dir, 'Facades')
|
|
|
|
|
|
|
|
editor_mono_framework_dir = os.path.join(editor_mono_root_dir, 'lib', 'mono', '4.5')
|
|
|
|
editor_mono_framework_facades_dir = os.path.join(editor_mono_framework_dir, 'Facades')
|
|
|
|
|
|
|
|
if not os.path.isdir(editor_mono_framework_dir):
|
|
|
|
os.makedirs(editor_mono_framework_dir)
|
|
|
|
if not os.path.isdir(editor_mono_framework_facades_dir):
|
|
|
|
os.makedirs(editor_mono_framework_facades_dir)
|
|
|
|
|
|
|
|
for assembly in glob(os.path.join(mono_framework_dir, '*.dll')):
|
|
|
|
copy(assembly, editor_mono_framework_dir)
|
|
|
|
for assembly in glob(os.path.join(mono_framework_facades_dir, '*.dll')):
|
|
|
|
copy(assembly, editor_mono_framework_facades_dir)
|
|
|
|
|
|
|
|
|
|
|
|
def copy_mono_etc_dir(mono_root, target_mono_config_dir, platform):
|
|
|
|
from distutils.dir_util import copy_tree
|
|
|
|
from glob import glob
|
|
|
|
from shutil import copy
|
|
|
|
|
|
|
|
if not os.path.isdir(target_mono_config_dir):
|
|
|
|
os.makedirs(target_mono_config_dir)
|
|
|
|
|
|
|
|
mono_etc_dir = os.path.join(mono_root, 'etc', 'mono')
|
|
|
|
if not os.path.isdir(mono_etc_dir):
|
|
|
|
mono_etc_dir = ''
|
|
|
|
etc_hint_dirs = []
|
|
|
|
if platform != 'windows':
|
|
|
|
etc_hint_dirs += ['/etc/mono', '/usr/local/etc/mono']
|
|
|
|
if 'MONO_CFG_DIR' in os.environ:
|
|
|
|
etc_hint_dirs += [os.path.join(os.environ['MONO_CFG_DIR'], 'mono')]
|
|
|
|
for etc_hint_dir in etc_hint_dirs:
|
|
|
|
if os.path.isdir(etc_hint_dir):
|
|
|
|
mono_etc_dir = etc_hint_dir
|
|
|
|
break
|
|
|
|
if not mono_etc_dir:
|
|
|
|
raise RuntimeError('Mono installation etc directory not found')
|
|
|
|
|
|
|
|
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'))
|
2019-05-20 18:34:35 +02:00
|
|
|
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'))
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
for file in glob(os.path.join(mono_etc_dir, '*')):
|
|
|
|
if os.path.isfile(file):
|
|
|
|
copy(file, target_mono_config_dir)
|
|
|
|
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
def copy_mono_shared_libs(env, mono_root, target_mono_root_dir):
|
2019-03-01 21:51:20 +01:00
|
|
|
from shutil import copy
|
|
|
|
|
2019-05-20 18:34:35 +02:00
|
|
|
def copy_if_exists(src, dst):
|
|
|
|
if os.path.isfile(src):
|
|
|
|
copy(src, dst)
|
|
|
|
|
|
|
|
platform = env['platform']
|
|
|
|
|
2019-03-01 21:51:20 +01:00
|
|
|
if platform == 'windows':
|
2019-11-28 23:42:37 +01:00
|
|
|
src_mono_bin_dir = os.path.join(mono_root, 'bin')
|
2019-03-01 21:51:20 +01:00
|
|
|
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)
|
|
|
|
|
2020-02-22 19:27:14 +01:00
|
|
|
mono_posix_helper_file = find_file_in_dir(src_mono_bin_dir, ['MonoPosixHelper'], prefixes=['', 'lib'], extensions=['.dll'])
|
|
|
|
copy(os.path.join(src_mono_bin_dir, mono_posix_helper_file), os.path.join(target_mono_bin_dir, 'MonoPosixHelper.dll'))
|
2019-11-19 17:22:06 +01:00
|
|
|
|
|
|
|
# For newer versions
|
2019-11-28 23:42:37 +01:00
|
|
|
btls_dll_path = os.path.join(src_mono_bin_dir, 'libmono-btls-shared.dll')
|
2019-11-19 17:22:06 +01:00
|
|
|
if os.path.isfile(btls_dll_path):
|
|
|
|
copy(btls_dll_path, target_mono_bin_dir)
|
2019-03-01 21:51:20 +01:00
|
|
|
else:
|
2019-05-20 18:34:35 +02:00
|
|
|
target_mono_lib_dir = get_android_out_dir(env) if platform == 'android' else os.path.join(target_mono_root_dir, 'lib')
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
if not os.path.isdir(target_mono_lib_dir):
|
|
|
|
os.makedirs(target_mono_lib_dir)
|
|
|
|
|
2019-12-18 08:39:37 +01:00
|
|
|
lib_file_names = []
|
2019-03-01 21:51:20 +01:00
|
|
|
if platform == 'osx':
|
2019-12-18 08:39:37 +01:00
|
|
|
lib_file_names = [lib_name + '.dylib' for lib_name in [
|
|
|
|
'libmono-btls-shared', 'libmono-native-compat', 'libMonoPosixHelper'
|
|
|
|
]]
|
2019-11-10 17:10:38 +01:00
|
|
|
elif is_unix_like(platform):
|
2019-05-20 18:34:35 +02:00
|
|
|
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'
|
|
|
|
]]
|
|
|
|
|
2019-12-18 08:39:37 +01:00
|
|
|
for lib_file_name in lib_file_names:
|
|
|
|
copy_if_exists(os.path.join(mono_root, 'lib', lib_file_name), target_mono_lib_dir)
|
2019-03-01 21:51:20 +01:00
|
|
|
|
|
|
|
def pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext):
|
|
|
|
tmpenv = Environment()
|
|
|
|
tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
|
|
|
|
tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L')
|
|
|
|
for hint_dir in tmpenv['LIBPATH']:
|
2020-02-22 19:27:14 +01:00
|
|
|
name_found = find_name_in_dir_files(hint_dir, mono_lib_names, prefixes=['lib'], extensions=[sharedlib_ext])
|
2019-03-01 21:51:20 +01:00
|
|
|
if name_found and os.path.isdir(os.path.join(hint_dir, '..', 'include', 'mono-2.0')):
|
|
|
|
return os.path.join(hint_dir, '..')
|
|
|
|
return ''
|