summaryrefslogtreecommitdiffstats
path: root/build/moz.configure/android-ndk.configure
diff options
context:
space:
mode:
Diffstat (limited to 'build/moz.configure/android-ndk.configure')
-rw-r--r--build/moz.configure/android-ndk.configure407
1 files changed, 407 insertions, 0 deletions
diff --git a/build/moz.configure/android-ndk.configure b/build/moz.configure/android-ndk.configure
new file mode 100644
index 0000000000..51683d8d33
--- /dev/null
+++ b/build/moz.configure/android-ndk.configure
@@ -0,0 +1,407 @@
+# -*- 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/.
+
+
+@depends(toolchains_base_dir, "--help")
+@imports(_from="os.path", _import="isdir")
+@imports(_from="mozboot.android", _import="NDK_VERSION")
+def default_android_ndk_root(toolchains_base_dir, _):
+ for ndk in ("android-ndk-%s" % NDK_VERSION, "android-ndk"):
+ path = os.path.join(toolchains_base_dir, ndk)
+ if isdir(path):
+ return path
+
+
+option(
+ "--with-android-ndk",
+ nargs=1,
+ default=default_android_ndk_root,
+ help="location where the Android NDK can be found{|}",
+)
+
+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"]:
+ # 64-bit support was added in API 21.
+ return "21"
+ return "16"
+
+
+option(
+ "--with-android-version",
+ nargs=1,
+ help="android platform version{|}",
+ default=min_android_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.")
+
+ 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")
+@imports(_from="os.path", _import="isdir")
+def ndk(value):
+ if value:
+ if not isdir(value[0]):
+ die(
+ "The path you specified with --with-android-ndk (%s) is not "
+ "a directory" % value[0]
+ )
+ return value[0]
+
+ die(
+ "You must specify --with-android-ndk=/path/to/ndk when targeting Android, "
+ "or try |mach bootstrap|."
+ )
+
+
+set_config("ANDROID_NDK", ndk)
+add_old_configure_assignment("android_ndk", ndk)
+
+
+@depends(ndk)
+@checking("for android ndk version")
+@imports(_from="__builtin__", _import="open")
+@imports(_from="mozboot.android", _import="NDK_VERSION")
+@imports(_from="mozboot.android", _import="get_ndk_version")
+@imports(_from="mozboot.android", _import="GetNdkVersionError")
+def ndk_version(ndk):
+ if not ndk:
+ # Building 'js/src' for non-Android.
+ return
+
+ try:
+ major, minor, human = get_ndk_version(ndk)
+ except GetNdkVersionError as e:
+ die(str(e))
+
+ if NDK_VERSION != human:
+ die(
+ "The only supported version of the NDK is %s (have %s)\n"
+ "Please run |mach bootstrap| "
+ "to install the correct NDK." % (NDK_VERSION, human)
+ )
+ return namespace(
+ major=major,
+ minor=minor,
+ )
+
+
+set_config("ANDROID_NDK_MAJOR_VERSION", ndk_version.major)
+set_config("ANDROID_NDK_MINOR_VERSION", ndk_version.minor)
+
+
+@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":
+ return
+
+ if "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)
+set_config("ANDROID_PLATFORM", android_platform)
+
+
+@depends(android_platform, ndk, target)
+@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)
+@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")
+@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 == "x86_64":
+ target_base = "x86_64"
+ 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"
+ host_kernel = "windows" if host.kernel == "WINNT" else host.kernel.lower()
+
+ toolchain = toolchain_format % (ndk, target_base, host_kernel, host.cpu)
+ log.debug("Trying %s" % quote(toolchain))
+ if not isdir(toolchain) and host.cpu == "x86_64":
+ toolchain = toolchain_format % (ndk, target_base, host_kernel, "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)
+@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 [
+ # You'd think we'd want to use -stdlib=libc++, but this doesn't work
+ # (cf. https://bugzilla.mozilla.org/show_bug.cgi?id=1510897#c2)
+ # Using -stdlib=libc++ and removing some of the -I below also doesn't
+ # work because not everything that is in cxx_include comes in the C++
+ # header directory that comes with clang.
+ "-stdlib=libstdc++",
+ "-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)
+def extra_toolchain_flags(
+ android_system, android_sysroot, toolchain_dir, android_version
+):
+ 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,
+ ]
+ 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,
+ stlport_cppflags,
+ android_toolchain,
+ android_toolchain_prefix_base,
+)
+@imports(_from="os.path", _import="isdir")
+def bindgen_cflags_android(toolchain_flags, stlport_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")
+
+ return (
+ toolchain_flags
+ + stlport_flags
+ + [
+ "-I%s" % os.path.join(gcc_include, "include"),
+ "-I%s" % os.path.join(gcc_include, "include-fixed"),
+ ]
+ )
+
+
+@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)