Brian Daniels / mbed-tools

Fork of mbed-tools by Morpheus

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers project.py Source File

project.py

00001 import sys
00002 from os.path import join, abspath, dirname, exists, basename
00003 ROOT = abspath(join(dirname(__file__), ".."))
00004 sys.path.insert(0, ROOT)
00005 
00006 from shutil import move, rmtree
00007 from optparse import OptionParser
00008 
00009 from tools.paths import EXPORT_DIR, EXPORT_WORKSPACE, EXPORT_TMP
00010 from tools.paths import MBED_BASE, MBED_LIBRARIES
00011 from tools.export import export, setup_user_prj, EXPORTERS, mcu_ide_matrix
00012 from tools.utils import args_error
00013 from tools.tests import TESTS, Test, TEST_MAP
00014 from tools.targets import TARGET_NAMES
00015 from tools.libraries import LIBRARIES
00016 
00017 try:
00018     import tools.private_settings as ps
00019 except:
00020     ps = object()
00021 
00022 
00023 if __name__ == '__main__':
00024     # Parse Options
00025     parser = OptionParser()
00026 
00027     targetnames = TARGET_NAMES
00028     targetnames.sort()
00029     toolchainlist = EXPORTERS.keys()
00030     toolchainlist.sort()
00031 
00032     parser.add_option("-m", "--mcu",
00033                       metavar="MCU",
00034                       default='LPC1768',
00035                       help="generate project for the given MCU (%s)"% ', '.join(targetnames))
00036 
00037     parser.add_option("-i",
00038                       dest="ide",
00039                       default='uvision',
00040                       help="The target IDE: %s"% str(toolchainlist))
00041 
00042     parser.add_option("-c", "--clean",
00043                       action="store_true",
00044                       default=False,
00045                       help="clean the export directory")
00046 
00047     parser.add_option("-p",
00048                       type="int",
00049                       dest="program",
00050                       help="The index of the desired test program: [0-%d]"% (len(TESTS)-1))
00051 
00052     parser.add_option("-n",
00053                       dest="program_name",
00054                       help="The name of the desired test program")
00055 
00056     parser.add_option("-b",
00057                       dest="build",
00058                       action="store_true",
00059                       default=False,
00060                       help="use the mbed library build, instead of the sources")
00061 
00062     parser.add_option("-L", "--list-tests",
00063                       action="store_true",
00064                       dest="list_tests",
00065                       default=False,
00066                       help="list available programs in order and exit")
00067 
00068     parser.add_option("-S", "--list-matrix",
00069                       action="store_true",
00070                       dest="supported_ides",
00071                       default=False,
00072                       help="displays supported matrix of MCUs and IDEs")
00073 
00074     parser.add_option("-E",
00075                       action="store_true",
00076                       dest="supported_ides_html",
00077                       default=False,
00078                       help="writes tools/export/README.md")
00079 
00080     parser.add_option("--source",
00081                       dest="source_dir",
00082                       default=None,
00083                       help="The source (input) directory")
00084 
00085     parser.add_option("-D", "",
00086                       action="append",
00087                       dest="macros",
00088                       help="Add a macro definition")
00089 
00090     (options, args) = parser.parse_args()
00091 
00092     # Print available tests in order and exit
00093     if options.list_tests is True:
00094         print '\n'.join(map(str, sorted(TEST_MAP.values())))
00095         sys.exit()
00096 
00097     # Only prints matrix of supported IDEs
00098     if options.supported_ides:
00099         print mcu_ide_matrix()
00100         exit(0)
00101 
00102     # Only prints matrix of supported IDEs
00103     if options.supported_ides_html:
00104         html = mcu_ide_matrix(verbose_html=True)
00105         try:
00106             with open("./export/README.md","w") as f:
00107                 f.write("Exporter IDE/Platform Support\n")
00108                 f.write("-----------------------------------\n")
00109                 f.write("\n")
00110                 f.write(html)
00111         except IOError as e:
00112             print "I/O error({0}): {1}".format(e.errno, e.strerror)
00113         except:
00114             print "Unexpected error:", sys.exc_info()[0]
00115             raise
00116         exit(0)
00117 
00118     # Clean Export Directory
00119     if options.clean:
00120         if exists(EXPORT_DIR):
00121             rmtree(EXPORT_DIR)
00122 
00123     # Target
00124     if options.mcu is None :
00125         args_error(parser, "[ERROR] You should specify an MCU")
00126     mcus = options.mcu
00127 
00128     # IDE
00129     if options.ide is None:
00130         args_error(parser, "[ERROR] You should specify an IDE")
00131     ide = options.ide
00132 
00133     # Export results
00134     successes = []
00135     failures = []
00136     zip = True
00137     clean = True
00138 
00139     for mcu in mcus.split(','):
00140         # Program Number or name
00141         p, n, src = options.program, options.program_name, options.source_dir
00142 
00143         if src is not None:
00144             # --source is used to generate IDE files to toolchain directly in the source tree and doesn't generate zip file
00145             project_dir = options.source_dir
00146             project_name = basename(project_dir)
00147             project_temp = project_dir
00148             lib_symbols = [] + options.macros
00149             zip = False   # don't create zip
00150             clean = False # don't cleanup because we use the actual source tree to generate IDE files
00151         else:
00152             if n is not None and p is not None:
00153                 args_error(parser, "[ERROR] specify either '-n' or '-p', not both")
00154             if n:
00155                 if not n in TEST_MAP.keys():
00156                     # Check if there is an alias for this in private_settings.py
00157                     if getattr(ps, "test_alias", None) is not None:
00158                         alias = ps.test_alias.get(n, "")
00159                         if not alias in TEST_MAP.keys():
00160                             args_error(parser, "[ERROR] Program with name '%s' not found" % n)
00161                         else:
00162                             n = alias
00163                     else:
00164                         args_error(parser, "[ERROR] Program with name '%s' not found" % n)
00165                 p = TEST_MAP[n].n
00166                 
00167             if p is None or (p < 0) or (p > (len(TESTS)-1)):
00168                 message = "[ERROR] You have to specify one of the following tests:\n"
00169                 message += '\n'.join(map(str, sorted(TEST_MAP.values())))
00170                 args_error(parser, message)
00171 
00172             # Project
00173             if p is None or (p < 0) or (p > (len(TESTS)-1)):
00174                 message = "[ERROR] You have to specify one of the following tests:\n"
00175                 message += '\n'.join(map(str, sorted(TEST_MAP.values())))
00176                 args_error(parser, message)
00177             test = Test(p)
00178 
00179             # Some libraries have extra macros (called by exporter symbols) to we need to pass
00180             # them to maintain compilation macros integrity between compiled library and
00181             # header files we might use with it
00182             lib_symbols = [] + options.macros
00183             for lib in LIBRARIES:
00184                 if lib['build_dir'] in test.dependencies:
00185                     lib_macros = lib.get('macros', None)
00186                     if lib_macros is not None:
00187                         lib_symbols.extend(lib_macros)
00188 
00189             if not options.build:
00190                 # Substitute the library builds with the sources
00191                 # TODO: Substitute also the other library build paths
00192                 if MBED_LIBRARIES in test.dependencies:
00193                     test.dependencies.remove(MBED_LIBRARIES)
00194                     test.dependencies.append(MBED_BASE)
00195 
00196             # Build the project with the same directory structure of the mbed online IDE
00197             project_name = test.id
00198             project_dir = join(EXPORT_WORKSPACE, project_name)
00199             project_temp = EXPORT_TMP
00200             setup_user_prj(project_dir, test.source_dir, test.dependencies)
00201 
00202         # Export to selected toolchain
00203         tmp_path, report = export(project_dir, project_name, ide, mcu, project_dir, project_temp, clean=clean, zip=zip, extra_symbols=lib_symbols)
00204         print tmp_path
00205         if report['success']:
00206             zip_path = join(EXPORT_DIR, "%s_%s_%s.zip" % (project_name, ide, mcu))
00207             if zip:
00208                 move(tmp_path, zip_path)
00209             successes.append("%s::%s\t%s"% (mcu, ide, zip_path))
00210         else:
00211             failures.append("%s::%s\t%s"% (mcu, ide, report['errormsg']))
00212 
00213     # Prints export results
00214     print
00215     if len(successes) > 0:
00216         print "Successful exports:"
00217         for success in successes:
00218             print "  * %s"% success
00219     if len(failures) > 0:
00220         print "Failed exports:"
00221         for failure in failures:
00222             print "  * %s"% failure