Daniel Vizcaya / Mbed OS 04_RTOS_Embebidos
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, ignore=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     ignore - list of paths to add to mbedignore
00091 
00092     Returns an object of type Exporter (tools/exports/exporters.py)
00093     """
00094     project_dir, name, src, lib = setup_project(ide, target, program=project_id,
00095                                                 source_dir=src, build=build, export_path=export_path)
00096 
00097     zip_name = name+".zip" if zip_proj else None
00098 
00099     return export_project(src, project_dir, target, ide, name=name,
00100                           macros=macros, libraries_paths=lib, zip_proj=zip_name,
00101                           build_profile=build_profile, notify=notify,
00102                           app_config=app_config, ignore=ignore)
00103 
00104 
00105 def main ():
00106     """Entry point"""
00107     # Parse Options
00108     parser = ArgumentParser()
00109 
00110     targetnames = TARGET_NAMES
00111     targetnames.sort()
00112     toolchainlist = list(EXPORTERS.keys())
00113     toolchainlist.sort()
00114 
00115     parser.add_argument("-m", "--mcu",
00116                         metavar="MCU",
00117                         help="generate project for the given MCU ({})".format(
00118                             ', '.join(targetnames)))
00119 
00120     parser.add_argument("-i",
00121                         dest="ide",
00122                         type=argparse_force_lowercase_type(
00123                             toolchainlist, "toolchain"),
00124                         help="The target IDE: %s"% str(toolchainlist))
00125 
00126     parser.add_argument("-c", "--clean",
00127                         action="store_true",
00128                         default=False,
00129                         help="clean the export directory")
00130 
00131     group = parser.add_mutually_exclusive_group(required=False)
00132     group.add_argument(
00133         "-p",
00134         type=test_known,
00135         dest="program",
00136         help="The index of the desired test program: [0-%s]"% (len(TESTS)-1))
00137 
00138     group.add_argument("-n",
00139                        type=test_name_known,
00140                        dest="program",
00141                        help="The name of the desired test program")
00142 
00143     parser.add_argument("-b",
00144                       dest="build",
00145                       default=False,
00146                       action="store_true",
00147                       help="use the mbed library build, instead of the sources")
00148 
00149     group.add_argument("-L", "--list-tests",
00150                        action="store_true",
00151                        dest="list_tests",
00152                        default=False,
00153                        help="list available programs in order and exit")
00154 
00155     group.add_argument("-S", "--list-matrix",
00156                        dest="supported_ides",
00157                        default=False,
00158                        const="matrix",
00159                        choices=["matrix", "ides"],
00160                        nargs="?",
00161                        help="displays supported matrix of MCUs and IDEs")
00162 
00163     parser.add_argument("-E",
00164                         action="store_true",
00165                         dest="supported_ides_html",
00166                         default=False,
00167                         help="writes tools/export/README.md")
00168 
00169     parser.add_argument("--build",
00170                         type=argparse_filestring_type,
00171                         dest="build_dir",
00172                         default=None,
00173                         help="Directory for the exported project files")
00174 
00175     parser.add_argument("--source",
00176                         action="append",
00177                         type=argparse_filestring_type,
00178                         dest="source_dir",
00179                         default=[],
00180                         help="The source (input) directory")
00181 
00182     parser.add_argument("-D",
00183                         action="append",
00184                         dest="macros",
00185                         help="Add a macro definition")
00186 
00187     parser.add_argument("--profile", dest="profile", action="append",
00188                         type=argparse_profile_filestring_type,
00189                         help="Build profile to use. Can be either path to json" \
00190                         "file or one of the default one ({})".format(", ".join(list_profiles())),
00191                         default=[])
00192 
00193     parser.add_argument("--update-packs",
00194                         dest="update_packs",
00195                         action="store_true",
00196                         default=False)
00197     parser.add_argument("--app-config",
00198                         dest="app_config",
00199                         default=None)
00200 
00201     parser.add_argument("--ignore", dest="ignore", type=argparse_many(str),
00202                         default=None, help="Comma separated list of patterns to add to mbedignore (eg. ./main.cpp)")
00203 
00204     options = parser.parse_args()
00205 
00206     # Print available tests in order and exit
00207     if options.list_tests is True:
00208         print('\n'.join([str(test) for test in  sorted(TEST_MAP.values())]))
00209         sys.exit()
00210 
00211     # Only prints matrix of supported IDEs
00212     if options.supported_ides:
00213         if options.supported_ides == "matrix":
00214             print_large_string(mcu_ide_matrix())
00215         elif options.supported_ides == "ides":
00216             print(mcu_ide_list())
00217         exit(0)
00218 
00219     # Only prints matrix of supported IDEs
00220     if options.supported_ides_html:
00221         html = mcu_ide_matrix(verbose_html=True)
00222         try:
00223             with open("./export/README.md", "w") as readme:
00224                 readme.write("Exporter IDE/Platform Support\n")
00225                 readme.write("-----------------------------------\n")
00226                 readme.write("\n")
00227                 readme.write(html)
00228         except IOError as exc:
00229             print("I/O error({0}): {1}".format(exc.errno, exc.strerror))
00230         except:
00231             print("Unexpected error:", sys.exc_info()[0])
00232             raise
00233         exit(0)
00234 
00235     if options.update_packs:
00236         from tools.arm_pack_manager import Cache
00237         cache = Cache(True, True)
00238         cache.cache_everything()
00239 
00240     # Target
00241     if not options.mcu:
00242         args_error(parser, "argument -m/--mcu is required")
00243 
00244     # Toolchain
00245     if not options.ide:
00246         args_error(parser, "argument -i is required")
00247 
00248     # Clean Export Directory
00249     if options.clean:
00250         if exists(EXPORT_DIR):
00251             rmtree(EXPORT_DIR)
00252 
00253     zip_proj = not bool(options.source_dir)
00254 
00255     notify = TerminalNotifier()
00256 
00257     if (options.program is None) and (not options.source_dir):
00258         args_error(parser, "one of -p, -n, or --source is required")
00259     exporter, toolchain_name = get_exporter_toolchain(options.ide)
00260     mcu = extract_mcus(parser, options)[0]
00261     if not exporter.is_target_supported(mcu):
00262         args_error(parser, "%s not supported by %s"%(mcu,options.ide))
00263     profile = extract_profile(parser, options, toolchain_name, fallback="debug")
00264     if options.clean:
00265         for cls in EXPORTERS.values():
00266             try:
00267                 cls.clean(basename(abspath(options.source_dir[0])))
00268             except (NotImplementedError, IOError, OSError):
00269                 pass
00270         for f in list(EXPORTERS.values())[0].CLEAN_FILES:
00271             try:
00272                 remove(f)
00273             except (IOError, OSError):
00274                 pass
00275     try:
00276         export(mcu, options.ide, build=options.build,
00277                src=options.source_dir, macros=options.macros,
00278                project_id=options.program, zip_proj=zip_proj,
00279                build_profile=profile, app_config=options.app_config,
00280                export_path=options.build_dir, notify=notify,
00281                ignore=options.ignore)
00282     except NotSupportedException as exc:
00283         print("[ERROR] %s" % str(exc))
00284 
00285 if __name__ == "__main__":
00286     main()