Home | History | Annotate | Download | only in llvm-libc++
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 2015 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 """Builds libc++ for Android."""
     18 from __future__ import print_function
     19 
     20 import os
     21 import shutil
     22 import site
     23 import subprocess
     24 
     25 THIS_DIR = os.path.realpath(os.path.dirname(__file__))
     26 site.addsitedir(os.path.join(THIS_DIR, '../../../build/lib'))
     27 
     28 import build_support  # pylint: disable=import-error
     29 
     30 
     31 class ArgParser(build_support.ArgParser):
     32     def __init__(self):  # pylint: disable=super-on-old-class
     33         super(ArgParser, self).__init__()
     34 
     35         self.add_argument(
     36             '--arch', choices=build_support.ALL_ARCHITECTURES,
     37             help='Architectures to build. Builds all if not present.')
     38 
     39 
     40 def main(args):
     41     arches = build_support.ALL_ARCHITECTURES
     42     if args.arch is not None:
     43         arches = [args.arch]
     44 
     45     abis = []
     46     for arch in arches:
     47         abis.extend(build_support.arch_to_abis(arch))
     48 
     49     ndk_build = build_support.ndk_path('build/ndk-build')
     50     prebuilt_ndk = build_support.android_path('prebuilts/ndk/current')
     51     platforms_root = os.path.join(prebuilt_ndk, 'platforms')
     52     toolchains_root = os.path.join(prebuilt_ndk, 'toolchains')
     53     libcxx_path = build_support.ndk_path('sources/cxx-stl/llvm-libc++')
     54     obj_out = os.path.join(args.out_dir, 'libcxx/obj')
     55 
     56     # TODO(danalbert): Stop building to the source directory.
     57     # This is historical, and simplifies packaging a bit. We need to pack up
     58     # all the source as well as the libraries. If build_support.make_package
     59     # were to change to allow a list of directories instead of one directory,
     60     # we could make this unnecessary.  Will be a follow up CL.
     61     lib_out = os.path.join(libcxx_path, 'libs')
     62 
     63     build_cmd = [
     64         'bash', ndk_build, '-C', THIS_DIR, build_support.jobs_arg(), 'V=1',
     65         'APP_ABI=' + ' '.join(abis),
     66 
     67         # Use the prebuilt platforms and toolchains.
     68         'NDK_PLATFORMS_ROOT=' + platforms_root,
     69         'NDK_TOOLCHAINS_ROOT=' + toolchains_root,
     70         'NDK_NEW_TOOLCHAINS_LAYOUT=true',
     71 
     72         # Tell ndk-build where all of our makefiles are and where outputs
     73         # should go. The defaults in ndk-build are only valid if we have a
     74         # typical ndk-build layout with a jni/{Android,Application}.mk.
     75         'NDK_PROJECT_PATH=null',
     76         'APP_BUILD_SCRIPT=' + os.path.join(THIS_DIR, 'Android.mk'),
     77         'NDK_APPLICATION_MK=' + os.path.join(THIS_DIR, 'Application.mk'),
     78         'NDK_OUT=' + obj_out,
     79         'NDK_LIBS_OUT=' + lib_out,
     80 
     81         # Make sure we don't pick up a cached copy.
     82         'LIBCXX_FORCE_REBUILD=true',
     83 
     84         # Put armeabi-v7a-hard in its own directory.
     85         '_NDK_TESTING_ALL_=yes',
     86     ]
     87     print('Building libc++ for ABIs: {}'.format(', '.join(abis)))
     88     subprocess.check_call(build_cmd)
     89 
     90     # The static libraries are installed to NDK_OUT, not NDK_LIB_OUT, so we
     91     # need to install them to our package directory.
     92     for abi in abis:
     93         static_lib_dir = os.path.join(obj_out, 'local', abi)
     94         install_dir = os.path.join(lib_out, abi)
     95         is_arm = abi.startswith('armeabi')
     96 
     97         if is_arm:
     98             shutil.copy2(
     99                 os.path.join(static_lib_dir, 'libunwind.a'), install_dir)
    100 
    101         shutil.copy2(os.path.join(static_lib_dir, 'libc++abi.a'), install_dir)
    102         shutil.copy2(
    103             os.path.join(static_lib_dir, 'libandroid_support.a'), install_dir)
    104         shutil.copy2(
    105             os.path.join(static_lib_dir, 'libc++_static.a'), install_dir)
    106 
    107     build_support.make_package('libcxx', libcxx_path, args.dist_dir)
    108 
    109 
    110 if __name__ == '__main__':
    111     build_support.run(main, ArgParser)
    112