Build libc++ using the just-built NDK.
This gets us out of depending on prebuilts/ndk (and as such a
sometimes out of sync sysroot) when building libc++.
Test: ./checkbuild.py && ./run_tests.py
Test: ./checkbuild.py libc++
Bug: None
Change-Id: I195a2dba37731dac85e81c7c173399c0d0843346
diff --git a/build/core/definitions.mk b/build/core/definitions.mk
index 9df5b06..f7c998b 100644
--- a/build/core/definitions.mk
+++ b/build/core/definitions.mk
@@ -2204,8 +2204,9 @@
# $1: STL name as it appears in APP_STL (e.g. system)
#
ndk-stl-select = \
- $(call import-module,$(NDK_STL.$1.IMPORT_MODULE)) \
- $(eval STL_DEFAULT_STD_VERSION := $(strip $(NDK_STL.$1.DEFAULT_STD_VERSION)))
+ $(if $(filter none,$1),,\
+ $(call import-module,$(NDK_STL.$1.IMPORT_MODULE)) \
+ $(eval STL_DEFAULT_STD_VERSION := $(strip $(NDK_STL.$1.DEFAULT_STD_VERSION))))
# Called after all Android.mk files are parsed to add
# proper STL dependencies to every C++ module.
@@ -2217,7 +2218,7 @@
$(NDK_STL.$1.SHARED_LIBS),\
$(NDK_STL.$1.LDLIBS))
-$(call ndk-stl-register,none,cxx-stl/system)
+$(call ndk-stl-register,none)
$(call ndk-stl-register,system,cxx-stl/system,libstdc++)
$(call ndk-stl-register,\
diff --git a/checkbuild.py b/checkbuild.py
index 312c98d..c4fd57e 100755
--- a/checkbuild.py
+++ b/checkbuild.py
@@ -628,11 +628,143 @@
self.validate_notice(install_path)
-class Libcxx(ndk.builds.InvokeExternalBuildModule):
+def make_linker_script(path, libs):
+ with open(path, 'w') as linker_script:
+ linker_script.write('INPUT({})\n'.format(' '.join(libs)))
+
+
+def create_libcxx_linker_scripts(lib_dir, abi):
+ static_libs = ['-lc++_static', '-lc++abi']
+ is_arm = abi == 'armeabi-v7a'
+ needs_android_support = abi in ndk.abis.LP32_ABIS
+ if needs_android_support:
+ static_libs.append('-landroid_support')
+ if is_arm:
+ static_libs.extend(['-lunwind', '-ldl', '-latomic'])
+ make_linker_script(os.path.join(lib_dir, 'libc++.a'), static_libs)
+
+ shared_libs = []
+ if needs_android_support:
+ shared_libs.append('-landroid_support')
+ if is_arm:
+ shared_libs.extend(['-lunwind', '-latomic'])
+ shared_libs.append('-lc++_shared')
+ make_linker_script(os.path.join(lib_dir, 'libc++.so'), shared_libs)
+
+
+class Libcxx(ndk.builds.Module):
name = 'libc++'
path = 'sources/cxx-stl/llvm-libc++'
script = 'ndk/sources/cxx-stl/llvm-libc++/build.py'
arch_specific = True
+ deps = {
+ 'clang',
+ 'gcc',
+ 'host-tools',
+ 'libandroid_support',
+ 'meta',
+ 'ndk-build',
+ 'ndk-build-shortcut',
+ 'platforms',
+ 'sysroot',
+ }
+
+ def __init__(self):
+ super(Libcxx, self).__init__()
+ self.abis = None
+ self.obj_out = None
+ self.lib_out = None
+ self.libcxx_path = ndk.paths.android_path('external/libcxx')
+
+ def set_abis(self, arch):
+ if arch is None:
+ self.abis = ndk.abis.ALL_ABIS
+ else:
+ self.abis = ndk.abis.arch_to_abis(arch)
+
+ def build(self, build_dir, _dist_dir, args):
+ ndk_path = ndk.paths.get_install_path(build_dir)
+ ndk_build = os.path.join(ndk_path, 'ndk-build')
+ bionic_path = ndk.paths.android_path('bionic')
+
+ self.obj_out = os.path.join(build_dir, 'libcxx/obj')
+ self.lib_out = os.path.join(build_dir, 'libcxx/libs')
+ self.set_abis(args.arch)
+
+ android_mk = os.path.join(self.libcxx_path, 'Android.mk')
+ application_mk = os.path.join(self.libcxx_path, 'Application.mk')
+
+ build_cmd = [
+ 'bash', ndk_build, '-C', self.libcxx_path, 'V=1', 'NDK_LOG=1',
+ 'APP_ABI={}'.format(' '.join(self.abis)),
+ 'NDK_OUT=' + self.obj_out,
+ 'NDK_LIBS_OUT=' + self.lib_out,
+ 'LIBCXX_FORCE_REBUILD=true',
+ 'BIONIC_PATH=' + bionic_path,
+
+ # Tell ndk-build where all of our makefiles are. The defaults in
+ # ndk-build are only valid if we have a typical ndk-build layout
+ # with a jni/{Android,Application}.mk.
+ 'NDK_PROJECT_PATH=null',
+ 'APP_BUILD_SCRIPT=' + android_mk,
+ 'NDK_APPLICATION_MK=' + application_mk,
+ ]
+
+ print('Running: ' + ' '.join(build_cmd))
+ subprocess.check_call(build_cmd)
+
+ def install(self, out_dir, dist_dir, args):
+ ndk_path = ndk.paths.get_install_path(out_dir)
+ install_root = os.path.join(ndk_path, self.path)
+
+ if os.path.exists(install_root):
+ shutil.rmtree(install_root)
+ os.makedirs(install_root)
+
+ shutil.copy2(
+ os.path.join(self.libcxx_path, 'Android.mk'), install_root)
+ shutil.copy2(
+ os.path.join(self.libcxx_path, 'NOTICE'), install_root)
+ shutil.copytree(
+ os.path.join(self.libcxx_path, 'include'),
+ os.path.join(install_root, 'include'))
+ shutil.copytree(self.lib_out, os.path.join(install_root, 'libs'))
+
+ # TODO(danalbert): Fix the test runner to work with a separated test
+ # source and build output tree. The test runner itself works with this,
+ # but we need to do some work to separate the two when we invoke it.
+ shutil.copytree(
+ os.path.join(self.libcxx_path, 'test'),
+ os.path.join(install_root, 'test'),
+ symlinks=True)
+ shutil.copytree(
+ os.path.join(self.libcxx_path, 'utils'),
+ os.path.join(install_root, 'utils'))
+
+ for abi in self.abis:
+ lib_dir = os.path.join(install_root, 'libs', abi)
+
+ # The static libraries installed to the obj dir, not the lib dir.
+ self.install_static_libs(lib_dir, abi)
+
+ # Create linker scripts for the libraries we use so that we link
+ # things properly even when we're not using ndk-build. The linker
+ # will read the script in place of the library so that we link the
+ # unwinder and other support libraries appropriately.
+ create_libcxx_linker_scripts(lib_dir, abi)
+
+ def install_static_libs(self, lib_dir, abi):
+ static_lib_dir = os.path.join(self.obj_out, 'local', abi)
+
+ shutil.copy2(os.path.join(static_lib_dir, 'libc++abi.a'), lib_dir)
+ shutil.copy2(os.path.join(static_lib_dir, 'libc++_static.a'), lib_dir)
+
+ if abi == 'armeabi-v7a':
+ shutil.copy2(os.path.join(static_lib_dir, 'libunwind.a'), lib_dir)
+
+ if abi in ndk.abis.LP32_ABIS:
+ shutil.copy2(
+ os.path.join(static_lib_dir, 'libandroid_support.a'), lib_dir)
class Platforms(ndk.builds.Module):
diff --git a/sources/android/support/Android.mk b/sources/android/support/Android.mk
index d0e0060..2c50a47 100644
--- a/sources/android/support/Android.mk
+++ b/sources/android/support/Android.mk
@@ -26,8 +26,6 @@
# 32-bit ABIs
-BIONIC_PATH := ../../../../bionic
-
android_support_c_includes += \
$(BIONIC_PATH)/libc \
$(BIONIC_PATH)/libc/upstream-openbsd/android/include \
diff --git a/sources/cxx-stl/llvm-libc++/build.py b/sources/cxx-stl/llvm-libc++/build.py
deleted file mode 100755
index 02ce9d0..0000000
--- a/sources/cxx-stl/llvm-libc++/build.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Builds libc++ for Android."""
-from __future__ import print_function
-
-import os
-import shutil
-import site
-import subprocess
-
-THIS_DIR = os.path.realpath(os.path.dirname(__file__))
-site.addsitedir(os.path.join(THIS_DIR, '../../../build/lib'))
-
-import build_support # pylint: disable=import-error
-
-
-class ArgParser(build_support.ArgParser):
- def __init__(self): # pylint: disable=super-on-old-class
- super(ArgParser, self).__init__()
-
- self.add_argument(
- '--arch', choices=build_support.ALL_ARCHITECTURES,
- help='Architectures to build. Builds all if not present.')
-
-
-def make_linker_script(path, libs):
- with open(path, 'w') as linker_script:
- linker_script.write('INPUT({})\n'.format(' '.join(libs)))
-
-
-def main(args):
- arches = build_support.ALL_ARCHITECTURES
- if args.arch is not None:
- arches = [args.arch]
-
- abis = []
- for arch in arches:
- abis.extend(build_support.arch_to_abis(arch))
-
- ndk_build = build_support.ndk_path('build/ndk-build')
- prebuilt_ndk = build_support.android_path('prebuilts/ndk')
- platform_prebuilts = os.path.join(prebuilt_ndk, 'platform')
- platforms_root = os.path.join(prebuilt_ndk, 'current/platforms')
- unified_sysroot_path = os.path.join(platform_prebuilts, 'sysroot')
- toolchains_root = os.path.join(prebuilt_ndk, 'current/toolchains')
- libcxx_path = build_support.android_path('external/libcxx')
- obj_out = os.path.join(args.out_dir, 'libcxx/obj')
-
- # TODO(danalbert): Stop building to the source directory.
- # This is historical, and simplifies packaging a bit. We need to pack up
- # all the source as well as the libraries. If build_support.make_package
- # were to change to allow a list of directories instead of one directory,
- # we could make this unnecessary. Will be a follow up CL.
- lib_out = os.path.join(libcxx_path, 'libs')
-
- build_cmd = [
- 'bash', ndk_build, '-C', THIS_DIR, build_support.jobs_arg(), 'V=1',
- 'APP_ABI=' + ' '.join(abis),
-
- # Use the prebuilt platforms and toolchains.
- 'NDK_UNIFIED_SYSROOT_PATH=' + unified_sysroot_path,
- 'NDK_PLATFORMS_ROOT=' + platforms_root,
- 'NDK_TOOLCHAINS_ROOT=' + toolchains_root,
- 'NDK_NEW_TOOLCHAINS_LAYOUT=true',
-
- # Tell ndk-build where all of our makefiles are and where outputs
- # should go. The defaults in ndk-build are only valid if we have a
- # typical ndk-build layout with a jni/{Android,Application}.mk.
- 'NDK_PROJECT_PATH=null',
- 'APP_BUILD_SCRIPT=' + os.path.join(libcxx_path, 'Android.mk'),
- 'NDK_APPLICATION_MK=' + os.path.join(libcxx_path, 'Application.mk'),
- 'NDK_OUT=' + obj_out,
- 'NDK_LIBS_OUT=' + lib_out,
-
- # Make sure we don't pick up a cached copy.
- 'LIBCXX_FORCE_REBUILD=true',
- ]
- print('Building libc++ for ABIs: {}'.format(', '.join(abis)))
- print('Running: ' + ' '.join(build_cmd))
- subprocess.check_call(build_cmd)
-
- # The static libraries are installed to NDK_OUT, not NDK_LIB_OUT, so we
- # need to install them to our package directory.
- for abi in abis:
- static_lib_dir = os.path.join(obj_out, 'local', abi)
- install_dir = os.path.join(lib_out, abi)
- is_arm = abi.startswith('armeabi')
- needs_android_support = abi in ('armeabi-v7a', 'x86')
-
- if is_arm:
- shutil.copy2(
- os.path.join(static_lib_dir, 'libunwind.a'), install_dir)
-
- shutil.copy2(os.path.join(static_lib_dir, 'libc++abi.a'), install_dir)
- if needs_android_support:
- shutil.copy2(os.path.join(
- static_lib_dir, 'libandroid_support.a'), install_dir)
- shutil.copy2(
- os.path.join(static_lib_dir, 'libc++_static.a'), install_dir)
-
- # Create linker scripts for the libraries we use so that we link things
- # properly even when we're not using ndk-build. The linker will read
- # the script in place of the library so that we link the unwinder and
- # other support libraries appropriately.
- static_libs = ['-lc++_static', '-lc++abi']
- if needs_android_support:
- static_libs.append('-landroid_support')
- if is_arm:
- static_libs.extend(['-lunwind', '-ldl', '-latomic'])
- make_linker_script(os.path.join(install_dir, 'libc++.a'), static_libs)
-
- shared_libs = []
- if needs_android_support:
- shared_libs.append('-landroid_support')
- if is_arm:
- shared_libs.extend(['-lunwind', '-latomic'])
- shared_libs.append('-lc++_shared')
- make_linker_script(os.path.join(install_dir, 'libc++.so'), shared_libs)
-
- build_support.make_package('libc++', libcxx_path, args.dist_dir)
-
-
-if __name__ == '__main__':
- build_support.run(main, ArgParser)
diff --git a/sources/cxx-stl/llvm-libc++abi/Application.mk b/sources/cxx-stl/llvm-libc++abi/Application.mk
deleted file mode 100644
index f98280d..0000000
--- a/sources/cxx-stl/llvm-libc++abi/Application.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-NDK_TOOLCHAIN_VERSION := clang
-APP_STL := none
diff --git a/sources/cxx-stl/llvm-libc++abi/NOTICE b/sources/cxx-stl/llvm-libc++abi/NOTICE
deleted file mode 120000
index 72aac42..0000000
--- a/sources/cxx-stl/llvm-libc++abi/NOTICE
+++ /dev/null
@@ -1 +0,0 @@
-libcxxabi/LICENSE.TXT
\ No newline at end of file