comparison python/ppci/recipe.py @ 377:9667d78ba79e

Switched to xml for project description
author Windel Bouwman
date Fri, 11 Apr 2014 15:47:50 +0200
parents 577ed7fb3fe4
children
comparison
equal deleted inserted replaced
376:1e951e71d3f1 377:9667d78ba79e
1 #!/usr/bin/python3
2
1 import os 3 import os
2 import yaml 4 import xml.dom.minidom
3 5
4 from .buildtasks import Compile, Assemble, Link 6 from .tasks import Project, Target
5 from .objectfile import ObjectFile
6 from .target.target_list import targets
7 7
8 8
9 class RecipeLoader: 9 class RecipeLoader:
10 """ Loads a recipe into a runner from a dictionary or file """ 10 """ Loads a recipe into a runner from a dictionary or file """
11 def __init__(self, runner): 11 def load_file(self, recipe_file):
12 self.runner = runner 12 """ Loads a build configuration from file """
13 self.directive_handlers = {} 13 recipe_dir = os.path.abspath(os.path.dirname(recipe_file))
14 for a in dir(self): 14 dom = xml.dom.minidom.parse(recipe_file)
15 if a.startswith('handle_'): 15 project = self.load_project(dom)
16 f = getattr(self, a) 16 project.set_property('basedir', recipe_dir)
17 self.directive_handlers[a[7:]] = f 17 return project
18 18
19 def load_file(self, recipe_file): 19 def load_project(self, elem):
20 """ Loads a recipe dictionary from file """ 20 elem = elem.getElementsByTagName("project")[0]
21 self.recipe_dir = os.path.abspath(os.path.dirname(recipe_file)) 21 name = elem.getAttribute('name')
22 with open(recipe_file, 'r') as f: 22 project = Project(name)
23 recipe = yaml.load(f) 23 if elem.hasAttribute('default'):
24 self.load_dict(recipe) 24 project.default = elem.getAttribute('default')
25 else:
26 project.default = None
25 27
26 def relpath(self, filename): 28 for pe in elem.getElementsByTagName("property"):
27 return os.path.join(self.recipe_dir, filename) 29 name = pe.getAttribute('name')
30 value = pe.getAttribute('value')
31 project.set_property(name, value)
32 for te in elem.getElementsByTagName("target"):
33 name = te.getAttribute('name')
34 target = Target(name, project)
35 if te.hasAttribute('depends'):
36 dependencies = te.getAttribute('depends').split(',')
37 for dep in dependencies:
38 target.add_dependency(dep)
39 # print(name)
40 project.add_target(target)
41 for cn in te.childNodes:
42 # print(cn, type(cn))
43 if type(cn) is xml.dom.minidom.Element:
44 task_name = cn.tagName
45 task_props = {}
46 for i in range(cn.attributes.length):
47 atr = cn.attributes.item(i)
48 #print(atr, atr.name, atr.value)
49 task_props[atr.name] = atr.value
50 target.add_task((task_name, task_props))
51 return project
28 52
29 def openfile(self, filename):
30 return open(self.relpath(filename), 'r')
31
32 def handle_compile(self, value):
33 sources = [self.openfile(s) for s in value['sources']]
34 if 'includes' in value:
35 includes = [self.openfile(i) for i in value['includes']]
36 else:
37 includes = []
38 target = targets[value['machine']]
39 output = ObjectFile()
40 task = Compile(sources, includes, target, output)
41 self.runner.add_task(task)
42 return task
43
44 def handle_assemble(self, value):
45 asm_src = self.openfile(value['source'])
46 target = targets[value['machine']]
47 output = ObjectFile()
48 task = Assemble(asm_src, target, output)
49 self.runner.add_task(task)
50 return task
51
52 def handle_link(self, value):
53 inputs = value['inputs']
54 objs = []
55 for i in inputs:
56 task = self.load_dict(i)
57 objs.append(task.output)
58 layout = value['layout']
59 output = self.relpath(value['output'])
60 self.runner.add_task(Link(objs, layout, output))
61
62 def handle_apps(self, value):
63 for a in value:
64 self.load_dict(a)
65
66 def load_dict(self, recipe):
67 for command, value in recipe.items():
68 return self.directive_handlers[command](value)
69