blob: 7dba7f83435593aa15db05c5ea1ae47c68b23291 [file] [log] [blame]
# Copyright 2018 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""setup_board builds the sysroot for a board.
The setup_board process includes the simple directory creations, installs
several configuration files, sets up portage command wrappers and configs,
and installs the toolchain and some core dependency packages (e.g. kernel
headers, gcc-libs).
"""
import argparse
import logging
from chromite.lib import build_target_lib
from chromite.lib import commandline
from chromite.lib import portage_util
from chromite.lib import sysroot_lib
from chromite.lib.telemetry import trace
from chromite.service import sysroot
tracer = trace.get_tracer(__name__)
def GetParser():
"""Build the argument parser."""
parser = commandline.ArgumentParser(description=__doc__)
parser.add_argument(
"-b",
"--board",
"--build-target",
required=True,
dest="board",
help="The name of the board to set up.",
)
parser.add_argument(
"--default",
action="store_true",
default=False,
help="Set the board to the default board in your chroot.",
)
parser.add_argument(
"--force",
action="store_true",
default=False,
help="Force re-creating the board root.",
)
# The positive and negative versions of the arguments are used.
parser.add_bool_argument(
"--usepkg",
True,
"Use binary packages to bootstrap.",
"Do not use binary packages to bootstrap.",
)
# Legacy negative version of the argument.
parser.add_argument(
"--nousepkg",
action="store_false",
dest="usepkg",
help="Do not use binary packages to bootstrap.",
)
advanced = parser.add_argument_group("Advanced Options")
advanced.add_argument(
"--accept-licenses", help="Licenses to append to the accept list."
)
# Build target related arguments.
target = parser.add_argument_group("Advanced Build Target Options")
target.add_argument(
"--profile",
help="The portage configuration profile to use. Profile "
"must be located in overlay-board/profiles.",
)
target.add_argument("--board-root", type="str_path", help="Board root.")
target.add_bool_argument(
"--public",
default=None,
enabled_desc=(
"Simulate a public build by selecting only public overlays. Note "
"behavior differences may still exist when using an actual public "
"checkout, i.e., this is for convenience only. Don't use this to "
"produce a build which is guaranteed to be free of all private "
"artifacts. By default, this is enabled for boards without a "
"private overlay."
),
disabled_desc=(
"Disable --public on a normally-public board (e.g., amd64-generic)."
),
)
target.add_argument(
"--reuse-configs",
action="store_true",
help="Reuse the build target configs from the existing sysroot.",
)
# Arguments related to the build itself.
build = parser.add_argument_group("Advanced Build Modification Options")
build.add_argument(
"--jobs",
type=int,
help="Maximum number of packages to build in parallel.",
)
build.add_argument(
"--regen-configs",
action="store_true",
default=False,
help="Regenerate all config files (useful for "
"modifying profiles without rebuild).",
)
build.add_argument(
"--quiet",
action="store_true",
default=False,
help="Don't print warnings when board already exists.",
)
build.add_bool_argument(
"--setup-toolchains",
default=False,
enabled_desc="Setup or update toolchains for the board.",
disabled_desc="Use currently installed toolchain versions.",
)
build.add_argument(
"--skip-toolchain-update",
action="store_false",
dest="toolchain_update",
deprecated="Alias for --no-toolchain-update",
)
build.add_bool_argument(
"--update-chroot",
default=None,
enabled_desc="Call update_chroot.",
disabled_desc="Don't call update_chroot.",
)
build.add_argument(
"--skip-chroot-upgrade",
action="store_false",
dest="update_chroot",
deprecated="Alias for --no-update-chroot.",
)
build.add_argument(
"--skip-board-pkg-init",
action="store_true",
default=False,
help="Don't emerge any packages during setup_board into "
"the board root.",
)
build.add_argument(
"--reuse-pkgs-from-local-boards",
dest="reuse_local",
action="store_true",
default=False,
help="Bootstrap from local packages instead of remote packages.",
)
build.add_argument(
"--backtrack",
type=int,
default=sysroot.BACKTRACK_DEFAULT,
help="See emerge --backtrack.",
)
parser.add_argument(
"--fewer-binhosts",
dest="expanded_binhost_inheritance",
default=True,
action="store_false",
help=argparse.SUPPRESS,
)
return parser
def _ParseArgs(args):
"""Parse and validate arguments."""
parser = GetParser()
opts = parser.parse_args(args)
# Translate raw options to config objects.
opts.build_target = build_target_lib.BuildTarget(
opts.board,
build_root=opts.board_root,
profile=opts.profile,
public=opts.public,
)
if opts.reuse_configs:
sysroot_path = (
opts.board_root
or build_target_lib.get_default_sysroot_path(opts.board)
)
sysroot_inst = sysroot_lib.Sysroot(sysroot_path)
if not sysroot_inst.Exists():
parser.error(
"--reuse-configs can only be used with an existing sysroot."
)
try:
opts.build_target = sysroot_inst.build_target
except sysroot_lib.NoBuildTargetFileError:
logging.exception("No build target configuration file.")
parser.error(
"The sysroot does not have a build target configuration "
"file, it probably just predates the file. If this error "
"persists after setting up the board without using "
"--reuse-configs please file a bug for the CrOS Build team."
)
update_chroot = opts.update_chroot
if update_chroot is None:
update_chroot = opts.setup_toolchains
opts.run_config = sysroot.SetupBoardRunConfig(
set_default=opts.default,
force=opts.force,
usepkg=opts.usepkg,
jobs=opts.jobs,
regen_configs=opts.regen_configs,
quiet=opts.quiet,
update_toolchain=opts.setup_toolchains,
upgrade_chroot=update_chroot,
init_board_pkgs=not opts.skip_board_pkg_init,
local_build=opts.reuse_local,
expanded_binhost_inheritance=opts.expanded_binhost_inheritance,
use_cq_prebuilts=opts.usepkg,
backtrack=opts.backtrack,
)
opts.Freeze()
return opts
def main(argv):
commandline.RunInsideChroot()
opts = _ParseArgs(argv)
with tracer.start_as_current_span("chromite.scripts.setup_board") as span:
try:
span.set_attributes(
{
"build_target": opts.build_target.name,
"update_chroot": opts.run_config.update_chroot,
"update_toolchain": opts.run_config.update_toolchain,
"set_default": opts.run_config.set_default,
}
)
sysroot.SetupBoard(
opts.build_target, opts.accept_licenses, opts.run_config
)
except portage_util.MissingOverlayError as e:
# Add a bit more user-friendly message as people can typo names
# easily.
logging.error(
"%s\n"
"Double check the --board setting and make sure you're syncing "
"the right manifest (internal-vs-external).",
e,
)
return 1
except sysroot.Error as e:
logging.error(e)
return 1