Imported Upstream version 2.55.0
[platform/upstream/glib.git] / win32 / setup.py
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
11
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
30
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)
38
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, '..'))
46
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)
68
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'])
74
75     files = vars['libgio_2_0_la_SOURCES'].split() + \
76             vars['win32_more_sources_for_vcproj'].split()
77
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)")
96
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'])
116
117     files = vars['libglib_2_0_la_SOURCES'].split()
118
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)")
136
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'])
142
143     files = vars['libgobject_2_0_la_SOURCES'].split()
144
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)")
160
161 def read_vars_from_AM(path, vars = {}, conds = {}, filters = None):
162     '''
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
168     '''
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)
199
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
230
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
239
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)
258
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)
263
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 -------------------
292
293     #------------ submodule gobject -------------------
294     mkenums_vars = ver.copy()
295     process_in(os.path.join(srcroot, 'gobject', 'glib-mkenums.in'),
296                os.path.join(srcroot, 'gobject', 'glib-mkenums'),
297                mkenums_vars)
298
299     generate_libgobject_sourcefiles(srcroot,
300                                 os.path.join(srcroot, 'win32', 'libgobject.sourcefiles'), '9')
301     generate_libgobject_sourcefiles(srcroot,
302                                 os.path.join(srcroot, 'win32', 'libgobject.vs10.sourcefiles'), '10')
303     generate_libgobject_sourcefiles(srcroot,
304                                 os.path.join(srcroot, 'win32', 'libgobject.vs10.sourcefiles.filters'), '10f')
305     process_include(os.path.join(srcroot, 'win32', 'vs9', 'gobject.vcprojin'),
306                     os.path.join(srcroot, 'win32', 'vs9', 'gobject.vcproj'),
307                     includes = [os.path.join(srcroot, 'win32')])
308     process_include(os.path.join(srcroot, 'win32', 'vs10', 'gobject.vcxprojin'),
309                     os.path.join(srcroot, 'win32', 'vs10', 'gobject.vcxproj'),
310                     includes = [os.path.join(srcroot, 'win32')])
311     process_include(os.path.join(srcroot, 'win32', 'vs10', 'gobject.vcxproj.filtersin'),
312                     os.path.join(srcroot, 'win32', 'vs10', 'gobject.vcxproj.filters'),
313                     includes = [os.path.join(srcroot, 'win32')])
314     os.unlink(os.path.join(srcroot, 'win32', 'libgobject.sourcefiles'))
315     os.unlink(os.path.join(srcroot, 'win32', 'libgobject.vs10.sourcefiles'))
316     os.unlink(os.path.join(srcroot, 'win32', 'libgobject.vs10.sourcefiles.filters'))
317     #------------ end of submodule gobject -------------------
318
319     #------------ submodule gio -------------------
320     #depends on glib-mkenums
321     generate_libgio_sourcefiles(srcroot,
322                                 os.path.join(srcroot, 'win32', 'libgio.sourcefiles'), '9')
323     generate_libgio_sourcefiles(srcroot,
324                                 os.path.join(srcroot, 'win32', 'libgio.vs10.sourcefiles'), '10')
325     generate_libgio_sourcefiles(srcroot,
326                                 os.path.join(srcroot, 'win32', 'libgio.vs10.sourcefiles.filters'), '10f')
327     process_include(os.path.join(srcroot, 'win32', 'vs9', 'gio.vcprojin'),
328                     os.path.join(srcroot, 'win32', 'vs9', 'gio.vcproj'),
329                     includes = [os.path.join(srcroot, 'win32')])
330     process_include(os.path.join(srcroot, 'win32', 'vs10', 'gio.vcxprojin'),
331                     os.path.join(srcroot, 'win32', 'vs10', 'gio.vcxproj'),
332                     includes = [os.path.join(srcroot, 'win32')])
333     process_include(os.path.join(srcroot, 'win32', 'vs10', 'gio.vcxproj.filtersin'),
334                     os.path.join(srcroot, 'win32', 'vs10', 'gio.vcxproj.filters'),
335                     includes = [os.path.join(srcroot, 'win32')])
336     os.unlink(os.path.join(srcroot, 'win32', 'libgio.sourcefiles'))
337     os.unlink(os.path.join(srcroot, 'win32', 'libgio.vs10.sourcefiles'))
338     os.unlink(os.path.join(srcroot, 'win32', 'libgio.vs10.sourcefiles.filters'))
339     generate_libgio_enumtypes(srcroot, opt.perl)
340     #------------ end of submodule gio -------------------
341
342     #------------ submodule gmodule -------------------
343     #------------ end of submodule gmodule -------------------
344     return 0
345
346 if __name__ == '__main__':
347     sys.exit(main(sys.argv))