mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1820947 - Use "new style" sysroot on Android. r=firefox-build-system-reviewers,andi
For a few NDK releases now, the situation has been simplified wrt headers and libraries, and while we're currently still using things here and there because we never changed our ways, we can simplify things a lot by using the new simplified things. This involves: - Using a --target that contains the Android version, making clang set __ANDROID_API__ itself, and makes it look in $sysroot/usr/lib/$target/$ver when linking. - Using the sysroot that is under toolchains/llvm/prebuilt/*. - Removing the hacks around libstdc++/libc++. This ends up emptying stlport compiler flags, which allows to remove a bunch of things. Differential Revision: https://phabricator.services.mozilla.com/D172039
This commit is contained in:
parent
63bff39aa5
commit
eaca1f3dd4
@ -11,7 +11,7 @@ case "$target" in
|
||||
LDFLAGS="$extra_android_flags $LDFLAGS"
|
||||
CPPFLAGS="$extra_android_flags $CPPFLAGS"
|
||||
CFLAGS="-fno-short-enums $CFLAGS"
|
||||
CXXFLAGS="-fno-short-enums $CXXFLAGS $stlport_cppflags"
|
||||
CXXFLAGS="-fno-short-enums $CXXFLAGS"
|
||||
ASFLAGS="$extra_android_flags -DANDROID $ASFLAGS"
|
||||
;;
|
||||
esac
|
||||
|
@ -121,84 +121,50 @@ 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
|
||||
@imports(_from="mozbuild.shellutil", _import="quote")
|
||||
def host_dir(host, base_dir):
|
||||
dir_format = "%s/%s-%s"
|
||||
host_kernel = "windows" if host.kernel == "WINNT" else host.kernel.lower()
|
||||
|
||||
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
|
||||
dir = dir_format % (base_dir, host_kernel, host.cpu)
|
||||
log.debug("Trying %s" % quote(dir))
|
||||
if not isdir(dir) and host.cpu == "x86_64":
|
||||
dir = dir_format % (base_dir, host_kernel, "x86")
|
||||
log.debug("Trying %s" % quote(dir))
|
||||
if not isdir(dir) and host.kernel == "Darwin" and host.cpu == "aarch64":
|
||||
dir = dir_format % (base_dir, host_kernel, "x86_64")
|
||||
log.debug("Trying %s" % quote(dir))
|
||||
if isdir(dir):
|
||||
return dir
|
||||
|
||||
|
||||
@depends(ndk, target)
|
||||
@depends(ndk, target, host)
|
||||
@checking("for android sysroot directory")
|
||||
@imports(_from="os.path", _import="isdir")
|
||||
def android_sysroot(ndk, target):
|
||||
def android_sysroot(ndk, target, host):
|
||||
if target.os != "Android":
|
||||
return
|
||||
|
||||
search_dirs = [
|
||||
# (<if this directory exists>, <return this directory>)
|
||||
(os.path.join(ndk, "sysroot"), os.path.join(ndk, "sysroot")),
|
||||
os.path.join(
|
||||
host_dir(host, os.path.join(ndk, "toolchains", "llvm", "prebuilt")),
|
||||
"sysroot",
|
||||
),
|
||||
]
|
||||
|
||||
for test_dir, sysroot_dir in search_dirs:
|
||||
if isdir(test_dir):
|
||||
for sysroot_dir in search_dirs:
|
||||
if isdir(sysroot_dir):
|
||||
return sysroot_dir
|
||||
|
||||
die(
|
||||
"Android sysroot directory not found in %s."
|
||||
% str([sysroot_dir for test_dir, sysroot_dir in search_dirs])
|
||||
% str([sysroot_dir for sysroot_dir in search_dirs])
|
||||
)
|
||||
|
||||
|
||||
@depends(ndk, target)
|
||||
@checking("for android system directory")
|
||||
@imports(_from="os.path", _import="isdir")
|
||||
def android_system(ndk, target):
|
||||
if target.os != "Android":
|
||||
return
|
||||
|
||||
search_dirs = [
|
||||
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))
|
||||
|
||||
|
||||
@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
|
||||
@ -216,18 +182,8 @@ def android_toolchain(target, host, ndk, toolchain):
|
||||
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 not isdir(toolchain) and host.kernel == "Darwin" and host.cpu == "aarch64":
|
||||
toolchain = toolchain_format % (ndk, target_base, host_kernel, "x86_64")
|
||||
log.debug("Trying %s" % quote(toolchain))
|
||||
if isdir(toolchain):
|
||||
toolchain = host_dir(host, "%s/toolchains/%s-4.9/prebuilt" % (ndk, target_base))
|
||||
if toolchain:
|
||||
return toolchain
|
||||
die("You have to specify --with-android-toolchain=" "/path/to/ndk/toolchain.")
|
||||
|
||||
@ -281,58 +237,6 @@ def android_lldb_server(target, host, ndk, lldb):
|
||||
set_config("ANDROID_LLDB_SERVER", android_lldb_server)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
option(
|
||||
env="STLPORT_LIBS",
|
||||
nargs=1,
|
||||
@ -340,48 +244,27 @@ option(
|
||||
)
|
||||
|
||||
|
||||
@depends("STLPORT_LIBS", ndk, android_cpu_arch)
|
||||
@depends("STLPORT_LIBS", ndk)
|
||||
@imports(_from="os.path", _import="isfile")
|
||||
def stlport_libs(value, ndk, android_cpu_arch):
|
||||
def stlport_libs(value, ndk):
|
||||
if value and len(value):
|
||||
return value.split()
|
||||
if not ndk:
|
||||
return
|
||||
|
||||
cxx_libs = os.path.join(
|
||||
ndk, "sources", "cxx-stl", "llvm-libc++", "libs", android_cpu_arch
|
||||
)
|
||||
if not isfile(os.path.join(cxx_libs, "libc++_static.a")):
|
||||
die("Couldn't find path to llvm-libc++ in the android ndk")
|
||||
|
||||
libs = [
|
||||
"-L%s" % cxx_libs,
|
||||
"-lc++_static",
|
||||
]
|
||||
|
||||
for lib in ("c++abi", "unwind", "android_support"):
|
||||
if isfile(os.path.join(cxx_libs, "lib%s.a" % lib)):
|
||||
libs.append("-l%s" % lib)
|
||||
|
||||
return libs
|
||||
return ["-static-libstdc++"]
|
||||
|
||||
|
||||
set_config("STLPORT_LIBS", stlport_libs)
|
||||
|
||||
|
||||
@depends(android_system, android_sysroot, android_toolchain, android_version)
|
||||
def extra_toolchain_flags(
|
||||
android_system, android_sysroot, toolchain_dir, android_version
|
||||
):
|
||||
@depends(android_sysroot, android_toolchain)
|
||||
def extra_toolchain_flags(android_sysroot, toolchain_dir):
|
||||
if not android_sysroot:
|
||||
return []
|
||||
flags = [
|
||||
"-isystem",
|
||||
android_system,
|
||||
"-isystem",
|
||||
os.path.join(android_sysroot, "usr", "include"),
|
||||
"--sysroot={}".format(android_sysroot),
|
||||
"--gcc-toolchain={}".format(toolchain_dir),
|
||||
"-D__ANDROID_API__=%d" % android_version,
|
||||
]
|
||||
return flags
|
||||
|
||||
@ -389,12 +272,9 @@ def extra_toolchain_flags(
|
||||
add_old_configure_assignment("extra_android_flags", extra_toolchain_flags)
|
||||
|
||||
|
||||
@depends(extra_toolchain_flags, stlport_cppflags)
|
||||
def bindgen_cflags_android(toolchain_flags, stlport_flags):
|
||||
if not toolchain_flags:
|
||||
return
|
||||
|
||||
return toolchain_flags + stlport_flags
|
||||
@depends(extra_toolchain_flags)
|
||||
def bindgen_cflags_android(toolchain_flags):
|
||||
return toolchain_flags
|
||||
|
||||
|
||||
@depends("--with-android-googlevr-sdk", target)
|
||||
|
@ -123,6 +123,7 @@ option(
|
||||
clang_search_path,
|
||||
target,
|
||||
target_sysroot.path,
|
||||
android_version,
|
||||
)
|
||||
@checking("for clang for bindgen", lambda x: x.path if x else "not found")
|
||||
def bindgen_clang_compiler(
|
||||
@ -133,6 +134,7 @@ def bindgen_clang_compiler(
|
||||
clang_search_path,
|
||||
target,
|
||||
sysroot_path,
|
||||
android_version,
|
||||
):
|
||||
# When the target compiler is clang, use that, including flags.
|
||||
if cxx_compiler.type == "clang":
|
||||
@ -172,14 +174,18 @@ def bindgen_clang_compiler(
|
||||
flags = []
|
||||
if sysroot_path:
|
||||
flags.extend(("--sysroot", sysroot_path))
|
||||
info = check_compiler(configure_cache, [clang_path] + flags, "C++", target)
|
||||
info = check_compiler(
|
||||
configure_cache, [clang_path] + flags, "C++", target, android_version
|
||||
)
|
||||
# Usually, one check_compiler pass would be enough, but when cross-compiling
|
||||
# and the host and target don't use the same default C++ standard, we don't
|
||||
# get the --std flag, so try again. This is the same thing as valid_compiler()
|
||||
# does in toolchain.configure.
|
||||
if info.flags:
|
||||
flags += info.flags
|
||||
info = check_compiler(configure_cache, [clang_path] + flags, "C++", target)
|
||||
info = check_compiler(
|
||||
configure_cache, [clang_path] + flags, "C++", target, android_version
|
||||
)
|
||||
return namespace(
|
||||
path=clang_path,
|
||||
flags=flags + info.flags,
|
||||
|
@ -105,7 +105,6 @@ def compiler_class(compiler, host_or_target):
|
||||
self,
|
||||
dependable(flags),
|
||||
extra_toolchain_flags,
|
||||
stlport_cppflags,
|
||||
dependable(header),
|
||||
onerror,
|
||||
configure_cache,
|
||||
@ -116,7 +115,6 @@ def compiler_class(compiler, host_or_target):
|
||||
compiler,
|
||||
flags,
|
||||
extra_flags,
|
||||
stlport_flags,
|
||||
header,
|
||||
onerror,
|
||||
configure_cache,
|
||||
@ -124,8 +122,6 @@ def compiler_class(compiler, host_or_target):
|
||||
flags = list(flags or [])
|
||||
if is_target:
|
||||
flags += extra_flags or []
|
||||
if compiler.language == "C++":
|
||||
flags += stlport_flags or []
|
||||
header = header or ""
|
||||
if isinstance(header, (list, tuple)):
|
||||
header = "\n".join(header)
|
||||
|
@ -410,7 +410,7 @@ def same_arch_different_bits():
|
||||
|
||||
@imports(_from="mozbuild.shellutil", _import="quote")
|
||||
@imports(_from="mozbuild.configure.constants", _import="OS_preprocessor_checks")
|
||||
def check_compiler(configure_cache, compiler, language, target):
|
||||
def check_compiler(configure_cache, compiler, language, target, android_version):
|
||||
info = get_compiler_info(configure_cache, compiler, language)
|
||||
|
||||
flags = []
|
||||
@ -445,6 +445,13 @@ def check_compiler(configure_cache, compiler, language, target):
|
||||
# Check compiler target
|
||||
# --------------------------------------------------------------------
|
||||
has_target = False
|
||||
if target.os == "Android" and android_version:
|
||||
# This makes clang define __ANDROID_API__ and use versioned library
|
||||
# directories from the NDK.
|
||||
toolchain = "%s%d" % (target.toolchain, android_version)
|
||||
else:
|
||||
toolchain = target.toolchain
|
||||
|
||||
if info.type == "clang":
|
||||
# Add the target explicitly when the target is aarch64 macosx, because
|
||||
# the Xcode clang target is named differently, and we need to work around
|
||||
@ -463,7 +470,7 @@ def check_compiler(configure_cache, compiler, language, target):
|
||||
or not info.endianness
|
||||
or info.endianness != target.endianness
|
||||
):
|
||||
flags.append("--target=%s" % target.toolchain)
|
||||
flags.append("--target=%s" % toolchain)
|
||||
has_target = True
|
||||
|
||||
# Add target flag when there is an OS mismatch (e.g. building for Android on
|
||||
@ -472,7 +479,7 @@ def check_compiler(configure_cache, compiler, language, target):
|
||||
elif target.os in OS_preprocessor_checks and (
|
||||
not info.os or info.os != target.os
|
||||
):
|
||||
flags.append("--target=%s" % target.toolchain)
|
||||
flags.append("--target=%s" % toolchain)
|
||||
has_target = True
|
||||
|
||||
if not has_target and (not info.cpu or info.cpu != target.cpu):
|
||||
@ -482,9 +489,9 @@ def check_compiler(configure_cache, compiler, language, target):
|
||||
elif (info.cpu, target.cpu) in same_arch:
|
||||
flags.append("-m64")
|
||||
elif info.type == "clang-cl" and target.cpu == "aarch64":
|
||||
flags.append("--target=%s" % target.toolchain)
|
||||
flags.append("--target=%s" % toolchain)
|
||||
elif info.type == "clang":
|
||||
flags.append("--target=%s" % target.toolchain)
|
||||
flags.append("--target=%s" % toolchain)
|
||||
|
||||
return namespace(
|
||||
type=info.type,
|
||||
@ -1199,6 +1206,7 @@ def compiler(
|
||||
host_or_target,
|
||||
sysroot,
|
||||
macos_target,
|
||||
android_version,
|
||||
multiarch_dir,
|
||||
winsysroot,
|
||||
host,
|
||||
@ -1214,6 +1222,7 @@ def compiler(
|
||||
host_or_target,
|
||||
sysroot,
|
||||
macos_target,
|
||||
android_version,
|
||||
multiarch_dir,
|
||||
winsysroot,
|
||||
host,
|
||||
@ -1235,7 +1244,11 @@ def compiler(
|
||||
flags.extend(provided_compiler.flags)
|
||||
|
||||
info = check_compiler(
|
||||
configure_cache, wrapper + [compiler] + flags, language, host_or_target
|
||||
configure_cache,
|
||||
wrapper + [compiler] + flags,
|
||||
language,
|
||||
host_or_target,
|
||||
android_version,
|
||||
)
|
||||
|
||||
if info.type == "clang" and language == "C++" and host_or_target.os == "OSX":
|
||||
@ -1258,6 +1271,7 @@ def compiler(
|
||||
wrapper + [compiler] + flags,
|
||||
language,
|
||||
host_or_target,
|
||||
android_version,
|
||||
)
|
||||
except FatalCheckError:
|
||||
pass
|
||||
@ -1383,6 +1397,15 @@ def compiler(
|
||||
% (host_or_target.alias, info.version)
|
||||
)
|
||||
|
||||
if host_or_target.os == "Android":
|
||||
# Need at least clang 8 for support for __ANDROID_API__ and versioned
|
||||
# library directories from the NDK.
|
||||
if info.type == "clang" and info.version < "8.0":
|
||||
raise FatalCheckError(
|
||||
"Only clang/llvm 8.0 or newer is supported for %s (found version %s)."
|
||||
% (host_or_target.alias, info.version)
|
||||
)
|
||||
|
||||
if info.flags:
|
||||
raise FatalCheckError("Unknown compiler or compiler not supported.")
|
||||
|
||||
@ -1815,7 +1838,8 @@ def linker_ldflags_tmpl(host_or_target):
|
||||
target,
|
||||
target_sysroot,
|
||||
target_multiarch_dir,
|
||||
android_platform,
|
||||
android_sysroot,
|
||||
android_version,
|
||||
c_compiler,
|
||||
developer_options,
|
||||
)
|
||||
@ -1826,6 +1850,7 @@ def linker_ldflags_tmpl(host_or_target):
|
||||
host_sysroot,
|
||||
host_multiarch_dir,
|
||||
dependable(None),
|
||||
dependable(None),
|
||||
host_c_compiler,
|
||||
developer_options,
|
||||
)
|
||||
@ -1837,7 +1862,8 @@ def linker_ldflags_tmpl(host_or_target):
|
||||
target,
|
||||
sysroot,
|
||||
multiarch_dir,
|
||||
android_platform,
|
||||
android_sysroot,
|
||||
android_version,
|
||||
c_compiler,
|
||||
developer_options,
|
||||
):
|
||||
@ -1863,11 +1889,17 @@ def linker_ldflags_tmpl(host_or_target):
|
||||
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)
|
||||
if android_sysroot:
|
||||
# BFD/gold linkers need a manual --rpath-link for indirect
|
||||
# dependencies.
|
||||
flags += [
|
||||
"-Wl,--rpath-link={}/usr/lib/{}".format(
|
||||
android_sysroot, target.toolchain
|
||||
),
|
||||
"-Wl,--rpath-link={}/usr/lib/{}/{}".format(
|
||||
android_sysroot, target.toolchain, android_version
|
||||
),
|
||||
]
|
||||
if (
|
||||
developer_options
|
||||
and linker
|
||||
|
@ -29,7 +29,7 @@ for v in ("OS_CPPFLAGS", "OS_CFLAGS", "DEBUG", "CLANG_PLUGIN", "OPTIMIZE", "FRAM
|
||||
for flag in COMPILE_FLAGS[v]:
|
||||
if flag == "-isystem":
|
||||
flags.append("".join(COMPILE_FLAGS[v][idx : idx + 2]))
|
||||
elif flag.startswith(("-m", "-I", "-isystem")) or flag == "-fPIC":
|
||||
elif flag.startswith(("-m", "-I", "-isystem", "--sysroot=")) or flag == "-fPIC":
|
||||
flags.append(flag)
|
||||
idx += 1
|
||||
COMPILE_FLAGS[v] = flags
|
||||
|
@ -56,10 +56,6 @@ class BaseCompileChecks(unittest.TestCase):
|
||||
def extra_toolchain_flags():
|
||||
return []
|
||||
|
||||
@depends(when=True)
|
||||
def stlport_cppflags():
|
||||
return []
|
||||
|
||||
@depends(when=True)
|
||||
def linker_ldflags():
|
||||
return []
|
||||
|
Loading…
Reference in New Issue
Block a user