Beispiel #1
0
 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)
Beispiel #2
0
    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