gecko-dev/build/moz.configure/android-ndk.configure

403 строки
13 KiB
Python

# -*- 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 http://mozilla.org/MPL/2.0/.
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')
option('--with-android-googlevr-sdk', nargs=1,
help='location of the Android GoogleVR SDK')
@depends(target)
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'
js_option('--with-android-version',
nargs=1,
help='android platform version',
default=min_android_version)
@depends('--with-android-version', min_android_version, '--help')
@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.')
try:
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, '--help')
def ndk(value, build_project, help):
if help:
return
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)
@depends(ndk)
@checking('for android ndk version')
@imports(_from='__builtin__', _import='open')
def ndk_version(ndk):
if not ndk:
# Building 'js/src' for non-Android.
return
with open(os.path.join(ndk, 'source.properties'), 'r') as f:
for line in f:
if not line.startswith('Pkg.Revision'):
continue
(_, version) = line.split('=')
if version:
return version.strip()
die('Unexpected Pkg.Revision line in source.properties')
die('Cannot determine NDK version from source.properties')
@depends(ndk_version)
def ndk_major_version(ndk_version):
if not ndk_version:
# Building 'js/src' for non-Android.
return
(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)
@depends(ndk_version)
def ndk_minor_version(ndk_version):
if not ndk_version:
# Building 'js/src' for non-Android.
return
(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, '--help')
@checking('for android platform directory')
@imports(_from='os.path', _import='isdir')
def android_platform(target, android_version, ndk, _):
if target.os != 'Android':
return
if 'mips' in target.cpu:
target_dir_name = 'mips'
elif 'aarch64' == target.cpu:
target_dir_name = 'arm64'
else:
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
else:
platform_version = android_version
platform_dir = os.path.join(ndk,
'platforms',
'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)
@depends(android_platform, ndk, target, '--help')
@checking('for android sysroot directory')
@imports(_from='os.path', _import='isdir')
def android_sysroot(android_platform, ndk, target, _):
if target.os != 'Android':
return
# NDK r15 has both unified and non-unified headers, but we only support
# non-unified for that NDK, so look for that first.
search_dirs = [
# (<if this directory exists>, <return this directory>)
(os.path.join(android_platform, 'usr', 'include'), android_platform),
(os.path.join(ndk, 'sysroot'), os.path.join(ndk, 'sysroot')),
]
for test_dir, sysroot_dir in search_dirs:
if isdir(test_dir):
return sysroot_dir
die("Android sysroot directory not found in %s." %
str([sysroot_dir for test_dir, sysroot_dir in search_dirs]))
add_old_configure_assignment('android_sysroot', android_sysroot)
@depends(android_platform, ndk, target, '--help')
@checking('for android system directory')
@imports(_from='os.path', _import='isdir')
def android_system(android_platform, ndk, target, _):
if target.os != 'Android':
return
# NDK r15 has both unified and non-unified headers, but we only support
# non-unified for that NDK, so look for that first.
search_dirs = [
os.path.join(android_platform, 'usr', 'include'),
os.path.join(ndk, 'sysroot', 'usr', 'include', target.toolchain),
]
for system_dir in search_dirs:
if isdir(system_dir):
return system_dir
die("Android system directory not found in %s." % str(search_dirs))
add_old_configure_assignment('android_system', android_system)
@depends(target, host, ndk, '--with-android-toolchain', '--help')
@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, _):
if not ndk:
return
if toolchain:
return toolchain[0]
else:
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'
else:
die('Target cpu is not supported.')
toolchain_format = '%s/toolchains/%s-4.9/prebuilt/%s-%s'
toolchain = toolchain_format % (ndk, target_base,
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
die('You have to specify --with-android-toolchain='
'/path/to/ndk/toolchain.')
set_config('ANDROID_TOOLCHAIN', android_toolchain)
@depends(target)
def android_toolchain_prefix_base(target):
if target.cpu == 'x86':
# Ideally, the --target should just have the right x86 variant
# in the first place.
return 'i686-linux-android'
return target.toolchain
option(env='STLPORT_CPPFLAGS',
nargs=1,
help='Options compiler should pass for standard C++ library')
@depends('STLPORT_CPPFLAGS', ndk, '--help')
@imports(_from='os.path', _import='isdir')
def stlport_cppflags(value, ndk, _):
if value and len(value):
return value.split()
if not ndk:
return
ndk_base = os.path.join(ndk, 'sources', 'cxx-stl')
cxx_base = os.path.join(ndk_base, 'llvm-libc++')
cxx_include = os.path.join(cxx_base, 'libcxx', 'include')
cxxabi_base = os.path.join(ndk_base, 'llvm-libc++abi')
cxxabi_include = os.path.join(cxxabi_base, 'libcxxabi', 'include')
if not isdir(cxx_include):
# NDK r13 removes the inner "libcxx" directory.
cxx_include = os.path.join(cxx_base, 'include')
if not isdir(cxx_include):
die("Couldn't find path to libc++ includes in the android ndk")
if not isdir(cxxabi_include):
# NDK r13 removes the inner "libcxxabi" directory.
cxxabi_include = os.path.join(cxxabi_base, 'include')
if not isdir(cxxabi_include):
die("Couldn't find path to libc++abi includes in the android ndk")
# Add android/support/include/ for prototyping long double math
# functions, locale-specific C library functions, multibyte support,
# etc.
return [
'-I%s' % cxx_include,
'-I%s' % os.path.join(ndk, 'sources', 'android', 'support', 'include'),
'-I%s' % cxxabi_include]
add_old_configure_assignment('stlport_cppflags', stlport_cppflags)
@depends(android_system, android_sysroot, android_toolchain, android_version,
stlport_cppflags)
def extra_toolchain_flags(android_system, android_sysroot, toolchain_dir,
android_version, stlport_cppflags):
if not android_sysroot:
return []
flags = ['-isystem',
android_system,
'-isystem',
os.path.join(android_sysroot, 'usr', 'include'),
'-gcc-toolchain',
toolchain_dir,
'-D__ANDROID_API__=%d' % android_version]
flags.extend(stlport_cppflags if stlport_cppflags else [])
return flags
@depends(android_toolchain_prefix_base, android_toolchain)
def android_toolchain_prefix(prefix_base, toolchain):
if toolchain:
return '%s/bin/%s-' % (toolchain, prefix_base)
imply_option('--with-toolchain-prefix', android_toolchain_prefix,
reason='--with-android-ndk')
@depends(extra_toolchain_flags, android_toolchain,
android_toolchain_prefix_base, '--help')
@imports(_from='os.path', _import='isdir')
def bindgen_cflags_defaults(toolchain_flags, toolchain, toolchain_prefix, _):
if not toolchain_flags:
return
gcc_include = os.path.join(
toolchain, 'lib', 'gcc', toolchain_prefix, '4.9.x')
if not isdir(gcc_include):
gcc_include = os.path.join(
toolchain, 'lib', 'gcc', toolchain_prefix, '4.9')
cflags_format = "%s -I%s -I%s"
return cflags_format % (' '.join(toolchain_flags),
os.path.join(gcc_include, 'include'),
os.path.join(gcc_include, 'include-fixed'))
@depends(host, ndk)
@imports(_from='os.path', _import='exists')
@imports(_from='os.path', _import='isdir')
def android_clang_compiler(host, ndk):
if not ndk:
return
llvm_path = '%s/toolchains/llvm/prebuilt/%s-%s/bin' % (ndk,
host.kernel.lower(),
host.cpu)
if not isdir(llvm_path) and host.cpu == 'x86_64':
llvm_path = toolchain_format % (ndk, host.kernel.lower(), 'x86')
if not isdir(llvm_path):
die("Couldn't find path to LLVM toolchain at %s" % llvm_path)
clang = '%s/clang' % llvm_path
if not exists(clang):
die("Couln't find clang in LLVM toolchain at %s" % clang)
return clang
@depends('--with-android-googlevr-sdk', target)
@checking('for GoogleVR SDK', lambda x: x.result)
@imports(_from='os.path', _import='exists')
@imports(_from='os.path', _import='abspath')
def googlevr_sdk(value, target):
if not value:
return namespace(
result='Not specified'
)
path = abspath(value[0])
if not exists(path):
die('Could not find GoogleVR SDK %s', path)
include = '%s/libraries/headers/' % path
if 'arm' == target.cpu:
arch = 'armeabi-v7a'
elif 'aarch64' == target.cpu:
arch = 'arm64-v8a'
elif 'x86' == target.cpu:
arch = 'x86'
else:
die('Unsupported GoogleVR cpu architecture %s' % target.cpu)
libs = '{0}/libraries/jni/{1}/'.format(path, arch)
if not exists(libs):
die('Could not find GoogleVR NDK at %s. Did you try running '
'\'./gradlew :extractNdk\' in %s?', libs, path)
return namespace(
result=path,
include=include,
libs=libs,
enabled=True,
)
set_define('MOZ_ANDROID_GOOGLE_VR', googlevr_sdk.enabled)
set_config('MOZ_ANDROID_GOOGLE_VR', googlevr_sdk.enabled)
set_config('MOZ_ANDROID_GOOGLE_VR_INCLUDE', googlevr_sdk.include)
set_config('MOZ_ANDROID_GOOGLE_VR_LIBS', googlevr_sdk.libs)