Clone of official tools
project.py@22:9e85236d8716, 2016-07-16 (annotated)
- Committer:
- screamer
- Date:
- Sat Jul 16 00:34:03 2016 +0100
- Revision:
- 22:9e85236d8716
- Parent:
- 13:ab47a20b66f0
- Child:
- 23:fbae331171fa
Sync with the mbedmicro/mbed tools
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
screamer | 0:66f3b5499f7f | 1 | import sys |
screamer | 0:66f3b5499f7f | 2 | from os.path import join, abspath, dirname, exists, basename |
screamer | 0:66f3b5499f7f | 3 | ROOT = abspath(join(dirname(__file__), "..")) |
screamer | 0:66f3b5499f7f | 4 | sys.path.insert(0, ROOT) |
screamer | 0:66f3b5499f7f | 5 | |
screamer | 0:66f3b5499f7f | 6 | from shutil import move, rmtree |
screamer | 22:9e85236d8716 | 7 | from argparse import ArgumentParser |
screamer | 0:66f3b5499f7f | 8 | from os import path |
screamer | 0:66f3b5499f7f | 9 | |
screamer | 0:66f3b5499f7f | 10 | from tools.paths import EXPORT_DIR, EXPORT_WORKSPACE, EXPORT_TMP |
screamer | 0:66f3b5499f7f | 11 | from tools.paths import MBED_BASE, MBED_LIBRARIES |
screamer | 0:66f3b5499f7f | 12 | from tools.export import export, setup_user_prj, EXPORTERS, mcu_ide_matrix |
screamer | 0:66f3b5499f7f | 13 | from tools.utils import args_error, mkdir |
screamer | 0:66f3b5499f7f | 14 | from tools.tests import TESTS, Test, TEST_MAP |
screamer | 22:9e85236d8716 | 15 | from tools.tests import test_known, test_name_known |
screamer | 0:66f3b5499f7f | 16 | from tools.targets import TARGET_NAMES |
screamer | 0:66f3b5499f7f | 17 | from tools.libraries import LIBRARIES |
screamer | 22:9e85236d8716 | 18 | from utils import argparse_lowercase_type, argparse_uppercase_type, argparse_filestring_type, argparse_many |
screamer | 22:9e85236d8716 | 19 | from utils import argparse_force_lowercase_type, argparse_force_uppercase_type |
screamer | 0:66f3b5499f7f | 20 | |
screamer | 0:66f3b5499f7f | 21 | |
screamer | 0:66f3b5499f7f | 22 | |
screamer | 0:66f3b5499f7f | 23 | if __name__ == '__main__': |
screamer | 0:66f3b5499f7f | 24 | # Parse Options |
screamer | 22:9e85236d8716 | 25 | parser = ArgumentParser() |
screamer | 0:66f3b5499f7f | 26 | |
screamer | 0:66f3b5499f7f | 27 | targetnames = TARGET_NAMES |
screamer | 0:66f3b5499f7f | 28 | targetnames.sort() |
screamer | 0:66f3b5499f7f | 29 | toolchainlist = EXPORTERS.keys() |
screamer | 0:66f3b5499f7f | 30 | toolchainlist.sort() |
screamer | 0:66f3b5499f7f | 31 | |
screamer | 22:9e85236d8716 | 32 | parser.add_argument("-m", "--mcu", |
screamer | 0:66f3b5499f7f | 33 | metavar="MCU", |
screamer | 0:66f3b5499f7f | 34 | default='LPC1768', |
screamer | 22:9e85236d8716 | 35 | type=argparse_many(argparse_force_uppercase_type(targetnames, "MCU")), |
screamer | 0:66f3b5499f7f | 36 | help="generate project for the given MCU (%s)"% ', '.join(targetnames)) |
screamer | 0:66f3b5499f7f | 37 | |
screamer | 22:9e85236d8716 | 38 | parser.add_argument("-i", |
screamer | 0:66f3b5499f7f | 39 | dest="ide", |
screamer | 0:66f3b5499f7f | 40 | default='uvision', |
screamer | 22:9e85236d8716 | 41 | type=argparse_force_lowercase_type(toolchainlist, "toolchain"), |
screamer | 0:66f3b5499f7f | 42 | help="The target IDE: %s"% str(toolchainlist)) |
screamer | 0:66f3b5499f7f | 43 | |
screamer | 22:9e85236d8716 | 44 | parser.add_argument("-c", "--clean", |
screamer | 0:66f3b5499f7f | 45 | action="store_true", |
screamer | 0:66f3b5499f7f | 46 | default=False, |
screamer | 0:66f3b5499f7f | 47 | help="clean the export directory") |
screamer | 0:66f3b5499f7f | 48 | |
screamer | 22:9e85236d8716 | 49 | group = parser.add_mutually_exclusive_group(required=False) |
screamer | 22:9e85236d8716 | 50 | group.add_argument("-p", |
screamer | 22:9e85236d8716 | 51 | type=test_known, |
screamer | 0:66f3b5499f7f | 52 | dest="program", |
screamer | 0:66f3b5499f7f | 53 | help="The index of the desired test program: [0-%d]"% (len(TESTS)-1)) |
screamer | 0:66f3b5499f7f | 54 | |
screamer | 22:9e85236d8716 | 55 | group.add_argument("-n", |
screamer | 22:9e85236d8716 | 56 | type=test_name_known, |
screamer | 22:9e85236d8716 | 57 | dest="program", |
screamer | 0:66f3b5499f7f | 58 | help="The name of the desired test program") |
screamer | 0:66f3b5499f7f | 59 | |
screamer | 22:9e85236d8716 | 60 | parser.add_argument("-b", |
screamer | 0:66f3b5499f7f | 61 | dest="build", |
screamer | 0:66f3b5499f7f | 62 | action="store_true", |
screamer | 0:66f3b5499f7f | 63 | default=False, |
screamer | 0:66f3b5499f7f | 64 | help="use the mbed library build, instead of the sources") |
screamer | 0:66f3b5499f7f | 65 | |
screamer | 22:9e85236d8716 | 66 | group.add_argument("-L", "--list-tests", |
screamer | 0:66f3b5499f7f | 67 | action="store_true", |
screamer | 0:66f3b5499f7f | 68 | dest="list_tests", |
screamer | 0:66f3b5499f7f | 69 | default=False, |
screamer | 0:66f3b5499f7f | 70 | help="list available programs in order and exit") |
screamer | 0:66f3b5499f7f | 71 | |
screamer | 22:9e85236d8716 | 72 | group.add_argument("-S", "--list-matrix", |
screamer | 0:66f3b5499f7f | 73 | action="store_true", |
screamer | 0:66f3b5499f7f | 74 | dest="supported_ides", |
screamer | 0:66f3b5499f7f | 75 | default=False, |
screamer | 0:66f3b5499f7f | 76 | help="displays supported matrix of MCUs and IDEs") |
screamer | 0:66f3b5499f7f | 77 | |
screamer | 22:9e85236d8716 | 78 | parser.add_argument("-E", |
screamer | 0:66f3b5499f7f | 79 | action="store_true", |
screamer | 0:66f3b5499f7f | 80 | dest="supported_ides_html", |
screamer | 0:66f3b5499f7f | 81 | default=False, |
screamer | 0:66f3b5499f7f | 82 | help="writes tools/export/README.md") |
screamer | 0:66f3b5499f7f | 83 | |
screamer | 22:9e85236d8716 | 84 | parser.add_argument("--source", |
screamer | 13:ab47a20b66f0 | 85 | action="append", |
screamer | 22:9e85236d8716 | 86 | type=argparse_filestring_type, |
screamer | 0:66f3b5499f7f | 87 | dest="source_dir", |
screamer | 22:9e85236d8716 | 88 | default=[], |
screamer | 0:66f3b5499f7f | 89 | help="The source (input) directory") |
screamer | 0:66f3b5499f7f | 90 | |
screamer | 22:9e85236d8716 | 91 | parser.add_argument("-D", |
screamer | 0:66f3b5499f7f | 92 | action="append", |
screamer | 0:66f3b5499f7f | 93 | dest="macros", |
screamer | 0:66f3b5499f7f | 94 | help="Add a macro definition") |
screamer | 0:66f3b5499f7f | 95 | |
screamer | 22:9e85236d8716 | 96 | options = parser.parse_args() |
screamer | 0:66f3b5499f7f | 97 | |
screamer | 0:66f3b5499f7f | 98 | # Print available tests in order and exit |
screamer | 0:66f3b5499f7f | 99 | if options.list_tests is True: |
screamer | 0:66f3b5499f7f | 100 | print '\n'.join(map(str, sorted(TEST_MAP.values()))) |
screamer | 0:66f3b5499f7f | 101 | sys.exit() |
screamer | 0:66f3b5499f7f | 102 | |
screamer | 0:66f3b5499f7f | 103 | # Only prints matrix of supported IDEs |
screamer | 0:66f3b5499f7f | 104 | if options.supported_ides: |
screamer | 0:66f3b5499f7f | 105 | print mcu_ide_matrix() |
screamer | 0:66f3b5499f7f | 106 | exit(0) |
screamer | 0:66f3b5499f7f | 107 | |
screamer | 0:66f3b5499f7f | 108 | # Only prints matrix of supported IDEs |
screamer | 0:66f3b5499f7f | 109 | if options.supported_ides_html: |
screamer | 0:66f3b5499f7f | 110 | html = mcu_ide_matrix(verbose_html=True) |
screamer | 0:66f3b5499f7f | 111 | try: |
screamer | 0:66f3b5499f7f | 112 | with open("./export/README.md","w") as f: |
screamer | 0:66f3b5499f7f | 113 | f.write("Exporter IDE/Platform Support\n") |
screamer | 0:66f3b5499f7f | 114 | f.write("-----------------------------------\n") |
screamer | 0:66f3b5499f7f | 115 | f.write("\n") |
screamer | 0:66f3b5499f7f | 116 | f.write(html) |
screamer | 0:66f3b5499f7f | 117 | except IOError as e: |
screamer | 0:66f3b5499f7f | 118 | print "I/O error({0}): {1}".format(e.errno, e.strerror) |
screamer | 0:66f3b5499f7f | 119 | except: |
screamer | 0:66f3b5499f7f | 120 | print "Unexpected error:", sys.exc_info()[0] |
screamer | 0:66f3b5499f7f | 121 | raise |
screamer | 0:66f3b5499f7f | 122 | exit(0) |
screamer | 0:66f3b5499f7f | 123 | |
screamer | 0:66f3b5499f7f | 124 | # Clean Export Directory |
screamer | 0:66f3b5499f7f | 125 | if options.clean: |
screamer | 0:66f3b5499f7f | 126 | if exists(EXPORT_DIR): |
screamer | 0:66f3b5499f7f | 127 | rmtree(EXPORT_DIR) |
screamer | 0:66f3b5499f7f | 128 | |
screamer | 0:66f3b5499f7f | 129 | # Export results |
screamer | 0:66f3b5499f7f | 130 | successes = [] |
screamer | 0:66f3b5499f7f | 131 | failures = [] |
screamer | 0:66f3b5499f7f | 132 | zip = True |
screamer | 0:66f3b5499f7f | 133 | clean = True |
screamer | 0:66f3b5499f7f | 134 | |
screamer | 0:66f3b5499f7f | 135 | # source_dir = use relative paths, otherwise sources are copied |
screamer | 0:66f3b5499f7f | 136 | sources_relative = True if options.source_dir else False |
screamer | 0:66f3b5499f7f | 137 | |
screamer | 22:9e85236d8716 | 138 | for mcu in options.mcu: |
screamer | 0:66f3b5499f7f | 139 | # Program Number or name |
screamer | 22:9e85236d8716 | 140 | p, src, ide = options.program, options.source_dir, options.ide |
screamer | 0:66f3b5499f7f | 141 | |
screamer | 22:9e85236d8716 | 142 | if src: |
screamer | 0:66f3b5499f7f | 143 | # --source is used to generate IDE files to toolchain directly in the source tree and doesn't generate zip file |
screamer | 0:66f3b5499f7f | 144 | project_dir = options.source_dir |
screamer | 22:9e85236d8716 | 145 | project_name = TESTS[p] if p else "Unnamed_project" |
screamer | 13:ab47a20b66f0 | 146 | project_temp = path.join(options.source_dir[0], 'projectfiles', '%s_%s' % (ide, mcu)) |
screamer | 0:66f3b5499f7f | 147 | mkdir(project_temp) |
screamer | 0:66f3b5499f7f | 148 | lib_symbols = [] |
screamer | 0:66f3b5499f7f | 149 | if options.macros: |
screamer | 0:66f3b5499f7f | 150 | lib_symbols += options.macros |
screamer | 0:66f3b5499f7f | 151 | zip = False # don't create zip |
screamer | 0:66f3b5499f7f | 152 | clean = False # don't cleanup because we use the actual source tree to generate IDE files |
screamer | 0:66f3b5499f7f | 153 | else: |
screamer | 0:66f3b5499f7f | 154 | test = Test(p) |
screamer | 0:66f3b5499f7f | 155 | |
screamer | 0:66f3b5499f7f | 156 | # Some libraries have extra macros (called by exporter symbols) to we need to pass |
screamer | 0:66f3b5499f7f | 157 | # them to maintain compilation macros integrity between compiled library and |
screamer | 0:66f3b5499f7f | 158 | # header files we might use with it |
screamer | 0:66f3b5499f7f | 159 | lib_symbols = [] |
screamer | 0:66f3b5499f7f | 160 | if options.macros: |
screamer | 0:66f3b5499f7f | 161 | lib_symbols += options.macros |
screamer | 0:66f3b5499f7f | 162 | for lib in LIBRARIES: |
screamer | 0:66f3b5499f7f | 163 | if lib['build_dir'] in test.dependencies: |
screamer | 0:66f3b5499f7f | 164 | lib_macros = lib.get('macros', None) |
screamer | 0:66f3b5499f7f | 165 | if lib_macros is not None: |
screamer | 0:66f3b5499f7f | 166 | lib_symbols.extend(lib_macros) |
screamer | 0:66f3b5499f7f | 167 | |
screamer | 0:66f3b5499f7f | 168 | if not options.build: |
screamer | 0:66f3b5499f7f | 169 | # Substitute the library builds with the sources |
screamer | 0:66f3b5499f7f | 170 | # TODO: Substitute also the other library build paths |
screamer | 0:66f3b5499f7f | 171 | if MBED_LIBRARIES in test.dependencies: |
screamer | 0:66f3b5499f7f | 172 | test.dependencies.remove(MBED_LIBRARIES) |
screamer | 0:66f3b5499f7f | 173 | test.dependencies.append(MBED_BASE) |
screamer | 0:66f3b5499f7f | 174 | |
screamer | 0:66f3b5499f7f | 175 | # Build the project with the same directory structure of the mbed online IDE |
screamer | 0:66f3b5499f7f | 176 | project_name = test.id |
screamer | 13:ab47a20b66f0 | 177 | project_dir = [join(EXPORT_WORKSPACE, project_name)] |
screamer | 0:66f3b5499f7f | 178 | project_temp = EXPORT_TMP |
screamer | 13:ab47a20b66f0 | 179 | setup_user_prj(project_dir[0], test.source_dir, test.dependencies) |
screamer | 0:66f3b5499f7f | 180 | |
screamer | 0:66f3b5499f7f | 181 | # Export to selected toolchain |
screamer | 13:ab47a20b66f0 | 182 | tmp_path, report = export(project_dir, project_name, ide, mcu, project_dir[0], project_temp, clean=clean, make_zip=zip, extra_symbols=lib_symbols, sources_relative=sources_relative) |
screamer | 0:66f3b5499f7f | 183 | if report['success']: |
screamer | 13:ab47a20b66f0 | 184 | if not zip: |
screamer | 13:ab47a20b66f0 | 185 | zip_path = join(project_temp, project_name) |
screamer | 13:ab47a20b66f0 | 186 | else: |
screamer | 13:ab47a20b66f0 | 187 | zip_path = join(EXPORT_DIR, "%s_%s_%s.zip" % (project_name, ide, mcu)) |
screamer | 0:66f3b5499f7f | 188 | move(tmp_path, zip_path) |
screamer | 0:66f3b5499f7f | 189 | successes.append("%s::%s\t%s"% (mcu, ide, zip_path)) |
screamer | 0:66f3b5499f7f | 190 | else: |
screamer | 0:66f3b5499f7f | 191 | failures.append("%s::%s\t%s"% (mcu, ide, report['errormsg'])) |
screamer | 0:66f3b5499f7f | 192 | |
screamer | 0:66f3b5499f7f | 193 | # Prints export results |
screamer | 0:66f3b5499f7f | 194 | |
screamer | 0:66f3b5499f7f | 195 | if len(successes) > 0: |
screamer | 0:66f3b5499f7f | 196 | print "Successful exports:" |
screamer | 0:66f3b5499f7f | 197 | for success in successes: |
screamer | 0:66f3b5499f7f | 198 | print " * %s"% success |
screamer | 0:66f3b5499f7f | 199 | if len(failures) > 0: |
screamer | 0:66f3b5499f7f | 200 | print "Failed exports:" |
screamer | 0:66f3b5499f7f | 201 | for failure in failures: |
screamer | 0:66f3b5499f7f | 202 | print " * %s"% failure |