view python/zcc.py @ 366:39bf68bf1891

Fix sample tests and deterministic build
author Windel Bouwman
date Fri, 21 Mar 2014 09:43:01 +0100
parents c2ddc8a36f5e
children 9667d78ba79e
line wrap: on
line source

#!/usr/bin/env python

import sys
import os
import argparse
import logging

from ppci.buildtasks import Compile, Assemble, Link
from ppci.tasks import TaskRunner
from ppci.report import RstFormatter
from ppci.objectfile import ObjectFile
from ppci.target.target_list import targets, targetnames
from ppci.recipe import RecipeLoader
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


def make_parser():
    parser = argparse.ArgumentParser(description='lcfos Compiler')

    parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])',
                        type=logLevel, default='INFO')
    parser.add_argument('--display-build-steps', action='store_true')
    parser.add_argument('--report',
                help='Specify a file to write the compile report to',
                type=argparse.FileType('w'))
    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')
    return parser


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)

    if args.report:
        fh = logging.StreamHandler(args.report)
        fh.setFormatter(RstFormatter())
        logging.getLogger().addHandler(fh)

    runner = TaskRunner()
    if args.command == 'compile':
        tg = targets[args.target]
        output = ObjectFile()
        runner.add_task(Compile(args.source, args.imp, tg, output))
    elif args.command == 'recipe':
        recipe_loader = RecipeLoader(runner)
        recipe_loader.load_file(args.recipe_file)
    else:
        raise NotImplementedError('Invalid option')

    if args.display_build_steps:
        runner.display()
        res = 0
    else:
        res = runner.run_tasks()

    if args.report:
        logging.getLogger().removeHandler(fh)
        args.report.close()

    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))