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

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