| 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 # main = nexe target |
| 110 # lib = library target |
| 111 # so = shared object target, automatically added to NMF |
| 112 # so-standalone = shared object target, not put into NMF |
| 113 'TYPE': (str, ['main', 'lib', 'so', 'so-standalone'], True), |
| 107 'SOURCES': (list, '', True), | 114 'SOURCES': (list, '', True), |
| 108 'CCFLAGS': (list, '', False), | 115 'CCFLAGS': (list, '', False), |
| 109 'CXXFLAGS': (list, '', False), | 116 'CXXFLAGS': (list, '', False), |
| 110 'DEFINES': (list, '', False), | 117 'DEFINES': (list, '', False), |
| 111 'LDFLAGS': (list, '', False), | 118 'LDFLAGS': (list, '', False), |
| 112 'INCLUDES': (list, '', False), | 119 'INCLUDES': (list, '', False), |
| 113 'LIBS' : (list, '', False), | 120 'LIBS' : (list, '', False), |
| 114 'DEPS' : (list, '', False) | 121 'DEPS' : (list, '', False) |
| 115 }, True), | 122 }, True), |
| 116 'HEADERS': (list, { | 123 'HEADERS': (list, { |
| 117 'FILES': (list, '', True), | 124 'FILES': (list, '', True), |
| 118 'DEST': (str, '', True), | 125 'DEST': (str, '', True), |
| 119 }, False), | 126 }, False), |
| 120 'SEARCH': (list, '', False), | 127 'SEARCH': (list, '', False), |
| 121 'POST': (str, '', False), | 128 'POST': (str, '', False), |
| 122 'PRE': (str, '', False), | 129 'PRE': (str, '', False), |
| 123 'DEST': (str, ['examples', 'src', 'testlibs', 'tests'], True), | 130 'DEST': (str, ['examples', 'src', 'testlibs', 'tests'], True), |
| 124 'NAME': (str, '', False), | 131 'NAME': (str, '', False), |
| 125 'DATA': (list, '', False), | 132 'DATA': (list, '', False), |
| 126 'TITLE': (str, '', False), | 133 'TITLE': (str, '', False), |
| 127 'DESC': (str, '', False), | |
| 128 'FOCUS': (str, '', False), | |
| 129 'GROUP': (str, '', False), | 134 'GROUP': (str, '', False), |
| 130 'EXPERIMENTAL': (bool, [True, False], False) | 135 'EXPERIMENTAL': (bool, [True, False], False) |
| 131 } | 136 } |
| 132 | 137 |
| 133 | 138 |
| 134 def ErrorMsgFunc(text): | 139 def ErrorMsgFunc(text): |
| 135 sys.stderr.write(text + '\n') | 140 sys.stderr.write(text + '\n') |
| 136 | 141 |
| 137 | 142 |
| 138 def ValidateFormat(src, dsc_format, ErrorMsg=ErrorMsgFunc): | 143 def ValidateFormat(src, dsc_format, ErrorMsg=ErrorMsgFunc): |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 return None | 251 return None |
| 247 | 252 |
| 248 | 253 |
| 249 def IsNexe(desc): | 254 def IsNexe(desc): |
| 250 for target in desc['TARGETS']: | 255 for target in desc['TARGETS']: |
| 251 if target['TYPE'] == 'main': | 256 if target['TYPE'] == 'main': |
| 252 return True | 257 return True |
| 253 return False | 258 return False |
| 254 | 259 |
| 255 | 260 |
| 256 def ProcessHTML(srcroot, dstroot, desc, toolchains): | 261 def ProcessHTML(srcroot, dstroot, desc, toolchains, configs, first_toolchain): |
| 257 name = desc['NAME'] | 262 name = desc['NAME'] |
| 258 outdir = os.path.join(dstroot, desc['DEST'], name) | 263 outdir = os.path.join(dstroot, desc['DEST'], name) |
| 259 srcfile = os.path.join(srcroot, 'index.html') | 264 srcfile = os.path.join(srcroot, 'index.html') |
| 260 dstfile = os.path.join(outdir, 'index.html') | 265 dstfile = os.path.join(outdir, 'index.html') |
| 261 tools = GetPlatforms(toolchains, desc['TOOLS']) | 266 tools = GetPlatforms(toolchains, desc['TOOLS'], first_toolchain) |
| 262 | 267 |
| 263 if use_gyp and getos.GetPlatform() != 'win': | 268 if use_gyp and getos.GetPlatform() != 'win': |
| 264 configs = ['debug', 'release'] | 269 # Make the config names lowercase when using gyp... |
| 265 else: | 270 configs = [c.lower() for c in configs] |
| 266 configs = ['Debug', 'Release'] | |
| 267 | 271 |
| 268 if use_gyp: | 272 if use_gyp: |
| 269 path = "build/{tc}-{config}" | 273 path = "build/{tc}-{config}" |
| 270 else: | 274 else: |
| 271 path = "{tc}/{config}" | 275 path = "{tc}/{config}" |
| 272 | 276 |
| 273 replace = { | 277 replace = { |
| 274 'title': desc['TITLE'], | 278 'title': desc['TITLE'], |
| 275 'attrs': | 279 'attrs': |
| 276 'data-name="%s" data-tools="%s" data-configs="%s" data-path="%s"' % ( | 280 '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) | 320 ErrorExit('Failed to find: ' + src_name) |
| 317 dst_file = os.path.join(dst_dir, src_name) | 321 dst_file = os.path.join(dst_dir, src_name) |
| 318 if os.path.exists(dst_file): | 322 if os.path.exists(dst_file): |
| 319 if os.stat(src_file).st_mtime <= os.stat(dst_file).st_mtime: | 323 if os.stat(src_file).st_mtime <= os.stat(dst_file).st_mtime: |
| 320 Trace('Skipping "%s", destination "%s" is newer.' % ( | 324 Trace('Skipping "%s", destination "%s" is newer.' % ( |
| 321 src_file, dst_file)) | 325 src_file, dst_file)) |
| 322 continue | 326 continue |
| 323 buildbot_common.CopyFile(src_file, dst_file) | 327 buildbot_common.CopyFile(src_file, dst_file) |
| 324 | 328 |
| 325 | 329 |
| 326 def ProcessProject(srcroot, dstroot, desc, toolchains): | 330 def ProcessProject(srcroot, dstroot, desc, toolchains, first_toolchain): |
| 327 name = desc['NAME'] | 331 name = desc['NAME'] |
| 328 out_dir = os.path.join(dstroot, desc['DEST'], name) | 332 out_dir = os.path.join(dstroot, desc['DEST'], name) |
| 329 buildbot_common.MakeDir(out_dir) | 333 buildbot_common.MakeDir(out_dir) |
| 330 srcdirs = desc.get('SEARCH', ['.', '..']) | 334 srcdirs = desc.get('SEARCH', ['.', '..']) |
| 331 | 335 |
| 332 # Copy sources to example directory | 336 # Copy sources to example directory |
| 333 sources = GenerateSourceCopyList(desc) | 337 sources = GenerateSourceCopyList(desc) |
| 334 FindAndCopyFiles(sources, srcroot, srcdirs, out_dir) | 338 FindAndCopyFiles(sources, srcroot, srcdirs, out_dir) |
| 335 | 339 |
| 336 # Copy public headers to the include directory. | 340 # Copy public headers to the include directory. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 359 gyp += '.bat' | 363 gyp += '.bat' |
| 360 buildbot_common.Run([gyp, '-Gstandalone', '--format', generator, | 364 buildbot_common.Run([gyp, '-Gstandalone', '--format', generator, |
| 361 '--toplevel-dir=.', gypfile], cwd=out_dir) | 365 '--toplevel-dir=.', gypfile], cwd=out_dir) |
| 362 | 366 |
| 363 if sys.platform == 'win32' or not use_gyp: | 367 if sys.platform == 'win32' or not use_gyp: |
| 364 if IsNexe(desc): | 368 if IsNexe(desc): |
| 365 template = os.path.join(SCRIPT_DIR, 'template.mk') | 369 template = os.path.join(SCRIPT_DIR, 'template.mk') |
| 366 else: | 370 else: |
| 367 template = os.path.join(SCRIPT_DIR, 'library.mk') | 371 template = os.path.join(SCRIPT_DIR, 'library.mk') |
| 368 | 372 |
| 369 tools = {} | 373 # Ensure the order of |tools| is the same as toolchains; that way if |
| 370 tool_list = [] | 374 # first_toolchain is set, it will choose based on the order of |toolchains|. |
| 371 for tool in desc['TOOLS']: | 375 tools = [tool for tool in toolchains if tool in desc['TOOLS']] |
| 372 if ':' in tool: | 376 if first_toolchain: |
| 373 tool, arch = tool.split(':') | 377 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 = { | 378 template_dict = { |
| 386 'pre': desc.get('PRE', ''), | 379 'pre': desc.get('PRE', ''), |
| 387 'tools': tool_list, | 380 'tools': tools, |
| 388 'targets': desc['TARGETS'], | 381 'targets': desc['TARGETS'], |
| 389 } | 382 } |
| 390 RunTemplateFile(template, make_path, template_dict) | 383 RunTemplateFile(template, make_path, template_dict) |
| 391 | 384 |
| 392 outdir = os.path.dirname(os.path.abspath(make_path)) | 385 outdir = os.path.dirname(os.path.abspath(make_path)) |
| 393 pepperdir = os.path.dirname(os.path.dirname(outdir)) | 386 pepperdir = os.path.dirname(os.path.dirname(outdir)) |
| 394 AddMakeBat(pepperdir, outdir) | 387 AddMakeBat(pepperdir, outdir) |
| 395 return (name, desc['DEST']) | 388 return (name, desc['DEST']) |
| 396 | 389 |
| 397 | 390 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 414 parser.add_option('--master', help='Create master Makefile.', | 407 parser.add_option('--master', help='Create master Makefile.', |
| 415 action='store_true') | 408 action='store_true') |
| 416 parser.add_option('--newlib', help='Create newlib examples.', | 409 parser.add_option('--newlib', help='Create newlib examples.', |
| 417 action='store_true') | 410 action='store_true') |
| 418 parser.add_option('--glibc', help='Create glibc examples.', | 411 parser.add_option('--glibc', help='Create glibc examples.', |
| 419 action='store_true') | 412 action='store_true') |
| 420 parser.add_option('--pnacl', help='Create pnacl examples.', | 413 parser.add_option('--pnacl', help='Create pnacl examples.', |
| 421 action='store_true') | 414 action='store_true') |
| 422 parser.add_option('--host', help='Create host examples.', | 415 parser.add_option('--host', help='Create host examples.', |
| 423 action='store_true') | 416 action='store_true') |
| 417 parser.add_option('--config', help='Add configuration (debug/release).', |
| 418 action='append') |
| 424 parser.add_option('--experimental', help='Create experimental examples.', | 419 parser.add_option('--experimental', help='Create experimental examples.', |
| 425 action='store_true') | 420 action='store_true') |
| 421 parser.add_option('--first-valid-toolchain', |
| 422 help='Only build one toolchain, the first one that is valid.', |
| 423 action='store_true') |
| 426 parser.add_option('-v', '--verbose', help='Verbose output', | 424 parser.add_option('-v', '--verbose', help='Verbose output', |
| 427 action='store_true') | 425 action='store_true') |
| 428 | 426 |
| 429 toolchains = [] | 427 toolchains = [] |
| 430 platform = getos.GetPlatform() | 428 platform = getos.GetPlatform() |
| 431 | 429 |
| 432 options, args = parser.parse_args(argv) | 430 options, args = parser.parse_args(argv) |
| 433 if options.verbose: | 431 if options.verbose: |
| 434 Trace.verbose = True | 432 Trace.verbose = True |
| 435 if options.newlib: | 433 if options.newlib: |
| 436 toolchains.append('newlib') | 434 toolchains.append('newlib') |
| 437 if options.glibc: | 435 if options.glibc: |
| 438 toolchains.append('glibc') | 436 toolchains.append('glibc') |
| 439 if options.pnacl: | 437 if options.pnacl: |
| 440 toolchains.append('pnacl') | 438 toolchains.append('pnacl') |
| 441 if options.host: | 439 if options.host: |
| 442 toolchains.append(platform) | 440 toolchains.append(platform) |
| 443 | 441 |
| 444 if not args: | 442 if not args: |
| 445 ErrorExit('Please specify one or more projects to generate Makefiles for.') | 443 ErrorExit('Please specify one or more projects to generate Makefiles for.') |
| 446 | 444 |
| 447 # By default support newlib and glibc | 445 # By default support newlib and glibc |
| 448 if not toolchains: | 446 if not toolchains: |
| 449 toolchains = ['newlib', 'glibc', 'pnacl'] | 447 toolchains = ['newlib', 'glibc', 'pnacl'] |
| 450 | 448 |
| 449 valid_configs = ['Debug', 'Release'] |
| 450 if options.config: |
| 451 configs = [] |
| 452 for config in options.config: |
| 453 if config in valid_configs: |
| 454 configs.append(config) |
| 455 else: |
| 456 ErrorExit('Invalid config: %s' % config) |
| 457 else: |
| 458 configs = valid_configs |
| 459 |
| 451 master_projects = {} | 460 master_projects = {} |
| 452 | 461 |
| 453 landing_page = LandingPage() | |
| 454 for i, filename in enumerate(args): | 462 for i, filename in enumerate(args): |
| 455 if i: | 463 if i: |
| 456 # Print two newlines between each dsc file we process | 464 # Print two newlines between each dsc file we process |
| 457 Trace('\n') | 465 Trace('\n') |
| 458 desc = LoadProject(filename, toolchains) | 466 desc = LoadProject(filename, toolchains) |
| 459 if not desc: | 467 if not desc: |
| 460 Trace('Skipping %s, not in [%s].' % (filename, ', '.join(toolchains))) | 468 Trace('Skipping %s, not in [%s].' % (filename, ', '.join(toolchains))) |
| 461 continue | 469 continue |
| 462 | 470 |
| 463 if desc.get('EXPERIMENTAL', False) and not options.experimental: | 471 if desc.get('EXPERIMENTAL', False) and not options.experimental: |
| 464 Trace('Skipping %s, experimental only.' % (filename,)) | 472 Trace('Skipping %s, experimental only.' % (filename,)) |
| 465 continue | 473 continue |
| 466 | 474 |
| 467 srcroot = os.path.dirname(os.path.abspath(filename)) | 475 srcroot = os.path.dirname(os.path.abspath(filename)) |
| 468 if not ProcessProject(srcroot, options.dstroot, desc, toolchains): | 476 if not ProcessProject(srcroot, options.dstroot, desc, toolchains, |
| 477 options.first_valid_toolchain): |
| 469 ErrorExit('\n*** Failed to process project: %s ***' % filename) | 478 ErrorExit('\n*** Failed to process project: %s ***' % filename) |
| 470 | 479 |
| 471 # if this is an example update it's html file. | 480 # if this is an example update it's html file. |
| 472 if ShouldProcessHTML(desc): | 481 if ShouldProcessHTML(desc): |
| 473 ProcessHTML(srcroot, options.dstroot, desc, toolchains) | 482 ProcessHTML(srcroot, options.dstroot, desc, toolchains, configs, |
| 474 | 483 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 | 484 |
| 480 # Create a list of projects for each DEST. This will be used to generate a | 485 # Create a list of projects for each DEST. This will be used to generate a |
| 481 # master makefile. | 486 # master makefile. |
| 482 master_projects.setdefault(desc['DEST'], []).append(desc) | 487 master_projects.setdefault(desc['DEST'], []).append(desc) |
| 483 | 488 |
| 484 # Generate the landing page text file. | 489 |
| 485 index_html = os.path.join(options.dstroot, 'examples', 'index.html') | 490 if master_projects.get('examples'): |
| 486 with open(index_html, 'w') as fh: | 491 landing_page = LandingPage() |
| 487 fh.write(landing_page.GeneratePage()) | 492 for desc in master_projects.get('examples'): |
| 493 landing_page.AddDesc(desc) |
| 494 |
| 495 # Generate the landing page text file. |
| 496 index_html = os.path.join(options.dstroot, 'examples', 'index.html') |
| 497 example_resources_dir = os.path.join(SDK_EXAMPLE_DIR, 'resources') |
| 498 index_template = os.path.join(example_resources_dir, 'index.html.template') |
| 499 with open(index_html, 'w') as fh: |
| 500 fh.write(landing_page.GeneratePage(index_template)) |
| 501 |
| 502 # Copy additional files needed for the landing page. |
| 503 extra_files = ['index.css', 'index.js', 'button_close.png', |
| 504 'button_close_hover.png'] |
| 505 for filename in extra_files: |
| 506 src_file = os.path.join(example_resources_dir, filename) |
| 507 dst_file = os.path.join(options.dstroot, 'examples', filename) |
| 508 buildbot_common.CopyFile(src_file, dst_file) |
| 488 | 509 |
| 489 if options.master: | 510 if options.master: |
| 490 if use_gyp: | 511 if use_gyp: |
| 491 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile_gyp') | 512 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile_gyp') |
| 492 else: | 513 else: |
| 493 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile') | 514 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile') |
| 494 for dest, projects in master_projects.iteritems(): | 515 for dest, projects in master_projects.iteritems(): |
| 495 master_out = os.path.join(options.dstroot, dest, 'Makefile') | 516 master_out = os.path.join(options.dstroot, dest, 'Makefile') |
| 496 GenerateMasterMakefile(master_in, master_out, projects) | 517 GenerateMasterMakefile(master_in, master_out, projects) |
| 497 | 518 |
| 498 return 0 | 519 return 0 |
| 499 | 520 |
| 500 | 521 |
| 501 if __name__ == '__main__': | 522 if __name__ == '__main__': |
| 502 sys.exit(main(sys.argv[1:])) | 523 sys.exit(main(sys.argv[1:])) |
| 503 | 524 |
| OLD | NEW |