Generate documentation with Skydoc. (#28)
Fixes #12
diff --git a/.gitignore b/.gitignore
index a6ef824..5a10533 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
+*.swp
/bazel-*
diff --git a/WORKSPACE b/WORKSPACE
index 17eeab0..6282123 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -9,3 +9,24 @@
load("//rust:rust.bzl", "rust_repositories")
rust_repositories()
+
+# Used for documenting Rust rules.
+git_repository(
+ name = "io_bazel_rules_sass",
+ remote = "https://github.com/bazelbuild/rules_sass.git",
+ tag = "0.0.2",
+)
+
+load("@io_bazel_rules_sass//sass:sass.bzl", "sass_repositories")
+
+sass_repositories()
+
+git_repository(
+ name = "io_bazel_skydoc",
+ remote = "https://github.com/bazelbuild/skydoc.git",
+ tag = "0.1.2",
+)
+
+load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories")
+
+skydoc_repositories()
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..0526883
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,201 @@
+
+
+<!--
+Documentation generated by Skydoc
+-->
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width initial-scale=1" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+
+ <title>Overview</title>
+
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" type="text/css">
+ <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+ <link rel="stylesheet" href="https://code.getmdl.io/1.1.1/material.green-light_blue.min.css">
+ <script defer src="https://code.getmdl.io/1.1.1/material.min.js"></script>
+ <link rel="stylesheet" href="/main.css">
+ </head>
+ <body>
+ <div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer
+ mdl-layout--fixed-header">
+ <header class="mdl-layout__header">
+ <div class="mdl-layout__header-row">
+ <span class="mdl-layout-title">Overview</span>
+ </div>
+ </header>
+ <div class="mdl-layout__drawer">
+ <span class="mdl-layout-title">Bazel</span>
+ <nav class="drawer-nav">
+ <ul class="drawer-nav">
+
+<li><a href="/index.html">Overview</a></li>
+<li>
+ <a href="/rust/rust.html">Rust Rules</a>
+ <ul>
+ <li><a href="/rust/rust.html#overview">Overview</a></li>
+ <li>
+ <a href="/rust/rust.html#rust_bench_test">
+ rust_bench_test
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_binary">
+ rust_binary
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_doc">
+ rust_doc
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_doc_test">
+ rust_doc_test
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_library">
+ rust_library
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_test">
+ rust_test
+ </a>
+ </li>
+ </ul>
+</li>
+
+ </ul>
+ </nav>
+ </div>
+
+ <main class="mdl-layout__content">
+ <div class="page-content">
+<h1>Overview</h1>
+
+
+<nav class="toc">
+ <h2>Rule sets</h2>
+ <ul>
+ <li><a href="#rust">Rust Rules</a></li>
+ </ul>
+</nav>
+
+<h2><a href="/rust/rust.html">Rust Rules</a></h2>
+
+<h3>Rules</h3>
+<table class="overview-table">
+ <colgroup>
+ <col class="col-name" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr>
+ <td>
+ <a href="/rust/rust.html#rust_bench_test">
+ <code>rust_bench_test</code>
+ </a>
+ </td>
+ <td>
+ <p>Builds a Rust benchmark test.</p>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="/rust/rust.html#rust_binary">
+ <code>rust_binary</code>
+ </a>
+ </td>
+ <td>
+ <p>Builds a Rust binary crate.</p>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="/rust/rust.html#rust_doc">
+ <code>rust_doc</code>
+ </a>
+ </td>
+ <td>
+ <p>Generates code documentation.</p>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="/rust/rust.html#rust_doc_test">
+ <code>rust_doc_test</code>
+ </a>
+ </td>
+ <td>
+ <p>Runs Rust documentation tests.</p>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="/rust/rust.html#rust_library">
+ <code>rust_library</code>
+ </a>
+ </td>
+ <td>
+ <p>Builds a Rust library crate.</p>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="/rust/rust.html#rust_test">
+ <code>rust_test</code>
+ </a>
+ </td>
+ <td>
+ <p>Builds a Rust test crate.</p>
+
+ </td>
+ </tr>
+ </tbody>
+</table>
+<h3>Macros</h3>
+<table class="overview-table">
+ <colgroup>
+ <col class="col-name" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr>
+ <td>
+ <a href="/rust/rust.html#rust_repositories">
+ <code>rust_repositories</code>
+ </a>
+ </td>
+ <td>
+ <p>Adds the external dependencies needed for the Rust rules.</p>
+
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+ </div>
+
+ <footer class="mdl-mini-footer">
+ <div class="mdl-mini-footer__left-section">
+ <div class="mdl-logo">Bazel</div>
+ <ul class="mdl-mini-footer__link-list">
+ <li><a href="http://bazel.io">Home</a></li>
+ <li><a href="https://github.com/bazelbuild">GitHub</a></li>
+ </ul>
+ </div>
+ </footer>
+ </main>
+ </div>
+ </body>
+</html>
diff --git a/docs/main.css b/docs/main.css
new file mode 100755
index 0000000..f506e12
--- /dev/null
+++ b/docs/main.css
@@ -0,0 +1,3 @@
+body{background-color:#fafafa}pre,code{font-family:'Liberation Mono', Consolas, Monaco, 'Andale Mono', monospace}pre{background-color:#eee;padding:20px;overflow-x:auto;word-wrap:normal}pre code{overflow-wrap:normal;white-space:pre}code{display:inline-block;font-size:90%;white-space:pre-wrap}.mdl-layout__drawer{background-color:#fff}.mdl-layout__drawer .mdl-layout-title{border-bottom:1px solid #e0e0e0;padding-left:24px}.drawer-nav ul{list-style:none;padding-left:0}.drawer-nav ul li{display:block;padding:0}.drawer-nav ul li ul li a{padding-left:44px;font-weight:400}.drawer-nav ul li a{display:block;flex-shrink:0;padding:15px 0 15px 22px;margin:0;font-weight:600;color:#757575;line-height:1em;text-decoration:none;cursor:pointer}.drawer-nav ul li a:active,.drawer-nav ul li a:hover{background-color:#f0f0f0}.drawer-nav ul li.active a{color:#4caf50;font-weight:500}h1.page-title{font-size:34px;font-weight:400;line-height:40px;margin-bottom:30px;color:#4caf50}p.lead{font-size:20px;line-height:32px}table{border-collapse:collapse;border-spacing:0;background-color:#fff;table-layout:auto}table thead th{background-color:#fafafa;border:1px solid #eee;color:#757575;padding:12px 12px 12px 24px;vertical-align:top}table tbody td{border:1px solid #eee;padding:12px 12px 12px 24px;vertical-align:top}table.params-table{width:100%}table.params-table col.col-param{width:25%}table.params-table col.col-description{width:75%}table.overview-table{width:100%}table.overview-table col.col-name{width:25%}table.overview-table col.col-description{width:75%}table.overview-table td p{margin:0}hr{margin-top:80px;margin-bottom:80px}nav.toc{border-left:5px solid #4caf50;padding-left:20px;margin-bottom:48px}nav.toc h1,nav.toc h2{font-size:15px;line-height:16px;padding-bottom:12px;margin-bottom:0;font-weight:400;color:#757575}nav.toc ul{list-style:none;margin-top:0;padding-left:0}nav.toc ul li{font-size:20px;line-height:40px}nav.toc ul li a{color:#4caf50}.page-content{margin-left:auto;margin-right:auto;padding-top:60px;padding-bottom:60px;width:760px}.page-content a{text-decoration:none}.page-content h1{font-size:34px;font-weight:400;line-height:40px;margin-bottom:30px;color:#4caf50}.page-content h2{font-size:24px;font-weight:400;line-height:32px;margin-bottom:30px;color:#4caf50}.page-content h3{font-size:20px;font-weight:400;line-height:32px;margin-bottom:30px;color:#4caf50}@media (max-width: 768px){.page-content{width:360px}}@media (min-width: 768px){.page-content{width:760px}}@media (min-width: 1476px){.page-content{width:1160px}}.mdl-mini-footer{padding-left:40px}
+
+/*# sourceMappingURL=main.css.map */
\ No newline at end of file
diff --git a/docs/rust/rust.html b/docs/rust/rust.html
new file mode 100644
index 0000000..ebd10d1
--- /dev/null
+++ b/docs/rust/rust.html
@@ -0,0 +1,923 @@
+
+
+<!--
+Documentation generated by Skydoc
+-->
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width initial-scale=1" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+
+ <title>Rust Rules</title>
+
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" type="text/css">
+ <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+ <link rel="stylesheet" href="https://code.getmdl.io/1.1.1/material.green-light_blue.min.css">
+ <script defer src="https://code.getmdl.io/1.1.1/material.min.js"></script>
+ <link rel="stylesheet" href="/main.css">
+ </head>
+ <body>
+ <div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer
+ mdl-layout--fixed-header">
+ <header class="mdl-layout__header">
+ <div class="mdl-layout__header-row">
+ <span class="mdl-layout-title">Rust Rules</span>
+ </div>
+ </header>
+ <div class="mdl-layout__drawer">
+ <span class="mdl-layout-title">Bazel</span>
+ <nav class="drawer-nav">
+ <ul class="drawer-nav">
+
+<li><a href="/index.html">Overview</a></li>
+<li>
+ <a href="/rust/rust.html">Rust Rules</a>
+ <ul>
+ <li><a href="/rust/rust.html#overview">Overview</a></li>
+ <li>
+ <a href="/rust/rust.html#rust_bench_test">
+ rust_bench_test
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_binary">
+ rust_binary
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_doc">
+ rust_doc
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_doc_test">
+ rust_doc_test
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_library">
+ rust_library
+ </a>
+ </li>
+ <li>
+ <a href="/rust/rust.html#rust_test">
+ rust_test
+ </a>
+ </li>
+ </ul>
+</li>
+
+ </ul>
+ </nav>
+ </div>
+
+ <main class="mdl-layout__content">
+ <div class="page-content">
+ <h1>Rust Rules</h1>
+
+<nav class="toc">
+ <h2><a href="#overview">Overview</a></h2>
+ <h2>Rules</h2>
+ <ul>
+ <li><a href="#rust_bench_test">rust_bench_test</a></li>
+ <li><a href="#rust_binary">rust_binary</a></li>
+ <li><a href="#rust_doc">rust_doc</a></li>
+ <li><a href="#rust_doc_test">rust_doc_test</a></li>
+ <li><a href="#rust_library">rust_library</a></li>
+ <li><a href="#rust_test">rust_test</a></li>
+ </ul>
+ <h2>Macros</h2>
+ <ul>
+ <li><a href="#rust_repositories">rust_repositories</a></li>
+ </ul>
+</nav>
+ <hr>
+ <h2 id="overview">Overview</h2>
+ <p>These build rules are used for building <a href="http://www.rust-lang.org/">Rust</a> projects with Bazel.</p>
+<h3>Setup</h3>
+<p>To use the Rust rules, add the following to your <code>WORKSPACE</code> file to add the
+external repositories for the Rust toolchain:</p>
+<pre><code class="lang-python">git_repository(
+ name = "io_bazel_rules_rust",
+ remote = "https://github.com/bazelbuild/rules_rust.git",
+ tag = "0.0.1",
+)
+load("@io_bazel_rules_rust//rust:rust.bzl", "rust_repositories")
+
+rust_repositories()
+</code></pre>
+<h3>Roadmap</h3>
+<ul>
+<li>Add <code>rust_toolchain</code> rule to make it easy to use a custom Rust toolchain.</li>
+<li>Add tool for taking <code>Cargo.toml</code> and generating a <code>WORKSPACE</code> file with
+workspace rules for pulling external dependencies.</li>
+<li>Improve expressiveness of features and support for <a href="http://doc.crates.io/manifest.html#the-[features]-section">Cargo's feature
+groups</a>.</li>
+<li>Add <code>cargo_crate</code> workspace rule for pulling crates from
+<a href="https://crates.io/">Cargo</a>.</li>
+</ul>
+
+ <hr>
+
+ <h2 id="rust_repositories">rust_repositories</h2>
+
+ <pre>rust_repositories()</pre>
+
+ <p>Adds the external dependencies needed for the Rust rules.</p>
+
+
+ <hr>
+
+ <h2 id="rust_bench_test">rust_bench_test</h2>
+
+ <pre>rust_bench_test(<a href="#rust_bench_test.name">name</a>, <a href="#rust_bench_test.deps">deps</a>, <a href="#rust_bench_test.data">data</a>, <a href="#rust_bench_test.srcs">srcs</a>, <a href="#rust_bench_test.crate_features">crate_features</a>, <a href="#rust_bench_test.crate_root">crate_root</a>, <a href="#rust_bench_test.rustc_flags">rustc_flags</a>)</pre>
+
+ <p>Builds a Rust benchmark test.</p>
+<p><strong>Warning</strong>: This rule is currently experimental. <a href="https://doc.rust-lang.org/book/benchmark-tests.html">Rust Benchmark
+tests</a> require the <code>Bencher</code> interface in the unstable <code>libtest</code>
+crate, which is behind the <code>test</code> unstable feature gate. As a result, using
+this rule would require using a nightly binary release of Rust. A
+<code>rust_toolchain</code> rule will be added in the <a href="#roadmap">near future</a> to make it
+easy to use a custom Rust toolchain, such as a nightly release.</p>
+
+
+ <h3 id="rust_bench_test_args">Attributes</h3>
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="rust_bench_test.name">
+ <td><code>name</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#name">Name</a>; Required</code></p>
+ <p>This name will also be used as the name of the binary crate built by
+this rule.</p>
+ </td>
+ </tr>
+ <tr id="rust_bench_test.deps">
+ <td><code>deps</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <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 id="rust_bench_test.data">
+ <td><code>data</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <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"><code>include_str!</code></a>
+macro.</p>
+ </td>
+ </tr>
+ <tr id="rust_bench_test.srcs">
+ <td><code>srcs</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <p>List of Rust <code>.rs</code> source files used to build the test.</p>
+<p>If <code>srcs</code> contains more than one file, then there must be a file either
+named <code>lib.rs</code>. Otherwise, <code>crate_root</code> must be set to the source file that
+is the root of the crate to be passed to rustc to build this crate.</p>
+ </td>
+ </tr>
+ <tr id="rust_bench_test.crate_features">
+ <td><code>crate_features</code></td>
+ <td>
+ <p><code>List of strings; Optional; Default is []</code></p>
+ <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 id="rust_bench_test.crate_root">
+ <td><code>crate_root</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; Optional</code></p>
+ <p>The file that will be passed to <code>rustc</code> to be used for building
+this crate.</p>
+<p>If <code>crate_root</code> is not set, then this rule will look for a <code>lib.rs</code> file or
+the single file in <code>srcs</code> if <code>srcs</code> contains only one file.</p>
+ </td>
+ </tr>
+ <tr id="rust_bench_test.rustc_flags">
+ <td><code>rustc_flags</code></td>
+ <td>
+ <p><code>List of strings; Optional; Default is []</code></p>
+ <p>List of compiler flags passed to <code>rustc</code>.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+ <h3 id="rust_bench_test_examples">Examples</h3>
+ <p>Suppose you have the following directory structure for a Rust project with a
+library crate, <code>fibonacci</code> with benchmarks under the <code>benches/</code> directory:</p>
+<pre><code>[workspace]/
+ WORKSPACE
+ fibonacci/
+ BUILD
+ src/
+ lib.rs
+ benches/
+ fibonacci_bench.rs
+</code></pre>
+<p><code>fibonacci/src/lib.rs</code>:</p>
+<pre><code class="lang-rust">pub fn fibonacci(n: u64) -> u64 {
+ if n < 2 {
+ return n;
+ }
+ let mut n1: u64 = 0;
+ let mut n2: u64 = 1;
+ for _ in 1..n {
+ let sum = n1 + n2;
+ n1 = n2;
+ n2 = sum;
+ }
+ n2
+}
+</code></pre>
+<p><code>fibonacci/benches/fibonacci_bench.rs</code>:</p>
+<pre><code class="lang-rust">#![feature(test)]
+
+extern crate test;
+extern crate fibonacci;
+
+use test::Bencher;
+
+#[bench]
+fn bench_fibonacci(b: &mut Bencher) {
+ b.iter(|| fibonacci::fibonacci(40));
+}
+</code></pre>
+<p>To build the benchmark test, simply add a <code>rust_bench_test</code> target:</p>
+<p><code>fibonacci/BUILD</code>:</p>
+<pre><code class="lang-python">package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_bench_test")
+
+rust_library(
+ name = "fibonacci",
+ srcs = ["src/lib.rs"],
+)
+
+rust_bench_test(
+ name = "fibonacci_bench",
+ srcs = ["benches/fibonacci_bench.rs"],
+ deps = [":fibonacci"],
+)
+</code></pre>
+<p>Run the benchmark test using: <code>bazel build //fibonacci:fibonacci_bench</code>.</p>
+
+ <hr>
+
+ <h2 id="rust_binary">rust_binary</h2>
+
+ <pre>rust_binary(<a href="#rust_binary.name">name</a>, <a href="#rust_binary.deps">deps</a>, <a href="#rust_binary.data">data</a>, <a href="#rust_binary.srcs">srcs</a>, <a href="#rust_binary.crate_features">crate_features</a>, <a href="#rust_binary.crate_root">crate_root</a>, <a href="#rust_binary.rustc_flags">rustc_flags</a>)</pre>
+
+ <p>Builds a Rust binary crate.</p>
+
+
+ <h3 id="rust_binary_args">Attributes</h3>
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="rust_binary.name">
+ <td><code>name</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#name">Name</a>; Required</code></p>
+ <p>This name will also be used as the name of the binary crate built by
+this rule.</p>
+ </td>
+ </tr>
+ <tr id="rust_binary.deps">
+ <td><code>deps</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <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 id="rust_binary.data">
+ <td><code>data</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <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"><code>include_str!</code></a>
+macro.</p>
+ </td>
+ </tr>
+ <tr id="rust_binary.srcs">
+ <td><code>srcs</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <p>List of Rust <code>.rs</code> source files used to build the test.</p>
+<p>If <code>srcs</code> contains more than one file, then there must be a file either
+named <code>lib.rs</code>. Otherwise, <code>crate_root</code> must be set to the source file that
+is the root of the crate to be passed to rustc to build this crate.</p>
+ </td>
+ </tr>
+ <tr id="rust_binary.crate_features">
+ <td><code>crate_features</code></td>
+ <td>
+ <p><code>List of strings; Optional; Default is []</code></p>
+ <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 id="rust_binary.crate_root">
+ <td><code>crate_root</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; Optional</code></p>
+ <p>The file that will be passed to <code>rustc</code> to be used for building
+this crate.</p>
+<p>If <code>crate_root</code> is not set, then this rule will look for a <code>lib.rs</code> file or
+the single file in <code>srcs</code> if <code>srcs</code> contains only one file.</p>
+ </td>
+ </tr>
+ <tr id="rust_binary.rustc_flags">
+ <td><code>rustc_flags</code></td>
+ <td>
+ <p><code>List of strings; Optional; Default is []</code></p>
+ <p>List of compiler flags passed to <code>rustc</code>.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+ <h3 id="rust_binary_examples">Examples</h3>
+ <p>Suppose you have the following directory structure for a Rust project with a
+library crate, <code>hello_lib</code>, and a binary crate, <code>hello_world</code> that uses the
+<code>hello_lib</code> library:</p>
+<pre><code>[workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+ hello_world/
+ BUILD
+ src/
+ main.rs
+</code></pre>
+<p><code>hello_lib/src/lib.rs</code>:</p>
+<pre><code class="lang-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);
+ }
+}
+</code></pre>
+<p><code>hello_lib/BUILD</code>:</p>
+<pre><code class="lang-python">package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library")
+
+rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+)
+</code></pre>
+<p><code>hello_world/src/main.rs</code>:</p>
+<pre><code class="lang-rust">extern crate hello_lib;
+
+fn main() {
+ let hello = hello_lib::Greeter::new("Hello");
+ hello.greet("world");
+}
+</code></pre>
+<p><code>hello_world/BUILD</code>:</p>
+<pre><code class="lang-python">load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary")
+
+rust_binary(
+ name = "hello_world",
+ srcs = ["src/main.rs"],
+ deps = ["//hello_lib"],
+)
+</code></pre>
+<p>Build and run <code>hello_world</code>:</p>
+<pre><code>$ 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
+</code></pre>
+
+ <hr>
+
+ <h2 id="rust_doc">rust_doc</h2>
+
+ <pre>rust_doc(<a href="#rust_doc.name">name</a>, <a href="#rust_doc.dep">dep</a>, <a href="#rust_doc.html_after_content">html_after_content</a>, <a href="#rust_doc.html_before_content">html_before_content</a>, <a href="#rust_doc.html_in_header">html_in_header</a>, <a href="#rust_doc.markdown_css">markdown_css</a>)</pre>
+
+ <p>Generates code documentation.</p>
+
+
+ <h3 id="rust_doc_args">Attributes</h3>
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="rust_doc.name">
+ <td><code>name</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#name">Name</a>; Required</code></p>
+ <p>A unique name for this rule.</p>
+ </td>
+ </tr>
+ <tr id="rust_doc.dep">
+ <td><code>dep</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; Required</code></p>
+ <p>The label of the target to run documentation tests for.</p>
+<p><code>rust_doc_test</code> can run documentation tests for the source files of
+<code>rust_library</code> or <code>rust_binary</code> targets.</p>
+ </td>
+ </tr>
+ <tr id="rust_doc.html_after_content">
+ <td><code>html_after_content</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; Optional</code></p>
+ <p>File to add in <code>&lt;body&gt;</code>, after content.</p>
+ </td>
+ </tr>
+ <tr id="rust_doc.html_before_content">
+ <td><code>html_before_content</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; Optional</code></p>
+ <p>File to add in <code>&lt;body&gt;</code>, before content.</p>
+ </td>
+ </tr>
+ <tr id="rust_doc.html_in_header">
+ <td><code>html_in_header</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; Optional</code></p>
+ <p>File to add to <code>&lt;head&gt;</code>.</p>
+ </td>
+ </tr>
+ <tr id="rust_doc.markdown_css">
+ <td><code>markdown_css</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <p>CSS files to include via <code>&lt;link&gt;</code> in a rendered
+Markdown file.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+ <h3 id="rust_doc_examples">Examples</h3>
+ <p>Suppose you have the following directory structure for a Rust library crate:</p>
+<pre><code>[workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+</code></pre>
+<p>To build <a href="https://doc.rust-lang.org/book/documentation.html"><code>rustdoc</code></a> documentation for the <code>hello_lib</code> crate, define
+a <code>rust_doc</code> rule that depends on the the <code>hello_lib</code> <code>rust_library</code> target:</p>
+<pre><code class="lang-python">package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_doc")
+
+rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+)
+
+rust_doc(
+ name = "hello_lib_doc",
+ dep = ":hello_lib",
+)
+</code></pre>
+<p>Running <code>bazel build //hello_lib:hello_lib_doc</code> will build a zip file containing
+the documentation for the <code>hello_lib</code> library crate generated by <code>rustdoc</code>.</p>
+
+ <hr>
+
+ <h2 id="rust_doc_test">rust_doc_test</h2>
+
+ <pre>rust_doc_test(<a href="#rust_doc_test.name">name</a>, <a href="#rust_doc_test.dep">dep</a>)</pre>
+
+ <p>Runs Rust documentation tests.</p>
+
+
+ <h3 id="rust_doc_test_args">Attributes</h3>
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="rust_doc_test.name">
+ <td><code>name</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#name">Name</a>; Required</code></p>
+ <p>A unique name for this rule.</p>
+ </td>
+ </tr>
+ <tr id="rust_doc_test.dep">
+ <td><code>dep</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; Required</code></p>
+ <p>The label of the target to run documentation tests for.</p>
+<p><code>rust_doc_test</code> can run documentation tests for the source files of
+<code>rust_library</code> or <code>rust_binary</code> targets.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+ <h3 id="rust_doc_test_examples">Examples</h3>
+ <p>Suppose you have the following directory structure for a Rust library crate:</p>
+<pre><code>[workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+</code></pre>
+<p>To run <a href="https://doc.rust-lang.org/book/documentation.html#documentation-as-tests">documentation tests</a> for the <code>hello_lib</code> crate, define a
+<code>rust_doc_test</code> target that depends on the <code>hello_lib</code> <code>rust_library</code> target:</p>
+<pre><code class="lang-python">package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_doc_test")
+
+rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+)
+
+rust_doc_test(
+ name = "hello_lib_doc_test",
+ dep = ":hello_lib",
+)
+</code></pre>
+<p>Running <code>bazel test //hello_lib:hello_lib_doc_test</code> will run all documentation
+tests for the <code>hello_lib</code> library crate.</p>
+
+ <hr>
+
+ <h2 id="rust_library">rust_library</h2>
+
+ <pre>rust_library(<a href="#rust_library.name">name</a>, <a href="#rust_library.deps">deps</a>, <a href="#rust_library.data">data</a>, <a href="#rust_library.srcs">srcs</a>, <a href="#rust_library.crate_features">crate_features</a>, <a href="#rust_library.crate_root">crate_root</a>, <a href="#rust_library.crate_type">crate_type</a>, <a href="#rust_library.rustc_flags">rustc_flags</a>)</pre>
+
+ <p>Builds a Rust library crate.</p>
+
+
+ <h3 id="rust_library_args">Attributes</h3>
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="rust_library.name">
+ <td><code>name</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#name">Name</a>; Required</code></p>
+ <p>This name will also be used as the name of the library crate built by
+this rule.</p>
+ </td>
+ </tr>
+ <tr id="rust_library.deps">
+ <td><code>deps</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <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 id="rust_library.data">
+ <td><code>data</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <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"><code>include_str!</code></a>
+macro.</p>
+ </td>
+ </tr>
+ <tr id="rust_library.srcs">
+ <td><code>srcs</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <p>List of Rust <code>.rs</code> source files used to build the test.</p>
+<p>If <code>srcs</code> contains more than one file, then there must be a file either
+named <code>lib.rs</code>. Otherwise, <code>crate_root</code> must be set to the source file that
+is the root of the crate to be passed to rustc to build this crate.</p>
+ </td>
+ </tr>
+ <tr id="rust_library.crate_features">
+ <td><code>crate_features</code></td>
+ <td>
+ <p><code>List of strings; Optional; Default is []</code></p>
+ <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 id="rust_library.crate_root">
+ <td><code>crate_root</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; Optional</code></p>
+ <p>The file that will be passed to <code>rustc</code> to be used for building
+this crate.</p>
+<p>If <code>crate_root</code> is not set, then this rule will look for a <code>lib.rs</code> file or
+the single file in <code>srcs</code> if <code>srcs</code> contains only one file.</p>
+ </td>
+ </tr>
+ <tr id="rust_library.crate_type">
+ <td><code>crate_type</code></td>
+ <td>
+ <p><code>String; Optional; Default is ''</code></p>
+
+ </td>
+ </tr>
+ <tr id="rust_library.rustc_flags">
+ <td><code>rustc_flags</code></td>
+ <td>
+ <p><code>List of strings; Optional; Default is []</code></p>
+ <p>List of compiler flags passed to <code>rustc</code>.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+ <h3 id="rust_library_examples">Examples</h3>
+ <p>Suppose you have the following directory structure for a simple Rust library
+crate:</p>
+<pre><code>[workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ greeter.rs
+ lib.rs
+</code></pre>
+<p><code>hello_lib/src/greeter.rs</code>:</p>
+<pre><code class="lang-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);
+ }
+}
+</code></pre>
+<p><code>hello_lib/src/lib.rs</code>:</p>
+<pre><code class="lang-rust">pub mod greeter;
+</code></pre>
+<p><code>hello_lib/BUILD</code>:</p>
+<pre><code class="lang-python">package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library")
+
+rust_library(
+ name = "hello_lib",
+ srcs = [
+ "src/greeter.rs",
+ "src/lib.rs",
+ ],
+)
+</code></pre>
+<p>Build the library:</p>
+<pre><code>$ 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
+</code></pre>
+
+ <hr>
+
+ <h2 id="rust_test">rust_test</h2>
+
+ <pre>rust_test(<a href="#rust_test.name">name</a>, <a href="#rust_test.deps">deps</a>, <a href="#rust_test.data">data</a>, <a href="#rust_test.srcs">srcs</a>, <a href="#rust_test.crate_features">crate_features</a>, <a href="#rust_test.crate_root">crate_root</a>, <a href="#rust_test.rustc_flags">rustc_flags</a>)</pre>
+
+ <p>Builds a Rust test crate.</p>
+
+
+ <h3 id="rust_test_args">Attributes</h3>
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="rust_test.name">
+ <td><code>name</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#name">Name</a>; Required</code></p>
+ <p>This name will also be used as the name of the binary crate built by
+this rule.</p>
+ </td>
+ </tr>
+ <tr id="rust_test.deps">
+ <td><code>deps</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <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 id="rust_test.data">
+ <td><code>data</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <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"><code>include_str!</code></a>
+macro.</p>
+ </td>
+ </tr>
+ <tr id="rust_test.srcs">
+ <td><code>srcs</code></td>
+ <td>
+ <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+ <p>List of Rust <code>.rs</code> source files used to build the test.</p>
+<p>If <code>srcs</code> contains more than one file, then there must be a file either
+named <code>lib.rs</code>. Otherwise, <code>crate_root</code> must be set to the source file that
+is the root of the crate to be passed to rustc to build this crate.</p>
+ </td>
+ </tr>
+ <tr id="rust_test.crate_features">
+ <td><code>crate_features</code></td>
+ <td>
+ <p><code>List of strings; Optional; Default is []</code></p>
+ <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 id="rust_test.crate_root">
+ <td><code>crate_root</code></td>
+ <td>
+ <p><code><a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; Optional</code></p>
+ <p>The file that will be passed to <code>rustc</code> to be used for building
+this crate.</p>
+<p>If <code>crate_root</code> is not set, then this rule will look for a <code>lib.rs</code> file or
+the single file in <code>srcs</code> if <code>srcs</code> contains only one file.</p>
+ </td>
+ </tr>
+ <tr id="rust_test.rustc_flags">
+ <td><code>rustc_flags</code></td>
+ <td>
+ <p><code>List of strings; Optional; Default is []</code></p>
+ <p>List of compiler flags passed to <code>rustc</code>.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+ <h3 id="rust_test_examples">Examples</h3>
+ <p>Suppose you have the following directory structure for a Rust library crate
+with unit test code in the library sources:</p>
+<pre><code>[workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+</code></pre>
+<p><code>hello_lib/src/lib.rs</code>:</p>
+<pre><code class="lang-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);
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::Greeter;
+
+ #[test]
+ fn test_greeting() {
+ let hello = Greeter::new("Hi");
+ assert_eq!("Hi Rust", hello.greeting("Rust"));
+ }
+}
+</code></pre>
+<p>To build and run the tests, simply add a <code>rust_test</code> rule with no <code>srcs</code> and
+only depends on the <code>hello_lib</code> <code>rust_library</code> target:</p>
+<p><code>hello_lib/BUILD</code>:</p>
+<pre><code class="lang-python">package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_test")
+
+rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+)
+
+rust_test(
+ name = "hello_lib_test",
+ deps = [":hello_lib"],
+)
+</code></pre>
+<p>Run the test with <code>bazel build //hello_lib:hello_lib_test</code>.</p>
+<h3>Example: <code>test</code> directory</h3>
+<p>Integration tests that live in the <a href="http://doc.rust-lang.org/book/testing.html#the-tests-directory"><code>tests</code> directory</a>, they are
+essentially built as separate crates. Suppose you have the following directory
+structure where <code>greeting.rs</code> is an integration test for the <code>hello_lib</code>
+library crate:</p>
+<pre><code>[workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+ tests/
+ greeting.rs
+</code></pre>
+<p><code>hello_lib/tests/greeting.rs</code>:</p>
+<pre><code class="lang-rust">extern crate hello_lib;
+
+use hello_lib;
+
+#[test]
+fn test_greeting() {
+ let hello = greeter::Greeter::new("Hello");
+ assert_eq!("Hello world", hello.greeting("world"));
+}
+</code></pre>
+<p>To build the <code>greeting.rs</code> integration test, simply add a <code>rust_test</code> target
+with <code>greeting.rs</code> in <code>srcs</code> and a dependency on the <code>hello_lib</code> target:</p>
+<p><code>hello_lib/BUILD</code>:</p>
+<pre><code class="lang-python">package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_test")
+
+rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+)
+
+rust_test(
+ name = "greeting_test",
+ srcs = ["tests/greeting.rs"],
+ deps = [":hello_lib"],
+)
+</code></pre>
+<p>Run the test with <code>bazel build //hello_lib:hello_lib_test</code>.</p>
+
+
+
+ </div>
+
+ <footer class="mdl-mini-footer">
+ <div class="mdl-mini-footer__left-section">
+ <div class="mdl-logo">Bazel</div>
+ <ul class="mdl-mini-footer__link-list">
+ <li><a href="http://bazel.io">Home</a></li>
+ <li><a href="https://github.com/bazelbuild">GitHub</a></li>
+ </ul>
+ </div>
+ </footer>
+ </main>
+ </div>
+ </body>
+</html>
diff --git a/rust/BUILD b/rust/BUILD
index 3abf631..21e9bb8 100644
--- a/rust/BUILD
+++ b/rust/BUILD
@@ -1,9 +1,11 @@
package(default_visibility = ["//visibility:public"])
-filegroup(
- name = "srcs",
- srcs = glob(["**"]),
- visibility = ["//tools:__pkg__"],
+load("@io_bazel_skydoc//skylark:skylark.bzl", "skylark_doc")
+
+skylark_doc(
+ name = "rust-docs",
+ srcs = ["rust.bzl"],
+ format = "html",
)
config_setting(
diff --git a/rust/rust.bzl b/rust/rust.bzl
index 6d904d2..5546e2d 100644
--- a/rust/rust.bzl
+++ b/rust/rust.bzl
@@ -12,7 +12,38 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-"""Rust rules for Bazel"""
+"""Rust Rules
+
+These build rules are used for building [Rust][rust] projects with Bazel.
+
+[rust]: http://www.rust-lang.org/
+
+### Setup
+
+To use the Rust rules, add the following to your `WORKSPACE` file to add the
+external repositories for the Rust toolchain:
+
+```python
+git_repository(
+ name = "io_bazel_rules_rust",
+ remote = "https://github.com/bazelbuild/rules_rust.git",
+ tag = "0.0.1",
+)
+load("@io_bazel_rules_rust//rust:rust.bzl", "rust_repositories")
+
+rust_repositories()
+```
+
+### Roadmap
+
+* Add `rust_toolchain` rule to make it easy to use a custom Rust toolchain.
+* 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/).
+"""
RUST_FILETYPE = FileType([".rs"])
@@ -167,16 +198,16 @@
features_flags += ["--cfg feature=\\\"%s\\\"" % feature]
return features_flags
-def get_dirname(short_path):
+def _get_dirname(short_path):
return short_path[0:short_path.rfind('/')]
def _rust_toolchain(ctx):
return struct(
rustc_path = ctx.file._rustc.path,
rustc_lib_path = ctx.files._rustc_lib[0].dirname,
- rustc_lib_short_path = get_dirname(ctx.files._rustc_lib[0].short_path),
+ rustc_lib_short_path = _get_dirname(ctx.files._rustc_lib[0].short_path),
rustlib_path = ctx.files._rustlib[0].dirname,
- rustlib_short_path = get_dirname(ctx.files._rustlib[0].short_path),
+ rustlib_short_path = _get_dirname(ctx.files._rustlib[0].short_path),
rustdoc_path = ctx.file._rustdoc.path,
rustdoc_short_path = ctx.file._rustdoc.short_path)
@@ -627,47 +658,528 @@
),
}
-_rust_library_attrs = _rust_common_attrs + {
+_rust_library_attrs = {
"crate_type": attr.string(),
}
rust_library = rule(
_rust_library_impl,
- attrs = _rust_library_attrs + _rust_toolchain_attrs,
+ attrs = dict(_rust_common_attrs.items() +
+ _rust_library_attrs.items() +
+ _rust_toolchain_attrs.items()),
fragments = ["cpp"],
outputs = {
"rust_lib": "lib%{name}.rlib",
},
)
+"""Builds a Rust library crate.
+
+Args:
+ name: This name will also be used as the name of the library crate built by
+ this rule.
+ srcs: List of Rust `.rs` source files used to build the library.
+
+ If `srcs` contains more than one file, then there must be a file either
+ named `lib.rs`. Otherwise, `crate_root` must be set to the source file that
+ is the root of the crate to be passed to rustc to build this crate.
+ crate_root: The file that will be passed to `rustc` to be used for building
+ this crate.
+
+ If `crate_root` is not set, then this rule will look for a `lib.rs` file or
+ the single file in `srcs` if `srcs` contains only one file.
+ deps: List of other libraries to be linked to this library target.
+
+ These can be either other `rust_library` targets or `cc_library` targets if
+ linking a native library.
+ data: List of files used by this rule at runtime.
+
+ This attribute can be used to specify any data files that are embedded into
+ the library, such as via the
+ [`include_str!`](https://doc.rust-lang.org/std/macro.include_str!.html)
+ macro.
+ crate_features: List of features to enable for this crate.
+
+ Features are defined in the code using the `#[cfg(feature = "foo")]`
+ configuration option. The features listed here will be passed to `rustc`
+ with `--cfg feature="${feature_name}"` flags.
+ rustc_flags: List of compiler flags passed to `rustc`.
+
+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("@io_bazel_rules_rust//rust:rust.bzl", "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
+ ```
+"""
rust_binary = rule(
_rust_binary_impl,
- attrs = _rust_common_attrs + _rust_toolchain_attrs,
+ attrs = dict(_rust_common_attrs.items() + _rust_toolchain_attrs.items()),
executable = True,
fragments = ["cpp"],
)
+"""Builds a Rust binary crate.
+
+Args:
+ name: This name will also be used as the name of the binary crate built by
+ this rule.
+ srcs: List of Rust `.rs` source files used to build the library.
+
+ If `srcs` contains more than one file, then there must be a file either
+ named `main.rs`. Otherwise, `crate_root` must be set to the source file that
+ is the root of the crate to be passed to rustc to build this crate.
+ crate_root: The file that will be passed to `rustc` to be used for building
+ this crate.
+
+ If `crate_root` is not set, then this rule will look for a `bin.rs` file or
+ the single file in `srcs` if `srcs` contains only one file.
+ deps: List of other libraries to be linked to this library target.
+
+ These must be `rust_library` targets.
+ data: List of files used by this rule at runtime.
+
+ This attribute can be used to specify any data files that are embedded into
+ the library, such as via the
+ [`include_str!`](https://doc.rust-lang.org/std/macro.include_str!.html)
+ macro.
+ crate_features: List of features to enable for this crate.
+
+ Features are defined in the code using the `#[cfg(feature = "foo")]`
+ configuration option. The features listed here will be passed to `rustc`
+ with `--cfg feature="${feature_name}"` flags.
+ rustc_flags: List of compiler flags passed to `rustc`.
+
+Example:
+ Suppose you have the following directory structure for a Rust project with a
+ library crate, `hello_lib`, and a binary crate, `hello_world` that uses the
+ `hello_lib` library:
+
+ ```
+ [workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+ hello_world/
+ BUILD
+ src/
+ main.rs
+ ```
+
+ `hello_lib/src/lib.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/BUILD`:
+
+ ```python
+ package(default_visibility = ["//visibility:public"])
+
+ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library")
+
+ rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+ )
+ ```
+
+ `hello_world/src/main.rs`:
+
+ ```rust
+ extern crate hello_lib;
+
+ fn main() {
+ let hello = hello_lib::Greeter::new("Hello");
+ hello.greet("world");
+ }
+ ```
+
+ `hello_world/BUILD`:
+
+ ```python
+ load("@io_bazel_rules_rust//rust:rust.bzl", "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
+ ```
+"""
rust_test = rule(
_rust_test_impl,
- attrs = _rust_common_attrs + _rust_toolchain_attrs,
+ attrs = dict(_rust_common_attrs.items() + _rust_toolchain_attrs.items()),
executable = True,
fragments = ["cpp"],
test = True,
)
+"""Builds a Rust test crate.
+
+Args:
+ name: This name will also be used as the name of the binary crate built by
+ this rule.
+ srcs: List of Rust `.rs` source files used to build the test.
+
+ If `srcs` contains more than one file, then there must be a file either
+ named `lib.rs`. Otherwise, `crate_root` must be set to the source file that
+ is the root of the crate to be passed to rustc to build this crate.
+ crate_root: The file that will be passed to `rustc` to be used for building
+ this crate.
+
+ If `crate_root` is not set, then this rule will look for a `lib.rs` file or
+ the single file in `srcs` if `srcs` contains only one file.
+ deps: List of other libraries to be linked to this library target.
+
+ These must be `rust_library` targets.
+ data: List of files used by this rule at runtime.
+
+ This attribute can be used to specify any data files that are embedded into
+ the library, such as via the
+ [`include_str!`](https://doc.rust-lang.org/std/macro.include_str!.html)
+ macro.
+ crate_features: List of features to enable for this crate.
+
+ Features are defined in the code using the `#[cfg(feature = "foo")]`
+ configuration option. The features listed here will be passed to `rustc`
+ with `--cfg feature="${feature_name}"` flags.
+ rustc_flags: List of compiler flags passed to `rustc`.
+
+Examples:
+ Suppose you have the following directory structure for a Rust library crate
+ with unit test code in the library sources:
+
+ ```
+ [workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+ ```
+
+ `hello_lib/src/lib.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);
+ }
+ }
+
+ #[cfg(test)]
+ mod test {
+ use super::Greeter;
+
+ #[test]
+ fn test_greeting() {
+ let hello = Greeter::new("Hi");
+ assert_eq!("Hi Rust", hello.greeting("Rust"));
+ }
+ }
+ ```
+
+ To build and run the tests, simply add a `rust_test` rule with no `srcs` and
+ only depends on the `hello_lib` `rust_library` target:
+
+ `hello_lib/BUILD`:
+
+ ```python
+ package(default_visibility = ["//visibility:public"])
+
+ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_test")
+
+ rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+ )
+
+ rust_test(
+ name = "hello_lib_test",
+ deps = [":hello_lib"],
+ )
+ ```
+
+ Run the test with `bazel build //hello_lib:hello_lib_test`.
+
+ ### Example: `test` directory
+
+ Integration tests that live in the [`tests` directory][int-tests], they are
+ essentially built as separate crates. Suppose you have the following directory
+ structure where `greeting.rs` is an integration test for the `hello_lib`
+ library crate:
+
+ [int-tests]: http://doc.rust-lang.org/book/testing.html#the-tests-directory
+
+ ```
+ [workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+ tests/
+ greeting.rs
+ ```
+
+ `hello_lib/tests/greeting.rs`:
+
+ ```rust
+ extern crate hello_lib;
+
+ use hello_lib;
+
+ #[test]
+ fn test_greeting() {
+ let hello = greeter::Greeter::new("Hello");
+ assert_eq!("Hello world", hello.greeting("world"));
+ }
+ ```
+
+ To build the `greeting.rs` integration test, simply add a `rust_test` target
+ with `greeting.rs` in `srcs` and a dependency on the `hello_lib` target:
+
+ `hello_lib/BUILD`:
+
+ ```python
+ package(default_visibility = ["//visibility:public"])
+
+ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_test")
+
+ rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+ )
+
+ rust_test(
+ name = "greeting_test",
+ srcs = ["tests/greeting.rs"],
+ deps = [":hello_lib"],
+ )
+ ```
+
+ Run the test with `bazel build //hello_lib:hello_lib_test`.
+"""
rust_bench_test = rule(
_rust_bench_test_impl,
- attrs = _rust_common_attrs + _rust_toolchain_attrs,
+ attrs = dict(_rust_common_attrs.items() + _rust_toolchain_attrs.items()),
executable = True,
fragments = ["cpp"],
test = True,
)
+"""Builds a Rust benchmark test.
+
+**Warning**: This rule is currently experimental. [Rust Benchmark
+tests][rust-bench] require the `Bencher` interface in the unstable `libtest`
+crate, which is behind the `test` unstable feature gate. As a result, using
+this rule would require using a nightly binary release of Rust. A
+`rust_toolchain` rule will be added in the [near future](#roadmap) to make it
+easy to use a custom Rust toolchain, such as a nightly release.
+
+[rust-bench]: https://doc.rust-lang.org/book/benchmark-tests.html
+
+Args:
+ name: This name will also be used as the name of the binary crate built by
+ this rule.
+ srcs: List of Rust `.rs` source files used to build the test.
+
+ If `srcs` contains more than one file, then there must be a file either
+ named `lib.rs`. Otherwise, `crate_root` must be set to the source file that
+ is the root of the crate to be passed to rustc to build this crate.
+ crate_root: The file that will be passed to `rustc` to be used for building
+ this crate.
+
+ If `crate_root` is not set, then this rule will look for a `lib.rs` file or
+ the single file in `srcs` if `srcs` contains only one file.
+ deps: List of other libraries to be linked to this library target.
+
+ These must be `rust_library` targets.
+ data: List of files used by this rule at runtime.
+
+ This attribute can be used to specify any data files that are embedded into
+ the library, such as via the
+ [`include_str!`](https://doc.rust-lang.org/std/macro.include_str!.html)
+ macro.
+ crate_features: List of features to enable for this crate.
+
+ Features are defined in the code using the `#[cfg(feature = "foo")]`
+ configuration option. The features listed here will be passed to `rustc`
+ with `--cfg feature="${feature_name}"` flags.
+ rustc_flags: List of compiler flags passed to `rustc`.
+
+Example:
+ Suppose you have the following directory structure for a Rust project with a
+ library crate, `fibonacci` with benchmarks under the `benches/` directory:
+
+ ```
+ [workspace]/
+ WORKSPACE
+ fibonacci/
+ BUILD
+ src/
+ lib.rs
+ benches/
+ fibonacci_bench.rs
+ ```
+
+ `fibonacci/src/lib.rs`:
+
+ ```rust
+ pub fn fibonacci(n: u64) -> u64 {
+ if n < 2 {
+ return n;
+ }
+ let mut n1: u64 = 0;
+ let mut n2: u64 = 1;
+ for _ in 1..n {
+ let sum = n1 + n2;
+ n1 = n2;
+ n2 = sum;
+ }
+ n2
+ }
+ ```
+
+ `fibonacci/benches/fibonacci_bench.rs`:
+
+ ```rust
+ #![feature(test)]
+
+ extern crate test;
+ extern crate fibonacci;
+
+ use test::Bencher;
+
+ #[bench]
+ fn bench_fibonacci(b: &mut Bencher) {
+ b.iter(|| fibonacci::fibonacci(40));
+ }
+ ```
+
+ To build the benchmark test, simply add a `rust_bench_test` target:
+
+ `fibonacci/BUILD`:
+
+ ```python
+ package(default_visibility = ["//visibility:public"])
+
+ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_bench_test")
+
+ rust_library(
+ name = "fibonacci",
+ srcs = ["src/lib.rs"],
+ )
+
+ rust_bench_test(
+ name = "fibonacci_bench",
+ srcs = ["benches/fibonacci_bench.rs"],
+ deps = [":fibonacci"],
+ )
+ ```
+
+ Run the benchmark test using: `bazel build //fibonacci:fibonacci_bench`.
+"""
_rust_doc_common_attrs = {
"dep": attr.label(mandatory = True),
}
-_rust_doc_attrs = _rust_doc_common_attrs + {
+_rust_doc_attrs = {
"markdown_css": attr.label_list(allow_files = CSS_FILETYPE),
"html_in_header": attr.label(allow_files = HTML_MD_FILETYPE),
"html_before_content": attr.label(allow_files = HTML_MD_FILETYPE),
@@ -676,18 +1188,116 @@
rust_doc = rule(
_rust_doc_impl,
- attrs = _rust_doc_attrs + _rust_toolchain_attrs,
+ attrs = dict(_rust_doc_common_attrs.items() +
+ _rust_doc_attrs.items() +
+ _rust_toolchain_attrs.items()),
outputs = {
"rust_doc_zip": "%{name}-docs.zip",
},
)
+"""Generates code documentation.
+
+Args:
+ name: A unique name for this rule.
+ dep: The label of the target to generate code documentation for.
+
+ `rust_doc` can generate HTML code documentation for the source files of
+ `rust_library` or `rust_binary` targets.
+ markdown_css: CSS files to include via `<link>` in a rendered
+ Markdown file.
+ html_in_header: File to add to `<head>`.
+ html_before_content: File to add in `<body>`, before content.
+ html_after_content: File to add in `<body>`, after content.
+
+Example:
+ Suppose you have the following directory structure for a Rust library crate:
+
+ ```
+ [workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+ ```
+
+ To build [`rustdoc`][rustdoc] documentation for the `hello_lib` crate, define
+ a `rust_doc` rule that depends on the the `hello_lib` `rust_library` target:
+
+ [rustdoc]: https://doc.rust-lang.org/book/documentation.html
+
+ ```python
+ package(default_visibility = ["//visibility:public"])
+
+ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_doc")
+
+ rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+ )
+
+ rust_doc(
+ name = "hello_lib_doc",
+ dep = ":hello_lib",
+ )
+ ```
+
+ Running `bazel build //hello_lib:hello_lib_doc` will build a zip file containing
+ the documentation for the `hello_lib` library crate generated by `rustdoc`.
+"""
rust_doc_test = rule(
_rust_doc_test_impl,
- attrs = _rust_doc_common_attrs + _rust_toolchain_attrs,
+ attrs = dict(_rust_doc_common_attrs.items() +
+ _rust_toolchain_attrs.items()),
executable = True,
test = True,
)
+"""Runs Rust documentation tests.
+
+Args:
+ name: A unique name for this rule.
+ dep: The label of the target to run documentation tests for.
+
+ `rust_doc_test` can run documentation tests for the source files of
+ `rust_library` or `rust_binary` targets.
+
+Example:
+ Suppose you have the following directory structure for a Rust library crate:
+
+ ```
+ [workspace]/
+ WORKSPACE
+ hello_lib/
+ BUILD
+ src/
+ lib.rs
+ ```
+
+ To run [documentation tests][doc-test] for the `hello_lib` crate, define a
+ `rust_doc_test` target that depends on the `hello_lib` `rust_library` target:
+
+ [doc-test]: https://doc.rust-lang.org/book/documentation.html#documentation-as-tests
+
+ ```python
+ package(default_visibility = ["//visibility:public"])
+
+ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_doc_test")
+
+ rust_library(
+ name = "hello_lib",
+ srcs = ["src/lib.rs"],
+ )
+
+ rust_doc_test(
+ name = "hello_lib_doc_test",
+ dep = ":hello_lib",
+ )
+ ```
+
+ Running `bazel test //hello_lib:hello_lib_doc_test` will run all documentation
+ tests for the `hello_lib` library crate.
+"""
RUST_BUILD_FILE = """
config_setting(
@@ -752,6 +1362,7 @@
"""
def rust_repositories():
+ """Adds the external dependencies needed for the Rust rules."""
native.new_http_archive(
name = "rust_linux_x86_64",
url = "http://bazel-mirror.storage.googleapis.com/static.rust-lang.org/dist/rust-1.11.0-x86_64-unknown-linux-gnu.tar.gz",