diff options
author | Damien Martin-Guillerez <dmarting@google.com> | 2016-05-09 14:28:07 +0000 |
---|---|---|
committer | Klaus Aehlig <aehlig@google.com> | 2016-05-09 14:41:46 +0000 |
commit | de424b6c1d0fcfd5b8cb58d495ce98cf73be58dd (patch) | |
tree | 7b8fcff3b169c5813f45214dae211afbcca1f410 /tools/build_rules | |
parent | fab3925f76832b64113624bc2ea1c6861fca768d (diff) |
Remove rust, jsonnet, scala and closure from the Bazel repository
Those rules were moved to, respectively, https://github.com/bazelbuild/rules_rust,
https://github.com/bazelbuild/rules_jsonnet, https://github.com/bazelbuild/rules_scala, and https://github.com/bazelbuild/rules_closure.
--
MOS_MIGRATED_REVID=121834063
Diffstat (limited to 'tools/build_rules')
-rw-r--r-- | tools/build_rules/closure/BUILD | 26 | ||||
-rw-r--r-- | tools/build_rules/closure/README.md | 128 | ||||
-rw-r--r-- | tools/build_rules/closure/closure_js_binary.bzl | 124 | ||||
-rw-r--r-- | tools/build_rules/closure/closure_js_library.bzl | 49 | ||||
-rw-r--r-- | tools/build_rules/closure/closure_repositories.bzl | 114 | ||||
-rw-r--r-- | tools/build_rules/closure/closure_stylesheet_library.bzl | 82 | ||||
-rw-r--r-- | tools/build_rules/closure/closure_template_library.bzl | 59 | ||||
-rw-r--r-- | tools/build_rules/rust/BUILD | 49 | ||||
-rw-r--r-- | tools/build_rules/rust/README.md | 1008 | ||||
-rw-r--r-- | tools/build_rules/rust/rust.bzl | 755 | ||||
-rw-r--r-- | tools/build_rules/rust/test/BUILD | 3 | ||||
-rw-r--r-- | tools/build_rules/rust/test/rust_rule_test.bzl | 58 |
12 files changed, 0 insertions, 2455 deletions
diff --git a/tools/build_rules/closure/BUILD b/tools/build_rules/closure/BUILD deleted file mode 100644 index 486a8aadd8..0000000000 --- a/tools/build_rules/closure/BUILD +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2015 The Bazel Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -java_binary( - name = "closure_stylesheets", - main_class = "com.google.common.css.compiler.commandline.ClosureCommandLineCompiler", - visibility = ["//visibility:public"], - runtime_deps = ["@closure_stylesheets//jar"], -) - -filegroup( - name = "srcs", - srcs = glob(["**"]), - visibility = ["//tools:__pkg__"], -) diff --git a/tools/build_rules/closure/README.md b/tools/build_rules/closure/README.md deleted file mode 100644 index 0f7c979443..0000000000 --- a/tools/build_rules/closure/README.md +++ /dev/null @@ -1,128 +0,0 @@ -# Closure Tools for Bazel - -## Deprecation notice - -Please note, Closure Tools for Bazel is deprecated, and will be moved soon. -Please see [github.com/bazelbuild/rules_closure](https://github.com/bazelbuild/rules_closure/) -for the new rules. - -## Overview - -These rules define targets for JavaScript, stylesheets, and templates that will -be compiled with the Closure Tools toolchain. - -* `closure_js_binary` -* `closure_js_library` -* `closure_stylesheet_library` -* `closure_template_library` - -## Setup - -Add the following to your `WORKSPACE` file to add the external repositories -for the various Closure Tools binaries and the Closure Library: - -```python -load("@bazel_tools//tools/build_rules/closure:closure_repositories.bzl", "closure_repositories") - -closure_repositories() -``` - -## Usage - -Suppose we are building a web application with template, stylesheet, and -JavaScript files: `hello.soy`, `hello.gss`, and `hello.js`. - -`hello.soy` - -``` -{namespace hello.templates autoescape="strict"} - -/** - * Renders an element containing the text "hello". - */ -{template .hello} - <div class="{css hello-container}">Hello.</div> -{/template} -``` - -`hello.gss` - -```css -.hello-container { - color: red; - font-weight: bold; -} -``` - -`hello.js` - -```javascript -goog.provide('hello'); - -goog.require('goog.soy'); -goog.require('hello.templates'); - -goog.soy.renderElement(document.body, hello.templates.hello); -``` - -We can create a BUILD file to compile these and produce two files: - -* `hello_combined.css` -* `hello_combined.js` - -`BUILD` - -```python -load("@bazel_tools//tools/build_rules/closure:closure_js_binary.bzl", "closure_js_binary") -load("@bazel_tools//tools/build_rules/closure:closure_js_library.bzl", "closure_js_library") -load("@bazel_tools//tools/build_rules/closure:closure_stylesheet_library.bzl", "closure_stylesheet_library") -load("@bazel_tools//tools/build_rules/closure:closure_template_library.bzl", "closure_template_library") - -closure_js_binary( - name = "hello", - main = "hello", - deps = [":hello_lib"], -) - -closure_js_library( - name = "hello_lib", - srcs = ["hello.js"], - deps = [ - "@closure_library//:closure_library", - "@closure_templates//:closure_templates_js", - ":hello_css", - ":hello_soy", - ] -) - -closure_stylesheet_library( - name = "hello_css", - srcs = ["hello.gss"], - deps = ["@closure_library//:closure_library_css"], -) - -closure_template_library( - name = "hello_soy", - srcs = ["hello.soy"], -) -``` - -## Known Issues - -The version of the Closure Templates compiler that is used will emit warnings -about protected property access and about a missing enum value. These issues -have been fixed in the source, but are not yet available as a downloadable -archive. These warnings are safe to ignore. - -You may define a new_local_repository target if you wish to check out the source -from Github yourself. Otherwise you may wish to wait until the Closure tools are -available as Bazel workspaces. e.g. - -```python -new_local_repository( - name = "closure_templates", - build_file = "tools/build_rules/closure/closure_templates.BUILD", - path = "/home/user/src/github/google/closure-templates/target", -) -``` - diff --git a/tools/build_rules/closure/closure_js_binary.bzl b/tools/build_rules/closure/closure_js_binary.bzl deleted file mode 100644 index c4453ffb10..0000000000 --- a/tools/build_rules/closure/closure_js_binary.bzl +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright 2015 The Bazel Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Build definitions for JavaScript binaries compiled with the Closure Compiler. - -A single file is produced with the _compiled.js suffix. - -By default, the name of the entry point is assumed to be the same as that of the -build target. This behaviour may be overridden with the "main" attribute. - -The optimization level may be set with the "compilation_level" attribute. -Supported values are: unobfuscated, simple, and advanced. - -Example: - - closure_js_binary( - name = "hello", - compilation_level = "simple", - language_in = "ecmascript6", - language_out = "ecmascript3", - externs = ["//third_party/javascript/google_cast/cast.js"], - deps = [ - "@closure_library//:closure_library", - ":hello_lib", - ], - ) - -This rule will produce hello_combined.js. -""" - -_COMPILATION_LEVELS = { - "whitespace_only": [ - "--compilation_level=WHITESPACE_ONLY", - "--formatting=PRETTY_PRINT" - ], - "simple": ["--compilation_level=SIMPLE"], - "advanced": ["--compilation_level=ADVANCED"] -} - -_SUPPORTED_LANGUAGES = { - "es3": ["ES3"], - "ecmascript3": ["ECMASCRIPT3"], - "es5": ["ES5"], - "ecmascript5": ["ECMASCRIPT5"], - "es5_strict": ["ES5_STRICT"], - "ecmascript5_strict": ["ECMASCRIPT5_STRICT"], - "es6": ["ES6"], - "ecmascript6": ["ECMASCRIPT6"], - "es6_strict": ["ES6_STRICT"], - "ecmascript6_strict": ["ECMASCRIPT6_STRICT"], - "es6_typed": ["ES6_TYPED"], - "ecmascript6_typed": ["ECMASCRIPT6_TYPED"], -} - -def _impl(ctx): - externs = set(order="compile") - srcs = set(order="compile") - for dep in ctx.attr.deps: - externs += dep.transitive_js_externs - srcs += dep.transitive_js_srcs - - args = [ - "--entry_point=goog:%s" % ctx.attr.main, - "--js_output_file=%s" % ctx.outputs.out.path, - "--dependency_mode=LOOSE", - "--warning_level=VERBOSE", - ] + (["--js=%s" % src.path for src in srcs] + - ["--externs=%s" % extern.path for extern in externs]) - - # Set the compilation level. - if ctx.attr.compilation_level in _COMPILATION_LEVELS: - args += _COMPILATION_LEVELS[ctx.attr.compilation_level] - else: - fail("Invalid compilation_level '%s', expected one of %s" % - (ctx.attr.compilation_level, _COMPILATION_LEVELS.keys())) - - # Set the language in. - if ctx.attr.language_in in _SUPPORTED_LANGUAGES: - args += "--language_in=" + _SUPPORTED_LANGUAGES[ctx.attr.language_in] - else: - fail("Invalid language_in '%s', expected one of %s" % - (ctx.attr.language_in, _SUPPORTED_LANGUAGES.keys())) - - # Set the language out. - if ctx.attr.language_out in _SUPPORTED_LANGUAGES: - args += "--language_out=" + _SUPPORTED_LANGUAGES[ctx.attr.language_out] - else: - fail("Invalid language_out '%s', expected one of %s" % - (ctx.attr.language_out, _SUPPORTED_LANGUAGES.keys())) - - ctx.action( - inputs=list(srcs) + list(externs), - outputs=[ctx.outputs.out], - arguments=args, - executable=ctx.executable._closure_compiler) - - return struct(files=set([ctx.outputs.out])) - -closure_js_binary = rule( - implementation=_impl, - attrs={ - "deps": attr.label_list( - allow_files=False, - providers=["transitive_js_externs", "transitive_js_srcs"]), - "main": attr.string(default="%{name}"), - "compilation_level": attr.string(default="advanced"), - "language_in": attr.string(default="ecmascript6"), - "language_out": attr.string(default="ecmascript3"), - "_closure_compiler": attr.label( - default=Label("//external:closure_compiler_"), - executable=True), - }, - outputs={"out": "%{name}_combined.js"}) diff --git a/tools/build_rules/closure/closure_js_library.bzl b/tools/build_rules/closure/closure_js_library.bzl deleted file mode 100644 index b759b4989a..0000000000 --- a/tools/build_rules/closure/closure_js_library.bzl +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2015 The Bazel Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Build definitions for JavaScript libraries. The library targets may be used -in closure_js_binary rules. - -Example: - - closure_js_library( - name = "hello_lib", - srcs = ["hello.js"], - deps = ["//third_party/javascript/closure_library"], - ) -""" - -_JS_FILE_TYPE = FileType([".js"]) - -def _impl(ctx): - externs = set(order="compile") - srcs = set(order="compile") - for dep in ctx.attr.deps: - externs += dep.transitive_js_externs - srcs += dep.transitive_js_srcs - - externs += _JS_FILE_TYPE.filter(ctx.files.externs) - srcs += _JS_FILE_TYPE.filter(ctx.files.srcs) - - return struct( - files=set(), transitive_js_externs=externs, transitive_js_srcs=srcs) - -closure_js_library = rule( - implementation=_impl, - attrs={ - "externs": attr.label_list(allow_files=_JS_FILE_TYPE), - "srcs": attr.label_list(allow_files=_JS_FILE_TYPE), - "deps": attr.label_list( - providers=["transitive_js_externs", "transitive_js_srcs"]) - }) diff --git a/tools/build_rules/closure/closure_repositories.bzl b/tools/build_rules/closure/closure_repositories.bzl deleted file mode 100644 index f67f76f7d4..0000000000 --- a/tools/build_rules/closure/closure_repositories.bzl +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright 2015 The Bazel Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -CLOSURE_COMPILER_BUILD_FILE = """ -java_import( - name = "closure_compiler_jar", - jars = ["compiler.jar"], -) - -java_binary( - name = "closure_compiler", - main_class = "com.google.javascript.jscomp.CommandLineRunner", - visibility = ["//visibility:public"], - runtime_deps = [":closure_compiler_jar"], -) -""" - -CLOSURE_LIBRARY_BUILD_FILE = """ -load("@bazel_tools//tools/build_rules/closure:closure_js_library.bzl", "closure_js_library") -load("@bazel_tools//tools/build_rules/closure:closure_stylesheet_library.bzl", "closure_stylesheet_library") - -closure_js_library( - name = "closure_library", - srcs = glob( - [ - "closure/goog/**/*.js", - "third_party/closure/goog/**/*.js", - ], - exclude = [ - "closure/goog/**/*_test.js", - "closure/goog/demos/**/*.js", - "third_party/closure/goog/**/*_test.js", - ], - ), - visibility = ["//visibility:public"], -) - -closure_stylesheet_library( - name = "closure_library_css", - srcs = glob(["closure/goog/css/**/*.css"]), - visibility = ["//visibility:public"], -) -""" - -CLOSURE_TEMPLATES_BUILD_FILE = """ -load("@bazel_tools//tools/build_rules/closure:closure_js_library.bzl", "closure_js_library") - -java_import( - name = "closure_templates_jar", - jars = ["SoyToJsSrcCompiler.jar"], -) - -java_binary( - name = "closure_templates", - main_class = "com.google.template.soy.SoyToJsSrcCompiler", - visibility = ["//visibility:public"], - runtime_deps = [":closure_templates_jar"], -) - -closure_js_library( - name = "closure_templates_js", - srcs = ["soyutils_usegoog.js"], - visibility = ["//visibility:public"], -) -""" - -def closure_repositories(): - native.new_http_archive( - name = "closure_compiler", - build_file_content = CLOSURE_COMPILER_BUILD_FILE, - sha256 = "215ba5df026e5d92bda6634463a9c634d38a1aa4b6dab336da5c52e884cbde95", - url = "https://dl.google.com/closure-compiler/compiler-20160208.zip", - ) - - native.new_http_archive( - name = "closure_library", - build_file_content = CLOSURE_LIBRARY_BUILD_FILE, - sha256 = "8f610300e4930190137505a574a54d12346426f2a7b4f179026e41674e452a86", - url = "https://github.com/google/closure-library/archive/20160208.zip", - ) - - native.http_jar( - name = "closure_stylesheets", - sha256 = "5308cb46f7677b9995237ade57770d27592aff69359d29be571220a2bf10e724", - url = "https://github.com/google/closure-stylesheets/releases/download/v1.1.0/closure-stylesheets.jar", - ) - - native.new_http_archive( - name = "closure_templates", - build_file_content = CLOSURE_TEMPLATES_BUILD_FILE, - sha256 = "cdd94123cd0d1c3a183c15e855739c0aa5390297c22dddc731b8d7b23815e8a2", - url = "http://dl.google.com/closure-templates/closure-templates-for-javascript-latest.zip", - ) - - native.bind( - name = "closure_compiler_", - actual = "@closure_compiler//:closure_compiler", - ) - - native.bind( - name = "closure_templates_", - actual = "@closure_templates//:closure_templates", - ) diff --git a/tools/build_rules/closure/closure_stylesheet_library.bzl b/tools/build_rules/closure/closure_stylesheet_library.bzl deleted file mode 100644 index c1532c0547..0000000000 --- a/tools/build_rules/closure/closure_stylesheet_library.bzl +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright 2015 The Bazel Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Build definitions for Closure stylesheets. Two files are produced: a minified -and obfuscated CSS file and a JS file defining a map between CSS classes and the -obfuscated class name. The stylesheet targets may be used in closure_js_binary -rules. - -Both CSS and GSS files may be used with this rule. - -Example: - - closure_stylesheet_library( - name = "hello_css", - srcs = ["hello.gss"]. - ) - -This rule will produce hello_css_combined.css and hello_css_renaming.js. -""" - -_GSS_FILE_TYPE = FileType([".css", ".gss"]) - -def _impl(ctx): - srcs = set(order="compile") - for dep in ctx.attr.deps: - srcs += dep.transitive_gss_srcs - - srcs += _GSS_FILE_TYPE.filter(ctx.files.srcs) - - args = [ - "--output-file", - ctx.outputs.out.path, - "--output-renaming-map", - ctx.outputs.out_renaming.path, - "--output-renaming-map-format", - "CLOSURE_COMPILED", - "--rename", - "CLOSURE" - ] + [src.path for src in srcs] - - ctx.action( - inputs=list(srcs), - outputs=[ctx.outputs.out, ctx.outputs.out_renaming], - arguments=args, - executable=ctx.executable._closure_stylesheets) - - return struct( - files=set([ctx.outputs.out]), - transitive_gss_srcs=srcs, - transitive_js_externs=set(), - transitive_js_srcs=[ctx.outputs.out_renaming]) - -# There are two outputs: -# - %{name}_combined.css: A minified and obfuscated CSS file. -# - %{name}_renaming.js: A map from the original CSS class name to the -# obfuscated name. This file is used by -# closure_js_binary rules. -closure_stylesheet_library = rule( - implementation=_impl, - attrs={ - "srcs": attr.label_list(allow_files=_GSS_FILE_TYPE), - "deps": attr.label_list( - providers=["transitive_gss_srcs", "transitive_js_srcs"]), - "_closure_stylesheets": attr.label( - default=Label("//tools/build_rules/closure:closure_stylesheets"), - executable=True), - }, - outputs={ - "out": "%{name}_combined.css", - "out_renaming": "%{name}_renaming.js" - }) diff --git a/tools/build_rules/closure/closure_template_library.bzl b/tools/build_rules/closure/closure_template_library.bzl deleted file mode 100644 index 94f246aa2a..0000000000 --- a/tools/build_rules/closure/closure_template_library.bzl +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2015 The Bazel Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Build definitions for Closure templates. The template targets may be used in -closure_js_binary rules. - -Example: - - closure_template_library( - name = "hello_soy", - srcs = ["hello.soy"], - ) - -This rule will produce hello_soy.js. -""" - -_SOY_FILE_TYPE = FileType([".soy"]) - -def _impl(ctx): - srcs = ctx.files.srcs - args = [ - "--outputPathFormat", - ctx.outputs.out.path, - "--shouldGenerateJsdoc", - "--shouldProvideRequireSoyNamespaces", - "--srcs", - ",".join([src.path for src in srcs]) - ] - - ctx.action( - inputs=list(srcs), - outputs=[ctx.outputs.out], - arguments=args, - executable=ctx.executable._closure_templates) - - return struct( - files=set(), transitive_js_externs=set(), - transitive_js_srcs=set([ctx.outputs.out])) - -closure_template_library = rule( - implementation=_impl, - attrs={ - "srcs": attr.label_list(allow_files=_SOY_FILE_TYPE), - "_closure_templates": attr.label( - default=Label("//external:closure_templates_"), - executable=True), - }, - outputs={"out": "%{name}.js"}) diff --git a/tools/build_rules/rust/BUILD b/tools/build_rules/rust/BUILD deleted file mode 100644 index 3abf631571..0000000000 --- a/tools/build_rules/rust/BUILD +++ /dev/null @@ -1,49 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "srcs", - srcs = glob(["**"]), - visibility = ["//tools:__pkg__"], -) - -config_setting( - name = "darwin", - values = {"host_cpu": "darwin"}, -) - -config_setting( - name = "k8", - values = {"host_cpu": "k8"}, -) - -filegroup( - name = "rustc", - srcs = select({ - ":darwin": ["@rust_darwin_x86_64//:rustc"], - ":k8": ["@rust_linux_x86_64//:rustc"], - }), -) - -filegroup( - name = "rustc_lib", - srcs = select({ - ":darwin": ["@rust_darwin_x86_64//:rustc_lib"], - ":k8": ["@rust_linux_x86_64//:rustc_lib"], - }), -) - -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"], - ":k8": ["@rust_linux_x86_64//:rustlib"], - }), -) diff --git a/tools/build_rules/rust/README.md b/tools/build_rules/rust/README.md deleted file mode 100644 index 85b9978ee7..0000000000 --- a/tools/build_rules/rust/README.md +++ /dev/null @@ -1,1008 +0,0 @@ -# Rust Rules - -<div class="toc"> - <h2>Rules</h2> - <ul> - <li><a href="#rust_library">rust_library</a></li> - <li><a href="#rust_binary">rust_binary</a></li> - <li><a href="#rust_test">rust_test</a></li> - <li><a href="#rust_bench_test">rust_bench_test</a></li> - <li><a href="#rust_doc">rust_doc</a></li> - <li><a href="#rust_doc_test">rust_doc_test</a></li> - </ul> -</div> - -## Overview - -These build rules are used for building [Rust][rust] projects with Bazel. - -[rust]: http://www.rust-lang.org/ - -<a name="setup"></a> -## Setup - -To use the Rust rules, add the following to your `WORKSPACE` file to add the -external repositories for the Rust toolchain: - -```python -load("@bazel_tools//tools/build_rules/rust:rust.bzl", "rust_repositories") - -rust_repositories() -``` - -<a name="roadmap"></a> -## 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/). - -<a name="rust_library"></a> -## rust_library - -```python -rust_library(name, srcs, deps, data, crate_features, rustc_flags) -``` - -<table class="table table-condensed table-bordered table-params"> - <colgroup> - <col class="col-param" /> - <col class="param-description" /> - </colgroup> - <thead> - <tr> - <th colspan="2">Attributes</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>name</code></td> - <td> - <code>Name, required</code> - <p>A unique name for this rule.</p> - <p> - This name will also be used as the name of the library crate built by - this rule. - </p> - </td> - </tr> - <tr> - <td><code>srcs</code></td> - <td> - <code>List of labels, required</code> - <p>List of Rust <code>.rs</code> source files used to build the - library.</p> - <p> - 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 <code>rustc</code> to build this - crate. - </p> - </td> - </tr> - <tr> - <td><code>crate_root</code></td> - <td> - <code>Label, optional</code> - <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> - </td> - <tr> - <td><code>deps</code></td> - <td> - <code>List of labels, optional</code> - <p>List of other libraries to be linked to this library target.</p> - <p> - These can be either other <code>rust_library</code> targets or - <code>cc_library</code> targets if linking a native library. - </p> - </td> - </tr> - <tr> - <td><code>data</code></td> - <td> - <code>List of labels, optional</code> - <p>List of files used by this rule at runtime.</p> - <p> - This attribute can be used to specify any data files that are embedded - into the library, such as via the - <a href="https://doc.rust-lang.org/std/macro.include_str!.html target="_blank"><code>include_str!</code></a> - macro. - </p> - </td> - </tr> - <tr> - <td><code>crate_features</code></td> - <td> - <code>List of strings, optional</code> - <p>List of features to enable for this crate.</p> - <p> - Features are defined in the code using the - <code>#[cfg(feature = "foo")]</code> configuration option. The - features listed here will be passed to <code>rustc</code> with - <code>--cfg feature="${feature_name}"</code> flags. - </p> - </td> - </tr> - <tr> - <td><code>rustc_flags</code></td> - <td> - <code>List of strings, optional</code> - <p>List of compiler flags passed to <code>rustc</code>.</p> - </td> - </tr> - </tbody> -</table> - -### 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("@bazel_tools//tools/build_rules/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 -``` - -<a name="rust_binary"></a> -## rust_binary - -``` -rust_binary(name, srcs, deps, data, crate_features, rustc_flags) -``` - -<table class="table table-condensed table-bordered table-params"> - <colgroup> - <col class="col-param" /> - <col class="param-description" /> - </colgroup> - <thead> - <tr> - <th colspan="2">Attributes</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>name</code></td> - <td> - <code>Name, required</code> - <p>A unique name for this rule.</p> - <p> - This name will also be used as the name of the binary crate built by - this rule. - </p> - </td> - </tr> - <tr> - <td><code>srcs</code></td> - <td> - <code>List of labels, required</code> - <p>List of Rust <code>.rs</code> source files used to build the - binary.</p> - <p> - If <code>srcs</code> contains more than one file, then there must be - a file either named <code>main.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 <code>rustc</code> to build this - crate. - </p> - </td> - </tr> - <tr> - <td><code>crate_root</code></td> - <td> - <code>Label, optional</code> - <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>main.rs</code> file or the single file in <code>srcs</code> - if <code>srcs</code> contains only one file. - </p> - </td> - </td> - <tr> - <td><code>deps</code></td> - <td> - <code>List of labels, optional</code> - <p>List of other libraries to be linked to this library target.</p> - <p> - These must be <code>rust_library</code> targets. - </p> - </td> - </tr> - <tr> - <td><code>data</code></td> - <td> - <code>List of labels, optional</code> - <p>List of files used by this rule at runtime.</p> - <p> - This attribute can be used to specify any data files that are embedded - into the library, such as via the - <a href="https://doc.rust-lang.org/std/macro.include_str!.html target="_blank"><code>include_str!</code></a> - macro. - </p> - </td> - </tr> - <tr> - <td><code>crate_features</code></td> - <td> - <code>List of strings, optional</code> - <p>List of features to enable for this crate.</p> - <p> - Features are defined in the code using the - <code>#[cfg(feature = "foo")]</code> configuration option. The - features listed here will be passed to <code>rustc</code> with - <code>--cfg feature="${feature_name}"</code> flags. - </p> - </td> - </tr> - <tr> - <td><code>rustc_flags</code></td> - <td> - <code>List of strings, optional</code> - <p>List of compiler flags passed to <code>rustc</code>.</p> - </td> - </tr> - </tbody> -</table> - -### 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("@bazel_tools//tools/build_rules/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("@bazel_tools//tools/build_rules/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 -``` - -<a name="rust_test"></a> -## rust_test - -```python -rust_test(name, srcs, deps, data, crate_features, rustc_flags) -``` - -<table class="table table-condensed table-bordered table-params"> - <colgroup> - <col class="col-param" /> - <col class="param-description" /> - </colgroup> - <thead> - <tr> - <th colspan="2">Attributes</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>name</code></td> - <td> - <code>Name, required</code> - <p>A unique name for this rule.</p> - <p> - This name will also be used as the name of the binary test crate - built by this rule. - </p> - </td> - </tr> - <tr> - <td><code>srcs</code></td> - <td> - <code>List of labels, required</code> - <p>List of Rust <code>.rs</code> source files used to build the - library.</p> - <p> - 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 <code>rustc</code> to build this - crate. - </p> - </td> - </tr> - <tr> - <td><code>crate_root</code></td> - <td> - <code>Label, optional</code> - <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> - </td> - <tr> - <td><code>deps</code></td> - <td> - <code>List of labels, optional</code> - <p>List of other libraries to be linked to this test target.</p> - <p> - These must be <code>rust_library</code> targets. - </p> - </td> - </tr> - <tr> - <td><code>data</code></td> - <td> - <code>List of labels, optional</code> - <p>List of files used by this rule at runtime.</p> - <p> - This attribute can be used to specify any data files that are embedded - into the library, such as via the - <a href="https://doc.rust-lang.org/std/macro.include_str!.html target="_blank"><code>include_str!</code></a> - macro. - </p> - </td> - </tr> - <tr> - <td><code>crate_features</code></td> - <td> - <code>List of strings, optional</code> - <p>List of features to enable for this crate.</p> - <p> - Features are defined in the code using the - <code>#[cfg(feature = "foo")]</code> configuration option. The - features listed here will be passed to <code>rustc</code> with - <code>--cfg feature="${feature_name}"</code> flags. - </p> - </td> - </tr> - <tr> - <td><code>rustc_flags</code></td> - <td> - <code>List of strings, optional</code> - <p>List of compiler flags passed to <code>rustc</code>.</p> - </td> - </tr> - </tbody> -</table> - -### Example - -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("@bazel_tools//tools/build_rules/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("@bazel_tools//tools/build_rules/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`. - -<a name="rust_bench_test"></a> -## rust\_bench\_test - -```python -rust_bench_test(name, srcs, deps, data, crate_features, rustc_flags) -``` - -**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 - -<table class="table table-condensed table-bordered table-params"> - <colgroup> - <col class="col-param" /> - <col class="param-description" /> - </colgroup> - <thead> - <tr> - <th colspan="2">Attributes</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>name</code></td> - <td> - <code>Name, required</code> - <p>A unique name for this rule.</p> - <p> - This name will also be used as the name of the binary test crate - built by this rule. - </p> - </td> - </tr> - <tr> - <td><code>srcs</code></td> - <td> - <code>List of labels, required</code> - <p>List of Rust <code>.rs</code> source files used to build the - library.</p> - <p> - 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 <code>rustc</code> to build this - crate. - </p> - </td> - </tr> - <tr> - <td><code>crate_root</code></td> - <td> - <code>Label, optional</code> - <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> - </td> - <tr> - <td><code>deps</code></td> - <td> - <code>List of labels, optional</code> - <p>List of other libraries to be linked to this test target.</p> - <p> - These must be <code>rust_library</code> targets. - </p> - </td> - </tr> - <tr> - <td><code>data</code></td> - <td> - <code>List of labels, optional</code> - <p>List of files used by this rule at runtime.</p> - <p> - This attribute can be used to specify any data files that are embedded - into the library, such as via the - <a href="https://doc.rust-lang.org/std/macro.include_str!.html target="_blank"><code>include_str!</code></a> - macro. - </p> - </td> - </tr> - <tr> - <td><code>crate_features</code></td> - <td> - <code>List of strings, optional</code> - <p>List of features to enable for this crate.</p> - <p> - Features are defined in the code using the - <code>#[cfg(feature = "foo")]</code> configuration option. The - features listed here will be passed to <code>rustc</code> with - <code>--cfg feature="${feature_name}"</code> flags. - </p> - </td> - </tr> - <tr> - <td><code>rustc_flags</code></td> - <td> - <code>List of strings, optional</code> - <p>List of compiler flags passed to <code>rustc</code>.</p> - </td> - </tr> - </tbody> -</table> - -### 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("@bazel_tools//tools/build_rules/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`. - -<a name="rust_doc"></a> -## rust_doc - -```python -rust_doc(name, dep, markdown_css, html_in_header, html_before_content, html_after_content) -``` - -<table class="table table-condensed table-bordered table-params"> - <colgroup> - <col class="col-param" /> - <col class="param-description" /> - </colgroup> - <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_doc</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><link></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><head></code>.</p> - </td> - </tr> - <tr> - <td><code>html_before_content</code></td> - <td> - <code>Label, optional</code> - <p>File to add in <code><body></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><body></code>, after content.</p> - </td> - </tr> - </tbody> -</table> - -### 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("@bazel_tools//tools/build_rules/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`. - -<a name="rust_doc_test"></a> -## rust\_doc\_test - -```python -rust_doc_test(name, dep) -``` - -<table class="table table-condensed table-bordered table-params"> - <colgroup> - <col class="col-param" /> - <col class="param-description" /> - </colgroup> - <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 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> - -### 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("@bazel_tools//tools/build_rules/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. diff --git a/tools/build_rules/rust/rust.bzl b/tools/build_rules/rust/rust.bzl deleted file mode 100644 index 59ba17eee5..0000000000 --- a/tools/build_rules/rust/rust.bzl +++ /dev/null @@ -1,755 +0,0 @@ -# Copyright 2015 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# 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"]) - -LIBRARY_CRATE_TYPES = [ - "lib", - "rlib", - "dylib", - "staticlib", -] - -# Used by rust_doc -HTML_MD_FILETYPE = FileType([ - ".html", - ".md", -]) - -CSS_FILETYPE = FileType([".css"]) - -ZIP_PATH = "/usr/bin/zip" - -def _path_parts(path): - """Takes a path and returns a list of its parts with all "." elements removed. - - The main use case of this function is if one of the inputs to _relative() - is a relative path, such as "./foo". - - Args: - path_parts: A list containing parts of a path. - - Returns: - Returns a list containing the path parts with all "." elements removed. - """ - path_parts = path.split("/") - return [part for part in path_parts if part != "."] - -def _relative(src_path, dest_path): - """Returns the relative path from src_path to dest_path.""" - src_parts = _path_parts(src_path) - dest_parts = _path_parts(dest_path) - n = 0 - done = False - for src_part, dest_part in zip(src_parts, dest_parts): - if src_part != dest_part: - break - n += 1 - - relative_path = "" - for i in range(n, len(src_parts)): - relative_path += "../" - relative_path += "/".join(dest_parts[n:]) - - return relative_path - -def _create_setup_cmd(lib, deps_dir, in_runfiles): - """ - Helper function to construct a command for symlinking a library into the - deps directory. - """ - lib_path = lib.short_path if in_runfiles else lib.path - return ( - "ln -sf " + _relative(deps_dir, lib_path) + " " + - deps_dir + "/" + lib.basename + "\n" - ) - -def _setup_deps(deps, name, working_dir, is_library=False, in_runfiles=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 if the current target is a rust_library target, False - otherwise. - in_runfiles: True if the setup commands will be run in a .runfiles - directory. In this case, the working dir should be '.', and the deps - will be symlinked into the .deps dir from the runfiles tree. - - 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"] - - has_rlib = False - has_native = False - - libs = set() - transitive_libs = set() - symlinked_libs = set() - 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] + 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 - - elif hasattr(dep, "cc"): - if not is_library: - fail("Only rust_library targets can depend on cc_library") - - # This dependency is a cc_library - native_libs = A_FILETYPE.filter(dep.cc.libs) - libs += native_libs - transitive_libs += native_libs - symlinked_libs += native_libs - 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, in_runfiles)] - - search_flags = [] - if has_rlib: - search_flags += ["-L dependency=%s" % deps_dir] - if has_native: - 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) - -def _get_features_flags(features): - """ - Constructs a string containing the feature flags from the features specified - in the features attribute. - """ - features_flags = [] - for feature in features: - 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_name, crate_type, src, output_dir, - depinfo, rust_flags=[]): - """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 File object for 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 - - Return: - String containing the rustc command. - """ - - # Paths to the Rust compiler and standard libraries. - toolchain = _rust_toolchain(ctx) - - # Paths to cc (for linker) and ar - cpp_fragment = ctx.fragments.cpp - cc = cpp_fragment.compiler_executable - ar = cpp_fragment.ar_executable - # Currently, the CROSSTOOL config for darwin sets ar to "libtool". Because - # rust uses ar-specific flags, use /usr/bin/ar in this case. - # TODO(dzc): This is not ideal. Remove this workaround once ar_executable - # always points to an ar binary. - ar_str = "%s" % ar - if ar_str.find("libtool", 0) != -1: - ar = "/usr/bin/ar" - - # Construct features flags - features_flags = _get_features_flags(ctx.attr.crate_features) - - return " ".join( - ["set -e;"] + - depinfo.setup_cmd + - [ - "LD_LIBRARY_PATH=%s" % toolchain.rustc_lib_path, - "DYLD_LIBRARY_PATH=%s" % toolchain.rustc_lib_path, - toolchain.rustc_path, - src.path, - "--crate-name %s" % crate_name, - "--crate-type %s" % crate_type, - "-C opt-level=3", - "--codegen ar=%s" % ar, - "--codegen linker=%s" % cc, - "--codegen link-args='%s'" % ' '.join(cpp_fragment.link_options), - "-L all=%s" % toolchain.rustlib_path, - "--out-dir %s" % output_dir, - "--emit=dep-info,link", - ] + - features_flags + - rust_flags + - depinfo.search_flags + - depinfo.link_flags + - ctx.attr.rustc_flags) - -def _find_crate_root_src(srcs, file_names=["lib.rs"]): - """Finds the source file for the crate root.""" - if len(srcs) == 1: - return srcs[0] - for src in srcs: - if src.basename in file_names: - return src - fail("No %s source file found." % " or ".join(file_names), "srcs") - -def _crate_root_src(ctx, file_names=["lib.rs"]): - if ctx.file.crate_root == None: - return _find_crate_root_src(ctx.files.srcs, file_names) - else: - return ctx.file.crate_root - -def _rust_library_impl(ctx): - """ - Implementation for rust_library Skylark rule. - """ - - # Find lib.rs - lib_rs = _crate_root_src(ctx) - - # Validate crate_type - crate_type = "" - if ctx.attr.crate_type != "": - if ctx.attr.crate_type not in LIBRARY_CRATE_TYPES: - fail("Invalid crate_type for rust_library. Allowed crate types are: %s" - % " ".join(LIBRARY_CRATE_TYPES), "crate_type") - crate_type += ctx.attr.crate_type - else: - crate_type += "lib" - - # 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, - is_library=True) - - # Build rustc command - cmd = _build_rustc_command( - ctx = ctx, - crate_name = ctx.label.name, - crate_type = crate_type, - src = lib_rs, - output_dir = output_dir, - depinfo = depinfo) - - # Compile action. - compile_inputs = ( - ctx.files.srcs + - ctx.files.data + - depinfo.libs + - depinfo.transitive_libs + - [ctx.file.rustc] + - ctx.files.rustc_lib + - ctx.files.rustlib) - - ctx.action( - inputs = compile_inputs, - outputs = [rust_lib], - mnemonic = 'Rustc', - command = cmd, - use_default_shell_env = True, - progress_message = ("Compiling Rust library %s (%d files)" - % (ctx.label.name, len(ctx.files.srcs)))) - - return struct( - files = set([rust_lib]), - crate_type = crate_type, - crate_root = lib_rs, - rust_srcs = ctx.files.srcs, - rust_deps = ctx.attr.deps, - transitive_libs = depinfo.transitive_libs, - rust_lib = rust_lib) - -def _rust_binary_impl(ctx): - """Implementation for rust_binary Skylark rule.""" - - # Find main.rs. - main_rs = _crate_root_src(ctx, ["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, - is_library=False) - - # Build rustc command. - cmd = _build_rustc_command(ctx = ctx, - crate_name = ctx.label.name, - crate_type = "bin", - src = main_rs, - output_dir = output_dir, - depinfo = depinfo) - - # Compile action. - compile_inputs = ( - ctx.files.srcs + - ctx.files.data + - depinfo.libs + - depinfo.transitive_libs + - [ctx.file.rustc] + - ctx.files.rustc_lib + - ctx.files.rustlib) - - ctx.action( - inputs = compile_inputs, - outputs = [rust_binary], - mnemonic = "Rustc", - command = cmd, - use_default_shell_env = True, - progress_message = ("Compiling Rust binary %s (%d files)" - % (ctx.label.name, len(ctx.files.srcs)))) - - return struct(rust_srcs = ctx.files.srcs, - crate_root = main_rs, - rust_deps = ctx.attr.deps) - -def _rust_test_common(ctx, test_binary): - """Builds a Rust test binary. - - Args: - ctx: The ctx object for the current target. - test_binary: The File object for the test binary. - """ - output_dir = test_binary.dirname - - if len(ctx.attr.deps) == 1 and len(ctx.files.srcs) == 0: - # Target has a single dependency but no srcs. Build the test binary using - # the dependency's srcs. - dep = ctx.attr.deps[0] - crate_type = dep.crate_type if hasattr(dep, "crate_type") else "bin" - target = struct(name = ctx.label.name, - srcs = dep.rust_srcs, - deps = dep.rust_deps, - crate_root = dep.crate_root, - crate_type = crate_type) - else: - # Target is a standalone crate. Build the test binary as its own crate. - target = struct(name = ctx.label.name, - srcs = ctx.files.srcs, - deps = ctx.attr.deps, - crate_root = _crate_root_src(ctx), - crate_type = "lib") - - # Get information about dependencies - depinfo = _setup_deps(target.deps, - target.name, - output_dir, - is_library=False) - - cmd = _build_rustc_command(ctx = ctx, - crate_name = test_binary.basename, - crate_type = target.crate_type, - src = target.crate_root, - output_dir = output_dir, - depinfo = depinfo, - rust_flags = ["--test"]) - - compile_inputs = (target.srcs + - depinfo.libs + - depinfo.transitive_libs + - [ctx.file.rustc] + - ctx.files.rustc_lib + - ctx.files.rustlib) - - ctx.action( - inputs = compile_inputs, - outputs = [test_binary], - mnemonic = "RustcTest", - command = cmd, - use_default_shell_env = True, - progress_message = ("Compiling Rust test %s (%d files)" - % (ctx.label.name, len(target.srcs)))) - -def _rust_test_impl(ctx): - """ - Implementation for rust_test Skylark rule. - """ - _rust_test_common(ctx, ctx.outputs.executable) - -def _rust_bench_test_impl(ctx): - """Implementation for the rust_bench_test Skylark rule.""" - rust_bench_test = ctx.outputs.executable - test_binary = ctx.new_file(ctx.configuration.bin_dir, - "%s_bin" % rust_bench_test.basename) - _rust_test_common(ctx, test_binary) - - ctx.file_action( - output = rust_bench_test, - content = " ".join([ - "#!/bin/bash\n", - "set -e\n", - "%s --bench\n" % test_binary.short_path]), - executable = True) - - runfiles = ctx.runfiles(files = [test_binary], collect_data = True) - return struct(runfiles = runfiles) - -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_doc_impl(ctx): - """Implementation of the rust_doc rule.""" - rust_doc_zip = ctx.outputs.rust_doc_zip - - # Gather attributes about the rust_library target to generated rustdocs for. - target = struct(name = ctx.label.name, - srcs = ctx.attr.dep.rust_srcs, - deps = ctx.attr.dep.rust_deps, - crate_root = ctx.attr.dep.crate_root) - - # Find lib.rs - lib_rs = (_find_crate_root_src(target.srcs, ["lib.rs", "main.rs"]) - if target.crate_root == None else target.crate_root) - - # Get information about 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.path, - "--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)))) - -def _rust_doc_test_impl(ctx): - """Implementation for the rust_doc_test rule.""" - rust_doc_test = ctx.outputs.executable - - # Gather attributes about the rust_library target to generated rustdocs for. - target = struct(name = ctx.label.name, - srcs = ctx.attr.dep.rust_srcs, - deps = ctx.attr.dep.rust_deps, - crate_root = ctx.attr.dep.crate_root) - - # Find lib.rs - lib_rs = (_find_crate_root_src(target.srcs, ["lib.rs", "main.rs"]) - if target.crate_root == None else target.crate_root) - - # Get information about dependencies - output_dir = rust_doc_test.dirname - depinfo = _setup_deps(target.deps, - target.name, - working_dir=".", - is_library=False, - in_runfiles=True) - - # Construct rustdoc test command, which will be written to a shell script - # to be executed to run the test. - toolchain = _rust_toolchain(ctx) - doc_test_cmd = " ".join( - ["#!/bin/bash\n"] + - ["set -e\n"] + - depinfo.setup_cmd + - [ - "LD_LIBRARY_PATH=%s" % toolchain.rustc_lib_path, - "DYLD_LIBRARY_PATH=%s" % toolchain.rustc_lib_path, - toolchain.rustdoc_path, - "-L all=%s" % toolchain.rustlib_path, - lib_rs.path, - ] + - depinfo.search_flags + - depinfo.link_flags) - - ctx.file_action(output = rust_doc_test, - content = doc_test_cmd, - executable = True) - - doc_test_inputs = (target.srcs + - depinfo.libs + - depinfo.transitive_libs + - [ctx.file.rustdoc] + - ctx.files.rustc_lib + - ctx.files.rustlib) - - runfiles = ctx.runfiles(files = doc_test_inputs, collect_data = True) - return struct(runfiles = runfiles) - -_rust_common_attrs = { - "srcs": attr.label_list(allow_files = RUST_FILETYPE), - "crate_root": attr.label( - allow_files = RUST_FILETYPE, - single_file = True, - ), - "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("@bazel_tools//tools/build_rules/rust:rustc"), - executable = True, - single_file = True, - ), - "rustc_lib": attr.label( - default = Label("@bazel_tools//tools/build_rules/rust:rustc_lib"), - ), - "rustlib": attr.label( - default = Label("@bazel_tools//tools/build_rules/rust:rustlib"), - ), - "rustdoc": attr.label( - default = Label("@bazel_tools//tools/build_rules/rust:rustdoc"), - executable = True, - single_file = True, - ), -} - -_rust_library_attrs = _rust_common_attrs + { - "crate_type": attr.string(), -} - -rust_library = rule( - _rust_library_impl, - attrs = _rust_library_attrs + _rust_toolchain_attrs, - fragments = ["cpp"], - outputs = { - "rust_lib": "lib%{name}.rlib", - }, -) - -rust_binary = rule( - _rust_binary_impl, - attrs = _rust_common_attrs + _rust_toolchain_attrs, - executable = True, - fragments = ["cpp"], -) - -rust_test = rule( - _rust_test_impl, - attrs = _rust_common_attrs + _rust_toolchain_attrs, - executable = True, - fragments = ["cpp"], - test = True, -) - -rust_bench_test = rule( - _rust_bench_test_impl, - attrs = _rust_common_attrs + _rust_toolchain_attrs, - executable = True, - fragments = ["cpp"], - test = True, -) - -_rust_doc_common_attrs = { - "dep": attr.label(mandatory = True), -} - -_rust_doc_attrs = _rust_doc_common_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), - "html_after_content": attr.label(allow_files = HTML_MD_FILETYPE), -} - -rust_doc = rule( - _rust_doc_impl, - attrs = _rust_doc_attrs + _rust_toolchain_attrs, - outputs = { - "rust_doc_zip": "%{name}-docs.zip", - }, -) - -rust_doc_test = rule( - _rust_doc_test_impl, - attrs = _rust_doc_common_attrs + _rust_toolchain_attrs, - executable = True, - test = True, -) - -RUST_BUILD_FILE = """ -config_setting( - name = "darwin", - values = {"host_cpu": "darwin"}, -) - -config_setting( - name = "k8", - values = {"host_cpu": "k8"}, -) - -filegroup( - name = "rustc", - srcs = select({ - ":darwin": ["rustc/bin/rustc"], - ":k8": ["rustc/bin/rustc"], - }), - visibility = ["//visibility:public"], -) - -filegroup( - name = "rustc_lib", - srcs = select({ - ":darwin": glob(["rustc/lib/*.dylib"]), - ":k8": glob(["rustc/lib/*.so"]), - }), - visibility = ["//visibility:public"], -) - -filegroup( - name = "rustdoc", - srcs = select({ - ":darwin": ["rustc/bin/rustdoc"], - ":k8": ["rustc/bin/rustdoc"], - }), - visibility = ["//visibility:public"], -) - -filegroup( - name = "rustlib", - srcs = select({ - ":darwin": glob([ - "rust-std-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/*.rlib", - "rust-std-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/*.dylib", - "rust-std-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/*.a", - "rustc/lib/rustlib/x86_64-apple-darwin/lib/*.rlib", - "rustc/lib/rustlib/x86_64-apple-darwin/lib/*.dylib", - "rustc/lib/rustlib/x86_64-apple-darwin/lib/*.a", - ]), - ":k8": glob([ - "rust-std-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.rlib", - "rust-std-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.so", - "rust-std-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.a", - "rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.rlib", - "rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.so", - "rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/*.a", - ]), - }), - visibility = ["//visibility:public"], -) -""" - -def rust_repositories(): - native.new_http_archive( - name = "rust_linux_x86_64", - url = "https://static.rust-lang.org/dist/rust-1.6.0-x86_64-unknown-linux-gnu.tar.gz", - strip_prefix = "rust-1.6.0-x86_64-unknown-linux-gnu", - sha256 = "8630cc02432b4423d64eeae4ef071ec58e5dd1f3d555a3a3cc34b759202813f6", - build_file_content = RUST_BUILD_FILE, - ) - - native.new_http_archive( - name = "rust_darwin_x86_64", - url = "https://static.rust-lang.org/dist/rust-1.6.0-x86_64-apple-darwin.tar.gz", - strip_prefix = "rust-1.6.0-x86_64-apple-darwin", - sha256 = "8c6897ed37ef6fd2890b176afa65306cc8943e3c770c9530a701f1aefd3942b1", - build_file_content = RUST_BUILD_FILE, - ) diff --git a/tools/build_rules/rust/test/BUILD b/tools/build_rules/rust/test/BUILD deleted file mode 100644 index dca03f2bdf..0000000000 --- a/tools/build_rules/rust/test/BUILD +++ /dev/null @@ -1,3 +0,0 @@ -load(":rust_rule_test.bzl", "rust_rule_test") - -rust_rule_test("//examples/rust") diff --git a/tools/build_rules/rust/test/rust_rule_test.bzl b/tools/build_rules/rust/test/rust_rule_test.bzl deleted file mode 100644 index c4094bd46a..0000000000 --- a/tools/build_rules/rust/test/rust_rule_test.bzl +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2015 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tests for rust rules.""" - -load( - "//tools/build_rules/rust:rust.bzl", - "rust_library", - "rust_binary", - "rust_test", -) -load( - "//tools/build_rules:test_rules.bzl", - "rule_test", -) - -def _rust_library_test(package): - rule_test( - name ="hello_lib_rule_test", - generates = ["libhello_lib.rlib"], - provides = { - "rust_lib": "/libhello_lib.rlib$", - "transitive_libs": "^\\[\\]$" - }, - rule = package + "/hello_lib:hello_lib", - ) - -def _rust_binary_test(package): - rule_test( - name = "hello_world_rule_test", - generates = ["hello_world"], - rule = package + "/hello_world:hello_world", - ) - -def _rust_test_test(package): - """Issue rule tests for rust_test.""" - rule_test( - name = "greeting_rule_test", - generates = ["greeting"], - rule = package + "/hello_lib:greeting", - ) - -def rust_rule_test(package): - """Issue simple tests on rust rules.""" - _rust_library_test(package) - _rust_binary_test(package) - _rust_test_test(package) |