aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--WORKSPACE12
-rw-r--r--examples/rust/hello_lib/BUILD7
-rw-r--r--examples/rust/hello_lib/src/greeter.rs31
-rw-r--r--examples/rust/hello_world/BUILD7
-rw-r--r--tools/build_rules/rust/BUILD8
-rw-r--r--tools/build_rules/rust/README.md77
-rw-r--r--tools/build_rules/rust/rust-darwin-x86_64.BUILD29
-rw-r--r--tools/build_rules/rust/rust-linux-x86_64.BUILD29
-rw-r--r--tools/build_rules/rust/rust.BUILD57
-rw-r--r--tools/build_rules/rust/rust.WORKSPACE12
-rw-r--r--tools/build_rules/rust/rust.bzl315
11 files changed, 433 insertions, 151 deletions
diff --git a/WORKSPACE b/WORKSPACE
index 6f2df12186..b3aebe8e76 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -44,16 +44,16 @@ maven_jar(
new_http_archive(
name = "rust-linux-x86_64",
- url = "https://static.rust-lang.org/dist/rust-1.2.0-x86_64-unknown-linux-gnu.tar.gz",
- sha256 = "2311420052e06b3e698ce892924ec40890a8ff0499902e7fc5350733187a1531",
- build_file = "tools/build_rules/rust/rust-linux-x86_64.BUILD",
+ url = "https://static.rust-lang.org/dist/rust-1.3.0-x86_64-unknown-linux-gnu.tar.gz",
+ sha256 = "fa755b6331ff7554e6e8545ee20af7897b0adc65f471dd24ae8a467a944755b4",
+ build_file = "tools/build_rules/rust/rust.BUILD",
)
new_http_archive(
name = "rust-darwin-x86_64",
- url = "https://static.rust-lang.org/dist/rust-1.2.0-x86_64-apple-darwin.tar.gz",
- sha256 = "0d471e672fac5a450ae5507b335fda2efc0b22ea9fb7f215c6a9c466dafa2661",
- build_file = "tools/build_rules/rust/rust-darwin-x86_64.BUILD",
+ url = "https://static.rust-lang.org/dist/rust-1.3.0-x86_64-apple-darwin.tar.gz",
+ sha256 = "bfeac876e22cc5fe63a250644ce1a6f3892c13a5461131a881419bd06fcb2011",
+ build_file = "tools/build_rules/rust/rust.BUILD",
)
# In order to run the Android integration tests, uncomment these rules, point
diff --git a/examples/rust/hello_lib/BUILD b/examples/rust/hello_lib/BUILD
index 64cc935b27..a075f8b168 100644
--- a/examples/rust/hello_lib/BUILD
+++ b/examples/rust/hello_lib/BUILD
@@ -1,6 +1,6 @@
package(default_visibility = ["//visibility:public"])
-load("/tools/build_rules/rust/rust", "rust_library", "rust_test")
+load("/tools/build_rules/rust/rust", "rust_library", "rust_docs", "rust_test")
rust_library(
name = "hello_lib",
@@ -10,6 +10,11 @@ rust_library(
],
)
+rust_docs(
+ name = "hello_lib_docs",
+ dep = ":hello_lib",
+)
+
rust_test(
name = "greeting",
srcs = ["tests/greeting.rs"],
diff --git a/examples/rust/hello_lib/src/greeter.rs b/examples/rust/hello_lib/src/greeter.rs
index be59ff888d..2a4a2f1d3f 100644
--- a/examples/rust/hello_lib/src/greeter.rs
+++ b/examples/rust/hello_lib/src/greeter.rs
@@ -12,19 +12,50 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+/// Object that displays a greeting.
pub struct Greeter {
greeting: String,
}
+/// Implementation of Greeter.
impl Greeter {
+ /// Constructs a new `Greeter`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hello_lib::greeter;
+ ///
+ /// let greeter = Greeter::new("Hello");
+ /// ```
pub fn new(greeting: &str) -> Greeter {
Greeter { greeting: greeting.to_string(), }
}
+ /// Returns the greeting as a string.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hello_lib::greeter;
+ ///
+ /// let greeter = Greeter::new("Hello");
+ /// let greeting = greeter.greeting("World");
+ /// ```
pub fn greeting(&self, thing: &str) -> String {
format!("{} {}", &self.greeting, thing)
}
+ /// Prints the greeting.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hello_lib::greeter;
+ ///
+ /// let greeter = Greeter::new("Hello");
+ /// greeter.greet("World");
+ /// ```
pub fn greet(&self, thing: &str) {
println!("{} {}", &self.greeting, thing);
}
diff --git a/examples/rust/hello_world/BUILD b/examples/rust/hello_world/BUILD
index e774dcc835..ccd87f1b93 100644
--- a/examples/rust/hello_world/BUILD
+++ b/examples/rust/hello_world/BUILD
@@ -1,9 +1,14 @@
package(default_visibility = ["//visibility:public"])
-load("/tools/build_rules/rust/rust", "rust_binary")
+load("/tools/build_rules/rust/rust", "rust_binary", "rust_docs")
rust_binary(
name = "hello_world",
srcs = ["src/main.rs"],
deps = ["//examples/rust/hello_lib"],
)
+
+rust_docs(
+ name = "hello_world_docs",
+ dep = ":hello_world",
+)
diff --git a/tools/build_rules/rust/BUILD b/tools/build_rules/rust/BUILD
index e212a3160e..78d2ee6223 100644
--- a/tools/build_rules/rust/BUILD
+++ b/tools/build_rules/rust/BUILD
@@ -33,6 +33,14 @@ filegroup(
)
filegroup(
+ name = "rustdoc",
+ srcs = select({
+ ":darwin": ["@rust-darwin-x86_64//:rustdoc"],
+ ":k8": ["@rust-linux-x86_64//:rustdoc"],
+ }),
+)
+
+filegroup(
name = "rustlib",
srcs = select({
":darwin": ["@rust-darwin-x86_64//:rustlib"],
diff --git a/tools/build_rules/rust/README.md b/tools/build_rules/rust/README.md
index c82179d08b..536c10f837 100644
--- a/tools/build_rules/rust/README.md
+++ b/tools/build_rules/rust/README.md
@@ -10,6 +10,7 @@ These build rules are used for building [Rust][rust] projects with Bazel.
* [`rust_library`](#reference-rust_library)
* [`rust_binary`](#reference-rust_binary)
* [`rust_test`](#reference-rust_test)
+ * [`rust_docs`](#reference-rust_docs)
* [Roadmap](#roadmap)
[rust]: http://www.rust-lang.org/
@@ -320,7 +321,9 @@ Hello world
<a name="reference-rust_test"></a>
### `rust_test`
-`rust_test(name, srcs, deps, data, crate_features, rustc_flags)`
+```python
+rust_test(name, srcs, deps, data, crate_features, rustc_flags)
+```
<table>
<thead>
@@ -402,18 +405,82 @@ Hello world
</tbody>
</table>
+<a name="reference-rust_docs"></a>
+### `rust_docs`
+
+```python
+rust_docs(name, dep, markdown_css, html_in_header, html_before_content, html_after_content)
+```
+
+<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>
+ </td>
+ </tr>
+ <tr>
+ <td><code>dep</code></td>
+ <td>
+ <code>Label, required</code>
+ <p>The label of the target to generate code documentation for.</p>
+ <p>
+ <code>rust_docs</code> can generate HTML code documentation for the
+ source files of <code>rust_library</code> or <code>rust_binary</code>
+ targets.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>markdown_css</code></td>
+ <td>
+ <code>List of Labels, optional</code>
+ <p>
+ CSS files to include via <code>&lt;link&gt;</code> in a rendered
+ Markdown file.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>html_in_header</code></td>
+ <td>
+ <code>Label, optional</code>
+ <p>File to add to <code>&lt;head&gt;</code>.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>html_before_content</code></td>
+ <td>
+ <code>Label, optional</code>
+ <p>File to add in <code>&lt;body&gt;</code>, before content.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>html_after_content</code></td>
+ <td>
+ <code>Label, optional</code>
+ <p>File to add in <code>&lt;body&gt;</code>, after content.</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
diff --git a/tools/build_rules/rust/rust-darwin-x86_64.BUILD b/tools/build_rules/rust/rust-darwin-x86_64.BUILD
deleted file mode 100644
index cc7aaadd2f..0000000000
--- a/tools/build_rules/rust/rust-darwin-x86_64.BUILD
+++ /dev/null
@@ -1,29 +0,0 @@
-BASE_DIR = "rust-1.2.0-x86_64-apple-darwin/"
-
-filegroup(
- name = "rustc",
- srcs = [BASE_DIR + "rustc/bin/rustc"],
- visibility = ["//visibility:public"],
-)
-
-filegroup(
- name = "rustc_lib",
- srcs = glob([BASE_DIR + "rustc/lib/*.dylib"]),
- visibility = ["//visibility:public"],
-)
-
-filegroup(
- name = "rustdoc",
- srcs = [BASE_DIR + "rustc/bin/rustdoc"],
- visibility = ["//visibility:public"],
-)
-
-filegroup(
- name = "rustlib",
- srcs = glob([
- BASE_DIR + "rustc/lib/rustlib/x86_64-apple-darwin/lib/*.rlib",
- BASE_DIR + "rustc/lib/rustlib/x86_64-apple-darwin/lib/*.dylib",
- BASE_DIR + "rustc/lib/rustlib/x86_64-apple-darwin/lib/*.a",
- ]),
- visibility = ["//visibility:public"],
-)
diff --git a/tools/build_rules/rust/rust-linux-x86_64.BUILD b/tools/build_rules/rust/rust-linux-x86_64.BUILD
deleted file mode 100644
index 7d4a7e3478..0000000000
--- a/tools/build_rules/rust/rust-linux-x86_64.BUILD
+++ /dev/null
@@ -1,29 +0,0 @@
-BASE_DIR = "rust-1.2.0-x86_64-unknown-linux-gnu/"
-
-filegroup(
- name = "rustc",
- srcs = [BASE_DIR + "rustc/bin/rustc"],
- visibility = ["//visibility:public"],
-)
-
-filegroup(
- name = "rustc_lib",
- srcs = glob([BASE_DIR + "rustc/lib/*.so"]),
- visibility = ["//visibility:public"],
-)
-
-filegroup(
- name = "rustdoc",
- srcs = [BASE_DIR + "rustc/bin/rustdoc"],
- visibility = ["//visibility:public"],
-)
-
-filegroup(
- name = "rustlib",
- srcs = glob([
- BASE_DIR + "rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.rlib",
- BASE_DIR + "rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.so",
- BASE_DIR + "rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.a",
- ]),
- visibility = ["//visibility:public"],
-)
diff --git a/tools/build_rules/rust/rust.BUILD b/tools/build_rules/rust/rust.BUILD
new file mode 100644
index 0000000000..576f8b868b
--- /dev/null
+++ b/tools/build_rules/rust/rust.BUILD
@@ -0,0 +1,57 @@
+RUST_VERSION = "1.3.0"
+LINUX_BASE_DIR = "rust-%s-x86_64-unknown-linux-gnu/" % RUST_VERSION
+DARWIN_BASE_DIR = "rust-%s-x86_64-apple-darwin/" % RUST_VERSION
+
+config_setting(
+ name = "darwin",
+ values = {"host_cpu": "darwin"},
+)
+
+config_setting(
+ name = "k8",
+ values = {"host_cpu": "k8"},
+)
+
+filegroup(
+ name = "rustc",
+ srcs = select({
+ ":darwin": [DARWIN_BASE_DIR + "rustc/bin/rustc"],
+ ":k8": [LINUX_BASE_DIR + "rustc/bin/rustc"],
+ }),
+ visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "rustc_lib",
+ srcs = select({
+ ":darwin": glob([DARWIN_BASE_DIR + "rustc/lib/*.dylib"]),
+ ":k8": glob([LINUX_BASE_DIR + "rustc/lib/*.so"]),
+ }),
+ visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "rustdoc",
+ srcs = select({
+ ":darwin": [DARWIN_BASE_DIR + "rustc/bin/rustdoc"],
+ ":k8": [LINUX_BASE_DIR + "rustc/bin/rustdoc"],
+ }),
+ visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "rustlib",
+ srcs = select({
+ ":darwin": glob([
+ DARWIN_BASE_DIR + "rustc/lib/rustlib/x86_64-apple-darwin/lib/*.rlib",
+ DARWIN_BASE_DIR + "rustc/lib/rustlib/x86_64-apple-darwin/lib/*.dylib",
+ DARWIN_BASE_DIR + "rustc/lib/rustlib/x86_64-apple-darwin/lib/*.a",
+ ]),
+ ":k8": glob([
+ LINUX_BASE_DIR + "rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.rlib",
+ LINUX_BASE_DIR + "rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.so",
+ LINUX_BASE_DIR + "rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.a",
+ ]),
+ }),
+ visibility = ["//visibility:public"],
+)
diff --git a/tools/build_rules/rust/rust.WORKSPACE b/tools/build_rules/rust/rust.WORKSPACE
index 4086ce80be..c93deb4917 100644
--- a/tools/build_rules/rust/rust.WORKSPACE
+++ b/tools/build_rules/rust/rust.WORKSPACE
@@ -1,13 +1,13 @@
new_http_archive(
name = "rust-linux-x86_64",
- url = "https://static.rust-lang.org/dist/rust-1.2.0-x86_64-unknown-linux-gnu.tar.gz",
- sha256 = "2311420052e06b3e698ce892924ec40890a8ff0499902e7fc5350733187a1531",
- build_file = "tools/build_rules/rust/rust-linux-x86_64.BUILD",
+ url = "https://static.rust-lang.org/dist/rust-1.3.0-x86_64-unknown-linux-gnu.tar.gz",
+ sha256 = "fa755b6331ff7554e6e8545ee20af7897b0adc65f471dd24ae8a467a944755b4",
+ build_file = "tools/build_rules/rust/rust.BUILD",
)
new_http_archive(
name = "rust-darwin-x86_64",
- url = "https://static.rust-lang.org/dist/rust-1.2.0-x86_64-apple-darwin.tar.gz",
- sha256 = "0d471e672fac5a450ae5507b335fda2efc0b22ea9fb7f215c6a9c466dafa2661",
- build_file = "tools/build_rules/rust/rust-darwin-x86_64.BUILD",
+ url = "https://static.rust-lang.org/dist/rust-1.3.0-x86_64-apple-darwin.tar.gz",
+ sha256 = "bfeac876e22cc5fe63a250644ce1a6f3892c13a5461131a881419bd06fcb2011",
+ build_file = "tools/build_rules/rust/rust.BUILD",
)
diff --git a/tools/build_rules/rust/rust.bzl b/tools/build_rules/rust/rust.bzl
index 943c6c73a3..ace888949c 100644
--- a/tools/build_rules/rust/rust.bzl
+++ b/tools/build_rules/rust/rust.bzl
@@ -12,13 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+"""Rust rules for Bazel"""
+
RUST_FILETYPE = FileType([".rs"])
A_FILETYPE = FileType([".a"])
+# Used by rust_docs
+HTML_MD_FILETYPE = FileType([".html", ".md"])
+CSS_FILETYPE = FileType([".css"])
+
+ZIP_PATH = "/usr/bin/zip"
+
def _relative(src_path, dest_path):
- """
- Returns the relative path from src_path to dest_path
- """
+ """Returns the relative path from src_path to dest_path."""
src_parts = src_path.split("/")
dest_parts = dest_path.split("/")
n = 0
@@ -45,11 +51,25 @@ def _create_setup_cmd(lib, deps_dir):
deps_dir + "/" + lib.basename + "\n"
)
-# TODO(dzc): rust_binary should not be able to depend on cc_library
-def _setup_deps(deps, name, working_dir):
+def _setup_deps(deps, name, working_dir, is_library=False):
"""
Walks through dependencies and constructs the necessary commands for linking
to all the necessary dependencies.
+
+ Args:
+ deps: List of Labels containing deps from ctx.attr.deps.
+ name: Name of the current target.
+ working_dir: The output directory for the current target's outputs.
+ is_library: True the current target is a rust_library target, False
+ otherwise.
+
+ Returns:
+ Returns a struct containing the following fields:
+ libs:
+ transitive_libs:
+ setup_cmd:
+ search_flags:
+ link_flags:
"""
deps_dir = working_dir + "/" + name + ".deps"
setup_cmd = ["rm -rf " + deps_dir + "; mkdir " + deps_dir + "\n"]
@@ -63,21 +83,21 @@ def _setup_deps(deps, name, working_dir):
link_flags = []
for dep in deps:
if hasattr(dep, "rust_lib"):
+ # This dependency is a rust_library
libs += [dep.rust_lib]
- transitive_libs += [dep.rust_lib]
- symlinked_libs += [dep.rust_lib]
+ transitive_libs += [dep.rust_lib] + dep.transitive_libs
+ symlinked_libs += [dep.rust_lib] + dep.transitive_libs
link_flags += [(
"--extern " + dep.label.name + "=" +
deps_dir + "/" + dep.rust_lib.basename
)]
has_rlib = True
- if hasattr(dep, "transitive_libs"):
- transitive_libs += dep.transitive_libs
- symlinked_libs += dep.transitive_libs
+ elif hasattr(dep, "cc"):
+ if not is_library:
+ fail("Only rust_library targets can depend on cc_library")
- # If this rule depends on a cc_library
- if hasattr(dep, "cc"):
+ # This dependency is a cc_library
native_libs = A_FILETYPE.filter(dep.cc.libs)
libs += native_libs
transitive_libs += native_libs
@@ -85,22 +105,26 @@ def _setup_deps(deps, name, working_dir):
link_flags += ["-l static=" + dep.label.name]
has_native = True
+ else:
+ fail(("rust_library" if is_library else "rust_binary and rust_test") +
+ " targets can only depend on rust_library " +
+ ("or cc_library " if is_library else "") + "targets")
+
for symlinked_lib in symlinked_libs:
setup_cmd += [_create_setup_cmd(symlinked_lib, deps_dir)]
search_flags = []
if has_rlib:
- search_flags += ["-L dependency=" + deps_dir]
+ search_flags += ["-L dependency=%s" % deps_dir]
if has_native:
- search_flags += ["-L native=" + deps_dir]
+ search_flags += ["-L native=%s" % deps_dir]
return struct(
libs = list(libs),
transitive_libs = list(transitive_libs),
setup_cmd = setup_cmd,
search_flags = search_flags,
- link_flags = link_flags,
- )
+ link_flags = link_flags)
def _get_features_flags(features):
"""
@@ -109,19 +133,37 @@ def _get_features_flags(features):
"""
features_flags = []
for feature in features:
- features_flags += [" --cfg feature=\\\"" + feature + "\\\""]
+ features_flags += ["--cfg feature=\\\"%s\\\"" % feature]
return features_flags
+def _rust_toolchain(ctx):
+ return struct(
+ rustc_path = ctx.file._rustc.path,
+ rustc_lib_path = ctx.files._rustc_lib[0].dirname,
+ rustlib_path = ctx.files._rustlib[0].dirname,
+ rustdoc_path = ctx.file._rustdoc.path)
+
def _build_rustc_command(ctx, crate_type, src, output_dir, depinfo,
extra_flags=[]):
- """
- Builds the rustc command
+ """Builds the rustc command.
+
+ Constructs the rustc command used to build the current target.
+
+ Args:
+ ctx: The ctx object for the current target.
+ crate_type: The type of crate to build ("lib" or "bin")
+ src: The path to the crate root source file ("lib.rs" or "main.rs")
+ output_dir: The output directory for the target.
+ depinfo: Struct containing information about dependencies as returned by
+ _setup_deps
+ extra_flags: Additional command line flags.
+
+ Return:
+ String containing the rustc command.
"""
# Paths to the Rust compiler and standard libraries.
- rustc_path = ctx.file._rustc.path
- rustc_lib_path = ctx.files._rustc_lib[0].dirname
- rustlib_path = ctx.files._rustlib[0].dirname
+ toolchain = _rust_toolchain(ctx)
# Paths to cc (for linker) and ar
cpp_fragment = ctx.fragments.cpp
@@ -141,46 +183,49 @@ def _build_rustc_command(ctx, crate_type, src, output_dir, depinfo,
return " ".join([
"set -e;",
" ".join(depinfo.setup_cmd),
- "LD_LIBRARY_PATH=" + rustc_lib_path,
- "DYLD_LIBRARY_PATH=" + rustc_lib_path,
- rustc_path + " " + src,
- "--crate-name " + ctx.label.name,
- "--crate-type " + crate_type,
- "-g",
+ "LD_LIBRARY_PATH=%s" % toolchain.rustc_lib_path,
+ "DYLD_LIBRARY_PATH=%s" % toolchain.rustc_lib_path,
+ toolchain.rustc_path,
+ src,
+ "--crate-name %s" % ctx.label.name,
+ "--crate-type %s" % crate_type,
+ "-C opt-level=3",
"--codegen ar=%s" % ar,
"--codegen linker=%s" % cc,
- "-L all=" + rustlib_path,
+ "-L all=%s" % toolchain.rustlib_path,
" ".join(extra_flags),
" ".join(features_flags),
- "--out-dir " + output_dir,
+ "--out-dir %s" % output_dir,
"--emit=dep-info,link",
" ".join(depinfo.search_flags),
" ".join(depinfo.link_flags),
" ".join(ctx.attr.rustc_flags),
])
+def _find_crate_root_src(srcs, file_names=["lib.rs"]):
+ """Finds the source file for the crate root."""
+ for src in srcs:
+ if src.basename in file_names:
+ return src.path
+ fail("No %s source file found." % " or ".join(file_names), "srcs")
+
def _rust_library_impl(ctx):
"""
Implementation for rust_library Skylark rule.
"""
# Find lib.rs
- srcs = ctx.files.srcs
- lib_rs = None
- crate_name_rs = ctx.label.name + ".rs"
- for src in srcs:
- if src.basename == "lib.rs" or src.basename == crate_name_rs:
- lib_rs = src.path
-
- if not lib_rs:
- fail("No lib.rs or source file matching crate name found.")
+ lib_rs = _find_crate_root_src(ctx.files.srcs)
# Output library
rust_lib = ctx.outputs.rust_lib
output_dir = rust_lib.dirname
# Dependencies
- depinfo = _setup_deps(ctx.attr.deps, ctx.label.name, output_dir)
+ depinfo = _setup_deps(ctx.attr.deps,
+ ctx.label.name,
+ output_dir,
+ is_library=True)
# Build rustc command
cmd = _build_rustc_command(
@@ -191,64 +236,74 @@ def _rust_library_impl(ctx):
depinfo = depinfo)
# Compile action.
+ compile_inputs = (
+ ctx.files.srcs +
+ ctx.files.data +
+ depinfo.libs +
+ [ctx.file._rustc] +
+ ctx.files._rustc_lib +
+ ctx.files._rustlib)
+
ctx.action(
- inputs = srcs + ctx.files.data + depinfo.libs + [ctx.file._rustc] +
- ctx.files._rustc_lib + ctx.files._rustlib,
+ inputs = compile_inputs,
outputs = [rust_lib],
mnemonic = 'Rustc',
command = cmd,
use_default_shell_env = True,
- progress_message = "Compiling Rust library " + ctx.label.name
- )
+ progress_message = ("Compiling Rust library %s (%d files)"
+ % (ctx.label.name, len(ctx.files.srcs))))
return struct(
files = set([rust_lib]),
+ rust_srcs = ctx.files.srcs,
+ rust_deps = ctx.attr.deps,
transitive_libs = depinfo.transitive_libs,
- rust_lib = rust_lib,
- )
+ rust_lib = rust_lib)
def _rust_binary_impl_common(ctx, extra_flags = []):
- """
- Implementation for rust_binary Skylark rule.
- """
+ """Implementation for rust_binary Skylark rule."""
# Find main.rs.
- srcs = ctx.files.srcs
- main_rs = None
- crate_name_rs = ctx.label.name + ".rs"
- for src in srcs:
- if src.basename == "main.rs" or src.basename == crate_name_rs:
- main_rs = src.path
-
- if not main_rs:
- fail("No main.rs or source file matching crate name found.")
+ main_rs = _find_crate_root_src(ctx.files.srcs, ["main.rs"])
# Output binary
rust_binary = ctx.outputs.executable
output_dir = rust_binary.dirname
# Dependencies
- depinfo = _setup_deps(ctx.attr.deps, ctx.label.name, output_dir)
+ depinfo = _setup_deps(ctx.attr.deps,
+ ctx.label.name,
+ output_dir,
+ is_library=False)
# Build rustc command.
- cmd = _build_rustc_command(
- ctx = ctx,
- crate_type = "bin",
- src = main_rs,
- output_dir = output_dir,
- depinfo = depinfo,
- extra_flags = extra_flags)
+ cmd = _build_rustc_command(ctx = ctx,
+ crate_type = "bin",
+ src = main_rs,
+ output_dir = output_dir,
+ depinfo = depinfo,
+ extra_flags = extra_flags)
# Compile action.
+ compile_inputs = (
+ ctx.files.srcs +
+ ctx.files.data +
+ depinfo.libs +
+ [ctx.file._rustc] +
+ ctx.files._rustc_lib +
+ ctx.files._rustlib)
+
ctx.action(
- inputs = srcs + ctx.files.data + depinfo.libs + [ctx.file._rustc] +
- ctx.files._rustc_lib + ctx.files._rustlib,
+ inputs = compile_inputs,
outputs = [rust_binary],
mnemonic = 'Rustc',
command = cmd,
use_default_shell_env = True,
- progress_message = "Compiling Rust binary " + ctx.label.name
- )
+ progress_message = ("Compiling Rust binary %s (%d files)"
+ % (ctx.label.name, len(ctx.files.srcs))))
+
+ return struct(rust_srcs = ctx.files.srcs,
+ rust_deps = ctx.attr.deps)
def _rust_binary_impl(ctx):
"""
@@ -258,16 +313,101 @@ def _rust_binary_impl(ctx):
def _rust_test_impl(ctx):
"""
- Implementation for rust_test Skylark rule.
+ Implementation for rust_test and rust_bench_test Skylark rules.
"""
return _rust_binary_impl_common(ctx, ["--test"])
+def _build_rustdoc_flags(ctx):
+ """Collects the rustdoc flags."""
+ doc_flags = []
+ doc_flags += [
+ "--markdown-css %s" % css.path for css in ctx.files.markdown_css]
+ if hasattr(ctx.file, "html_in_header"):
+ doc_flags += ["--html-in-header %s" % ctx.file.html_in_header.path]
+ if hasattr(ctx.file, "html_before_content"):
+ doc_flags += ["--html-before-content %s" %
+ ctx.file.html_before_content.path]
+ if hasattr(ctx.file, "html_after_content"):
+ doc_flags += ["--html-after-content %s"]
+ return doc_flags
+
+def _rust_docs_impl(ctx):
+ """Implementation of the rust_docs rule."""
+ rust_doc_zip = ctx.outputs.rust_doc_zip
+
+ # Gather attributes about the rust_library target to generated rustdocs for.
+ target = struct(name = ctx.attr.dep.label.name,
+ srcs = ctx.attr.dep.rust_srcs,
+ deps = ctx.attr.dep.rust_deps)
+
+ # Find lib.rs
+ lib_rs = _find_crate_root_src(target.srcs, ["lib.rs", "main.rs"])
+
+ # Dependencies
+ output_dir = rust_doc_zip.dirname
+ depinfo = _setup_deps(target.deps,
+ target.name,
+ output_dir,
+ is_library=False)
+
+ # Rustdoc flags.
+ doc_flags = _build_rustdoc_flags(ctx)
+
+ # Build rustdoc command.
+ toolchain = _rust_toolchain(ctx)
+ docs_dir = rust_doc_zip.dirname + "/_rust_docs"
+ doc_cmd = " ".join(
+ ["set -e"] +
+ depinfo.setup_cmd + [
+ "rm -rf %s;" % docs_dir,
+ "mkdir %s;" % docs_dir,
+ "LD_LIBRARY_PATH=%s" % toolchain.rustc_lib_path,
+ "DYLD_LIBRARY_PATH=%s" % toolchain.rustc_lib_path,
+ toolchain.rustdoc_path,
+ lib_rs,
+ "--crate-name %s" % target.name,
+ "-L all=%s" % toolchain.rustlib_path,
+ "-o %s" % docs_dir,
+ ] +
+ doc_flags +
+ depinfo.search_flags +
+ depinfo.link_flags + [
+ "&&",
+ "(cd %s" % docs_dir,
+ "&&",
+ ZIP_PATH,
+ "-qR",
+ rust_doc_zip.basename,
+ "$(find . -type f) )",
+ "&&",
+ "mv %s/%s %s" % (docs_dir, rust_doc_zip.basename, rust_doc_zip.path),
+ ])
+
+ # Rustdoc action
+ rustdoc_inputs = (target.srcs +
+ depinfo.libs +
+ [ctx.file._rustdoc] +
+ ctx.files._rustc_lib +
+ ctx.files._rustlib)
+
+ ctx.action(
+ inputs = rustdoc_inputs,
+ outputs = [rust_doc_zip],
+ mnemonic = 'Rustdoc',
+ command = doc_cmd,
+ use_default_shell_env = True,
+ progress_message = ("Generating rustdoc for %s (%d files)"
+ % (target.name, len(target.srcs))))
+
_rust_common_attrs = {
"srcs": attr.label_list(allow_files = RUST_FILETYPE),
"data": attr.label_list(allow_files = True, cfg = DATA_CFG),
"deps": attr.label_list(),
"crate_features": attr.string_list(),
"rustc_flags": attr.string_list(),
+}
+
+_rust_toolchain_attrs = {
"_rustc": attr.label(
default = Label("//tools/build_rules/rust:rustc"),
executable = True,
@@ -275,11 +415,15 @@ _rust_common_attrs = {
"_rustc_lib": attr.label(
default = Label("//tools/build_rules/rust:rustc_lib")),
"_rustlib": attr.label(default = Label("//tools/build_rules/rust:rustlib")),
+ "_rustdoc": attr.label(
+ default = Label("//tools/build_rules/rust:rustdoc"),
+ executable = True,
+ single_file = True),
}
rust_library = rule(
_rust_library_impl,
- attrs = _rust_common_attrs,
+ attrs = _rust_common_attrs + _rust_toolchain_attrs,
outputs = {
"rust_lib": "lib%{name}.rlib",
},
@@ -289,15 +433,38 @@ rust_library = rule(
rust_binary = rule(
_rust_binary_impl,
executable = True,
- attrs = _rust_common_attrs,
+ attrs = _rust_common_attrs + _rust_toolchain_attrs,
fragments = ["cpp"],
)
rust_test = rule(
_rust_test_impl,
executable = True,
- attrs = _rust_common_attrs,
+ attrs = _rust_common_attrs + _rust_toolchain_attrs,
test = True,
fragments = ["cpp"],
)
+rust_bench_test = rule(
+ _rust_test_impl,
+ executable = True,
+ attrs = _rust_common_attrs + _rust_toolchain_attrs,
+ test = True,
+ fragments = ["cpp"],
+)
+
+_rust_doc_attrs = {
+ "dep": attr.label(mandatory = True),
+ "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),
+ "html_after_content": attr.label(allow_files = HTML_MD_FILETYPE),
+}
+
+rust_docs = rule(
+ _rust_docs_impl,
+ attrs = _rust_doc_attrs + _rust_toolchain_attrs,
+ outputs = {
+ "rust_doc_zip": "%{name}-docs.zip",
+ },
+)