annotate 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
rev   line source
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
1
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
2 """
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
3 Defines task classes that can compile, link etc..
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
4 Task can depend upon one another.
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
5 """
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
6
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
7 import logging
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
8
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
9 from .c3 import Builder
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
10 from .irutils import Verifier
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
11 from .codegen import CodeGenerator
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
12 from .transform import CleanPass, RemoveAddZero
337
b00219172a42 Added cool lm3s811 qemu project
Windel Bouwman
parents: 336
diff changeset
13 from .tasks import Task, TaskError
b00219172a42 Added cool lm3s811 qemu project
Windel Bouwman
parents: 336
diff changeset
14 from . import DiagnosticsManager, CompilerError
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
15 from .assembler import Assembler
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
16 from .objectfile import ObjectFile
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
17 from .linker import Linker
348
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 346
diff changeset
18 from .outstream import BinaryOutputStream, MasterOutputStream, LoggerOutputStream
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
19 from .target.target_list import targets
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
20 from .target import Target
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
21
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
22
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
23 def fix_target(tg):
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
24 """ Try to return an instance of the Target class """
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
25 if isinstance(tg, Target):
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
26 return tg
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
27 elif isinstance(tg, str):
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
28 if tg in targets:
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
29 return targets[tg]
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
30 else:
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
31 raise TaskError('Target {} not found'.format(tg))
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
32 raise TaskError('Invalid target {}'.format(tg))
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
33
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
34
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
35 def fix_file(f):
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
36 """ Determine if argument is a file like object or make it so! """
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
37 if hasattr(f, 'read'):
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
38 # Assume this is a file like object
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
39 return f
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
40 elif isinstance(f, str):
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
41 return open(f, 'r')
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
42 else:
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
43 raise TaskError('cannot use {} as input'.format(f))
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
44
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
45 def fix_object(o):
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
46 if isinstance(o, ObjectFile):
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
47 return o
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
48 else:
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
49 raise TaskError('Cannot use {} as objectfile'.format(o))
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
50
331
a78b41ff6ad2 Added better recipe files
Windel Bouwman
parents: 329
diff changeset
51 class BuildTask(Task):
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
52 """ Base task for all kind of weird build tasks """
331
a78b41ff6ad2 Added better recipe files
Windel Bouwman
parents: 329
diff changeset
53 def __init__(self, name):
a78b41ff6ad2 Added better recipe files
Windel Bouwman
parents: 329
diff changeset
54 super().__init__(name)
a78b41ff6ad2 Added better recipe files
Windel Bouwman
parents: 329
diff changeset
55 self.logger = logging.getLogger('buildtask')
a78b41ff6ad2 Added better recipe files
Windel Bouwman
parents: 329
diff changeset
56
a78b41ff6ad2 Added better recipe files
Windel Bouwman
parents: 329
diff changeset
57
a78b41ff6ad2 Added better recipe files
Windel Bouwman
parents: 329
diff changeset
58 class Assemble(BuildTask):
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
59 """ Task that can runs the assembler over the source and enters the
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
60 output into an object file """
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
61 def __init__(self, source, target, output_object):
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
62 super().__init__('Assemble')
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
63 self.source = fix_file(source)
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
64 self.output = output_object
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
65 o2 = BinaryOutputStream(self.output)
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
66 o1 = LoggerOutputStream()
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
67 self.ostream = MasterOutputStream([o1, o2])
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
68 self.assembler = Assembler(fix_target(target))
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
69
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
70 def run(self):
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
71 self.logger.debug('Assembling into code section')
348
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 346
diff changeset
72 self.ostream.select_section('code')
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 342
diff changeset
73 self.assembler.assemble(self.source, self.ostream)
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
74 self.logger.debug('Assembling finished')
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
75
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
76
331
a78b41ff6ad2 Added better recipe files
Windel Bouwman
parents: 329
diff changeset
77 class Compile(BuildTask):
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
78 """ Task that compiles C3 source for some target into an object file """
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
79 def __init__(self, sources, includes, target, output_object):
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
80 super().__init__('Compile')
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
81 self.sources = list(map(fix_file, sources))
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
82 self.includes = list(map(fix_file, includes))
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
83 self.target = fix_target(target)
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
84 self.output = output_object
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
85
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
86 def run(self):
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
87 self.logger.debug('Compile started')
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
88 diag = DiagnosticsManager()
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
89 c3b = Builder(diag, self.target)
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
90 cg = CodeGenerator(self.target)
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
91
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
92 for ircode in c3b.build(self.sources, self.includes):
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
93 if not ircode:
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 348
diff changeset
94 # Something went wrong, do not continue the code generation
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 348
diff changeset
95 continue
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
96
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
97 d = {'ircode':ircode}
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
98 self.logger.debug('Verifying code {}'.format(ircode), extra=d)
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
99 Verifier().verify(ircode)
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
100
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
101 # Optimization passes:
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
102 CleanPass().run(ircode)
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
103 Verifier().verify(ircode)
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
104 RemoveAddZero().run(ircode)
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
105 Verifier().verify(ircode)
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
106 CleanPass().run(ircode)
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
107 Verifier().verify(ircode)
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
108
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
109 # Code generation:
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
110 d = {'ircode':ircode}
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
111 self.logger.debug('Starting code generation for {}'.format(ircode), extra=d)
348
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 346
diff changeset
112
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 346
diff changeset
113 o2 = BinaryOutputStream(self.output)
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 346
diff changeset
114 o1 = LoggerOutputStream()
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
115 o = MasterOutputStream([o1, o2])
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
116 cg.generate(ircode, o)
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
117
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
118 if not c3b.ok:
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
119 diag.printErrors()
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
120 raise TaskError('Compile errors')
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
121
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
122
331
a78b41ff6ad2 Added better recipe files
Windel Bouwman
parents: 329
diff changeset
123 class Link(BuildTask):
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
124 """ Link together a collection of object files """
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
125 def __init__(self, objects, layout, output_file):
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
126 super().__init__('Link')
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
127 self.objects = list(map(fix_object, objects))
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
128 self.linker = Linker()
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
129 self.duration = 0.1337
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
130 self.layout = layout
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
131 self.output_file = output_file
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
132
6f4753202b9a Added more recipes
Windel Bouwman
parents: 332
diff changeset
133 def run(self):
337
b00219172a42 Added cool lm3s811 qemu project
Windel Bouwman
parents: 336
diff changeset
134 try:
b00219172a42 Added cool lm3s811 qemu project
Windel Bouwman
parents: 336
diff changeset
135 output_obj = self.linker.link(self.objects, self.layout)
b00219172a42 Added cool lm3s811 qemu project
Windel Bouwman
parents: 336
diff changeset
136 except CompilerError as e:
b00219172a42 Added cool lm3s811 qemu project
Windel Bouwman
parents: 336
diff changeset
137 raise TaskError(e.msg)
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
138 code = output_obj.get_section('code').data
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
139 with open(self.output_file, 'wb') as f:
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
140 f.write(code)
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
141
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
142
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
143 class ObjCopy(BuildTask):
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
144 def __init__(self, objects, output_file):
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
145 super().__init__('ObjCopy')
329
8f6f3ace4e78 Added build tasks
Windel Bouwman
parents:
diff changeset
146