Mercurial > lcfOS
comparison python/ppci/buildtasks.py @ 366:39bf68bf1891
Fix sample tests and deterministic build
author | Windel Bouwman |
---|---|
date | Fri, 21 Mar 2014 09:43:01 +0100 |
parents | 5477e499b039 |
children | 9667d78ba79e |
comparison
equal
deleted
inserted
replaced
365:98ff43cfdd36 | 366:39bf68bf1891 |
---|---|
14 from . import DiagnosticsManager, CompilerError | 14 from . import DiagnosticsManager, CompilerError |
15 from .assembler import Assembler | 15 from .assembler import Assembler |
16 from .objectfile import ObjectFile | 16 from .objectfile import ObjectFile |
17 from .linker import Linker | 17 from .linker import Linker |
18 from .outstream import BinaryOutputStream, MasterOutputStream, LoggerOutputStream | 18 from .outstream import BinaryOutputStream, MasterOutputStream, LoggerOutputStream |
19 from .target.target_list import targets | |
20 from .target import Target | |
19 | 21 |
22 | |
23 def fix_target(tg): | |
24 """ Try to return an instance of the Target class """ | |
25 if isinstance(tg, Target): | |
26 return tg | |
27 elif isinstance(tg, str): | |
28 if tg in targets: | |
29 return targets[tg] | |
30 else: | |
31 raise TaskError('Target {} not found'.format(tg)) | |
32 raise TaskError('Invalid target {}'.format(tg)) | |
33 | |
34 | |
35 def fix_file(f): | |
36 """ Determine if argument is a file like object or make it so! """ | |
37 if hasattr(f, 'read'): | |
38 # Assume this is a file like object | |
39 return f | |
40 elif isinstance(f, str): | |
41 return open(f, 'r') | |
42 else: | |
43 raise TaskError('cannot use {} as input'.format(f)) | |
44 | |
45 def fix_object(o): | |
46 if isinstance(o, ObjectFile): | |
47 return o | |
48 else: | |
49 raise TaskError('Cannot use {} as objectfile'.format(o)) | |
20 | 50 |
21 class BuildTask(Task): | 51 class BuildTask(Task): |
22 """ Base task for all kind of weird build tasks """ | 52 """ Base task for all kind of weird build tasks """ |
23 def __init__(self, name): | 53 def __init__(self, name): |
24 super().__init__(name) | 54 super().__init__(name) |
28 class Assemble(BuildTask): | 58 class Assemble(BuildTask): |
29 """ Task that can runs the assembler over the source and enters the | 59 """ Task that can runs the assembler over the source and enters the |
30 output into an object file """ | 60 output into an object file """ |
31 def __init__(self, source, target, output_object): | 61 def __init__(self, source, target, output_object): |
32 super().__init__('Assemble') | 62 super().__init__('Assemble') |
33 self.source = source | 63 self.source = fix_file(source) |
34 self.output = output_object | 64 self.output = output_object |
35 self.ostream = BinaryOutputStream(self.output) | 65 o2 = BinaryOutputStream(self.output) |
36 self.assembler = Assembler(target) | 66 o1 = LoggerOutputStream() |
67 self.ostream = MasterOutputStream([o1, o2]) | |
68 self.assembler = Assembler(fix_target(target)) | |
37 | 69 |
38 def run(self): | 70 def run(self): |
71 self.logger.debug('Assembling into code section') | |
39 self.ostream.select_section('code') | 72 self.ostream.select_section('code') |
40 self.assembler.assemble(self.source, self.ostream) | 73 self.assembler.assemble(self.source, self.ostream) |
74 self.logger.debug('Assembling finished') | |
41 | 75 |
42 | 76 |
43 class Compile(BuildTask): | 77 class Compile(BuildTask): |
44 """ Task that compiles C3 source for some target into an object file """ | 78 """ Task that compiles C3 source for some target into an object file """ |
45 def __init__(self, sources, includes, target, output_object): | 79 def __init__(self, sources, includes, target, output_object): |
46 super().__init__('Compile') | 80 super().__init__('Compile') |
47 self.sources = sources | 81 self.sources = list(map(fix_file, sources)) |
48 self.includes = includes | 82 self.includes = list(map(fix_file, includes)) |
49 self.target = target | 83 self.target = fix_target(target) |
50 self.output = output_object | 84 self.output = output_object |
51 | 85 |
52 def run(self): | 86 def run(self): |
53 self.logger.debug('Compile started') | 87 self.logger.debug('Compile started') |
54 diag = DiagnosticsManager() | 88 diag = DiagnosticsManager() |
76 d = {'ircode':ircode} | 110 d = {'ircode':ircode} |
77 self.logger.debug('Starting code generation for {}'.format(ircode), extra=d) | 111 self.logger.debug('Starting code generation for {}'.format(ircode), extra=d) |
78 | 112 |
79 o2 = BinaryOutputStream(self.output) | 113 o2 = BinaryOutputStream(self.output) |
80 o1 = LoggerOutputStream() | 114 o1 = LoggerOutputStream() |
81 o = MasterOutputStream() | 115 o = MasterOutputStream([o1, o2]) |
82 o.add_substream(o1) | |
83 o.add_substream(o2) | |
84 cg.generate(ircode, o) | 116 cg.generate(ircode, o) |
85 | 117 |
86 if not c3b.ok: | 118 if not c3b.ok: |
87 diag.printErrors() | 119 diag.printErrors() |
88 raise TaskError('Compile errors') | 120 raise TaskError('Compile errors') |
90 | 122 |
91 class Link(BuildTask): | 123 class Link(BuildTask): |
92 """ Link together a collection of object files """ | 124 """ Link together a collection of object files """ |
93 def __init__(self, objects, layout, output_file): | 125 def __init__(self, objects, layout, output_file): |
94 super().__init__('Link') | 126 super().__init__('Link') |
95 self.objects = objects | 127 self.objects = list(map(fix_object, objects)) |
96 self.linker = Linker() | 128 self.linker = Linker() |
97 self.duration = 0.1337 | 129 self.duration = 0.1337 |
98 self.layout = layout | 130 self.layout = layout |
99 self.output_file = output_file | 131 self.output_file = output_file |
100 | 132 |