comparison python/zcc.py @ 334:6f4753202b9a

Added more recipes
author Windel Bouwman
date Thu, 13 Feb 2014 22:02:08 +0100
parents 87feb8a23b4d
children d1ecc493384e
comparison
equal deleted inserted replaced
333:dcae6574c974 334:6f4753202b9a
4 import os 4 import os
5 import argparse 5 import argparse
6 import logging 6 import logging
7 import yaml 7 import yaml
8 8
9 from ppci.buildtasks import Compile 9 from ppci.buildtasks import Compile, Assemble, Link
10 from ppci.tasks import TaskRunner 10 from ppci.tasks import TaskRunner
11 from ppci.report import RstFormatter 11 from ppci.report import RstFormatter
12 import outstream 12 from ppci.objectfile import ObjectFile
13 from target.target_list import target_list 13 from target.target_list import target_list
14 import ppci 14 import ppci
15 15
16 16
17 def logLevel(s): 17 def logLevel(s):
27 27
28 def make_parser(): 28 def make_parser():
29 parser = argparse.ArgumentParser(description='lcfos Compiler') 29 parser = argparse.ArgumentParser(description='lcfos Compiler')
30 30
31 parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])', 31 parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])',
32 type=logLevel, default='WARN') 32 type=logLevel, default='INFO')
33 parser.add_argument('--display-build-steps', action='store_true') 33 parser.add_argument('--display-build-steps', action='store_true')
34 sub_parsers = parser.add_subparsers(title='commands', 34 sub_parsers = parser.add_subparsers(title='commands',
35 description='possible commands', dest='command') 35 description='possible commands', dest='command')
36 recipe_parser = sub_parsers.add_parser('recipe', help="Bake recipe") 36 recipe_parser = sub_parsers.add_parser('recipe', help="Bake recipe")
37 recipe_parser.add_argument('recipe_file', help='recipe file') 37 recipe_parser.add_argument('recipe_file', help='recipe file')
50 type=argparse.FileType('w')) 50 type=argparse.FileType('w'))
51 return parser 51 return parser
52 52
53 53
54 class RecipeLoader: 54 class RecipeLoader:
55 """ Loads a recipe into a runner from a dictionary or file """
56 def __init__(self):
57 self.directive_handlers = {}
58 for a in dir(self):
59 if a.startswith('handle_'):
60 f = getattr(self, a)
61 self.directive_handlers[a[7:]] = f
62
55 def load_file(self, recipe_file, runner): 63 def load_file(self, recipe_file, runner):
56 """ Loads a recipe dictionary into a task runner """ 64 """ Loads a recipe dictionary into a task runner """
57 self.recipe_dir = os.path.abspath(os.path.dirname(recipe_file)) 65 self.recipe_dir = os.path.abspath(os.path.dirname(recipe_file))
58 with open(recipe_file, 'r') as f: 66 with open(recipe_file, 'r') as f:
59 recipe = yaml.load(f) 67 recipe = yaml.load(f)
60 self.load_dict(recipe, runner) 68 self.runner = runner
69 self.load_dict(recipe)
61 70
62 def relpath(self, filename): 71 def relpath(self, filename):
63 return os.path.join(self.recipe_dir, filename) 72 return os.path.join(self.recipe_dir, filename)
64 73
65 def openfile(self, filename): 74 def openfile(self, filename):
66 return open(self.relpath(filename), 'r') 75 return open(self.relpath(filename), 'r')
67 76
68 def load_dict(self, recipe, runner): 77 def handle_compile(self, value):
78 sources = [self.openfile(s) for s in value['sources']]
79 includes = [self.openfile(i) for i in value['includes']]
80 target = targets[value['machine']]
81 output = ObjectFile()
82 task = Compile(sources, includes, target, output)
83 self.runner.add_task(task)
84 return task
85
86 def handle_assemble(self, value):
87 asm_src = self.openfile(value['source'])
88 target = targets[value['machine']]
89 output = ObjectFile()
90 task = Assemble(asm_src, target, output)
91 self.runner.add_task(task)
92 return task
93
94 def handle_link(self, value):
95 inputs = value['inputs']
96 objs = []
97 for i in inputs:
98 task = self.load_dict(i)
99 objs.append(task.output)
100 self.runner.add_task(Link(objs, None))
101
102 def handle_apps(self, value):
103 for a in value:
104 self.load_dict(a)
105
106 def load_dict(self, recipe):
69 for command, value in recipe.items(): 107 for command, value in recipe.items():
70 if command == 'compile': 108 return self.directive_handlers[command](value)
71 sources = [self.openfile(s) for s in value['sources']]
72 includes = [self.openfile(i) for i in value['includes']]
73 target = targets[value['machine']]
74 output = outstream.TextOutputStream()
75 runner.add_task(Compile(sources, includes, target, output))
76 elif command == 'link':
77 self.load_dict(value['inputs'], runner)
78 #runner.add_task(Link())
79 elif command == 'assemble':
80 pass
81 elif command == 'apps':
82 for a in value:
83 self.load_dict(a, runner)
84 else:
85 raise NotImplementedError(command)
86 109
87 110
88 def main(args): 111 def main(args):
89 # Configure some logging: 112 # Configure some logging:
90 logging.getLogger().setLevel(logging.DEBUG) 113 logging.getLogger().setLevel(logging.DEBUG)
94 logging.getLogger().addHandler(ch) 117 logging.getLogger().addHandler(ch)
95 118
96 runner = TaskRunner() 119 runner = TaskRunner()
97 if args.command == 'compile': 120 if args.command == 'compile':
98 tg = targets[args.target] 121 tg = targets[args.target]
99 outs = outstream.TextOutputStream() 122 output = ObjectFile()
100 runner.add_task(Compile(args.source, args.imp, tg, outs)) 123 runner.add_task(Compile(args.source, args.imp, tg, output))
101 elif args.command == 'recipe': 124 elif args.command == 'recipe':
102 recipe_loader = RecipeLoader() 125 recipe_loader = RecipeLoader()
103 recipe_loader.load_file(args.recipe_file, runner) 126 recipe_loader.load_file(args.recipe_file, runner)
104 else: 127 else:
105 raise NotImplementedError('Invalid option') 128 raise NotImplementedError('Invalid option')