Clone of official tools

Committer:
screamer
Date:
Thu Jul 14 20:21:19 2016 +0100
Revision:
13:ab47a20b66f0
Parent:
0:66f3b5499f7f
Child:
22:9e85236d8716
Apply latest tools

Who changed what in which revision?

UserRevisionLine numberNew 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 0:66f3b5499f7f 7 from optparse import OptionParser
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 0:66f3b5499f7f 15 from tools.targets import TARGET_NAMES
screamer 0:66f3b5499f7f 16 from tools.libraries import LIBRARIES
screamer 0:66f3b5499f7f 17
screamer 0:66f3b5499f7f 18 try:
screamer 0:66f3b5499f7f 19 import tools.private_settings as ps
screamer 0:66f3b5499f7f 20 except:
screamer 0:66f3b5499f7f 21 ps = object()
screamer 0:66f3b5499f7f 22
screamer 0:66f3b5499f7f 23
screamer 0:66f3b5499f7f 24 if __name__ == '__main__':
screamer 0:66f3b5499f7f 25 # Parse Options
screamer 0:66f3b5499f7f 26 parser = OptionParser()
screamer 0:66f3b5499f7f 27
screamer 0:66f3b5499f7f 28 targetnames = TARGET_NAMES
screamer 0:66f3b5499f7f 29 targetnames.sort()
screamer 0:66f3b5499f7f 30 toolchainlist = EXPORTERS.keys()
screamer 0:66f3b5499f7f 31 toolchainlist.sort()
screamer 0:66f3b5499f7f 32
screamer 0:66f3b5499f7f 33 parser.add_option("-m", "--mcu",
screamer 0:66f3b5499f7f 34 metavar="MCU",
screamer 0:66f3b5499f7f 35 default='LPC1768',
screamer 0:66f3b5499f7f 36 help="generate project for the given MCU (%s)"% ', '.join(targetnames))
screamer 0:66f3b5499f7f 37
screamer 0:66f3b5499f7f 38 parser.add_option("-i",
screamer 0:66f3b5499f7f 39 dest="ide",
screamer 0:66f3b5499f7f 40 default='uvision',
screamer 0:66f3b5499f7f 41 help="The target IDE: %s"% str(toolchainlist))
screamer 0:66f3b5499f7f 42
screamer 0:66f3b5499f7f 43 parser.add_option("-c", "--clean",
screamer 0:66f3b5499f7f 44 action="store_true",
screamer 0:66f3b5499f7f 45 default=False,
screamer 0:66f3b5499f7f 46 help="clean the export directory")
screamer 0:66f3b5499f7f 47
screamer 0:66f3b5499f7f 48 parser.add_option("-p",
screamer 0:66f3b5499f7f 49 type="int",
screamer 0:66f3b5499f7f 50 dest="program",
screamer 0:66f3b5499f7f 51 help="The index of the desired test program: [0-%d]"% (len(TESTS)-1))
screamer 0:66f3b5499f7f 52
screamer 0:66f3b5499f7f 53 parser.add_option("-n",
screamer 0:66f3b5499f7f 54 dest="program_name",
screamer 0:66f3b5499f7f 55 help="The name of the desired test program")
screamer 0:66f3b5499f7f 56
screamer 0:66f3b5499f7f 57 parser.add_option("-b",
screamer 0:66f3b5499f7f 58 dest="build",
screamer 0:66f3b5499f7f 59 action="store_true",
screamer 0:66f3b5499f7f 60 default=False,
screamer 0:66f3b5499f7f 61 help="use the mbed library build, instead of the sources")
screamer 0:66f3b5499f7f 62
screamer 0:66f3b5499f7f 63 parser.add_option("-L", "--list-tests",
screamer 0:66f3b5499f7f 64 action="store_true",
screamer 0:66f3b5499f7f 65 dest="list_tests",
screamer 0:66f3b5499f7f 66 default=False,
screamer 0:66f3b5499f7f 67 help="list available programs in order and exit")
screamer 0:66f3b5499f7f 68
screamer 0:66f3b5499f7f 69 parser.add_option("-S", "--list-matrix",
screamer 0:66f3b5499f7f 70 action="store_true",
screamer 0:66f3b5499f7f 71 dest="supported_ides",
screamer 0:66f3b5499f7f 72 default=False,
screamer 0:66f3b5499f7f 73 help="displays supported matrix of MCUs and IDEs")
screamer 0:66f3b5499f7f 74
screamer 0:66f3b5499f7f 75 parser.add_option("-E",
screamer 0:66f3b5499f7f 76 action="store_true",
screamer 0:66f3b5499f7f 77 dest="supported_ides_html",
screamer 0:66f3b5499f7f 78 default=False,
screamer 0:66f3b5499f7f 79 help="writes tools/export/README.md")
screamer 0:66f3b5499f7f 80
screamer 0:66f3b5499f7f 81 parser.add_option("--source",
screamer 13:ab47a20b66f0 82 action="append",
screamer 0:66f3b5499f7f 83 dest="source_dir",
screamer 0:66f3b5499f7f 84 default=None,
screamer 0:66f3b5499f7f 85 help="The source (input) directory")
screamer 0:66f3b5499f7f 86
screamer 0:66f3b5499f7f 87 parser.add_option("-D", "",
screamer 0:66f3b5499f7f 88 action="append",
screamer 0:66f3b5499f7f 89 dest="macros",
screamer 0:66f3b5499f7f 90 help="Add a macro definition")
screamer 0:66f3b5499f7f 91
screamer 0:66f3b5499f7f 92 (options, args) = parser.parse_args()
screamer 0:66f3b5499f7f 93
screamer 0:66f3b5499f7f 94 # Print available tests in order and exit
screamer 0:66f3b5499f7f 95 if options.list_tests is True:
screamer 0:66f3b5499f7f 96 print '\n'.join(map(str, sorted(TEST_MAP.values())))
screamer 0:66f3b5499f7f 97 sys.exit()
screamer 0:66f3b5499f7f 98
screamer 0:66f3b5499f7f 99 # Only prints matrix of supported IDEs
screamer 0:66f3b5499f7f 100 if options.supported_ides:
screamer 0:66f3b5499f7f 101 print mcu_ide_matrix()
screamer 0:66f3b5499f7f 102 exit(0)
screamer 0:66f3b5499f7f 103
screamer 0:66f3b5499f7f 104 # Only prints matrix of supported IDEs
screamer 0:66f3b5499f7f 105 if options.supported_ides_html:
screamer 0:66f3b5499f7f 106 html = mcu_ide_matrix(verbose_html=True)
screamer 0:66f3b5499f7f 107 try:
screamer 0:66f3b5499f7f 108 with open("./export/README.md","w") as f:
screamer 0:66f3b5499f7f 109 f.write("Exporter IDE/Platform Support\n")
screamer 0:66f3b5499f7f 110 f.write("-----------------------------------\n")
screamer 0:66f3b5499f7f 111 f.write("\n")
screamer 0:66f3b5499f7f 112 f.write(html)
screamer 0:66f3b5499f7f 113 except IOError as e:
screamer 0:66f3b5499f7f 114 print "I/O error({0}): {1}".format(e.errno, e.strerror)
screamer 0:66f3b5499f7f 115 except:
screamer 0:66f3b5499f7f 116 print "Unexpected error:", sys.exc_info()[0]
screamer 0:66f3b5499f7f 117 raise
screamer 0:66f3b5499f7f 118 exit(0)
screamer 0:66f3b5499f7f 119
screamer 0:66f3b5499f7f 120 # Clean Export Directory
screamer 0:66f3b5499f7f 121 if options.clean:
screamer 0:66f3b5499f7f 122 if exists(EXPORT_DIR):
screamer 0:66f3b5499f7f 123 rmtree(EXPORT_DIR)
screamer 0:66f3b5499f7f 124
screamer 0:66f3b5499f7f 125 # Target
screamer 0:66f3b5499f7f 126 if options.mcu is None :
screamer 0:66f3b5499f7f 127 args_error(parser, "[ERROR] You should specify an MCU")
screamer 0:66f3b5499f7f 128 mcus = options.mcu
screamer 0:66f3b5499f7f 129
screamer 0:66f3b5499f7f 130 # IDE
screamer 0:66f3b5499f7f 131 if options.ide is None:
screamer 0:66f3b5499f7f 132 args_error(parser, "[ERROR] You should specify an IDE")
screamer 0:66f3b5499f7f 133 ide = options.ide
screamer 0:66f3b5499f7f 134
screamer 0:66f3b5499f7f 135 # Export results
screamer 0:66f3b5499f7f 136 successes = []
screamer 0:66f3b5499f7f 137 failures = []
screamer 0:66f3b5499f7f 138 zip = True
screamer 0:66f3b5499f7f 139 clean = True
screamer 0:66f3b5499f7f 140
screamer 0:66f3b5499f7f 141 # source_dir = use relative paths, otherwise sources are copied
screamer 0:66f3b5499f7f 142 sources_relative = True if options.source_dir else False
screamer 0:66f3b5499f7f 143
screamer 0:66f3b5499f7f 144 for mcu in mcus.split(','):
screamer 0:66f3b5499f7f 145 # Program Number or name
screamer 0:66f3b5499f7f 146 p, n, src, ide = options.program, options.program_name, options.source_dir, options.ide
screamer 0:66f3b5499f7f 147
screamer 0:66f3b5499f7f 148 if src is not None:
screamer 0:66f3b5499f7f 149 # --source is used to generate IDE files to toolchain directly in the source tree and doesn't generate zip file
screamer 0:66f3b5499f7f 150 project_dir = options.source_dir
screamer 13:ab47a20b66f0 151 project_name = n if n else "Unnamed_Project"
screamer 13:ab47a20b66f0 152 project_temp = path.join(options.source_dir[0], 'projectfiles', '%s_%s' % (ide, mcu))
screamer 0:66f3b5499f7f 153 mkdir(project_temp)
screamer 0:66f3b5499f7f 154 lib_symbols = []
screamer 0:66f3b5499f7f 155 if options.macros:
screamer 0:66f3b5499f7f 156 lib_symbols += options.macros
screamer 0:66f3b5499f7f 157 zip = False # don't create zip
screamer 0:66f3b5499f7f 158 clean = False # don't cleanup because we use the actual source tree to generate IDE files
screamer 0:66f3b5499f7f 159 else:
screamer 0:66f3b5499f7f 160 if n is not None and p is not None:
screamer 0:66f3b5499f7f 161 args_error(parser, "[ERROR] specify either '-n' or '-p', not both")
screamer 0:66f3b5499f7f 162 if n:
screamer 0:66f3b5499f7f 163 if not n in TEST_MAP.keys():
screamer 0:66f3b5499f7f 164 # Check if there is an alias for this in private_settings.py
screamer 0:66f3b5499f7f 165 if getattr(ps, "test_alias", None) is not None:
screamer 0:66f3b5499f7f 166 alias = ps.test_alias.get(n, "")
screamer 0:66f3b5499f7f 167 if not alias in TEST_MAP.keys():
screamer 0:66f3b5499f7f 168 args_error(parser, "[ERROR] Program with name '%s' not found" % n)
screamer 0:66f3b5499f7f 169 else:
screamer 0:66f3b5499f7f 170 n = alias
screamer 0:66f3b5499f7f 171 else:
screamer 0:66f3b5499f7f 172 args_error(parser, "[ERROR] Program with name '%s' not found" % n)
screamer 0:66f3b5499f7f 173 p = TEST_MAP[n].n
screamer 0:66f3b5499f7f 174
screamer 0:66f3b5499f7f 175 if p is None or (p < 0) or (p > (len(TESTS)-1)):
screamer 0:66f3b5499f7f 176 message = "[ERROR] You have to specify one of the following tests:\n"
screamer 0:66f3b5499f7f 177 message += '\n'.join(map(str, sorted(TEST_MAP.values())))
screamer 0:66f3b5499f7f 178 args_error(parser, message)
screamer 0:66f3b5499f7f 179
screamer 0:66f3b5499f7f 180 # Project
screamer 0:66f3b5499f7f 181 if p is None or (p < 0) or (p > (len(TESTS)-1)):
screamer 0:66f3b5499f7f 182 message = "[ERROR] You have to specify one of the following tests:\n"
screamer 0:66f3b5499f7f 183 message += '\n'.join(map(str, sorted(TEST_MAP.values())))
screamer 0:66f3b5499f7f 184 args_error(parser, message)
screamer 0:66f3b5499f7f 185 test = Test(p)
screamer 0:66f3b5499f7f 186
screamer 0:66f3b5499f7f 187 # Some libraries have extra macros (called by exporter symbols) to we need to pass
screamer 0:66f3b5499f7f 188 # them to maintain compilation macros integrity between compiled library and
screamer 0:66f3b5499f7f 189 # header files we might use with it
screamer 0:66f3b5499f7f 190 lib_symbols = []
screamer 0:66f3b5499f7f 191 if options.macros:
screamer 0:66f3b5499f7f 192 lib_symbols += options.macros
screamer 0:66f3b5499f7f 193 for lib in LIBRARIES:
screamer 0:66f3b5499f7f 194 if lib['build_dir'] in test.dependencies:
screamer 0:66f3b5499f7f 195 lib_macros = lib.get('macros', None)
screamer 0:66f3b5499f7f 196 if lib_macros is not None:
screamer 0:66f3b5499f7f 197 lib_symbols.extend(lib_macros)
screamer 0:66f3b5499f7f 198
screamer 0:66f3b5499f7f 199 if not options.build:
screamer 0:66f3b5499f7f 200 # Substitute the library builds with the sources
screamer 0:66f3b5499f7f 201 # TODO: Substitute also the other library build paths
screamer 0:66f3b5499f7f 202 if MBED_LIBRARIES in test.dependencies:
screamer 0:66f3b5499f7f 203 test.dependencies.remove(MBED_LIBRARIES)
screamer 0:66f3b5499f7f 204 test.dependencies.append(MBED_BASE)
screamer 0:66f3b5499f7f 205
screamer 0:66f3b5499f7f 206 # Build the project with the same directory structure of the mbed online IDE
screamer 0:66f3b5499f7f 207 project_name = test.id
screamer 13:ab47a20b66f0 208 project_dir = [join(EXPORT_WORKSPACE, project_name)]
screamer 0:66f3b5499f7f 209 project_temp = EXPORT_TMP
screamer 13:ab47a20b66f0 210 setup_user_prj(project_dir[0], test.source_dir, test.dependencies)
screamer 0:66f3b5499f7f 211
screamer 0:66f3b5499f7f 212 # Export to selected toolchain
screamer 13:ab47a20b66f0 213 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 214 if report['success']:
screamer 13:ab47a20b66f0 215 if not zip:
screamer 13:ab47a20b66f0 216 zip_path = join(project_temp, project_name)
screamer 13:ab47a20b66f0 217 else:
screamer 13:ab47a20b66f0 218 zip_path = join(EXPORT_DIR, "%s_%s_%s.zip" % (project_name, ide, mcu))
screamer 0:66f3b5499f7f 219 move(tmp_path, zip_path)
screamer 0:66f3b5499f7f 220 successes.append("%s::%s\t%s"% (mcu, ide, zip_path))
screamer 0:66f3b5499f7f 221 else:
screamer 0:66f3b5499f7f 222 failures.append("%s::%s\t%s"% (mcu, ide, report['errormsg']))
screamer 0:66f3b5499f7f 223
screamer 0:66f3b5499f7f 224 # Prints export results
screamer 0:66f3b5499f7f 225 print
screamer 0:66f3b5499f7f 226 if len(successes) > 0:
screamer 0:66f3b5499f7f 227 print "Successful exports:"
screamer 0:66f3b5499f7f 228 for success in successes:
screamer 0:66f3b5499f7f 229 print " * %s"% success
screamer 0:66f3b5499f7f 230 if len(failures) > 0:
screamer 0:66f3b5499f7f 231 print "Failed exports:"
screamer 0:66f3b5499f7f 232 for failure in failures:
screamer 0:66f3b5499f7f 233 print " * %s"% failure