Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ bzl_library(
srcs = ["extensions.bzl"],
visibility = ["//visibility:public"],
deps = [
"//rs/platforms:triples",
"//rs/private:annotations",
"//rs/private:cargo_credentials",
"//rs/private:cargo_workspace_graph",
Expand Down
24 changes: 23 additions & 1 deletion rs/extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ load("@aspect_tools_telemetry_report//:defs.bzl", "TELEMETRY") # buildifier: di
load("@bazel_lib//lib:repo_utils.bzl", "repo_utils")
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@rs_rust_host_tools//:defs.bzl", "RS_HOST_CARGO_LABEL")
load("//rs/platforms:triples.bzl", "SUPPORTED_EXEC_TRIPLES")
load("//rs/private:annotations.bzl", "annotation_for", "build_annotation_map", "well_known_annotation_snippet_paths")
load("//rs/private:cargo_credentials.bzl", "load_cargo_credentials")
load(
Expand All @@ -26,7 +27,7 @@ load("//rs/private:git_crate_metadata_repository.bzl", "git_crate_metadata_repos
load("//rs/private:lint_flags.bzl", "cargo_toml_lint_flags")
load("//rs/private:registry_config_repository.bzl", "registry_config_repository")
load("//rs/private:registry_utils.bzl", "CRATES_IO_REGISTRY", "registry_config_repo_name")
load("//rs/private:repository_utils.bzl", "render_select")
load("//rs/private:repository_utils.bzl", "exec_target_name", "render_select")
load("//rs/private:toml2json.bzl", "run_toml2json")

# Bazel 8 does not define attr.label_list_dict.
Expand Down Expand Up @@ -267,6 +268,7 @@ def _generate_hub_and_spokes(
annotations = annotations,
platform_triples = platform_triples,
materialize_workspace_members = False,
exec_platform_triples = SUPPORTED_EXEC_TRIPLES,
validate_lockfile = validate_lockfile,
debug = debug,
dep_label_prefix = "@%s//:" % hub_name,
Expand All @@ -277,6 +279,7 @@ def _generate_hub_and_spokes(
platform_cfg_attrs = workspace_resolution.platform_cfg_attrs
workspace_dep_labels_by_triple = workspace_resolution.workspace_dep_labels_by_triple
workspace_dep_versions_by_name = workspace_resolution.workspace_dep_versions_by_name
exec_feature_resolutions_by_fq_crate = workspace_resolution.exec_feature_resolutions_by_fq_crate

_date(mctx, "set up initial deps!")

Expand All @@ -290,6 +293,7 @@ def _generate_hub_and_spokes(
source = package["source"]

feature_resolutions = feature_resolutions_by_fq_crate[_fq_crate(crate_name, version)]
exec_feature_resolutions = exec_feature_resolutions_by_fq_crate[_fq_crate(crate_name, version)]

annotation = annotation_for(annotations, crate_name, version, hub_name)
suggested_annotation = None
Expand Down Expand Up @@ -323,6 +327,7 @@ crate.annotation(
gen_build_script = annotation.gen_build_script,
build_script_deps = [],
build_script_deps_select = _select(feature_resolutions.build_deps),
exec_build_script_deps_select = _select(exec_feature_resolutions.build_deps),
build_script_data = annotation.build_script_data,
build_script_data_select = annotation.build_script_data_select,
build_script_env = annotation.build_script_env,
Expand All @@ -338,11 +343,17 @@ crate.annotation(
deps = annotation.deps,
crate_tags = annotation.tags,
deps_select = _select(feature_resolutions.deps),
exec_deps_select = _select(exec_feature_resolutions.deps),
aliases = feature_resolutions.aliases,
exec_aliases = exec_feature_resolutions.aliases,
crate_features = annotation.crate_features,
crate_features_select = _select(feature_resolutions.features_enabled),
exec_crate_features_select = _select(exec_feature_resolutions.features_enabled),
target_active = bool(feature_resolutions.active),
exec_active = bool(exec_feature_resolutions.active),
use_legacy_rules_rust_platforms = use_legacy_rules_rust_platforms,
)
package["exec_target_name"] = exec_target_name(struct(**kwargs), crate_name)

repo_name = _spoke_repo(hub_name, crate_name, version)
package["target_repo_name"] = repo_name
Expand Down Expand Up @@ -438,6 +449,14 @@ alias(
actual = "{actual}",
)""".format(name = name, version = version, actual = _target_label(target_repo_name, target_package_path, name)))

exec_target = package["exec_target_name"]
if exec_target:
hub_contents.append("""
alias(
name = "{name}-{version}_exec",
actual = "{actual}",
)""".format(name = name, version = version, actual = _target_label(target_repo_name, target_package_path, exec_target)))

for binary in annotation.gen_binaries:
hub_contents.append("""
alias(
Expand Down Expand Up @@ -927,6 +946,9 @@ _annotation = tag_class(
"crate_features_select": attr.string_list_dict(
doc = "A list of strings to add to a crate's `rust_library::crate_features` attribute. Keys should be the platform triplet. Value should be a list of features.",
),
"is_proc_macro": attr.bool(
doc = "Resolve this proc-macro crate and its dependencies in the exec universe.",
),
"data": attr.label_list(
doc = "A list of labels to add to a crate's `rust_library::data` attribute.",
),
Expand Down
2 changes: 2 additions & 0 deletions rs/private/annotations.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def _crate_annotation(
tags = [],
crate_features = [],
crate_features_select = {},
is_proc_macro = False,
gen_binaries = [],
extra_aliased_targets = {},
rustc_flags = [],
Expand Down Expand Up @@ -43,6 +44,7 @@ def _crate_annotation(
tags = tags,
crate_features = crate_features,
crate_features_select = crate_features_select,
is_proc_macro = is_proc_macro,
gen_binaries = gen_binaries,
extra_aliased_targets = extra_aliased_targets,
rustc_flags = rustc_flags,
Expand Down
90 changes: 76 additions & 14 deletions rs/private/cargo_workspace_graph.bzl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
load("@bazel_skylib//lib:paths.bzl", "paths")
load("//rs/private:cfg_parser.bzl", "cfg_matches_expr_for_cfg_attrs", "triple_to_cfg_attrs")
load("//rs/private:resolver.bzl", "resolve")
load("//rs/private:resolver.bzl", "resolve", "seed_exec_build_dependencies")
load("//rs/private:select_utils.bzl", "compute_select")
load("//rs/private:semver.bzl", "select_matching_version")

Expand Down Expand Up @@ -64,6 +64,7 @@ def cfg_match_info_for_target(target, platform_cfg_attrs, cfg_match_cache):

def new_feature_resolutions(package_index, possible_deps, possible_features, platform_triples):
return struct(
active = set(),
features_enabled = {triple: set() for triple in platform_triples},
build_deps = {triple: set() for triple in platform_triples},
deps = {triple: set() for triple in platform_triples},
Expand Down Expand Up @@ -420,10 +421,12 @@ def _resolve_possible_deps(
packages,
resolver_versions_by_name,
feature_resolutions_by_fq_crate,
proc_macro_fq_crates,
platform_triples,
platform_cfg_attrs,
cfg_match_cache,
dep_label_prefix):
dep_label_prefix,
dep_label_suffix = ""):
for package in packages:
name = package["name"]
deps_by_name = {}
Expand Down Expand Up @@ -460,8 +463,10 @@ def _resolve_possible_deps(
dep_fq = fq_crate(dep_package, resolved_version)
if dep_fq not in feature_resolutions_by_fq_crate:
fail("Resolved %s dependency %s but no crate metadata was available" % (name, dep_fq))
dep["bazel_target"] = "%s%s" % (dep_label_prefix, dep_fq)
dep["bazel_target"] = "%s%s%s" % (dep_label_prefix, dep_fq, dep_label_suffix)
dep["feature_resolutions"] = feature_resolutions_by_fq_crate[dep_fq]
if dep_fq in proc_macro_fq_crates:
dep["is_proc_macro"] = True

target = dep.get("target")
match_info = cfg_match_info_for_target(target, platform_cfg_attrs, cfg_match_cache)
Expand All @@ -472,6 +477,11 @@ def _resolve_possible_deps(
else:
dep["target"] = set(match_info.matches)

def _apply_annotation_features(feature_resolutions, annotation):
for triple, features in feature_resolutions.features_enabled.items():
features.update(annotation.crate_features)
features.update(annotation.crate_features_select.get(triple, []))

def resolve_cargo_workspace_members(
ctx,
*,
Expand All @@ -483,19 +493,20 @@ def resolve_cargo_workspace_members(
annotations,
platform_triples,
materialize_workspace_members,
exec_platform_triples = [],
validate_lockfile = True,
debug = False,
dep_label_prefix = "//:",
skip_internal_rustc_placeholder_crates = True,
watch_manifests = False,
use_legacy_rules_rust_platforms = False):
platform_cfg_attrs = [triple_to_cfg_attrs(triple) for triple in platform_triples]
platform_cfg_attrs_by_triple = {}
for cfg_attr in platform_cfg_attrs:
platform_cfg_attrs_by_triple[cfg_attr["_triple"]] = cfg_attr
platform_cfg_attrs_by_triple = {cfg_attr["_triple"]: cfg_attr for cfg_attr in platform_cfg_attrs}

cfg_match_cache = {None: struct(matches = platform_triples, uses_feature_cfg = False)}

exec_platform_cfg_attrs_by_triple = {triple: triple_to_cfg_attrs(triple) for triple in exec_platform_triples}

workspace_member_keys = {}
for package in cargo_metadata["packages"]:
workspace_member_keys[(package["name"], package["version"])] = True
Expand Down Expand Up @@ -535,16 +546,56 @@ def resolve_cargo_workspace_members(

resolver_packages.append(resolver_package)

exec_feature_resolutions_by_fq_crate = {}
exec_resolver_packages = []
if exec_platform_triples:
for package in resolver_packages:
target_resolution = package["feature_resolutions"]
target_resolution.build_deps.update({triple: set() for triple in exec_platform_triples})
exec_resolution = new_feature_resolutions(
target_resolution.package_index,
[dict(dep) for dep in target_resolution.possible_deps],
target_resolution.possible_features,
exec_platform_triples,
)
exec_feature_resolutions_by_fq_crate[fq_crate(package["name"], package["version"])] = exec_resolution
exec_resolver_packages.append(dict(package, feature_resolutions = exec_resolution))

proc_macro_fq_crates = set()
for crate, annotation_versions in annotations.items():
for version_key, annotation in annotation_versions.items():
if not getattr(annotation, "is_proc_macro", False):
continue
versions = resolver_versions_by_name.get(crate, [])
if version_key != "*":
versions = [version_key] if version_key in versions else []
for version in versions:
proc_macro_fq_crates.add(fq_crate(crate, version))

_resolve_possible_deps(
resolver_packages,
resolver_versions_by_name,
feature_resolutions_by_fq_crate,
proc_macro_fq_crates,
platform_triples,
platform_cfg_attrs,
cfg_match_cache,
dep_label_prefix,
)

if exec_platform_triples:
_resolve_possible_deps(
exec_resolver_packages,
resolver_versions_by_name,
exec_feature_resolutions_by_fq_crate,
proc_macro_fq_crates,
exec_platform_triples,
exec_platform_cfg_attrs_by_triple.values(),
{None: struct(matches = exec_platform_triples, uses_feature_cfg = False)},
dep_label_prefix,
dep_label_suffix = "_exec",
)

workspace_fq_deps = compute_workspace_fq_deps(workspace_members, resolver_versions_by_name)
workspace_dep_versions_by_name = {}
workspace_dep_labels_by_triple = {triple: set() for triple in platform_triples}
Expand All @@ -554,6 +605,7 @@ def resolve_cargo_workspace_members(
ctx.watch(package["manifest_path"])

package_feature_resolutions = feature_resolutions_by_fq_crate[fq_crate(package["name"], package["version"])]
package_feature_resolutions.active.update(platform_triples)
if "default" in package.get("features", {}):
for triple in platform_triples:
package_feature_resolutions.features_enabled[triple].add("default")
Expand Down Expand Up @@ -611,8 +663,13 @@ def resolve_cargo_workspace_members(
match_info = cfg_match_info_for_target(target, platform_cfg_attrs, cfg_match_cache)

for triple in match_info.matches:
if dep.get("kind", "normal") == "build":
continue
if not is_first_party_dep or materialize_workspace_members:
workspace_dep_labels_by_triple[triple].add(":" + dep_name)
if dep_fq in proc_macro_fq_crates:
continue
feature_resolutions.active.add(triple)
feature_resolutions.features_enabled[triple].update(features)

for crate, annotation_versions in annotations.items():
Expand All @@ -625,15 +682,19 @@ def resolve_cargo_workspace_members(
if not annotation.crate_features and not annotation.crate_features_select:
continue
for version in target_versions:
features_enabled = feature_resolutions_by_fq_crate[fq_crate(crate, version)].features_enabled
if annotation.crate_features:
for triple in platform_triples:
features_enabled[triple].update(annotation.crate_features)
for triple, features in annotation.crate_features_select.items():
if triple in features_enabled:
features_enabled[triple].update(features)
fq = fq_crate(crate, version)
if exec_platform_triples and getattr(annotation, "is_proc_macro", False):
_apply_annotation_features(exec_feature_resolutions_by_fq_crate[fq], annotation)
else:
_apply_annotation_features(feature_resolutions_by_fq_crate[fq], annotation)
if exec_platform_triples:
_apply_annotation_features(exec_feature_resolutions_by_fq_crate[fq], annotation)

resolve(ctx, resolver_packages, feature_resolutions_by_fq_crate, platform_cfg_attrs_by_triple, debug, include_build_dependencies = not exec_platform_triples)

resolve(ctx, resolver_packages, feature_resolutions_by_fq_crate, platform_cfg_attrs_by_triple, debug)
if exec_platform_triples:
seed_exec_build_dependencies(resolver_packages, exec_resolver_packages, exec_platform_cfg_attrs_by_triple)
resolve(ctx, exec_resolver_packages, exec_feature_resolutions_by_fq_crate, exec_platform_cfg_attrs_by_triple, debug)

for package in packages:
feature_resolutions = package["feature_resolutions"]
Expand All @@ -651,6 +712,7 @@ def resolve_cargo_workspace_members(

return struct(
cfg_match_cache = cfg_match_cache,
exec_feature_resolutions_by_fq_crate = exec_feature_resolutions_by_fq_crate,
feature_resolutions_by_fq_crate = feature_resolutions_by_fq_crate,
platform_cfg_attrs = platform_cfg_attrs,
platform_cfg_attrs_by_triple = platform_cfg_attrs_by_triple,
Expand Down
Loading