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 cStringIO | 6 import cStringIO |
| 7 import optparse | 7 import optparse |
| 8 import os | 8 import os |
| 9 import sys | 9 import sys |
| 10 | 10 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 | 80 |
| 81 | 81 |
| 82 def GetProjectObjects(source_dict): | 82 def GetProjectObjects(source_dict): |
| 83 object_list = [] | 83 object_list = [] |
| 84 for key in ['.c', '.cc']: | 84 for key in ['.c', '.cc']: |
| 85 for src in source_dict[key]: | 85 for src in source_dict[key]: |
| 86 object_list.append(os.path.splitext(src)[0]) | 86 object_list.append(os.path.splitext(src)[0]) |
| 87 return object_list | 87 return object_list |
| 88 | 88 |
| 89 | 89 |
| 90 def GetPlatforms(plat_list, plat_filter): | 90 def GetPlatforms(plat_list, plat_filter, first_toolchain): |
| 91 platforms = [] | 91 platforms = [] |
| 92 for plat in plat_list: | 92 for plat in plat_list: |
| 93 if plat in plat_filter: | 93 if plat in plat_filter: |
| 94 platforms.append(plat) | 94 platforms.append(plat) |
| 95 | |
| 96 if first_toolchain: | |
| 97 return [platforms[0]] | |
| 95 return platforms | 98 return platforms |
| 96 | 99 |
| 97 | 100 |
| 98 # 'KEY' : ( <TYPE>, [Accepted Values], <Required?>) | 101 # 'KEY' : ( <TYPE>, [Accepted Values], <Required?>) |
| 99 DSC_FORMAT = { | 102 DSC_FORMAT = { |
| 100 'TOOLS' : (list, ['newlib:arm', 'newlib:x64', 'newlib:x86', 'newlib', | 103 'TOOLS' : (list, ['newlib:arm', 'newlib:x64', 'newlib:x86', 'newlib', |
| 101 'glibc', 'pnacl', 'win', 'linux'], True), | 104 'glibc', 'pnacl', 'win', 'linux'], True), |
| 102 'CONFIGS' : (list, ['Debug', 'Release'], False), | 105 'CONFIGS' : (list, ['Debug', 'Release'], False), |
| 103 'PREREQ' : (list, '', False), | 106 'PREREQ' : (list, '', False), |
| 104 'TARGETS' : (list, { | 107 'TARGETS' : (list, { |
| 105 'NAME': (str, '', True), | 108 'NAME': (str, '', True), |
| 106 'TYPE': (str, ['main', 'lib', 'so'], True), | 109 'TYPE': (str, ['main', 'lib', 'so', 'so-standalone'], True), |
|
noelallen1
2013/04/08 17:42:56
We should document somewhere what these different
binji
2013/04/08 19:33:52
Done.
| |
| 107 'SOURCES': (list, '', True), | 110 'SOURCES': (list, '', True), |
| 108 'CCFLAGS': (list, '', False), | 111 'CCFLAGS': (list, '', False), |
| 109 'CXXFLAGS': (list, '', False), | 112 'CXXFLAGS': (list, '', False), |
| 110 'DEFINES': (list, '', False), | 113 'DEFINES': (list, '', False), |
| 111 'LDFLAGS': (list, '', False), | 114 'LDFLAGS': (list, '', False), |
| 112 'INCLUDES': (list, '', False), | 115 'INCLUDES': (list, '', False), |
| 113 'LIBS' : (list, '', False), | 116 'LIBS' : (list, '', False), |
| 114 'DEPS' : (list, '', False) | 117 'DEPS' : (list, '', False) |
| 115 }, True), | 118 }, True), |
| 116 'HEADERS': (list, { | 119 'HEADERS': (list, { |
| 117 'FILES': (list, '', True), | 120 'FILES': (list, '', True), |
| 118 'DEST': (str, '', True), | 121 'DEST': (str, '', True), |
| 119 }, False), | 122 }, False), |
| 120 'SEARCH': (list, '', False), | 123 'SEARCH': (list, '', False), |
| 121 'POST': (str, '', False), | 124 'POST': (str, '', False), |
| 122 'PRE': (str, '', False), | 125 'PRE': (str, '', False), |
| 123 'DEST': (str, ['examples', 'src', 'testlibs', 'tests'], True), | 126 'DEST': (str, ['examples', 'src', 'testlibs', 'tests'], True), |
| 124 'NAME': (str, '', False), | 127 'NAME': (str, '', False), |
| 125 'DATA': (list, '', False), | 128 'DATA': (list, '', False), |
| 126 'TITLE': (str, '', False), | 129 'TITLE': (str, '', False), |
| 127 'DESC': (str, '', False), | |
| 128 'FOCUS': (str, '', False), | |
| 129 'GROUP': (str, '', False), | 130 'GROUP': (str, '', False), |
| 130 'EXPERIMENTAL': (bool, [True, False], False) | 131 'EXPERIMENTAL': (bool, [True, False], False) |
| 131 } | 132 } |
| 132 | 133 |
| 133 | 134 |
| 134 def ErrorMsgFunc(text): | 135 def ErrorMsgFunc(text): |
| 135 sys.stderr.write(text + '\n') | 136 sys.stderr.write(text + '\n') |
| 136 | 137 |
| 137 | 138 |
| 138 def ValidateFormat(src, dsc_format, ErrorMsg=ErrorMsgFunc): | 139 def ValidateFormat(src, dsc_format, ErrorMsg=ErrorMsgFunc): |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 return None | 247 return None |
| 247 | 248 |
| 248 | 249 |
| 249 def IsNexe(desc): | 250 def IsNexe(desc): |
| 250 for target in desc['TARGETS']: | 251 for target in desc['TARGETS']: |
| 251 if target['TYPE'] == 'main': | 252 if target['TYPE'] == 'main': |
| 252 return True | 253 return True |
| 253 return False | 254 return False |
| 254 | 255 |
| 255 | 256 |
| 256 def ProcessHTML(srcroot, dstroot, desc, toolchains): | 257 def ProcessHTML(srcroot, dstroot, desc, toolchains, configs, first_toolchain): |
| 257 name = desc['NAME'] | 258 name = desc['NAME'] |
| 258 outdir = os.path.join(dstroot, desc['DEST'], name) | 259 outdir = os.path.join(dstroot, desc['DEST'], name) |
| 259 srcfile = os.path.join(srcroot, 'index.html') | 260 srcfile = os.path.join(srcroot, 'index.html') |
| 260 dstfile = os.path.join(outdir, 'index.html') | 261 dstfile = os.path.join(outdir, 'index.html') |
| 261 tools = GetPlatforms(toolchains, desc['TOOLS']) | 262 tools = GetPlatforms(toolchains, desc['TOOLS'], first_toolchain) |
| 262 | 263 |
| 263 if use_gyp and getos.GetPlatform() != 'win': | 264 if use_gyp and getos.GetPlatform() != 'win': |
| 264 configs = ['debug', 'release'] | 265 # Make the config names lowercase when using gyp... |
| 265 else: | 266 configs = [c.lower() for c in configs] |
|
noelallen1
2013/04/08 17:42:56
This change assumes it's always correct for window
binji
2013/04/08 19:33:52
Below we validate that config is in ['Debug', 'Rel
| |
| 266 configs = ['Debug', 'Release'] | |
| 267 | 267 |
| 268 if use_gyp: | 268 if use_gyp: |
| 269 path = "build/{tc}-{config}" | 269 path = "build/{tc}-{config}" |
| 270 else: | 270 else: |
| 271 path = "{tc}/{config}" | 271 path = "{tc}/{config}" |
| 272 | 272 |
| 273 replace = { | 273 replace = { |
| 274 'title': desc['TITLE'], | 274 'title': desc['TITLE'], |
| 275 'attrs': | 275 'attrs': |
| 276 'data-name="%s" data-tools="%s" data-configs="%s" data-path="%s"' % ( | 276 'data-name="%s" data-tools="%s" data-configs="%s" data-path="%s"' % ( |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 ErrorExit('Failed to find: ' + src_name) | 316 ErrorExit('Failed to find: ' + src_name) |
| 317 dst_file = os.path.join(dst_dir, src_name) | 317 dst_file = os.path.join(dst_dir, src_name) |
| 318 if os.path.exists(dst_file): | 318 if os.path.exists(dst_file): |
| 319 if os.stat(src_file).st_mtime <= os.stat(dst_file).st_mtime: | 319 if os.stat(src_file).st_mtime <= os.stat(dst_file).st_mtime: |
| 320 Trace('Skipping "%s", destination "%s" is newer.' % ( | 320 Trace('Skipping "%s", destination "%s" is newer.' % ( |
| 321 src_file, dst_file)) | 321 src_file, dst_file)) |
| 322 continue | 322 continue |
| 323 buildbot_common.CopyFile(src_file, dst_file) | 323 buildbot_common.CopyFile(src_file, dst_file) |
| 324 | 324 |
| 325 | 325 |
| 326 def ProcessProject(srcroot, dstroot, desc, toolchains): | 326 def ProcessProject(srcroot, dstroot, desc, toolchains, first_toolchain): |
| 327 name = desc['NAME'] | 327 name = desc['NAME'] |
| 328 out_dir = os.path.join(dstroot, desc['DEST'], name) | 328 out_dir = os.path.join(dstroot, desc['DEST'], name) |
| 329 buildbot_common.MakeDir(out_dir) | 329 buildbot_common.MakeDir(out_dir) |
| 330 srcdirs = desc.get('SEARCH', ['.', '..']) | 330 srcdirs = desc.get('SEARCH', ['.', '..']) |
| 331 | 331 |
| 332 # Copy sources to example directory | 332 # Copy sources to example directory |
| 333 sources = GenerateSourceCopyList(desc) | 333 sources = GenerateSourceCopyList(desc) |
| 334 FindAndCopyFiles(sources, srcroot, srcdirs, out_dir) | 334 FindAndCopyFiles(sources, srcroot, srcdirs, out_dir) |
| 335 | 335 |
| 336 # Copy public headers to the include directory. | 336 # Copy public headers to the include directory. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 359 gyp += '.bat' | 359 gyp += '.bat' |
| 360 buildbot_common.Run([gyp, '-Gstandalone', '--format', generator, | 360 buildbot_common.Run([gyp, '-Gstandalone', '--format', generator, |
| 361 '--toplevel-dir=.', gypfile], cwd=out_dir) | 361 '--toplevel-dir=.', gypfile], cwd=out_dir) |
| 362 | 362 |
| 363 if sys.platform == 'win32' or not use_gyp: | 363 if sys.platform == 'win32' or not use_gyp: |
| 364 if IsNexe(desc): | 364 if IsNexe(desc): |
| 365 template = os.path.join(SCRIPT_DIR, 'template.mk') | 365 template = os.path.join(SCRIPT_DIR, 'template.mk') |
| 366 else: | 366 else: |
| 367 template = os.path.join(SCRIPT_DIR, 'library.mk') | 367 template = os.path.join(SCRIPT_DIR, 'library.mk') |
| 368 | 368 |
| 369 tools = {} | 369 # Ensure the order of |tools| is the same as toolchains; that way if |
| 370 tool_list = [] | 370 # first_toolchain is set, it will choose based on the order of |toolchains|. |
| 371 for tool in desc['TOOLS']: | 371 tools = [tool for tool in toolchains if tool in desc['TOOLS']] |
| 372 if ':' in tool: | 372 if first_toolchain: |
|
noelallen1
2013/04/08 17:42:56
Is this actually what we want? Do we really want
binji
2013/04/08 19:33:52
This change is so that we don't include extra tool
noelallen1
2013/04/08 19:48:16
That's fine, I though you were trying to solve a d
| |
| 373 tool, arch = tool.split(':') | 373 tools = [tools[0]] |
| 374 else: | |
| 375 arch = None | |
| 376 # Ignore tools that are not enabled in this SDK build | |
| 377 if tool not in toolchains: | |
| 378 continue | |
| 379 tools.setdefault(tool, []) | |
| 380 if tool not in tool_list: | |
| 381 tool_list.append(tool) | |
| 382 if arch: | |
| 383 tools[tool].append(arch) | |
| 384 | |
| 385 template_dict = { | 374 template_dict = { |
| 386 'pre': desc.get('PRE', ''), | 375 'pre': desc.get('PRE', ''), |
| 387 'tools': tool_list, | 376 'tools': tools, |
| 388 'targets': desc['TARGETS'], | 377 'targets': desc['TARGETS'], |
| 389 } | 378 } |
| 390 RunTemplateFile(template, make_path, template_dict) | 379 RunTemplateFile(template, make_path, template_dict) |
| 391 | 380 |
| 392 outdir = os.path.dirname(os.path.abspath(make_path)) | 381 outdir = os.path.dirname(os.path.abspath(make_path)) |
| 393 pepperdir = os.path.dirname(os.path.dirname(outdir)) | 382 pepperdir = os.path.dirname(os.path.dirname(outdir)) |
| 394 AddMakeBat(pepperdir, outdir) | 383 AddMakeBat(pepperdir, outdir) |
| 395 return (name, desc['DEST']) | 384 return (name, desc['DEST']) |
| 396 | 385 |
| 397 | 386 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 414 parser.add_option('--master', help='Create master Makefile.', | 403 parser.add_option('--master', help='Create master Makefile.', |
| 415 action='store_true') | 404 action='store_true') |
| 416 parser.add_option('--newlib', help='Create newlib examples.', | 405 parser.add_option('--newlib', help='Create newlib examples.', |
| 417 action='store_true') | 406 action='store_true') |
| 418 parser.add_option('--glibc', help='Create glibc examples.', | 407 parser.add_option('--glibc', help='Create glibc examples.', |
| 419 action='store_true') | 408 action='store_true') |
| 420 parser.add_option('--pnacl', help='Create pnacl examples.', | 409 parser.add_option('--pnacl', help='Create pnacl examples.', |
| 421 action='store_true') | 410 action='store_true') |
| 422 parser.add_option('--host', help='Create host examples.', | 411 parser.add_option('--host', help='Create host examples.', |
| 423 action='store_true') | 412 action='store_true') |
| 413 parser.add_option('--config', help='Add configuration (debug/release).', | |
| 414 action='append') | |
| 424 parser.add_option('--experimental', help='Create experimental examples.', | 415 parser.add_option('--experimental', help='Create experimental examples.', |
| 425 action='store_true') | 416 action='store_true') |
| 417 parser.add_option('--first-valid-toolchain', | |
|
noelallen1
2013/04/08 17:42:56
Same comment as above. Is this a testing optimiza
| |
| 418 help='Only build one toolchain, the first one that is valid.', | |
| 419 action='store_true') | |
| 426 parser.add_option('-v', '--verbose', help='Verbose output', | 420 parser.add_option('-v', '--verbose', help='Verbose output', |
| 427 action='store_true') | 421 action='store_true') |
| 428 | 422 |
| 429 toolchains = [] | 423 toolchains = [] |
| 430 platform = getos.GetPlatform() | 424 platform = getos.GetPlatform() |
| 431 | 425 |
| 432 options, args = parser.parse_args(argv) | 426 options, args = parser.parse_args(argv) |
| 433 if options.verbose: | 427 if options.verbose: |
| 434 Trace.verbose = True | 428 Trace.verbose = True |
| 435 if options.newlib: | 429 if options.newlib: |
| 436 toolchains.append('newlib') | 430 toolchains.append('newlib') |
| 437 if options.glibc: | 431 if options.glibc: |
| 438 toolchains.append('glibc') | 432 toolchains.append('glibc') |
| 439 if options.pnacl: | 433 if options.pnacl: |
| 440 toolchains.append('pnacl') | 434 toolchains.append('pnacl') |
| 441 if options.host: | 435 if options.host: |
| 442 toolchains.append(platform) | 436 toolchains.append(platform) |
| 443 | 437 |
| 444 if not args: | 438 if not args: |
| 445 ErrorExit('Please specify one or more projects to generate Makefiles for.') | 439 ErrorExit('Please specify one or more projects to generate Makefiles for.') |
| 446 | 440 |
| 447 # By default support newlib and glibc | 441 # By default support newlib and glibc |
| 448 if not toolchains: | 442 if not toolchains: |
| 449 toolchains = ['newlib', 'glibc', 'pnacl'] | 443 toolchains = ['newlib', 'glibc', 'pnacl'] |
| 450 | 444 |
| 445 valid_configs = ['Debug', 'Release'] | |
| 446 if options.config: | |
| 447 configs = [] | |
| 448 for config in options.config: | |
| 449 if config in valid_configs: | |
| 450 configs.append(config) | |
| 451 else: | |
| 452 ErrorExit('Invalid config: %s' % config) | |
| 453 else: | |
| 454 configs = valid_configs | |
| 455 | |
| 451 master_projects = {} | 456 master_projects = {} |
| 452 | 457 |
| 453 landing_page = LandingPage() | |
| 454 for i, filename in enumerate(args): | 458 for i, filename in enumerate(args): |
| 455 if i: | 459 if i: |
| 456 # Print two newlines between each dsc file we process | 460 # Print two newlines between each dsc file we process |
| 457 Trace('\n') | 461 Trace('\n') |
| 458 desc = LoadProject(filename, toolchains) | 462 desc = LoadProject(filename, toolchains) |
| 459 if not desc: | 463 if not desc: |
| 460 Trace('Skipping %s, not in [%s].' % (filename, ', '.join(toolchains))) | 464 Trace('Skipping %s, not in [%s].' % (filename, ', '.join(toolchains))) |
| 461 continue | 465 continue |
| 462 | 466 |
| 463 if desc.get('EXPERIMENTAL', False) and not options.experimental: | 467 if desc.get('EXPERIMENTAL', False) and not options.experimental: |
| 464 Trace('Skipping %s, experimental only.' % (filename,)) | 468 Trace('Skipping %s, experimental only.' % (filename,)) |
| 465 continue | 469 continue |
| 466 | 470 |
| 467 srcroot = os.path.dirname(os.path.abspath(filename)) | 471 srcroot = os.path.dirname(os.path.abspath(filename)) |
| 468 if not ProcessProject(srcroot, options.dstroot, desc, toolchains): | 472 if not ProcessProject(srcroot, options.dstroot, desc, toolchains, |
| 473 options.first_valid_toolchain): | |
| 469 ErrorExit('\n*** Failed to process project: %s ***' % filename) | 474 ErrorExit('\n*** Failed to process project: %s ***' % filename) |
| 470 | 475 |
| 471 # if this is an example update it's html file. | 476 # if this is an example update it's html file. |
| 472 if ShouldProcessHTML(desc): | 477 if ShouldProcessHTML(desc): |
| 473 ProcessHTML(srcroot, options.dstroot, desc, toolchains) | 478 ProcessHTML(srcroot, options.dstroot, desc, toolchains, configs, |
| 474 | 479 options.first_valid_toolchain) |
| 475 # if this is an example, update landing page html file. | |
| 476 if desc['DEST'] == 'examples': | |
| 477 Trace('Adding desc: %s' % filename) | |
| 478 landing_page.AddDesc(desc) | |
| 479 | 480 |
| 480 # Create a list of projects for each DEST. This will be used to generate a | 481 # Create a list of projects for each DEST. This will be used to generate a |
| 481 # master makefile. | 482 # master makefile. |
| 482 master_projects.setdefault(desc['DEST'], []).append(desc) | 483 master_projects.setdefault(desc['DEST'], []).append(desc) |
| 483 | 484 |
| 484 # Generate the landing page text file. | 485 |
| 485 index_html = os.path.join(options.dstroot, 'examples', 'index.html') | 486 if master_projects.get('examples'): |
| 486 with open(index_html, 'w') as fh: | 487 landing_page = LandingPage() |
| 487 fh.write(landing_page.GeneratePage()) | 488 for desc in master_projects.get('examples'): |
| 489 landing_page.AddDesc(desc) | |
| 490 | |
| 491 # Generate the landing page text file. | |
| 492 index_html = os.path.join(options.dstroot, 'examples', 'index.html') | |
| 493 example_resources_dir = os.path.join(SDK_EXAMPLE_DIR, 'resources') | |
| 494 index_template = os.path.join(example_resources_dir, 'index.html.template') | |
| 495 with open(index_html, 'w') as fh: | |
| 496 fh.write(landing_page.GeneratePage(index_template)) | |
| 497 | |
| 498 # Copy additional files needed for the landing page. | |
| 499 extra_files = ['index.css', 'index.js', 'button_close.png', | |
| 500 'button_close_hover.png'] | |
| 501 for filename in extra_files: | |
| 502 src_file = os.path.join(example_resources_dir, filename) | |
| 503 dst_file = os.path.join(options.dstroot, 'examples', filename) | |
| 504 buildbot_common.CopyFile(src_file, dst_file) | |
| 488 | 505 |
| 489 if options.master: | 506 if options.master: |
| 490 if use_gyp: | 507 if use_gyp: |
| 491 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile_gyp') | 508 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile_gyp') |
| 492 else: | 509 else: |
| 493 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile') | 510 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile') |
| 494 for dest, projects in master_projects.iteritems(): | 511 for dest, projects in master_projects.iteritems(): |
| 495 master_out = os.path.join(options.dstroot, dest, 'Makefile') | 512 master_out = os.path.join(options.dstroot, dest, 'Makefile') |
| 496 GenerateMasterMakefile(master_in, master_out, projects) | 513 GenerateMasterMakefile(master_in, master_out, projects) |
| 497 | 514 |
| 498 return 0 | 515 return 0 |
| 499 | 516 |
| 500 | 517 |
| 501 if __name__ == '__main__': | 518 if __name__ == '__main__': |
| 502 sys.exit(main(sys.argv[1:])) | 519 sys.exit(main(sys.argv[1:])) |
| 503 | 520 |
| OLD | NEW |