OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 import buildbot_common | 6 import buildbot_common |
7 import optparse | 7 import optparse |
8 import os | 8 import os |
9 import sys | 9 import sys |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... | |
39 return '$(patsubst %%.%s,%%_%s.o,$(%s_%s))' % (ext, arch, macro, EXT) | 39 return '$(patsubst %%.%s,%%_%s.o,$(%s_%s))' % (ext, arch, macro, EXT) |
40 | 40 |
41 | 41 |
42 def SetVar(varname, values): | 42 def SetVar(varname, values): |
43 if not values: | 43 if not values: |
44 return varname + ':=\n' | 44 return varname + ':=\n' |
45 | 45 |
46 line = varname + ':=' | 46 line = varname + ':=' |
47 out = '' | 47 out = '' |
48 for value in values: | 48 for value in values: |
49 if not line: | 49 if not line: |
binji
2012/06/11 20:22:29
is this if needed anymore? It looks like line shou
noelallen1
2012/06/11 20:34:38
Done.
| |
50 line = varname + '+=' | 50 line = varname + '+=' |
51 if len(line) + len(value) > 78: | 51 if len(line) + len(value) > 78: |
52 out += line[:-1] + '\n' | 52 out += line[:-1] + '\n' |
53 line = '' | 53 line = '%s+=%s ' % (varname, value) |
54 else: | 54 else: |
55 line += value + ' ' | 55 line += value + ' ' |
56 | 56 |
57 if line: | 57 if line: |
58 out += line[:-1] + '\n' | 58 out += line[:-1] + '\n' |
59 return out | 59 return out |
60 | 60 |
61 | 61 |
62 def GenerateCopyList(desc): | 62 def GenerateCopyList(desc): |
63 sources = [] | 63 sources = [] |
64 | 64 |
65 # Add sources for each target | 65 # Add sources for each target |
66 for target in desc['TARGETS']: | 66 for target in desc['TARGETS']: |
67 sources.extend(target['SOURCES']) | 67 sources.extend(target['SOURCES']) |
68 | 68 |
69 # And HTML and data files | 69 # And HTML and data files |
70 sources.append(desc['NAME'] + '.html') | 70 sources.append(desc['NAME'] + '.html') |
71 sources.extend(desc.get('DATA', [])) | 71 sources.extend(desc.get('DATA', [])) |
72 return sources | 72 return sources |
73 | 73 |
74 | 74 |
75 def GenerateReplacements(desc): | 75 def GenerateReplacements(desc): |
76 # Generate target settings | 76 # Generate target settings |
77 tools = desc['TOOLS'] | 77 tools = desc['TOOLS'] |
78 | 78 |
79 prelaunch = '' | 79 prerun = desc.get('PRE', '') |
80 prerun = '' | 80 postlaunch = desc.get('POST', '') |
81 | 81 |
82 settings = SetVar('VALID_TOOLCHAINS', tools) | 82 settings = SetVar('VALID_TOOLCHAINS', tools) |
83 settings+= 'TOOLCHAIN?=%s\n\n' % tools[0] | 83 settings+= 'TOOLCHAIN?=%s\n\n' % tools[0] |
84 | 84 |
85 rules = '' | 85 rules = '' |
86 targets = [] | 86 targets = [] |
87 remaps = '' | |
87 for target in desc['TARGETS']: | 88 for target in desc['TARGETS']: |
88 name = target['NAME'] | 89 name = target['NAME'] |
89 macro = name.upper() | 90 macro = name.upper() |
90 ext = GetExtType(target) | 91 ext = GetExtType(target) |
91 | 92 |
92 sources = target['SOURCES'] | 93 sources = target['SOURCES'] |
93 cc_sources = [fname for fname in sources if fname.endswith('.c')] | 94 cc_sources = [fname for fname in sources if fname.endswith('.c')] |
94 cxx_sources = [fname for fname in sources if fname.endswith('.cc')] | 95 cxx_sources = [fname for fname in sources if fname.endswith('.cc')] |
95 | 96 |
96 if cc_sources: | 97 if cc_sources: |
(...skipping 21 matching lines...) Expand all Loading... | |
118 objs = '%s_%s_CXX_O' % (macro, arch) | 119 objs = '%s_%s_CXX_O' % (macro, arch) |
119 rules += '%s:=%s\n' % (objs, GenPatsubst(arch, macro, 'cc', 'CXX')) | 120 rules += '%s:=%s\n' % (objs, GenPatsubst(arch, macro, 'cc', 'CXX')) |
120 rules += '$(%s) : %%_%s.o : %%.cc $(THIS_MAKEFILE)\n' % (objs, arch) | 121 rules += '$(%s) : %%_%s.o : %%.cc $(THIS_MAKEFILE)\n' % (objs, arch) |
121 rules += '\t$(NACL_CXX) -o $@ $< -m%s $(%s_CXXFLAGS)\n\n' % (arch, | 122 rules += '\t$(NACL_CXX) -o $@ $< -m%s $(%s_CXXFLAGS)\n\n' % (arch, |
122 macro) | 123 macro) |
123 object_sets.append('$(%s)' % objs) | 124 object_sets.append('$(%s)' % objs) |
124 target_name = '%s_x86_%s%s' % (name, arch, ext) | 125 target_name = '%s_x86_%s%s' % (name, arch, ext) |
125 targets.append(target_name) | 126 targets.append(target_name) |
126 rules += '%s : %s\n' % (target_name, ' '.join(object_sets)) | 127 rules += '%s : %s\n' % (target_name, ' '.join(object_sets)) |
127 rules += '\t$(NACL_LINK) -o $@ $^ -m%s $(%s_LDFLAGS)\n\n' % (arch, macro) | 128 rules += '\t$(NACL_LINK) -o $@ $^ -m%s $(%s_LDFLAGS)\n\n' % (arch, macro) |
129 if target['TYPE'] == 'so': | |
130 remaps += ' -n %s,%s.so' % (target_name, name) | |
128 | 131 |
129 nmf = desc['NAME'] + '.nmf' | 132 nmf = desc['NAME'] + '.nmf' |
130 nmfs = '%s : %s\n' % (nmf, ' '.join(targets)) | 133 nmfs = '%s : %s\n' % (nmf, ' '.join(targets)) |
131 nmfs +='\t$(NMF) $(NMF_ARGS) -o $@ $(NMF_PATHS) $^\n' | 134 nmfs +='\t$(NMF) $(NMF_ARGS) -o $@ $(NMF_PATHS) $^%s\n' % remaps |
132 | 135 |
133 targets = 'all : '+ ' '.join(targets + [nmf]) | 136 targets = 'all : '+ ' '.join(targets + [nmf]) |
134 return { | 137 return { |
135 '__PROJECT_SETTINGS__' : settings, | 138 '__PROJECT_SETTINGS__' : settings, |
136 '__PROJECT_TARGETS__' : targets, | 139 '__PROJECT_TARGETS__' : targets, |
137 '__PROJECT_RULES__' : rules, | 140 '__PROJECT_RULES__' : rules, |
138 '__PROJECT_NMFS__' : nmfs, | 141 '__PROJECT_NMFS__' : nmfs, |
139 '__PROJECT_PRELAUNCH__' : prelaunch, | 142 '__PROJECT_PRELAUNCH__' : prelaunch, |
140 '__PROJECT_PRERUN__' : prerun | 143 '__PROJECT_PRERUN__' : prerun, |
141 | 144 '__PROJECT_POSTLAUNCH__' : postlaunch |
142 } | 145 } |
143 | 146 |
144 | 147 |
145 # 'KEY' : ( <TYPE>, [Accepted Values], <Required?>) | 148 # 'KEY' : ( <TYPE>, [Accepted Values], <Required?>) |
146 DSC_FORMAT = { | 149 DSC_FORMAT = { |
147 'TOOLS' : (list, ['newlib', 'glibc', 'pnacl'], True), | 150 'TOOLS' : (list, ['newlib', 'glibc', 'pnacl'], True), |
148 'TARGETS' : (list, { | 151 'TARGETS' : (list, { |
149 'NAME': (str, '', True), | 152 'NAME': (str, '', True), |
150 'TYPE': (str, ['main', 'nexe', 'so'], True), | 153 'TYPE': (str, ['main', 'nexe', 'so'], True), |
151 'SOURCES': (list, '', True), | 154 'SOURCES': (list, '', True), |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
231 failed = True | 234 failed = True |
232 continue | 235 continue |
233 | 236 |
234 # If we got this far, it's an unexpected type | 237 # If we got this far, it's an unexpected type |
235 ErrorMsg('Unexpected type %s for key %s.' % (str(type(src[key])), key)) | 238 ErrorMsg('Unexpected type %s for key %s.' % (str(type(src[key])), key)) |
236 continue | 239 continue |
237 | 240 |
238 return not failed | 241 return not failed |
239 | 242 |
240 | 243 |
241 def ProcessProject(options, filename): | 244 def AddMakeBat(pepperdir, makepath): |
242 print 'Processing %s...' % filename | 245 """Create a simple batch file to execute Make. |
246 | |
247 Creates a simple batch file named make.bat for the Windows platform at the | |
248 given path, pointing to the Make executable in the SDK.""" | |
249 | |
250 makepath = os.path.abspath(makepath) | |
251 if not makepath.startswith(pepperdir): | |
252 buildbot_common.ErrorExit('Make.bat not relative to Pepper directory: ' + | |
253 makepath) | |
254 | |
255 makeexe = os.path.abspath(os.path.join(pepperdir, 'tools')) | |
256 relpath = os.path.relpath(makeexe, makepath) | |
257 | |
258 fp = open(os.path.join(makepath, 'make.bat'), 'wb') | |
259 outpath = os.path.join(relpath, 'make.exe') | |
260 | |
261 # Since make.bat is only used by Windows, for Windows path style | |
262 outpath = outpath.replace(os.path.sep, '\\') | |
263 fp.write('@%s %%*\n' % outpath) | |
264 fp.close() | |
265 | |
266 | |
267 def ProcessProject(dstroot, template, filename): | |
268 print '\n\nProcessing %s...' % filename | |
243 # Default src directory is the directory the description was found in | 269 # Default src directory is the directory the description was found in |
244 src_dir = os.path.dirname(os.path.abspath(filename)) | 270 src_dir = os.path.dirname(os.path.abspath(filename)) |
245 desc = open(filename, 'rb').read() | 271 desc = open(filename, 'rb').read() |
246 desc = eval(desc, {}, {}) | 272 desc = eval(desc, {}, {}) |
247 if not ValidateFormat(desc, DSC_FORMAT): | 273 if not ValidateFormat(desc, DSC_FORMAT): |
248 return False | 274 return (None, None) |
249 | 275 |
250 name = desc['NAME'] | 276 name = desc['NAME'] |
251 out_dir = os.path.join(options.dstroot, desc['DEST'], name) | 277 out_dir = os.path.join(dstroot, desc['DEST'], name) |
252 buildbot_common.MakeDir(out_dir) | 278 buildbot_common.MakeDir(out_dir) |
253 | 279 |
254 # Copy sources to example directory | 280 # Copy sources to example directory |
255 sources = GenerateCopyList(desc) | 281 sources = GenerateCopyList(desc) |
256 for src_name in sources: | 282 for src_name in sources: |
257 src_file = os.path.join(src_dir, src_name) | 283 src_file = os.path.join(src_dir, src_name) |
258 dst_file = os.path.join(out_dir, src_name) | 284 dst_file = os.path.join(out_dir, src_name) |
259 buildbot_common.CopyFile(src_file, dst_file) | 285 buildbot_common.CopyFile(src_file, dst_file) |
260 | 286 |
261 # Add Makefile | 287 # Add Makefile |
262 repdict = GenerateReplacements(desc) | 288 repdict = GenerateReplacements(desc) |
263 make_path = os.path.join(out_dir, 'Makefile') | 289 make_path = os.path.join(out_dir, 'Makefile') |
264 WriteMakefile(options.template, make_path, repdict) | 290 WriteMakefile(template, make_path, repdict) |
265 return True | 291 |
292 outdir = os.path.dirname(os.path.abspath(make_path)) | |
293 pepperdir = os.path.dirname(os.path.dirname(outdir)) | |
294 AddMakeBat(pepperdir, outdir) | |
295 return (name, desc['DEST']) | |
296 | |
297 | |
298 def GenerateExamplesMakefile(in_path, out_path, examples): | |
299 """Generate a Makefile that includes only the examples supported by this | |
300 SDK.""" | |
301 # Line wrap the PROJECTS variable | |
302 wrap_width = 80 | |
303 projects_text = '' | |
304 projects_line = 'PROJECTS:=' | |
binji
2012/06/11 20:22:29
Can you use SetVar() to wrap this?
noelallen1
2012/06/11 20:34:38
Done.
| |
305 for example in examples: | |
306 if len(projects_line + example + ' ') > wrap_width: | |
307 projects_text += projects_line + '\n' | |
308 projects_line = 'PROJECTS+=' | |
309 projects_line += example + ' ' | |
310 | |
311 # Add the last unwrapped line | |
312 projects_text += projects_line + '\n' | |
313 | |
314 out_makefile_text = '' | |
315 wrote_projects_text = False | |
316 snipping = False | |
317 for line in open(in_path, 'r'): | |
318 if line.startswith('# =SNIP='): | |
319 snipping = not snipping | |
320 continue | |
321 | |
322 if snipping: | |
323 if not wrote_projects_text: | |
324 out_makefile_text += projects_text | |
325 wrote_projects_text = True | |
326 else: | |
327 out_makefile_text += line | |
328 open(out_path, 'w').write(out_makefile_text) | |
329 | |
330 outdir = os.path.dirname(os.path.abspath(out_path)) | |
331 pepperdir = os.path.dirname(outdir) | |
332 AddMakeBat(pepperdir, outdir) | |
266 | 333 |
267 | 334 |
268 def main(argv): | 335 def main(argv): |
269 parser = optparse.OptionParser() | 336 parser = optparse.OptionParser() |
270 parser.add_option('--dstroot', help='Set root for destination.', | 337 parser.add_option('--dstroot', help='Set root for destination.', |
271 dest='dstroot', default=OUT_DIR) | 338 dest='dstroot', default=OUT_DIR) |
272 parser.add_option('--template', help='Set the makefile template.', | 339 parser.add_option('--template', help='Set the makefile template.', |
273 dest='template', default=os.path.join(SCRIPT_DIR, 'template.mk')) | 340 dest='template', default=os.path.join(SCRIPT_DIR, 'template.mk')) |
341 parser.add_option('--master', help='Create master Makefile.', | |
342 action='store_true', dest='master', default=False) | |
274 | 343 |
344 examples = [] | |
275 options, args = parser.parse_args(argv) | 345 options, args = parser.parse_args(argv) |
276 for filename in args: | 346 for filename in args: |
277 if not ProcessProject(options, filename): | 347 name, dest = ProcessProject(options.dstroot, options.template, filename) |
348 if not name: | |
278 print '\n*** Failed to process project: %s ***' % filename | 349 print '\n*** Failed to process project: %s ***' % filename |
279 return 1 | 350 return 1 |
280 | 351 |
352 if dest == 'examples': | |
353 examples.append(name) | |
354 | |
355 if options.master: | |
356 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile') | |
357 master_out = os.path.join(options.dstroot, 'examples', 'Makefile') | |
358 GenerateExamplesMakefile(master_in, master_out, examples) | |
359 | |
281 return 0 | 360 return 0 |
282 | 361 |
283 | 362 |
284 if __name__ == '__main__': | 363 if __name__ == '__main__': |
285 sys.exit(main(sys.argv[1:])) | 364 sys.exit(main(sys.argv[1:])) |
OLD | NEW |