blob: 0bbfcbf25e291ffc0cb1f077b946ebacc2783161 [file] [log] [blame] [edit]
# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
load("@bazel_skylib//lib:paths.bzl", "paths")
def _binary_package_info_init(
*,
file,
direct_runtime_deps,
**kwargs):
if "transitive_runtime_deps" in kwargs or "all_files" in kwargs:
fail("transitive_runtime_deps and all_files are autogenerated. Don't pass them in yourself.")
transitive_runtime_deps = depset(
transitive = [
depset(
[dep],
transitive = [dep.transitive_runtime_deps],
order = "postorder",
)
for dep in direct_runtime_deps
],
order = "postorder",
)
all_files = depset(
[file],
transitive = [pkg.all_files for pkg in direct_runtime_deps],
order = "postorder",
)
return dict(
file = file,
all_files = all_files,
direct_runtime_deps = tuple(direct_runtime_deps),
transitive_runtime_deps = transitive_runtime_deps,
**kwargs
)
BinaryPackageInfo, _new_binary_package_info = provider(
"""
Describes a Portage binary package.
A rule providing BinaryPackageInfo must also provide BinaryPackageSetInfo
that covers all transitive runtime dependencies of this package.
All fields in this provider must have immutable types (i.e. no list/dict)
because a BinaryPackageInfo is always accompanied by a BinaryPackageSetInfo
referencing it with a depset.
""",
fields = {
"file": """
File: A binary package file (.tbz2) of this package.
""",
"layer": """
File: The layer that contains the installed package. This
will only be set if the package doesn't require any pre/post install
hooks. This layer can be used directly instead of having to install
the package manually.
""",
"contents": """
ContentsLayersInfo: Locates installed/staged contents layers that
are used to implement fast package installation.
Since a BinaryPackageInfo contains exactly one ContentsLayersInfo,
a binary package can be installed only to a single sysroot directory
that is specified statically in the rule building BinaryPackageInfo.
An implication of this is that, when building a host package, we
have to statically choose whether to install it to "/" or
"/build/amd64-host".
""",
"category": """
str: The category of this package.
""",
"package_name": """
str: The name of this package.
""",
"version": """
str: The version of this package.
""",
"slot": """
str: The slot this package is installed to.
""",
"direct_runtime_deps": """
tuple[BinaryPackageInfo]: Direct runtime dependencies of the
package. See the provider description for why this field is a tuple,
not a list.
""",
# The following fields are automatically derived from other fields by
# the constructor. Don't set them yourself.
"all_files": """
Depset[File]: All binary package files including this package's one
itself and all transitive runtime dependencies.
The Depset must be constructed in a way so that its to_list()
returns packages in a valid installation order, i.e. a package's
runtime dependencies are fully satisfied by packages that appear
before it.
""",
"transitive_runtime_deps": """
Depset[BinaryPackageInfo]: Transitive runtime dependencies of the
package. Note that this depset does *NOT* contain this package
itself, just because it is impossible to construct a
self-referencing provider.
The Depset must be constructed in a way so that its to_list()
returns packages in a valid installation order, i.e. a package's
runtime dependencies are fully satisfied by packages that appear
before it.
""",
},
init = _binary_package_info_init,
)
ContentsLayersInfo = provider(
"""
Locates an installed/staged contents layer for a package.
This is an essentially a named struct. It always appears in an attribute of
BinaryPackageInfo.
""",
fields = {
"sysroot": """
str: A sysroot directory path where the package is installed. It
must be either "/build/<board>" or "/".
""",
"installed": """
File: A durable tree directory containing an installed contents
layer.
""",
"staged": """
File: A durable tree directory containing a staged contents layer.
""",
},
)
BinaryPackageSetInfo = provider(
"""
Represents a set of Portage binary packages.
A package set represented by this provider is always closed over transitive
runtime dependencies. That is, if the set contains a package X, it also
contains all transitive dependencies of the package X.
A rule providing BinaryPackageInfo must also provide BinaryPackageSetInfo
that covers all transitive runtime dependencies of this package.
""",
fields = {
"packages": """
Depset[BinaryPackageInfo]: All Portage binary packages included in
this set.
The Depset must be constructed in a way so that its to_list()
returns packages in a valid installation order, i.e. a package's
runtime dependencies are fully satisfied by packages that appear
before it.
""",
"files": """
Depset[File]: All Portage binary package files included in this set.
The Depset must be constructed in a way so that its to_list()
returns packages in a valid installation order, i.e. a package's
runtime dependencies are fully satisfied by packages that appear
before it.
""",
},
)
OverlayInfo = provider(
"Portage overlay info",
fields = {
"path": """
String: Path inside the container where the overlay's ebuilds are
mounted.
""",
"layer": """
File: A file which represents an overlay layer. A layer
file can be a tar file (.tar or .tar.zst).
""",
},
)
OverlaySetInfo = provider(
"Portage overlay set info",
fields = {
"layers": """
File[]: A list of files each of which represents an overlay. A layer
file can be a directory or a tar file (.tar or .tar.zst). Layers are
ordered from lower to upper; in other words, a file from a layer can
be overridden by one in another layer that appears later in the
list.
""",
},
)
SDKInfo = provider(
"""
Contains information necessary to mount an ephemeral CrOS SDK.
""",
fields = {
"layers": """
File[]: A list of files each of which represents a file system layer
of the SDK. A layer file can be a directory or a tar file (.tar or
.tar.zst). Layers are ordered from lower to upper; in other words,
a file from a layer can be overridden by one in another layer that
appears later in the list.
""",
"packages": """
Depset[BinaryPackageInfo]: The packages that are installed in the
SDK layer.
""",
},
)
EbuildLibraryInfo = provider(
"Ebuild library info",
fields = {
"strip_prefix": """
str: The prefix to strip off the files when installing into the sdk.
""",
"headers": """
Depset[File]: Headers provided by the package.
""",
"pkg_configs": """
Depset[File]: .pc files provided by the package.
""",
"shared_libs": """
Depset[File]: .so files provided by the package.
""",
"static_libs": """
Depset[File]: .a files provided by the package.
""",
},
)
# rustc flags to enable debug symbols.
RUSTC_DEBUG_FLAGS = ["--codegen=debuginfo=2"]
def _workspace_root(label):
return paths.join("..", label.workspace_name) if label.workspace_name else ""
def relative_path_in_label(file, label):
return paths.relativize(file.short_path, paths.join(_workspace_root(label), label.package))
def relative_path_in_package(file):
owner = file.owner
if owner == None:
fail("File does not have an associated owner label")
return relative_path_in_label(file, owner)
def compute_input_file_path(file, use_runfiles):
"""
Computes a file path referring to the given input file.
This function helps you to refer to input file path correctly in the two
major different working directory configurations: execroot and runfiles.
When you are going to use a file in a build action run by "bazel build",
pass use_runfiles=False. The function will just return `file.path` that is
valid in an action execroot.
When you are going to use a file in a binary file invoked for "bazel run"
or "bazel test", pass use_runfiles=True and make sure to include the file
in the runfiles of the binary. Then this function will return a file path
you can refer to the file in the runfile tree of the binary.
Args:
file: File: An input file.
use_runfiles: bool: Whether to refer to the input file in a path
relative to execroot or runfiles directory.
Returns:
A file path referring to the given file.
"""
if file.owner == None:
fail("Unable to compute a path for a file not associated with a label")
if use_runfiles:
return paths.join(_workspace_root(file.owner), file.short_path)
else:
return file.path
def single_binary_package_set_info(package_info):
"""
Creates BinaryPackageSetInfo for a single binary package.
Args:
package_info: BinaryPackageInfo: A provider describing a binary package.
Returns:
BinaryPackageSetInfo: A provider representing all transitive runtime
dependencies of the given binary package.
"""
return BinaryPackageSetInfo(
packages = depset(
[package_info],
transitive = [
depset(
[dep],
transitive = [dep.transitive_runtime_deps],
order = "postorder",
)
for dep in package_info.direct_runtime_deps
],
order = "postorder",
),
files = package_info.all_files,
)