Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bazelmod documentation and code examples. #2713

Merged
merged 61 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
69a9b33
Added some more Bazelmod code examples.
marvin-hansen Jun 24, 2024
bac6a13
Merge branch 'main' into main
marvin-hansen Jun 25, 2024
1f21f01
Added FFI example and dependencies vendoring example for Bazelmod.
marvin-hansen Jun 25, 2024
dcb42df
Merge remote-tracking branch 'origin/main'
marvin-hansen Jun 25, 2024
653bb40
Updated .gitignore to exclude fluff from JetBrain IDE's
marvin-hansen Jun 26, 2024
334f46b
Updated the crate_universe_bzlmod.md documentation.
marvin-hansen Jun 26, 2024
e7c60a3
Merge branch 'main' into main
marvin-hansen Jun 26, 2024
2aa5c3b
Updated presubmit.yml to build new bazelmod proto and oci example.
marvin-hansen Jun 27, 2024
50e0cc1
Added .gitignore file to all new Bazelmod examples.
marvin-hansen Jun 27, 2024
aaba5a3
Added CI build target for all remaining Bazelmod examples.
marvin-hansen Jun 27, 2024
e843c7c
Fixed a number of buildifier lint issues.
marvin-hansen Jun 27, 2024
82a25e0
Fixed more buildifier lint issues.
marvin-hansen Jun 27, 2024
a6a9774
Fixed MUSL cross compiling with Bazelmod CI build.
marvin-hansen Jun 27, 2024
893f774
Formated all bazel files in examples/bazelmod with buildifier
marvin-hansen Jun 27, 2024
2dddcee
Added Readme to compiler example and oci container example.
marvin-hansen Jun 27, 2024
f6706eb
Merge branch 'main' into main
marvin-hansen Jul 3, 2024
7f59ab6
Renovated Cross compilation with bzlmod example.
marvin-hansen Jul 4, 2024
426d896
Moved sysroot into MODULE.bazel.
marvin-hansen Jul 4, 2024
ff02ade
Merge remote-tracking branch 'origin/main'
marvin-hansen Jul 4, 2024
e158359
Removed OCI example.
marvin-hansen Jul 4, 2024
518a78b
Regenerate documentation
marvin-hansen Jul 4, 2024
4154f20
Regenerate documentation
marvin-hansen Jul 4, 2024
330fb57
Updated .gitignore files in examples to exclude hidden Mac system files.
marvin-hansen Jul 4, 2024
c0580e0
Fixed a corner case when compiling on older Intel Based Macs.
marvin-hansen Jul 4, 2024
30a4f27
Update sysroot in MUSL example.
marvin-hansen Jul 4, 2024
38752d9
Added Bazelversion file and symlinked all bzlmod examples to it.
marvin-hansen Jul 4, 2024
9aedaca
Removed .DS_Store Apple stuff.
marvin-hansen Jul 5, 2024
3c4d9e4
Formatted C code in FFI example.
marvin-hansen Jul 5, 2024
93e0b68
Formatted proto
marvin-hansen Jul 5, 2024
52eca2b
Merge branch 'bazelbuild:main' into main
marvin-hansen Jul 5, 2024
a2438ff
Formatted proto
marvin-hansen Jul 5, 2024
106a945
Merge remote-tracking branch 'origin/main'
marvin-hansen Jul 5, 2024
27ba0b6
Formatted proto
marvin-hansen Jul 5, 2024
0130fa4
Formatted proto
marvin-hansen Jul 5, 2024
0b405f4
Updated MUSL example
marvin-hansen Jul 5, 2024
82b7546
Formatted Bazelfiles.
marvin-hansen Jul 5, 2024
8c8fc22
Updated MUSL bazelmod example;
marvin-hansen Jul 5, 2024
7939b5b
Added platform tests to cross compile and MUSL example.
marvin-hansen Jul 5, 2024
fb25308
Formatted Bazel files.
marvin-hansen Jul 5, 2024
8a2f8d1
Formatted Bazel files.
marvin-hansen Jul 5, 2024
1854074
Switched MUSL example to MiMalloc
marvin-hansen Jul 5, 2024
f651e98
Removed more .DS_Store files and updated .gitignore
marvin-hansen Jul 5, 2024
200c187
Fixed platform script to work on BSD / Mac and Gnu/Linux systems.
marvin-hansen Jul 5, 2024
772bd63
Added local override to bazelmod MUSL example to test against head.
marvin-hansen Jul 7, 2024
1084934
Working on a patch to resolve MUSL toolchain.
marvin-hansen Jul 7, 2024
7a2576a
Added debug to rust_repository_set
marvin-hansen Jul 7, 2024
389508a
Added first draft to add constraint_value to MUSL toolchain via the a…
marvin-hansen Jul 7, 2024
ae6b370
Removed breaking return statement in abi_to_constraints
marvin-hansen Jul 7, 2024
e29643b
Uncommented MUSL case in abi_to_constraints
marvin-hansen Jul 7, 2024
ee2fd10
Reverted changed in rust_repository_set
marvin-hansen Jul 7, 2024
55713c2
Reverted back
marvin-hansen Jul 7, 2024
4fa6a19
Disabled MUSL on x86_64 due to issue #2726
marvin-hansen Jul 7, 2024
dbe63d7
Update examples/bzlmod/compile_opt/README.md
marvin-hansen Jul 8, 2024
96e1d83
Update examples/bzlmod/musl_cross_compiling/README.md
marvin-hansen Jul 8, 2024
95484c6
Removed bzlmod musl_cross_compiling example due to issue #2726
marvin-hansen Jul 8, 2024
0cc29b9
Updated cross compile Readme.
marvin-hansen Jul 8, 2024
6e97e3e
Removed .DS_Store files files and updated .gitignore
marvin-hansen Jul 8, 2024
dd99d68
Removed musl bazelmod example from CI config.
marvin-hansen Jul 8, 2024
7d099ab
Readme formatting in bzlmod/proto example.
marvin-hansen Jul 8, 2024
b8f87e0
Merge branch 'main' into main
marvin-hansen Jul 9, 2024
ab287dd
Removed all .DS_Store files in proto example.
marvin-hansen Jul 9, 2024
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ MODULE.bazel.lock
.vscode
*.code-workspace

# JetBrains
.idea
.idea/**

# BazelCI
bazelci.py

Expand Down
315 changes: 310 additions & 5 deletions docs/crate_universe_bzlmod.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,318 @@ This doc describes using crate_universe with bzlmod.

If you're using a WORKSPACE file, please see [the WORKSPACE equivalent of this doc](crate_universe.html).

There are some examples of using crate_universe with bzlmod:
There are some examples of using crate_universe with bzlmod in the [example folder](../examples/bzlmod).
marvin-hansen marked this conversation as resolved.
Show resolved Hide resolved

* https://github.com/bazelbuild/rules_rust/blob/main/examples/bzlmod/hello_world/MODULE.bazel
* https://github.com/bazelbuild/rules_rust/blob/main/examples/bzlmod/override_target/MODULE.bazel
* https://github.com/bazelbuild/rules_rust/blob/main/examples/bzlmod/all_crate_deps/MODULE.bazel
# Table of Contents

<a id="crate"></a>
1. [Setup](#Setup)
2. [Dependencies](#dependencies)
* [Cargo Workspace](#cargo-workspaces)
* [Direct Packages](#direct-dependencies)
* [Vendored Dependencies](#vendored-dependencies)
3. [Crate reference](#crate)
* [from_cargo](#from_cargo)
* [from_specs](#from_specs)


## Setup

To use rules_rust in a project using bzlmod, add the following to your MODULE.bazel file:

```starlark
bazel_dep(name = "rules_rust", version = "0.46.0")
```

You find the latest version on the [release page](https://github.com/bazelbuild/rules_rust/releases).


After adding `rules_rust` in your MODULE.bazel, set the following to begin using `crate_universe`:

```starlark
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")
// # ... Dependencies
use_repo(crate, "crates")
```

## Dependencies

There are three different ways to declare dependencies in your MODULE.

1) Cargo workspace
2) Direct Dependencies
3) Vendored Dependencies

### Cargo Workspaces

One of the simpler ways to wire up dependencies would be to first structure your project into a Cargo workspace. The crates_repository rule can ingest a root Cargo.toml file and generate Bazel dependencies from there. You find a complete example in the in the [example folder](../examples/bzlmod/all_crate_deps).

```starlark
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")

crate.from_cargo(
name = "crates",
cargo_lockfile = "//:Cargo.lock",
manifests = ["//:Cargo.toml"],
)
use_repo(crate, "crates")
```

The generated crates_repository contains helper macros which make collecting dependencies for Bazel targets simpler.
Notably, the all_crate_deps and aliases macros (
see [Dependencies API](https://bazelbuild.github.io/rules_rust/crate_universe.html#dependencies-api)) commonly allow the
Cargo.toml files to be the single source of truth for dependencies.
Since these macros come from the generated repository, the dependencies and alias definitions
they return will automatically update BUILD targets. In your BUILD files,
you use these macros for a Rust library as shown below:

```starlark
load("@crate_index//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")

rust_library(
name = "lib",
aliases = aliases(),
deps = all_crate_deps(
normal = True,
),
proc_macro_deps = all_crate_deps(
proc_macro = True,
),
)

rust_test(
name = "unit_test",
crate = ":lib",
aliases = aliases(
normal_dev = True,
proc_macro_dev = True,
),
deps = all_crate_deps(
normal_dev = True,
),
proc_macro_deps = all_crate_deps(
proc_macro_dev = True,
),
)
```

For a Rust binary that does not depend on any macro, use the following configuration
in your build file:

```starlark
rust_binary(
name = "bin",
srcs = ["src/main.rs"],
deps = all_crate_deps(normal = True),
)
```

You have to repin before your first build to ensure all Bazel targets for the macros
are generated.

Dependency syncing and updating is done in the repository rule which means it's done during the
analysis phase of builds. As mentioned in the environments variable table above, the `CARGO_BAZEL_REPIN`
(or `REPIN`) environment variables can be used to force the rule to update dependencies and potentially
render a new lockfile. Given an instance of this repository rule named `crates`, the easiest way to
repin dependencies is to run:

```shell
CARGO_BAZEL_REPIN=1 bazel sync --only=crates
```

This will result in all dependencies being updated for a project. The `CARGO_BAZEL_REPIN`
environment variable can also be used to customize how dependencies are updated.
For more details about repin, [please refer to the documentation](https://bazelbuild.github.io/rules_rust/crate_universe.html#crates_vendor).

### Direct Dependencies

In cases where Rust targets have heavy interactions with other Bazel targets ([Cc](https://docs.bazel.build/versions/main/be/c-cpp.html), [Proto](https://rules-proto-grpc.com/en/4.5.0/lang/rust.html),
etc.), maintaining Cargo.toml files may have diminishing returns as things like rust-analyzer
begin to be confused about missing targets or environment variables defined only in Bazel.
In situations like this, it may be desirable to have a “Cargo free” setup. You find an example in the in the [example folder](../examples/bzlmod/hello_world_no_cargo).

crates_repository supports this through the packages attribute,
as shown below.

```starlark
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")

crate.spec(package = "serde", features = ["derive"], version = "1.0")
crate.spec(package = "serde_json", version = "1.0")
crate.spec(package = "tokio", default_features=False, features = ["macros", "net", "rt-multi-thread"], version = "1.38")

crate.from_specs()
use_repo(crate, "crates")
```

Consuming dependencies may be more ergonomic in this case through the aliases defined in the new repository.
In your BUILD files, you use direct dependencies as shown below:

```starlark
rust_binary(
name = "bin",
crate_root = "src/main.rs",
srcs = glob([
"src/*.rs",
]),
deps = [
# External crates
"@crates//:serde",
"@crates//:serde_json",
"@crates//:tokio",
],
visibility = ["//visibility:public"],
)
```

Notice, direct dependencies do not need repining.
Only a cargo workspace needs updating whenever the underlying Cargo.toml file changed.

### Vendored Dependencies

In some cases, it is require that all external dependencies are vendored, meaning downloaded
and stored in the workspace. This helps, for example, to conduct licence scans, apply custom patches,
or to ensure full build reproducibility since no download error could possibly occur. You find a complete example in the in the [example folder](../examples/bzlmod/all_deps_vendor).

For the setup, you need to add the skylib in addition to the rust rules to your MODUE.bazel.

```starlark
module(
name = "deps_vendored",
version = "0.0.0"
)
###############################################################################
# B A Z E L C E N T R A L R E G I S T R Y # https://registry.bazel.build/
###############################################################################
# https://github.com/bazelbuild/bazel-skylib/releases/
bazel_dep(name = "bazel_skylib", version = "1.7.1")

# https://github.com/bazelbuild/rules_rust/releases
bazel_dep(name = "rules_rust", version = "0.46.0")

###############################################################################
# T O O L C H A I N S
###############################################################################

# Rust toolchain
RUST_EDITION = "2021"
RUST_VERSION = "1.79.0"

rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
edition = RUST_EDITION,
versions = [RUST_VERSION],
)
use_repo(rust, "rust_toolchains")
register_toolchains("@rust_toolchains//:all")

###############################################################################
# R U S T C R A T E S
###############################################################################
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")
```

Note, it is important to load the crate_universe rules otherwise you will get an error
as the rule set is needed in the vendored target.

Assuming you have a package called `basic` in which you want to vendor dependencies,
then you create a folder `basic/3rdparty`. The folder name can be arbitrary,
but by convention, its either thirdparty or 3rdparty to indicate vendored dependencies.
In the 3rdparty folder, you add a target crates_vendor to declare your dependencies to vendor. In the example, we vendor a specific version of bzip2.

```starlark
load("@rules_rust//crate_universe:defs.bzl", "crate", "crates_vendor")

crates_vendor(
name = "crates_vendor",
annotations = {
"bzip2-sys": [crate.annotation(
gen_build_script = True,
)],
},
cargo_lockfile = "Cargo.Bazel.lock",
generate_build_scripts = False,
mode = "remote",
packages = {
"bzip2": crate.spec(
version = "=0.3.3",
),
},
repository_name = "basic",
tags = ["manual"],
)
```

Next, you have to run `Cargo build` to generate a Cargo.lock file with all resolved dependencies.
Then, you rename Cargo.lock to Cargo.Bazel.lock and place it inside the `basic/3rdparty` folder.

At this point, you have the following folder and files:

```
basic
├── 3rdparty
│ ├── BUILD.bazel
│ ├── Cargo.Bazel.lock
```

Now you can run the `crates_vendor` target:

`bazel run //basic/3rdparty:crates_vendor`

This generates a crate folders with all configurations for the vendored dependencies.

```
basic
├── 3rdparty
│ ├── cratea
│ ├── BUILD.bazel
│ ├── Cargo.Bazel.lock
```

Suppose you have an application in `basic/src` that is defined in `basic/BUILD.bazel` and
that depends on a vendored dependency. You find a list of all available vendored dependencies
in the BUILD file of the generated folder: `basic/3rdparty/crates/BUILD.bazel`
You declare a vendored dependency in you target as following:

```starlark
load("@rules_rust//rust:defs.bzl", "rust_binary")

rust_binary(
name = "hello_sys",
srcs = ["src/main.rs"],
deps = ["//basic/3rdparty/crates:bzip2"],
visibility = ["//visibility:public"],
)
```
Note, the vendored dependency is not yet accessible because you have to define first
how to load the vendored dependencies. For that, you first create a file `sys_deps.bzl`
and add the following content:

```starlark
# rename the default name "crate_repositories" in case you import multiple vendored folders.
load("//basic/3rdparty/crates:defs.bzl", basic_crate_repositories = "crate_repositories")

def sys_deps():
"""
This macro loads dependencies for the `basic` crate examples
"""

# Load the vendored dependencies
basic_crate_repositories()
```

This is straightforward, you import the generated crate_repositories from the crates folder,
rename it to avoid name clashes in case you import from multiple vendored folders, and then
just load the vendored dependencies.

In a WORKSPACE configuration, you would just load and call sys_deps(), but in a MODULE configuration, you cannot do that. Instead, you create a new file `WORKSPACE.bzlmod` and add the following content.

```starlark
load("//:sys_deps.bzl", "sys_deps")
sys_deps()
```

Now, you can build the project as usual.

## crate

Expand Down
1 change: 1 addition & 0 deletions examples/bzlmod/all_deps_vendor/.bazeliskrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
USE_BAZEL_VERSION=7.2.0
Empty file.
33 changes: 33 additions & 0 deletions examples/bzlmod/all_deps_vendor/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module(
name = "deps_vendored",
version = "0.0.0"
)
###############################################################################
# B A Z E L C E N T R A L R E G I S T R Y # https://registry.bazel.build/
###############################################################################
# https://github.com/bazelbuild/bazel-skylib/releases/
bazel_dep(name = "bazel_skylib", version = "1.7.1")

# https://github.com/bazelbuild/rules_rust/releases
bazel_dep(name = "rules_rust", version = "0.46.0")

###############################################################################
# T O O L C H A I N S
###############################################################################

# Rust toolchain
RUST_EDITION = "2021"
RUST_VERSION = "1.79.0"

rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
edition = RUST_EDITION,
versions = [RUST_VERSION],
)
use_repo(rust, "rust_toolchains")
register_toolchains("@rust_toolchains//:all")

###############################################################################
# R U S T C R A T E S
###############################################################################
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")
Loading