Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-sdk-tools by
project.py@32:8ea194f6145b, 2017-01-04 (annotated)
- Committer:
- The Other Jimmy
- Date:
- Wed Jan 04 11:58:24 2017 -0600
- Revision:
- 32:8ea194f6145b
- Parent:
- 29:1210849dba19
Update tools to follow mbed-os tools release 5.3.1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
The Other Jimmy |
32:8ea194f6145b | 1 | """ The CLI entry point for exporting projects from the mbed tools to any of the |
The Other Jimmy |
32:8ea194f6145b | 2 | supported IDEs or project structures. |
The Other Jimmy |
32:8ea194f6145b | 3 | """ |
screamer | 0:66f3b5499f7f | 4 | import sys |
screamer | 0:66f3b5499f7f | 5 | from os.path import join, abspath, dirname, exists, basename |
screamer | 0:66f3b5499f7f | 6 | ROOT = abspath(join(dirname(__file__), "..")) |
screamer | 0:66f3b5499f7f | 7 | sys.path.insert(0, ROOT) |
screamer | 0:66f3b5499f7f | 8 | |
screamer | 0:66f3b5499f7f | 9 | from shutil import move, rmtree |
screamer | 22:9e85236d8716 | 10 | from argparse import ArgumentParser |
The Other Jimmy |
32:8ea194f6145b | 11 | from os.path import normpath, realpath |
screamer | 0:66f3b5499f7f | 12 | |
The Other Jimmy |
32:8ea194f6145b | 13 | from tools.paths import EXPORT_DIR, MBED_HAL, MBED_LIBRARIES, MBED_TARGETS_PATH |
The Other Jimmy |
32:8ea194f6145b | 14 | from tools.export import EXPORTERS, mcu_ide_matrix |
screamer | 23:fbae331171fa | 15 | from tools.tests import TESTS, TEST_MAP |
The Other Jimmy |
32:8ea194f6145b | 16 | from tools.tests import test_known, test_name_known, Test |
screamer | 0:66f3b5499f7f | 17 | from tools.targets import TARGET_NAMES |
The Other Jimmy |
32:8ea194f6145b | 18 | from tools.utils import argparse_filestring_type, argparse_profile_filestring_type, argparse_many, args_error |
The Other Jimmy |
32:8ea194f6145b | 19 | from tools.utils import argparse_force_lowercase_type |
The Other Jimmy |
32:8ea194f6145b | 20 | from tools.utils import argparse_force_uppercase_type |
The Other Jimmy |
32:8ea194f6145b | 21 | from tools.utils import print_large_string |
The Other Jimmy |
32:8ea194f6145b | 22 | from tools.project_api import export_project, get_exporter_toolchain |
The Other Jimmy |
32:8ea194f6145b | 23 | from tools.options import extract_profile, list_profiles |
The Other Jimmy |
32:8ea194f6145b | 24 | |
The Other Jimmy |
32:8ea194f6145b | 25 | def setup_project(ide, target, program=None, source_dir=None, build=None, export_path=None): |
The Other Jimmy |
32:8ea194f6145b | 26 | """Generate a name, if not provided, and find dependencies |
The Other Jimmy |
32:8ea194f6145b | 27 | |
The Other Jimmy |
32:8ea194f6145b | 28 | Positional arguments: |
The Other Jimmy |
32:8ea194f6145b | 29 | ide - IDE or project structure that will soon be exported to |
The Other Jimmy |
32:8ea194f6145b | 30 | target - MCU that the project will build for |
The Other Jimmy |
32:8ea194f6145b | 31 | |
The Other Jimmy |
32:8ea194f6145b | 32 | Keyword arguments: |
The Other Jimmy |
32:8ea194f6145b | 33 | program - the index of a test program |
The Other Jimmy |
32:8ea194f6145b | 34 | source_dir - the directory, or directories that contain all of the sources |
The Other Jimmy |
32:8ea194f6145b | 35 | build - a directory that will contain the result of the export |
The Other Jimmy |
32:8ea194f6145b | 36 | """ |
The Other Jimmy |
32:8ea194f6145b | 37 | # Some libraries have extra macros (called by exporter symbols) to we need |
The Other Jimmy |
32:8ea194f6145b | 38 | # to pass them to maintain compilation macros integrity between compiled |
The Other Jimmy |
32:8ea194f6145b | 39 | # library and header files we might use with it |
The Other Jimmy |
32:8ea194f6145b | 40 | if source_dir: |
The Other Jimmy |
32:8ea194f6145b | 41 | # --source is used to generate IDE files to toolchain directly |
The Other Jimmy |
32:8ea194f6145b | 42 | # in the source tree and doesn't generate zip file |
The Other Jimmy |
32:8ea194f6145b | 43 | project_dir = export_path or source_dir[0] |
The Other Jimmy |
32:8ea194f6145b | 44 | if program: |
The Other Jimmy |
32:8ea194f6145b | 45 | project_name = TESTS[program] |
The Other Jimmy |
32:8ea194f6145b | 46 | else: |
The Other Jimmy |
32:8ea194f6145b | 47 | project_name = basename(normpath(realpath(source_dir[0]))) |
The Other Jimmy |
32:8ea194f6145b | 48 | src_paths = source_dir |
The Other Jimmy |
32:8ea194f6145b | 49 | lib_paths = None |
The Other Jimmy |
32:8ea194f6145b | 50 | else: |
The Other Jimmy |
32:8ea194f6145b | 51 | test = Test(program) |
The Other Jimmy |
32:8ea194f6145b | 52 | if not build: |
The Other Jimmy |
32:8ea194f6145b | 53 | # Substitute the mbed library builds with their sources |
The Other Jimmy |
32:8ea194f6145b | 54 | if MBED_LIBRARIES in test.dependencies: |
The Other Jimmy |
32:8ea194f6145b | 55 | test.dependencies.remove(MBED_LIBRARIES) |
The Other Jimmy |
32:8ea194f6145b | 56 | test.dependencies.append(MBED_HAL) |
The Other Jimmy |
32:8ea194f6145b | 57 | test.dependencies.append(MBED_TARGETS_PATH) |
screamer | 0:66f3b5499f7f | 58 | |
screamer | 0:66f3b5499f7f | 59 | |
The Other Jimmy |
32:8ea194f6145b | 60 | src_paths = [test.source_dir] |
The Other Jimmy |
32:8ea194f6145b | 61 | lib_paths = test.dependencies |
The Other Jimmy |
32:8ea194f6145b | 62 | project_name = "_".join([test.id, ide, target]) |
The Other Jimmy |
32:8ea194f6145b | 63 | project_dir = join(EXPORT_DIR, project_name) |
screamer | 0:66f3b5499f7f | 64 | |
The Other Jimmy |
32:8ea194f6145b | 65 | return project_dir, project_name, src_paths, lib_paths |
The Other Jimmy |
32:8ea194f6145b | 66 | |
The Other Jimmy |
32:8ea194f6145b | 67 | |
The Other Jimmy |
32:8ea194f6145b | 68 | def export(target, ide, build=None, src=None, macros=None, project_id=None, |
The Other Jimmy |
32:8ea194f6145b | 69 | clean=False, zip_proj=False, build_profile=None, export_path=None, |
The Other Jimmy |
32:8ea194f6145b | 70 | silent=False): |
The Other Jimmy |
32:8ea194f6145b | 71 | """Do an export of a project. |
The Other Jimmy |
32:8ea194f6145b | 72 | |
The Other Jimmy |
32:8ea194f6145b | 73 | Positional arguments: |
The Other Jimmy |
32:8ea194f6145b | 74 | target - MCU that the project will compile for |
The Other Jimmy |
32:8ea194f6145b | 75 | ide - the IDE or project structure to export to |
The Other Jimmy |
32:8ea194f6145b | 76 | |
The Other Jimmy |
32:8ea194f6145b | 77 | Keyword arguments: |
The Other Jimmy |
32:8ea194f6145b | 78 | build - to use the compiled mbed libraries or not |
The Other Jimmy |
32:8ea194f6145b | 79 | src - directory or directories that contain the source to export |
The Other Jimmy |
32:8ea194f6145b | 80 | macros - extra macros to add to the project |
The Other Jimmy |
32:8ea194f6145b | 81 | project_id - the name of the project |
The Other Jimmy |
32:8ea194f6145b | 82 | clean - start from a clean state before exporting |
The Other Jimmy |
32:8ea194f6145b | 83 | zip_proj - create a zip file or not |
The Other Jimmy |
32:8ea194f6145b | 84 | |
The Other Jimmy |
32:8ea194f6145b | 85 | Returns an object of type Exporter (tools/exports/exporters.py) |
The Other Jimmy |
32:8ea194f6145b | 86 | """ |
The Other Jimmy |
32:8ea194f6145b | 87 | project_dir, name, src, lib = setup_project(ide, target, program=project_id, |
The Other Jimmy |
32:8ea194f6145b | 88 | source_dir=src, build=build, export_path=export_path) |
The Other Jimmy |
32:8ea194f6145b | 89 | |
The Other Jimmy |
32:8ea194f6145b | 90 | zip_name = name+".zip" if zip_proj else None |
The Other Jimmy |
32:8ea194f6145b | 91 | |
The Other Jimmy |
32:8ea194f6145b | 92 | return export_project(src, project_dir, target, ide, clean=clean, name=name, |
The Other Jimmy |
32:8ea194f6145b | 93 | macros=macros, libraries_paths=lib, zip_proj=zip_name, |
The Other Jimmy |
32:8ea194f6145b | 94 | build_profile=build_profile, silent=silent) |
The Other Jimmy |
32:8ea194f6145b | 95 | |
The Other Jimmy |
32:8ea194f6145b | 96 | |
The Other Jimmy |
32:8ea194f6145b | 97 | def main(): |
The Other Jimmy |
32:8ea194f6145b | 98 | """Entry point""" |
screamer | 0:66f3b5499f7f | 99 | # Parse Options |
screamer | 22:9e85236d8716 | 100 | parser = ArgumentParser() |
screamer | 0:66f3b5499f7f | 101 | |
screamer | 0:66f3b5499f7f | 102 | targetnames = TARGET_NAMES |
screamer | 0:66f3b5499f7f | 103 | targetnames.sort() |
screamer | 0:66f3b5499f7f | 104 | toolchainlist = EXPORTERS.keys() |
screamer | 0:66f3b5499f7f | 105 | toolchainlist.sort() |
screamer | 0:66f3b5499f7f | 106 | |
screamer | 22:9e85236d8716 | 107 | parser.add_argument("-m", "--mcu", |
The Other Jimmy |
32:8ea194f6145b | 108 | metavar="MCU", |
The Other Jimmy |
32:8ea194f6145b | 109 | default='LPC1768', |
The Other Jimmy |
32:8ea194f6145b | 110 | type=argparse_force_uppercase_type(targetnames, "MCU"), |
The Other Jimmy |
32:8ea194f6145b | 111 | help="generate project for the given MCU ({})".format( |
The Other Jimmy |
32:8ea194f6145b | 112 | ', '.join(targetnames))) |
screamer | 0:66f3b5499f7f | 113 | |
screamer | 22:9e85236d8716 | 114 | parser.add_argument("-i", |
The Other Jimmy |
32:8ea194f6145b | 115 | dest="ide", |
The Other Jimmy |
32:8ea194f6145b | 116 | default='uvision', |
The Other Jimmy |
32:8ea194f6145b | 117 | type=argparse_force_lowercase_type( |
The Other Jimmy |
32:8ea194f6145b | 118 | toolchainlist, "toolchain"), |
The Other Jimmy |
32:8ea194f6145b | 119 | help="The target IDE: %s"% str(toolchainlist)) |
screamer | 0:66f3b5499f7f | 120 | |
screamer | 22:9e85236d8716 | 121 | parser.add_argument("-c", "--clean", |
The Other Jimmy |
32:8ea194f6145b | 122 | action="store_true", |
The Other Jimmy |
32:8ea194f6145b | 123 | default=False, |
The Other Jimmy |
32:8ea194f6145b | 124 | help="clean the export directory") |
screamer | 0:66f3b5499f7f | 125 | |
screamer | 22:9e85236d8716 | 126 | group = parser.add_mutually_exclusive_group(required=False) |
The Other Jimmy |
32:8ea194f6145b | 127 | group.add_argument( |
The Other Jimmy |
32:8ea194f6145b | 128 | "-p", |
The Other Jimmy |
32:8ea194f6145b | 129 | type=test_known, |
The Other Jimmy |
32:8ea194f6145b | 130 | dest="program", |
The Other Jimmy |
32:8ea194f6145b | 131 | help="The index of the desired test program: [0-%s]"% (len(TESTS)-1)) |
screamer | 0:66f3b5499f7f | 132 | |
screamer | 22:9e85236d8716 | 133 | group.add_argument("-n", |
The Other Jimmy |
32:8ea194f6145b | 134 | type=test_name_known, |
The Other Jimmy |
32:8ea194f6145b | 135 | dest="program", |
The Other Jimmy |
32:8ea194f6145b | 136 | help="The name of the desired test program") |
screamer | 0:66f3b5499f7f | 137 | |
screamer | 22:9e85236d8716 | 138 | parser.add_argument("-b", |
screamer | 0:66f3b5499f7f | 139 | dest="build", |
screamer | 0:66f3b5499f7f | 140 | default=False, |
screamer | 29:1210849dba19 | 141 | action="store_true", |
screamer | 0:66f3b5499f7f | 142 | help="use the mbed library build, instead of the sources") |
screamer | 0:66f3b5499f7f | 143 | |
screamer | 22:9e85236d8716 | 144 | group.add_argument("-L", "--list-tests", |
The Other Jimmy |
32:8ea194f6145b | 145 | action="store_true", |
The Other Jimmy |
32:8ea194f6145b | 146 | dest="list_tests", |
The Other Jimmy |
32:8ea194f6145b | 147 | default=False, |
The Other Jimmy |
32:8ea194f6145b | 148 | help="list available programs in order and exit") |
screamer | 0:66f3b5499f7f | 149 | |
screamer | 22:9e85236d8716 | 150 | group.add_argument("-S", "--list-matrix", |
The Other Jimmy |
32:8ea194f6145b | 151 | action="store_true", |
The Other Jimmy |
32:8ea194f6145b | 152 | dest="supported_ides", |
The Other Jimmy |
32:8ea194f6145b | 153 | default=False, |
The Other Jimmy |
32:8ea194f6145b | 154 | help="displays supported matrix of MCUs and IDEs") |
screamer | 0:66f3b5499f7f | 155 | |
screamer | 22:9e85236d8716 | 156 | parser.add_argument("-E", |
The Other Jimmy |
32:8ea194f6145b | 157 | action="store_true", |
The Other Jimmy |
32:8ea194f6145b | 158 | dest="supported_ides_html", |
The Other Jimmy |
32:8ea194f6145b | 159 | default=False, |
The Other Jimmy |
32:8ea194f6145b | 160 | help="writes tools/export/README.md") |
screamer | 0:66f3b5499f7f | 161 | |
screamer | 22:9e85236d8716 | 162 | parser.add_argument("--source", |
The Other Jimmy |
32:8ea194f6145b | 163 | action="append", |
The Other Jimmy |
32:8ea194f6145b | 164 | type=argparse_filestring_type, |
The Other Jimmy |
32:8ea194f6145b | 165 | dest="source_dir", |
The Other Jimmy |
32:8ea194f6145b | 166 | default=[], |
The Other Jimmy |
32:8ea194f6145b | 167 | help="The source (input) directory") |
screamer | 0:66f3b5499f7f | 168 | |
screamer | 22:9e85236d8716 | 169 | parser.add_argument("-D", |
The Other Jimmy |
32:8ea194f6145b | 170 | action="append", |
The Other Jimmy |
32:8ea194f6145b | 171 | dest="macros", |
The Other Jimmy |
32:8ea194f6145b | 172 | help="Add a macro definition") |
The Other Jimmy |
32:8ea194f6145b | 173 | |
The Other Jimmy |
32:8ea194f6145b | 174 | parser.add_argument("--profile", dest="profile", action="append", |
The Other Jimmy |
32:8ea194f6145b | 175 | type=argparse_profile_filestring_type, |
The Other Jimmy |
32:8ea194f6145b | 176 | help="Build profile to use. Can be either path to json" \ |
The Other Jimmy |
32:8ea194f6145b | 177 | "file or one of the default one ({})".format(", ".join(list_profiles())), |
The Other Jimmy |
32:8ea194f6145b | 178 | default=[]) |
The Other Jimmy |
32:8ea194f6145b | 179 | |
The Other Jimmy |
32:8ea194f6145b | 180 | parser.add_argument("--update-packs", |
The Other Jimmy |
32:8ea194f6145b | 181 | dest="update_packs", |
The Other Jimmy |
32:8ea194f6145b | 182 | action="store_true", |
The Other Jimmy |
32:8ea194f6145b | 183 | default=False) |
screamer | 0:66f3b5499f7f | 184 | |
screamer | 22:9e85236d8716 | 185 | options = parser.parse_args() |
screamer | 0:66f3b5499f7f | 186 | |
screamer | 0:66f3b5499f7f | 187 | # Print available tests in order and exit |
screamer | 0:66f3b5499f7f | 188 | if options.list_tests is True: |
The Other Jimmy |
32:8ea194f6145b | 189 | print '\n'.join([str(test) for test in sorted(TEST_MAP.values())]) |
screamer | 0:66f3b5499f7f | 190 | sys.exit() |
screamer | 0:66f3b5499f7f | 191 | |
screamer | 0:66f3b5499f7f | 192 | # Only prints matrix of supported IDEs |
screamer | 0:66f3b5499f7f | 193 | if options.supported_ides: |
The Other Jimmy |
32:8ea194f6145b | 194 | print_large_string(mcu_ide_matrix()) |
screamer | 0:66f3b5499f7f | 195 | exit(0) |
screamer | 0:66f3b5499f7f | 196 | |
screamer | 0:66f3b5499f7f | 197 | # Only prints matrix of supported IDEs |
screamer | 0:66f3b5499f7f | 198 | if options.supported_ides_html: |
screamer | 0:66f3b5499f7f | 199 | html = mcu_ide_matrix(verbose_html=True) |
screamer | 0:66f3b5499f7f | 200 | try: |
The Other Jimmy |
32:8ea194f6145b | 201 | with open("./export/README.md", "w") as readme: |
The Other Jimmy |
32:8ea194f6145b | 202 | readme.write("Exporter IDE/Platform Support\n") |
The Other Jimmy |
32:8ea194f6145b | 203 | readme.write("-----------------------------------\n") |
The Other Jimmy |
32:8ea194f6145b | 204 | readme.write("\n") |
The Other Jimmy |
32:8ea194f6145b | 205 | readme.write(html) |
The Other Jimmy |
32:8ea194f6145b | 206 | except IOError as exc: |
The Other Jimmy |
32:8ea194f6145b | 207 | print "I/O error({0}): {1}".format(exc.errno, exc.strerror) |
screamer | 0:66f3b5499f7f | 208 | except: |
screamer | 0:66f3b5499f7f | 209 | print "Unexpected error:", sys.exc_info()[0] |
screamer | 0:66f3b5499f7f | 210 | raise |
screamer | 0:66f3b5499f7f | 211 | exit(0) |
screamer | 0:66f3b5499f7f | 212 | |
The Other Jimmy |
32:8ea194f6145b | 213 | if options.update_packs: |
The Other Jimmy |
32:8ea194f6145b | 214 | from tools.arm_pack_manager import Cache |
The Other Jimmy |
32:8ea194f6145b | 215 | cache = Cache(True, True) |
The Other Jimmy |
32:8ea194f6145b | 216 | cache.cache_descriptors() |
The Other Jimmy |
32:8ea194f6145b | 217 | |
screamer | 0:66f3b5499f7f | 218 | # Clean Export Directory |
screamer | 0:66f3b5499f7f | 219 | if options.clean: |
screamer | 0:66f3b5499f7f | 220 | if exists(EXPORT_DIR): |
screamer | 0:66f3b5499f7f | 221 | rmtree(EXPORT_DIR) |
screamer | 0:66f3b5499f7f | 222 | |
The Other Jimmy |
32:8ea194f6145b | 223 | for mcu in options.mcu: |
The Other Jimmy |
32:8ea194f6145b | 224 | zip_proj = not bool(options.source_dir) |
screamer | 0:66f3b5499f7f | 225 | |
The Other Jimmy |
32:8ea194f6145b | 226 | # Target |
The Other Jimmy |
32:8ea194f6145b | 227 | if not options.mcu: |
The Other Jimmy |
32:8ea194f6145b | 228 | args_error(parser, "argument -m/--mcu is required") |
The Other Jimmy |
32:8ea194f6145b | 229 | |
The Other Jimmy |
32:8ea194f6145b | 230 | # Toolchain |
The Other Jimmy |
32:8ea194f6145b | 231 | if not options.ide: |
The Other Jimmy |
32:8ea194f6145b | 232 | args_error(parser, "argument -i is required") |
screamer | 0:66f3b5499f7f | 233 | |
The Other Jimmy |
32:8ea194f6145b | 234 | if (options.program is None) and (not options.source_dir): |
The Other Jimmy |
32:8ea194f6145b | 235 | args_error(parser, "one of -p, -n, or --source is required") |
The Other Jimmy |
32:8ea194f6145b | 236 | # Export to selected toolchain |
The Other Jimmy |
32:8ea194f6145b | 237 | exporter, toolchain_name = get_exporter_toolchain(options.ide) |
The Other Jimmy |
32:8ea194f6145b | 238 | if options.mcu not in exporter.TARGETS: |
The Other Jimmy |
32:8ea194f6145b | 239 | args_error(parser, "%s not supported by %s"%(options.mcu,options.ide)) |
The Other Jimmy |
32:8ea194f6145b | 240 | profile = extract_profile(parser, options, toolchain_name) |
The Other Jimmy |
32:8ea194f6145b | 241 | export(options.mcu, options.ide, build=options.build, |
The Other Jimmy |
32:8ea194f6145b | 242 | src=options.source_dir, macros=options.macros, |
The Other Jimmy |
32:8ea194f6145b | 243 | project_id=options.program, clean=options.clean, |
The Other Jimmy |
32:8ea194f6145b | 244 | zip_proj=zip_proj, build_profile=profile) |
screamer | 0:66f3b5499f7f | 245 | |
The Other Jimmy |
32:8ea194f6145b | 246 | |
The Other Jimmy |
32:8ea194f6145b | 247 | if __name__ == "__main__": |
The Other Jimmy |
32:8ea194f6145b | 248 | main() |