mbed-os

Fork of mbed-os by erkin yucel

Committer:
xuaner
Date:
Thu Jul 20 14:26:57 2017 +0000
Revision:
1:3deb71413561
Parent:
0:f269e3021894
mbed_os

Who changed what in which revision?

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