blob: c82179d08bafbcd1e23d7dcd59f38c29ef80735f [file] [log] [blame] [view]
# Rust Rules for Bazel
## Overview
These build rules are used for building [Rust][rust] projects with Bazel.
* [Setup](#setup)
* [Basic Example](#basic-example)
* [Build Rule Reference](#reference)
* [`rust_library`](#reference-rust_library)
* [`rust_binary`](#reference-rust_binary)
* [`rust_test`](#reference-rust_test)
* [Roadmap](#roadmap)
[rust]: http://www.rust-lang.org/
<a name="setup"></a>
## Setup
To use the Rust rules, simply copy the contents of `rust.WORKSPACE` to your
`WORKSPACE` file.
<a name="basic-example"></a>
## Basic Example
Suppose you have the following directory structure for a simple Rust library
crate:
```
[workspace]/
WORKSPACE
hello_lib/
BUILD
src/
greeter.rs
lib.rs
```
`hello_lib/src/greeter.rs`:
```rust
pub struct Greeter {
greeting: String,
}
impl Greeter {
pub fn new(greeting: &str) -> Greeter {
Greeter { greeting: greeting.to_string(), }
}
pub fn greet(&self, thing: &str) {
println!("{} {}", &self.greeting, thing);
}
}
```
`hello_lib/src/lib.rs`:
```rust
pub mod greeter;
```
`hello_lib/BUILD`:
```python
package(default_visibility = ["//visibility:public"])
load("/tools/build_rules/rust/rust", "rust_library")
rust_library(
name = "hello_lib",
srcs = [
"src/greeter.rs",
"src/lib.rs",
],
)
```
Build the library:
```
$ bazel build //hello_lib
INFO: Found 1 target...
Target //examples/rust/hello_lib:hello_lib up-to-date:
bazel-bin/examples/rust/hello_lib/libhello_lib.rlib
INFO: Elapsed time: 1.245s, Critical Path: 1.01s
```
Now, let's add a binary crate that uses the `hello_lib` library. The directory
structure now looks like the following:
```
[workspace]/
WORKSPACE
hello_lib/
BUILD
src/
greeter.rs
lib.rs
hello_world/
BUILD
src/
main.rs
```
`hello_world/src/main.rs`:
```rust
extern crate hello_lib;
use hello_lib::greeter;
fn main() {
let hello = greeter::Greeter::new("Hello");
hello.greet("world");
}
```
`hello_world/BUILD`:
```python
load("/tools/build_rules/rust/rust", "rust_binary")
rust_binary(
name = "hello_world",
srcs = ["src/main.rs"],
deps = ["//hello_lib"],
)
```
Build and run `hello_world`:
```
$ bazel run //hello_world
INFO: Found 1 target...
Target //examples/rust/hello_world:hello_world up-to-date:
bazel-bin/examples/rust/hello_world/hello_world
INFO: Elapsed time: 1.308s, Critical Path: 1.22s
INFO: Running command line: bazel-bin/examples/rust/hello_world/hello_world
Hello world
```
<a name="reference"></a>
## Build Rule Reference
<a name="reference-rust_library"></a>
### `rust_library`
`rust_library(name, srcs, deps, data, crate_features, rustc_flags)`
<table>
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>name</code></td>
<td>
<code>Name, required</code>
<p>A unique name for this rule.</p>
<p>
This name will also be used as the name of the library crate built by
this rule.
</p>
</td>
</tr>
<tr>
<td><code>srcs</code></td>
<td>
<code>List of labels, required</code>
<p>List of Rust <code>.rs</code> source files used to build the
library.</p>
<p>
There must be a file either named <code>lib.rs</code> or with a name
matching the name of this crate. For example, if the name of a given
rule is <code>foo</code>, then there must be a file named
<code>lib.rs</code> or <code>foo.rs</code> in <code>srcs</code>.
This file will be passed to <code>rustc</code> as the crate root.
</p>
</td>
</tr>
<tr>
<td><code>deps</code></td>
<td>
<code>List of labels, optional</code>
<p>List of other libraries to be linked to this library target.</p>
<p>
These can be either other <code>rust_library</code> targets or
<code>cc_library</code> targets if linking a native library.
</p>
</td>
</tr>
<tr>
<td><code>data</code></td>
<td>
<code>List of labels, optional</code>
<p>List of files used by this rule at runtime.</p>
<p>
This attribute can be used to specify any data files that are embedded
into the library, such as via the
<a href="https://doc.rust-lang.org/std/macro.include_str!.html target="_blank"><code>include_str!</code></a>
macro.
</p>
</td>
</tr>
<tr>
<td><code>crate_features</code></td>
<td>
<code>List of strings, optional</code>
<p>List of features to enable for this crate.</p>
<p>
Features are defined in the code using the
<code>#[cfg(feature = "foo")]</code> configuration option. The
features listed here will be passed to <code>rustc</code> with
<code>--cfg feature="${feature_name}"</code> flags.
</p>
</td>
</tr>
<tr>
<td><code>rustc_flags</code></td>
<td>
<code>List of strings, optional</code>
<p>List of compiler flags passed to <code>rustc</code>.</p>
</td>
</tr>
</tbody>
</table>
<a name="reference-rust_binary"></a>
### `rust_binary`
`rust_binary(name, srcs, deps, data, crate_features, rustc_flags)`
<table>
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>name</code></td>
<td>
<code>Name, required</code>
<p>A unique name for this rule.</p>
<p>
This name will also be used as the name of the binary crate built by
this rule.
</p>
</td>
</tr>
<tr>
<td><code>srcs</code></td>
<td>
<code>List of labels, required</code>
<p>List of Rust <code>.rs</code> source files used to build the
binary.</p>
<p>
There must be a file either named <code>main.rs</code> or with a name
matching the name of this crate that contains the <code>main</code>
function. For example, if the name of a given
rule is <code>foo</code>, then there must be a file named
<code>main.rs</code> or <code>foo.rs</code> in <code>srcs</code>.
This file will be passed to <code>rustc</code> as the crate root.
</p>
</td>
</tr>
<tr>
<td><code>deps</code></td>
<td>
<code>List of labels, optional</code>
<p>List of other libraries to be linked to this library target.</p>
<p>
These must be <code>rust_library</code> targets.
</p>
</td>
</tr>
<tr>
<td><code>data</code></td>
<td>
<code>List of labels, optional</code>
<p>List of files used by this rule at runtime.</p>
<p>
This attribute can be used to specify any data files that are embedded
into the library, such as via the
<a href="https://doc.rust-lang.org/std/macro.include_str!.html target="_blank"><code>include_str!</code></a>
macro.
</p>
</td>
</tr>
<tr>
<td><code>crate_features</code></td>
<td>
<code>List of strings, optional</code>
<p>List of features to enable for this crate.</p>
<p>
Features are defined in the code using the
<code>#[cfg(feature = "foo")]</code> configuration option. The
features listed here will be passed to <code>rustc</code> with
<code>--cfg feature="${feature_name}"</code> flags.
</p>
</td>
</tr>
<tr>
<td><code>rustc_flags</code></td>
<td>
<code>List of strings, optional</code>
<p>List of compiler flags passed to <code>rustc</code>.</p>
</td>
</tr>
</tbody>
</table>
<a name="reference-rust_test"></a>
### `rust_test`
`rust_test(name, srcs, deps, data, crate_features, rustc_flags)`
<table>
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>name</code></td>
<td>
<code>Name, required</code>
<p>A unique name for this rule.</p>
<p>
This name will also be used as the name of the binary test crate
built by this rule.
</p>
</td>
</tr>
<tr>
<td><code>srcs</code></td>
<td>
<code>List of labels, required</code>
<p>List of Rust <code>.rs</code> source files used to build the
library.</p>
<p>
There must be a file either with a name matching the name of this
test. For example, if the name of a <code>rust_test</code> rule is
<code>foo</code>, then there must be a file named <code>foo.rs</code>
in <code>srcs</code>. This file will be passed to <code>rustc</code>
as the crate root.
</p>
</td>
</tr>
<tr>
<td><code>deps</code></td>
<td>
<code>List of labels, optional</code>
<p>List of other libraries to be linked to this test target.</p>
<p>
These must be <code>rust_library</code> targets.
</p>
</td>
</tr>
<tr>
<td><code>data</code></td>
<td>
<code>List of labels, optional</code>
<p>List of files used by this rule at runtime.</p>
<p>
This attribute can be used to specify any data files that are embedded
into the library, such as via the
<a href="https://doc.rust-lang.org/std/macro.include_str!.html target="_blank"><code>include_str!</code></a>
macro.
</p>
</td>
</tr>
<tr>
<td><code>crate_features</code></td>
<td>
<code>List of strings, optional</code>
<p>List of features to enable for this crate.</p>
<p>
Features are defined in the code using the
<code>#[cfg(feature = "foo")]</code> configuration option. The
features listed here will be passed to <code>rustc</code> with
<code>--cfg feature="${feature_name}"</code> flags.
</p>
</td>
</tr>
<tr>
<td><code>rustc_flags</code></td>
<td>
<code>List of strings, optional</code>
<p>List of compiler flags passed to <code>rustc</code>.</p>
</td>
</tr>
</tbody>
</table>
<a name="#roadmap"></a>
## Roadmap
### Near-term roadmap
* Implement `rust_bench_test` rule for running benchmarks.
* Enable `rust_test` to depend solely on a `rust_library` since many projects
intermix `#[test]` methods in implementation source.
* Improve documentation with more detailed examples.
* Implement `rust_doc` rule for generating [rustdoc][rustdoc] documentation.
[rustdoc]: https://doc.rust-lang.org/book/documentation.html#about-rustdoc
### Longer-term roadmap
* Add tool for taking `Cargo.toml` and generating a `WORKSPACE` file with
workspace rules for pulling external dependencies.
* Improve expressiveness of features and support for [Cargo's feature
groups](http://doc.crates.io/manifest.html#the-[features]-section).
* Add `cargo_crate` workspace rule for pulling crates from
[Cargo](https://crates.io/).