author Eugen Sawin <>
Fri, 30 Jun 2017 10:37:27 -0700
changeset 415774 8c0a3de985d41f7fad4118e30a011659b01e8e3a
parent 404833 1b48b5adae0bbd2aae798166197ee2d44e0eb08b
child 431699 fc5b1c09a348358cbb25b0e5ed82de73b86a0aeb
permissions -rw-r--r--
Bug 1318247 - [1.0] Add custom refcounting of zips in ZipCollection to allow for thread-safe reuse of zips. r=glandium

# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at

js_option('--with-android-ndk', nargs=1,
          help='location where the Android NDK can be found')

js_option('--with-android-toolchain', nargs=1,
          help='location of the Android toolchain')

js_option('--with-android-gnu-compiler-version', nargs=1,
          help='GNU compiler version to use')

def min_android_version(target):
    if target.cpu in ['aarch64', 'x86_64', 'mips64']:
        # 64-bit support was added in API 21.
        return '21'
    return '9'

          help='android platform version',

@depends('--with-android-version', min_android_version)
@imports(_from='__builtin__', _import='ValueError')
def android_version(value, min_version):
    if not value:
        # Someone has passed --without-android-version.
        die('--with-android-version cannot be disabled.')

        version = int(value[0])
    except ValueError:
        die('--with-android-version expects an integer value')

    if version < int(min_version):
        die('--with-android-version must be at least %s (got %s)',
            min_version, value[0])

    return version

add_old_configure_assignment('android_version', android_version)

@depends('--with-android-ndk', build_project)
def ndk(value, build_project):
    if build_project == 'mobile/android' and not value:
        die('You must specify --with-android-ndk=/path/to/ndk when '
            'building mobile/android')
    if value:
        return value[0]

set_config('ANDROID_NDK', ndk)
add_old_configure_assignment('android_ndk', ndk)

@checking('for android ndk version')
@imports(_from='__builtin__', _import='open')
def ndk_version(ndk):
    if not ndk:
        # Building 'js/src' for non-Android.
    with open(os.path.join(ndk, ''), 'r') as f:
        for line in f:
            if not line.startswith('Pkg.Revision'):
            (_, version) = line.split('=')
            if version:
                return version.strip()
            die('Unexpected Pkg.Revision line in')
    die('Cannot determine NDK version from')

def ndk_major_version(ndk_version):
    if not ndk_version:
        # Building 'js/src' for non-Android.
    (major, minor, revision) = ndk_version.split('.')
    if major:
        return major
    die('Unexpected NDK version string: ' + ndk_version)

set_config('ANDROID_NDK_MAJOR_VERSION', ndk_major_version);

def ndk_minor_version(ndk_version):
    if not ndk_version:
        # Building 'js/src' for non-Android.
    (major, minor, revision) = ndk_version.split('.')
    if minor:
        return minor
    die('Unexpected NDK version string: ' + ndk_version)

set_config('ANDROID_NDK_MINOR_VERSION', ndk_minor_version);

@depends(target, android_version, ndk)
@checking('for android platform directory')
@imports(_from='os.path', _import='isdir')
def android_platform(target, android_version, ndk):
    if target.os != 'Android':

    if 'mips' in target.cpu:
        target_dir_name = 'mips'
    elif 'aarch64' == target.cpu:
        target_dir_name = 'arm64'
        target_dir_name = target.cpu

    # Not all Android releases have their own platform release. We use
    # the next lower platform version in these cases.
    if android_version in (11, 10):
        platform_version = 9
    elif android_version in (20, 22):
        platform_version = android_version - 1
        platform_version = android_version

    platform_dir = os.path.join(ndk,
                                'android-%s' % platform_version,
                                'arch-%s' % target_dir_name)

    if not isdir(platform_dir):
        die("Android platform directory not found. With the current "
            "configuration, it should be in %s" % platform_dir)

    return platform_dir

add_old_configure_assignment('android_platform', android_platform)

def extra_toolchain_flags(platform_dir):
    if not platform_dir:
        return []
    return ['-idirafter',
            os.path.join(platform_dir, 'usr', 'include')]

@depends(target, host, ndk, '--with-android-toolchain',
@checking('for the Android toolchain directory', lambda x: x or 'not found')
@imports(_from='os.path', _import='isdir')
@imports(_from='mozbuild.shellutil', _import='quote')
def android_toolchain(target, host, ndk, toolchain, gnu_compiler_version):
    if not ndk:
    if toolchain:
        return toolchain[0]
        if target.cpu == 'arm' and target.endianness == 'little':
            target_base = 'arm-linux-androideabi'
        elif target.cpu == 'x86':
            target_base = 'x86'
        elif target.cpu == 'mips32' and target.endianness == 'little':
            target_base = 'mipsel-linux-android'
        elif target.cpu == 'aarch64' and target.endianness == 'little':
            target_base = 'aarch64-linux-android'
            die('Target cpu is not supported.')

        toolchain_format = '%s/toolchains/%s-%s/prebuilt/%s-%s'

        for version in gnu_compiler_version or ['4.9', '4.8', '4.7']:
            toolchain = toolchain_format % (ndk, target_base, version,
                                            host.kernel.lower(), host.cpu)
            log.debug('Trying %s' % quote(toolchain))
            if not isdir(toolchain) and host.cpu == 'x86_64':
                toolchain = toolchain_format % (ndk, target_base, version,
                                                host.kernel.lower(), 'x86')
                log.debug('Trying %s' % quote(toolchain))
            if isdir(toolchain):
                return toolchain
            if gnu_compiler_version:
                die('Your --with-android-gnu-compiler-version may be wrong')
            die('You have to specify --with-android-toolchain='

set_config('ANDROID_TOOLCHAIN', android_toolchain)

@depends(target, android_toolchain)
def android_toolchain_prefix(target, toolchain):
    if toolchain:
        if target.cpu == 'x86':
            # Ideally, the --target should just have the right x86 variant
            # in the first place.
            return '%s/bin/i686-linux-android-' % toolchain
        return '%s/bin/%s-' % (toolchain, target.toolchain)

imply_option('--with-toolchain-prefix', android_toolchain_prefix,