1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 """ This modules implements rombuilders.
21 """
22 import logging
23 import os
24 import sys
25 import shutil
26 import types
27 from version import Version
28 import re
29 import escapeddict
30 import imaker
31
32
33
34 logger = logging.getLogger("rom")
35
36
38 """ Create from a config element a list of parent
39 that are abstract (not buildable).
40 """
41 result = []
42 while (config.parent != None):
43 if config.parent.abstract != None:
44 result.append(config.parent)
45 config = config.parent
46 return result
47
48 -def read_file_content(filename):
49 """ Read the whole file content.
50 """
51 ftr = open(filename, "r")
52 content = ftr.read()
53 ftr.close()
54 return content
55
57 """ Escape a string recursively.
58 """
59
60
61
62 return config.interpolate(string)
63
65 """ Retrieve the target name of a step
66 """
67 result = re.search(r"^(?P<target>.+?)\s*:", text, re.M)
68 if (result != None):
69 return result.groupdict()['target']
70 raise Exception("Could'nt determine target name")
71
73 """ Remove dusplicates values from an array. """
74 elements = {}
75 for element in array: elements[element] = element
76 return elements.keys()
77
84
88
90 """ Configuration Builder for iMaker tool.
91 This tool generate a makefile.
92 """
93
94 - def __init__(self, config, product, usevar=False):
95 self._config = config
96 self._product = product
97
99 """ Generates a mytraces.txt file under \epoc32 based on the <mytraces/>
100 XML sub-elements defined for the image.
101 """
102 sys.stdout.flush()
103 if config.has_key('mytraces.binaries') and len(str(config['mytraces.binaries'])) > 0:
104 mytracestxt = escape_string(config['mytraces.file'], config)
105 logger.debug("Writing %s file" % mytracestxt)
106 binaries = config['mytraces.binaries']
107 traces_file = open(mytracestxt, 'w')
108 for binary in binaries:
109 traces_file.write(str(binary) + "\n")
110 traces_file.close()
111
113 """ Generate the makefile from xml configuration.
114 That method should be splitted....it's to long!!!
115 """
116 configs = self._config.getConfigurations(self._product)
117 if (len(configs) > 0):
118
119
120 targets = {}
121
122 master_filename = configs[0]['main.makefile.template']
123
124 outputfilename = os.path.basename(master_filename)
125 if configs[0].has_key('output.makefile.filename'):
126 outputfilename = configs[0]['output.makefile.filename']
127
128 filename = "%s/%s" % (get_product_path_var(self._product), outputfilename)
129 output = open(filename, "w+")
130 output.write("# DO NOT EDIT - FILE AUTOMATICALLY GENERATED\n")
131 output.write("# HELIUM variant configuration tool (C) Nokia - 2007\n\n")
132 mkdefine = '__' + re.sub(r'[^\w]', '_', os.path.basename(outputfilename)).upper() + '__'
133 output.write("ifndef %s\n" % mkdefine)
134 output.write("%s := 1\n\n" % mkdefine)
135 master_template = read_file_content(master_filename)
136 output.write(configs[0].interpolate(master_template) + "\n")
137
138 for config in configs:
139
140
141
142
143 if config.type == None:
144 raise Exception("Type not defined for configuration '%s'" % config.name)
145
146
147 if config.has_key("%s.makefile.template" % config.type):
148 template = read_file_content(config["%s.makefile.template" % config.type])
149 image_types = config['image.type']
150 if not isinstance(config['image.type'], types.ListType):
151 image_types = [config['image.type']]
152 for romtype in image_types:
153 config['image.type'] = romtype
154 out = config.interpolate(str(template))
155 output.write(out+"\n")
156 subtargets = [get_makefile_target(out)]
157 for parent in get_abstract_parents(config):
158 if not targets.has_key(parent.name):
159 targets[parent.name] = {}
160 targets[parent.name]['parent'] = parent
161 targets[parent.name]['subtargets'] = []
162 targets[parent.name]['subtargets'].extend(subtargets)
163 targets[parent.name]['subtargets'] = remove_duplicates(targets[parent.name]['subtargets'])
164 subtargets = [parent.name]
165 config['image.type'] = image_types
166 else:
167
168 print "WARNING: Could not find template for %s (%s)" % (config.name,"%s.makefile.template" % config.type)
169
170
171
172 output.write("###############################################################################\n")
173 output.write("# Generated group target\n")
174 output.write("###############################################################################\n\n")
175 for target in targets.keys():
176 if targets[target]['parent']['build.parallel'] == 'true':
177 output.write("%s: %s\n\n" % (target, " ".join(targets[target]['subtargets'])))
178 output.write("%s-dryrun:\n" % target)
179 output.write("\t@$(CALL_TARGET) -n %s\n\n" % target)
180 else:
181 output.write("%s-dryrun:\n" % target)
182 for subtarget in targets[target]['subtargets']:
183 output.write("\t@$(CALL_TARGET) -n %s\n" % subtarget)
184 output.write("\n")
185 output.write("%s:\n" % target)
186 output.write("\t@echo === %s started\n" % target)
187 for subtarget in targets[target]['subtargets']:
188 output.write("\t$(CALL_TARGET) %s\n" % subtarget)
189 output.write("\t@echo === %s finished\n" % target)
190 output.write("\n")
191 output.write("\nendif # %s\n" % mkdefine)
192 output.close()
193 print "File %s has been generated." % filename
194 else:
195 raise Exception("Could not find configuration: '%s'" % self._product)
196
197
199 """ Builder that create roms using makefpsx.
200 """
202 self.configs = configs
203
205 """ Go throught the config and build each roms.
206 """
207 for config in self.configs:
208 for k in sorted(config.keys()):
209 value = config[k]
210 if isinstance(value, types.UnicodeType):
211 value = value.encode('ascii', 'ignore')
212 print k + ': ' + str(value)
213 image = Image(config)
214 image.build()
215 print '======================================'
216 print
217
219 """ An Image object represents a ROM image, or .fpsx file.
220 """
221
223 """ Initialise the Image object.
224 """
225 self.config = config
226
239
241 """ Creates the destination directory of the ROM files if it does not exist.
242 """
243 dest = self.config['rom.output.dir']
244 if not os.path.exists( dest ):
245 os.makedirs( dest )
246
248 """ Copies the CMT image under \epoc32 and to the destination directory of
249 the ROM image, if the image will include the CMT.
250 """
251
252 if self.config['image.nocmt'] != 'true':
253 dest = self.config['rom.output.dir']
254 logger.debug("Copying " + self.config['cmt'] + " to " + dest)
255 shutil.copy( self.config['cmt'], dest )
256 logger.debug("Copying " + self.config['cmt'] + " to " + self.config['rommake.cmt.path'])
257 shutil.copy( self.config['cmt'], self.config['rommake.cmt.path'] )
258
260 """ Generates the version text files that define the version of the ROM image.
261 These are in UTF16 little endian (Symbian) format.
262 """
263 Version('sw', self.config).write()
264 Version('langsw', self.config).write()
265 Version('model', self.config).write()
266
268 """ Generates a mytraces.txt file under \epoc32 based on the <mytraces/>
269 XML sub-elements defined for the image.
270 """
271 sys.stdout.flush()
272 if self.config.has_key('mytraces.binaries'):
273 logger.debug("Writing mytraces.txt file")
274 binaries = self.config['mytraces.binaries']
275 traces_file = open( str(self.config['rommake.mytraces.file']), 'w' )
276 for binary in binaries:
277 traces_file.write( str(binary) + "\n" )
278 traces_file.close()
279 else:
280 self._clean_mytraces()
281
283 """ Calls the make_fpsx.cmd to build a ROM image.
284 """
285 logger.debug("Building rom image: " + str(self))
286 sys.stdout.flush()
287
288 args = [str(self.config['rommake.command']),
289 '-hid',
290 str(self.config['rommake.hwid']),
291 '-p',
292 str(self.config['rommake.product.name']),
293 '-iby',
294 str(self.config['image.iby']),
295 '-type',
296 str(self.config['image.type']),
297 '-traces',
298 '-verbose',
299 '-target',
300 self.config['rom.output.dir'],
301 '-o' + str(self)]
302 if 'rommake.args' in self.config:
303 extra_args = str(self.config['rommake.args']).split( ' ' )
304 args += extra_args
305 logger.debug("with args: " + str(args))
306 os.chdir(os.path.dirname(str(self.config['rommake.command'])))
307 os.spawnv(os.P_WAIT, str(self.config['rommake.command']), args)
308
310 logger.debug("Removing mytraces.txt file")
311 if os.path.exists( str( self.config['rommake.mytraces.file'] ) ):
312 os.remove( str( self.config['rommake.mytraces.file'] ) )
313
315 os.chdir( self.config['rom.output.dir'] )
316 if not( os.path.isdir('temp') ):
317 os.mkdir( 'temp' )
318 if not( os.path.isdir('logs') ):
319 os.mkdir( 'logs' )
320 if not( os.path.isdir('obys') ):
321 os.mkdir( 'obys' )
322
323 for element in os.listdir('.'):
324 if( os.path.isfile(element) ):
325 if( element.endswith('.img') or element.endswith('.bin') or element.endswith('.bb5') ):
326 shutil.move( element, 'temp' )
327 if( element.endswith('.log') or element.endswith('.dir') or element.endswith('.symbol') ):
328 shutil.move( element, 'logs' )
329 if( element.endswith('.oby') ):
330 shutil.move( element, 'obys' )
331
332
333
335 """ Returns the filename of the image file once copied to the
336 \*_flash_images directory.
337 """
338
339 name = str(self.config['rom.id']) + '_' + self.config['image.type']
340
341
342 if self.config['image.ui'] == 'text':
343 name += "_text"
344
345
346 if self.config['image.nocmt'] == 'true':
347 name += "_nocmt"
348
349
350 if self.config['image.name.extension'] != '':
351 name += '_' + self.config['image.name.extension']
352
353 return name
354