deps: Took out DirectX headers
[sdk] / deps / libffi-3.0.11 / generate-osx-source-and-headers.py
1 #!/usr/bin/env python
2 import subprocess
3 import re
4 import os
5 import errno
6 import collections
7 import sys
8
9 class Platform(object):
10     pass
11
12 sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)')
13
14 def sdkinfo(sdkname):
15     ret = {}
16     for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout:
17         kv = line.strip().split(': ', 1)
18         if len(kv) == 2:
19             k,v = kv
20             ret[k] = v
21     return ret
22
23 desktop_sdk_info = sdkinfo('macosx')
24
25 def latest_sdks():
26     latest_desktop = None
27     for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout:
28         match = sdk_re.match(line)
29         if match:
30             if 'OS X' in line:
31                 latest_desktop = match.group(1)
32
33     return latest_desktop
34
35 desktop_sdk = latest_sdks()
36
37 class desktop_platform_32(Platform):
38     sdk='macosx'
39     arch = 'i386'
40     name = 'mac32'
41     triple = 'i386-apple-darwin10'
42     sdkroot = desktop_sdk_info['Path']
43     
44     prefix = "#if defined(__i386__) && !defined(__x86_64__)\n\n"
45     suffix = "\n\n#endif"
46
47 class desktop_platform_64(Platform):
48     sdk='macosx'
49     arch = 'x86_64'
50     name = 'mac'
51     triple = 'x86_64-apple-darwin10'
52     sdkroot = desktop_sdk_info['Path']
53     
54     prefix = "#if !defined(__i386__) && defined(__x86_64__)\n\n"
55     suffix = "\n\n#endif"
56
57 def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
58     if not os.path.exists(dst_dir):
59         os.makedirs(dst_dir)
60     
61     out_filename = filename
62
63     if file_suffix:
64         split_name = os.path.splitext(filename)
65         out_filename =  "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
66
67     with open(os.path.join(src_dir, filename)) as in_file:
68         with open(os.path.join(dst_dir, out_filename), 'w') as out_file:
69             if prefix:
70                 out_file.write(prefix)
71
72             out_file.write(in_file.read())
73
74             if suffix:
75                 out_file.write(suffix)
76
77 headers_seen = collections.defaultdict(set)
78
79 def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None):
80     for root, dirs, files in os.walk(src_dir, followlinks=True):
81         relroot = os.path.relpath(root,src_dir)
82
83         def move_dir(arch, prefix='', suffix='', files=[]):
84             for file in files:
85                 file_suffix = None
86                 if file.endswith('.h'):
87                     if dest_include_dir:
88                         file_suffix = arch
89                         if arch:
90                             headers_seen[file].add(arch)
91                         move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix)
92
93                 elif dest_dir:
94                     outroot = os.path.join(dest_dir, relroot)
95                     move_file(root, outroot, file, prefix=prefix, suffix=suffix)
96
97         if relroot == '.':
98             move_dir(arch=arch,
99                      files=files,
100                      prefix=prefix,
101                      suffix=suffix)
102         elif relroot == 'x86':
103             move_dir(arch='i386',
104                      prefix="#if defined(__i386__) && !defined(__x86_64__)\n\n",
105                      suffix="\n\n#endif",
106                      files=files)
107             move_dir(arch='x86_64',
108                      prefix="#if !defined(__i386__) && defined(__x86_64__)\n\n",
109                      suffix="\n\n#endif",
110                      files=files)
111
112 def build_target(platform):
113     def xcrun_cmd(cmd):
114         return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip()
115
116     build_dir = 'build_' + platform.name
117     if not os.path.exists(build_dir):    
118         os.makedirs(build_dir)
119         env = dict(CC=xcrun_cmd('clang'),
120                    LD=xcrun_cmd('ld'),
121                    CFLAGS='-arch %s -isysroot %s -mmacosx-version-min=10.6' % (platform.arch, platform.sdkroot))
122         working_dir=os.getcwd()
123         try:
124             os.chdir(build_dir)
125             subprocess.check_call(['../configure', '-host', platform.triple], env=env)
126             move_source_tree('.', None, '../osx/include',
127                              arch=platform.arch,
128                              prefix=platform.prefix,
129                              suffix=platform.suffix)
130             move_source_tree('./include', None, '../osx/include',
131                              arch=platform.arch,
132                              prefix=platform.prefix,
133                              suffix=platform.suffix)
134         finally:
135             os.chdir(working_dir)
136
137         for header_name, archs in headers_seen.iteritems():
138             basename, suffix = os.path.splitext(header_name)
139
140 def main():
141     move_source_tree('src', 'osx/src', 'osx/include')
142     move_source_tree('include', None, 'osx/include')
143     build_target(desktop_platform_32)
144     build_target(desktop_platform_64)
145
146     for header_name, archs in headers_seen.iteritems():
147         basename, suffix = os.path.splitext(header_name)
148         with open(os.path.join('osx/include', header_name), 'w') as header:
149             for arch in archs:
150                 header.write('#include <%s_%s%s>\n' % (basename, arch, suffix))
151
152 if __name__ == '__main__':
153     main()