Skip to content

Commit

Permalink
cargo-bazel now supports alias_rule to customize the aliases gene…
Browse files Browse the repository at this point in the history
…rated (#2312)

Motivator is to be able to set `default_alias_rule = "opt"` so that all
Cargo fetched 3rd party dependencies are built with
`compilation_mode=opt` regardless of what `compilation_mode` the local
code is being built with.
  • Loading branch information
rickvanprim authored Dec 15, 2023
1 parent c0e6656 commit 3803401
Show file tree
Hide file tree
Showing 41 changed files with 3,254 additions and 62 deletions.
43 changes: 43 additions & 0 deletions crate_universe/3rdparty/crates/alias_rules.bzl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions crate_universe/private/common_utils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,33 @@ def cargo_environ(repository_ctx):
})

return env

def parse_alias_rule(value):
"""Attempts to parse an `AliasRule` from supplied string.
Args:
value (str): String value to be parsed.
Returns:
value: A Rust compatible `AliasRule`.
"""
if value == None:
return None

if value == "alias" or value == "dbg" or value == "fastbuild" or value == "opt":
return value

if value.count(":") != 2:
fail("Invalid custom value for `alias_rule`.\n{}\nValues must be in the format '<label to .bzl>:<rule>'.".format(value))

split = value.rsplit(":", 1)
bzl = Label(split[0])
rule = split[1]

if rule == "alias":
fail("Custom value rule cannot be named `alias`.\n{}".format(value))

return struct(
bzl = str(bzl),
rule = rule,
)
6 changes: 6 additions & 0 deletions crate_universe/private/crate.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Macros used for represeting crates or annotations for existing crates"""

load(":common_utils.bzl", "parse_alias_rule")

def _workspace_member(version, sha256 = None):
"""Define information for extra workspace members
Expand Down Expand Up @@ -83,6 +85,7 @@ def _annotation(
version = "*",
additive_build_file = None,
additive_build_file_content = None,
alias_rule = None,
build_script_data = None,
build_script_tools = None,
build_script_data_glob = None,
Expand Down Expand Up @@ -118,6 +121,8 @@ def _annotation(
additive_build_file_content (str, optional): Extra contents to write to the bottom of generated BUILD files.
additive_build_file (str, optional): A file containing extra contents to write to the bottom of
generated BUILD files.
alias_rule (str, optional): Alias rule to use instead of `native.alias()`. Overrides [render_config](#render_config)'s
'default_alias_rule'.
build_script_data (list, optional): A list of labels to add to a crate's `cargo_build_script::data` attribute.
build_script_tools (list, optional): A list of labels to add to a crate's `cargo_build_script::tools` attribute.
build_script_data_glob (list, optional): A list of glob patterns to add to a crate's `cargo_build_script::data`
Expand Down Expand Up @@ -175,6 +180,7 @@ def _annotation(
struct(
additive_build_file = additive_build_file,
additive_build_file_content = additive_build_file_content,
alias_rule = parse_alias_rule(alias_rule),
build_script_data = build_script_data,
build_script_tools = build_script_tools,
build_script_data_glob = build_script_data_glob,
Expand Down
8 changes: 7 additions & 1 deletion crate_universe/private/generate_utils.bzl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Utilities directly related to the `generate` step of `cargo-bazel`."""

load(":common_utils.bzl", "CARGO_BAZEL_DEBUG", "CARGO_BAZEL_ISOLATED", "REPIN_ALLOWLIST_ENV_VAR", "REPIN_ENV_VARS", "cargo_environ", "execute")
load(":common_utils.bzl", "CARGO_BAZEL_DEBUG", "CARGO_BAZEL_ISOLATED", "REPIN_ALLOWLIST_ENV_VAR", "REPIN_ENV_VARS", "cargo_environ", "execute", "parse_alias_rule")

CARGO_BAZEL_GENERATOR_SHA256 = "CARGO_BAZEL_GENERATOR_SHA256"
CARGO_BAZEL_GENERATOR_URL = "CARGO_BAZEL_GENERATOR_URL"
Expand Down Expand Up @@ -85,6 +85,7 @@ def render_config(
crate_label_template = "@{repository}__{name}-{version}//:{target}",
crate_repository_template = "{repository}__{name}-{version}",
crates_module_template = "//:{file}",
default_alias_rule = "alias",
default_package_name = None,
generate_target_compatible_with = True,
platforms_template = "@rules_rust//rust/platform:{triple}",
Expand Down Expand Up @@ -113,6 +114,10 @@ def render_config(
available format keys are [`{repository}`, `{name}`, `{version}`].
crates_module_template (str, optional): The pattern to use for the `defs.bzl` and `BUILD.bazel`
file names used for the crates module. The available format keys are [`{file}`].
default_alias_rule (str, option): Alias rule to use when generating aliases for all crates. Acceptable values
are 'alias', 'dbg'/'fastbuild'/'opt' (transitions each crate's `compilation_mode`) or a string
representing a rule in the form '<label to .bzl>:<rule>' that takes a single label parameter 'actual'.
See '@crate_index//:alias_rules.bzl' for an example.
default_package_name (str, optional): The default package name to use in the rendered macros. This affects the
auto package detection of things like `all_crate_deps`.
generate_target_compatible_with (bool, optional): Whether to generate `target_compatible_with` annotations on
Expand All @@ -132,6 +137,7 @@ def render_config(
crate_label_template = crate_label_template,
crate_repository_template = crate_repository_template,
crates_module_template = crates_module_template,
default_alias_rule = parse_alias_rule(default_alias_rule),
default_package_name = default_package_name,
generate_target_compatible_with = generate_target_compatible_with,
platforms_template = platforms_template,
Expand Down
46 changes: 46 additions & 0 deletions crate_universe/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ pub struct RenderConfig {
#[serde(default = "default_crate_repository_template")]
pub crate_repository_template: String,

/// Default alias rule to use for packages. Can be overridden by annotations.
#[serde(default)]
pub default_alias_rule: AliasRule,

/// The default of the `package_name` parameter to use for the module macros like `all_crate_deps`.
/// In general, this should be be unset to allow the macros to do auto-detection in the analysis phase.
pub default_package_name: Option<String>,
Expand Down Expand Up @@ -99,6 +103,7 @@ impl Default for RenderConfig {
crate_label_template: default_crate_label_template(),
crates_module_template: default_crates_module_template(),
crate_repository_template: default_crate_repository_template(),
default_alias_rule: AliasRule::default(),
default_package_name: Option::default(),
generate_target_compatible_with: default_generate_target_compatible_with(),
platforms_template: default_platforms_template(),
Expand Down Expand Up @@ -181,6 +186,43 @@ pub enum Checksumish {
},
}

#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Clone)]
pub enum AliasRule {
#[default]
#[serde(rename = "alias")]
Alias,
#[serde(rename = "dbg")]
Dbg,
#[serde(rename = "fastbuild")]
Fastbuild,
#[serde(rename = "opt")]
Opt,
#[serde(untagged)]
Custom { bzl: String, rule: String },
}

impl AliasRule {
pub fn bzl(&self) -> Option<String> {
match self {
AliasRule::Alias => None,
AliasRule::Dbg | AliasRule::Fastbuild | AliasRule::Opt => {
Some("//:alias_rules.bzl".to_owned())
}
AliasRule::Custom { bzl, .. } => Some(bzl.clone()),
}
}

pub fn rule(&self) -> String {
match self {
AliasRule::Alias => "alias".to_owned(),
AliasRule::Dbg => "transition_alias_dbg".to_owned(),
AliasRule::Fastbuild => "transition_alias_fastbuild".to_owned(),
AliasRule::Opt => "transition_alias_opt".to_owned(),
AliasRule::Custom { rule, .. } => rule.clone(),
}
}
}

#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
pub struct CrateAnnotations {
/// Which subset of the crate's bins should get produced as `rust_binary` targets.
Expand Down Expand Up @@ -288,6 +330,9 @@ pub struct CrateAnnotations {

/// Extra targets the should be aliased during rendering.
pub extra_aliased_targets: Option<BTreeMap<String, String>>,

/// Transition rule to use instead of `native.alias()`.
pub alias_rule: Option<AliasRule>,
}

macro_rules! joined_extra_member {
Expand Down Expand Up @@ -347,6 +392,7 @@ impl Add for CrateAnnotations {
patch_tool: self.patch_tool.or(rhs.patch_tool),
patches: joined_extra_member!(self.patches, rhs.patches, BTreeSet::new, BTreeSet::extend),
extra_aliased_targets: joined_extra_member!(self.extra_aliased_targets, rhs.extra_aliased_targets, BTreeMap::new, BTreeMap::extend),
alias_rule: self.alias_rule.or(rhs.alias_rule),
};

output
Expand Down
12 changes: 11 additions & 1 deletion crate_universe/src/context/crate_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::collections::{BTreeMap, BTreeSet};
use cargo_metadata::{Node, Package, PackageId};
use serde::{Deserialize, Serialize};

use crate::config::{CrateId, GenBinaries};
use crate::config::{AliasRule, CrateId, GenBinaries};
use crate::metadata::{CrateAnnotation, Dependency, PairredExtras, SourceAnnotation};
use crate::utils::sanitize_module_name;
use crate::utils::starlark::{Glob, SelectList, SelectMap, SelectStringDict, SelectStringList};
Expand Down Expand Up @@ -325,6 +325,10 @@ pub struct CrateContext {
/// Extra targets that should be aliased.
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub extra_aliased_targets: BTreeMap<String, String>,

/// Transition rule to use instead of `alias`.
#[serde(skip_serializing_if = "Option::is_none")]
pub alias_rule: Option<AliasRule>,
}

impl CrateContext {
Expand Down Expand Up @@ -481,6 +485,7 @@ impl CrateContext {
additive_build_file_content: None,
disable_pipelining: false,
extra_aliased_targets: BTreeMap::new(),
alias_rule: None,
}
.with_overrides(extras)
}
Expand Down Expand Up @@ -629,6 +634,11 @@ impl CrateContext {
self.extra_aliased_targets.append(&mut extra.clone());
}

// Transition alias
if let Some(alias_rule) = &crate_extra.alias_rule {
self.alias_rule.get_or_insert(alias_rule.clone());
}

// Git shallow_since
if let Some(SourceAnnotation::Git { shallow_since, .. }) = &mut self.repository {
*shallow_since = crate_extra.shallow_since.clone()
Expand Down
8 changes: 4 additions & 4 deletions crate_universe/src/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ mod test {
);

assert_eq!(
Digest("379610c3d0f58778cb066f51da66894f10d0e7ea903e4621c61534b4d1344e6f".to_owned()),
Digest("9fcd91ea8e2f7ded4c17895b41ae83b4d6c903f101911aea8bb5282135837b19".to_owned()),
digest,
);
}
Expand Down Expand Up @@ -256,7 +256,7 @@ mod test {
);

assert_eq!(
Digest("c4d5c9def86c1af758a29f144d8d9ab66b1c762d36f878d1e7f9b6e09782c512".to_owned()),
Digest("2b0c255dfcd33196867b604db956aaec0f4aab344941535968e4617c346e44f4".to_owned()),
digest,
);
}
Expand Down Expand Up @@ -287,7 +287,7 @@ mod test {
);

assert_eq!(
Digest("ab158c3dd56e1771bfaed167c661f9c6c33f1effdf6d870f80640384ad1bffaf".to_owned()),
Digest("b1cee7093144f3c5ed4c8b1b9a25df40da997f1b9da2d46ecfda88c67307f66d".to_owned()),
digest,
);
}
Expand Down Expand Up @@ -336,7 +336,7 @@ mod test {
);

assert_eq!(
Digest("b707269f173b2f78ae500317f9ae54df3c05c88972531c277045d0eb756fc681".to_owned()),
Digest("487524c404739b42956cff78e5f26779902f28a61bbb3380f6210f79d1c7fceb".to_owned()),
digest,
);
}
Expand Down
Loading

0 comments on commit 3803401

Please sign in to comment.