Clone of official tools

Revision:
0:66f3b5499f7f
Child:
13:ab47a20b66f0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project.py	Thu May 19 19:44:41 2016 +0100
@@ -0,0 +1,231 @@
+import sys
+from os.path import join, abspath, dirname, exists, basename
+ROOT = abspath(join(dirname(__file__), ".."))
+sys.path.insert(0, ROOT)
+
+from shutil import move, rmtree
+from optparse import OptionParser
+from os import path
+
+from tools.paths import EXPORT_DIR, EXPORT_WORKSPACE, EXPORT_TMP
+from tools.paths import MBED_BASE, MBED_LIBRARIES
+from tools.export import export, setup_user_prj, EXPORTERS, mcu_ide_matrix
+from tools.utils import args_error, mkdir
+from tools.tests import TESTS, Test, TEST_MAP
+from tools.targets import TARGET_NAMES
+from tools.libraries import LIBRARIES
+
+try:
+    import tools.private_settings as ps
+except:
+    ps = object()
+
+
+if __name__ == '__main__':
+    # Parse Options
+    parser = OptionParser()
+
+    targetnames = TARGET_NAMES
+    targetnames.sort()
+    toolchainlist = EXPORTERS.keys()
+    toolchainlist.sort()
+
+    parser.add_option("-m", "--mcu",
+                      metavar="MCU",
+                      default='LPC1768',
+                      help="generate project for the given MCU (%s)"% ', '.join(targetnames))
+
+    parser.add_option("-i",
+                      dest="ide",
+                      default='uvision',
+                      help="The target IDE: %s"% str(toolchainlist))
+
+    parser.add_option("-c", "--clean",
+                      action="store_true",
+                      default=False,
+                      help="clean the export directory")
+
+    parser.add_option("-p",
+                      type="int",
+                      dest="program",
+                      help="The index of the desired test program: [0-%d]"% (len(TESTS)-1))
+
+    parser.add_option("-n",
+                      dest="program_name",
+                      help="The name of the desired test program")
+
+    parser.add_option("-b",
+                      dest="build",
+                      action="store_true",
+                      default=False,
+                      help="use the mbed library build, instead of the sources")
+
+    parser.add_option("-L", "--list-tests",
+                      action="store_true",
+                      dest="list_tests",
+                      default=False,
+                      help="list available programs in order and exit")
+
+    parser.add_option("-S", "--list-matrix",
+                      action="store_true",
+                      dest="supported_ides",
+                      default=False,
+                      help="displays supported matrix of MCUs and IDEs")
+
+    parser.add_option("-E",
+                      action="store_true",
+                      dest="supported_ides_html",
+                      default=False,
+                      help="writes tools/export/README.md")
+
+    parser.add_option("--source",
+                      dest="source_dir",
+                      default=None,
+                      help="The source (input) directory")
+
+    parser.add_option("-D", "",
+                      action="append",
+                      dest="macros",
+                      help="Add a macro definition")
+
+    (options, args) = parser.parse_args()
+
+    # Print available tests in order and exit
+    if options.list_tests is True:
+        print '\n'.join(map(str, sorted(TEST_MAP.values())))
+        sys.exit()
+
+    # Only prints matrix of supported IDEs
+    if options.supported_ides:
+        print mcu_ide_matrix()
+        exit(0)
+
+    # Only prints matrix of supported IDEs
+    if options.supported_ides_html:
+        html = mcu_ide_matrix(verbose_html=True)
+        try:
+            with open("./export/README.md","w") as f:
+                f.write("Exporter IDE/Platform Support\n")
+                f.write("-----------------------------------\n")
+                f.write("\n")
+                f.write(html)
+        except IOError as e:
+            print "I/O error({0}): {1}".format(e.errno, e.strerror)
+        except:
+            print "Unexpected error:", sys.exc_info()[0]
+            raise
+        exit(0)
+
+    # Clean Export Directory
+    if options.clean:
+        if exists(EXPORT_DIR):
+            rmtree(EXPORT_DIR)
+
+    # Target
+    if options.mcu is None :
+        args_error(parser, "[ERROR] You should specify an MCU")
+    mcus = options.mcu
+
+    # IDE
+    if options.ide is None:
+        args_error(parser, "[ERROR] You should specify an IDE")
+    ide = options.ide
+
+    # Export results
+    successes = []
+    failures = []
+    zip = True
+    clean = True
+
+    # source_dir = use relative paths, otherwise sources are copied
+    sources_relative = True if options.source_dir else False
+
+    for mcu in mcus.split(','):
+        # Program Number or name
+        p, n, src, ide = options.program, options.program_name, options.source_dir, options.ide
+
+        if src is not None:
+            # --source is used to generate IDE files to toolchain directly in the source tree and doesn't generate zip file
+            project_dir = options.source_dir
+            project_name = basename(project_dir)
+            project_temp = path.join(options.source_dir, 'projectfiles', ide)
+            mkdir(project_temp)
+            lib_symbols = []
+            if options.macros:
+                lib_symbols += options.macros
+            zip = False   # don't create zip
+            clean = False # don't cleanup because we use the actual source tree to generate IDE files
+        else:
+            if n is not None and p is not None:
+                args_error(parser, "[ERROR] specify either '-n' or '-p', not both")
+            if n:
+                if not n in TEST_MAP.keys():
+                    # Check if there is an alias for this in private_settings.py
+                    if getattr(ps, "test_alias", None) is not None:
+                        alias = ps.test_alias.get(n, "")
+                        if not alias in TEST_MAP.keys():
+                            args_error(parser, "[ERROR] Program with name '%s' not found" % n)
+                        else:
+                            n = alias
+                    else:
+                        args_error(parser, "[ERROR] Program with name '%s' not found" % n)
+                p = TEST_MAP[n].n
+                
+            if p is None or (p < 0) or (p > (len(TESTS)-1)):
+                message = "[ERROR] You have to specify one of the following tests:\n"
+                message += '\n'.join(map(str, sorted(TEST_MAP.values())))
+                args_error(parser, message)
+
+            # Project
+            if p is None or (p < 0) or (p > (len(TESTS)-1)):
+                message = "[ERROR] You have to specify one of the following tests:\n"
+                message += '\n'.join(map(str, sorted(TEST_MAP.values())))
+                args_error(parser, message)
+            test = Test(p)
+
+            # Some libraries have extra macros (called by exporter symbols) to we need to pass
+            # them to maintain compilation macros integrity between compiled library and
+            # header files we might use with it
+            lib_symbols = []
+            if options.macros:
+                lib_symbols += options.macros
+            for lib in LIBRARIES:
+                if lib['build_dir'] in test.dependencies:
+                    lib_macros = lib.get('macros', None)
+                    if lib_macros is not None:
+                        lib_symbols.extend(lib_macros)
+
+            if not options.build:
+                # Substitute the library builds with the sources
+                # TODO: Substitute also the other library build paths
+                if MBED_LIBRARIES in test.dependencies:
+                    test.dependencies.remove(MBED_LIBRARIES)
+                    test.dependencies.append(MBED_BASE)
+
+            # Build the project with the same directory structure of the mbed online IDE
+            project_name = test.id
+            project_dir = join(EXPORT_WORKSPACE, project_name)
+            project_temp = EXPORT_TMP
+            setup_user_prj(project_dir, test.source_dir, test.dependencies)
+
+        # Export to selected toolchain
+        tmp_path, report = export(project_dir, project_name, ide, mcu, project_dir, project_temp, clean=clean, zip=zip, extra_symbols=lib_symbols, relative=sources_relative)
+        print tmp_path
+        if report['success']:
+            zip_path = join(EXPORT_DIR, "%s_%s_%s.zip" % (project_name, ide, mcu))
+            if zip:
+                move(tmp_path, zip_path)
+            successes.append("%s::%s\t%s"% (mcu, ide, zip_path))
+        else:
+            failures.append("%s::%s\t%s"% (mcu, ide, report['errormsg']))
+
+    # Prints export results
+    print
+    if len(successes) > 0:
+        print "Successful exports:"
+        for success in successes:
+            print "  * %s"% success
+    if len(failures) > 0:
+        print "Failed exports:"
+        for failure in failures:
+            print "  * %s"% failure