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 from generate_index import LandingPage | 10 from generate_index import LandingPage |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 86 |
87 def GenerateToolDefaults(tools): | 87 def GenerateToolDefaults(tools): |
88 defaults = '' | 88 defaults = '' |
89 for tool in tools: | 89 for tool in tools: |
90 defaults += MakeRules(tool).BuildDefaults() | 90 defaults += MakeRules(tool).BuildDefaults() |
91 return defaults | 91 return defaults |
92 | 92 |
93 | 93 |
94 def GenerateSettings(desc, tools): | 94 def GenerateSettings(desc, tools): |
95 settings = SetVar('VALID_TOOLCHAINS', tools) | 95 settings = SetVar('VALID_TOOLCHAINS', tools) |
96 settings += 'TOOLCHAIN?=%s\n\n' % tools[0] | 96 settings += 'TOOLCHAIN?=%s\n\n' % desc['TOOLS'][0] |
97 for target in desc['TARGETS']: | 97 for target in desc['TARGETS']: |
98 project = target['NAME'] | 98 project = target['NAME'] |
99 macro = project.upper() | 99 macro = project.upper() |
100 | 100 |
101 c_flags = target.get('CCFLAGS') | 101 c_flags = target.get('CCFLAGS') |
102 cc_flags = target.get('CXXFLAGS') | 102 cc_flags = target.get('CXXFLAGS') |
103 ld_flags = target.get('LDFLAGS') | 103 ld_flags = target.get('LDFLAGS') |
104 | 104 |
105 if c_flags: | 105 if c_flags: |
106 settings += SetVar(macro + '_CCFLAGS', c_flags) | 106 settings += SetVar(macro + '_CCFLAGS', c_flags) |
(...skipping 24 matching lines...) Expand all Loading... |
131 dlls.append(project) | 131 dlls.append(project) |
132 for arch in ['x86_32', 'x86_64']: | 132 for arch in ['x86_32', 'x86_64']: |
133 glibc_rename.append('-n %s_%s.so,%s.so' % (project, arch, project)) | 133 glibc_rename.append('-n %s_%s.so,%s.so' % (project, arch, project)) |
134 | 134 |
135 objects = GetProjectObjects(srcs) | 135 objects = GetProjectObjects(srcs) |
136 rules += SetVar('%s_OBJS' % project.upper(), objects) | 136 rules += SetVar('%s_OBJS' % project.upper(), objects) |
137 if glibc_rename: | 137 if glibc_rename: |
138 rules += SetVar('GLIBC_REMAP', glibc_rename) | 138 rules += SetVar('GLIBC_REMAP', glibc_rename) |
139 | 139 |
140 configs = desc.get('CONFIGS', ['Debug', 'Release']) | 140 configs = desc.get('CONFIGS', ['Debug', 'Release']) |
141 for tc in tools: | 141 for tc, enabled_arches in tools.iteritems(): |
| 142 print tc |
142 makeobj = MakeRules(tc) | 143 makeobj = MakeRules(tc) |
143 arches = makeobj.GetArches() | 144 arches = makeobj.GetArches() |
144 rules += makeobj.BuildDirectoryRules(configs) | 145 rules += makeobj.BuildDirectoryRules(configs) |
| 146 |
| 147 if enabled_arches: |
| 148 # filter out all arches that don't match the list |
| 149 # of enabled arches |
| 150 arches = [a for a in arches if a.get('<arch>') in enabled_arches] |
| 151 |
145 for cfg in configs: | 152 for cfg in configs: |
146 makeobj.SetConfig(cfg) | 153 makeobj.SetConfig(cfg) |
147 for target in desc['TARGETS']: | 154 for target in desc['TARGETS']: |
148 project = target['NAME'] | 155 project = target['NAME'] |
149 ptype = target['TYPE'] | 156 ptype = target['TYPE'] |
150 srcs = GetSourcesDict(target['SOURCES']) | 157 srcs = GetSourcesDict(target['SOURCES']) |
151 defs = target.get('DEFINES', []) | 158 defs = target.get('DEFINES', []) |
152 incs = target.get('INCLUDES', []) | 159 incs = target.get('INCLUDES', []) |
153 libs = target.get('LIBS', []) | 160 libs = target.get('LIBS', []) |
154 makeobj.SetProject(project, ptype, defs=defs, incs=incs, libs=libs) | 161 makeobj.SetProject(project, ptype, defs=defs, incs=incs, libs=libs) |
(...skipping 10 matching lines...) Expand all Loading... |
165 rules += makeobj.BuildLinkRule() | 172 rules += makeobj.BuildLinkRule() |
166 if executable: | 173 if executable: |
167 rules += GenerateNMFRules(tc, executable, dlls, cfg, arches) | 174 rules += GenerateNMFRules(tc, executable, dlls, cfg, arches) |
168 | 175 |
169 rules += GenerateCleanRules(tools, configs) | 176 rules += GenerateCleanRules(tools, configs) |
170 rules += '\nall: $(ALL_TARGETS)\n' | 177 rules += '\nall: $(ALL_TARGETS)\n' |
171 | 178 |
172 return '', rules | 179 return '', rules |
173 | 180 |
174 | 181 |
175 | |
176 def GenerateReplacements(desc, tools): | 182 def GenerateReplacements(desc, tools): |
177 # Generate target settings | 183 # Generate target settings |
178 settings = GenerateSettings(desc, tools) | 184 settings = GenerateSettings(desc, tools) |
179 tool_def = GenerateToolDefaults(tools) | 185 tool_def = GenerateToolDefaults(tools) |
180 _, rules = GenerateRules(desc, tools) | 186 _, rules = GenerateRules(desc, tools) |
181 | 187 |
182 prelaunch = desc.get('LAUNCH', '') | 188 prelaunch = desc.get('LAUNCH', '') |
183 prerun = desc.get('PRE', '') | 189 prerun = desc.get('PRE', '') |
184 postlaunch = desc.get('POST', '') | 190 postlaunch = desc.get('POST', '') |
185 | 191 |
186 target_def = 'all:' | 192 target_def = 'all:' |
187 | 193 |
188 return { | 194 return { |
189 '__PROJECT_SETTINGS__' : settings, | 195 '__PROJECT_SETTINGS__' : settings, |
190 '__PROJECT_TARGETS__' : target_def, | 196 '__PROJECT_TARGETS__' : target_def, |
191 '__PROJECT_TOOLS__' : tool_def, | 197 '__PROJECT_TOOLS__' : tool_def, |
192 '__PROJECT_RULES__' : rules, | 198 '__PROJECT_RULES__' : rules, |
193 '__PROJECT_PRELAUNCH__' : prelaunch, | 199 '__PROJECT_PRELAUNCH__' : prelaunch, |
194 '__PROJECT_PRERUN__' : prerun, | 200 '__PROJECT_PRERUN__' : prerun, |
195 '__PROJECT_POSTLAUNCH__' : postlaunch | 201 '__PROJECT_POSTLAUNCH__' : postlaunch |
196 } | 202 } |
197 | 203 |
198 | 204 |
199 # 'KEY' : ( <TYPE>, [Accepted Values], <Required?>) | 205 # 'KEY' : ( <TYPE>, [Accepted Values], <Required?>) |
200 DSC_FORMAT = { | 206 DSC_FORMAT = { |
201 'TOOLS' : (list, ['newlib', 'glibc', 'pnacl', 'win', 'linux'], True), | 207 'TOOLS' : (list, ['newlib:arm', 'newlib:x64', 'newlib:x86', 'newlib', |
| 208 'glibc', 'pnacl', 'win', 'linux'], True), |
202 'CONFIGS' : (list, ['Debug', 'Release'], False), | 209 'CONFIGS' : (list, ['Debug', 'Release'], False), |
203 'PREREQ' : (list, '', False), | 210 'PREREQ' : (list, '', False), |
204 'TARGETS' : (list, { | 211 'TARGETS' : (list, { |
205 'NAME': (str, '', True), | 212 'NAME': (str, '', True), |
206 'TYPE': (str, ['main', 'nexe', 'lib', 'so'], True), | 213 'TYPE': (str, ['main', 'nexe', 'lib', 'so'], True), |
207 'SOURCES': (list, '', True), | 214 'SOURCES': (list, '', True), |
208 'CCFLAGS': (list, '', False), | 215 'CCFLAGS': (list, '', False), |
209 'CXXFLAGS': (list, '', False), | 216 'CXXFLAGS': (list, '', False), |
210 'DEFINES': (list, '', False), | 217 'DEFINES': (list, '', False), |
211 'LDFLAGS': (list, '', False), | 218 'LDFLAGS': (list, '', False), |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 continue | 276 continue |
270 | 277 |
271 # If it's a bool, the expected values are always True or False. | 278 # If it's a bool, the expected values are always True or False. |
272 if exp_type is bool: | 279 if exp_type is bool: |
273 continue | 280 continue |
274 | 281 |
275 # If it's a string and there are expected values, make sure it matches | 282 # If it's a string and there are expected values, make sure it matches |
276 if exp_type is str: | 283 if exp_type is str: |
277 if type(exp_value) is list and exp_value: | 284 if type(exp_value) is list and exp_value: |
278 if value not in exp_value: | 285 if value not in exp_value: |
279 ErrorMsg('Value %s not expected for %s.' % (value, key)) | 286 ErrorMsg("Value '%s' not expected for %s." % (value, key)) |
280 failed = True | 287 failed = True |
281 continue | 288 continue |
282 | 289 |
283 # if it's a list, then we need to validate the values | 290 # if it's a list, then we need to validate the values |
284 if exp_type is list: | 291 if exp_type is list: |
285 # If we expect a dictionary, then call this recursively | 292 # If we expect a dictionary, then call this recursively |
286 if type(exp_value) is dict: | 293 if type(exp_value) is dict: |
287 for val in value: | 294 for val in value: |
288 if not ValidateFormat(val, exp_value, ErrorMsg): | 295 if not ValidateFormat(val, exp_value, ErrorMsg): |
289 failed = True | 296 failed = True |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 WriteReplaced(srcfile, dstfile, replace) | 394 WriteReplaced(srcfile, dstfile, replace) |
388 | 395 |
389 | 396 |
390 def LoadProject(filename, toolchains): | 397 def LoadProject(filename, toolchains): |
391 """Generate a Master Makefile that builds all examples. | 398 """Generate a Master Makefile that builds all examples. |
392 | 399 |
393 Load a project desciption file, verifying it conforms and checking | 400 Load a project desciption file, verifying it conforms and checking |
394 if it matches the set of requested toolchains. Return None if the | 401 if it matches the set of requested toolchains. Return None if the |
395 project is filtered out.""" | 402 project is filtered out.""" |
396 | 403 |
397 print '\n\nProcessing %s...' % filename | 404 print 'Processing %s...' % filename |
398 # Default src directory is the directory the description was found in | 405 # Default src directory is the directory the description was found in |
399 desc = open(filename, 'r').read() | 406 desc = open(filename, 'r').read() |
400 desc = eval(desc, {}, {}) | 407 desc = eval(desc, {}, {}) |
401 | 408 |
402 # Verify the format of this file | 409 # Verify the format of this file |
403 if not ValidateFormat(desc, DSC_FORMAT): | 410 if not ValidateFormat(desc, DSC_FORMAT): |
404 ErrorExit('Failed to validate: ' + filename) | 411 ErrorExit('Failed to validate: ' + filename) |
405 | 412 |
406 # Check if we are actually interested in this example | 413 # Check if we are actually interested in this example |
407 match = False | 414 match = False |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 gyp += '.bat' | 473 gyp += '.bat' |
467 buildbot_common.Run([gyp, '-Gstandalone', '--format', generator, | 474 buildbot_common.Run([gyp, '-Gstandalone', '--format', generator, |
468 '--toplevel-dir=.', gypfile], cwd=out_dir) | 475 '--toplevel-dir=.', gypfile], cwd=out_dir) |
469 | 476 |
470 if sys.platform == 'win32' or not use_gyp: | 477 if sys.platform == 'win32' or not use_gyp: |
471 if IsNexe(desc): | 478 if IsNexe(desc): |
472 template = os.path.join(SCRIPT_DIR, 'template.mk') | 479 template = os.path.join(SCRIPT_DIR, 'template.mk') |
473 else: | 480 else: |
474 template = os.path.join(SCRIPT_DIR, 'library.mk') | 481 template = os.path.join(SCRIPT_DIR, 'library.mk') |
475 | 482 |
476 tools = [] | 483 tools = {} |
| 484 tool_list = [] |
477 for tool in desc['TOOLS']: | 485 for tool in desc['TOOLS']: |
478 if tool in toolchains: | 486 if ':' in tool: |
479 tools.append(tool) | 487 tool, arch = tool.split(':') |
| 488 else: |
| 489 arch = None |
| 490 # Ignore tools that are not enabled in this SDK build |
| 491 if tool not in toolchains: |
| 492 continue |
| 493 tools.setdefault(tool, []) |
| 494 if tool not in tool_list: |
| 495 tool_list.append(tool) |
| 496 if arch: |
| 497 tools[tool].append(arch) |
480 | 498 |
| 499 desc['TOOLS'] = tool_list |
481 | 500 |
482 # Add Makefile and make.bat | 501 # Add Makefile and make.bat |
483 repdict = GenerateReplacements(desc, tools) | 502 repdict = GenerateReplacements(desc, tools) |
484 WriteReplaced(template, make_path, repdict) | 503 WriteReplaced(template, make_path, repdict) |
485 | 504 |
486 outdir = os.path.dirname(os.path.abspath(make_path)) | 505 outdir = os.path.dirname(os.path.abspath(make_path)) |
487 pepperdir = os.path.dirname(os.path.dirname(outdir)) | 506 pepperdir = os.path.dirname(os.path.dirname(outdir)) |
488 AddMakeBat(pepperdir, outdir) | 507 AddMakeBat(pepperdir, outdir) |
489 return (name, desc['DEST']) | 508 return (name, desc['DEST']) |
490 | 509 |
(...skipping 29 matching lines...) Expand all Loading... |
520 } | 539 } |
521 | 540 |
522 WriteReplaced(in_path, out_path, replace) | 541 WriteReplaced(in_path, out_path, replace) |
523 | 542 |
524 outdir = os.path.dirname(os.path.abspath(out_path)) | 543 outdir = os.path.dirname(os.path.abspath(out_path)) |
525 pepperdir = os.path.dirname(outdir) | 544 pepperdir = os.path.dirname(outdir) |
526 AddMakeBat(pepperdir, outdir) | 545 AddMakeBat(pepperdir, outdir) |
527 | 546 |
528 | 547 |
529 def main(argv): | 548 def main(argv): |
530 parser = optparse.OptionParser() | 549 usage = "usage: generate_make [options] <dsc_file ..>" |
| 550 parser = optparse.OptionParser(usage=usage) |
531 parser.add_option('--dstroot', help='Set root for destination.', | 551 parser.add_option('--dstroot', help='Set root for destination.', |
532 dest='dstroot', default=os.path.join(OUT_DIR, 'pepper_canary')) | 552 default=os.path.join(OUT_DIR, 'pepper_canary')) |
533 parser.add_option('--master', help='Create master Makefile.', | 553 parser.add_option('--master', help='Create master Makefile.', |
534 action='store_true', dest='master', default=False) | 554 action='store_true', default=False) |
535 parser.add_option('--newlib', help='Create newlib examples.', | 555 parser.add_option('--newlib', help='Create newlib examples.', |
536 action='store_true', dest='newlib', default=False) | 556 action='store_true', default=False) |
537 parser.add_option('--glibc', help='Create glibc examples.', | 557 parser.add_option('--glibc', help='Create glibc examples.', |
538 action='store_true', dest='glibc', default=False) | 558 action='store_true', default=False) |
539 parser.add_option('--pnacl', help='Create pnacl examples.', | 559 parser.add_option('--pnacl', help='Create pnacl examples.', |
540 action='store_true', dest='pnacl', default=False) | 560 action='store_true', default=False) |
541 parser.add_option('--host', help='Create host examples.', | 561 parser.add_option('--host', help='Create host examples.', |
542 action='store_true', dest='host', default=False) | 562 action='store_true', default=False) |
543 parser.add_option('--experimental', help='Create experimental examples.', | 563 parser.add_option('--experimental', help='Create experimental examples.', |
544 action='store_true', dest='experimental', default=False) | 564 action='store_true', default=False) |
545 | 565 |
546 toolchains = [] | 566 toolchains = [] |
547 platform = getos.GetPlatform() | 567 platform = getos.GetPlatform() |
548 | 568 |
549 options, args = parser.parse_args(argv) | 569 options, args = parser.parse_args(argv) |
550 if options.newlib: | 570 if options.newlib: |
551 toolchains.append('newlib') | 571 toolchains.append('newlib') |
552 if options.glibc: | 572 if options.glibc: |
553 toolchains.append('glibc') | 573 toolchains.append('glibc') |
554 if options.pnacl: | 574 if options.pnacl: |
555 toolchains.append('pnacl') | 575 toolchains.append('pnacl') |
556 if options.host: | 576 if options.host: |
557 toolchains.append(platform) | 577 toolchains.append(platform) |
558 | 578 |
559 if not args: | 579 if not args: |
560 ErrorExit('Please specify one or more projects to generate Makefiles for.') | 580 ErrorExit('Please specify one or more projects to generate Makefiles for.') |
561 | 581 |
562 # By default support newlib and glibc | 582 # By default support newlib and glibc |
563 if not toolchains: | 583 if not toolchains: |
564 toolchains = ['newlib', 'glibc'] | 584 toolchains = ['newlib', 'glibc', 'pnacl'] |
565 print 'Using default toolchains: ' + ' '.join(toolchains) | |
566 | 585 |
567 master_projects = {} | 586 master_projects = {} |
568 | 587 |
569 landing_page = LandingPage() | 588 landing_page = LandingPage() |
570 for filename in args: | 589 for i, filename in enumerate(args): |
| 590 if i: |
| 591 # Print two newlines between each dsc file we process |
| 592 print '\n' |
571 desc = LoadProject(filename, toolchains) | 593 desc = LoadProject(filename, toolchains) |
572 if not desc: | 594 if not desc: |
573 print 'Skipping %s, not in [%s].' % (filename, ', '.join(toolchains)) | 595 print 'Skipping %s, not in [%s].' % (filename, ', '.join(toolchains)) |
574 continue | 596 continue |
575 | 597 |
576 if desc.get('EXPERIMENTAL', False) and not options.experimental: | 598 if desc.get('EXPERIMENTAL', False) and not options.experimental: |
577 print 'Skipping %s, experimental only.' % (filename,) | 599 print 'Skipping %s, experimental only.' % (filename,) |
578 continue | 600 continue |
579 | 601 |
580 srcroot = os.path.dirname(os.path.abspath(filename)) | 602 srcroot = os.path.dirname(os.path.abspath(filename)) |
(...skipping 25 matching lines...) Expand all Loading... |
606 for dest, projects in master_projects.iteritems(): | 628 for dest, projects in master_projects.iteritems(): |
607 master_out = os.path.join(options.dstroot, dest, 'Makefile') | 629 master_out = os.path.join(options.dstroot, dest, 'Makefile') |
608 GenerateMasterMakefile(master_in, master_out, projects) | 630 GenerateMasterMakefile(master_in, master_out, projects) |
609 | 631 |
610 return 0 | 632 return 0 |
611 | 633 |
612 | 634 |
613 if __name__ == '__main__': | 635 if __name__ == '__main__': |
614 sys.exit(main(sys.argv[1:])) | 636 sys.exit(main(sys.argv[1:])) |
615 | 637 |
OLD | NEW |