forked from servo/mozjs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
android-build
executable file
·106 lines (81 loc) · 3.59 KB
/
android-build
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/bin/env 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/.
import os
import platform
import shutil
import subprocess
import sys
from typing import Dict, Optional
SUPPORTED_NDK_VERSION = '26'
API_LEVEL = '30'
def get_host_string() -> str:
os_type = platform.system().lower()
if os_type not in ["linux", "darwin"]:
raise Exception("Android cross builds are only supported on Linux and macOS.")
cpu_type = platform.machine().lower()
host_suffix = "unknown"
if cpu_type in ["i386", "i486", "i686", "i768", "x86"]:
host_suffix = "x86"
elif cpu_type in ["x86_64", "x86-64", "x64", "amd64"]:
host_suffix = "x86_64"
return os_type + "-" + host_suffix
def check_output(*args, **kwargs) -> str:
return subprocess.check_output(*args, **kwargs).decode("utf-8").strip()
def get_target_from_args() -> Optional[str]:
for arg in sys.argv:
if arg.startswith("--target="):
return arg.replace("--target=", "")
return None
def set_toolchain_binaries_in_env(toolchain_dir: str, env: Dict[str, str]):
cc = os.path.join(toolchain_dir, "bin", "clang")
cxx = os.path.join(toolchain_dir, "bin", "clang++")
ar = check_output([cc, "--print-prog-name=llvm-ar"])
objcopy = check_output([cc, "--print-prog-name=llvm-objcopy"])
ranlib = check_output([cc, "--print-prog-name=llvm-ranlib"])
strip = check_output([cc, "--print-prog-name=llvm-strip"])
yasm = check_output([cc, "--print-prog-name=yasm"])
host_cc = env.get('HOST_CC') or shutil.which("clang") or shutil.which("gcc")
host_cxx = env.get('HOST_CXX') or shutil.which("clang++") or shutil.which("g++")
assert(host_cc)
assert(host_cxx)
env["AR"] = ar
env["CC"] = cc
env["CPP"] = f"{cc} -E"
env["CXX"] = cxx
env["HOST_CC"] = host_cc
env["HOST_CXX"] = host_cxx
env["OBJCOPY"] = objcopy
env["RANLIB"] = ranlib
env["STRIP"] = strip
env["YASM"] = yasm
def create_environment_for_build() -> Dict[str, str]:
env = os.environ.copy()
if "ANDROID_NDK_ROOT" not in env:
raise Exception("Please set the ANDROID_NDK_ROOT environment variable.")
ndk_home_dir = env["ANDROID_NDK_ROOT"]
# Check if the NDK version is 21
if not os.path.isfile(os.path.join(ndk_home_dir, 'source.properties')):
raise Exception(
"ANDROID_NDK should have file `source.properties`.\n" +
"The environment variable ANDROID_NDK_ROOT may be set at a wrong path."
)
with open(os.path.join(ndk_home_dir, 'source.properties'), encoding="utf8") as ndk_properties:
version_found = ndk_properties.readlines()[1].split(' = ')[1].split('.')[0]
if version_found != SUPPORTED_NDK_VERSION:
raise Exception(
"Servo and dependencies currently only support NDK version " +
f"{SUPPORTED_NDK_VERSION}. Found {version_found}"
)
# Add the toolchain to the path.
host_string = get_host_string()
toolchain_dir = os.path.join(ndk_home_dir, "toolchains", "llvm", "prebuilt", host_string)
env['PATH'] = os.pathsep.join([os.path.join(toolchain_dir, "bin"), env["PATH"]])
set_toolchain_binaries_in_env(toolchain_dir, env)
# This environment variable is only used by the mozjs build.
env["ANDROID_API_LEVEL"] = API_LEVEL
return env
if __name__ == "__main__":
completed_process = subprocess.run(sys.argv[1:], env=create_environment_for_build())
sys.exit(completed_process.returncode)