Home | History | Annotate | Download | only in tests
      1 #!/usr/bin/env python
      2 
      3 import os
      4 import subprocess
      5 import sys
      6 
      7 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
      8 ANDROID_BUILD_TOP = os.path.abspath(os.path.join(SCRIPT_DIR, *(['..'] * 5)))
      9 
     10 NDK_VERSION = 'r11'
     11 API_LEVEL = 'android-24'
     12 
     13 def get_prebuilts_host():
     14     if sys.platform.startswith('linux'):
     15         return 'linux-x86'
     16     if sys.platform.startswith('darwin'):
     17         return 'darwin-x86'
     18     raise NotImplementedError('unknown platform')
     19 
     20 def get_prebuilts_gcc(arch, gcc_version):
     21     return os.path.join(ANDROID_BUILD_TOP, 'prebuilts', 'gcc',
     22                         get_prebuilts_host(), arch, gcc_version)
     23 
     24 def get_prebuilts_clang():
     25     return os.path.join(ANDROID_BUILD_TOP, 'prebuilts', 'clang', 'host',
     26                         get_prebuilts_host(), 'clang-stable')
     27 
     28 def get_prebuilts_ndk(subdirs):
     29     return os.path.join(ANDROID_BUILD_TOP, 'prebuilts', 'ndk', NDK_VERSION,
     30                         'platforms', API_LEVEL, *subdirs)
     31 
     32 
     33 class Target(object):
     34     def __init__(self, name, triple, cflags, ldflags, gcc_toolchain_dir,
     35                  clang_dir, ndk_include, ndk_lib):
     36         self.name = name
     37         self.target_triple = triple
     38         self.target_cflags = cflags
     39         self.target_ldflags = ldflags
     40 
     41         self.gcc_toolchain_dir = gcc_toolchain_dir
     42         self.clang_dir = clang_dir
     43         self.ndk_include = ndk_include
     44         self.ndk_lib = ndk_lib
     45 
     46     def compile(self, obj_file, src_file, cflags):
     47         clang = os.path.join(self.clang_dir, 'bin', 'clang')
     48 
     49         cmd = [clang, '-o', obj_file, '-c', src_file]
     50         cmd.extend(['-fPIE', '-fPIC'])
     51         cmd.extend(['-gcc-toolchain', self.gcc_toolchain_dir])
     52         cmd.extend(['-target', self.target_triple])
     53         cmd.extend(['-isystem', self.ndk_include])
     54         cmd.extend(cflags)
     55         cmd.extend(self.target_cflags)
     56         subprocess.check_call(cmd)
     57 
     58     def link(self, out_file, obj_files, ldflags):
     59         if '-shared' in ldflags:
     60             crtbegin = os.path.join(self.ndk_lib, 'crtbegin_so.o')
     61             crtend = os.path.join(self.ndk_lib, 'crtend_so.o')
     62         else:
     63             crtbegin = os.path.join(self.ndk_lib, 'crtbegin_static.o')
     64             crtend = os.path.join(self.ndk_lib, 'crtend_android.o')
     65 
     66         clang = os.path.join(self.clang_dir, 'bin', 'clang')
     67 
     68         cmd = [clang, '-o', out_file]
     69         cmd.extend(['-fPIE', '-fPIC', '-Wl,--no-undefined', '-nostdlib'])
     70         cmd.append('-L' + self.ndk_lib)
     71         cmd.extend(['-gcc-toolchain', self.gcc_toolchain_dir])
     72         cmd.extend(['-target', self.target_triple])
     73         cmd.append(crtbegin)
     74         cmd.extend(obj_files)
     75         cmd.append(crtend)
     76         cmd.extend(ldflags)
     77         cmd.extend(self.target_ldflags)
     78         if '-shared' not in ldflags:
     79             cmd.append('-Wl,-pie')
     80         subprocess.check_call(cmd)
     81 
     82 def create_targets():
     83     return {
     84         'arm': Target('arm', 'arm-linux-androideabi', [],[],
     85             get_prebuilts_gcc('arm', 'arm-linux-androideabi-4.9'),
     86             get_prebuilts_clang(),
     87             get_prebuilts_ndk(['arch-arm', 'usr', 'include']),
     88             get_prebuilts_ndk(['arch-arm', 'usr', 'lib'])),
     89 
     90         'arm64': Target('arm64', 'aarch64-linux-android', [], [],
     91             get_prebuilts_gcc('aarch64', 'aarch64-linux-android-4.9'),
     92             get_prebuilts_clang(),
     93             get_prebuilts_ndk(['arch-arm64', 'usr', 'include']),
     94             get_prebuilts_ndk(['arch-arm64', 'usr', 'lib'])),
     95 
     96         'x86': Target('x86', 'x86_64-linux-android', ['-m32'], ['-m32'],
     97             get_prebuilts_gcc('x86', 'x86_64-linux-android-4.9'),
     98             get_prebuilts_clang(),
     99             get_prebuilts_ndk(['arch-x86', 'usr', 'include']),
    100             get_prebuilts_ndk(['arch-x86', 'usr', 'lib'])),
    101 
    102         'x86_64': Target('x86_64', 'x86_64-linux-android', ['-m64'], ['-m64'],
    103             get_prebuilts_gcc('x86', 'x86_64-linux-android-4.9'),
    104             get_prebuilts_clang(),
    105             get_prebuilts_ndk(['arch-x86_64', 'usr', 'include']),
    106             get_prebuilts_ndk(['arch-x86_64', 'usr', 'lib64'])),
    107 
    108         'mips': Target('mips', 'mipsel-linux-android', [], [],
    109             get_prebuilts_gcc('mips', 'mips64el-linux-android-4.9'),
    110             get_prebuilts_clang(),
    111             get_prebuilts_ndk(['arch-mips', 'usr', 'include']),
    112             get_prebuilts_ndk(['arch-mips', 'usr', 'lib'])),
    113 
    114         'mips64': Target('mips64', 'mips64el-linux-android',
    115             ['-march=mips64el', '-mcpu=mips64r6'],
    116             ['-march=mips64el', '-mcpu=mips64r6'],
    117             get_prebuilts_gcc('mips', 'mips64el-linux-android-4.9'),
    118             get_prebuilts_clang(),
    119             get_prebuilts_ndk(['arch-mips64', 'usr', 'include']),
    120             get_prebuilts_ndk(['arch-mips64', 'usr', 'lib64'])),
    121     }
    122