普通文本  |  122行  |  4.65 KB

#!/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'])),
    }