diff --git a/android.py b/android.py index 2c9e428..7c72643 100755 --- a/android.py +++ b/android.py @@ -332,7 +332,7 @@ def setup_android_cross_template(env: dict, opts: AndroidOpts, target: str, host ] # Runtime cross template - runtime.setup_runtime_cross_template(env, opts, 'android', target, host_triple, target_triple, device_target, 'llvm-llvm64', offsets_dumper_abi) + runtime.setup_runtime_cross_template(env, opts, 'android', target, host_triple, target_triple, device_target, 'llvm64', offsets_dumper_abi) def setup_android_cross_mxe_template(env: dict, opts: AndroidOpts, target: str, host_arch: str): @@ -399,7 +399,7 @@ def setup_android_cross_mxe_template(env: dict, opts: AndroidOpts, target: str, env['_android-%s_CONFIGURE_FLAGS' % target] = CONFIGURE_FLAGS # Runtime cross template - runtime.setup_runtime_cross_template(env, opts, 'android', target, host_triple, target_triple, device_target, 'llvm-llvmwin64', offsets_dumper_abi) + runtime.setup_runtime_cross_template(env, opts, 'android', target, host_triple, target_triple, device_target, 'llvmwin64', offsets_dumper_abi) def make_standalone_toolchain(opts: AndroidOpts, target: str, api: str): @@ -461,6 +461,7 @@ def make(opts: AndroidOpts, product: str, target: str): 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, env['ANDROID_API_VERSION']) diff --git a/bcl.py b/bcl.py index d1d8eac..e4de5b8 100755 --- a/bcl.py +++ b/bcl.py @@ -3,6 +3,7 @@ import os import os.path +import sys from os.path import join as path_join from options import * @@ -141,9 +142,12 @@ def main(raw_args): opts = bcl_opts_from_args(args) products = args.product - for product in products: - action = actions[args.action] - action(opts, product) + try: + for product in products: + action = actions[args.action] + action(opts, product) + except BuildError as e: + sys.exit(e.message) if __name__ == '__main__': diff --git a/desktop.py b/desktop.py index cdfac69..16542ac 100755 --- a/desktop.py +++ b/desktop.py @@ -10,6 +10,7 @@ from options import * from os_utils import * import runtime + # TODO: mono cross-compilers target_platforms = ['linux', 'windows', 'osx'] @@ -26,13 +27,42 @@ host_triples = { 'osx': '%s-apple-darwin', } +llvm_table = { + 'linux': { + 'i686': 'llvm32', + 'x86_64': 'llvm64' + }, + 'windows': { + 'i686': 'llvm32', + 'x86_64': 'llvm64' + }, + 'osx': { + 'x86_64': 'llvm64' + } +} + def is_cross_compiling(target_platform: str) -> bool: return (sys.platform == 'darwin' and target_platform != 'osx') or \ (sys.platform in ['linux', 'linux2', 'cygwin'] and target_platform != 'linux') -def setup_desktop_template(env: dict, opts: RuntimeOpts, product: str, target_platform: str, target: str): +def get_osxcross_sdk(target, osxcross_bin): + osxcross_sdk = os.environ.get('OSXCROSS_SDK', 14) + + 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 + + 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_desktop_template(env: dict, opts: DesktopOpts, product: str, target_platform: str, target: str): host_triple = host_triples[target_platform] % target CONFIGURE_FLAGS = [ @@ -52,37 +82,62 @@ def setup_desktop_template(env: dict, opts: RuntimeOpts, product: str, target_pl env['_%s-%s_PATH' % (product, target)] = mxe_bin - name_fmt = target + '-w64-mingw32-%s' + name_fmt = path_join(mxe_bin, target + '-w64-mingw32-%s') - env['_%s-%s_AR' % (product, target)] = path_join(mxe_bin, name_fmt % 'ar') - env['_%s-%s_AS' % (product, target)] = path_join(mxe_bin, name_fmt % 'as') - env['_%s-%s_CC' % (product, target)] = path_join(mxe_bin, name_fmt % 'gcc') - env['_%s-%s_CXX' % (product, target)] = path_join(mxe_bin, name_fmt % 'g++') - env['_%s-%s_DLLTOOL' % (product, target)] = path_join(mxe_bin, name_fmt % 'dlltool') - env['_%s-%s_LD' % (product, target)] = path_join(mxe_bin, name_fmt % 'ld') - env['_%s-%s_OBJDUMP' % (product, target)] = path_join(mxe_bin, name_fmt % 'objdump') - env['_%s-%s_RANLIB' % (product, target)] = path_join(mxe_bin, name_fmt % 'ranlib') - env['_%s-%s_STRIP' % (product, target)] = path_join(mxe_bin, name_fmt % 'strip') + 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 % 'gcc' + env['_%s-%s_CXX' % (product, target)] = name_fmt % 'g++' + env['_%s-%s_DLLTOOL' % (product, target)] = name_fmt % 'dlltool' + env['_%s-%s_LD' % (product, target)] = name_fmt % 'ld' + env['_%s-%s_OBJDUMP' % (product, target)] = name_fmt % 'objdump' + env['_%s-%s_RANLIB' % (product, target)] = name_fmt % 'ranlib' + env['_%s-%s_STRIP' % (product, target)] = name_fmt % 'strip' CONFIGURE_FLAGS += [ '--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) + + env['_%s-%s_PATH' % (product, target)] = osxcross_bin + + 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_CONFIGURE_FLAGS' % (product, target)] = CONFIGURE_FLAGS - runtime.setup_runtime_template(env, opts, product, target, host_triple) + llvm = llvm_table[target_platform][target] if opts.with_llvm else '' + + runtime.setup_runtime_template(env, opts, product, target, host_triple, llvm=llvm) -def strip_libs(opts: RuntimeOpts, product: str, target_platform: str, target: str): +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 = target + '-w64-mingw32-%s' - strip = path_join(mxe_bin, name_fmt % 'strip') + name_fmt = path_join(mxe_bin, target + '-w64-mingw32-%s') + strip = name_fmt % 'strip' elif target_platform == 'osx': - assert False # TODO osxcross + 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) + + name_fmt = path_join(osxcross_bin, target + ('-apple-darwin%s-' % osxcross_sdk) + '%s') + strip = name_fmt % 'strip' else: strip = 'strip' @@ -101,7 +156,7 @@ def strip_libs(opts: RuntimeOpts, product: str, target_platform: str, target: st run_command(strip, args=['--strip-unneeded'] + dll_files, name='strip') -def configure(opts: RuntimeOpts, product: str, target_platform: str, target: str): +def configure(opts: DesktopOpts, product: str, target_platform: str, target: str): env = {} setup_desktop_template(env, opts, product, target_platform, target) @@ -112,7 +167,7 @@ def configure(opts: RuntimeOpts, product: str, target_platform: str, target: str runtime.run_configure(env, opts, product, target) -def make(opts: RuntimeOpts, product: str, target_platform: str, target: str): +def make(opts: DesktopOpts, product: str, target_platform: str, target: str): build_dir = path_join(opts.configure_dir, '%s-%s-%s' % (product, target, opts.configuration)) make_args = ['-C', build_dir] @@ -121,12 +176,13 @@ def make(opts: RuntimeOpts, product: str, target_platform: str, target: str): 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: strip_libs(opts, product, target_platform, target) -def clean(opts: RuntimeOpts, product: str, target_platform: str, target: str): +def clean(opts: DesktopOpts, product: str, target_platform: 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)), @@ -153,6 +209,7 @@ def main(raw_args): target_platform_subparser = subparsers.add_parser(target_platform) target_platform_subparser.add_argument('action', choices=['configure', 'make', 'clean']) target_platform_subparser.add_argument('--target', choices=targets[target_platform], action='append', required=True) + target_platform_subparser.add_argument('--with-llvm', action='store_true', default=False, help=default_help) cmd_utils.add_runtime_arguments(parser, default_help) @@ -162,14 +219,14 @@ def main(raw_args): input_target_platform = args.platform input_targets = args.target - opts = runtime_opts_from_args(args) + opts = desktop_opts_from_args(args) if not os.path.isdir(opts.mono_source_root): print('Mono sources directory not found: ' + opts.mono_source_root) sys.exit(1) - if is_cross_compiling(input_target_platform) and input_target_platform == 'osx': - raise RuntimeError('Cross-compiling for macOS is not currently supported') # TODO: osxcross + if input_target_platform == 'osx' and sys.platform != 'darwin' and not 'OSXCROSS_ROOT' in os.environ: + raise RuntimeError('The \'OSXCROSS_ROOT\' environment variable is required for cross-compiling to macOS') if is_cross_compiling(input_target_platform) and sys.platform == 'darwin': raise RuntimeError('Cross-compiling from macOS is not supported') diff --git a/llvm.py b/llvm.py index 5da7563..edb0bdf 100755 --- a/llvm.py +++ b/llvm.py @@ -8,8 +8,11 @@ from options import * from os_utils import * -target_values = ['llvm64', 'llvmwin64'] -mxe_targets = {'llvmwin64': {'arch': 'x86_64', 'mxe': 'mxe-Win64'}} +target_values = ['llvm32', 'llvm64', 'llvmwin32', 'llvmwin64'] +mxe_targets = { + 'llvmwin32': {'arch': 'i686', 'mxe': 'mxe-Win32'}, + 'llvmwin64': {'arch': 'x86_64', 'mxe': 'mxe-Win64'} +} def make(opts: BaseOpts, target: str): @@ -55,6 +58,9 @@ def make(opts: BaseOpts, target: str): dst_file='%s/external/llvm/cmake/modules/%s.cmake' % (opts.mono_source_root, mxe) ) + if target in ['llvm32', 'llvmwin32']: + CMAKE_ARGS += ['-DLLVM_BUILD_32_BITS=On'] + CMAKE_ARGS += [os.environ.get('llvm-%s_CMAKE_ARGS' % target, '')] make_args = [ @@ -108,9 +114,12 @@ def main(raw_args): opts = base_opts_from_args(args) targets = args.target - for target in targets: - action = { 'make': make, 'clean': clean }[args.action] - action(opts, target) + try: + for target in targets: + action = { 'make': make, 'clean': clean }[args.action] + action(opts, target) + except BuildError as e: + sys.exit(e.message) if __name__ == '__main__': diff --git a/options.py b/options.py index 54d4438..fbc2a39 100644 --- a/options.py +++ b/options.py @@ -31,6 +31,11 @@ class AndroidOpts(RuntimeOpts): toolchain_name_fmt: str = '%s-api%s-clang' +@dataclass +class DesktopOpts(RuntimeOpts): + with_llvm: bool + + @dataclass class BclOpts(BaseOpts): tests: bool @@ -77,3 +82,10 @@ def bcl_opts_from_args(args): **vars(base_opts_from_args(args)), tests = args.tests ) + + +def desktop_opts_from_args(args): + return DesktopOpts( + **vars(runtime_opts_from_args(args)), + with_llvm = args.with_llvm + ) diff --git a/reference_assemblies.py b/reference_assemblies.py index 5d05438..2669b73 100755 --- a/reference_assemblies.py +++ b/reference_assemblies.py @@ -1,5 +1,7 @@ #!/usr/bin/python +import sys + from os.path import join as path_join from options import * from os_utils import * @@ -53,8 +55,11 @@ def main(raw_args): opts = base_opts_from_args(args) - action = actions[args.action] - action(opts) + try: + action = actions[args.action] + action(opts) + except BuildError as e: + sys.exit(e.message) if __name__ == '__main__': diff --git a/runtime.py b/runtime.py index 27443d8..7b5b8ce 100644 --- a/runtime.py +++ b/runtime.py @@ -6,7 +6,7 @@ from options import RuntimeOpts from os_utils import * -def setup_runtime_template(env: dict, opts: RuntimeOpts, product: str, target: str, host_triple: str): +def setup_runtime_template(env: dict, opts: RuntimeOpts, product: str, target: str, host_triple: str, llvm: str=''): BITNESS = '' if any(s in host_triple for s in ['i686', 'i386']): BITNESS = '-m32' @@ -83,6 +83,9 @@ def setup_runtime_template(env: dict, opts: RuntimeOpts, product: str, target: s CONFIGURE_FLAGS += env.get('_%s-%s_CONFIGURE_FLAGS' % (product, target), []) CONFIGURE_FLAGS += env.get('%s-%s_CONFIGURE_FLAGS' % (product, target), []) + if llvm: + CONFIGURE_FLAGS += ['--with-llvm=%s/llvm-%s' % (opts.install_dir, llvm)] + env['_runtime_%s-%s_AC_VARS' % (product, target)] = AC_VARS env['_runtime_%s-%s_CONFIGURE_ENVIRONMENT' % (product, target)] = CONFIGURE_ENVIRONMENT env['_runtime_%s-%s_CONFIGURE_FLAGS' % (product, target)] = CONFIGURE_FLAGS @@ -93,7 +96,7 @@ def setup_runtime_cross_template(env: dict, opts: RuntimeOpts, product: str, tar CONFIGURE_FLAGS = [ '--target=%s' % target_triple, '--with-cross-offsets=%s.h' % target_triple, - '--with-llvm=%s/%s' % (opts.install_dir, llvm) + '--with-llvm=%s/llvm-%s' % (opts.install_dir, llvm) ] env['_cross-runtime_%s-%s_CONFIGURE_FLAGS' % (product, target)] = CONFIGURE_FLAGS diff --git a/wasm.py b/wasm.py index 50c0d8f..e6f65b7 100755 --- a/wasm.py +++ b/wasm.py @@ -137,6 +137,7 @@ def make(opts: RuntimeOpts, product: str, target: str): run_command('emmake', args=['make'] + make_args, env=make_env, name='make') run_command('make', args=['-C', '%s/mono' % build_dir, 'install'], name='make install mono') + run_command('make', args=['-C', '%s/data' % build_dir, 'install'], name='make install data') # Copy support headers