2.53.6
[glib.git] / win32 / setup.py
blobec57dc88ee8e1c33d4858ba54e47e5ed3776e78b
1 #!/usr/bin/python
2 # vim: encoding=utf-8
3 #expand *.in files
4 #this script is only intended for building from git, not for building from the released tarball, which already includes all necessary files
5 import os
6 import sys
7 import re
8 import string
9 import subprocess
10 import optparse
12 def get_version(srcroot):
13 ver = {}
14 RE_VERSION = re.compile(r'^m4_define\(\[(glib_\w+)\],\s*\[(\d+)\]\)')
15 with open(os.path.join(srcroot, 'configure.ac'), 'r') as ac:
16 for i in ac:
17 mo = RE_VERSION.search(i)
18 if mo:
19 ver[mo.group(1).upper()] = int(mo.group(2))
20 ver['GLIB_BINARY_AGE'] = 100 * ver['GLIB_MINOR_VERSION'] + ver['GLIB_MICRO_VERSION']
21 ver['GLIB_VERSION'] = '%d.%d.%d' % (ver['GLIB_MAJOR_VERSION'],
22 ver['GLIB_MINOR_VERSION'],
23 ver['GLIB_MICRO_VERSION'])
24 ver['LT_RELEASE'] = '%d.%d' % (ver['GLIB_MAJOR_VERSION'], ver['GLIB_MINOR_VERSION'])
25 ver['LT_CURRENT'] = 100 * ver['GLIB_MINOR_VERSION'] + ver['GLIB_MICRO_VERSION'] - ver['GLIB_INTERFACE_AGE']
26 ver['LT_REVISION'] = ver['GLIB_INTERFACE_AGE']
27 ver['LT_AGE'] = ver['GLIB_BINARY_AGE'] - ver['GLIB_INTERFACE_AGE']
28 ver['LT_CURRENT_MINUS_AGE'] = ver['LT_CURRENT'] - ver['LT_AGE']
29 return ver
31 def process_in(src, dest, vars):
32 RE_VARS = re.compile(r'@(\w+?)@')
33 with open(src, 'r') as s:
34 with open(dest, 'w') as d:
35 for i in s:
36 i = RE_VARS.sub(lambda x: str(vars[x.group(1)]), i)
37 d.write(i)
39 def get_srcroot():
40 if not os.path.isabs(__file__):
41 path = os.path.abspath(__file__)
42 else:
43 path = __file__
44 dirname = os.path.dirname(path)
45 return os.path.abspath(os.path.join(dirname, '..'))
47 def process_include(src, dest, includes):
48 RE_INCLUDE = re.compile(r'^\s*#include\s+"(.*)"')
49 with open(src, 'r') as s:
50 with open(dest, 'w') as d:
51 for i in s:
52 mo = RE_INCLUDE.search(i)
53 if mo:
54 target = ''
55 for j in includes:
56 #print "searching in ", j
57 if mo.group(1) in os.listdir(j):
58 target = os.path.join(j, mo.group(1))
59 break
60 if not target:
61 raise Exception("Couldn't fine include file %s" % mo.group(1))
62 else:
63 with open(target, 'r') as t:
64 for inc in t.readlines():
65 d.write(inc)
66 else:
67 d.write(i)
69 def generate_libgio_sourcefiles(srcroot, dest, stype):
70 vars = read_vars_from_AM(os.path.join(srcroot, 'gio', 'Makefile.am'),
71 vars = {'top_srcdir': srcroot},
72 conds = {'OS_WIN32': True},
73 filters = ['libgio_2_0_la_SOURCES', 'win32_more_sources_for_vcproj'])
75 files = vars['libgio_2_0_la_SOURCES'].split() + \
76 vars['win32_more_sources_for_vcproj'].split()
78 sources = [i for i in files \
79 if i != 'gdesktopappinfo.c' and \
80 not (i.startswith('gunix') and i.endswith('.c')) \
81 and i.endswith('.c') ]
82 if stype == '9':
83 with open(dest, 'w') as d:
84 for i in sources:
85 d.write('\t\t\t<File RelativePath="..\\..\\gio\\' + i.replace('/', '\\') + '"/>\n')
86 elif stype == '10':
87 with open(dest, 'w') as d:
88 for i in sources:
89 d.write('\t\t\t<ClCompile Include="..\\..\\gio\\' + i.replace('/', '\\') + '"/>\n')
90 elif stype == '10f':
91 with open(dest, 'w') as d:
92 for i in sources:
93 d.write('\t\t\t<ClCompile Include="..\\..\\gio\\' + i.replace('/', '\\') + '"><Filter>Source Files</Filter></ClCompile>\n')
94 else:
95 raise Exception("Must specify project type (9, 10 or 10f)")
97 def generate_libgio_enumtypes(srcroot, perl):
98 vars = read_vars_from_AM(os.path.join(srcroot, 'gio', 'Makefile.am'),
99 vars = {'top_srcdir': srcroot},
100 conds = {'OS_WIN32': True},
101 filters = ['gio_headers'])
102 cwd = os.getcwd()
103 os.chdir(os.path.join(srcroot, 'gio'))
104 for suffix in ['.c', '.h']:
105 cmd = [perl, os.path.join(srcroot, 'gobject', 'glib-mkenums'),
106 '--template', 'gioenumtypes' + suffix + '.template'] + vars['gio_headers'].split()
107 with open('gioenumtypes' + suffix, 'w') as d:
108 subprocess.Popen(cmd, stdout = d).communicate()
109 os.chdir(cwd)
110 def generate_libglib_sourcefiles(srcroot, dest, stype):
111 vars = read_vars_from_AM(os.path.join(srcroot, 'glib', 'Makefile.am'),
112 vars = {'top_srcdir': srcroot},
113 conds = {'OS_WIN32': True,
114 'ENABLE_REGEX': True},
115 filters = ['libglib_2_0_la_SOURCES'])
117 files = vars['libglib_2_0_la_SOURCES'].split()
119 sources = [i for i in files \
120 if not (i.endswith('-gcc.c') or i.endswith('-unix.c')) \
121 and i.endswith('.c') ]
122 if stype == '9':
123 with open(dest, 'w') as d:
124 for i in sources:
125 d.write('\t\t\t<File RelativePath="..\\..\\glib\\' + i.replace('/', '\\') + '"/>\n')
126 elif stype == '10':
127 with open(dest, 'w') as d:
128 for i in sources:
129 d.write('\t\t\t<ClCompile Include="..\\..\\glib\\' + i.replace('/', '\\') + '"/>\n')
130 elif stype == '10f':
131 with open(dest, 'w') as d:
132 for i in sources:
133 d.write('\t\t\t<ClCompile Include="..\\..\\glib\\' + i.replace('/', '\\') + '"><Filter>Source Files</Filter></ClCompile>\n')
134 else:
135 raise Exception("Must specify project type (9, 10 or 10f)")
137 def generate_libgobject_sourcefiles(srcroot, dest, stype):
138 vars = read_vars_from_AM(os.path.join(srcroot, 'gobject', 'Makefile.am'),
139 vars = {'top_srcdir': srcroot},
140 conds = {'OS_WIN32': True},
141 filters = ['libgobject_2_0_la_SOURCES'])
143 files = vars['libgobject_2_0_la_SOURCES'].split()
145 sources = [i for i in files if i.endswith('.c') ]
146 if stype == '9':
147 with open(dest, 'w') as d:
148 for i in sources:
149 d.write('\t\t\t<File RelativePath="..\\..\\gobject\\' + i.replace('/', '\\') + '"/>\n')
150 elif stype == '10':
151 with open(dest, 'w') as d:
152 for i in sources:
153 d.write('\t\t\t<ClCompile Include="..\\..\\gobject\\' + i.replace('/', '\\') + '"/>\n')
154 elif stype == '10f':
155 with open(dest, 'w') as d:
156 for i in sources:
157 d.write('\t\t\t<ClCompile Include="..\\..\\gobject\\' + i.replace('/', '\\') + '"><Filter>Source Files</Filter></ClCompile>\n')
158 else:
159 raise Exception("Must specify project type (9, 10 or 10f)")
161 def read_vars_from_AM(path, vars = {}, conds = {}, filters = None):
163 path: path to the Makefile.am
164 vars: predefined variables
165 conds: condition variables for Makefile
166 filters: if None, all variables defined are returned,
167 otherwise, it is a list contains that variables should be returned
169 cur_vars = vars.copy()
170 RE_AM_VAR_REF = re.compile(r'\$\((\w+?)\)')
171 RE_AM_VAR = re.compile(r'^\s*(\w+)\s*=(.*)$')
172 RE_AM_INCLUDE = re.compile(r'^\s*include\s+(\w+)')
173 RE_AM_CONTINUING = re.compile(r'\\\s*$')
174 RE_AM_IF = re.compile(r'^\s*if\s+(\w+)')
175 RE_AM_ELSE = re.compile(r'^\s*else')
176 RE_AM_ENDIF = re.compile(r'^\s*endif')
177 def am_eval(cont):
178 return RE_AM_VAR_REF.sub(lambda x: cur_vars.get(x.group(1), ''), cont)
179 with open(path, 'r') as f:
180 contents = f.readlines()
181 #combine continuing lines
182 i = 0
183 ncont = []
184 while i < len(contents):
185 line = contents[i]
186 if RE_AM_CONTINUING.search(line):
187 line = RE_AM_CONTINUING.sub('', line)
188 j = i + 1
189 while j < len(contents) and RE_AM_CONTINUING.search(contents[j]):
190 line += RE_AM_CONTINUING.sub('', contents[j])
191 j += 1
192 else:
193 if j < len(contents):
194 line += contents[j]
195 i = j
196 else:
197 i += 1
198 ncont.append(line)
200 #include, var define, var evaluation
201 i = -1
202 skip = False
203 oldskip = []
204 while i < len(ncont) - 1:
205 i += 1
206 line = ncont[i]
207 mo = RE_AM_IF.search(line)
208 if mo:
209 oldskip.append(skip)
210 skip = False if mo.group(1) in conds and conds[mo.group(1)] \
211 else True
212 continue
213 mo = RE_AM_ELSE.search(line)
214 if mo:
215 skip = not skip
216 continue
217 mo = RE_AM_ENDIF.search(line)
218 if mo:
219 skip = oldskip.pop()
220 continue
221 if not skip:
222 mo = RE_AM_INCLUDE.search(line)
223 if mo:
224 cur_vars.update(read_vars_from_AM(am_eval(mo.group(1)), cur_vars, conds, None))
225 continue
226 mo = RE_AM_VAR.search(line)
227 if mo:
228 cur_vars[mo.group(1)] = am_eval(mo.group(2).strip())
229 continue
231 #filter:
232 if filters != None:
233 ret = {}
234 for i in filters:
235 ret[i] = cur_vars.get(i, '')
236 return ret
237 else:
238 return cur_vars
240 def main(argv):
241 parser = optparse.OptionParser()
242 parser.add_option('-p', '--perl', dest='perl', metavar='PATH', default='C:\\Perl\\bin\\perl.exe', action='store', help='path to the perl interpretor (default: C:\\Perl\\bin\\perl.exe)')
243 opt, args = parser.parse_args(argv)
244 srcroot = get_srcroot()
245 #print 'srcroot', srcroot
246 ver = get_version(srcroot)
247 #print 'ver', ver
248 config_vars = ver.copy()
249 config_vars['GETTEXT_PACKAGE'] = 'Glib'
250 process_in(os.path.join(srcroot, 'config.h.win32.in'),
251 os.path.join(srcroot, 'config.h'),
252 config_vars)
253 glibconfig_vars = ver.copy()
254 glibconfig_vars['GLIB_WIN32_STATIC_COMPILATION_DEFINE'] = ''
255 process_in(os.path.join(srcroot, 'glib', 'glibconfig.h.win32.in'),
256 os.path.join(srcroot, 'glib', 'glibconfig.h'),
257 glibconfig_vars)
259 for submodule in ['glib', 'gobject', 'gthread', 'gmodule', 'gio']:
260 process_in(os.path.join(srcroot, submodule, submodule + '.rc.in'),
261 os.path.join(srcroot, submodule, submodule + '.rc'),
262 ver)
264 #------------ submodule gobject -------------------
265 generate_libglib_sourcefiles(srcroot,
266 os.path.join(srcroot, 'win32', 'libglib.sourcefiles'), '9')
267 generate_libglib_sourcefiles(srcroot,
268 os.path.join(srcroot, 'win32', 'libglib.vs10.sourcefiles'), '10')
269 generate_libglib_sourcefiles(srcroot,
270 os.path.join(srcroot, 'win32', 'libglib.vs10.sourcefiles.filters'), '10f')
271 process_include(os.path.join(srcroot, 'win32', 'vs9', 'glib.vcprojin'),
272 os.path.join(srcroot, 'win32', 'vs9', 'glib.vcproj'),
273 includes = [os.path.join(srcroot, 'win32')])
274 process_include(os.path.join(srcroot, 'win32', 'vs10', 'glib.vcxprojin'),
275 os.path.join(srcroot, 'win32', 'vs10', 'glib.vcxproj'),
276 includes = [os.path.join(srcroot, 'win32')])
277 process_include(os.path.join(srcroot, 'win32', 'vs10', 'glib.vcxproj.filtersin'),
278 os.path.join(srcroot, 'win32', 'vs10', 'glib.vcxproj.filters'),
279 includes = [os.path.join(srcroot, 'win32')])
280 os.unlink(os.path.join(srcroot, 'win32', 'libglib.sourcefiles'))
281 os.unlink(os.path.join(srcroot, 'win32', 'libglib.vs10.sourcefiles'))
282 os.unlink(os.path.join(srcroot, 'win32', 'libglib.vs10.sourcefiles.filters'))
283 with open(os.path.join(srcroot, 'glib', 'gspawn-win32-helper-console.c'), 'w') as c:
284 c.write('#define HELPER_CONSOLE\n')
285 c.write('#include "gspawn-win32-helper.c"\n')
286 with open(os.path.join(srcroot, 'glib', 'gspawn-win64-helper-console.c'), 'w') as c:
287 c.write('#define HELPER_CONSOLE\n')
288 c.write('#include "gspawn-win32-helper.c"\n')
289 with open(os.path.join(srcroot, 'glib', 'gspawn-win64-helper.c'), 'w') as c:
290 c.write('#include "gspawn-win32-helper.c"\n')
291 #------------ end of submodule glib -------------------
293 #------------ submodule gobject -------------------
294 mkenums_vars = ver.copy()
295 mkenums_vars.update({'PERL_PATH': opt.perl})
296 process_in(os.path.join(srcroot, 'gobject', 'glib-mkenums.in'),
297 os.path.join(srcroot, 'gobject', 'glib-mkenums'),
298 mkenums_vars)
300 generate_libgobject_sourcefiles(srcroot,
301 os.path.join(srcroot, 'win32', 'libgobject.sourcefiles'), '9')
302 generate_libgobject_sourcefiles(srcroot,
303 os.path.join(srcroot, 'win32', 'libgobject.vs10.sourcefiles'), '10')
304 generate_libgobject_sourcefiles(srcroot,
305 os.path.join(srcroot, 'win32', 'libgobject.vs10.sourcefiles.filters'), '10f')
306 process_include(os.path.join(srcroot, 'win32', 'vs9', 'gobject.vcprojin'),
307 os.path.join(srcroot, 'win32', 'vs9', 'gobject.vcproj'),
308 includes = [os.path.join(srcroot, 'win32')])
309 process_include(os.path.join(srcroot, 'win32', 'vs10', 'gobject.vcxprojin'),
310 os.path.join(srcroot, 'win32', 'vs10', 'gobject.vcxproj'),
311 includes = [os.path.join(srcroot, 'win32')])
312 process_include(os.path.join(srcroot, 'win32', 'vs10', 'gobject.vcxproj.filtersin'),
313 os.path.join(srcroot, 'win32', 'vs10', 'gobject.vcxproj.filters'),
314 includes = [os.path.join(srcroot, 'win32')])
315 os.unlink(os.path.join(srcroot, 'win32', 'libgobject.sourcefiles'))
316 os.unlink(os.path.join(srcroot, 'win32', 'libgobject.vs10.sourcefiles'))
317 os.unlink(os.path.join(srcroot, 'win32', 'libgobject.vs10.sourcefiles.filters'))
318 #------------ end of submodule gobject -------------------
320 #------------ submodule gio -------------------
321 #depends on glib-mkenums
322 generate_libgio_sourcefiles(srcroot,
323 os.path.join(srcroot, 'win32', 'libgio.sourcefiles'), '9')
324 generate_libgio_sourcefiles(srcroot,
325 os.path.join(srcroot, 'win32', 'libgio.vs10.sourcefiles'), '10')
326 generate_libgio_sourcefiles(srcroot,
327 os.path.join(srcroot, 'win32', 'libgio.vs10.sourcefiles.filters'), '10f')
328 process_include(os.path.join(srcroot, 'win32', 'vs9', 'gio.vcprojin'),
329 os.path.join(srcroot, 'win32', 'vs9', 'gio.vcproj'),
330 includes = [os.path.join(srcroot, 'win32')])
331 process_include(os.path.join(srcroot, 'win32', 'vs10', 'gio.vcxprojin'),
332 os.path.join(srcroot, 'win32', 'vs10', 'gio.vcxproj'),
333 includes = [os.path.join(srcroot, 'win32')])
334 process_include(os.path.join(srcroot, 'win32', 'vs10', 'gio.vcxproj.filtersin'),
335 os.path.join(srcroot, 'win32', 'vs10', 'gio.vcxproj.filters'),
336 includes = [os.path.join(srcroot, 'win32')])
337 os.unlink(os.path.join(srcroot, 'win32', 'libgio.sourcefiles'))
338 os.unlink(os.path.join(srcroot, 'win32', 'libgio.vs10.sourcefiles'))
339 os.unlink(os.path.join(srcroot, 'win32', 'libgio.vs10.sourcefiles.filters'))
340 generate_libgio_enumtypes(srcroot, opt.perl)
341 #------------ end of submodule gio -------------------
343 #------------ submodule gmodule -------------------
344 #------------ end of submodule gmodule -------------------
345 return 0
347 if __name__ == '__main__':
348 sys.exit(main(sys.argv))