Skip to content

Conversation

@dtolnay
Copy link
Contributor

@dtolnay dtolnay commented Aug 23, 2023

This PR allows Cargo package authors to specify metadata that replaces the need for crate_universe users to write annotations.

Crate_universe will pick up default values for various annotations fields from the metadata provided by the package author. It still remains possible for the crate_universe user to write their own annotations for the crate anyway, in which case these override the default values distributed by the package author.

For example the cxx crate contains some C++ source code that must get linked by the user. To accomplish this, all users of the crate from Bazel would previously have needed to fill in the following annotation:

crates_repository(
    name = "...",
    annotations = {
        "cxx": [crate.annotation(
            additive_build_file_content = """
            cc_library(
                name = "cxx_cc",
                srcs = ["src/cxx.cc"],
                hdrs = ["include/cxx.h"],
                include_prefix = "rust",
                includes = ["include"],
                linkstatic = True,
                strip_include_prefix = "include",
                visibility = ["//visibility:public"],
            )
            """,
            extra_aliased_targets = {"cxx_cc": "cxx_cc"},
            gen_build_script = False,
        )],
    },
    ...
)

Now cxx ships this annotation as part of the package metadata in its Cargo.toml, and Bazel users can pull in cxx without handwriting their own crate.annotation.

[package.metadata.bazel]
additive_build_file_content = """
cc_library(
    name = "cxx_cc",
    srcs = ["src/cxx.cc"],
    hdrs = ["include/cxx.h"],
    include_prefix = "rust",
    includes = ["include"],
    linkstatic = True,
    strip_include_prefix = "include",
    visibility = ["//visibility:public"],
)
"""
extra_aliased_targets = { cxx_cc = "cxx_cc" }
gen_build_script = false

Comment on lines 342 to 344
/// additive_build_file_contents = """
/// ...
/// """
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered a more TOML-native form for additive_build_file_content, but just using multiline string literal containing Starlark seems all right.

Support for the structured form can be introduced separately if desired.

[package.metadata.bazel]
extra_aliased_targets = { cxx_cc = "cxx_cc" }
gen_build_script = false

[[package.metadata.bazel.additive_build_file_content]]
[package.metadata.bazel.additive_build_file_content.cc_library]
name = "cxx_cc"
srcs = ["src/cxx.cc"]
hdrs = ["include/cxx.h"]
include_prefix = "rust"
includes = ["include"]
linkstatic = true
strip_include_prefix = "include"
visibility = ["//visibility:public"]

@dtolnay dtolnay force-pushed the packagemetadata branch 2 times, most recently from 27413f3 to 4ae5e42 Compare August 23, 2023 22:02
Copy link
Collaborator

@UebelAndre UebelAndre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty awesome change! Could you also add a unit test for this? I'm thinking a Cargo.toml file somewhere in crate_universe/test_data and have a test that reads the [package.metadata.bazel] section?

@UebelAndre UebelAndre mentioned this pull request Aug 24, 2023
@dtolnay
Copy link
Contributor Author

dtolnay commented Aug 24, 2023

I made a couple attempts at a test, but I haven't been able to figure out how to get crate_universe to pay attention to local path dependencies. It seems to only want to generate targets for crates.io dependencies (version) and git.

Here is what I have so far: affc1b5.

.sum();

if !extras.is_empty() {
crate_extra.apply_defaults_from_package_metadata(&pkg.metadata);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that the testing would just be in this file and cover the changes around here. Not necessarily a brand new test target. I think that'd get sufficient coverage of the functionality, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I get it now. Good call. I have added that test.

@dtolnay dtolnay requested a review from UebelAndre August 24, 2023 21:14
Copy link
Collaborator

@UebelAndre UebelAndre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic! Thank you so much!

@UebelAndre UebelAndre merged commit 6b50aac into bazelbuild:main Aug 24, 2023
@dtolnay dtolnay deleted the packagemetadata branch August 24, 2023 22:40
ttiurani pushed a commit to ttiurani/rules_rust that referenced this pull request Sep 15, 2023
…zelbuild#2124)

This PR allows Cargo package authors to specify metadata that replaces
the need for crate_universe users to write `annotations`.

Crate_universe will pick up default values for various `annotations`
fields from the metadata provided by the package author. It still
remains possible for the crate_universe user to write their own
`annotations` for the crate anyway, in which case these override the
default values distributed by the package author.

For example the `cxx` crate contains some C++ source code that must get
linked by the user. To accomplish this, all users of the crate from
Bazel would _previously_ have needed to fill in the following
annotation:

```bzl
crates_repository(
    name = "...",
    annotations = {
        "cxx": [crate.annotation(
            additive_build_file_content = """
            cc_library(
                name = "cxx_cc",
                srcs = ["src/cxx.cc"],
                hdrs = ["include/cxx.h"],
                include_prefix = "rust",
                includes = ["include"],
                linkstatic = True,
                strip_include_prefix = "include",
                visibility = ["//visibility:public"],
            )
            """,
            extra_aliased_targets = {"cxx_cc": "cxx_cc"},
            gen_build_script = False,
        )],
    },
    ...
)
```

Now `cxx` ships this annotation as part of [the package metadata in its
Cargo.toml](https://github.com/dtolnay/cxx/blob/1.0.105/Cargo.toml#L50-L64),
and Bazel users can pull in `cxx` without handwriting their own
`crate.annotation`.

```toml
[package.metadata.bazel]
additive_build_file_content = """
cc_library(
    name = "cxx_cc",
    srcs = ["src/cxx.cc"],
    hdrs = ["include/cxx.h"],
    include_prefix = "rust",
    includes = ["include"],
    linkstatic = True,
    strip_include_prefix = "include",
    visibility = ["//visibility:public"],
)
"""
extra_aliased_targets = { cxx_cc = "cxx_cc" }
gen_build_script = false
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants