mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-25 01:57:12 +00:00
249 lines
8.0 KiB
Python
249 lines
8.0 KiB
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/.
|
|
|
|
# If we add unicode_literals, Python 2.6.1 (required for OS X 10.6) breaks.
|
|
from __future__ import print_function
|
|
|
|
import errno
|
|
import os
|
|
import stat
|
|
import subprocess
|
|
import sys
|
|
|
|
# These are the platform and build-tools versions for building
|
|
# mobile/android, respectively. Try to keep these in synch with the
|
|
# build system and Mozilla's automation.
|
|
ANDROID_TARGET_SDK = '23'
|
|
ANDROID_BUILD_TOOLS_VERSION = '23.0.1'
|
|
|
|
# These are the "Android packages" needed for building Firefox for Android.
|
|
# Use |android list sdk --extended| to see these identifiers.
|
|
ANDROID_PACKAGES = [
|
|
'tools',
|
|
'platform-tools',
|
|
'build-tools-%s' % ANDROID_BUILD_TOOLS_VERSION,
|
|
'android-%s' % ANDROID_TARGET_SDK,
|
|
'extra-google-m2repository',
|
|
'extra-android-m2repository',
|
|
]
|
|
|
|
ANDROID_NDK_EXISTS = '''
|
|
Looks like you have the Android NDK installed at:
|
|
%s
|
|
'''
|
|
|
|
ANDROID_SDK_EXISTS = '''
|
|
Looks like you have the Android SDK installed at:
|
|
%s
|
|
We will install all required Android packages.
|
|
'''
|
|
|
|
NOT_INSTALLING_ANDROID_PACKAGES = '''
|
|
It looks like you already have the following Android packages:
|
|
%s
|
|
No need to update!
|
|
'''
|
|
|
|
INSTALLING_ANDROID_PACKAGES = '''
|
|
We are now installing the following Android packages:
|
|
%s
|
|
You may be prompted to agree to the Android license. You may see some of
|
|
output as packages are downloaded and installed.
|
|
'''
|
|
|
|
MISSING_ANDROID_PACKAGES = '''
|
|
We tried to install the following Android packages:
|
|
%s
|
|
But it looks like we couldn't install:
|
|
%s
|
|
Install these Android packages manually and run this bootstrapper again.
|
|
'''
|
|
|
|
MOBILE_ANDROID_MOZCONFIG_TEMPLATE = '''
|
|
Paste the lines between the chevrons (>>> and <<<) into your mozconfig file:
|
|
|
|
<<<
|
|
# Build Firefox for Android:
|
|
ac_add_options --enable-application=mobile/android
|
|
ac_add_options --target=arm-linux-androideabi
|
|
|
|
# With the following Android SDK and NDK:
|
|
ac_add_options --with-android-sdk="%s"
|
|
ac_add_options --with-android-ndk="%s"
|
|
>>>
|
|
'''
|
|
|
|
|
|
def check_output(*args, **kwargs):
|
|
"""Run subprocess.check_output even if Python doesn't provide it."""
|
|
from base import BaseBootstrapper
|
|
fn = getattr(subprocess, 'check_output', BaseBootstrapper._check_output)
|
|
|
|
return fn(*args, **kwargs)
|
|
|
|
|
|
def list_missing_android_packages(android_tool, packages):
|
|
'''
|
|
Use the given |android| tool to return the sub-list of Android
|
|
|packages| given that are not installed.
|
|
'''
|
|
missing = []
|
|
|
|
# There's no obvious way to see what's been installed already,
|
|
# but packages that are installed don't appear in the list of
|
|
# available packages.
|
|
lines = check_output([android_tool,
|
|
'list', 'sdk', '--no-ui', '--extended']).splitlines()
|
|
|
|
# Lines look like: 'id: 59 or "extra-google-simulators"'
|
|
for line in lines:
|
|
is_id_line = False
|
|
try:
|
|
is_id_line = line.startswith("id:")
|
|
except:
|
|
# Some lines contain non-ASCII characters. Ignore them.
|
|
pass
|
|
if not is_id_line:
|
|
continue
|
|
|
|
for package in packages:
|
|
if '"%s"' % package in line:
|
|
# Not installed!
|
|
missing.append(package)
|
|
|
|
return missing
|
|
|
|
|
|
def install_mobile_android_sdk_or_ndk(url, path):
|
|
'''
|
|
Fetch an Android SDK or NDK from |url| and unpack it into
|
|
the given |path|.
|
|
|
|
We expect wget to be installed and found on the system path.
|
|
|
|
We use, and wget respects, https. We could also include SHAs for a
|
|
small improvement in the integrity guarantee we give. But this script is
|
|
bootstrapped over https anyway, so it's a really minor improvement.
|
|
|
|
We use |wget --continue| as a cheap cache of the downloaded artifacts,
|
|
writing into |path|/mozboot. We don't yet clean the cache; it's better
|
|
to waste disk and not require a long re-download than to wipe the cache
|
|
prematurely.
|
|
'''
|
|
|
|
old_path = os.getcwd()
|
|
try:
|
|
download_path = os.path.join(path, 'mozboot')
|
|
try:
|
|
os.makedirs(download_path)
|
|
except OSError as e:
|
|
if e.errno == errno.EEXIST and os.path.isdir(download_path):
|
|
pass
|
|
else:
|
|
raise
|
|
|
|
os.chdir(download_path)
|
|
subprocess.check_call(['wget', '--continue', url])
|
|
file = url.split('/')[-1]
|
|
|
|
os.chdir(path)
|
|
abspath = os.path.join(download_path, file)
|
|
if file.endswith('.tar.gz') or file.endswith('.tgz'):
|
|
cmd = ['tar', 'zvxf', abspath]
|
|
elif file.endswith('.tar.bz2'):
|
|
cmd = ['tar', 'jvxf', abspath]
|
|
elif file.endswith('.zip'):
|
|
cmd = ['unzip', abspath]
|
|
elif file.endswith('.bin'):
|
|
# Execute the .bin file, which unpacks the content.
|
|
mode = os.stat(path).st_mode
|
|
os.chmod(abspath, mode | stat.S_IXUSR)
|
|
cmd = [abspath]
|
|
else:
|
|
raise NotImplementedError("Don't know how to unpack file: %s" % file)
|
|
|
|
print('Unpacking %s...' % abspath)
|
|
|
|
with open(os.devnull, "w") as stdout:
|
|
# These unpack commands produce a ton of output; ignore it. The
|
|
# .bin files are 7z archives; there's no command line flag to quiet
|
|
# output, so we use this hammer.
|
|
subprocess.check_call(cmd, stdout=stdout)
|
|
|
|
print('Unpacking %s... DONE' % abspath)
|
|
|
|
finally:
|
|
os.chdir(old_path)
|
|
|
|
|
|
def ensure_android_sdk_and_ndk(path, sdk_path, sdk_url, ndk_path, ndk_url):
|
|
'''
|
|
Ensure the Android SDK and NDK are found at the given paths. If not, fetch
|
|
and unpack the SDK and/or NDK from the given URLs into |path|.
|
|
'''
|
|
|
|
# It's not particularyl bad to overwrite the NDK toolchain, but it does take
|
|
# a while to unpack, so let's avoid the disk activity if possible. The SDK
|
|
# may prompt about licensing, so we do this first.
|
|
if os.path.isdir(ndk_path):
|
|
print(ANDROID_NDK_EXISTS % ndk_path)
|
|
else:
|
|
install_mobile_android_sdk_or_ndk(ndk_url, path)
|
|
|
|
# We don't want to blindly overwrite, since we use the |android| tool to
|
|
# install additional parts of the Android toolchain. If we overwrite,
|
|
# we lose whatever Android packages the user may have already installed.
|
|
if os.path.isdir(sdk_path):
|
|
print(ANDROID_SDK_EXISTS % sdk_path)
|
|
else:
|
|
install_mobile_android_sdk_or_ndk(sdk_url, path)
|
|
|
|
|
|
def ensure_android_packages(android_tool, packages=None):
|
|
'''
|
|
Use the given android tool (like 'android') to install required Android
|
|
packages.
|
|
'''
|
|
|
|
if not packages:
|
|
packages = ANDROID_PACKAGES
|
|
|
|
# Bug 1171232: The |android| tool behaviour has changed; we no longer can
|
|
# see what packages are installed easily. Force installing everything until
|
|
# we find a way to actually see the missing packages.
|
|
missing = packages
|
|
if not missing:
|
|
print(NOT_INSTALLING_ANDROID_PACKAGES % ', '.join(packages))
|
|
return
|
|
|
|
# This tries to install all the required Android packages. The user
|
|
# may be prompted to agree to the Android license.
|
|
print(INSTALLING_ANDROID_PACKAGES % ', '.join(missing))
|
|
subprocess.check_call([android_tool,
|
|
'update', 'sdk', '--no-ui', '--all',
|
|
'--filter', ','.join(missing)])
|
|
|
|
# Bug 1171232: The |android| tool behaviour has changed; we no longer can
|
|
# see what packages are installed easily. Don't check until we find a way
|
|
# to actually verify.
|
|
failing = []
|
|
if failing:
|
|
raise Exception(MISSING_ANDROID_PACKAGES % (', '.join(missing), ', '.join(failing)))
|
|
|
|
|
|
def suggest_mozconfig(sdk_path=None, ndk_path=None):
|
|
print(MOBILE_ANDROID_MOZCONFIG_TEMPLATE % (sdk_path, ndk_path))
|
|
|
|
|
|
def android_ndk_url(os_name, ver='r10e'):
|
|
# Produce a URL like 'https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin'.
|
|
base_url = 'https://dl.google.com/android/ndk/android-ndk'
|
|
|
|
if sys.maxsize > 2**32:
|
|
arch = 'x86_64'
|
|
else:
|
|
arch = 'x86'
|
|
|
|
return '%s-%s-%s-%s.bin' % (base_url, ver, os_name, arch)
|