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

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

Issue 13488007: [NaCl SDK] Make the SDK examples buildable as a packaged app. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more fixes, moved resources out of build_tools directory Created 7 years, 8 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 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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698