#!/usr/bin/env python
import os
import subprocess
import sys
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
ANDROID_BUILD_TOP = os.path.abspath(os.path.join(SCRIPT_DIR, *(['..'] * 5)))
NDK_VERSION = 'r11'
API_LEVEL = 'android-24'
def get_prebuilts_host():
if sys.platform.startswith('linux'):
return 'linux-x86'
if sys.platform.startswith('darwin'):
return 'darwin-x86'
raise NotImplementedError('unknown platform')
def get_prebuilts_gcc(arch, gcc_version):
return os.path.join(ANDROID_BUILD_TOP, 'prebuilts', 'gcc',
get_prebuilts_host(), arch, gcc_version)
def get_prebuilts_clang():
return os.path.join(ANDROID_BUILD_TOP, 'prebuilts', 'clang', 'host',
get_prebuilts_host(), 'clang-stable')
def get_prebuilts_ndk(subdirs):
return os.path.join(ANDROID_BUILD_TOP, 'prebuilts', 'ndk', NDK_VERSION,
'platforms', API_LEVEL, *subdirs)
class Target(object):
def __init__(self, name, triple, cflags, ldflags, gcc_toolchain_dir,
clang_dir, ndk_include, ndk_lib):
self.name = name
self.target_triple = triple
self.target_cflags = cflags
self.target_ldflags = ldflags
self.gcc_toolchain_dir = gcc_toolchain_dir
self.clang_dir = clang_dir
self.ndk_include = ndk_include
self.ndk_lib = ndk_lib
def compile(self, obj_file, src_file, cflags):
clang = os.path.join(self.clang_dir, 'bin', 'clang')
cmd = [clang, '-o', obj_file, '-c', src_file]
cmd.extend(['-fPIE', '-fPIC'])
cmd.extend(['-gcc-toolchain', self.gcc_toolchain_dir])
cmd.extend(['-target', self.target_triple])
cmd.extend(['-isystem', self.ndk_include])
cmd.extend(cflags)
cmd.extend(self.target_cflags)
subprocess.check_call(cmd)
def link(self, out_file, obj_files, ldflags):
if '-shared' in ldflags:
crtbegin = os.path.join(self.ndk_lib, 'crtbegin_so.o')
crtend = os.path.join(self.ndk_lib, 'crtend_so.o')
else:
crtbegin = os.path.join(self.ndk_lib, 'crtbegin_static.o')
crtend = os.path.join(self.ndk_lib, 'crtend_android.o')
clang = os.path.join(self.clang_dir, 'bin', 'clang')
cmd = [clang, '-o', out_file]
cmd.extend(['-fPIE', '-fPIC', '-Wl,--no-undefined', '-nostdlib'])
cmd.append('-L' + self.ndk_lib)
cmd.extend(['-gcc-toolchain', self.gcc_toolchain_dir])
cmd.extend(['-target', self.target_triple])
cmd.append(crtbegin)
cmd.extend(obj_files)
cmd.append(crtend)
cmd.extend(ldflags)
cmd.extend(self.target_ldflags)
if '-shared' not in ldflags:
cmd.append('-Wl,-pie')
subprocess.check_call(cmd)
def create_targets():
return {
'arm': Target('arm', 'arm-linux-androideabi', [],[],
get_prebuilts_gcc('arm', 'arm-linux-androideabi-4.9'),
get_prebuilts_clang(),
get_prebuilts_ndk(['arch-arm', 'usr', 'include']),
get_prebuilts_ndk(['arch-arm', 'usr', 'lib'])),
'arm64': Target('arm64', 'aarch64-linux-android', [], [],
get_prebuilts_gcc('aarch64', 'aarch64-linux-android-4.9'),
get_prebuilts_clang(),
get_prebuilts_ndk(['arch-arm64', 'usr', 'include']),
get_prebuilts_ndk(['arch-arm64', 'usr', 'lib'])),
'x86': Target('x86', 'x86_64-linux-android', ['-m32'], ['-m32'],
get_prebuilts_gcc('x86', 'x86_64-linux-android-4.9'),
get_prebuilts_clang(),
get_prebuilts_ndk(['arch-x86', 'usr', 'include']),
get_prebuilts_ndk(['arch-x86', 'usr', 'lib'])),
'x86_64': Target('x86_64', 'x86_64-linux-android', ['-m64'], ['-m64'],
get_prebuilts_gcc('x86', 'x86_64-linux-android-4.9'),
get_prebuilts_clang(),
get_prebuilts_ndk(['arch-x86_64', 'usr', 'include']),
get_prebuilts_ndk(['arch-x86_64', 'usr', 'lib64'])),
'mips': Target('mips', 'mipsel-linux-android', [], [],
get_prebuilts_gcc('mips', 'mips64el-linux-android-4.9'),
get_prebuilts_clang(),
get_prebuilts_ndk(['arch-mips', 'usr', 'include']),
get_prebuilts_ndk(['arch-mips', 'usr', 'lib'])),
'mips64': Target('mips64', 'mips64el-linux-android',
['-march=mips64el', '-mcpu=mips64r6'],
['-march=mips64el', '-mcpu=mips64r6'],
get_prebuilts_gcc('mips', 'mips64el-linux-android-4.9'),
get_prebuilts_clang(),
get_prebuilts_ndk(['arch-mips64', 'usr', 'include']),
get_prebuilts_ndk(['arch-mips64', 'usr', 'lib64'])),
}