#!/usr/bin/env python """ mbed SDK Copyright (c) 2011-2016 ARM Limited Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ import sys from os import path, remove, rename import shutil ROOT = path.abspath(path.join(path.dirname(__file__), "..", "..", "..")) sys.path.insert(0, ROOT) import argparse from tools.export import EXPORTERS from tools.targets import TARGET_NAMES from tools.tests import TESTS from tools.project import setup_project from tools.project_api import print_results, export_project from tools.tests import test_name_known, Test from tools.export.exporters import FailedBuildException, \ TargetNotSupportedException from tools.utils import argparse_force_lowercase_type, \ argparse_force_uppercase_type, argparse_many class ProgenBuildTest(object): """Object to encapsulate logic for progen build testing""" def __init__(self, desired_ides, mcus, tests): """ Initialize an instance of class ProgenBuildTest Args: desired_ides: the IDEs you wish to make/build project files for mcus: the mcus to specify in project files tests: the test projects to make/build project files from """ self.ides = desired_ides self.mcus = mcus self.tests = tests @property def mcu_ide_pairs(self): """Yields tuples of valid mcu, ide combinations""" for mcu in self.mcus: for ide in self.ides: if mcu in EXPORTERS[ide].TARGETS: yield mcu, ide @staticmethod def handle_log_files(project_dir, tool, name): """ Renames/moves log files Args: project_dir: the directory that contains project files tool: the ide that created the project files name: the name of the project clean: a boolean value determining whether to remove the created project files """ log = '' if tool == 'uvision' or tool == 'uvision5': log = path.join(project_dir, "build", "build_log.txt") elif tool == 'iar': log = path.join(project_dir, 'build_log.txt') try: with open(log, 'r') as in_log: print in_log.read() log_name = path.join(path.dirname(project_dir), name + "_log.txt") # check if a log already exists for this platform+test+ide if path.exists(log_name): # delete it if so remove(log_name) rename(log, log_name) except IOError: pass def generate_and_build(self, clean=False): """ Generate the project file and build the project Args: clean: a boolean value determining whether to remove the created project files Returns: successes: a list of strings that contain the mcu, ide, test properties of a successful build test skips: a list of strings that contain the mcu, ide, test properties of a skipped test (if the ide does not support mcu) failures: a list of strings that contain the mcu, ide, test properties of a failed build test """ successes = [] failures = [] skips = [] for mcu, ide in self.mcu_ide_pairs: for test in self.tests: export_location, name, src, lib = setup_project(ide, mcu, program=test) test_name = Test(test).id try: exporter = export_project(src, export_location, mcu, ide, clean=clean, name=name, libraries_paths=lib) exporter.progen_build() successes.append("%s::%s\t%s" % (mcu, ide, test_name)) except FailedBuildException: failures.append("%s::%s\t%s" % (mcu, ide, test_name)) except TargetNotSupportedException: skips.append("%s::%s\t%s" % (mcu, ide, test_name)) ProgenBuildTest.handle_log_files(export_location, ide, name) if clean: shutil.rmtree(export_location, ignore_errors=True) return successes, failures, skips def main(): """Entry point""" toolchainlist = ["iar", "uvision", "uvision5"] default_tests = [test_name_known("MBED_BLINKY")] targetnames = TARGET_NAMES targetnames.sort() parser = argparse.ArgumentParser(description= "Test progen builders. Leave any flag off" " to run with all possible options.") parser.add_argument("-i", dest="ides", default=toolchainlist, type=argparse_many(argparse_force_lowercase_type( toolchainlist, "toolchain")), help="The target IDE: %s"% str(toolchainlist)) parser.add_argument( "-p", type=argparse_many(test_name_known), dest="programs", help="The index of the desired test program: [0-%d]" % (len(TESTS) - 1), default=default_tests) parser.add_argument("-n", type=argparse_many(test_name_known), dest="programs", help="The name of the desired test program", default=default_tests) parser.add_argument( "-m", "--mcu", metavar="MCU", default='LPC1768', nargs="+", type=argparse_force_uppercase_type(targetnames, "MCU"), help="generate project for the given MCU (%s)" % ', '.join(targetnames)) parser.add_argument("-c", "--clean", dest="clean", action="store_true", help="clean up the exported project files", default=False) options = parser.parse_args() test = ProgenBuildTest(options.ides, options.mcu, options.programs) successes, failures, skips = test.generate_and_build(clean=options.clean) print_results(successes, failures, skips) sys.exit(len(failures)) if __name__ == "__main__": main()