tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

android-ndk.configure (11340B)


      1 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
      2 # vim: set filetype=python:
      3 # This Source Code Form is subject to the terms of the Mozilla Public
      4 # License, v. 2.0. If a copy of the MPL was not distributed with this
      5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      6 
      7 
      8 @depends(toolchains_base_dir, "--help")
      9 @imports(_from="os.path", _import="isdir")
     10 @imports(_from="mozboot.android", _import="NDK_VERSION")
     11 def default_android_ndk_root(toolchains_base_dir, _):
     12     for ndk in ("android-ndk-%s" % NDK_VERSION, "android-ndk"):
     13         path = os.path.join(toolchains_base_dir, ndk)
     14         if isdir(path):
     15             return path
     16 
     17 
     18 option(
     19     "--with-android-ndk",
     20     nargs=1,
     21     default=default_android_ndk_root,
     22     help="Location where the Android NDK can be found{|}",
     23 )
     24 
     25 option("--with-android-toolchain", nargs=1, help="Location of the Android toolchain")
     26 
     27 option(
     28     "--with-android-lldb-server", nargs=1, help="Location of the Android LLDB server"
     29 )
     30 
     31 option(
     32     "--with-android-googlevr-sdk", nargs=1, help="Location of the Android GoogleVR SDK"
     33 )
     34 
     35 
     36 @dependable
     37 def min_android_version():
     38     # Sync with android_sdk_version.min_sdk_version
     39     return "26"
     40 
     41 
     42 option(
     43     "--with-android-version",
     44     nargs=1,
     45     help="Android platform version{|}",
     46     default=min_android_version,
     47 )
     48 
     49 
     50 @depends("--with-android-version", min_android_version)
     51 @imports(_from="__builtin__", _import="ValueError")
     52 def android_version(value, min_version):
     53     if not value:
     54         # Someone has passed --without-android-version.
     55         die("--with-android-version cannot be disabled.")
     56 
     57     try:
     58         version = int(value[0])
     59     except ValueError:
     60         die("--with-android-version expects an integer value")
     61 
     62     if version < int(min_version):
     63         die(
     64             "--with-android-version must be at least %s (got %s)", min_version, value[0]
     65         )
     66 
     67     return version
     68 
     69 
     70 @depends("--with-android-ndk", want_bootstrap)
     71 @imports(_from="os.path", _import="isdir")
     72 @imports(_from="mozboot.android", _import="get_os_name_for_android")
     73 @imports(_from="mozboot.android", _import="ensure_android_ndk")
     74 @imports(_from="mozboot.android", _import="NDK_PATH")
     75 def ndk(value, want_bootstrap):
     76     if value:
     77         ndk_path = value[0]
     78         if not isdir(ndk_path):
     79             die(
     80                 "The path you specified with --with-android-ndk (%s) is not "
     81                 "a directory" % ndk_path
     82             )
     83         return ndk_path
     84     if not want_bootstrap("android-ndk"):
     85         die(
     86             "You must specify --with-android-ndk=/path/to/ndk when targeting Android, "
     87             "or try |mach bootstrap|."
     88         )
     89 
     90     os_name = get_os_name_for_android()
     91 
     92     ensure_android_ndk(os_name)
     93 
     94     return str(NDK_PATH)
     95 
     96 
     97 set_config("ANDROID_NDK", ndk)
     98 
     99 
    100 @depends(ndk)
    101 @checking("for android ndk version")
    102 @imports(_from="__builtin__", _import="open")
    103 @imports(_from="mozboot.android", _import="NDK_VERSION")
    104 @imports(_from="mozboot.android", _import="get_ndk_version")
    105 @imports(_from="mozboot.android", _import="GetNdkVersionError")
    106 def ndk_version(ndk):
    107     if not ndk:
    108         # Building 'js/src' for non-Android.
    109         return
    110 
    111     try:
    112         major, minor, human = get_ndk_version(ndk)
    113     except GetNdkVersionError as e:
    114         die(str(e))
    115 
    116     if NDK_VERSION != human:
    117         die(
    118             "The only supported version of the NDK is %s (have %s)\n"
    119             "Please run |mach bootstrap| "
    120             "to install the correct NDK." % (NDK_VERSION, human)
    121         )
    122     return namespace(
    123         major=major,
    124         minor=minor,
    125     )
    126 
    127 
    128 set_config("ANDROID_NDK_MAJOR_VERSION", ndk_version.major)
    129 set_config("ANDROID_NDK_MINOR_VERSION", ndk_version.minor)
    130 
    131 
    132 @imports(_from="os.path", _import="isdir")
    133 @imports(_from="mozshellutil", _import="quote")
    134 def host_dir(host, base_dir):
    135     dir_format = "%s/%s-%s"
    136     host_kernel = "windows" if host.kernel == "WINNT" else host.kernel.lower()
    137 
    138     dir = dir_format % (base_dir, host_kernel, host.cpu)
    139     log.debug("Trying %s" % quote(dir))
    140     if not isdir(dir) and host.cpu == "x86_64":
    141         dir = dir_format % (base_dir, host_kernel, "x86")
    142         log.debug("Trying %s" % quote(dir))
    143     if not isdir(dir) and host.kernel == "Darwin" and host.cpu == "aarch64":
    144         dir = dir_format % (base_dir, host_kernel, "x86_64")
    145         log.debug("Trying %s" % quote(dir))
    146     if isdir(dir):
    147         return dir
    148 
    149 
    150 @depends(host, ndk, "--with-android-toolchain")
    151 @checking("for the Android toolchain directory", lambda x: x or "not found")
    152 def android_toolchain(host, ndk, toolchain):
    153     if not ndk:
    154         return
    155     if toolchain:
    156         return toolchain[0]
    157 
    158     toolchain = host_dir(host, os.path.join(ndk, "toolchains", "llvm", "prebuilt"))
    159     if toolchain:
    160         return toolchain
    161     die("You have to specify --with-android-toolchain=" "/path/to/ndk/toolchain.")
    162 
    163 
    164 @depends(target, android_toolchain)
    165 @checking("for android sysroot directory")
    166 @imports(_from="os.path", _import="isdir")
    167 def android_sysroot(target, android_toolchain):
    168     if target.os != "Android":
    169         return
    170 
    171     search_dirs = [
    172         os.path.join(android_toolchain, "sysroot"),
    173     ]
    174 
    175     for sysroot_dir in search_dirs:
    176         if isdir(sysroot_dir):
    177             return sysroot_dir
    178 
    179     die(
    180         "Android sysroot directory not found in %s."
    181         % str([sysroot_dir for sysroot_dir in search_dirs])
    182     )
    183 
    184 
    185 @depends(target, host, ndk, "--with-android-lldb-server")
    186 @checking("for the Android LLDB server", lambda x: x or "not found")
    187 @imports(_from="os", _import="listdir")
    188 @imports(_from="os.path", _import="isdir")
    189 @imports(_from="os.path", _import="isfile")
    190 @imports(_from="mozshellutil", _import="quote")
    191 def android_lldb_server(target, host, ndk, lldb):
    192     if not ndk:
    193         return
    194     if lldb:
    195         return lldb[0]
    196     else:
    197         clang_format = "toolchains/llvm/prebuilt/%s-%s/lib/clang"
    198         llvm_lib = "lib/linux"
    199 
    200         host_kernel = "windows" if host.kernel == "WINNT" else host.kernel.lower()
    201         clang_path = os.path.join(ndk, clang_format % (host_kernel, host.cpu))
    202         if not isdir(clang_path) and host.kernel == "Darwin" and host.cpu == "aarch64":
    203             clang_path = os.path.join(ndk, clang_format % (host_kernel, "x86_64"))
    204         log.debug("Listing subdirectories of %s" % quote(clang_path))
    205         clang_subdirs = [
    206             x for x in listdir(clang_path) if isdir(os.path.join(clang_path, x))
    207         ]
    208         log.debug("Got %r" % clang_subdirs)
    209         if len(clang_subdirs) == 0:
    210             die(
    211                 "Could not resolve lldb-server in %s. Please specify --with-android-lldb-server=/path/to/android/lldb-server"
    212                 % quote(clang_path)
    213             )
    214         sorted_versions = sorted(clang_subdirs, key=Version)
    215         highest_version = sorted_versions[-1]
    216 
    217         if len(sorted_versions) > 1:
    218             log.warning("Using highest version available: %s" % quote(highest_version))
    219             log.warning(
    220                 " Available versions: "
    221                 + ", ".join(str(version) for version in sorted_versions)
    222             )
    223             log.warning(
    224                 "(To use an older version, please specify --with-android-lldb-server=/path/to/desired/android/lldb-server)"
    225             )
    226 
    227         if target.cpu == "x86":
    228             target_cpu = "i386"
    229         else:
    230             target_cpu = target.cpu
    231 
    232         full_path = os.path.join(
    233             clang_path, highest_version, llvm_lib, target_cpu, "lldb-server"
    234         )
    235         log.debug("Trying %s" % quote(full_path))
    236 
    237         if isfile(full_path):
    238             return full_path
    239         die("Please specify --with-android-lldb-server=/path/to/android/lldb-server")
    240 
    241 
    242 set_config("ANDROID_LLDB_SERVER", android_lldb_server)
    243 
    244 
    245 option(
    246     env="STLPORT_LIBS",
    247     nargs=1,
    248     help="Options linker should pass for standard C++ library",
    249 )
    250 
    251 
    252 @depends("STLPORT_LIBS", ndk)
    253 @imports(_from="os.path", _import="isfile")
    254 def stlport_libs(value, ndk):
    255     if value and len(value):
    256         return value.split()
    257     if not ndk:
    258         return
    259 
    260     return ["-static-libstdc++"]
    261 
    262 
    263 set_config("STLPORT_LIBS", stlport_libs)
    264 
    265 
    266 @depends(android_sysroot, android_toolchain)
    267 def extra_toolchain_flags(android_sysroot, toolchain_dir):
    268     if not android_sysroot:
    269         return []
    270     flags = [
    271         "--sysroot={}".format(android_sysroot),
    272         "--gcc-toolchain={}".format(toolchain_dir),
    273     ]
    274     return flags
    275 
    276 
    277 @depends(extra_toolchain_flags)
    278 def android_flags(extra_toolchain_flags):
    279     wead_symbols_defines = [
    280         "-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__",
    281     ]
    282     weak_symbols_flags = wead_symbols_defines + [
    283         "-Werror=unguarded-availability",
    284     ]
    285     return namespace(
    286         cflags=extra_toolchain_flags
    287         + [
    288             "-fno-short-enums",
    289         ]
    290         + weak_symbols_flags,
    291         cxxflags=extra_toolchain_flags
    292         + [
    293             "-fno-short-enums",
    294         ]
    295         + weak_symbols_flags,
    296         ldflags=extra_toolchain_flags,
    297         asflags=extra_toolchain_flags
    298         + [
    299             "-DANDROID",
    300         ]
    301         + wead_symbols_defines,
    302     )
    303 
    304 
    305 @depends(host, ndk)
    306 @imports(_from="os", _import="listdir")
    307 @imports(_from="os.path", _import="isfile")
    308 @imports(_from="os.path", _import="isdir")
    309 def android_system_headers(host, ndk):
    310     if not ndk:
    311         return
    312     host_kernel = "windows" if host.kernel == "WINNT" else host.kernel.lower()
    313     android_fmt = "toolchains/llvm/prebuilt/{}-{}/sysroot/usr/include/android"
    314     android_includes = os.path.join(ndk, android_fmt.format(host_kernel, host.cpu))
    315 
    316     if (
    317         not isdir(android_includes)
    318         and host.kernel == "Darwin"
    319         and host.cpu == "aarch64"
    320     ):
    321         android_includes = os.path.join(ndk, android_fmt.format(host_kernel, "x86_64"))
    322 
    323     return [
    324         f"android/{header}"
    325         for header in listdir(android_includes)
    326         if isfile(os.path.join(android_includes, header))
    327     ]
    328 
    329 
    330 set_config("ANDROID_SYSTEM_HEADERS", android_system_headers)
    331 
    332 
    333 @depends(extra_toolchain_flags)
    334 def bindgen_cflags_android(toolchain_flags):
    335     return toolchain_flags
    336 
    337 
    338 @depends("--with-android-googlevr-sdk", target)
    339 @checking("for GoogleVR SDK", lambda x: x.result)
    340 @imports(_from="os.path", _import="exists")
    341 @imports(_from="os.path", _import="abspath")
    342 def googlevr_sdk(value, target):
    343     if not value:
    344         return namespace(result="Not specified")
    345     path = abspath(value[0])
    346     if not exists(path):
    347         die("Could not find GoogleVR SDK %s", path)
    348     include = "%s/libraries/headers/" % path
    349     if "arm" == target.cpu:
    350         arch = "armeabi-v7a"
    351     elif "aarch64" == target.cpu:
    352         arch = "arm64-v8a"
    353     elif "x86" == target.cpu:
    354         arch = "x86"
    355     else:
    356         die("Unsupported GoogleVR cpu architecture %s" % target.cpu)
    357 
    358     libs = "{0}/libraries/jni/{1}/".format(path, arch)
    359 
    360     if not exists(libs):
    361         die(
    362             "Could not find GoogleVR NDK at %s. Did you try running "
    363             "'./gradlew :extractNdk' in %s?",
    364             libs,
    365             path,
    366         )
    367 
    368     return namespace(
    369         result=path,
    370         include=include,
    371         libs=libs,
    372         enabled=True,
    373     )
    374 
    375 
    376 set_define("MOZ_ANDROID_GOOGLE_VR", googlevr_sdk.enabled)
    377 set_config("MOZ_ANDROID_GOOGLE_VR", googlevr_sdk.enabled)
    378 set_config("MOZ_ANDROID_GOOGLE_VR_LIBS", googlevr_sdk.libs)