Skip to content

Commit 78df9b1

Browse files
authored
rust: add minimal complete Rust toolchain (#4279)
Summary: This patch includes: - a WORKSPACE dependency on `rules_rust`; - a sample Rust library, with tests and doctests; - a sample Rust binary that depends on the library; - third-party Rust deps with build files generated by `cargo raze`; - a build structure that works with both Bazel and Cargo; - documentation. Test Plan: First, run Bazel tests: ``` bazel test //tensorboard/data/server/... ``` Note that if you change the `assert_eq!` in `lib.rs`’s docstring, the doc test fails, and if you change its `#[test]` assertions, then the normal test fails. Then, run the binary: ``` bazel run //tensorboard/data/server ``` …and note that it prints `2 + 2 = 4`, thanks to our helpful library. Next, `cd` into `tensorboard/data/server/` and note that `cargo run` and `cargo test` still work, just as in a normal Rust toolchain. If you use `rust-analyzer`, it should pick up this project automatically. Googlers, see <http://cl/340933226> for Copybara changes. wchargin-branch: rust-toolchain
1 parent a823483 commit 78df9b1

16 files changed

+376
-1
lines changed

Diff for: .gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
third_party/rust/** -diff -merge linguist-generated=true

Diff for: WORKSPACE

+11
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ load("@upb//bazel:repository_defs.bzl", "bazel_version_repository")
107107

108108
bazel_version_repository(name = "bazel_version")
109109

110+
http_archive(
111+
name = "io_bazel_rules_rust",
112+
sha256 = "9beda941ab076d15428d8615475329bd65002a13a26c2837932af0fb3dc582c5",
113+
strip_prefix = "rules_rust-9426a3820093e75ea07d14f875e42f789632507f",
114+
urls = [
115+
# Master branch as of 2020-10-23
116+
"http://mirror.tensorflow.org/github.com/bazelbuild/rules_rust/archive/9426a3820093e75ea07d14f875e42f789632507f.tar.gz",
117+
"https://github.com/bazelbuild/rules_rust/archive/9426a3820093e75ea07d14f875e42f789632507f.tar.gz",
118+
],
119+
)
120+
110121
# Please add all new dependencies in workspace.bzl.
111122
load("//third_party:workspace.bzl", "tensorboard_workspace")
112123
tensorboard_workspace()

Diff for: tensorboard/data/server/.gitignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
# ==============================================================================
15+
16+
target/

Diff for: tensorboard/data/server/BUILD

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary", "rust_doc_test", "rust_library", "rust_test")
2+
3+
package(default_visibility = ["//tensorboard:internal"])
4+
5+
licenses(["notice"])
6+
7+
rust_library(
8+
name = "rustboard_core",
9+
srcs = [
10+
"lib.rs",
11+
],
12+
edition = "2018",
13+
)
14+
15+
rust_test(
16+
name = "rustboard_core_test",
17+
crate = ":rustboard_core",
18+
)
19+
20+
rust_doc_test(
21+
name = "rustboard_core_doc_test",
22+
dep = ":rustboard_core",
23+
)
24+
25+
rust_binary(
26+
name = "server",
27+
srcs = ["main.rs"],
28+
edition = "2018",
29+
deps = [
30+
":rustboard_core",
31+
"//third_party/rust:byteorder",
32+
],
33+
)

Diff for: tensorboard/data/server/Cargo.lock

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: tensorboard/data/server/Cargo.toml

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
# ==============================================================================
15+
16+
[package]
17+
name = "rustboard"
18+
version = "0.1.0"
19+
authors = ["The TensorFlow Authors <[email protected]>"]
20+
edition = "2018"
21+
22+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
23+
24+
[dependencies]
25+
byteorder = "1.3.4"
26+
27+
[[bin]]
28+
name = "rustboard"
29+
path = "main.rs"
30+
31+
[lib]
32+
name = "rustboard_core"
33+
path = "lib.rs"
34+
35+
[raze]
36+
workspace_path = "//third_party/rust"
37+
genmode = "Remote"

Diff for: tensorboard/data/server/DEVELOPMENT.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Using Rust in TensorBoard
2+
3+
## Building
4+
5+
The `//tensorboard/data/server` package can be built with Bazel. It builds
6+
hermetically and with no additional setup. If you like using `bazel build`,
7+
`bazel run`, and `bazel test`, you can stop reading now.
8+
9+
This package can also be built with Cargo, the standard Rust toolchain. You
10+
might want to use Cargo:
11+
12+
- …to use the `rust-analyzer` language server in your editor of choice.
13+
- …to use tools like `cargo clippy` (a linter) or `cargo geiger` (an auditor
14+
for unsafe code) or `cargo tree` (to show the crate dependency graph).
15+
- …to use `cargo raze` to generate Bazel build files from the Cargo package
16+
structure.
17+
- …to use other Rust toolchains, like the beta or nightly channels.
18+
- …to cross-compile.
19+
- …simply because you’re more familiar with it or prefer it.
20+
21+
The easiest way to get and use Cargo is with <https://rustup.rs>. Cargo resolves
22+
subcommands by looking for executables called `cargo-*` (analogous to Git), so
23+
you may want to `cargo install cargo-raze cargo-watch cargo-geiger` for some
24+
useful tools.
25+
26+
To build with Cargo, change into the `tensorboard/data/server/` directory and
27+
use standard Cargo commands, like `cargo build --release` or `cargo test`.
28+
Running `cargo raze` from within `tensorboard/data/server/` will update the
29+
build files under `third_party/rust/`, using `Cargo.toml` as the source of
30+
truth.
31+
32+
You should be able to use `rust-analyzer` without doing anything special or
33+
changing into the `tensorboard/data/server/` subdirectory: just open one of the
34+
Rust source files in your editor. For editor setup, consult
35+
[the `rust-analyzer` docs][ra-docs].
36+
37+
[ra-docs]: https://rust-analyzer.github.io/
38+
39+
## Adding third-party dependencies
40+
41+
Rust dependencies are usually hosted on [crates.io]. We use [`cargo-raze`][raze]
42+
to automatically generate Bazel build files for these third-party dependencies.
43+
44+
The source of truth for `cargo-raze` is the `Cargo.toml` file. To add a new
45+
dependency:
46+
47+
1. Run `cargo install cargo-raze` to ensure that you have [`cargo-raze`][raze]
48+
installed.
49+
2. Add an entry to the `[dependencies]` section of `Cargo.toml`. The new line
50+
should look like `rand = "0.7.3"`. You can find the most recent version of a
51+
package on <https://crates.io/>.
52+
3. Change into the `tensorboard/data/server/` directory.
53+
4. Run `cargo generate-lockfile` to update `Cargo.lock`. Running this before
54+
`cargo raze` ensures that the `http_archive` workspace rules in the
55+
generated build files will have `sha256` checksums.
56+
5. Run `cargo raze` to update `third_party/rust/...`.
57+
58+
This will add a new target like `//third_party/rust:rand`. Manually build it
59+
with Bazel to ensure that it works: `bazel build //third_party/rust:rand`. If
60+
the build fails, you’ll need to teach `cargo-raze` how to handle this package by
61+
adding crate-specific metadata to a `[raze.crates.CRATE-NAME.VERSION]` section
62+
of the `Cargo.toml` file. Failure modes may include:
63+
64+
- The package uses a `build.rs` script to generate code at compile time.
65+
Solution: add `gen_buildrs = true`.
66+
- The package needs certain features to be enabled. Solution: add
67+
`additional_flags = ["--cfg=FEATURE_NAME"]`.
68+
69+
See `Cargo.toml` for prior art. Googlers: you may be able to glean some hints
70+
from the corresponding Google-internal build files.
71+
72+
When done, commit the changes to `Cargo.toml`, `Cargo.lock`, and the
73+
`third_party/rust/` directory.
74+
75+
[crates.io]: https://crates.io/
76+
[raze]: https://github.com/google/cargo-raze

Diff for: tensorboard/data/server/lib.rs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
==============================================================================*/
15+
16+
/// Adds two integers together and returns the result. Must not overflow.
17+
///
18+
/// # Examples
19+
///
20+
/// ```
21+
/// assert_eq!(rustboard_core::add(20, 22), 42);
22+
/// ```
23+
pub fn add(x: i32, y: i32) -> i32 {
24+
x + y
25+
}
26+
27+
#[cfg(test)]
28+
mod test {
29+
use super::add;
30+
31+
#[test]
32+
fn test_add() {
33+
assert_eq!(add(2, 4), 6);
34+
assert_eq!(add(999, 999), 1998);
35+
}
36+
}

Diff for: tensorboard/data/server/main.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
==============================================================================*/
15+
16+
use byteorder::{ByteOrder, LittleEndian};
17+
18+
fn main() {
19+
let ptr = LittleEndian::read_u32(b"\x2e\x68\x63\x73"); // look, a dependency!
20+
assert_eq!(ptr, 0x7363682e);
21+
println!("Hello, server! 2 + 2 = {}", rustboard_core::add(2, 2)); // look, a sibling crate!
22+
}

Diff for: tensorboard/tools/license_test.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# tf_imports/*.html define their respective OSS license.
1818
files=$(git grep -L "Copyright 20[0-9][0-9] The TensorFlow" \
1919
'tensorboard/*.*' \
20-
':!*.'{pyc,json,png,wav,proto,pbtxt,md,in,rst,cfg,ipynb,svg} \
20+
':!*.'{pyc,json,png,wav,proto,pbtxt,md,in,rst,cfg,ipynb,svg,lock} \
2121
':!tensorboard/components/tf_imports/*.html')
2222

2323
count=$(echo "$files" | wc -l | awk '{print $1}')

Diff for: third_party/rust.bzl

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the 'License');
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an 'AS IS' BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
TensorBoard external Rust dependencies (both infrastructure and frontend libs)
17+
"""
18+
19+
load("@io_bazel_rules_rust//rust:repositories.bzl", "rust_repositories")
20+
load("@io_bazel_rules_rust//:workspace.bzl", "rust_workspace")
21+
load("//third_party/rust:crates.bzl", "raze_fetch_remote_crates")
22+
23+
def tensorboard_rust_workspace():
24+
"""TensorBoard Rust dependencies."""
25+
rust_repositories()
26+
rust_workspace()
27+
raze_fetch_remote_crates()

Diff for: third_party/rust/BUILD.bazel

+22
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: third_party/rust/crates.bzl

+22
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: third_party/rust/remote/BUILD.bazel

Whitespace-only changes.

0 commit comments

Comments
 (0)