def do_run(self, args, ignored): self.args = args # Avoid having to pass them around log.dbg('args:', args, level=log.VERBOSE_EXTREME) self._sanity_precheck() self._setup_build_dir() if is_zephyr_build(self.build_dir): self._update_cache() if self.args.cmake or self.args.cmake_opts: self.run_cmake = True else: self.run_cmake = True self._setup_source_dir() self._sanity_check() log.inf('source directory: {}'.format(self.source_dir), colorize=True) log.inf('build directory: {}{}'. format(self.build_dir, (' (created)' if self.created_build_dir else '')), colorize=True) if self.cmake_cache: board = self.cmake_cache.get('CACHED_BOARD') elif self.args.board: board = self.args.board else: board = 'UNKNOWN' # shouldn't happen log.inf('BOARD:', board, colorize=True) self._run_cmake(self.args.cmake_opts) self._sanity_check() self._update_cache() extra_args = ['--target', args.target] if args.target else [] cmake.run_build(self.build_dir, extra_args=extra_args)
def do_run(self, args, remainder): self.args = args # Avoid having to pass them around log.dbg('args: {} remainder: {}'.format(args, remainder, level=log.VERBOSE_EXTREME)) # Store legacy -s option locally source_dir = self.args.source_dir self._parse_remainder(remainder) if source_dir: if self.args.source_dir: log.die("source directory specified twice:({} and {})".format( source_dir, self.args.source_dir)) self.args.source_dir = source_dir log.dbg('source_dir: {} cmake_opts: {}'.format(self.args.source_dir, self.args.cmake_opts)) self._sanity_precheck() self._setup_build_dir() if is_zephyr_build(self.build_dir): self._update_cache() if self.args.cmake or self.args.cmake_opts: self.run_cmake = True else: self.run_cmake = True self._setup_source_dir() self._sanity_check() log.inf('source directory: {}'.format(self.source_dir), colorize=True) log.inf('build directory: {}{}'.format( self.build_dir, (' (created)' if self.created_build_dir else '')), colorize=True) if self.cmake_cache: board = self.cmake_cache.get('CACHED_BOARD') elif self.args.board: board = self.args.board else: board = 'UNKNOWN' # shouldn't happen log.inf('BOARD:', board, colorize=True) self._run_cmake(self.args.cmake_opts) self._sanity_check() self._update_cache() extra_args = ['--target', args.target] if args.target else [] cmake.run_build(self.build_dir, extra_args=extra_args)
def _dump_context(command, args, runner_args, cached_runner_var): build_dir = _build_dir(args, die_if_none=False) # Try to figure out the CMake cache file based on the build # directory or an explicit argument. if build_dir is not None: cache_file = path.abspath( path.join(build_dir, args.cmake_cache or cmake.DEFAULT_CACHE)) elif args.cmake_cache: cache_file = path.abspath(args.cmake_cache) else: cache_file = None # Load the cache itself, if possible. if cache_file is None: log.wrn('No build directory (--build-dir) or CMake cache ' '(--cache-file) given or found; output will be limited') cache = None else: try: cache = cmake.CMakeCache(cache_file) except Exception: log.die('Cannot load cache {}.'.format(cache_file)) # If we have a build directory, try to ensure build artifacts are # up to date. If that doesn't work, still try to print information # on a best-effort basis. if build_dir and not args.skip_rebuild: try: cmake.run_build(build_dir) except CalledProcessError: msg = 'Failed re-building application; cannot load context. ' if args.build_dir: msg += 'Is {} the right --build-dir?'.format(args.build_dir) else: msg += textwrap.dedent('''\ Use --build-dir (-d) to specify a build directory; the one used was {}.'''.format(build_dir)) log.die('\n'.join( textwrap.wrap(msg, initial_indent='', subsequent_indent=INDENT, break_on_hyphens=False))) if cache is None: _dump_no_context_info(command, args) if not args.runner: return if args.runner: # Just information on one runner was requested. _dump_one_runner_info(cache, args, build_dir, INDENT) return board = cache['CACHED_BOARD'] all_cls = { cls.name(): cls for cls in ZephyrBinaryRunner.get_runners() if command.name in cls.capabilities().commands } available = [r for r in cache.get_list('ZEPHYR_RUNNERS') if r in all_cls] available_cls = {r: all_cls[r] for r in available if r in all_cls} default_runner = cache.get(cached_runner_var) cfg = cached_runner_config(build_dir, cache) log.inf('All Zephyr runners which support {}:'.format(command.name), colorize=True) for line in util.wrap(', '.join(all_cls.keys()), INDENT): log.inf(line) log.inf('(Not all may work with this build, see available runners below.)', colorize=True) if cache is None: log.warn('Missing or invalid CMake cache {}; there is no context.', 'Use --build-dir to specify the build directory.') return log.inf('Build directory:', colorize=True) log.inf(INDENT + build_dir) log.inf('Board:', colorize=True) log.inf(INDENT + board) log.inf('CMake cache:', colorize=True) log.inf(INDENT + cache_file) if not available: # Bail with a message if no runners are available. msg = ('No runners available for {}. ' 'Consult the documentation for instructions on how to run ' 'binaries on this target.').format(board) for line in util.wrap(msg, ''): log.inf(line, colorize=True) return log.inf('Available {} runners:'.format(command.name), colorize=True) log.inf(INDENT + ', '.join(available)) log.inf('Additional options for available', command.name, 'runners:', colorize=True) for runner in available: _dump_runner_opt_help(runner, all_cls[runner]) log.inf('Default {} runner:'.format(command.name), colorize=True) log.inf(INDENT + default_runner) _dump_runner_config(cfg, '', INDENT) log.inf('Runner-specific information:', colorize=True) for runner in available: log.inf('{}{}:'.format(INDENT, runner), colorize=True) _dump_runner_cached_opts(cache, runner, INDENT * 2, INDENT * 3) _dump_runner_caps(available_cls[runner], INDENT * 2) if len(available) > 1: log.inf('(Add -r RUNNER to just print information about one runner.)', colorize=True)
def do_run_common(command, args, runner_args, cached_runner_var): if args.context: _dump_context(command, args, runner_args, cached_runner_var) return command_name = command.name build_dir = _build_dir(args) if not args.skip_rebuild: try: cmake.run_build(build_dir) except CalledProcessError: if args.build_dir: log.die('cannot run {}, build in {} failed'.format( command_name, args.build_dir)) else: log.die('cannot run {}; no --build-dir given and build in ' 'current directory {} failed'.format( command_name, build_dir)) # Runner creation, phase 1. # # Get the default runner name from the cache, allowing a command # line override. Get the ZephyrBinaryRunner class by name, and # make sure it supports the command. cache_file = path.join(build_dir, args.cmake_cache or cmake.DEFAULT_CACHE) cache = cmake.CMakeCache(cache_file) board = cache['CACHED_BOARD'] available = cache.get_list('ZEPHYR_RUNNERS') if not available: log.wrn('No cached runners are available in', cache_file) runner = args.runner or cache.get(cached_runner_var) if runner is None: raise CommandContextError( textwrap.dedent(""" No {} runner available for {}. Please either specify one manually, or check your board's documentation for alternative instructions.""".format(command_name, board))) log.inf('Using runner:', runner) if runner not in available: log.wrn('Runner {} is not configured for use with {}, ' 'this may not work'.format(runner, board)) runner_cls = get_runner_cls(runner) if command_name not in runner_cls.capabilities().commands: log.die('Runner {} does not support command {}'.format( runner, command_name)) # Runner creation, phase 2. # # At this point, the common options above are already parsed in # 'args', and unrecognized arguments are in 'runner_args'. # # - Pull the RunnerConfig out of the cache # - Override cached values with applicable command-line options cfg = cached_runner_config(build_dir, cache) _override_config_from_namespace(cfg, args) # Runner creation, phase 3. # # - Pull out cached runner arguments, and append command-line # values (which should override the cache) # - Construct a runner-specific argument parser to handle cached # values plus overrides given in runner_args # - Parse arguments and create runner instance from final # RunnerConfig and parsed arguments. cached_runner_args = cache.get_list('ZEPHYR_RUNNER_ARGS_{}'.format( cmake.make_c_identifier(runner))) assert isinstance(runner_args, list), runner_args # If the user passed -- to force the parent argument parser to stop # parsing, it will show up here, and needs to be filtered out. runner_args = [arg for arg in runner_args if arg != '--'] final_runner_args = cached_runner_args + runner_args parser = argparse.ArgumentParser(prog=runner) runner_cls.add_parser(parser) parsed_args, unknown = parser.parse_known_args(args=final_runner_args) if unknown: raise CommandContextError('Runner', runner, 'received unknown arguments', unknown) runner = runner_cls.create(cfg, parsed_args) runner.run(command_name)
def _run_build(self, target): extra_args = ['--target', target] if target else [] cmake.run_build(self.build_dir, extra_args=extra_args)
def do_run_common(command, args, runner_args, cached_runner_var): if args.context: _dump_context(command, args, runner_args, cached_runner_var) return command_name = command.name build_dir = _build_dir(args) if not args.skip_rebuild: _banner('west {}: rebuilding'.format(command_name)) try: cmake.run_build(build_dir) except CalledProcessError: if args.build_dir: log.die('cannot run {}, build in {} failed'.format( command_name, args.build_dir)) else: log.die('cannot run {}; no --build-dir given and build in ' 'current directory {} failed'.format( command_name, build_dir)) # Runner creation, phase 1. # # Get the default runner name from the cache, allowing a command # line override. Get the ZephyrBinaryRunner class by name, and # make sure it supports the command. cache_file = path.join(build_dir, args.cmake_cache or cmake.DEFAULT_CACHE) try: cache = cmake.CMakeCache(cache_file) except FileNotFoundError: log.die('no CMake cache found (expected one at {})'.format(cache_file)) board = cache['CACHED_BOARD'] available = cache.get_list('ZEPHYR_RUNNERS') if not available: log.wrn('No cached runners are available in', cache_file) runner = args.runner or cache.get(cached_runner_var) if runner is None: log.die('No', command_name, 'runner available for board', board, '({} is not in the cache).'.format(cached_runner_var), "Check your board's documentation for instructions.") _banner('west {}: using runner {}'.format(command_name, runner)) if runner not in available: log.wrn('Runner {} is not configured for use with {}, ' 'this may not work'.format(runner, board)) runner_cls = get_runner_cls(runner) if command_name not in runner_cls.capabilities().commands: log.die('Runner {} does not support command {}'.format( runner, command_name)) # Runner creation, phase 2. # # At this point, the common options above are already parsed in # 'args', and unrecognized arguments are in 'runner_args'. # # - Set up runner logging to delegate to west. # - Pull the RunnerConfig out of the cache # - Override cached values with applicable command-line options logger = logging.getLogger('runners') logger.setLevel(LOG_LEVEL) logger.addHandler(WestLogHandler()) cfg = cached_runner_config(build_dir, cache) _override_config_from_namespace(cfg, args) # Runner creation, phase 3. # # - Pull out cached runner arguments, and append command-line # values (which should override the cache) # - Construct a runner-specific argument parser to handle cached # values plus overrides given in runner_args # - Parse arguments and create runner instance from final # RunnerConfig and parsed arguments. cached_runner_args = cache.get_list('ZEPHYR_RUNNER_ARGS_{}'.format( cmake.make_c_identifier(runner))) assert isinstance(runner_args, list), runner_args # If the user passed -- to force the parent argument parser to stop # parsing, it will show up here, and needs to be filtered out. runner_args = [arg for arg in runner_args if arg != '--'] final_runner_args = cached_runner_args + runner_args parser = argparse.ArgumentParser(prog=runner) runner_cls.add_parser(parser) parsed_args, unknown = parser.parse_known_args(args=final_runner_args) if unknown: log.die('Runner', runner, 'received unknown arguments:', unknown) runner = runner_cls.create(cfg, parsed_args) try: runner.run(command_name) except ValueError as ve: log.err(str(ve), fatal=True) dump_traceback() raise CommandError(1) except MissingProgram as e: log.die('required program', e.filename, 'not found; install it or add its location to PATH')