Blame generate-darwin-source-and-headers.py

Packit 07cbca
#!/usr/bin/env python
Packit 07cbca
import subprocess
Packit 07cbca
import os
Packit 07cbca
import errno
Packit 07cbca
import collections
Packit 07cbca
import glob
Packit 07cbca
import argparse
Packit 07cbca
Packit 07cbca
class Platform(object):
Packit 07cbca
    pass
Packit 07cbca
Packit 07cbca
class simulator_platform(Platform):
Packit 07cbca
    directory = 'darwin_ios'
Packit 07cbca
    sdk = 'iphonesimulator'
Packit 07cbca
    arch = 'i386'
Packit 07cbca
    triple = 'i386-apple-darwin11'
Packit 07cbca
    version_min = '-miphoneos-version-min=5.1.1'
Packit 07cbca
Packit 07cbca
    prefix = "#ifdef __i386__\n\n"
Packit 07cbca
    suffix = "\n\n#endif"
Packit 07cbca
    src_dir = 'x86'
Packit 07cbca
    src_files = ['darwin.S', 'win32.S', 'ffi.c']
Packit 07cbca
Packit 07cbca
Packit 07cbca
class simulator64_platform(Platform):
Packit 07cbca
    directory = 'darwin_ios'
Packit 07cbca
    sdk = 'iphonesimulator'
Packit 07cbca
    arch = 'x86_64'
Packit 07cbca
    triple = 'x86_64-apple-darwin13'
Packit 07cbca
    version_min = '-miphoneos-version-min=7.0'
Packit 07cbca
Packit 07cbca
    prefix = "#ifdef __x86_64__\n\n"
Packit 07cbca
    suffix = "\n\n#endif"
Packit 07cbca
    src_dir = 'x86'
Packit 07cbca
    src_files = ['darwin64.S', 'ffi64.c']
Packit 07cbca
Packit 07cbca
Packit 07cbca
class device_platform(Platform):
Packit 07cbca
    directory = 'darwin_ios'
Packit 07cbca
    sdk = 'iphoneos'
Packit 07cbca
    arch = 'armv7'
Packit 07cbca
    triple = 'arm-apple-darwin11'
Packit 07cbca
    version_min = '-miphoneos-version-min=5.1.1'
Packit 07cbca
Packit 07cbca
    prefix = "#ifdef __arm__\n\n"
Packit 07cbca
    suffix = "\n\n#endif"
Packit 07cbca
    src_dir = 'arm'
Packit 07cbca
    src_files = ['sysv.S', 'trampoline.S', 'ffi.c']
Packit 07cbca
Packit 07cbca
Packit 07cbca
class device64_platform(Platform):
Packit 07cbca
    directory = 'darwin_ios'
Packit 07cbca
    sdk = 'iphoneos'
Packit 07cbca
    arch = 'arm64'
Packit 07cbca
    triple = 'aarch64-apple-darwin13'
Packit 07cbca
    version_min = '-miphoneos-version-min=7.0'
Packit 07cbca
Packit 07cbca
    prefix = "#ifdef __arm64__\n\n"
Packit 07cbca
    suffix = "\n\n#endif"
Packit 07cbca
    src_dir = 'aarch64'
Packit 07cbca
    src_files = ['sysv.S', 'ffi.c']
Packit 07cbca
Packit 07cbca
Packit 07cbca
class desktop32_platform(Platform):
Packit 07cbca
    directory = 'darwin_osx'
Packit 07cbca
    sdk = 'macosx'
Packit 07cbca
    arch = 'i386'
Packit 07cbca
    triple = 'i386-apple-darwin10'
Packit 07cbca
    version_min = '-mmacosx-version-min=10.6'
Packit 07cbca
    src_dir = 'x86'
Packit 07cbca
    src_files = ['darwin.S', 'win32.S', 'ffi.c']
Packit 07cbca
Packit 07cbca
    prefix = "#ifdef __i386__\n\n"
Packit 07cbca
    suffix = "\n\n#endif"
Packit 07cbca
Packit 07cbca
Packit 07cbca
class desktop64_platform(Platform):
Packit 07cbca
    directory = 'darwin_osx'
Packit 07cbca
    sdk = 'macosx'
Packit 07cbca
    arch = 'x86_64'
Packit 07cbca
    triple = 'x86_64-apple-darwin10'
Packit 07cbca
    version_min = '-mmacosx-version-min=10.6'
Packit 07cbca
Packit 07cbca
    prefix = "#ifdef __x86_64__\n\n"
Packit 07cbca
    suffix = "\n\n#endif"
Packit 07cbca
    src_dir = 'x86'
Packit 07cbca
    src_files = ['darwin64.S', 'ffi64.c']
Packit 07cbca
Packit 07cbca
Packit 07cbca
def mkdir_p(path):
Packit 07cbca
    try:
Packit 07cbca
        os.makedirs(path)
Packit 07cbca
    except OSError as exc:  # Python >2.5
Packit 07cbca
        if exc.errno == errno.EEXIST:
Packit 07cbca
            pass
Packit 07cbca
        else:
Packit 07cbca
            raise
Packit 07cbca
Packit 07cbca
Packit 07cbca
def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
Packit 07cbca
    mkdir_p(dst_dir)
Packit 07cbca
    out_filename = filename
Packit 07cbca
Packit 07cbca
    if file_suffix:
Packit 07cbca
        split_name = os.path.splitext(filename)
Packit 07cbca
        out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
Packit 07cbca
Packit 07cbca
    with open(os.path.join(src_dir, filename)) as in_file:
Packit 07cbca
        with open(os.path.join(dst_dir, out_filename), 'w') as out_file:
Packit 07cbca
            if prefix:
Packit 07cbca
                out_file.write(prefix)
Packit 07cbca
Packit 07cbca
            out_file.write(in_file.read())
Packit 07cbca
Packit 07cbca
            if suffix:
Packit 07cbca
                out_file.write(suffix)
Packit 07cbca
Packit 07cbca
Packit 07cbca
def list_files(src_dir, pattern=None, filelist=None):
Packit 07cbca
    if pattern: filelist = glob.iglob(os.path.join(src_dir, pattern))
Packit 07cbca
    for file in filelist:
Packit 07cbca
        yield os.path.basename(file)
Packit 07cbca
Packit 07cbca
Packit 07cbca
def copy_files(src_dir, dst_dir, pattern=None, filelist=None, file_suffix=None, prefix=None, suffix=None):
Packit 07cbca
    for filename in list_files(src_dir, pattern=pattern, filelist=filelist):
Packit 07cbca
        move_file(src_dir, dst_dir, filename, file_suffix=file_suffix, prefix=prefix, suffix=suffix)
Packit 07cbca
Packit 07cbca
Packit 07cbca
def copy_src_platform_files(platform):
Packit 07cbca
    src_dir = os.path.join('src', platform.src_dir)
Packit 07cbca
    dst_dir = os.path.join(platform.directory, 'src', platform.src_dir)
Packit 07cbca
    copy_files(src_dir, dst_dir, filelist=platform.src_files, file_suffix=platform.arch, prefix=platform.prefix, suffix=platform.suffix)
Packit 07cbca
Packit 07cbca
Packit 07cbca
def build_target(platform, platform_headers):
Packit 07cbca
    def xcrun_cmd(cmd):
Packit 07cbca
        return 'xcrun -sdk %s %s -arch %s' % (platform.sdk, cmd, platform.arch)
Packit 07cbca
Packit 07cbca
    tag='%s-%s' % (platform.sdk, platform.arch)
Packit 07cbca
    build_dir = 'build_%s' % tag
Packit 07cbca
    mkdir_p(build_dir)
Packit 07cbca
    env = dict(CC=xcrun_cmd('clang'),
Packit 07cbca
               LD=xcrun_cmd('ld'),
Packit 07cbca
               CFLAGS='%s' % (platform.version_min))
Packit 07cbca
    working_dir = os.getcwd()
Packit 07cbca
    try:
Packit 07cbca
        os.chdir(build_dir)
Packit 07cbca
        subprocess.check_call(['../configure', '-host', platform.triple], env=env)
Packit 07cbca
    finally:
Packit 07cbca
        os.chdir(working_dir)
Packit 07cbca
Packit 07cbca
    for src_dir in [build_dir, os.path.join(build_dir, 'include')]:
Packit 07cbca
        copy_files(src_dir,
Packit 07cbca
                   os.path.join(platform.directory, 'include'),
Packit 07cbca
                   pattern='*.h',
Packit 07cbca
                   file_suffix=platform.arch,
Packit 07cbca
                   prefix=platform.prefix,
Packit 07cbca
                   suffix=platform.suffix)
Packit 07cbca
Packit 07cbca
        for filename in list_files(src_dir, pattern='*.h'):
Packit 07cbca
            platform_headers[filename].add((platform.prefix, platform.arch, platform.suffix))
Packit 07cbca
Packit 07cbca
Packit 07cbca
def make_tramp():
Packit 07cbca
    with open('src/arm/trampoline.S', 'w') as tramp_out:
Packit 07cbca
        p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out)
Packit 07cbca
        p.wait()
Packit 07cbca
Packit 07cbca
Packit 07cbca
def generate_source_and_headers(generate_osx=True, generate_ios=True):
Packit 07cbca
    copy_files('src', 'darwin_common/src', pattern='*.c')
Packit 07cbca
    copy_files('include', 'darwin_common/include', pattern='*.h')
Packit 07cbca
Packit 07cbca
    if generate_ios:
Packit 07cbca
        make_tramp()
Packit 07cbca
        copy_src_platform_files(simulator_platform)
Packit 07cbca
        copy_src_platform_files(simulator64_platform)
Packit 07cbca
        copy_src_platform_files(device_platform)
Packit 07cbca
        copy_src_platform_files(device64_platform)
Packit 07cbca
    if generate_osx:
Packit 07cbca
        copy_src_platform_files(desktop32_platform)
Packit 07cbca
        copy_src_platform_files(desktop64_platform)
Packit 07cbca
Packit 07cbca
    platform_headers = collections.defaultdict(set)
Packit 07cbca
Packit 07cbca
    if generate_ios:
Packit 07cbca
        build_target(simulator_platform, platform_headers)
Packit 07cbca
        build_target(simulator64_platform, platform_headers)
Packit 07cbca
        build_target(device_platform, platform_headers)
Packit 07cbca
        build_target(device64_platform, platform_headers)
Packit 07cbca
    if generate_osx:
Packit 07cbca
        build_target(desktop32_platform, platform_headers)
Packit 07cbca
        build_target(desktop64_platform, platform_headers)
Packit 07cbca
Packit 07cbca
    mkdir_p('darwin_common/include')
Packit 07cbca
    for header_name, tag_tuples in platform_headers.iteritems():
Packit 07cbca
        basename, suffix = os.path.splitext(header_name)
Packit 07cbca
        with open(os.path.join('darwin_common/include', header_name), 'w') as header:
Packit 07cbca
            for tag_tuple in tag_tuples:
Packit 07cbca
                header.write('%s#include <%s_%s%s>\n%s\n' % (tag_tuple[0], basename, tag_tuple[1], suffix, tag_tuple[2]))
Packit 07cbca
Packit 07cbca
if __name__ == '__main__':
Packit 07cbca
    parser = argparse.ArgumentParser()
Packit 07cbca
    parser.add_argument('--only-ios', action='store_true', default=False)
Packit 07cbca
    parser.add_argument('--only-osx', action='store_true', default=False)
Packit 07cbca
    args = parser.parse_args()
Packit 07cbca
Packit 07cbca
    generate_source_and_headers(generate_osx=not args.only_ios, generate_ios=not args.only_osx)