Chromium Code Reviews| 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 |