Mercurial > lcfOS
view python/zcc.py @ 331:a78b41ff6ad2
Added better recipe files
author | Windel Bouwman |
---|---|
date | Fri, 07 Feb 2014 12:39:59 +0100 |
parents | 8f6f3ace4e78 |
children | 87feb8a23b4d |
line wrap: on
line source
#!/usr/bin/env python import sys import os import argparse import logging import yaml from ppci.buildtasks import Compile from ppci.tasks import TaskRunner from ppci.report import RstFormatter import outstream from target.target_list import target_list import ppci def logLevel(s): """ Converts a string to a valid logging level """ numeric_level = getattr(logging, s.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: {}'.format(s)) return numeric_level targets = {t.name: t for t in target_list} targetnames = list(targets.keys()) def make_parser(): parser = argparse.ArgumentParser(description='lcfos Compiler') parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])', type=logLevel, default='WARN') sub_parsers = parser.add_subparsers(title='commands', description='possible commands', dest='command') recipe_parser = sub_parsers.add_parser('recipe', help="Bake recipe") recipe_parser.add_argument('recipe_file', help='recipe file') compile_parser = sub_parsers.add_parser('compile', help="compile source") compile_parser.add_argument('source', type=argparse.FileType('r'), help='the source file to build', nargs="+") compile_parser.add_argument('-i', '--imp', type=argparse.FileType('r'), help='Possible import module', action='append', default=[]) compile_parser.add_argument('--target', help="Backend selection", choices=targetnames, required=True) compile_parser.add_argument('-o', '--output', help='Output file', metavar='filename') compile_parser.add_argument('--report', help='Specify a file to write the compile report to', type=argparse.FileType('w')) return parser class RecipeLoader: def load_file(self, recipe_file, runner): """ Loads a recipe dictionary into a task runner """ self.recipe_dir = os.path.abspath(os.path.dirname(recipe_file)) with open(recipe_file, 'r') as f: recipe = yaml.load(f) self.load_dict(recipe, runner) def relpath(self, filename): return os.path.join(self.recipe_dir, filename) def openfile(self, filename): return open(self.relpath(filename), 'r') def load_dict(self, recipe, runner): for command, value in recipe.items(): if command == 'compile': sources = [self.openfile(s) for s in value['sources']] includes = [self.openfile(i) for i in value['includes']] target = targets[value['machine']] output = outstream.TextOutputStream() runner.add_task(Compile(sources, includes, target, output)) elif command == 'link': self.load_dict(value['inputs'], runner) #runner.add_task(Link()) elif command == 'assemble': pass elif command == 'apps': for a in value: self.load_dict(a, runner) else: raise NotImplementedError(command) def main(args): # Configure some logging: logging.getLogger().setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setFormatter(logging.Formatter(ppci.logformat)) ch.setLevel(args.log) logging.getLogger().addHandler(ch) runner = TaskRunner() if args.command == 'compile': tg = targets[args.target] outs = outstream.TextOutputStream() runner.add_task(Compile(args.source, args.imp, tg, outs)) elif args.command == 'recipe': recipe_loader = RecipeLoader() recipe_loader.load_file(args.recipe_file, runner) else: raise NotImplementedError('Invalid option') res = runner.run_tasks() logging.getLogger().removeHandler(ch) return res if __name__ == '__main__': parser = make_parser() arguments = parser.parse_args() if not arguments.command: parser.print_usage() sys.exit(1) sys.exit(main(arguments))