def _build_dir(args, die_if_none=True): # Get the build directory for the given argument list and environment. if args.build_dir: return args.build_dir cwd = getcwd() default = path.join(cwd, DEFAULT_BUILD_DIR) if is_zephyr_build(default): return default elif is_zephyr_build(cwd): return cwd elif die_if_none: log.die('--build-dir was not given, and neither {} ' 'nor {} are zephyr build directories.'.format(default, cwd)) else: return None
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 find_build_dir(dir): '''Heuristic for finding a build directory. If the given argument is truthy, it is returned. Otherwise, if the current working directory is a build directory, it is returned. Otherwise, west.build.DEFAULT_BUILD_DIR is returned.''' if dir: build_dir = dir else: cwd = os.getcwd() if is_zephyr_build(cwd): build_dir = cwd else: build_dir = DEFAULT_BUILD_DIR return os.path.abspath(build_dir)
def do_run(self, args, ignored): self.args = args # for check_force # Find the build directory and parse .config and DT. build_dir = find_build_dir(args.build_dir) self.check_force(os.path.isdir(build_dir), 'no such build directory {}'.format(build_dir)) self.check_force( is_zephyr_build(build_dir), "build directory {} doesn't look like a Zephyr build " 'directory'.format(build_dir)) bcfg = BuildConfiguration(build_dir) # Decide on output formats. formats = [] bin_exists = 'CONFIG_BUILD_OUTPUT_BIN' in bcfg if args.gen_bin: self.check_force( bin_exists, '--bin given but CONFIG_BUILD_OUTPUT_BIN not set ' "in build directory's ({}) .config".format(build_dir)) formats.append('bin') elif args.gen_bin is None and bin_exists: formats.append('bin') hex_exists = 'CONFIG_BUILD_OUTPUT_HEX' in bcfg if args.gen_hex: self.check_force( hex_exists, '--hex given but CONFIG_BUILD_OUTPUT_HEX not set ' "in build directory's ({}) .config".format(build_dir)) formats.append('hex') elif args.gen_hex is None and hex_exists: formats.append('hex') if not formats: log.dbg('nothing to do: no output files') return # Delegate to the signer. if args.tool == 'imgtool': signer = ImgtoolSigner() elif args.tool == 'rimage': signer = RimageSigner() # (Add support for other signers here in elif blocks) else: raise RuntimeError("can't happen") signer.sign(self, build_dir, bcfg, formats)
def _sanity_check_source_dir(self): if self.source_dir == self.build_dir: # There's no forcing this. log.die('source and build directory {} cannot be the same; ' 'use --build-dir {} to specify a build directory'.format( self.source_dir, self.build_dir)) srcrel = os.path.relpath(self.source_dir) self.check_force( not is_zephyr_build(self.source_dir), 'it looks like {srcrel} is a build directory: ' 'did you mean --build-dir {srcrel} instead?'.format(srcrel=srcrel)) self.check_force( 'CMakeLists.txt' in os.listdir(self.source_dir), 'source directory "{srcrel}" does not contain ' 'a CMakeLists.txt; is this really what you ' 'want to build? (Use -s SOURCE_DIR to specify ' 'the application source directory)'.format(srcrel=srcrel))
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 _run_pristine(self): log.inf('Making build dir {} pristine'.format(self.build_dir)) zb = os.environ.get('ZEPHYR_BASE') if not zb: log.die('Internal error: ZEPHYR_BASE not set in the environment, ' 'and should have been by the main script') if not is_zephyr_build(self.build_dir): log.die('Refusing to run pristine on a folder that is not a ' 'Zephyr build system') cmake_args = ['-P', '{}/cmake/pristine.cmake'.format(zb)] cmake = shutil.which('cmake') if cmake is None: log.die('CMake is not installed or cannot be found; cannot make ' 'the build folder pristine') cmd = [cmake] + cmake_args subprocess.check_call(cmd, cwd=self.build_dir)
def do_run(self, args, ignored): if not (args.gen_bin or args.gen_hex): return self.check_force(os.path.isdir(args.build_dir), 'no such build directory {}'.format(args.build_dir)) self.check_force(is_zephyr_build(args.build_dir), "build directory {} doesn't look like a Zephyr build " 'directory'.format(args.build_dir)) if args.tool == 'imgtool': signer = ImgtoolSigner() # (Add support for other signers here in elif blocks) else: raise RuntimeError("can't happen") # Provide the build directory if not given, and defer to the signer. args.build_dir = find_build_dir(args.build_dir) signer.sign(args)
def _setup_build_dir(self): # Initialize build_dir and created_build_dir attributes. log.dbg('setting up build directory', level=log.VERBOSE_EXTREME) if self.args.build_dir: build_dir = self.args.build_dir else: cwd = os.getcwd() if is_zephyr_build(cwd): build_dir = cwd else: build_dir = DEFAULT_BUILD_DIR build_dir = os.path.abspath(build_dir) if os.path.exists(build_dir): if not os.path.isdir(build_dir): log.die('build directory {} exists and is not a directory'. format(build_dir)) else: os.makedirs(build_dir, exist_ok=False) self.created_build_dir = True self.run_cmake = True self.build_dir = build_dir
def _sanity_check(self): # Sanity check the build configuration. # Side effect: may update cmake_cache attribute. log.dbg('sanity checking the build', level=log.VERBOSE_EXTREME) self._sanity_check_source_dir() self.check_force( is_zephyr_build(self.build_dir) or self.args.board, 'this looks like a new or clean build, please provide --board') if not self.cmake_cache: return # That's all we can check without a cache. cached_app = self.cmake_cache.get('APPLICATION_SOURCE_DIR') log.dbg('APPLICATION_SOURCE_DIR:', cached_app, level=log.VERBOSE_EXTREME) source_abs = (os.path.abspath(self.args.source_dir) if self.args.source_dir else None) cached_abs = os.path.abspath(cached_app) if cached_app else None log.dbg('pristine:', self.auto_pristine, level=log.VERBOSE_EXTREME) # If the build directory specifies a source app, make sure it's # consistent with --source-dir. apps_mismatched = (source_abs and cached_abs and source_abs != cached_abs) self.check_force( not apps_mismatched or self.auto_pristine, 'Build directory "{}" is for application "{}", but source ' 'directory "{}" was specified; please clean it, use --pristine, ' 'or use --build-dir to set another build directory'. format(self.build_dir, cached_abs, source_abs)) if apps_mismatched: self.run_cmake = True # If they insist, we need to re-run cmake. # If CACHED_BOARD is not defined, we need --board from the # command line. cached_board = self.cmake_cache.get('CACHED_BOARD') log.dbg('CACHED_BOARD:', cached_board, level=log.VERBOSE_EXTREME) # If app_mismatched and pristine are true we will run pristine on the # build, invalidating the cached board. Whenever we run pristine we # require the user to provide all the require inputs again. self.check_force((cached_board and not (apps_mismatched and self.auto_pristine)) or self.args.board, 'Cached board not defined, please provide --board') # Check consistency between cached board and --board. boards_mismatched = (self.args.board and cached_board and self.args.board != cached_board) self.check_force( not boards_mismatched or self.auto_pristine, 'Build directory {} targets board {}, but board {} was specified. ' '(Clean the directory, use --pristine, or use --build-dir to ' 'specify a different one.)'. format(self.build_dir, cached_board, self.args.board)) if self.auto_pristine and (apps_mismatched or boards_mismatched): log.inf('Making build dir {} pristine'.format(self.build_dir)) self._run_build('pristine') self.cmake_cache = None log.dbg('run_cmake:', True, level=log.VERBOSE_EXTREME) self.run_cmake = True # Tricky corner-case: The user has not specified a build folder but # there was one in the CMake cache. Since this is going to be # invalidated, reset to CWD and re-run the basic tests. if ((boards_mismatched and not apps_mismatched) and (not source_abs and cached_abs)): self._setup_source_dir() self._sanity_check_source_dir()
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 args.pristine is not None: pristine = args.pristine else: # Load the pristine={auto, always, never} configuration value pristine = config.get('build', 'pristine', fallback='never') if pristine not in ['auto', 'always', 'never']: log.wrn('treating unknown build.pristine value "{}" as "never"'. format(pristine)) pristine = 'never' self.auto_pristine = (pristine == 'auto') log.dbg('pristine: {} auto_pristine: {}'.format(pristine, self.auto_pristine)) if is_zephyr_build(self.build_dir): if pristine == 'always': log.inf('Making build dir {} pristine'.format(self.build_dir)) self._run_build('pristine') self.run_cmake = True else: 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() self._run_build(args.target)
def _sanity_check(self): # Sanity check the build configuration. # Side effect: may update cmake_cache attribute. log.dbg('sanity checking the build', level=log.VERBOSE_EXTREME) if self.source_dir == self.build_dir: # There's no forcing this. log.die('source and build directory {} cannot be the same; ' 'use --build-dir {} to specify a build directory'. format(self.source_dir, self.build_dir)) srcrel = os.path.relpath(self.source_dir) if is_zephyr_build(self.source_dir): self._check_force('it looks like {srcrel} is a build directory: ' 'did you mean -build-dir {srcrel} instead?'. format(srcrel=srcrel)) elif 'CMakeLists.txt' not in os.listdir(self.source_dir): self._check_force('source directory "{srcrel}" does not contain ' 'a CMakeLists.txt; is that really what you ' 'want to build? (Use -s SOURCE_DIR to specify ' 'the application source directory)'. format(srcrel=srcrel)) if not is_zephyr_build(self.build_dir) and not self.args.board: self._check_force('this looks like a new or clean build, ' 'please provide --board') if not self.cmake_cache: return # That's all we can check without a cache. cached_app = self.cmake_cache.get('APPLICATION_SOURCE_DIR') log.dbg('APPLICATION_SOURCE_DIR:', cached_app, level=log.VERBOSE_EXTREME) source_abs = (os.path.abspath(self.args.source_dir) if self.args.source_dir else None) cached_abs = os.path.abspath(cached_app) if cached_app else None if cached_abs and source_abs and source_abs != cached_abs: self._check_force('build directory "{}" is for application "{}", ' 'but source directory "{}" was specified; ' 'please clean it or use --build-dir to set ' 'another build directory'. format(self.build_dir, cached_abs, source_abs)) self.run_cmake = True # If they insist, we need to re-run cmake. cached_board = self.cmake_cache.get('CACHED_BOARD') log.dbg('CACHED_BOARD:', cached_board, level=log.VERBOSE_EXTREME) if not cached_board and not self.args.board: if self.created_build_dir: self._check_force( 'Building for the first time: you must provide --board') else: self._check_force( 'Board is missing or unknown, please provide --board') if self.args.board and cached_board and \ self.args.board != cached_board: self._check_force('Build directory {} targets board {}, ' 'but board {} was specified. (Clean that ' 'directory or use --build-dir to specify ' 'a different one.)'. format(self.build_dir, cached_board, self.args.board))
def _sanity_check(self): # Sanity check the build configuration. # Side effect: may update cmake_cache attribute. log.dbg('sanity checking the build', level=log.VERBOSE_EXTREME) if self.source_dir == self.build_dir: # There's no forcing this. log.die('source and build directory {} cannot be the same; ' 'use --build-dir {} to specify a build directory'.format( self.source_dir, self.build_dir)) srcrel = os.path.relpath(self.source_dir) self.check_force( not is_zephyr_build(self.source_dir), 'it looks like {srcrel} is a build directory: ' 'did you mean --build-dir {srcrel} instead?'.format(srcrel=srcrel)) self.check_force( 'CMakeLists.txt' in os.listdir(self.source_dir), 'source directory "{srcrel}" does not contain ' 'a CMakeLists.txt; is this really what you ' 'want to build? (Use -s SOURCE_DIR to specify ' 'the application source directory)'.format(srcrel=srcrel)) self.check_force( is_zephyr_build(self.build_dir) or self.args.board, 'this looks like a new or clean build, please provide --board') if not self.cmake_cache: return # That's all we can check without a cache. cached_app = self.cmake_cache.get('APPLICATION_SOURCE_DIR') log.dbg('APPLICATION_SOURCE_DIR:', cached_app, level=log.VERBOSE_EXTREME) source_abs = (os.path.abspath(self.args.source_dir) if self.args.source_dir else None) cached_abs = os.path.abspath(cached_app) if cached_app else None # If the build directory specifies a source app, make sure it's # consistent with --source-dir. apps_mismatched = (source_abs and cached_abs and source_abs != cached_abs) self.check_force( not apps_mismatched, 'Build directory "{}" is for application "{}", but source ' 'directory "{}" was specified; please clean it or use --build-dir ' 'to set another build directory'.format(self.build_dir, cached_abs, source_abs)) if apps_mismatched: self.run_cmake = True # If they insist, we need to re-run cmake. # If CACHED_BOARD is not defined, we need --board from the # command line. cached_board = self.cmake_cache.get('CACHED_BOARD') log.dbg('CACHED_BOARD:', cached_board, level=log.VERBOSE_EXTREME) self.check_force(cached_board or self.args.board, 'Cached board not defined, please provide --board') # Check consistency between cached board and --board. boards_mismatched = (self.args.board and cached_board and self.args.board != cached_board) self.check_force( not boards_mismatched, 'Build directory {} targets board {}, but board {} was specified. ' '(Clean the directory or use --build-dir to specify a different ' 'one.)'.format(self.build_dir, cached_board, self.args.board))