github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/generate-darwin-source-and-headers.py (about)

     1  #!/usr/bin/env python
     2  import subprocess
     3  import os
     4  import errno
     5  import collections
     6  import glob
     7  import argparse
     8  
     9  class Platform(object):
    10      pass
    11  
    12  class simulator_platform(Platform):
    13      directory = 'darwin_ios'
    14      sdk = 'iphonesimulator'
    15      arch = 'i386'
    16      triple = 'i386-apple-darwin11'
    17      version_min = '-miphoneos-version-min=7.0'
    18  
    19      prefix = "#ifdef __i386__\n\n"
    20      suffix = "\n\n#endif"
    21      src_dir = 'x86'
    22      src_files = ['darwin.S', 'win32.S', 'ffi.c']
    23  
    24  
    25  class simulator64_platform(Platform):
    26      directory = 'darwin_ios'
    27      sdk = 'iphonesimulator'
    28      arch = 'x86_64'
    29      triple = 'x86_64-apple-darwin13'
    30      version_min = '-miphoneos-version-min=7.0'
    31  
    32      prefix = "#ifdef __x86_64__\n\n"
    33      suffix = "\n\n#endif"
    34      src_dir = 'x86'
    35      src_files = ['darwin64.S', 'ffi64.c']
    36  
    37  
    38  class device_platform(Platform):
    39      directory = 'darwin_ios'
    40      sdk = 'iphoneos'
    41      arch = 'armv7'
    42      triple = 'arm-apple-darwin11'
    43      version_min = '-miphoneos-version-min=7.0'
    44  
    45      prefix = "#ifdef __arm__\n\n"
    46      suffix = "\n\n#endif"
    47      src_dir = 'arm'
    48      src_files = ['sysv.S', 'trampoline.S', 'ffi.c']
    49  
    50  
    51  class device64_platform(Platform):
    52      directory = 'darwin_ios'
    53      sdk = 'iphoneos'
    54      arch = 'arm64'
    55      triple = 'aarch64-apple-darwin13'
    56      version_min = '-miphoneos-version-min=7.0'
    57  
    58      prefix = "#ifdef __arm64__\n\n"
    59      suffix = "\n\n#endif"
    60      src_dir = 'aarch64'
    61      src_files = ['sysv.S', 'ffi.c']
    62  
    63  
    64  class desktop32_platform(Platform):
    65      directory = 'darwin_osx'
    66      sdk = 'macosx'
    67      arch = 'i386'
    68      triple = 'i386-apple-darwin10'
    69      version_min = '-mmacosx-version-min=10.6'
    70      src_dir = 'x86'
    71      src_files = ['darwin.S', 'win32.S', 'ffi.c']
    72  
    73      prefix = "#ifdef __i386__\n\n"
    74      suffix = "\n\n#endif"
    75  
    76  
    77  class desktop64_platform(Platform):
    78      directory = 'darwin_osx'
    79      sdk = 'macosx'
    80      arch = 'x86_64'
    81      triple = 'x86_64-apple-darwin10'
    82      version_min = '-mmacosx-version-min=10.6'
    83  
    84      prefix = "#ifdef __x86_64__\n\n"
    85      suffix = "\n\n#endif"
    86      src_dir = 'x86'
    87      src_files = ['darwin64.S', 'ffi64.c']
    88  
    89  
    90  def mkdir_p(path):
    91      try:
    92          os.makedirs(path)
    93      except OSError as exc:  # Python >2.5
    94          if exc.errno == errno.EEXIST:
    95              pass
    96          else:
    97              raise
    98  
    99  
   100  def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
   101      mkdir_p(dst_dir)
   102      out_filename = filename
   103  
   104      if file_suffix:
   105          split_name = os.path.splitext(filename)
   106          out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
   107  
   108      with open(os.path.join(src_dir, filename)) as in_file:
   109          with open(os.path.join(dst_dir, out_filename), 'w') as out_file:
   110              if prefix:
   111                  out_file.write(prefix)
   112  
   113              out_file.write(in_file.read())
   114  
   115              if suffix:
   116                  out_file.write(suffix)
   117  
   118  
   119  def list_files(src_dir, pattern=None, filelist=None):
   120      if pattern: filelist = glob.iglob(os.path.join(src_dir, pattern))
   121      for file in filelist:
   122          yield os.path.basename(file)
   123  
   124  
   125  def copy_files(src_dir, dst_dir, pattern=None, filelist=None, file_suffix=None, prefix=None, suffix=None):
   126      for filename in list_files(src_dir, pattern=pattern, filelist=filelist):
   127          move_file(src_dir, dst_dir, filename, file_suffix=file_suffix, prefix=prefix, suffix=suffix)
   128  
   129  
   130  def copy_src_platform_files(platform):
   131      src_dir = os.path.join('src', platform.src_dir)
   132      dst_dir = os.path.join(platform.directory, 'src', platform.src_dir)
   133      copy_files(src_dir, dst_dir, filelist=platform.src_files, file_suffix=platform.arch, prefix=platform.prefix, suffix=platform.suffix)
   134  
   135  
   136  def build_target(platform, platform_headers):
   137      def xcrun_cmd(cmd):
   138          return 'xcrun -sdk %s %s -arch %s' % (platform.sdk, cmd, platform.arch)
   139  
   140      tag='%s-%s' % (platform.sdk, platform.arch)
   141      build_dir = 'build_%s' % tag
   142      mkdir_p(build_dir)
   143      env = dict(CC=xcrun_cmd('clang'),
   144                 LD=xcrun_cmd('ld'),
   145                 CFLAGS='%s' % (platform.version_min))
   146      working_dir = os.getcwd()
   147      try:
   148          os.chdir(build_dir)
   149          subprocess.check_call(['../configure', '-host', platform.triple], env=env)
   150      finally:
   151          os.chdir(working_dir)
   152  
   153      for src_dir in [build_dir, os.path.join(build_dir, 'include')]:
   154          copy_files(src_dir,
   155                     os.path.join(platform.directory, 'include'),
   156                     pattern='*.h',
   157                     file_suffix=platform.arch,
   158                     prefix=platform.prefix,
   159                     suffix=platform.suffix)
   160  
   161          for filename in list_files(src_dir, pattern='*.h'):
   162              platform_headers[filename].add((platform.prefix, platform.arch, platform.suffix))
   163  
   164  
   165  def make_tramp():
   166      with open('src/arm/trampoline.S', 'w') as tramp_out:
   167          p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out)
   168          p.wait()
   169  
   170  
   171  def generate_source_and_headers(generate_osx=True, generate_ios=True):
   172      copy_files('src', 'darwin_common/src', pattern='*.c')
   173      copy_files('include', 'darwin_common/include', pattern='*.h')
   174  
   175      if generate_ios:
   176          make_tramp()
   177          copy_src_platform_files(simulator_platform)
   178          copy_src_platform_files(simulator64_platform)
   179          copy_src_platform_files(device_platform)
   180          copy_src_platform_files(device64_platform)
   181      if generate_osx:
   182          copy_src_platform_files(desktop32_platform)
   183          copy_src_platform_files(desktop64_platform)
   184  
   185      platform_headers = collections.defaultdict(set)
   186  
   187      if generate_ios:
   188          build_target(simulator_platform, platform_headers)
   189          build_target(simulator64_platform, platform_headers)
   190          build_target(device_platform, platform_headers)
   191          build_target(device64_platform, platform_headers)
   192      if generate_osx:
   193          build_target(desktop32_platform, platform_headers)
   194          build_target(desktop64_platform, platform_headers)
   195  
   196      mkdir_p('darwin_common/include')
   197      for header_name, tag_tuples in platform_headers.iteritems():
   198          basename, suffix = os.path.splitext(header_name)
   199          with open(os.path.join('darwin_common/include', header_name), 'w') as header:
   200              for tag_tuple in tag_tuples:
   201                  header.write('%s#include <%s_%s%s>\n%s\n' % (tag_tuple[0], basename, tag_tuple[1], suffix, tag_tuple[2]))
   202  
   203  if __name__ == '__main__':
   204      parser = argparse.ArgumentParser()
   205      parser.add_argument('--only-ios', action='store_true', default=False)
   206      parser.add_argument('--only-osx', action='store_true', default=False)
   207      args = parser.parse_args()
   208  
   209      generate_source_and_headers(generate_osx=not args.only_ios, generate_ios=not args.only_osx)