Mercurial > lcfOS
comparison python/zcc.py @ 329:8f6f3ace4e78
Added build tasks
author | Windel Bouwman |
---|---|
date | Wed, 05 Feb 2014 21:29:31 +0100 |
parents | e9fe6988497c |
children | a78b41ff6ad2 |
comparison
equal
deleted
inserted
replaced
328:0bb16d2a5699 | 329:8f6f3ace4e78 |
---|---|
2 | 2 |
3 import sys | 3 import sys |
4 import argparse | 4 import argparse |
5 import logging | 5 import logging |
6 | 6 |
7 from ppci.c3 import Builder, AstPrinter | 7 from ppci.c3 import AstPrinter |
8 import ppci | 8 from ppci.buildtasks import Compile |
9 from ppci.irutils import Verifier, Writer | 9 from ppci.tasks import TaskRunner |
10 from ppci.codegen import CodeGenerator | |
11 import outstream | 10 import outstream |
12 from utils import HexFile | 11 from utils import HexFile |
13 import target | 12 import target |
14 from target.target_list import target_list | 13 from target.target_list import target_list |
15 from ppci import irutils | 14 from ppci import irutils |
16 import io | 15 import io |
17 from ppci.transform import CleanPass, RemoveAddZero | |
18 | 16 |
19 | 17 |
20 logformat='%(asctime)s|%(levelname)s|%(name)s|%(message)s' | 18 logformat='%(asctime)s|%(levelname)s|%(name)s|%(message)s' |
21 | 19 |
22 | 20 |
121 parser.add_argument('source', type=argparse.FileType('r'), \ | 119 parser.add_argument('source', type=argparse.FileType('r'), \ |
122 help='the source file to build', nargs="+") | 120 help='the source file to build', nargs="+") |
123 parser.add_argument('-i', '--imp', type=argparse.FileType('r'), \ | 121 parser.add_argument('-i', '--imp', type=argparse.FileType('r'), \ |
124 help='Possible import module', action='append', default=[]) | 122 help='Possible import module', action='append', default=[]) |
125 | 123 |
124 #sub_parsers = parser.add_subparsers() | |
125 #recipe = sub_parsers.add_parser('recipe') | |
126 parser.add_argument('--optimize', action='store_true', help="Optimize") | 126 parser.add_argument('--optimize', action='store_true', help="Optimize") |
127 parser.add_argument('--target', help="Backend selection", | 127 parser.add_argument('--target', help="Backend selection", |
128 choices=targetnames, required=True) | 128 choices=targetnames, required=True) |
129 parser.add_argument('-o', '--output', help='Output file', metavar='filename') | 129 parser.add_argument('-o', '--output', help='Output file', metavar='filename') |
130 parser.add_argument('--hexfile', help='Output hexfile', | 130 parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])', |
131 type=argparse.FileType('w')) | |
132 parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])', | |
133 type=logLevel, default='WARN') | 131 type=logLevel, default='WARN') |
134 parser.add_argument('--report', | 132 parser.add_argument('--report', |
135 help='Specify a file to write the compile report to', | 133 help='Specify a file to write the compile report to', |
136 type=argparse.FileType('w')) | 134 type=argparse.FileType('w')) |
137 | |
138 | |
139 def zcc(srcs, imps, tg, outs, diag): | |
140 """ | |
141 Compiler driver | |
142 Compile sources into output stream. | |
143 Sources is an iterable of open files. | |
144 """ | |
145 logger = logging.getLogger('zcc') | |
146 logger.info('Zcc started {}'.format(srcs)) | |
147 # Front end: | |
148 c3b = Builder(diag, tg) | |
149 cg = CodeGenerator(tg) | |
150 | |
151 # TODO: remove this arm specifics: | |
152 outs.getSection('code').address = 0x08000000 | |
153 outs.getSection('data').address = 0x20000000 | |
154 | |
155 # Emit some custom start code: | |
156 tg.startCode(outs) | |
157 for ircode in c3b.build(srcs, imps): | |
158 if not ircode: | |
159 return | |
160 | |
161 d = {'ircode':ircode} | |
162 logger.info('Verifying code {}'.format(ircode), extra=d) | |
163 Verifier().verify(ircode) | |
164 | |
165 # Optimization passes: | |
166 CleanPass().run(ircode) | |
167 Verifier().verify(ircode) | |
168 RemoveAddZero().run(ircode) | |
169 Verifier().verify(ircode) | |
170 CleanPass().run(ircode) | |
171 Verifier().verify(ircode) | |
172 | |
173 # Code generation: | |
174 d = {'ircode':ircode} | |
175 logger.info('Starting code generation for {}'.format(ircode), extra=d) | |
176 cg.generate(ircode, outs) | |
177 # TODO: fixup references, do this in another way? | |
178 outs.backpatch() | |
179 outs.backpatch() # Why two times? | |
180 return c3b.ok | |
181 | 135 |
182 | 136 |
183 def main(args): | 137 def main(args): |
184 # Configure some logging: | 138 # Configure some logging: |
185 logging.getLogger().setLevel(logging.DEBUG) | 139 logging.getLogger().setLevel(logging.DEBUG) |
191 fh = logging.StreamHandler(stream=args.report) | 145 fh = logging.StreamHandler(stream=args.report) |
192 fh.setFormatter(RstFormatter()) | 146 fh.setFormatter(RstFormatter()) |
193 logging.getLogger().addHandler(fh) | 147 logging.getLogger().addHandler(fh) |
194 | 148 |
195 tg = targets[args.target] | 149 tg = targets[args.target] |
196 diag = ppci.DiagnosticsManager() | |
197 outs = outstream.TextOutputStream() | 150 outs = outstream.TextOutputStream() |
198 | 151 |
199 res = zcc(args.source, args.imp, tg, outs, diag) | 152 tr = TaskRunner() |
200 if not res: | 153 tr.add_task(Compile(args.source, args.imp, tg, outs)) |
201 diag.printErrors() | 154 |
155 res = tr.run_tasks() | |
156 if res > 0: | |
202 return 1 | 157 return 1 |
203 | |
204 logging.info('Assembly created', extra={'zcc_outs':outs}) | 158 logging.info('Assembly created', extra={'zcc_outs':outs}) |
205 | 159 |
206 code_bytes = outs.sections['code'].to_bytes() | 160 code_bytes = outs.sections['code'].to_bytes() |
207 if args.output: | 161 if args.output: |
208 output_filename = args.output | 162 output_filename = args.output |
209 with open(output_filename, 'wb') as f: | 163 with open(output_filename, 'wb') as f: |
210 f.write(code_bytes) | 164 f.write(code_bytes) |
211 | |
212 if args.hexfile: | |
213 logging.info('Creating hexfile') | |
214 hf = HexFile() | |
215 hf.addRegion(0x08000000, code_bytes) | |
216 hf.save(args.hexfile) | |
217 | 165 |
218 if args.report: | 166 if args.report: |
219 logging.getLogger().removeHandler(fh) | 167 logging.getLogger().removeHandler(fh) |
220 logging.getLogger().removeHandler(ch) | 168 logging.getLogger().removeHandler(ch) |
221 return 0 | 169 return 0 |