def main(args): parser = argparse.ArgumentParser( description='Set up an Android cross build', epilog='Additional arguments will be passed to gyp_crashpad.py.') parser.add_argument('--arch', required=True, help='Target architecture') parser.add_argument('--api-level', required=True, help='Target API level') parser.add_argument('--ndk', required=True, help='Standalone NDK toolchain') (parsed, extra_command_line_args) = parser.parse_known_args(args) SYS_PLATFORM_TO_NDK_HOST_ARCH = { 'cygwin': 'windows-x86_64', 'darwin': 'darwin-x86_64', 'linux': 'linux-x86_64', 'linux2': 'linux-x86_64', 'darwin': 'darwin-x86_64', 'win32': 'windows-x86_64', } ndk_host_arch = SYS_PLATFORM_TO_NDK_HOST_ARCH[sys.platform] ndk_bin_dir = os.path.join(parsed.ndk, 'toolchains', 'llvm', 'prebuilt', ndk_host_arch, 'bin') if not os.path.exists(ndk_bin_dir): parser.error("missing toolchain") ARCH_TO_ARCH_TRIPLET = { 'arm': 'armv7a-linux-androideabi', 'arm64': 'aarch64-linux-android', 'ia32': 'i686-linux-android', 'x64': 'x86_64-linux-android', } clang_prefix = ARCH_TO_ARCH_TRIPLET[parsed.arch] + parsed.api_level os.environ['CC_target'] = os.path.join(ndk_bin_dir, clang_prefix + '-clang') os.environ['CXX_target'] = os.path.join(ndk_bin_dir, clang_prefix + '-clang++') extra_args = ['-D', 'android_api_level=' + parsed.api_level] # ARM only includes 'v7a' in the tool prefix for clang tool_prefix = ('arm-linux-androideabi' if parsed.arch == 'arm' else ARCH_TO_ARCH_TRIPLET[parsed.arch]) for tool in ('ar', 'nm', 'readelf'): os.environ['%s_target' % tool.upper()] = (os.path.join( ndk_bin_dir, '%s-%s' % (tool_prefix, tool))) return gyp_crashpad.main([ '-D', 'OS=android', '-D', 'target_arch=%s' % parsed.arch, '-D', 'clang=1', '-f', 'ninja-android' ] + extra_args + extra_command_line_args)
def main(args): parser = argparse.ArgumentParser( description='Set up an Android cross build', epilog='Additional arguments will be passed to gyp_crashpad.py.') parser.add_argument('--ndk', required=True, help='Standalone NDK toolchain') parser.add_argument('--compiler', default='clang', choices=('clang', 'gcc'), help='The compiler to use, clang by default') (parsed, extra_command_line_args) = parser.parse_known_args(args) NDK_ERROR = ( 'NDK must be a valid standalone NDK toolchain.\n' + 'See https://developer.android.com/ndk/guides/standalone_toolchain.html' ) arch_dirs = glob.glob(os.path.join(parsed.ndk, '*-linux-android*')) if len(arch_dirs) != 1: parser.error(NDK_ERROR) arch_triplet = os.path.basename(arch_dirs[0]) ARCH_TRIPLET_TO_ARCH = { 'arm-linux-androideabi': 'arm', 'aarch64-linux-android': 'arm64', 'i686-linux-android': 'x86', 'x86_64-linux-android': 'x86_64', 'mipsel-linux-android': 'mips', 'mips64el-linux-android': 'mips64', } if arch_triplet not in ARCH_TRIPLET_TO_ARCH: parser.error(NDK_ERROR) arch = ARCH_TRIPLET_TO_ARCH[arch_triplet] ndk_bin_dir = os.path.join(parsed.ndk, 'bin') clang_path = os.path.join(ndk_bin_dir, 'clang') extra_args = [] if parsed.compiler == 'clang': os.environ['CC_target'] = clang_path os.environ['CXX_target'] = os.path.join(ndk_bin_dir, 'clang++') elif parsed.compiler == 'gcc': os.environ['CC_target'] = os.path.join(ndk_bin_dir, '%s-gcc' % arch_triplet) os.environ['CXX_target'] = os.path.join(ndk_bin_dir, '%s-g++' % arch_triplet) # Unlike the Clang build, when using GCC with “unified headers,” # __ANDROID_API__ isn’t set automatically and must be pushed in to the # build. Fish the correct value out of the Clang wrapper script. If unified # headers are not being used, the Clang wrapper won’t mention # __ANDROID_API__, but the standalone toolchain’s <android/api-level.h> will # #define it for both Clang and GCC. # # Unified headers are the way of the future, according to # https://android.googlesource.com/platform/ndk/+/ndk-r14/CHANGELOG.md and # https://android.googlesource.com/platform/ndk/+/master/docs/UnifiedHeaders.md. with open(clang_path, 'r') as file: clang_script_contents = file.read() matches = re.finditer(r'\s-D__ANDROID_API__=([\d]+)\s', clang_script_contents) match = next(matches, None) if match: android_api = int(match.group(1)) extra_args.extend(['-D', 'android_api_level=%d' % android_api]) if next(matches, None): raise AssertionError('__ANDROID_API__ defined too many times') for tool in ('ar', 'nm', 'readelf'): os.environ['%s_target' % tool.upper()] = (os.path.join( ndk_bin_dir, '%s-%s' % (arch_triplet, tool))) return gyp_crashpad.main([ '-D', 'OS=android', '-D', 'target_arch=%s' % arch, '-D', 'clang=%d' % (1 if parsed.compiler == 'clang' else 0), '-f', 'ninja-android' ] + extra_args + extra_command_line_args)
def main(args): parser = argparse.ArgumentParser( description='Set up an Android cross build', epilog='Additional arguments will be passed to gyp_crashpad.py.') parser.add_argument('--ndk', required=True, help='Standalone NDK toolchain') parser.add_argument('--compiler', default='clang', choices=('clang', 'gcc'), help='The compiler to use, clang by default') (parsed, extra_command_line_args) = parser.parse_known_args(args) NDK_ERROR=( 'NDK must be a valid standalone NDK toolchain.\n' + 'See https://developer.android.com/ndk/guides/standalone_toolchain.html') arch_dirs = glob.glob(os.path.join(parsed.ndk, '*-linux-android*')) if len(arch_dirs) != 1: parser.error(NDK_ERROR) arch_triplet = os.path.basename(arch_dirs[0]) ARCH_TRIPLET_TO_ARCH = { 'arm-linux-androideabi': 'arm', 'aarch64-linux-android': 'arm64', 'i686-linux-android': 'ia32', 'x86_64-linux-android': 'x64', 'mipsel-linux-android': 'mips', 'mips64el-linux-android': 'mips64', } if arch_triplet not in ARCH_TRIPLET_TO_ARCH: parser.error(NDK_ERROR) arch = ARCH_TRIPLET_TO_ARCH[arch_triplet] ndk_bin_dir = os.path.join(parsed.ndk, 'bin') clang_path = os.path.join(ndk_bin_dir, 'clang') extra_args = [] if parsed.compiler == 'clang': os.environ['CC_target'] = clang_path os.environ['CXX_target'] = os.path.join(ndk_bin_dir, 'clang++') elif parsed.compiler == 'gcc': os.environ['CC_target'] = os.path.join(ndk_bin_dir, '%s-gcc' % arch_triplet) os.environ['CXX_target'] = os.path.join(ndk_bin_dir, '%s-g++' % arch_triplet) # Unlike the Clang build, when using GCC with “unified headers,” # __ANDROID_API__ isn’t set automatically and must be pushed in to the # build. Fish the correct value out of the Clang wrapper script. If unified # headers are not being used, the Clang wrapper won’t mention # __ANDROID_API__, but the standalone toolchain’s <android/api-level.h> will # #define it for both Clang and GCC. # # Unified headers are the way of the future, according to # https://android.googlesource.com/platform/ndk/+/ndk-r14/CHANGELOG.md and # https://android.googlesource.com/platform/ndk/+/master/docs/UnifiedHeaders.md. with open(clang_path, 'r') as file: clang_script_contents = file.read() matches = re.finditer(r'\s-D__ANDROID_API__=([\d]+)\s', clang_script_contents) match = next(matches, None) if match: android_api = int(match.group(1)) extra_args.extend(['-D', 'android_api_level=%d' % android_api]) if next(matches, None): raise AssertionError('__ANDROID_API__ defined too many times') for tool in ('ar', 'nm', 'readelf'): os.environ['%s_target' % tool.upper()] = ( os.path.join(ndk_bin_dir, '%s-%s' % (arch_triplet, tool))) return gyp_crashpad.main( ['-D', 'OS=android', '-D', 'target_arch=%s' % arch, '-D', 'clang=%d' % (1 if parsed.compiler == 'clang' else 0), '-f', 'ninja-android'] + extra_args + extra_command_line_args)