Nicolas Borla / Mbed OS BBR_1Ebene
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers project.py Source File

project.py

00001 """ The CLI entry point for exporting projects from the mbed tools to any of the
00002 supported IDEs or project structures.
00003 """
00004 from __future__ import print_function, absolute_import
00005 from builtins import str
00006 
00007 import sys
00008 from os.path import (join, abspath, dirname, exists, basename, normpath,
00009                      realpath, relpath, basename)
00010 from os import remove
00011 ROOT = abspath(join(dirname(__file__), ".."))
00012 sys.path.insert(0, ROOT)
00013 
00014 from shutil import move, rmtree
00015 from argparse import ArgumentParser
00016 
00017 from tools.paths import EXPORT_DIR, MBED_HAL, MBED_LIBRARIES, MBED_TARGETS_PATH
00018 from tools.settings import BUILD_DIR
00019 from tools.export import EXPORTERS, mcu_ide_matrix, mcu_ide_list, export_project, get_exporter_toolchain
00020 from tools.tests import TESTS, TEST_MAP
00021 from tools.tests import test_known, test_name_known, Test
00022 from tools.targets import TARGET_NAMES
00023 from tools.utils import argparse_filestring_type, argparse_profile_filestring_type, argparse_many, args_error
00024 from tools.utils import argparse_force_lowercase_type
00025 from tools.utils import argparse_force_uppercase_type
00026 from tools.utils import print_large_string
00027 from tools.utils import NotSupportedException
00028 from tools.options import extract_profile, list_profiles, extract_mcus
00029 from tools.notifier.term import TerminalNotifier
00030 
00031 def setup_project (ide, target, program=None, source_dir=None, build=None, export_path=None):
00032     """Generate a name, if not provided, and find dependencies
00033 
00034     Positional arguments:
00035     ide - IDE or project structure that will soon be exported to
00036     target - MCU that the project will build for
00037 
00038     Keyword arguments:
00039     program - the index of a test program
00040     source_dir - the directory, or directories that contain all of the sources
00041     build - a directory that will contain the result of the export
00042     """
00043     # Some libraries have extra macros (called by exporter symbols) to we need
00044     # to pass them to maintain compilation macros integrity between compiled
00045     # library and header files we might use with it
00046     if source_dir:
00047         # --source is used to generate IDE files to toolchain directly
00048         # in the source tree and doesn't generate zip file
00049         project_dir = export_path or source_dir[0]
00050         if program:
00051             project_name = TESTS[program]
00052         else:
00053             project_name = basename(normpath(realpath(source_dir[0])))
00054         src_paths = {relpath(path, project_dir): [path] for path in source_dir}
00055         lib_paths = None
00056     else:
00057         test = Test(program)
00058         if not build:
00059             # Substitute the mbed library builds with their sources
00060             if MBED_LIBRARIES in test.dependencies:
00061                 test.dependencies.remove(MBED_LIBRARIES)
00062                 test.dependencies.append(MBED_HAL)
00063                 test.dependencies.append(MBED_TARGETS_PATH)
00064 
00065 
00066         src_paths = [test.source_dir]
00067         lib_paths = test.dependencies
00068         project_name = "_".join([test.id, ide, target])
00069         project_dir = join(EXPORT_DIR, project_name)
00070 
00071     return project_dir, project_name, src_paths, lib_paths
00072 
00073 
00074 def export (target, ide, build=None, src=None, macros=None, project_id=None,
00075            zip_proj=False, build_profile=None, export_path=None, notify=None,
00076            app_config=None):
00077     """Do an export of a project.
00078 
00079     Positional arguments:
00080     target - MCU that the project will compile for
00081     ide - the IDE or project structure to export to
00082 
00083     Keyword arguments:
00084     build - to use the compiled mbed libraries or not
00085     src - directory or directories that contain the source to export
00086     macros - extra macros to add to the project
00087     project_id - the name of the project
00088     clean - start from a clean state before exporting
00089     zip_proj - create a zip file or not
00090 
00091     Returns an object of type Exporter (tools/exports/exporters.py)
00092     """
00093     project_dir, name, src, lib = setup_project(ide, target, program=project_id,
00094                                                 source_dir=src, build=build, export_path=export_path)
00095 
00096     zip_name = name+".zip" if zip_proj else None
00097 
00098     return export_project(src, project_dir, target, ide, name=name,
00099                           macros=macros, libraries_paths=lib, zip_proj=zip_name,
00100                           build_profile=build_profile, notify=notify,
00101                           app_config=app_config)
00102 
00103 
00104 def main ():
00105     """Entry point"""
00106     # Parse Options
00107     parser = ArgumentParser()
00108 
00109     targetnames = TARGET_NAMES
00110     targetnames.sort()
00111     toolchainlist = list(EXPORTERS.keys())
00112     toolchainlist.sort()
00113 
00114     parser.add_argument("-m", "--mcu",
00115                         metavar="MCU",
00116                         help="generate project for the given MCU ({})".format(
00117                             ', '.join(targetnames)))
00118 
00119     parser.add_argument("-i",
00120                         dest="ide",
00121                         type=argparse_force_lowercase_type(
00122                             toolchainlist, "toolchain"),
00123                         help="The target IDE: %s"% str(toolchainlist))
00124 
00125     parser.add_argument("-c", "--clean",
00126                         action="store_true",
00127                         default=False,
00128                         help="clean the export directory")
00129 
00130     group = parser.add_mutually_exclusive_group(required=False)
00131     group.add_argument(
00132         "-p",
00133         type=test_known,
00134         dest="program",
00135         help="The index of the desired test program: [0-%s]"% (len(TESTS)-1))
00136 
00137     group.add_argument("-n",
00138                        type=test_name_known,
00139                        dest="program",
00140                        help="The name of the desired test program")
00141 
00142     parser.add_argument("-b",
00143                       dest="build",
00144                       default=False,
00145                       action="store_true",
00146                       help="use the mbed library build, instead of the sources")
00147 
00148     group.add_argument("-L", "--list-tests",
00149                        action="store_true",
00150                        dest="list_tests",
00151                        default=False,
00152                        help="list available programs in order and exit")
00153 
00154     group.add_argument("-S", "--list-matrix",
00155                        dest="supported_ides",
00156                        default=False,
00157                        const="matrix",
00158                        choices=["matrix", "ides"],
00159                        nargs="?",
00160                        help="displays supported matrix of MCUs and IDEs")
00161 
00162     parser.add_argument("-E",
00163                         action="store_true",
00164                         dest="supported_ides_html",
00165                         default=False,
00166                         help="writes tools/export/README.md")
00167 
00168     parser.add_argument("--build",
00169                         type=argparse_filestring_type,
00170                         dest="build_dir",
00171                         default=None,
00172                         help="Directory for the exported project files")
00173 
00174     parser.add_argument("--source",
00175                         action="append",
00176                         type=argparse_filestring_type,
00177                         dest="source_dir",
00178                         default=[],
00179                         help="The source (input) directory")
00180 
00181     parser.add_argument("-D",
00182                         action="append",
00183                         dest="macros",
00184                         help="Add a macro definition")
00185 
00186     parser.add_argument("--profile", dest="profile", action="append",
00187                         type=argparse_profile_filestring_type,
00188                         help="Build profile to use. Can be either path to json" \
00189                         "file or one of the default one ({})".format(", ".join(list_profiles())),
00190                         default=[])
00191 
00192     parser.add_argument("--update-packs",
00193                         dest="update_packs",
00194                         action="store_true",
00195                         default=False)
00196     parser.add_argument("--app-config",
00197                         dest="app_config",
00198                         default=None)
00199 
00200     options = parser.parse_args()
00201 
00202     # Print available tests in order and exit
00203     if options.list_tests is True:
00204         print('\n'.join([str(test) for test in  sorted(TEST_MAP.values())]))
00205         sys.exit()
00206 
00207     # Only prints matrix of supported IDEs
00208     if options.supported_ides:
00209         if options.supported_ides == "matrix":
00210             print_large_string(mcu_ide_matrix())
00211         elif options.supported_ides == "ides":
00212             print(mcu_ide_list())
00213         exit(0)
00214 
00215     # Only prints matrix of supported IDEs
00216     if options.supported_ides_html:
00217         html = mcu_ide_matrix(verbose_html=True)
00218         try:
00219             with open("./export/README.md", "w") as readme:
00220                 readme.write("Exporter IDE/Platform Support\n")
00221                 readme.write("-----------------------------------\n")
00222                 readme.write("\n")
00223                 readme.write(html)
00224         except IOError as exc:
00225             print("I/O error({0}): {1}".format(exc.errno, exc.strerror))
00226         except:
00227             print("Unexpected error:", sys.exc_info()[0])
00228             raise
00229         exit(0)
00230 
00231     if options.update_packs:
00232         from tools.arm_pack_manager import Cache
00233         cache = Cache(True, True)
00234         cache.cache_everything()
00235 
00236     # Target
00237     if not options.mcu:
00238         args_error(parser, "argument -m/--mcu is required")
00239 
00240     # Toolchain
00241     if not options.ide:
00242         args_error(parser, "argument -i is required")
00243 
00244     # Clean Export Directory
00245     if options.clean:
00246         if exists(EXPORT_DIR):
00247             rmtree(EXPORT_DIR)
00248 
00249     zip_proj = not bool(options.source_dir)
00250 
00251     notify = TerminalNotifier()
00252 
00253     if (options.program is None) and (not options.source_dir):
00254         args_error(parser, "one of -p, -n, or --source is required")
00255     exporter, toolchain_name = get_exporter_toolchain(options.ide)
00256     mcu = extract_mcus(parser, options)[0]
00257     if not exporter.is_target_supported(mcu):
00258         args_error(parser, "%s not supported by %s"%(mcu,options.ide))
00259     profile = extract_profile(parser, options, toolchain_name, fallback="debug")
00260     if options.clean:
00261         for cls in EXPORTERS.values():
00262             try:
00263                 cls.clean(basename(abspath(options.source_dir[0])))
00264             except (NotImplementedError, IOError, OSError):
00265                 pass
00266         for f in list(EXPORTERS.values())[0].CLEAN_FILES:
00267             try:
00268                 remove(f)
00269             except (IOError, OSError):
00270                 pass
00271     try:
00272         export(mcu, options.ide, build=options.build,
00273                src=options.source_dir, macros=options.macros,
00274                project_id=options.program, zip_proj=zip_proj,
00275                build_profile=profile, app_config=options.app_config,
00276                export_path=options.build_dir, notify = notify)
00277     except NotSupportedException as exc:
00278         print("[ERROR] %s" % str(exc))
00279 
00280 if __name__ == "__main__":
00281     main()