generate-darwin-source-and-headers.py 6.5 KB

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