Exemple #1
0
def ConvertDepsToManifest(deps_file, project_blacklist, manifest_file, remote):
    """Convert dependencies in .DEPS.git files to manifest entries.

  Arguments:
    deps_file: The path to the .DEPS.git file.
    project_blacklist: Set of project names that we shouldn't write
      entries for; specifically since they're already in our parent.
    manifest_file: The file object to write manifest entries to.
    remote: The remote value to write to the new manifest.
  """
    _, merged_deps = chrome_set_ver.GetParsedDeps(deps_file)
    mappings = chrome_set_ver.GetPathToProjectMappings(merged_deps)

    # Check for double checkouts and blacklisted projects.
    previous_projects = set(project_blacklist)
    for rel_path, project in sorted(mappings.iteritems(), key=lambda x: x[1]):
        rel_path = os.path.join('chromium', rel_path)
        if project.startswith('chromiumos'):
            cros_build_lib.Warning('Skipping project %s in %s', project,
                                   deps_file)
        elif project in previous_projects:
            cros_build_lib.Warning('Found double checkout of %s to %s',
                                   project, rel_path)
        else:
            manifest_file.write(_MkProject(rel_path, project, remote))
            previous_projects.add(project)
Exemple #2
0
def FindChromeCandidates(overlay_dir):
    """Return a tuple of chrome's unstable ebuild and stable ebuilds.

  Args:
    overlay_dir: The path to chrome's portage overlay dir.
  Returns:
    Tuple [unstable_ebuild, stable_ebuilds].
  Raises:
    Exception: if no unstable ebuild exists for Chrome.
  """
    stable_ebuilds = []
    unstable_ebuilds = []
    for path in [
            os.path.join(overlay_dir, entry)
            for entry in os.listdir(overlay_dir)
    ]:
        if path.endswith('.ebuild'):
            ebuild = ChromeEBuild(path)
            if not ebuild.chrome_version:
                cros_build_lib.Warning('Poorly formatted ebuild found at %s' %
                                       path)
            else:
                if '9999' in ebuild.version:
                    unstable_ebuilds.append(ebuild)
                else:
                    stable_ebuilds.append(ebuild)

    # Apply some sanity checks.
    if not unstable_ebuilds:
        raise Exception('Missing 9999 ebuild for %s' % overlay_dir)
    if not stable_ebuilds:
        cros_build_lib.Warning('Missing stable ebuild for %s' % overlay_dir)

    return portage_utilities.BestEBuild(unstable_ebuilds), stable_ebuilds
Exemple #3
0
    def _VerifyGoma(user_rc):
        """Verify that the user's goma installation is working.

    Arguments:
      user_rc: User-supplied rc file.
    """
        user_env = osutils.SourceEnvironment(user_rc, ['PATH'], env=True)
        goma_ctl = osutils.Which('goma_ctl.sh', user_env.get('PATH'))
        if goma_ctl is not None:
            manifest = os.path.join(os.path.dirname(goma_ctl), 'MANIFEST')
            platform_env = osutils.SourceEnvironment(manifest, ['PLATFORM'])
            platform = platform_env.get('PLATFORM')
            if platform is not None and platform != 'chromeos':
                cros_build_lib.Warning('Found %s version of Goma in PATH.',
                                       platform)
                cros_build_lib.Warning('Goma will not work')
Exemple #4
0
def _PostParseCheck(options, _args):
    """Perform some usage validation (after we've parsed the arguments

  Args:
    options/args: The options/args object returned by optparse
  """
    if options.local_pkg_path and not os.path.isfile(options.local_pkg_path):
        cros_build_lib.Die('%s is not a file.', options.local_pkg_path)

    if not options.gyp_defines:
        gyp_env = os.getenv('GYP_DEFINES', None)
        if gyp_env is not None:
            options.gyp_defines = chrome_util.ProcessGypDefines(gyp_env)
            logging.debug('GYP_DEFINES taken from environment: %s',
                          options.gyp_defines)

    if options.strict and not options.gyp_defines:
        cros_build_lib.Die('When --strict is set, the GYP_DEFINES environment '
                           'variable must be set.')

    if options.build_dir:
        chrome_path = os.path.join(options.build_dir, 'chrome')
        if os.path.isfile(chrome_path):
            deps = lddtree.ParseELF(chrome_path)
            if 'libbase.so' in deps['libs']:
                cros_build_lib.Warning(
                    'Detected a component build of Chrome.  component build is '
                    'not working properly for Chrome OS.  See crbug.com/196317.  '
                    'Use at your own risk!')
  def _UploadPrebuilt(self, package_path, url_suffix):
    """Upload host or board prebuilt files to Google Storage space.

    Args:
      package_path: The path to the packages dir.
      url_suffix: The remote subdirectory where we should upload the packages.

    """

    # Process Packages file, removing duplicates and filtered packages.
    pkg_index = binpkg.GrabLocalPackageIndex(package_path)
    pkg_index.SetUploadLocation(self._binhost_base_url, url_suffix)
    pkg_index.RemoveFilteredPackages(self._ShouldFilterPackage)
    uploads = pkg_index.ResolveDuplicateUploads(self._pkg_indexes)
    unmatched_pkgs = self._packages - self._found_packages
    if unmatched_pkgs:
      cros_build_lib.Warning('unable to match packages: %r' % unmatched_pkgs)

    # Write Packages file.
    tmp_packages_file = pkg_index.WriteToNamedTemporaryFile()

    remote_location = '%s/%s' % (self._upload_location.rstrip('/'), url_suffix)
    assert remote_location.startswith('gs://')

    # Build list of files to upload.
    upload_files = GenerateUploadDict(package_path, remote_location, uploads)
    remote_file = '%s/Packages' % remote_location.rstrip('/')
    upload_files[tmp_packages_file.name] = remote_file

    RemoteUpload(self._acl, upload_files)
    def _HandleExceptionAsWarning(self, exception):
        """Use instead of HandleStageException to treat an exception as a warning.

    This is used by the ForgivingBuilderStage's to treat any exceptions as
    warnings instead of stage failures.
    """
        cros_build_lib.PrintBuildbotStepWarnings()
        cros_build_lib.Warning(self._StringifyException(exception))
        return results_lib.Results.FORGIVEN, None
Exemple #7
0
    def _PrepareProject(self):
        """Make sure the project is synced properly and is ready for pinning."""
        handler = git.ManifestCheckout.Cached(self.repo_root)
        path_to_project_dict = dict(
            ([attrs['path'], project])
            for project, attrs in handler.projects.iteritems())

        # TODO(rcui): Handle case where a dependency never makes it to the manifest
        # (i.e., dep path added as double checkout, and then gets deleted). We need
        # to delete those.  crosbug/22123.
        if not git.IsGitRepo(self.abs_path):
            if self.manifest_rel_path in path_to_project_dict:
                raise ProjectException(
                    '%s in full layout manifest but not in working '
                    "tree. Please run 'repo sync %s'" %
                    (self.manifest_rel_path,
                     path_to_project_dict[self.manifest_rel_path]))
            else:
                cros_build_lib.Warning(
                    'Project %s is not in the manifest.  Automatically checking out '
                    'to %s.\n' % (self.project_url, self.abs_path))
                repository.CloneGitRepo(self.abs_path, self.project_url)
                cros_build_lib.RunCommand(
                    ['git', 'checkout',
                     git.GetGitRepoRevision(self.abs_path)],
                    cwd=self.abs_path)
        elif not _IsGitStoreInRepo(self.abs_path):
            if self.manifest_rel_path in path_to_project_dict:
                # If path is now in the manifest, tell user to manually delete our
                # managed checkout and re-sync.
                raise ProjectException(
                    '%s needs to be replaced.  Please remove the '
                    "directory and run 'repo sync %s'" %
                    (self.manifest_rel_path,
                     path_to_project_dict[self.manifest_rel_path]))
            else:
                # If not managed by Repo we need to perform sync.
                cros_build_lib.RunCommand(
                    ['git', 'pull', '--rebase', self.project_url],
                    cwd=self.abs_path)
        elif not os.path.islink(self.abs_path):
            # Skip symlinks - we don't want to error out for the cros.DEPS projects.
            if self.manifest_rel_path not in path_to_project_dict:
                # If it is 'managed by repo' but not in the manifest, repo tried
                # deleting it but failed because of local changes.
                raise ProjectException(
                    '%s is no longer in the manifest but has local '
                    'changes.  Please remove and try again.' %
                    self.manifest_rel_path)
            elif self.project_name != path_to_project_dict[
                    self.manifest_rel_path]:
                cros_build_lib.Die(
                    '.DEPS.git for %s conflicts with manifest.xml!  Running with '
                    'older .DEPS.git files are not yet supported.  '
                    "Please run'repo sync --jobs=<jobs>' to sync everything up."
                    % self.manifest_rel_path)
Exemple #8
0
def LoadCheckpoint(buildroot):
  """Restore completed stage info from checkpoint file."""
  completed_stages_file = _GetCheckpointFile(buildroot)
  if not os.path.exists(completed_stages_file):
    cros_build_lib.Warning('Checkpoint file not found in buildroot %s'
                           % buildroot)
    return

  with open(completed_stages_file, 'r') as load_file:
    Results.RestoreCompletedStages(load_file)
Exemple #9
0
def ExtractCPEList(deps_list):
    cpe_dump = []
    for cpv, record in deps_list.items():
        if record["cpes"]:
            cpe_dump.append({
                "Name": cpv,
                "Targets": sorted(record["cpes"]),
                "Repository": "cros"
            })
        else:
            cros_build_lib.Warning("No CPE entry for %s", cpv)
    return sorted(cpe_dump, key=lambda k: k["Name"])
Exemple #10
0
  def RestoreCompletedStages(self, out):
    """Load the successfully completed stages from the provided file |out|."""
    # Read the file, and strip off the newlines.
    for line in out:
      record = line.strip().split(self.SPLIT_TOKEN)
      if len(record) != 3:
        cros_build_lib.Warning(
            'State file does not match expected format, ignoring.')
        # Wipe any partial state.
        self._previous = {}
        break

      self._previous[record[0]] = record
Exemple #11
0
def _GetStickyEBuild(stable_ebuilds):
    """Returns the sticky ebuild."""
    sticky_ebuilds = []
    non_sticky_re = re.compile(_NON_STICKY_REGEX)
    for ebuild in stable_ebuilds:
        if not non_sticky_re.match(ebuild.version):
            sticky_ebuilds.append(ebuild)

    if not sticky_ebuilds:
        raise Exception('No sticky ebuilds found')
    elif len(sticky_ebuilds) > 1:
        cros_build_lib.Warning('More than one sticky ebuild found')

    return portage_utilities.BestEBuild(sticky_ebuilds)
def _PrintUsageAndDie(error_message=''):
    """Prints optional error_message the usage and returns an error exit code."""
    command_usage = 'Commands: \n'
    # Add keys and usage information from dictionary.
    commands = sorted(COMMAND_DICTIONARY.keys())
    for command in commands:
        command_usage += '  %s: %s\n' % (command, COMMAND_DICTIONARY[command])
    commands_str = '|'.join(commands)
    cros_build_lib.Warning('Usage: %s FLAGS [%s]\n\n%s' %
                           (sys.argv[0], commands_str, command_usage))
    if error_message:
        cros_build_lib.Die(error_message)
    else:
        sys.exit(1)
Exemple #13
0
    def _ResetProject(self, commit_hash):
        """Actually pin project to the specified commit hash."""
        if not git.DoesCommitExistInRepo(self.abs_path, commit_hash):
            cros_build_lib.Die(
                'Commit %s not found in %s.\n'
                "You probably need to run 'repo sync --jobs=<jobs>' "
                'to update your checkout.' % (commit_hash, self.abs_path))

        result = cros_build_lib.RunCommand(['git', 'checkout', commit_hash],
                                           error_code_ok=True,
                                           cwd=self.abs_path)
        if result.returncode != 0:
            cros_build_lib.Warning(
                'Failed to pin project %s.\n'
                'You probably have uncommited local changes.' % self.abs_path)
Exemple #14
0
    def Pin(self, commit_hash):
        """Attempt to pin the project to the specified commit hash.

    Arguments:
      commit_hash: The commit to pin the project to.

    Raises:
      ProjectException when an error occurs.
    """
        self._PrepareProject()
        if git.GetCurrentBranch(self.abs_path):
            cros_build_lib.Warning(
                "Not pinning project %s that's checked out to a "
                'development branch.' % self.rel_path)
        elif (commit_hash
              and (commit_hash != git.GetGitRepoRevision(self.abs_path))):
            print 'Pinning project %s' % self.rel_path
            self._ResetProject(commit_hash)
        else:
            cros_build_lib.Debug('Skipping project %s, already pinned' %
                                 self.rel_path)
Exemple #15
0
def GetApprovalSummary(_opts, cls):
  """Return a dict of the most important approvals"""
  approvs = dict([(x, '') for x in GERRIT_SUMMARY_CATS])
  if 'approvals' in cls['currentPatchSet']:
    for approver in cls['currentPatchSet']['approvals']:
      cats = GERRIT_APPROVAL_MAP.get(approver['type'])
      if not cats:
        cros_build_lib.Warning('unknown gerrit approval type: %s',
                               approver['type'])
        continue
      cat = cats[0].strip()
      val = int(approver['value'])
      if not cat in approvs:
        # Ignore the extended categories in the summary view.
        continue
      elif approvs[cat] is '':
        approvs[cat] = val
      elif val < 0:
        approvs[cat] = min(approvs[cat], val)
      else:
        approvs[cat] = max(approvs[cat], val)
  return approvs
def GenerateBreakpadSymbol(elf_file,
                           debug_file=None,
                           breakpad_dir=None,
                           board=None,
                           strip_cfi=False,
                           num_errors=None):
    """Generate the symbols for |elf_file| using |debug_file|

  Args:
    elf_file: The file to dump symbols for
    debug_file: Split debug file to use for symbol information
    breakpad_dir: The dir to store the output symbol file in
    board: If |breakpad_dir| is not specified, use |board| to find it
    strip_cfi: Do not generate CFI data
    num_errors: An object to update with the error count (needs a .value member)
  Returns:
    The number of errors that were encountered.
  """
    if breakpad_dir is None:
        breakpad_dir = FindBreakpadDir(board)
    if num_errors is None:
        num_errors = ctypes.c_int()

    cmd_base = ['dump_syms']
    if strip_cfi:
        cmd_base += ['-c']
    # Some files will not be readable by non-root (e.g. set*id /bin/su).
    needs_sudo = not os.access(elf_file, os.R_OK)

    def _DumpIt(cmd_args):
        if needs_sudo:
            run_command = cros_build_lib.SudoRunCommand
        else:
            run_command = cros_build_lib.RunCommand
        return run_command(cmd_base + cmd_args,
                           redirect_stderr=True,
                           log_stdout_to_file=temp.name,
                           error_code_ok=True,
                           debug_level=logging.DEBUG)

    def _CrashCheck(ret, msg):
        if ret < 0:
            cros_build_lib.PrintBuildbotStepWarnings()
            cros_build_lib.Warning('dump_syms crashed with %s; %s',
                                   osutils.StrSignal(-ret), msg)

    osutils.SafeMakedirs(breakpad_dir)
    with tempfile.NamedTemporaryFile(dir=breakpad_dir, bufsize=0) as temp:
        if debug_file:
            # Try to dump the symbols using the debug file like normal.
            cmd_args = [elf_file, os.path.dirname(debug_file)]
            result = _DumpIt(cmd_args)

            if result.returncode:
                # Sometimes dump_syms can crash because there's too much info.
                # Try dumping and stripping the extended stuff out.  At least
                # this way we'll get the extended symbols.  http://crbug.com/266064
                _CrashCheck(result.returncode, 'retrying w/out CFI')
                cmd_args = ['-c', '-r'] + cmd_args
                result = _DumpIt(cmd_args)
                _CrashCheck(result.returncode, 'retrying w/out debug')

            basic_dump = result.returncode
        else:
            basic_dump = True

        if basic_dump:
            # If that didn't work (no debug, or dump_syms still failed), try
            # dumping just the file itself directly.
            result = _DumpIt([elf_file])
            if result.returncode:
                # A lot of files (like kernel files) contain no debug information,
                # do not consider such occurrences as errors.
                cros_build_lib.PrintBuildbotStepWarnings()
                _CrashCheck(result.returncode, 'giving up entirely')
                if 'file contains no debugging information' in result.error:
                    cros_build_lib.Warning('no symbols found for %s', elf_file)
                else:
                    num_errors.value += 1
                    cros_build_lib.Error('dumping symbols for %s failed:\n%s',
                                         elf_file, result.error)
                return num_errors.value

        # Move the dumped symbol file to the right place:
        # /build/$BOARD/usr/lib/debug/breakpad/<module-name>/<id>/<module-name>.sym
        header = ReadSymsHeader(temp)
        cros_build_lib.Info('Dumped %s as %s : %s', elf_file, header.name,
                            header.id)
        sym_file = os.path.join(breakpad_dir, header.name, header.id,
                                header.name + '.sym')
        osutils.SafeMakedirs(os.path.dirname(sym_file))
        os.rename(temp.name, sym_file)
        os.chmod(sym_file, 0644)
        temp.delete = False

    return num_errors.value
Exemple #17
0
def _BuildInitialPackageRoot(output_dir,
                             paths,
                             elfs,
                             ldpaths,
                             path_rewrite_func=lambda x: x,
                             root='/'):
    """Link in all packable files and their runtime dependencies

  This also wraps up executable ELFs with helper scripts.

  Args:
    output_dir: The output directory to store files
    paths: All the files to include
    elfs: All the files which are ELFs (a subset of |paths|)
    ldpaths: A dict of static ldpath information
    path_rewrite_func: User callback to rewrite paths in output_dir
    root: The root path to pull all packages/files from
  """
    # Link in all the files.
    sym_paths = []
    for path in paths:
        new_path = path_rewrite_func(path)
        dst = output_dir + new_path
        osutils.SafeMakedirs(os.path.dirname(dst))

        # Is this a symlink which we have to rewrite or wrap?
        # Delay wrap check until after we have created all paths.
        src = root + path
        if os.path.islink(src):
            tgt = os.readlink(src)
            if os.path.sep in tgt:
                sym_paths.append(
                    (new_path, lddtree.normpath(ReadlinkRoot(src, root))))

                # Rewrite absolute links to relative and then generate the symlink
                # ourselves.  All other symlinks can be hardlinked below.
                if tgt[0] == '/':
                    tgt = os.path.relpath(tgt, os.path.dirname(new_path))
                    os.symlink(tgt, dst)
                    continue

        os.link(src, dst)

    # Now see if any of the symlinks need to be wrapped.
    for sym, tgt in sym_paths:
        if tgt in elfs:
            GeneratePathWrapper(output_dir, sym, tgt)

    # Locate all the dependencies for all the ELFs.  Stick them all in the
    # top level "lib" dir to make the wrapper simpler.  This exact path does
    # not matter since we execute ldso directly, and we tell the ldso the
    # exact path to search for its libraries.
    libdir = os.path.join(output_dir, 'lib')
    osutils.SafeMakedirs(libdir)
    donelibs = set()
    for elf in elfs:
        e = lddtree.ParseELF(elf, root, ldpaths)
        interp = e['interp']
        if interp:
            # Generate a wrapper if it is executable.
            interp = os.path.join('/lib', os.path.basename(interp))
            lddtree.GenerateLdsoWrapper(output_dir,
                                        path_rewrite_func(elf),
                                        interp,
                                        libpaths=e['rpath'] + e['runpath'])

        for lib, lib_data in e['libs'].iteritems():
            if lib in donelibs:
                continue

            src = path = lib_data['path']
            if path is None:
                cros_build_lib.Warning('%s: could not locate %s', elf, lib)
                continue
            donelibs.add(lib)

            # Needed libs are the SONAME, but that is usually a symlink, not a
            # real file.  So link in the target rather than the symlink itself.
            # We have to walk all the possible symlinks (SONAME could point to a
            # symlink which points to a symlink), and we have to handle absolute
            # ourselves (since we have a "root" argument).
            dst = os.path.join(libdir, os.path.basename(path))
            src = ReadlinkRoot(src, root)

            os.link(root + src, dst)
Exemple #18
0
def GenerateBlameList(source_repo, lkgm_path, only_print_chumps=False):
    """Generate the blamelist since the specified manifest.

  Arguments:
    source_repo: Repository object for the source code.
    lkgm_path: Path to LKGM manifest.
    only_print_chumps: If True, only print changes that were chumped.
  """
    handler = git.Manifest(lkgm_path)
    reviewed_on_re = re.compile(r'\s*Reviewed-on:\s*(\S+)')
    author_re = re.compile(r'\s*Author:.*<(\S+)@\S+>\s*')
    committer_re = re.compile(r'\s*Commit:.*<(\S+)@\S+>\s*')
    for project in handler.projects.keys():
        rel_src_path = handler.projects[project].get('path')

        # If it's not part of our source tree, it doesn't affect our build.
        if not rel_src_path:
            continue

        # Additional case in case the repo has been removed from the manifest.
        src_path = source_repo.GetRelativePath(rel_src_path)
        if not os.path.exists(src_path):
            cros_build_lib.Info('Detected repo removed from manifest %s' %
                                project)
            continue

        revision = handler.projects[project]['revision']
        try:
            result = cros_build_lib.RunCommand(
                ['git', 'log', '--pretty=full',
                 '%s..HEAD' % revision],
                print_cmd=False,
                redirect_stdout=True,
                cwd=src_path)
        except cros_build_lib.RunCommandError as ex:
            # Git returns 128 when the revision does not exist.
            if ex.result.returncode != 128:
                raise
            cros_build_lib.Warning(
                'Detected branch removed from local checkout.')
            cros_build_lib.PrintBuildbotStepWarnings()
            return
        current_author = None
        current_committer = None
        for line in unicode(result.output, 'ascii', 'ignore').splitlines():
            author_match = author_re.match(line)
            if author_match:
                current_author = author_match.group(1)

            committer_match = committer_re.match(line)
            if committer_match:
                current_committer = committer_match.group(1)

            review_match = reviewed_on_re.match(line)
            if review_match:
                review = review_match.group(1)
                _, _, change_number = review.rpartition('/')
                items = [
                    os.path.basename(project),
                    current_author,
                    change_number,
                ]
                if current_committer != 'chrome-bot':
                    items.insert(0, 'CHUMP')
                elif only_print_chumps:
                    continue
                cros_build_lib.PrintBuildbotLink(' | '.join(items), review)
Exemple #19
0
def main(argv):

    usage = 'usage: %prog [-d <DEPS.git file>] [command]'
    parser = optparse.OptionParser(usage=usage)

    # TODO(rcui): have -d accept a URL.
    parser.add_option('-d',
                      '--deps',
                      default=None,
                      help=('DEPS file to use. Defaults to '
                            '<chrome_src_root>/.DEPS.git'))
    parser.add_option('--internal',
                      action='store_false',
                      dest='internal',
                      default=True,
                      help='Allow chrome-internal URLs')
    parser.add_option('--runhooks',
                      action='store_true',
                      dest='runhooks',
                      default=False,
                      help="Run hooks as well.")
    parser.add_option('-v',
                      '--verbose',
                      default=False,
                      action='store_true',
                      help='Run with debug output.')
    (options, _inputs) = parser.parse_args(argv)

    # Set cros_build_lib debug level to hide RunCommand spew.
    if options.verbose:
        cros_build_lib.logger.setLevel(logging.DEBUG)
    else:
        cros_build_lib.logger.setLevel(logging.WARNING)

    if cros_build_lib.IsInsideChroot():
        ssh_path = '/usr/bin/ssh_no_update'
        if os.path.isfile(ssh_path):
            os.environ['GIT_SSH'] = ssh_path
        else:
            cros_build_lib.Warning(
                "Can't find %s.  Run build_packages or setup_board to update "
                "your choot." % ssh_path)

    repo_root = git.FindRepoCheckoutRoot(os.getcwd())
    chromium_src_root = os.path.join(repo_root, _CHROMIUM_SRC_ROOT)
    if not os.path.isdir(os.path.join(chromium_src_root, '.git')):
        error_msg = 'chromium checkout not found at %s.\n' % chromium_src_root

        manifest = os.path.join(repo_root, '.repo', 'manifest.xml')
        if os.path.basename(os.path.realpath(manifest)) == 'gerrit-source.xml':
            error_msg += ("Please run repo sync and try again.")
        else:
            link = 'http://www.chromium.org/chromium-os/new-chrome-developer-workflow'
            error_msg += (
                'Detected you are not using gerrit_source.xml.  Follow '
                'instructions at %s to use repo checkout of chrome.' % link)

        cros_build_lib.Die(error_msg)

    # Add DEPS files to parse.
    deps_files_to_parse = []
    if options.deps:
        deps_files_to_parse.append(options.deps)
    else:
        deps_files_to_parse.append(os.path.join(chromium_src_root,
                                                '.DEPS.git'))

    internal_deps = os.path.join(repo_root, _CHROMIUM_SRC_INTERNAL,
                                 '.DEPS.git')
    if os.path.exists(internal_deps):
        deps_files_to_parse.append(internal_deps)

    # Prepare source tree for resetting.
    chromium_root = os.path.join(repo_root, _CHROMIUM_ROOT)
    _CreateCrosSymlink(repo_root)

    # Parse DEPS files and store hooks.
    hook_dicts = []
    for deps_file in deps_files_to_parse:
        deps, merged_deps = GetParsedDeps(deps_file)
        _ResetGitCheckout(repo_root, merged_deps)
        hook_dicts.append(deps.get('hooks', {}))

    # Run hooks after checkout has been reset properly.
    if options.runhooks:
        for hooks in hook_dicts:
            _RunHooks(chromium_root, hooks)
def UploadSymbol(sym_file,
                 upload_url,
                 file_limit=DEFAULT_FILE_LIMIT,
                 sleep=0,
                 num_errors=None):
    """Upload |sym_file| to |upload_url|

  Args:
    sym_file: The full path to the breakpad symbol to upload
    upload_url: The crash server to upload things to
    file_limit: The max file size of a symbol file before we try to strip it
    sleep: Number of seconds to sleep before running
    num_errors: An object to update with the error count (needs a .value member)
  Returns:
    The number of errors that were encountered.
  """
    if num_errors is None:
        num_errors = ctypes.c_int()
    elif num_errors.value > MAX_TOTAL_ERRORS_FOR_RETRY:
        # Abandon ship!  It's on fire!  NOoooooooooooOOOoooooo.
        return 0

    upload_file = sym_file

    if sleep:
        # Keeps us from DoS-ing the symbol server.
        time.sleep(sleep)

    cros_build_lib.Debug('uploading %s' % sym_file)

    # Ideally there'd be a tempfile.SpooledNamedTemporaryFile that we could use.
    with tempfile.NamedTemporaryFile(prefix='upload_symbols',
                                     bufsize=0) as temp_sym_file:
        if file_limit:
            # If the symbols size is too big, strip out the call frame info.  The CFI
            # is unnecessary for 32bit x86 targets where the frame pointer is used (as
            # all of ours have) and it accounts for over half the size of the symbols
            # uploaded.
            file_size = os.path.getsize(sym_file)
            if file_size > file_limit:
                cros_build_lib.Warning(
                    'stripping CFI from %s due to size %s > %s', sym_file,
                    file_size, file_limit)
                temp_sym_file.writelines([
                    x for x in open(sym_file, 'rb').readlines()
                    if not x.startswith('STACK CFI')
                ])
                upload_file = temp_sym_file.name

        # Hopefully the crash server will let it through.  But it probably won't.
        # Not sure what the best answer is in this case.
        file_size = os.path.getsize(upload_file)
        if file_size > CRASH_SERVER_FILE_LIMIT:
            cros_build_lib.PrintBuildbotStepWarnings()
            cros_build_lib.Error(
                'upload file %s is awfully large, risking rejection '
                'by symbol server (%s > %s)', sym_file, file_size,
                CRASH_SERVER_FILE_LIMIT)
            num_errors.value += 1

        # Upload the symbol file.
        try:
            cros_build_lib.RetryCommand(SymUpload,
                                        MAX_RETRIES,
                                        upload_file,
                                        upload_url,
                                        sleep=INITIAL_RETRY_DELAY)
            cros_build_lib.Info('successfully uploaded %10i bytes: %s',
                                file_size, os.path.basename(sym_file))
        except cros_build_lib.RunCommandError as e:
            cros_build_lib.Warning(
                'could not upload: %s:\n{stdout} %s\n{stderr} %s',
                os.path.basename(sym_file), e.result.output, e.result.error)
            num_errors.value += 1

    return num_errors.value
def main(argv):
    parser = commandline.ArgumentParser(description=__doc__)

    parser.add_argument('sym_files', type='path', nargs='*', default=None)
    parser.add_argument('--board',
                        default=None,
                        help='board to build packages for')
    parser.add_argument('--breakpad_root',
                        type='path',
                        default=None,
                        help='root directory for breakpad symbols')
    parser.add_argument('--official_build',
                        action='store_true',
                        default=False,
                        help='point to official symbol server')
    parser.add_argument('--regenerate',
                        action='store_true',
                        default=False,
                        help='regenerate all symbols')
    parser.add_argument('--upload-count',
                        type=int,
                        default=None,
                        help='only upload # number of symbols')
    parser.add_argument('--strip_cfi',
                        type=int,
                        default=CRASH_SERVER_FILE_LIMIT - (10 * 1024 * 1024),
                        help='strip CFI data for files above this size')
    parser.add_argument('--testing',
                        action='store_true',
                        default=False,
                        help='run in testing mode')
    parser.add_argument('--yes',
                        action='store_true',
                        default=False,
                        help='answer yes to all prompts')

    opts = parser.parse_args(argv)

    if opts.sym_files:
        if opts.regenerate:
            cros_build_lib.Die(
                '--regenerate may not be used with specific files')
    else:
        if opts.board is None:
            cros_build_lib.Die('--board is required')

    if opts.breakpad_root and opts.regenerate:
        cros_build_lib.Die('--regenerate may not be used with --breakpad_root')

    if opts.testing:
        # TODO(build): Kill off --testing mode once unittests are up-to-snuff.
        cros_build_lib.Info('running in testing mode')
        # pylint: disable=W0601,W0603
        global INITIAL_RETRY_DELAY, SymUpload, DEFAULT_SLEEP_DELAY
        INITIAL_RETRY_DELAY = DEFAULT_SLEEP_DELAY = 0
        SymUpload = TestingSymUpload

    if not opts.yes:
        query = textwrap.wrap(
            textwrap.dedent("""
        Uploading symbols for an entire Chromium OS build is really only
        necessary for release builds and in a few cases for developers
        to debug problems.  It will take considerable time to run.  For
        developer debugging purposes, consider instead passing specific
        files to upload.
    """), 80)
        cros_build_lib.Warning('\n%s', '\n'.join(query))
        if not cros_build_lib.BooleanPrompt(
                prompt='Are you sure you want to upload all build symbols',
                default=False):
            cros_build_lib.Die('better safe than sorry')

    ret = 0
    if opts.regenerate:
        ret += cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
            opts.board, breakpad_dir=opts.breakpad_root)

    ret += UploadSymbols(opts.board,
                         official=opts.official_build,
                         breakpad_dir=opts.breakpad_root,
                         file_limit=opts.strip_cfi,
                         sleep=DEFAULT_SLEEP_DELAY,
                         upload_count=opts.upload_count,
                         sym_files=opts.sym_files)
    if ret:
        cros_build_lib.Error('encountered %i problem(s)', ret)
        # Since exit(status) gets masked, clamp it to 1 so we don't inadvertently
        # return 0 in case we are a multiple of the mask.
        ret = 1

    return ret
def UploadSymbols(board=None,
                  official=False,
                  breakpad_dir=None,
                  file_limit=DEFAULT_FILE_LIMIT,
                  sleep=DEFAULT_SLEEP_DELAY,
                  upload_count=None,
                  sym_files=None):
    """Upload all the generated symbols for |board| to the crash server

  You can use in a few ways:
    * pass |board| to locate all of its symbols
    * pass |breakpad_dir| to upload all the symbols in there
    * pass |sym_files| to upload specific symbols

  Args:
    board: The board whose symbols we wish to upload
    official: Use the official symbol server rather than the staging one
    breakpad_dir: The full path to the breakpad directory where symbols live
    file_limit: The max file size of a symbol file before we try to strip it
    sleep: How long to sleep in between uploads
    upload_count: If set, only upload this many symbols (meant for testing)
    sym_files: Specific symbol files to upload, otherwise search |breakpad_dir|
  Returns:
    The number of errors that were encountered.
  """
    num_errors = 0

    if official:
        upload_url = OFFICIAL_UPLOAD_URL
    else:
        cros_build_lib.Warning(
            'unofficial builds upload to the staging server')
        upload_url = STAGING_UPLOAD_URL

    if sym_files:
        cros_build_lib.Info('uploading specified symbol files to %s',
                            upload_url)
        sym_file_sets = [('', '', sym_files)]
        all_files = True
    else:
        if breakpad_dir is None:
            breakpad_dir = cros_generate_breakpad_symbols.FindBreakpadDir(
                board)
        cros_build_lib.Info('uploading all symbols to %s from %s', upload_url,
                            breakpad_dir)
        sym_file_sets = os.walk(breakpad_dir)
        all_files = False

    # We need to limit ourselves to one upload at a time to avoid the server
    # kicking in DoS protection.  See these bugs for more details:
    # http://crbug.com/209442
    # http://crbug.com/212496
    bg_errors = multiprocessing.Value('i')
    with parallel.BackgroundTaskRunner(UploadSymbol,
                                       file_limit=file_limit,
                                       sleep=sleep,
                                       num_errors=bg_errors,
                                       processes=1) as queue:
        for root, _, files in sym_file_sets:
            if upload_count == 0:
                break

            for sym_file in files:
                if all_files or sym_file.endswith('.sym'):
                    sym_file = os.path.join(root, sym_file)
                    queue.put([sym_file, upload_url])

                    if upload_count is not None:
                        upload_count -= 1
                        if upload_count == 0:
                            break
    num_errors += bg_errors.value

    return num_errors
Exemple #23
0
  def Initialize(self, local_manifest=None, extra_args=()):
    """Initializes a repository.  Optionally forces a local manifest.

    Args:
      local_manifest: The absolute path to a custom manifest to use.  This will
                      replace .repo/manifest.xml.
      extra_args: Extra args to pass to 'repo init'
    """

    # Do a sanity check on the repo; if it exists and we can't pull a
    # manifest from it, we know it's fairly screwed up and needs a fresh
    # rebuild.
    if os.path.exists(os.path.join(self.directory, '.repo', 'manifest.xml')):
      try:
        cros_build_lib.RunCommandCaptureOutput(
            ['repo', 'manifest'], cwd=self.directory)
      except cros_build_lib.RunCommandError:
        cros_build_lib.Warning("Wiping %r due to `repo manifest` failure",
                               self.directory)
        paths = [os.path.join(self.directory, '.repo', x) for x in
                 ('manifest.xml', 'manifests.git', 'manifests', 'repo')]
        cros_build_lib.SudoRunCommand(['rm', '-rf'] + paths)
        self._repo_update_needed = False

    # Wipe local_manifest.xml if it exists- it can interfere w/ things in
    # bad ways (duplicate projects, etc); we control this repository, thus
    # we can destroy it.
    osutils.SafeUnlink(os.path.join(self.directory, 'local_manifest.xml'))

    # Force a repo self update first; during reinit, repo doesn't do the
    # update itself, but we could be doing the init on a repo version less
    # then v1.9.4, which didn't have proper support for doing reinit that
    # involved changing the manifest branch in use; thus selfupdate.
    # Additionally, if the self update fails for *any* reason, wipe the repo
    # innards and force repo init to redownload it; same end result, just
    # less efficient.
    # Additionally, note that this method may be called multiple times;
    # thus code appropriately.
    if self._repo_update_needed:
      try:
        cros_build_lib.RunCommand(['repo', 'selfupdate'], cwd=self.directory)
      except cros_build_lib.RunCommandError:
        osutils.RmDir(os.path.join(self.directory, '.repo', 'repo'),
                      ignore_missing=True)
      self._repo_update_needed = False

    init_cmd = self._INIT_CMD + ['--manifest-url', self.repo_url]
    if self._referenced_repo:
      init_cmd.extend(['--reference', self._referenced_repo])
    if self._manifest:
      init_cmd.extend(['--manifest-name', self._manifest])
    if self._depth is not None:
      init_cmd.extend(['--depth', str(self._depth)])
    init_cmd.extend(extra_args)
    # Handle branch / manifest options.
    if self.branch:
      init_cmd.extend(['--manifest-branch', self.branch])

    cros_build_lib.RunCommand(init_cmd, cwd=self.directory, input='\n\ny\n')
    if local_manifest and local_manifest != self._manifest:
      self._SwitchToLocalManifest(local_manifest)
Exemple #24
0
def WriteFirmware(options):
    """Write firmware to the board.

  This uses cros_bundle_firmware to create a firmware image and write it to
  the board.

  Args:
    options: Command line options
  """
    flash = []
    kernel = []
    run = []
    secure = []
    servo = []
    silent = []
    verbose_arg = []
    ro_uboot = []

    bl2 = ['--bl2', '%s/spl/%s-spl.bin' % (outdir, smdk)]

    if options.use_defaults:
        bl1 = []
        bmpblk = []
        ecro = []
        ecrw = []
        defaults = []
    else:
        bl1 = ['--bl1', '##/build/%s/firmware/u-boot.bl1.bin' % options.board]
        bmpblk = [
            '--bmpblk',
            '##/build/%s/firmware/bmpblk.bin' % options.board
        ]
        ecro = ['--ecro', '##/build/%s/firmware/ec.RO.bin' % options.board]
        ecrw = ['--ec', '##/build/%s/firmware/ec.RW.bin' % options.board]
        defaults = ['-D']

    if arch == 'x86':
        seabios = [
            '--seabios',
            '##/build/%s/firmware/seabios.cbfs' % options.board
        ]
    else:
        seabios = []

    if options.sdcard:
        dest = 'sd:.'
    elif arch == 'x86':
        dest = 'em100'
    elif arch == 'sandbox':
        dest = ''
    else:
        dest = 'usb'

    port = SERVO_PORT.get(options.board, '')
    if port:
        servo = ['--servo', '%d' % port]

    if options.flash:
        flash = ['-F', 'spi']

        # The small builds don't have the command line interpreter so cannot
        # run the magic flasher script. So use the standard U-Boot in this
        # case.
        if options.small:
            cros_build_lib.Warning('Using standard U-Boot as flasher')
            flash += ['-U', '##/build/%s/firmware/u-boot.bin' % options.board]

    if options.mmc:
        flash = ['-F', 'sdmmc']

    if options.verbose:
        verbose_arg = ['-v', '%s' % options.verbose]

    if options.secure:
        secure += ['--bootsecure', '--bootcmd', 'vboot_twostop']

    if not options.verified:
        # Make a small image, without GBB, etc.
        secure.append('-s')

    if options.kernel:
        kernel = ['--kernel', '##/build/%s/boot/vmlinux.uimg' % options.board]

    if not options.console:
        silent = ['--add-config-int', 'silent-console', '1']

    if not options.run:
        run = ['--bootcmd', 'none']

    if arch != 'sandbox' and not in_chroot and servo:
        if dest == 'usb':
            cros_build_lib.Warning('Image cannot be written to board')
            dest = ''
            servo = []
        elif dest == 'em100':
            cros_build_lib.Warning(
                'Please reset the board manually to boot firmware')
            servo = []

        if not servo:
            cros_build_lib.Warning(
                '(sadly dut-control does not work outside chroot)')

    if dest:
        dest = ['-w', dest]
    else:
        dest = []

    soc = SOCS.get(board)
    if not soc:
        soc = SOCS.get(uboard, '')
    dt_name = DEFAULT_DTS.get(options.board, options.board)
    dts_file = 'board/%s/dts/%s%s.dts' % (vendor, soc, dt_name)
    Log('Device tree: %s' % dts_file)

    if arch == 'sandbox':
        uboot_fname = '%s/u-boot' % outdir
    else:
        uboot_fname = '%s/u-boot.bin' % outdir

    if options.ro:
        # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
        # ebuild one as RW.
        # TODO([email protected]): Option to build U-Boot a second time to get
        # a fresh RW U-Boot.
        cros_build_lib.Warning('Using standard U-Boot for RW')
        ro_uboot = ['--add-blob', 'ro-boot', uboot_fname]
        uboot_fname = '##/build/%s/firmware/u-boot.bin' % options.board
    cbf = [
        '%s/platform/dev/host/cros_bundle_firmware' % src_root, '-b',
        options.board, '-d', dts_file, '-I',
        'arch/%s/dts' % arch, '-I', 'cros/dts', '-u', uboot_fname, '-O',
        '%s/out' % outdir, '-M', family
    ]

    for other in [
            bl1, bl2, bmpblk, defaults, dest, ecro, ecrw, flash, kernel, run,
            seabios, secure, servo, silent, verbose_arg, ro_uboot
    ]:
        if other:
            cbf += other
    if options.cbfargs:
        for item in options.cbfargs:
            cbf += item.split(' ')
    os.environ['PYTHONPATH'] = ('%s/platform/dev/host/lib:%s/..' %
                                (src_root, src_root))
    Log(' '.join(cbf))
    result = cros_build_lib.RunCommand(cbf, **kwargs)
    if result.returncode:
        cros_build_lib.Die('cros_bundle_firmware failed')

    if not dest or not result.returncode:
        cros_build_lib.Info('Image is available at %s/out/image.bin' % outdir)
    else:
        if result.returncode:
            cros_build_lib.Die('Failed to write image to board')
        else:
            cros_build_lib.Info('Image written to board with %s' %
                                ' '.join(dest + servo))
def _FindUprevCandidates(files):
    """Return the uprev candidate ebuild from a specified list of files.

  Usually an uprev candidate is a the stable ebuild in a cros_workon
  directory.  However, if no such stable ebuild exists (someone just
  checked in the 9999 ebuild), this is the unstable ebuild.

  If the package isn't a cros_workon package, return None.

  Args:
    files: List of files in a package directory.
  """
    stable_ebuilds = []
    unstable_ebuilds = []
    for path in files:
        if not path.endswith('.ebuild') or os.path.islink(path):
            continue
        ebuild = EBuild(path)
        if not ebuild.is_workon or ebuild.is_blacklisted:
            continue
        if ebuild.is_stable:
            if ebuild.version == '9999':
                cros_build_lib.Die(
                    'KEYWORDS in 9999 ebuild should not be stable %s' % path)
            stable_ebuilds.append(ebuild)
        else:
            unstable_ebuilds.append(ebuild)

    # If both ebuild lists are empty, the passed in file list was for
    # a non-workon package.
    if not unstable_ebuilds:
        if stable_ebuilds:
            path = os.path.dirname(stable_ebuilds[0].ebuild_path)
            cros_build_lib.Die('Missing 9999 ebuild in %s' % path)
        return None

    path = os.path.dirname(unstable_ebuilds[0].ebuild_path)
    if len(unstable_ebuilds) > 1:
        cros_build_lib.Die('Found multiple unstable ebuilds in %s' % path)

    if not stable_ebuilds:
        cros_build_lib.Warning('Missing stable ebuild in %s' % path)
        return unstable_ebuilds[0]

    if len(stable_ebuilds) == 1:
        return stable_ebuilds[0]

    stable_versions = set(ebuild.version_no_rev for ebuild in stable_ebuilds)
    if len(stable_versions) > 1:
        package = stable_ebuilds[0].package
        message = 'Found multiple stable ebuild versions in %s:' % path
        for version in stable_versions:
            message += '\n    %s-%s' % (package, version)
        cros_build_lib.Die(message)

    uprev_ebuild = max(stable_ebuilds, key=lambda eb: eb.current_revision)
    for ebuild in stable_ebuilds:
        if ebuild != uprev_ebuild:
            cros_build_lib.Warning('Ignoring stable ebuild revision %s in %s' %
                                   (ebuild.version, path))
    return uprev_ebuild
def GenerateBreakpadSymbols(board,
                            breakpad_dir=None,
                            strip_cfi=False,
                            generate_count=None,
                            sysroot=None):
    """Generate all the symbols for this board

  TODO(build):
  This should be merged with buildbot_commands.GenerateBreakpadSymbols()
  once we rewrite cros_generate_breakpad_symbols in python.

  Args:
    board: The board whose symbols we wish to generate
    breakpad_dir: The full path to the breakpad directory where symbols live
    strip_cfi: Do not generate CFI data
    generate_count: If set, only generate this many symbols (meant for testing)
    sysroot: The root where to find the corresponding ELFs
  Returns:
    The number of errors that were encountered.
  """
    if breakpad_dir is None:
        breakpad_dir = FindBreakpadDir(board)
    if sysroot is None:
        sysroot = os.path.join('/build', board)
    # Make sure non-root can write out symbols as needed.
    osutils.SafeMakedirs(breakpad_dir, sudo=True)
    if not os.access(breakpad_dir, os.W_OK):
        cros_build_lib.SudoRunCommand(
            ['chown', '-R', str(os.getuid()), breakpad_dir])
    debug_dir = FindDebugDir(board)

    cros_build_lib.Info('generating all breakpad symbol files using %s',
                        debug_dir)

    # Let's locate all the debug_files first and their size.  This way we can
    # start processing the largest files first in parallel with the small ones.
    debug_files = []
    for root, _, files in os.walk(debug_dir):
        for debug_file in files:
            debug_file = os.path.join(root, debug_file)
            if debug_file.endswith('.ko.debug'):
                cros_build_lib.Debug('Skipping kernel module %s', debug_file)
            elif debug_file.endswith('.debug'):
                if os.path.islink(debug_file):
                    # The build-id stuff is common enough to filter out by default.
                    if '/.build-id/' in debug_file:
                        msg = cros_build_lib.Debug
                    else:
                        msg = cros_build_lib.Warning
                    msg('Skipping symbolic link %s', debug_file)
                else:
                    debug_files.append(
                        (os.path.getsize(debug_file), debug_file))

    # Now start generating symbols for all the inputs.
    bg_errors = multiprocessing.Value('i')
    with parallel.BackgroundTaskRunner(GenerateBreakpadSymbol,
                                       breakpad_dir=breakpad_dir,
                                       board=board,
                                       strip_cfi=strip_cfi,
                                       num_errors=bg_errors) as queue:
        for _, debug_file in sorted(debug_files, reverse=True):
            if generate_count == 0:
                break

            # Turn /build/$BOARD/usr/lib/debug/sbin/foo.debug into
            # /build/$BOARD/sbin/foo.
            elf_file = os.path.join(sysroot, debug_file[len(debug_dir) + 1:-6])
            if not os.path.exists(elf_file):
                # Sometimes we filter out programs from /usr/bin but leave behind
                # the .debug file.
                cros_build_lib.Warning('Skipping missing %s', elf_file)
                continue

            queue.put([elf_file, debug_file])
            if generate_count is not None:
                generate_count -= 1
                if generate_count == 0:
                    break

    return bg_errors.value
 def _CrashCheck(ret, msg):
     if ret < 0:
         cros_build_lib.PrintBuildbotStepWarnings()
         cros_build_lib.Warning('dump_syms crashed with %s; %s',
                                osutils.StrSignal(-ret), msg)
def main(_argv):
    parser = optparse.OptionParser('cros_mark_as_stable OPTIONS packages')
    parser.add_option('--all',
                      action='store_true',
                      help='Mark all packages as stable.')
    parser.add_option('-b',
                      '--boards',
                      default='',
                      help='Colon-separated list of boards')
    parser.add_option('--drop_file',
                      help='File to list packages that were revved.')
    parser.add_option('--dryrun',
                      action='store_true',
                      help='Passes dry-run to git push if pushing a change.')
    parser.add_option('-o',
                      '--overlays',
                      help='Colon-separated list of overlays to modify.')
    parser.add_option('-p',
                      '--packages',
                      help='Colon separated list of packages to rev.')
    parser.add_option('-r',
                      '--srcroot',
                      default=os.path.join(constants.SOURCE_ROOT, 'src'),
                      help='Path to root src directory.')
    parser.add_option('--verbose',
                      action='store_true',
                      help='Prints out debug info.')
    (options, args) = parser.parse_args()

    portage_utilities.EBuild.VERBOSE = options.verbose

    if len(args) != 1:
        _PrintUsageAndDie('Must specify a valid command [commit, push]')

    command = args[0]
    package_list = None
    if options.packages:
        package_list = options.packages.split(':')

    _CheckSaneArguments(command, options)
    if options.overlays:
        overlays = {}
        for path in options.overlays.split(':'):
            if not os.path.isdir(path):
                cros_build_lib.Die('Cannot find overlay: %s' % path)
            overlays[path] = []
    else:
        cros_build_lib.Warning('Missing --overlays argument')
        overlays = {
            '%s/private-overlays/chromeos-overlay' % options.srcroot: [],
            '%s/third_party/chromiumos-overlay' % options.srcroot: []
        }

    manifest = git.ManifestCheckout.Cached(options.srcroot)

    if command == 'commit':
        portage_utilities.BuildEBuildDictionary(overlays, options.all,
                                                package_list)

    # Contains the array of packages we actually revved.
    revved_packages = []
    new_package_atoms = []

    # Slight optimization hack: process the chromiumos overlay before any other
    # cros-workon overlay first so we can do background cache generation in it.
    # A perfect solution would walk all the overlays, figure out any dependencies
    # between them (with layout.conf), and then process them in dependency order.
    # However, this operation isn't slow enough to warrant that level of
    # complexity, so we'll just special case the main overlay.
    #
    # Similarly, generate the cache in the portage-stable tree asap.  We know
    # we won't have any cros-workon packages in there, so generating the cache
    # is the only thing it'll be doing.  The chromiumos overlay instead might
    # have revbumping to do before it can generate the cache.
    keys = overlays.keys()
    for overlay in ('/third_party/chromiumos-overlay',
                    '/third_party/portage-stable'):
        for k in keys:
            if k.endswith(overlay):
                keys.remove(k)
                keys.insert(0, k)
                break

    with parallel.BackgroundTaskRunner(portage_utilities.RegenCache) as queue:
        for overlay in keys:
            ebuilds = overlays[overlay]
            if not os.path.isdir(overlay):
                cros_build_lib.Warning("Skipping %s" % overlay)
                continue

            # Note we intentionally work from the non push tracking branch;
            # everything built thus far has been against it (meaning, http mirrors),
            # thus we should honor that.  During the actual push, the code switches
            # to the correct urls, and does an appropriate rebasing.
            tracking_branch = git.GetTrackingBranchViaManifest(
                overlay, manifest=manifest)[1]

            if command == 'push':
                PushChange(constants.STABLE_EBUILD_BRANCH,
                           tracking_branch,
                           options.dryrun,
                           cwd=overlay)
            elif command == 'commit':
                existing_branch = git.GetCurrentBranch(overlay)
                work_branch = GitBranch(constants.STABLE_EBUILD_BRANCH,
                                        tracking_branch,
                                        cwd=overlay)
                work_branch.CreateBranch()
                if not work_branch.Exists():
                    cros_build_lib.Die(
                        'Unable to create stabilizing branch in %s' % overlay)

                # In the case of uprevving overlays that have patches applied to them,
                # include the patched changes in the stabilizing branch.
                if existing_branch:
                    cros_build_lib.RunCommand(
                        ['git', 'rebase', existing_branch],
                        print_cmd=False,
                        cwd=overlay)

                messages = []
                for ebuild in ebuilds:
                    if options.verbose:
                        cros_build_lib.Info('Working on %s', ebuild.package)
                    try:
                        new_package = ebuild.RevWorkOnEBuild(
                            options.srcroot, manifest)
                        if new_package:
                            revved_packages.append(ebuild.package)
                            new_package_atoms.append('=%s' % new_package)
                            messages.append(_GIT_COMMIT_MESSAGE %
                                            ebuild.package)
                    except (OSError, IOError):
                        cros_build_lib.Warning(
                            'Cannot rev %s\n' % ebuild.package +
                            'Note you will have to go into %s '
                            'and reset the git repo yourself.' % overlay)
                        raise

                if messages:
                    portage_utilities.EBuild.CommitChange(
                        '\n\n'.join(messages), overlay)

                if cros_build_lib.IsInsideChroot():
                    # Regenerate caches if need be.  We do this all the time to
                    # catch when users make changes without updating cache files.
                    queue.put([overlay])

    if command == 'commit':
        if cros_build_lib.IsInsideChroot():
            CleanStalePackages(options.boards.split(':'), new_package_atoms)
        if options.drop_file:
            osutils.WriteFile(options.drop_file, ' '.join(revved_packages))
Exemple #29
0
def SetupBuild(options):
    """Set up parameters needed for the build.

  This checks the current environment and options and sets up various things
  needed for the build, including 'base' which holds the base flags for
  passing to the U-Boot Makefile.

  Args:
    options: Command line options

  Returns:
    Base flags to use for U-Boot, as a list.
  """
    global arch, board, compiler, family, outdir, smdk, uboard, vendor, verbose

    if not verbose:
        verbose = options.verbose != 0

    logger.setLevel(options.verbose)

    Log('Building for %s' % options.board)

    # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
    # But don't mess up upstream boards which use _ in their name.
    parts = options.board.split('_')
    if parts[0] in ['daisy', 'peach']:
        board = parts[0]
    else:
        board = options.board

    # To allow this to be run from 'cros_sdk'
    if in_chroot:
        os.chdir(os.path.join(src_root, 'third_party', 'u-boot', 'files'))

    base_board = board

    if options.verified:
        base_board = 'chromeos_%s' % base_board

    uboard = UBOARDS.get(base_board, base_board)
    Log('U-Boot board is %s' % uboard)

    # Pull out some information from the U-Boot boards config file
    family = None
    with open('boards.cfg') as f:
        for line in f:
            if uboard in line:
                if line[0] == '#':
                    continue
                fields = line.split()
                if not fields:
                    continue
                arch = fields[1]
                fields += [None, None, None]
                smdk = fields[3]
                vendor = fields[4]
                family = fields[5]
                break
    if not arch:
        cros_build_lib.Die("Selected board '%s' not found in boards.cfg." %
                           board)

    vboot = os.path.join('build', board, 'usr')
    if arch == 'x86':
        family = 'em100'
        if in_chroot:
            compiler = 'i686-pc-linux-gnu-'
        else:
            compiler = '/opt/i686/bin/i686-unknown-elf-'
    elif arch == 'arm':
        if in_chroot:
            # Use the Chrome OS toolchain
            compiler = 'armv7a-cros-linux-gnueabi-'
        else:
            compiler = glob.glob('/opt/linaro/gcc-linaro-arm-linux-*/bin/*gcc')
            if not compiler:
                cros_build_lib.Die(
                    """Please install an ARM toolchain for your machine.
'Install a Linaro toolchain from:'
'https://launchpad.net/linaro-toolchain-binaries'
'or see cros/commands/cros_chrome_sdk.py.""")
            compiler = compiler[0]
        compiler = re.sub('gcc$', '', compiler)
    elif arch == 'sandbox':
        compiler = ''
    else:
        cros_build_lib.Die("Selected arch '%s' not supported." % arch)

    if not options.build:
        options.incremental = True

    cpus = multiprocessing.cpu_count()

    outdir = os.path.join(OUT_DIR, uboard)
    base = [
        'make',
        '-j%d' % cpus,
        'O=%s' % outdir,
        'ARCH=%s' % arch,
        'CROSS_COMPILE=%s' % compiler, '--no-print-directory',
        'HOSTSTRIP=true',
        'DEV_TREE_SRC=%s-%s' % (family, options.dt), 'QEMU_ARCH='
    ]

    if options.verbose < 2:
        base.append('-s')

    if options.ro and options.rw:
        cros_build_lib.Die('Cannot specify both --ro and --rw options')
    if options.ro:
        base.append('CROS_RO=1')
        options.small = True

    if options.rw:
        base.append('CROS_RW=1')
        options.small = True

    if options.small:
        base.append('CROS_SMALL=1')
    else:
        base.append('CROS_FULL=1')

    if options.verified:
        base += [
            'VBOOT=%s' % vboot, 'MAKEFLAGS_VBOOT=DEBUG=1', 'QUIET=1',
            'CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS',
            'VBOOT_SOURCE=%s/platform/vboot_reference' % src_root
        ]
        base.append('VBOOT_DEBUG=1')

    # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
    # to a recent change, the need for which I didn't fully understand. But
    # U-Boot doesn't normally use this. We have added an option to U-Boot to
    # enable use of <stdint.h> and without it vboot will fail to build. So we
    # need to enable it where ww can. We can't just enable it always since
    # that would prevent this script from building other non-Chrome OS boards
    # with a different (older) toolchain, or Chrome OS boards without vboot.
    # So use USE_STDINT if the toolchain supports it, and not if not. This
    # file was originally part of glibc but has recently migrated to the
    # compiler so it is reasonable to use it with a stand-alone program like
    # U-Boot. At this point the comment has got long enough that we may as
    # well include some poetry which seems to be sorely lacking the code base,
    # so this is from Ogden Nash:
    #    To keep your marriage brimming
    #    With love in the loving cup,
    #    Whenever you're wrong, admit it;
    #    Whenever you're right, shut up.
    cmd = [CompilerTool('gcc'), '-ffreestanding', '-x', 'c', '-c', '-']
    result = cros_build_lib.RunCommandCaptureOutput(
        cmd, input='#include <stdint.h>', **kwargs)
    if result.returncode == 0:
        base.append('USE_STDINT=1')

    if options.trace:
        base.append('FTRACE=1')
    if options.separate:
        base.append('DEV_TREE_SEPARATE=1')

    if options.incremental:
        # Get the correct board for cros_write_firmware
        config_mk = '%s/include/config.mk' % outdir
        if not os.path.exists(config_mk):
            cros_build_lib.Warning('No build found for %s - dropping -i' %
                                   board)
            options.incremental = False

    config_mk = 'include/config.mk'
    if os.path.exists(config_mk):
        cros_build_lib.Warning("Warning: '%s' exists, try 'make distclean'" %
                               config_mk)

    # For when U-Boot supports ccache
    # See http://patchwork.ozlabs.org/patch/245079/
    if use_ccache:
        os.environ['CCACHE'] = 'ccache'

    return base