-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is the essentially the NDK that the version of SpiderMonkey supports. This makes a few changes to the SpiderMonkey source as well: 1. Pulls in a change from a more recent version so that the correct version of the clock functions are used. 2. Disables all attempts by SpiderMonkey to set the sysroot, Android platform includes, and the STL. Modern NDKs don't require these flags, they often just break mysteriously if not used perfectly. SpiderMonkey upstream is starting to use them less, but is still pretty far in the past. This makes everything about the Android build simpler. In addition, some compilation errors for 32-bit machines are fixed.
- Loading branch information
Showing
12 changed files
with
483 additions
and
251 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#!/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 = '21' | ||
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=ar"]) | ||
objcopy = check_output([cc, "--print-prog-name=objcopy"]) | ||
ranlib = check_output([cc, "--print-prog-name=ranlib"]) | ||
strip = check_output([cc, "--print-prog-name=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["PKG_CONFIG"] = "/usr/bin/pkg-config" | ||
env["RANLIB"] = ranlib | ||
env["STRIP"] = strip | ||
env["YASM"] = yasm | ||
|
||
|
||
def set_compiler_flags_in_env(toolchain_dir: str, env: Dict[str, str]): | ||
target = get_target_from_args() | ||
if target == "armv7-linux-androideabi": | ||
ndk_target_name = "armv7a-linux-androideabi" | ||
elif target == "aarch64-linux-android": | ||
ndk_target_name = "aarch64-linux-androideabi" | ||
elif target == "i686-linux-android" or target == "x86_64-linux-android": | ||
ndk_target_name = target | ||
else: | ||
raise Exception(f"Unknown target {target}") | ||
|
||
# Including the api level in the target name means that we will not have to | ||
# define the Android API level when calling the compiler. | ||
target_arg = f"--target={ndk_target_name}{API_LEVEL}" | ||
stl_include_dir = os.path.join(toolchain_dir, "sysroot", "usr", "include", "c++", "v1") | ||
stl_arg = f"-I{stl_include_dir}" | ||
|
||
env["CFLAGS"] = target_arg | ||
env["CPPFLAGS"] = stl_arg | ||
env["CXXFLAGS"] = " ".join([target_arg, stl_arg]) | ||
|
||
def create_environment_for_build() -> Dict[str, str]: | ||
env = os.environ.copy() | ||
if "ANDROID_NDK_HOME" not in env: | ||
raise Exception("Please set the ANDROID_NDK_HOME environment variable.") | ||
|
||
ndk_home_dir = env["ANDROID_NDK_HOME"] | ||
|
||
# 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_HOME 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) | ||
set_compiler_flags_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__": | ||
subprocess.run(sys.argv[1:], env=create_environment_for_build()) |
12 changes: 0 additions & 12 deletions
12
mozjs/etc/patches/0010-Always-pass-the-sysroot-when-using-the-Android-NDK.patch
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
diff --git a/build/autoconf/android.m4 b/build/autoconf/android.m4 | ||
index d4967864d..30eba4ff5 100644 | ||
--- a/build/autoconf/android.m4 | ||
+++ b/build/autoconf/android.m4 | ||
@@ -8,12 +8,14 @@ AC_DEFUN([MOZ_ANDROID_NDK], | ||
case "$target" in | ||
*-android*|*-linuxandroid*) | ||
dnl $android_* will be set for us by Python configure. | ||
- directory_include_args="-isystem $android_system -isystem $android_sysroot/usr/include" | ||
+ dnl | ||
+ dnl See the mozjs note android-nkd.configure for why these lines are commented out. | ||
+ dnl directory_include_args="-isystem $android_system -isystem $android_sysroot/usr/include" | ||
|
||
# clang will do any number of interesting things with host tools unless we tell | ||
# it to use the NDK tools. | ||
- extra_opts="--gcc-toolchain=$(dirname $(dirname $TOOLCHAIN_PREFIX))" | ||
- CPPFLAGS="$extra_opts -D__ANDROID_API__=$android_version $CPPFLAGS" | ||
+ dnl extra_opts="--gcc-toolchain=$(dirname $(dirname $TOOLCHAIN_PREFIX))" | ||
+ dnl CPPFLAGS="$extra_opts -D__ANDROID_API__=$android_version $CPPFLAGS" | ||
ASFLAGS="$extra_opts $ASFLAGS" | ||
LDFLAGS="$extra_opts $LDFLAGS" | ||
|
||
diff --git a/build/moz.configure/android-ndk.configure b/build/moz.configure/android-ndk.configure | ||
index 7448743a4..6c60d9713 100644 | ||
--- a/build/moz.configure/android-ndk.configure | ||
+++ b/build/moz.configure/android-ndk.configure | ||
@@ -380,6 +380,20 @@ def extra_toolchain_flags( | ||
): | ||
if not android_sysroot: | ||
return [] | ||
+ | ||
+ # Note for mozjs: | ||
+ # Normally Gecko passes all the arguments below to the compiler. The truth | ||
+ # is though that modern NDKs do not need them. They are all handled by the | ||
+ # special NDK-provided compiler wrappers [1]. The mozjs build expects to | ||
+ # use these wrappers and any small mistake in the way the compiler is | ||
+ # invoked will cause any number of subtle build errors. We are simple | ||
+ # people in mozjs land. Let's not even try to get this right and rely on | ||
+ # the NDK to properly invoke the compiler. | ||
+ # | ||
+ # 1. https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#Clang | ||
+ if android_sysroot: | ||
+ return [] | ||
+ | ||
flags = [ | ||
"-isystem", | ||
android_system, | ||
diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure | ||
index ec482be95..42873cf6e 100755 | ||
--- a/build/moz.configure/toolchain.configure | ||
+++ b/build/moz.configure/toolchain.configure | ||
@@ -1692,11 +1692,13 @@ def linker_ldflags( | ||
sysroot.path, multiarch_dir, sysroot.stdcxx_version | ||
) | ||
) | ||
- if android_platform: | ||
- flags.append("-L{}/usr/lib".format(android_platform)) | ||
- flags.append("-Wl,--rpath-link={}/usr/lib".format(android_platform)) | ||
- flags.append("--sysroot") | ||
- flags.append(android_platform) | ||
+ # mozjs: The NDK compiler / linker wrappers take care of properly setting these variables. | ||
+ # See the mozjs note in android-ndk.configure. | ||
+ # if android_platform: | ||
+ # flags.append("-L{}/usr/lib".format(android_platform)) | ||
+ # flags.append("-Wl,--rpath-link={}/usr/lib".format(android_platform)) | ||
+ # flags.append("--sysroot") | ||
+ # flags.append(android_platform) | ||
return flags | ||
|
||
|
||
diff --git a/mozglue/misc/ConditionVariable_posix.cpp b/mozglue/misc/ConditionVariable_posix.cpp | ||
index fcc404713..6f6076db7 100644 | ||
--- a/mozglue/misc/ConditionVariable_posix.cpp | ||
+++ b/mozglue/misc/ConditionVariable_posix.cpp | ||
@@ -20,10 +20,13 @@ using mozilla::TimeDuration; | ||
|
||
static const long NanoSecPerSec = 1000000000; | ||
|
||
-// Android 32-bit & macOS 10.12 has the clock functions, but not | ||
+// mozjs patch note: This following patched lines come from the upstream version | ||
+// of SpiderMonkey: | ||
+// | ||
+// Android 4.4 or earlier & macOS 10.12 has the clock functions, but not | ||
// pthread_condattr_setclock. | ||
#if defined(HAVE_CLOCK_MONOTONIC) && \ | ||
- !(defined(__ANDROID__) && !defined(__LP64__)) && !defined(__APPLE__) | ||
+ !(defined(__ANDROID__) && __ANDROID_API__ < 21) && !defined(__APPLE__) | ||
# define CV_USE_CLOCK_API | ||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.