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