def SelectCommit(self, commit, checkout=True): """Checkout the selected commit for this build """ self.commit = commit if checkout and self.checkout: gitutil.Checkout(commit.hash)
def RunCommit(self, commit_upto, brd, work_dir, do_config, config_only, force_build, force_build_failures): """Build a particular commit. If the build is already done, and we are not forcing a build, we skip the build and just return the previously-saved results. Args: commit_upto: Commit number to build (0...n-1) brd: Board object to build work_dir: Directory to which the source will be checked out do_config: True to run a make <board>_defconfig on the source config_only: Only configure the source, do not build it force_build: Force a build even if one was previously done force_build_failures: Force a bulid if the previous result showed failure Returns: tuple containing: - CommandResult object containing the results of the build - boolean indicating whether 'make config' is still needed """ # Create a default result - it will be overwritte by the call to # self.Make() below, in the event that we do a build. result = command.CommandResult() result.return_code = 0 if self.builder.in_tree: out_dir = work_dir else: if self.per_board_out_dir: out_rel_dir = os.path.join('..', brd.target) else: out_rel_dir = 'build' out_dir = os.path.join(work_dir, out_rel_dir) # Check if the job was already completed last time done_file = self.builder.GetDoneFile(commit_upto, brd.target) result.already_done = os.path.exists(done_file) will_build = (force_build or force_build_failures or not result.already_done) if result.already_done: # Get the return code from that build and use it with open(done_file, 'r') as fd: try: result.return_code = int(fd.readline()) except ValueError: # The file may be empty due to running out of disk space. # Try a rebuild result.return_code = RETURN_CODE_RETRY # Check the signal that the build needs to be retried if result.return_code == RETURN_CODE_RETRY: will_build = True elif will_build: err_file = self.builder.GetErrFile(commit_upto, brd.target) if os.path.exists(err_file) and os.stat(err_file).st_size: result.stderr = 'bad' elif not force_build: # The build passed, so no need to build it again will_build = False if will_build: # We are going to have to build it. First, get a toolchain if not self.toolchain: try: self.toolchain = self.builder.toolchains.Select(brd.arch) except ValueError as err: result.return_code = 10 result.stdout = '' result.stderr = str(err) # TODO([email protected]): This gets swallowed, but needs # to be reported. if self.toolchain: # Checkout the right commit if self.builder.commits: commit = self.builder.commits[commit_upto] if self.builder.checkout: git_dir = os.path.join(work_dir, '.git') gitutil.Checkout(commit.hash, git_dir, work_dir, force=True) else: commit = 'current' # Set up the environment and command line env = self.toolchain.MakeEnvironment(self.builder.full_path) Mkdir(out_dir) args = [] cwd = work_dir src_dir = os.path.realpath(work_dir) if not self.builder.in_tree: if commit_upto is None: # In this case we are building in the original source # directory (i.e. the current directory where buildman # is invoked. The output directory is set to this # thread's selected work directory. # # Symlinks can confuse U-Boot's Makefile since # we may use '..' in our path, so remove them. out_dir = os.path.realpath(out_dir) args.append('O=%s' % out_dir) cwd = None src_dir = os.getcwd() else: args.append('O=%s' % out_rel_dir) if self.builder.verbose_build: args.append('V=1') else: args.append('-s') if self.builder.num_jobs is not None: args.extend(['-j', str(self.builder.num_jobs)]) if self.builder.warnings_as_errors: args.append('KCFLAGS=-Werror') config_args = ['%s_defconfig' % brd.target] config_out = '' args.extend(self.builder.toolchains.GetMakeArguments(brd)) args.extend(self.toolchain.MakeArgs()) # If we need to reconfigure, do that now if do_config: config_out = '' if not self.incremental: result = self.Make(commit, brd, 'mrproper', cwd, 'mrproper', *args, env=env) config_out += result.combined result = self.Make(commit, brd, 'config', cwd, *(args + config_args), env=env) config_out += result.combined do_config = False # No need to configure next time if result.return_code == 0: if config_only: args.append('cfg') result = self.Make(commit, brd, 'build', cwd, *args, env=env) result.stderr = result.stderr.replace(src_dir + '/', '') if self.builder.verbose_build: result.stdout = config_out + result.stdout else: result.return_code = 1 result.stderr = 'No tool chain for %s\n' % brd.arch result.already_done = False result.toolchain = self.toolchain result.brd = brd result.commit_upto = commit_upto result.out_dir = out_dir return result, do_config