| # Copyright 2020 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from google.protobuf import json_format as jsonpb |
| |
| from recipe_engine import recipe_api |
| |
| from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2 |
| |
| |
| class ToolchainApi(recipe_api.RecipeApi): |
| """Helpers for building Fuchsia toolchains.""" |
| |
| def strip_runtimes( |
| self, name, spec, path, build_id_subpath, readelf, dump_syms=None, objcopy=None |
| ): |
| """Prepares runtimes for deployment and generates a runtime.json file. |
| |
| Given a spec in the schema of runtime.json, does the following: |
| |
| - Strips the runtime binaries (optional) |
| - Creates the .build-id repo (optional) |
| - Creates the breakpad .sym file and places in .build-id (optional) |
| |
| The path to the debug binary and (optional) sym file are then |
| included in the final runtime.json output, which is saved to a file. |
| |
| Args: |
| name (str): Step name. |
| spec (list): The runtime spec. |
| //zircon/public/gn/toolchain/clang.gni:clang_runtime sets the |
| schema. "dist" keys may optionally be a glob pattern matching |
| exactly one file. "soname", "debug", and "breakpad" keys will |
| be filled in. |
| path (Path): The path where runtime.json will be generated. |
| build_id_subpath (str): The subpath relative to path where the |
| build-id repo lives. |
| readelf (Path): The path to a readelf binary. |
| dump_syms (Path or None): An optional path to dump_syms for |
| generating Breakpad symbols. |
| objcopy (Path or None): An optional path to llvm-objcopy for |
| stripping the supplied runtimes. The .build-id repo is |
| populated for you if this is supplied. |
| """ |
| runtimes_args = [ |
| "--dir", |
| path, |
| "--build-id-repo", |
| build_id_subpath, |
| "--readelf", |
| readelf, |
| ] |
| if dump_syms: |
| runtimes_args += ["--dump_syms", dump_syms] |
| if objcopy: |
| runtimes_args += ["--objcopy", objcopy] |
| self.m.python( |
| name, |
| script=self.resource("runtimes.py"), |
| venv=True, |
| args=runtimes_args, |
| stdin=self.m.json.input(spec), |
| stdout=self.m.json.output( |
| leak_to=path.join("runtime.json"), name="runtime.json" |
| ), |
| ) |
| |
| def trigger_build( |
| self, |
| toolchain_name, |
| gitiles_repository, |
| gitiles_revision, |
| digest, |
| builders, |
| gitiles_ref="refs/heads/main", |
| git_repository_info=None, |
| git_revision_info=None, |
| fuchsia_host="fuchsia.googlesource.com", |
| fuchsia_project="integration", |
| fuchsia_ref="refs/heads/releases/canary", |
| ): |
| """Schedules a build of Fuchsia with the newly built toolchain. |
| |
| Required args: |
| toolchain_name (str): The name of the build property used for |
| overriding the toolchain. |
| gitiles_repository (str): URL of the gitiles repository for this toolchain. |
| gitiles_revision (str): Hash of the toolchain commit in the gitiles repository. |
| digest (str): Digest of the CAS upload of the toolchain build. |
| builders ([str]): List of builders to schedule. |
| Optional args: |
| gitiles_ref (str): Git ref of the toolchain. Default "refs/heads/main". |
| git_repository_info (str): String to publish under the |
| git_repository property of the build. For informational |
| purposes. Defaults to gitiles_repository. |
| git_revision_info (str): String to publish under the |
| git_revision property of the build. For informational purposes. |
| Defaults to gitiles_revision. |
| fuchsia_host (str): Hostname of the Fuchsia git server. |
| fuchsia_project (str): Name of the project repository to build. |
| fuchsia_ref (str): Git ref of the project to build. |
| """ |
| |
| # TODO(43620): It's possible some of this knowledge needs to go in |
| # api.build. Ideally the list of bots to test for each toolchain |
| # would be shared with/generated from fuchsia.star directly. |
| |
| fuchsia_rev = self.m.git.get_remote_branch_head( |
| "https://%s/%s" % (fuchsia_host, fuchsia_project), fuchsia_ref |
| ) |
| |
| if git_repository_info is None: |
| git_repository_info = gitiles_repository |
| if git_revision_info is None: |
| git_revision_info = gitiles_revision |
| |
| self.m.scheduler.emit_trigger( |
| self.m.scheduler.BuildbucketTrigger( |
| properties={ |
| toolchain_name: { |
| # Purely for informational purposes; not consumed by |
| # any recipe or recipe module. |
| "git_repository": git_repository_info, |
| "git_revision": git_revision_info, |
| }, |
| "$fuchsia/build": { |
| toolchain_name: {"source": "isolated", "version": digest} |
| }, |
| "$fuchsia/checkout": { |
| "gitiles_commit": jsonpb.MessageToDict( |
| common_pb2.GitilesCommit( |
| host=fuchsia_host, |
| project=fuchsia_project, |
| id=fuchsia_rev, |
| ) |
| ) |
| }, |
| }, |
| tags={ |
| "buildset": "commit/gitiles/%s/+/%s" |
| % (gitiles_repository.split("://")[1], gitiles_revision), |
| "gitiles_ref": gitiles_ref, |
| }, |
| ), |
| project=self.m.buildbucket.build.builder.project, |
| jobs=builders, |
| ) |