Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(802)

Side by Side Diff: native_client_sdk/src/build_tools/generate_make.py

Issue 10821050: add dependancy generatation to generated Makefiles (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased against latest Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 make_rules 7 import make_rules
8 import optparse 8 import optparse
9 import os 9 import os
10 import sys 10 import sys
11 11
12 from make_rules import BuildDefineList, BuildLibList, BuildToolDict 12 from make_rules import BuildDefineList, BuildLibList, BuildToolDict
13 from make_rules import GetBuildRule, BUILD_RULES 13 from make_rules import GetBuildRule, BUILD_RULES
14 14
15 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 15 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
16 SDK_SRC_DIR = os.path.dirname(SCRIPT_DIR) 16 SDK_SRC_DIR = os.path.dirname(SCRIPT_DIR)
17 SDK_EXAMPLE_DIR = os.path.join(SDK_SRC_DIR, 'examples') 17 SDK_EXAMPLE_DIR = os.path.join(SDK_SRC_DIR, 'examples')
18 SDK_DIR = os.path.dirname(SDK_SRC_DIR) 18 SDK_DIR = os.path.dirname(SDK_SRC_DIR)
19 SRC_DIR = os.path.dirname(SDK_DIR) 19 SRC_DIR = os.path.dirname(SDK_DIR)
20 OUT_DIR = os.path.join(SRC_DIR, 'out') 20 OUT_DIR = os.path.join(SRC_DIR, 'out')
21 PPAPI_DIR = os.path.join(SRC_DIR, 'ppapi') 21 PPAPI_DIR = os.path.join(SRC_DIR, 'ppapi')
22 22
23 # Add SDK make tools scripts to the python path. 23 # Add SDK make tools scripts to the python path.
24 sys.path.append(os.path.join(SDK_SRC_DIR, 'tools')) 24 sys.path.append(os.path.join(SDK_SRC_DIR, 'tools'))
25 import getos 25 import getos
26 26
27 SUPPORTED_HOSTS = ['win'] 27 SUPPORTED_HOSTS = ['win']
28 28
29 def ErrorExit(text): 29 def ErrorExit(text):
30 sys.stderr.write(text + '\n') 30 ErrorMsgFunc(text)
31 sys.exit(1) 31 sys.exit(1)
32 32
33 33
34 def Replace(text, replacements): 34 def Replace(text, replacements):
35 for key in replacements: 35 for key in replacements:
36 val = replacements[key] 36 val = replacements[key]
37 if val is not None: 37 if val is not None:
38 text = text.replace(key, val) 38 text = text.replace(key, val)
39 return text 39 return text
40 40
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 80
81 def GetSourcesDict(sources): 81 def GetSourcesDict(sources):
82 source_map = {} 82 source_map = {}
83 for key in ['.c', '.cc']: 83 for key in ['.c', '.cc']:
84 source_list = [fname for fname in sources if fname.endswith(key)] 84 source_list = [fname for fname in sources if fname.endswith(key)]
85 if source_list: 85 if source_list:
86 source_map[key] = source_list 86 source_map[key] = source_list
87 else: 87 else:
88 source_map[key] = [] 88 source_map[key] = []
89 return source_map 89 return source_map
90 90
91 91
92 def GetPlatforms(plat_list, plat_filter): 92 def GetPlatforms(plat_list, plat_filter):
93 platforms = [] 93 platforms = []
94 for plat in plat_list: 94 for plat in plat_list:
95 if plat in plat_filter: 95 if plat in plat_filter:
96 platforms.append(plat) 96 platforms.append(plat)
97 return platforms 97 return platforms
98 98
99 99
100 def GenerateToolDefaults(desc, tools): 100 def GenerateToolDefaults(desc, tools):
101 defaults = '' 101 defaults = ''
102 for tool in tools: 102 for tool in tools:
103 defaults += BUILD_RULES[tool]['DEFS'] 103 defaults += BUILD_RULES[tool]['DEFS']
104 return defaults 104 return defaults
105 105
106 106
107 def GenerateSettings(desc, tools): 107 def GenerateSettings(desc, tools):
108 settings = SetVar('VALID_TOOLCHAINS', tools) 108 settings = SetVar('VALID_TOOLCHAINS', tools)
109 settings+= 'TOOLCHAIN?=%s\n\n' % tools[0] 109 settings+= 'TOOLCHAIN?=%s\n\n' % tools[0]
110 for target in desc['TARGETS']: 110 for target in desc['TARGETS']:
111 name = target['NAME'] 111 name = target['NAME']
112 macro = name.upper() 112 macro = name.upper()
113 srcs = GetSourcesDict(target['SOURCES']) 113 srcs = GetSourcesDict(target['SOURCES'])
114 114
(...skipping 15 matching lines...) Expand all
130 def GetTarget(tool, targ_type, replace): 130 def GetTarget(tool, targ_type, replace):
131 pattern = BUILD_RULES[tool]['TOOL'][targ_type] 131 pattern = BUILD_RULES[tool]['TOOL'][targ_type]
132 return Replace(pattern, replace) 132 return Replace(pattern, replace)
133 133
134 134
135 def GenerateCompile(target, tool, arch, srcs): 135 def GenerateCompile(target, tool, arch, srcs):
136 """Generates a Compile target. 136 """Generates a Compile target.
137 137
138 For the given target, toolset and architecture, returns a rule to generate 138 For the given target, toolset and architecture, returns a rule to generate
139 the object files for the set of sources. 139 the object files for the set of sources.
140 140
141 Returns: 141 Returns:
142 Returns a tuple containin the objects and the rule. 142 Returns a tuple containin the objects and the rule.
143 """ 143 """
144 rules = '' 144 rules = ''
145 name = target['NAME'] 145 name = target['NAME']
146 object_sets = [] 146 object_sets = []
147 147
148 defines = target.get('DEFINES', []) 148 defines = target.get('DEFINES', [])
149 defs = BuildDefineList(tool, defines) 149 defs = BuildDefineList(tool, defines)
150 150
151 if srcs['.c']: 151 if srcs['.c']:
152 replace = BuildToolDict(tool, name, arch, 'c', DEFLIST=defs) 152 replace = BuildToolDict(tool, name, arch, 'c', DEFLIST=defs)
153 compile_rule = GetBuildRule(tool, 'CC') 153 compile_rule = GetBuildRule(tool, 'CC')
154 rules += Replace(compile_rule, replace) 154 rules += Replace(compile_rule, replace)
155 object_sets.append('$(%s)' % replace['<OBJS>']) 155 object_sets.append('$(%s)' % replace['<OBJS>'])
156 156
157 if srcs['.cc']: 157 if srcs['.cc']:
158 replace = BuildToolDict(tool, name, arch, 'cc', DEFLIST=defs) 158 replace = BuildToolDict(tool, name, arch, 'cc', DEFLIST=defs)
159 compile_rule = GetBuildRule(tool, 'CXX') 159 compile_rule = GetBuildRule(tool, 'CXX')
160 rules += Replace(compile_rule, replace) 160 rules += Replace(compile_rule, replace)
161 object_sets.append('$(%s)' % replace['<OBJS>']) 161 object_sets.append('$(%s)' % replace['<OBJS>'])
162
162 return (' '.join(object_sets), rules) 163 return (' '.join(object_sets), rules)
163 164
164 165
165 def GenerateLink(target, tool, arch, objs): 166 def GenerateLink(target, tool, arch, objs):
166 """Generate a Link target. 167 """Generate a Link target.
167 168
168 Returns: 169 Returns:
169 Returns a tuple containing the rule and target. 170 Returns a tuple containing the rule and target.
170 """ 171 """
171 targ_type = target['TYPE'] 172 targ_type = target['TYPE']
172 link_rule = GetBuildRule(tool, targ_type.upper()) 173 link_rule = GetBuildRule(tool, targ_type.upper())
173 libs = target.get('LIBS', []) 174 libs = target.get('LIBS', [])
174 libs = BuildLibList(tool, libs) 175 libs = BuildLibList(tool, libs)
175 replace = BuildToolDict(tool, target['NAME'], arch, 'nexe', 176 replace = BuildToolDict(tool, target['NAME'], arch, 'nexe',
176 OBJS=objs, LIBLIST=libs) 177 OBJS=objs, LIBLIST=libs)
177 rule = Replace(link_rule, replace) 178 rule = Replace(link_rule, replace)
178 target_out = GetTarget(tool, targ_type, replace) 179 target_out = GetTarget(tool, targ_type, replace)
179 return target_out, rule 180 return target_out, rule
180 181
181 182
182 def GenerateNMF(target, tool): 183 def GenerateNMF(target, tool):
183 nmf_rule = BUILD_RULES[tool]['NMF'] 184 nmf_rule = BUILD_RULES[tool]['NMF']
184 replace = BuildToolDict(tool, target['NAME']) 185 replace = BuildToolDict(tool, target['NAME'])
185 rule = Replace(nmf_rule, replace) 186 rule = Replace(nmf_rule, replace)
186 target_out = GetTarget(tool, 'nmf', replace) 187 target_out = GetTarget(tool, 'nmf', replace)
187 return target_out, rule 188 return target_out, rule
(...skipping 18 matching lines...) Expand all
206 207
207 if target['TYPE'] == 'main': 208 if target['TYPE'] == 'main':
208 main = target 209 main = target
209 elif target['TYPE'] == 'lib': 210 elif target['TYPE'] == 'lib':
210 all_targets.append(targs) 211 all_targets.append(targs)
211 212
212 if main: 213 if main:
213 targs, nmf_rule = GenerateNMF(main, tc) 214 targs, nmf_rule = GenerateNMF(main, tc)
214 rules += nmf_rule 215 rules += nmf_rule
215 all_targets.append(targs) 216 all_targets.append(targs)
216 rules += '\n.PHONY : clean\nclean:\n\t$(RM) ' + ' '.join(clean) 217 rules += '\n.PHONY : clean\nclean:\n\t$(RM) $(DEPFILES) ' + ' '.join(clean)
218 rules += '\n\n-include $(DEPFILES)'
217 return ' '.join(all_targets), rules 219 return ' '.join(all_targets), rules
218 220
219 221
220
221 def GenerateTargets(desc, tools): 222 def GenerateTargets(desc, tools):
222 targets = [] 223 targets = []
223 rules = '' 224 rules = ''
224 for tc in tools: 225 for tc in tools:
225 for target in desc['TARGETS']: 226 for target in desc['TARGETS']:
226 name = target['NAME'] 227 name = target['NAME']
227 replace = BuildToolDict(tc, name) 228 replace = BuildToolDict(tc, name)
228 target = GetTarget(tc, target['TYPE'], replace) 229 target = GetTarget(tc, target['TYPE'], replace)
229 if target: 230 if target:
230 targets.append(target) 231 targets.append(target)
(...skipping 19 matching lines...) Expand all
250 '__PROJECT_SETTINGS__' : settings, 251 '__PROJECT_SETTINGS__' : settings,
251 '__PROJECT_TARGETS__' : target_def, 252 '__PROJECT_TARGETS__' : target_def,
252 '__PROJECT_TOOLS__' : tool_def, 253 '__PROJECT_TOOLS__' : tool_def,
253 '__PROJECT_RULES__' : rules, 254 '__PROJECT_RULES__' : rules,
254 '__PROJECT_PRELAUNCH__' : prelaunch, 255 '__PROJECT_PRELAUNCH__' : prelaunch,
255 '__PROJECT_PRERUN__' : prerun, 256 '__PROJECT_PRERUN__' : prerun,
256 '__PROJECT_POSTLAUNCH__' : postlaunch 257 '__PROJECT_POSTLAUNCH__' : postlaunch
257 } 258 }
258 259
259 260
260
261 # 'KEY' : ( <TYPE>, [Accepted Values], <Required?>) 261 # 'KEY' : ( <TYPE>, [Accepted Values], <Required?>)
262 DSC_FORMAT = { 262 DSC_FORMAT = {
263 'TOOLS' : (list, ['newlib', 'glibc', 'pnacl', 'win'], True), 263 'TOOLS' : (list, ['newlib', 'glibc', 'pnacl', 'win'], True),
264 'PREREQ' : (list, '', False), 264 'PREREQ' : (list, '', False),
265 'TARGETS' : (list, { 265 'TARGETS' : (list, {
266 'NAME': (str, '', True), 266 'NAME': (str, '', True),
267 'TYPE': (str, ['main', 'nexe', 'lib', 'so'], True), 267 'TYPE': (str, ['main', 'nexe', 'lib', 'so'], True),
268 'SOURCES': (list, '', True), 268 'SOURCES': (list, '', True),
269 'CCFLAGS': (list, '', False), 269 'CCFLAGS': (list, '', False),
270 'CXXFLAGS': (list, '', False), 270 'CXXFLAGS': (list, '', False),
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 303
304 # For each provided key, verify it's valid 304 # For each provided key, verify it's valid
305 for key in src: 305 for key in src:
306 # Verify the key is known 306 # Verify the key is known
307 if key not in format: 307 if key not in format:
308 ErrorMsg('Unexpected key %s.' % key) 308 ErrorMsg('Unexpected key %s.' % key)
309 failed = True 309 failed = True
310 continue 310 continue
311 311
312 exp_type, exp_value, required = format[key] 312 exp_type, exp_value, required = format[key]
313 value = src[key] 313 value = src[key]
314 314
315 # Verify the key is of the expected type 315 # Verify the key is of the expected type
316 if exp_type != type(value): 316 if exp_type != type(value):
317 ErrorMsg('Key %s expects %s not %s.' % ( 317 ErrorMsg('Key %s expects %s not %s.' % (
318 key, exp_type.__name__.upper(), type(value).__name__.upper())) 318 key, exp_type.__name__.upper(), type(value).__name__.upper()))
319 failed = True 319 failed = True
320 continue 320 continue
321 321
322 # Verify the value is non-empty if required 322 # Verify the value is non-empty if required
323 if required and not value: 323 if required and not value:
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 def IsNexe(desc): 402 def IsNexe(desc):
403 for target in desc['TARGETS']: 403 for target in desc['TARGETS']:
404 if target['TYPE'] == 'main': 404 if target['TYPE'] == 'main':
405 return True 405 return True
406 return False 406 return False
407 407
408 408
409 def ProcessHTML(srcroot, dstroot, desc, toolchains): 409 def ProcessHTML(srcroot, dstroot, desc, toolchains):
410 name = desc['NAME'] 410 name = desc['NAME']
411 outdir = os.path.join(dstroot, desc['DEST'], name) 411 outdir = os.path.join(dstroot, desc['DEST'], name)
412 412
413 srcfile = os.path.join(srcroot, 'index.html') 413 srcfile = os.path.join(srcroot, 'index.html')
414 tools = GetPlatforms(toolchains, desc['TOOLS']) 414 tools = GetPlatforms(toolchains, desc['TOOLS'])
415 for tool in tools: 415 for tool in tools:
416 dstfile = os.path.join(outdir, 'index_%s.html' % tool); 416 dstfile = os.path.join(outdir, 'index_%s.html' % tool);
417 print 'Writting from %s to %s' % (srcfile, dstfile) 417 print 'Writting from %s to %s' % (srcfile, dstfile)
418 replace = { 418 replace = {
419 '<NAME>': name, 419 '<NAME>': name,
420 '<TITLE>': desc['TITLE'], 420 '<TITLE>': desc['TITLE'],
421 '<tc>': tool 421 '<tc>': tool
422 } 422 }
423 WriteReplaced(srcfile, dstfile, replace) 423 WriteReplaced(srcfile, dstfile, replace)
424 424
425 replace['<tc>'] = tools[0] 425 replace['<tc>'] = tools[0]
426 srcfile = os.path.join(SDK_SRC_DIR, 'build_tools', 'redirect.html') 426 srcfile = os.path.join(SDK_SRC_DIR, 'build_tools', 'redirect.html')
427 dstfile = os.path.join(outdir, 'index.html') 427 dstfile = os.path.join(outdir, 'index.html')
428 WriteReplaced(srcfile, dstfile, replace) 428 WriteReplaced(srcfile, dstfile, replace)
429 429
430 430
431 def LoadProject(filename, toolchains): 431 def LoadProject(filename, toolchains):
432 """Generate a Master Makefile that builds all examples. 432 """Generate a Master Makefile that builds all examples.
433 433
434 Load a project desciption file, verifying it conforms and checking 434 Load a project desciption file, verifying it conforms and checking
435 if it matches the set of requested toolchains. Return None if the 435 if it matches the set of requested toolchains. Return None if the
436 project is filtered out.""" 436 project is filtered out."""
437 437
438 print '\n\nProcessing %s...' % filename 438 print '\n\nProcessing %s...' % filename
439 # Default src directory is the directory the description was found in 439 # Default src directory is the directory the description was found in
440 desc = open(filename, 'r').read() 440 desc = open(filename, 'r').read()
441 desc = eval(desc, {}, {}) 441 desc = eval(desc, {}, {})
442 442
443 # Verify the format of this file 443 # Verify the format of this file
444 if not ValidateFormat(desc, DSC_FORMAT): 444 if not ValidateFormat(desc, DSC_FORMAT):
445 ErrorExit('Failed to validate: ' + filename) 445 ErrorExit('Failed to validate: ' + filename)
446 446
447 # Check if we are actually interested in this example 447 # Check if we are actually interested in this example
448 match = False 448 match = False
449 for toolchain in toolchains: 449 for toolchain in toolchains:
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 504
505 505
506 def GenerateMasterMakefile(in_path, out_path, projects): 506 def GenerateMasterMakefile(in_path, out_path, projects):
507 """Generate a Master Makefile that builds all examples. """ 507 """Generate a Master Makefile that builds all examples. """
508 replace = { '__PROJECT_LIST__' : SetVar('PROJECTS', projects) } 508 replace = { '__PROJECT_LIST__' : SetVar('PROJECTS', projects) }
509 WriteReplaced(in_path, out_path, replace) 509 WriteReplaced(in_path, out_path, replace)
510 510
511 outdir = os.path.dirname(os.path.abspath(out_path)) 511 outdir = os.path.dirname(os.path.abspath(out_path))
512 pepperdir = os.path.dirname(outdir) 512 pepperdir = os.path.dirname(outdir)
513 AddMakeBat(pepperdir, outdir) 513 AddMakeBat(pepperdir, outdir)
514 514
515 515
516 def main(argv): 516 def main(argv):
517 parser = optparse.OptionParser() 517 parser = optparse.OptionParser()
518 parser.add_option('--dstroot', help='Set root for destination.', 518 parser.add_option('--dstroot', help='Set root for destination.',
519 dest='dstroot', default=os.path.join(OUT_DIR, 'pepper_canary')) 519 dest='dstroot', default=os.path.join(OUT_DIR, 'pepper_canary'))
520 parser.add_option('--master', help='Create master Makefile.', 520 parser.add_option('--master', help='Create master Makefile.',
521 action='store_true', dest='master', default=False) 521 action='store_true', dest='master', default=False)
522 parser.add_option('--newlib', help='Create newlib examples.', 522 parser.add_option('--newlib', help='Create newlib examples.',
523 action='store_true', dest='newlib', default=False) 523 action='store_true', dest='newlib', default=False)
524 parser.add_option('--glibc', help='Create glibc examples.', 524 parser.add_option('--glibc', help='Create glibc examples.',
525 action='store_true', dest='glibc', default=False) 525 action='store_true', dest='glibc', default=False)
526 parser.add_option('--pnacl', help='Create pnacl examples.', 526 parser.add_option('--pnacl', help='Create pnacl examples.',
527 action='store_true', dest='pnacl', default=False) 527 action='store_true', dest='pnacl', default=False)
528 parser.add_option('--host', help='Create host examples.', 528 parser.add_option('--host', help='Create host examples.',
529 action='store_true', dest='host', default=False) 529 action='store_true', dest='host', default=False)
530 530
531 toolchains = [] 531 toolchains = []
532 platform = getos.GetPlatform() 532 platform = getos.GetPlatform()
533 533
534 options, args = parser.parse_args(argv) 534 options, args = parser.parse_args(argv)
535 if options.newlib: 535 if options.newlib:
536 toolchains.append('newlib') 536 toolchains.append('newlib')
537 if options.glibc: 537 if options.glibc:
538 toolchains.append('glibc') 538 toolchains.append('glibc')
539 if options.pnacl: 539 if options.pnacl:
540 toolchains.append('pnacl') 540 toolchains.append('pnacl')
541 if options.host: 541 if options.host:
542 toolchains.append(platform) 542 toolchains.append(platform)
543 543
544 if not args:
545 ErrorExit('Please specify one or more projects to generate Makefiles for.')
546
544 # By default support newlib and glibc 547 # By default support newlib and glibc
545 if not toolchains: 548 if not toolchains:
546 toolchains = ['newlib', 'glibc'] 549 toolchains = ['newlib', 'glibc']
547 print 'Using default toolchains: ' + ' '.join(toolchains) 550 print 'Using default toolchains: ' + ' '.join(toolchains)
548 551
549 examples = [] 552 examples = []
550 libs = [] 553 libs = []
551 for filename in args: 554 for filename in args:
552 desc = LoadProject(filename, toolchains) 555 desc = LoadProject(filename, toolchains)
553 if not desc: 556 if not desc:
(...skipping 17 matching lines...) Expand all
571 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile') 574 master_in = os.path.join(SDK_EXAMPLE_DIR, 'Makefile')
572 master_out = os.path.join(options.dstroot, 'examples', 'Makefile') 575 master_out = os.path.join(options.dstroot, 'examples', 'Makefile')
573 GenerateMasterMakefile(master_in, master_out, examples) 576 GenerateMasterMakefile(master_in, master_out, examples)
574 master_out = os.path.join(options.dstroot, 'src', 'Makefile') 577 master_out = os.path.join(options.dstroot, 'src', 'Makefile')
575 GenerateMasterMakefile(master_in, master_out, libs) 578 GenerateMasterMakefile(master_in, master_out, libs)
576 return 0 579 return 0
577 580
578 581
579 if __name__ == '__main__': 582 if __name__ == '__main__':
580 sys.exit(main(sys.argv[1:])) 583 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « no previous file | native_client_sdk/src/build_tools/make_rules.py » ('j') | native_client_sdk/src/build_tools/make_rules.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698