From 2e9e78f4e8f9cfe4eeaba79f92fbcc5605a70c7b Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Tue, 7 Apr 2020 19:27:27 +0200 Subject: [PATCH] Fix '--osx-toolchain' being ignored, added OSXCross LD_LIBRARY_PATH wrapper --- desktop.py | 9 ++++++--- ios.py | 28 ++++++++++------------------ options.py | 4 +++- os_utils.py | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/desktop.py b/desktop.py index 14ca4b0..1fe70f0 100755 --- a/desktop.py +++ b/desktop.py @@ -101,12 +101,15 @@ def setup_desktop_template(env: dict, opts: DesktopOpts, product: str, target_pl 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) + osx_toolchain_path = path_join(osxcross_root, 'target') + osxcross_bin = path_join(osx_toolchain_path, 'bin') + osx_triple_abi = 'darwin%s' % get_osxcross_sdk(osxcross_bin, arch=target) # TODO: Replace with '--osx-triple-abi' as in ios.py env['_%s-%s_PATH' % (product, target)] = osxcross_bin - name_fmt = path_join(osxcross_bin, target + ('-apple-darwin%s-' % osxcross_sdk) + '%s') + wrapper_path = create_osxcross_wrapper(opts, product, target, osx_toolchain_path) + name_fmt = path_join(osxcross_bin, target + '-apple-' + osx_triple_abi + '-%s') + name_fmt = "%s %s" % (wrapper_path, name_fmt) env['_%s-%s_AR' % (product, target)] = name_fmt % 'ar' env['_%s-%s_AS' % (product, target)] = name_fmt % 'as' diff --git a/ios.py b/ios.py index 167fc55..f0fe6aa 100755 --- a/ios.py +++ b/ios.py @@ -64,7 +64,9 @@ def setup_ios_device_template(env: dict, opts: iOSOpts, target: str): tools_path = path_join(opts.ios_toolchain_path, 'usr', 'bin') if sys.platform != 'darwin': + wrapper_path = create_osxcross_wrapper(opts, 'ios', target, opts.ios_toolchain_path) name_fmt = path_join(tools_path, osxcross_tool_triple + '-%s') + name_fmt = "%s %s" % (wrapper_path, name_fmt) else: name_fmt = path_join(tools_path, '%s') @@ -190,7 +192,9 @@ def setup_ios_simulator_template(env: dict, opts: iOSOpts, target: str): tools_path = path_join(opts.ios_toolchain_path, 'usr', 'bin') if sys.platform != 'darwin': + wrapper_path = create_osxcross_wrapper(opts, 'ios', target, opts.ios_toolchain_path) name_fmt = path_join(tools_path, osxcross_tool_triple + '-%s') + name_fmt = "%s %s" % (wrapper_path, name_fmt) else: name_fmt = path_join(tools_path, '%s') @@ -297,17 +301,6 @@ class iOSCrossTable: } -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] @@ -335,16 +328,14 @@ def setup_ios_cross_template(env: dict, opts: iOSOpts, target: str, host_arch: s 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) + osxcross_root = opts.osx_toolchain_path + osxcross_bin = path_join(osxcross_root, 'bin') env['_ios-%s_PATH' % target] = osxcross_bin - name_fmt = path_join(osxcross_bin, target + ('-apple-darwin%s-' % osxcross_sdk) + '%s') + wrapper_path = create_osxcross_wrapper(opts, 'ios', target, opts.osx_toolchain_path) + name_fmt = path_join(osxcross_bin, target + '-apple-' + opts.osx_triple_abi + '-%s') + name_fmt = "%s %s" % (wrapper_path, name_fmt) else: tools_path = path_join(opts.osx_toolchain_path, 'usr', 'bin') name_fmt = path_join(tools_path, '%s') @@ -482,6 +473,7 @@ def main(raw_args): 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) + parser.add_argument('--osx-triple-abi', default='darwin18', help=default_help) cmd_utils.add_runtime_arguments(parser, default_help) diff --git a/options.py b/options.py index 7c0424d..03058a7 100755 --- a/options.py +++ b/options.py @@ -38,6 +38,7 @@ class iOSOpts(RuntimeOpts): ios_version_min: str osx_toolchain_path: str osx_sdk_path: str + osx_triple_abi: str @dataclass @@ -94,7 +95,8 @@ def ios_opts_from_args(args): 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 '' + osx_sdk_path = abspath(args.osx_sdk) if args.ios_sdk else '', + osx_triple_abi = args.osx_triple_abi ) diff --git a/os_utils.py b/os_utils.py index 310597d..9ef401c 100755 --- a/os_utils.py +++ b/os_utils.py @@ -1,6 +1,7 @@ import os import os.path +from options import * class BuildError(Exception): @@ -148,3 +149,36 @@ def xcrun_find_sdk(sdk_name): return '' sdk_path = xcrun_output return sdk_path + + +def chmod_plus_x(file): + import os + import stat + umask = os.umask(0) + os.umask(umask) + st = os.stat(file) + os.chmod(file, st.st_mode | ((stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) & ~umask)) + + +def create_osxcross_wrapper(opts: RuntimeOpts, product: str, target: str, toolchain_path : str): + # OSXCROSS toolchain executables use rpath to locate the toolchain's shared libraries. + # However, when moving the toolchain without care, the rpaths can be broken. + # Since fixing the rpaths can be tedious, we use this wrapper to override LD_LIBRARY_PATH. + # The reason we don't just run configure and make with LD_LIBRARY_PATH is because + # we want the resulting configuration to be independent from out python scripts. + + wrapper_src = """#!/bin/bash +LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:%s" $1 "$@" +""" % os.path.join(toolchain_path, 'lib') + + build_dir = os.path.join(opts.configure_dir, '%s-%s-%s' % (product, target, opts.configuration)) + wrapper_path = os.path.join(build_dir, 'osxcross_cmd_wrapper.sh') + + mkdir_p(build_dir) + + with open(wrapper_path, 'w') as f: + f.write(wrapper_src) + + chmod_plus_x(wrapper_path) + + return wrapper_path