Lee Kai Xuan / mbed-os

Fork of mbed-os by erkin yucel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers build.py Source File

build.py

00001 #! /usr/bin/env python2
00002 """
00003 mbed SDK
00004 Copyright (c) 2011-2013 ARM Limited
00005 
00006 Licensed under the Apache License, Version 2.0 (the "License");
00007 you may not use this file except in compliance with the License.
00008 You may obtain a copy of the License at
00009 
00010     http://www.apache.org/licenses/LICENSE-2.0
00011 
00012 Unless required by applicable law or agreed to in writing, software
00013 distributed under the License is distributed on an "AS IS" BASIS,
00014 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 See the License for the specific language governing permissions and
00016 limitations under the License.
00017 
00018 LIBRARIES BUILD
00019 """
00020 import sys
00021 from time import time
00022 from os.path import join, abspath, dirname
00023 
00024 
00025 # Be sure that the tools directory is in the search path
00026 ROOT = abspath(join(dirname(__file__), ".."))
00027 sys.path.insert(0, ROOT)
00028 
00029 
00030 from tools.toolchains import TOOLCHAINS, TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
00031 from tools.toolchains import mbedToolchain
00032 from tools.targets import TARGET_NAMES, TARGET_MAP
00033 from tools.options import get_default_options_parser
00034 from tools.options import extract_profile
00035 from tools.build_api import build_library, build_mbed_libs, build_lib
00036 from tools.build_api import mcu_toolchain_matrix
00037 from tools.build_api import static_analysis_scan, static_analysis_scan_lib, static_analysis_scan_library
00038 from tools.build_api import print_build_results
00039 from tools.settings import CPPCHECK_CMD, CPPCHECK_MSG_FORMAT
00040 from utils import argparse_filestring_type, args_error
00041 from tools.settings import CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, CLI_COLOR_MAP
00042 from utils import argparse_filestring_type, argparse_dir_not_parent
00043 
00044 if __name__ == '__main__':
00045     start = time()
00046 
00047     # Parse Options
00048     parser = get_default_options_parser()
00049 
00050     parser.add_argument("--source", dest="source_dir", type=argparse_filestring_type,
00051                         default=None, help="The source (input) directory", action="append")
00052 
00053     parser.add_argument("--build", dest="build_dir", type=argparse_dir_not_parent(ROOT),
00054                       default=None, help="The build (output) directory")
00055 
00056     parser.add_argument("--no-archive", dest="no_archive", action="store_true",
00057                       default=False, help="Do not produce archive (.ar) file, but rather .o")
00058 
00059     # Extra libraries
00060     parser.add_argument("-r", "--rtos",
00061                       action="store_true",
00062                       dest="rtos",
00063                       default=False,
00064                       help="Compile the rtos")
00065 
00066     parser.add_argument("--rpc",
00067                       action="store_true",
00068                       dest="rpc",
00069                       default=False,
00070                       help="Compile the rpc library")
00071 
00072     parser.add_argument("-e", "--eth",
00073                       action="store_true", dest="eth",
00074                       default=False,
00075                       help="Compile the ethernet library")
00076 
00077     parser.add_argument("-U", "--usb_host",
00078                       action="store_true",
00079                       dest="usb_host",
00080                       default=False,
00081                       help="Compile the USB Host library")
00082 
00083     parser.add_argument("-u", "--usb",
00084                       action="store_true",
00085                       dest="usb",
00086                       default=False,
00087                       help="Compile the USB Device library")
00088 
00089     parser.add_argument("-d", "--dsp",
00090                       action="store_true",
00091                       dest="dsp",
00092                       default=False,
00093                       help="Compile the DSP library")
00094 
00095     parser.add_argument("-F", "--fat",
00096                       action="store_true",
00097                       dest="fat",
00098                       default=False,
00099                       help="Compile FS and SD card file system library")
00100 
00101     parser.add_argument("-b", "--ublox",
00102                       action="store_true",
00103                       dest="ublox",
00104                       default=False,
00105                       help="Compile the u-blox library")
00106 
00107     parser.add_argument( "--cpputest",
00108                       action="store_true",
00109                       dest="cpputest_lib",
00110                       default=False,
00111                       help="Compiles 'cpputest' unit test library (library should be on the same directory level as mbed repository)")
00112 
00113     parser.add_argument("-D",
00114                       action="append",
00115                       dest="macros",
00116                       help="Add a macro definition")
00117 
00118     parser.add_argument("-S", "--supported-toolchains",
00119                       action="store_true",
00120                       dest="supported_toolchains",
00121                       default=False,
00122                       help="Displays supported matrix of MCUs and toolchains")
00123 
00124     parser.add_argument('-f', '--filter',
00125                       dest='general_filter_regex',
00126                       default=None,
00127                       help='For some commands you can use filter to filter out results')
00128 
00129     parser.add_argument("--cppcheck",
00130                       action="store_true",
00131                       dest="cppcheck_validation",
00132                       default=False,
00133                       help="Forces 'cppcheck' static code analysis")
00134 
00135     parser.add_argument("-j", "--jobs", type=int, dest="jobs",
00136                       default=0, help="Number of concurrent jobs. Default: 0/auto (based on host machine's number of CPUs)")
00137     parser.add_argument("-N", "--artifact-name", dest="artifact_name",
00138                       default=None, help="The built project's name")
00139 
00140     parser.add_argument("-v", "--verbose",
00141                       action="store_true",
00142                       dest="verbose",
00143                       default=False,
00144                       help="Verbose diagnostic output")
00145 
00146     parser.add_argument("--silent",
00147                       action="store_true",
00148                       dest="silent",
00149                       default=False,
00150                       help="Silent diagnostic output (no copy, compile notification)")
00151 
00152     parser.add_argument("-x", "--extra-verbose-notifications",
00153                       action="store_true",
00154                       dest="extra_verbose_notify",
00155                       default=False,
00156                       help="Makes compiler more verbose, CI friendly.")
00157 
00158     options = parser.parse_args()
00159 
00160     # Only prints matrix of supported toolchains
00161     if options.supported_toolchains:
00162         print mcu_toolchain_matrix(platform_filter=options.general_filter_regex)
00163         exit(0)
00164 
00165 
00166     # Get target list
00167     targets = options.mcu if options.mcu else TARGET_NAMES
00168 
00169     # Get toolchains list
00170     toolchains = options.tool if options.tool else TOOLCHAINS
00171 
00172     if options.source_dir and not options.build_dir:
00173         args_error(parser, "argument --build is required by argument --source")
00174 
00175     if options.color:
00176         # This import happens late to prevent initializing colorization when we don't need it
00177         import colorize
00178         if options.verbose:
00179             notify = mbedToolchain.print_notify_verbose
00180         else:
00181             notify = mbedToolchain.print_notify
00182         notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify)
00183     else:
00184         notify = None
00185 
00186     # Get libraries list
00187     libraries = []
00188 
00189     # Additional Libraries
00190     if options.rtos:
00191         libraries.extend(["rtx", "rtos"])
00192     if options.rpc:
00193         libraries.extend(["rpc"])
00194     if options.eth:
00195         libraries.append("eth")
00196     if options.usb:
00197         libraries.append("usb")
00198     if options.usb_host:
00199         libraries.append("usb_host")
00200     if options.dsp:
00201         libraries.extend(["dsp"])
00202     if options.fat:
00203         libraries.extend(["fat"])
00204     if options.ublox:
00205         libraries.extend(["rtx", "rtos", "usb_host", "ublox"])
00206     if options.cpputest_lib:
00207         libraries.extend(["cpputest"])
00208 
00209     # Build results
00210     failures = []
00211     successes = []
00212     skipped = []
00213 
00214     # CPPCHECK code validation
00215     if options.cppcheck_validation:
00216         for toolchain in toolchains:
00217             if not TOOLCHAIN_CLASSES[toolchain].check_executable():
00218                 search_path = TOOLCHAIN_PATHS[toolchain] or "No path set"
00219                 args_error(parser, "Could not find executable for %s.\n"
00220                                    "Currently set search path: %s"
00221                            % (toolchain, search_path))
00222             for target in targets:
00223                 try:
00224                     mcu = TARGET_MAP[target]
00225                     # CMSIS and MBED libs analysis
00226                     profile = extract_profile(parser, options, toolchain)
00227                     static_analysis_scan(
00228                         mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT,
00229                         verbose=options.verbose, jobs=options.jobs,
00230                         build_profile=profile)
00231                     for lib_id in libraries:
00232                         # Static check for library
00233                         static_analysis_scan_lib(
00234                             lib_id, mcu, toolchain, CPPCHECK_CMD,
00235                             CPPCHECK_MSG_FORMAT,
00236                             extra_verbose=options.extra_verbose_notify,
00237                             verbose=options.verbose, jobs=options.jobs,
00238                             clean=options.clean, macros=options.macros,
00239                             build_profile=profile)
00240                         pass
00241                 except Exception, e:
00242                     if options.verbose:
00243                         import traceback
00244                         traceback.print_exc(file=sys.stdout)
00245                         sys.exit(1)
00246                     print e
00247     else:
00248         # Build
00249         for toolchain in toolchains:
00250             for target in targets:
00251                 tt_id = "%s::%s" % (toolchain, target)
00252                 if toolchain not in TARGET_MAP[target].supported_toolchains:
00253                     # Log this later
00254                     print "%s skipped: toolchain not supported" % tt_id
00255                     skipped.append(tt_id)
00256                 else:
00257                     try:
00258                         mcu = TARGET_MAP[target]
00259                         profile = extract_profile(parser, options, toolchain)
00260                         if options.source_dir:
00261                             lib_build_res = build_library(options.source_dir, options.build_dir, mcu, toolchain,
00262                                                         extra_verbose=options.extra_verbose_notify,
00263                                                         verbose=options.verbose,
00264                                                         silent=options.silent,
00265                                                         jobs=options.jobs,
00266                                                         clean=options.clean,
00267                                                         archive=(not options.no_archive),
00268                                                         macros=options.macros,
00269                                                         name=options.artifact_name,
00270                                                         build_profile=profile)
00271                         else:
00272                             lib_build_res = build_mbed_libs(mcu, toolchain,
00273                                                         extra_verbose=options.extra_verbose_notify,
00274                                                         verbose=options.verbose,
00275                                                         silent=options.silent,
00276                                                         jobs=options.jobs,
00277                                                         clean=options.clean,
00278                                                             macros=options.macros,
00279                                                             build_profile=profile)
00280 
00281                         for lib_id in libraries:
00282                             build_lib(lib_id, mcu, toolchain,
00283                                     extra_verbose=options.extra_verbose_notify,
00284                                     verbose=options.verbose,
00285                                     silent=options.silent,
00286                                     clean=options.clean,
00287                                     macros=options.macros,
00288                                       jobs=options.jobs,
00289                                       build_profile=profile)
00290                         if lib_build_res:
00291                             successes.append(tt_id)
00292                         else:
00293                             skipped.append(tt_id)
00294                     except Exception, e:
00295                         if options.verbose:
00296                             import traceback
00297                             traceback.print_exc(file=sys.stdout)
00298                             sys.exit(1)
00299                         failures.append(tt_id)
00300                         print e
00301 
00302     # Write summary of the builds
00303     print
00304     print "Completed in: (%.2f)s" % (time() - start)
00305     print
00306 
00307     for report, report_name in [(successes, "Build successes:"),
00308                                 (skipped, "Build skipped:"),
00309                                 (failures, "Build failures:"),
00310                                ]:
00311         if report:
00312             print print_build_results(report, report_name),
00313 
00314     if failures:
00315         sys.exit(1)