Mercurial > lcfOS
changeset 329:8f6f3ace4e78
Added build tasks
author | Windel Bouwman |
---|---|
date | Wed, 05 Feb 2014 21:29:31 +0100 |
parents | 0bb16d2a5699 |
children | a79ac866732f |
files | python/ppci/buildtasks.py python/ppci/tasks.py python/zcc.py test/testzcc.py |
diffstat | 4 files changed, 147 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ppci/buildtasks.py Wed Feb 05 21:29:31 2014 +0100 @@ -0,0 +1,85 @@ + +""" +Defines task classes that can compile, link etc.. +Task can depend upon one another. +""" + +import logging + +from .c3 import Builder +from .irutils import Verifier +from .codegen import CodeGenerator +from .transform import CleanPass, RemoveAddZero +from .tasks import Task +from . import DiagnosticsManager + + +class Assemble(Task): + def __init__(self): + super().__init__('Assemble') + + def run(self): + pass + + +class Compile(Task): + """ Task that compiles source to some target """ + def __init__(self, sources, includes, target, output_object): + super().__init__('Compile') + self.sources = sources + self.includes = includes + self.target = target + self.output = output_object + + def run(self): + logger = logging.getLogger('zcc') + logger.info('Zcc started {}'.format(self.sources)) + diag = DiagnosticsManager() + c3b = Builder(diag, self.target) + cg = CodeGenerator(self.target) + + for ircode in c3b.build(self.sources, self.includes): + if not ircode: + return + + d = {'ircode':ircode} + logger.info('Verifying code {}'.format(ircode), extra=d) + Verifier().verify(ircode) + + # Optimization passes: + CleanPass().run(ircode) + Verifier().verify(ircode) + RemoveAddZero().run(ircode) + Verifier().verify(ircode) + CleanPass().run(ircode) + Verifier().verify(ircode) + + # Code generation: + d = {'ircode':ircode} + logger.info('Starting code generation for {}'.format(ircode), extra=d) + cg.generate(ircode, self.output) + + # TODO: fixup references, do this in another way? + self.output.backpatch() + if not c3b.ok: + diag.printErrors() + raise TaskError('Compile errors') + + +class Link(Task): + def __init__(self, objects, output_file): + super().__init__('Link') + + +class ObjCopy(Task): + pass + + +def load_recipe(recipe, runner): + """ Loads a recipe dictionary into a task runner """ + if 'compile' in recipe: + #sources = + runner.add_task(Compile()) + else: + raise Exception() +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ppci/tasks.py Wed Feb 05 21:29:31 2014 +0100 @@ -0,0 +1,46 @@ + +class TaskError(Exception): + pass + + +class Task: + """ Task that can run, and depend on other tasks """ + def __init__(self, name): + self.name = name + self.subtasks = [] + self.completed = False + self.dependencies = [] + + def run(self): + raise NotImplementedError("Implement this abstract method!") + + def fire(self): + assert all(t.completed for t in self.dependencies) + self.run() + self.completed = True + + def addSubTask(self, tsk): + self.subtasks.append(tsk) + return tsk + + def addDependency(self, task): + self.dependencies.append(task) + return task + + +class TaskRunner: + def __init__(self): + self.task_list = [] + + def add_task(self, task): + self.task_list.append(task) + + def run_tasks(self): + try: + for t in self.task_list: + #print('Running {}'.format(t.name)) + t.fire() + except TaskError as e: + print('Error: {}'.format(e)) + return 1 + return 0
--- a/python/zcc.py Tue Feb 04 09:01:11 2014 +0100 +++ b/python/zcc.py Wed Feb 05 21:29:31 2014 +0100 @@ -4,17 +4,15 @@ import argparse import logging -from ppci.c3 import Builder, AstPrinter -import ppci -from ppci.irutils import Verifier, Writer -from ppci.codegen import CodeGenerator +from ppci.c3 import AstPrinter +from ppci.buildtasks import Compile +from ppci.tasks import TaskRunner import outstream from utils import HexFile import target from target.target_list import target_list from ppci import irutils import io -from ppci.transform import CleanPass, RemoveAddZero logformat='%(asctime)s|%(levelname)s|%(name)s|%(message)s' @@ -123,63 +121,19 @@ parser.add_argument('-i', '--imp', type=argparse.FileType('r'), \ help='Possible import module', action='append', default=[]) +#sub_parsers = parser.add_subparsers() +#recipe = sub_parsers.add_parser('recipe') parser.add_argument('--optimize', action='store_true', help="Optimize") parser.add_argument('--target', help="Backend selection", choices=targetnames, required=True) parser.add_argument('-o', '--output', help='Output file', metavar='filename') -parser.add_argument('--hexfile', help='Output hexfile', - type=argparse.FileType('w')) -parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])', +parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])', type=logLevel, default='WARN') parser.add_argument('--report', - help='Specify a file to write the compile report to', + help='Specify a file to write the compile report to', type=argparse.FileType('w')) -def zcc(srcs, imps, tg, outs, diag): - """ - Compiler driver - Compile sources into output stream. - Sources is an iterable of open files. - """ - logger = logging.getLogger('zcc') - logger.info('Zcc started {}'.format(srcs)) - # Front end: - c3b = Builder(diag, tg) - cg = CodeGenerator(tg) - - # TODO: remove this arm specifics: - outs.getSection('code').address = 0x08000000 - outs.getSection('data').address = 0x20000000 - - # Emit some custom start code: - tg.startCode(outs) - for ircode in c3b.build(srcs, imps): - if not ircode: - return - - d = {'ircode':ircode} - logger.info('Verifying code {}'.format(ircode), extra=d) - Verifier().verify(ircode) - - # Optimization passes: - CleanPass().run(ircode) - Verifier().verify(ircode) - RemoveAddZero().run(ircode) - Verifier().verify(ircode) - CleanPass().run(ircode) - Verifier().verify(ircode) - - # Code generation: - d = {'ircode':ircode} - logger.info('Starting code generation for {}'.format(ircode), extra=d) - cg.generate(ircode, outs) - # TODO: fixup references, do this in another way? - outs.backpatch() - outs.backpatch() # Why two times? - return c3b.ok - - def main(args): # Configure some logging: logging.getLogger().setLevel(logging.DEBUG) @@ -193,14 +147,14 @@ logging.getLogger().addHandler(fh) tg = targets[args.target] - diag = ppci.DiagnosticsManager() outs = outstream.TextOutputStream() - res = zcc(args.source, args.imp, tg, outs, diag) - if not res: - diag.printErrors() + tr = TaskRunner() + tr.add_task(Compile(args.source, args.imp, tg, outs)) + + res = tr.run_tasks() + if res > 0: return 1 - logging.info('Assembly created', extra={'zcc_outs':outs}) code_bytes = outs.sections['code'].to_bytes() @@ -209,12 +163,6 @@ with open(output_filename, 'wb') as f: f.write(code_bytes) - if args.hexfile: - logging.info('Creating hexfile') - hf = HexFile() - hf.addRegion(0x08000000, code_bytes) - hf.save(args.hexfile) - if args.report: logging.getLogger().removeHandler(fh) logging.getLogger().removeHandler(ch)
--- a/test/testzcc.py Tue Feb 04 09:01:11 2014 +0100 +++ b/test/testzcc.py Wed Feb 05 21:29:31 2014 +0100 @@ -8,7 +8,6 @@ import io import target - # Store testdir for safe switch back to directory: testdir = os.path.dirname(os.path.abspath(__file__)) @@ -75,14 +74,13 @@ function void t2() {var int t3; t3 = 2;} """ f = io.StringIO(src) - diag = ppci.DiagnosticsManager() outs = outstream.TextOutputStream() tg = target.target_list.armtarget - self.assertTrue(zcc.zcc([f], [], tg, outs, diag)) + tr = ppci.tasks.TaskRunner() + tr.add_task(ppci.buildtasks.Compile([f], [], tg, outs)) + tr.run_tasks() code = outs.getSection('code') - self.assertEqual(0x08000000, code.address) - data = outs.getSection('data') - self.assertEqual(0x20000000, data.address) + self.assertEqual(0x0, code.address) if __name__ == '__main__':