diff options
author | Damien Martin-Guillerez <dmarting@google.com> | 2016-07-28 12:47:11 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2016-07-29 10:09:06 +0000 |
commit | 95a54b98368a1c680c14e13d841b14a27aba01ca (patch) | |
tree | 4a4f51e0d40ac2231b27054207ff838ef574a4fd | |
parent | adc2d75bfb4bc7000b69183b6053a8ce6578748e (diff) |
Rollback of commit 3e8bcae69a0718cf6972be086706b1841e0ed6b7.
*** Reason for rollback ***
Breaks design docs links
*** Original change description ***
Move Bazel docs into versioned directory.
* Move all Bazel docs (excluding main page, search page, and blog)
into versions/master directory.
* Replace all original pages with redirects.
* Add Jekyll config with default_version setting to specify the default
version to redirect docs to.
* Add Jekyll config with version_prefix setting specific to pages under
each version directory.
* Update layouts to generate links to pages for the same version with the
version_prefix.
* Update Blaze rel...
***
--
MOS_MIGRATED_REVID=128690580
99 files changed, 6827 insertions, 6721 deletions
diff --git a/site/BUILD b/site/BUILD index 52f9da12be..89cfc8996d 100644 --- a/site/BUILD +++ b/site/BUILD @@ -2,7 +2,7 @@ load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar") exports_files( [ - "versions/master/docs/bazel-user-manual.html", + "docs/bazel-user-manual.html", "command-line-reference-prefix.html", "command-line-reference-suffix.html", ], diff --git a/site/_config.yml b/site/_config.yml index bbedaceb2f..d6dccbaa8e 100644 --- a/site/_config.yml +++ b/site/_config.yml @@ -4,12 +4,3 @@ paginate: 10 highlighter: pygments sass: sass_dir: _sass - -default_version: "master" -defaults: - - - scope: - path: "versions/master" - values: - version_prefix: "/versions/master" - diff --git a/site/_includes/header.html b/site/_includes/header.html index 933583564b..5af2024ea9 100644 --- a/site/_includes/header.html +++ b/site/_includes/header.html @@ -25,13 +25,13 @@ </form> <ul class="nav navbar-nav navbar-right"> <li{% if page.nav == "docs" %} class="active"{% endif %}> - <a href="{{ page.version_prefix }}/docs/install.html">Docs</a> + <a href="/docs/install.html">Docs</a> </li> <li{% if page.nav == "contribute" %} class="active"{% endif %}> - <a href="{{ page.version_prefix }}/contributing.html">Contribute!</a> + <a href="/contributing.html">Contribute!</a> </li> <li{% if page.nav == "faq" %} class="active"{% endif %}> - <a href="{{ page.version_prefix }}/faq.html">FAQ</a></li> + <a href="/faq.html">FAQ</a></li> <li{% if page.nav == "blog" %} class="active"{% endif %}> <a href="/blog">Blog</a> </li> diff --git a/site/_layouts/contribute.html b/site/_layouts/contribute.html index dd00aa4887..98a11aedb0 100644 --- a/site/_layouts/contribute.html +++ b/site/_layouts/contribute.html @@ -24,16 +24,16 @@ nav: contribute </a> <nav class="sidebar collapse" id="sidebar-nav"> <ul class="sidebar-nav"> - <li><a href="{{ page.version_prefix }}/contributing.html">Contributing to Bazel</a></li> - <li><a href="{{ page.version_prefix }}/hard_to_write_rules.html">Pitfalls</a></li> - <li><a href="{{ page.version_prefix }}/users.html">Who's Using Bazel</a></li> - <li><a href="{{ page.version_prefix }}/roadmap.html">Roadmap</a></li> - <li><a href="{{ page.version_prefix }}/governance.html">Governance</a></li> + <li><a href="/contributing.html">Contributing to Bazel</a></li> + <li><a href="/hard_to_write_rules.html">Pitfalls</a></li> + <li><a href="/users.html">Who's Using Bazel</a></li> + <li><a href="/roadmap.html">Roadmap</a></li> + <li><a href="/governance.html">Governance</a></li> </ul> <h3>How Bazel Works</h3> <ul class="sidebar-nav"> - <li><a href="{{ page.version_prefix }}/docs/skyframe.html">Skyframe</a></li> - <li><a href="{{ page.version_prefix }}/docs/designs/index.html">Design Documents</a></li> + <li><a href="/docs/skyframe.html">Skyframe</a></li> + <li><a href="/docs/designs/index.html">Design Documents</a></li> </ul> <h3>External Resources</h3> <ul class="sidebar-nav"> diff --git a/site/_layouts/documentation.html b/site/_layouts/documentation.html index 37239f5cd6..576ecc08ee 100644 --- a/site/_layouts/documentation.html +++ b/site/_layouts/documentation.html @@ -24,8 +24,8 @@ nav: docs </a> <nav class="sidebar collapse" id="sidebar-nav"> <ul class="sidebar-nav"> - <li><a href="{{ page.version_prefix }}/docs/install.html">Installing</a></li> - <li><a href="{{ page.version_prefix }}/docs/getting-started.html">Getting Started</a></li> + <li><a href="/docs/install.html">Installing</a></li> + <li><a href="/docs/getting-started.html">Getting Started</a></li> <li> <a class="sidebar-nav-heading" data-toggle="collapse" href="#tutorial-menu" aria-expanded="false" @@ -33,47 +33,47 @@ nav: docs Tutorial <span class="caret"></span> </a> <ul class="collapse sidebar-nav sidebar-submenu" id="tutorial-menu"> - <li><a href="{{ page.version_prefix }}/docs/tutorial/java.html">Build Java</a></li> - <li><a href="{{ page.version_prefix }}/docs/tutorial/cpp.html">Build C++</a></li> + <li><a href="/docs/tutorial/java.html">Build Java</a></li> + <li><a href="/docs/tutorial/cpp.html">Build C++</a></li> <li> <a class="sidebar-nav-heading" href="#app-menu" data-toggle="collapse" aria-expanded="false" aria-controls="app-menu"> Build Mobile Application </a> <ul class="collapse sidebar-nav sidebar-submenu" id="app-menu"> - <li><a href="{{ page.version_prefix }}/docs/tutorial/app.html">Introduction</a></li> - <li><a href="{{ page.version_prefix }}/docs/tutorial/environment.html">Set Up Your Environment</a></li> - <li><a href="{{ page.version_prefix }}/docs/tutorial/workspace.html">Set Up a Workspace</a></li> - <li><a href="{{ page.version_prefix }}/docs/tutorial/android-app.html">Build an Android App</a></li> - <li><a href="{{ page.version_prefix }}/docs/tutorial/ios-app.html">Build an iOS App</a></li> - <li><a href="{{ page.version_prefix }}/docs/tutorial/backend-server.html">Build the Backend Server</a></li> - <li><a href="{{ page.version_prefix }}/docs/tutorial/review.html">Review</a></li> + <li><a href="/docs/tutorial/app.html">Introduction</a></li> + <li><a href="/docs/tutorial/environment.html">Set Up Your Environment</a></li> + <li><a href="/docs/tutorial/workspace.html">Set Up a Workspace</a></li> + <li><a href="/docs/tutorial/android-app.html">Build an Android App</a></li> + <li><a href="/docs/tutorial/ios-app.html">Build an iOS App</a></li> + <li><a href="/docs/tutorial/backend-server.html">Build the Backend Server</a></li> + <li><a href="/docs/tutorial/review.html">Review</a></li> </ul> </li> </ul> </li> - <li><a href="{{ page.version_prefix }}/docs/support.html">Get Support</a></li> + <li><a href="/docs/support.html">Get Support</a></li> </ul> <h3>Using Bazel</h3> <ul class="sidebar-nav"> - <li><a href="{{ page.version_prefix }}/docs/build-ref.html">BUILD files</a></li> - <li><a href="{{ page.version_prefix }}/docs/bazel-user-manual.html">User Manual</a></li> - <li><a href="{{ page.version_prefix }}/docs/test-encyclopedia.html">Writing Tests</a></li> - <li><a href="{{ page.version_prefix }}/docs/query.html">Query Language</a></li> - <li><a href="{{ page.version_prefix }}/docs/query-how-to.html">Query How-To</a></li> - <li><a href="{{ page.version_prefix }}/docs/mobile-install.html">mobile-install (Android)</a></li> - <li><a href="{{ page.version_prefix }}/docs/external.html">External Dependencies</a></li> - <li><a href="{{ page.version_prefix }}/docs/command-line-reference.html">Command-line Reference</a></li> - <li><a href="{{ page.version_prefix }}/docs/output_directories.html">Output Directories</a></li> + <li><a href="/docs/build-ref.html">BUILD files</a></li> + <li><a href="/docs/bazel-user-manual.html">User Manual</a></li> + <li><a href="/docs/test-encyclopedia.html">Writing Tests</a></li> + <li><a href="/docs/query.html">Query Language</a></li> + <li><a href="/docs/query-how-to.html">Query How-To</a></li> + <li><a href="/docs/mobile-install.html">mobile-install (Android)</a></li> + <li><a href="/docs/external.html">External Dependencies</a></li> + <li><a href="/docs/command-line-reference.html">Command-line Reference</a></li> + <li><a href="/docs/output_directories.html">Output Directories</a></li> </ul> {% include be-nav.html %} <h3>Extensions</h3> <ul class="sidebar-nav"> - <li><a href="{{ page.version_prefix }}/docs/skylark/concepts.html">Overview</a></li> - <li><a href="{{ page.version_prefix }}/docs/skylark/macros.html">Macros</a></li> - <li><a href="{{ page.version_prefix }}/docs/skylark/rules.html">Rules</a></li> - <li><a href="{{ page.version_prefix }}/docs/skylark/aspects.html">Aspects</a></li> - <li><a href="{{ page.version_prefix }}/docs/skylark/repository_rules.html">Repository rules</a></li> + <li><a href="/docs/skylark/concepts.html">Overview</a></li> + <li><a href="/docs/skylark/macros.html">Macros</a></li> + <li><a href="/docs/skylark/rules.html">Rules</a></li> + <li><a href="/docs/skylark/aspects.html">Aspects</a></li> + <li><a href="/docs/skylark/repository_rules.html">Repository rules</a></li> <li> <a class="sidebar-nav-heading" data-toggle="collapse" href="#skylark-lib-menu" aria-expanded="false" @@ -84,8 +84,8 @@ nav: docs {% include skylark-nav.html %} </ul> </li> - <li><a href="{{ page.version_prefix }}/docs/skylark/cookbook.html">Examples</a></li> - <li><a href="{{ page.version_prefix }}/docs/skylark/deploying.html">Packaging rules</a></li> + <li><a href="/docs/skylark/cookbook.html">Examples</a></li> + <li><a href="/docs/skylark/deploying.html">Packaging rules</a></li> </ul> </nav> </div> diff --git a/site/_layouts/redirect.html b/site/_layouts/redirect.html deleted file mode 100644 index 85ae15edbf..0000000000 --- a/site/_layouts/redirect.html +++ /dev/null @@ -1,7 +0,0 @@ -<html> - <head> - <script> - window.location.replace("/versions/{{ site.default_version }}/{{ page.redirect }}"); - </script> - </head> -</html> diff --git a/site/contributing.md b/site/contributing.md index 5bafefcb56..6ea17d48a5 100644 --- a/site/contributing.md +++ b/site/contributing.md @@ -1,4 +1,146 @@ --- -layout: redirect -redirect: contributing.html +layout: contribute +title: Contributing to Bazel --- + +# Contributing to Bazel + +<p class="lead">We welcome contributions! This page covers setting up your +machine to develop Bazel and, when you've made a patch, how to submit it.</p> + +## How can I contribute to Bazel? + +In general, we prefer contributions that fix bugs or add features (as opposed to +stylistic, refactoring, or "cleanup" changes). Please check with us on the +[dev list](https://groups.google.com/forum/#!forum/bazel-dev) before investing +a lot of time in a patch. + +## Patch Acceptance Process + +<!-- Our markdown parser doesn't support nested lists. --> +<ol> +<li>Read the <a href="governance.html">Bazel governance plan</a>.</li> +<li>Discuss your plan and design, and get agreement on our <a href="https://groups.google.com/forum/#!forum/bazel-dev">mailing list</a>. +<li>Prepare a git commit that implements the feature. Don't forget to add tests. +<li>Create a new code review on <a href="https://bazel-review.googlesource.com">Gerrit</a> + by running: + <pre>$ git push https://bazel.googlesource.com/bazel HEAD:refs/for/master</pre> + Gerrit upload requires that you: + <ul> + <li>Have signed a + <a href="https://cla.developers.google.com">Contributor License Agreement</a>. + <li>Have an automatically generated "Change Id" line in your commit message. + If you haven't used Gerrit before, it will print a bash command to create + the git hook and then you will need to run `git commit --amend` to add the + line. + </ul> + The HTTP password required by Gerrit can be obtained from your + <a href="https://bazel-review.googlesource.com/#/settings/http-password">Gerrit settings page</a>. + See the + <a href="https://gerrit-review.googlesource.com/Documentation/user-upload.html">Gerrit documentation</a> + for more information about uploading changes. +<li>Complete a code review with a + <a href="governance.html#core-contributors">core contributor</a>. Amend your existing + commit and re-push to make changes to your patch. +<li>An engineer at Google applies the patch to our internal version control + system. +<li>The patch is exported as a Git commit, at which point the Gerrit code review + is closed. +</ol> + +## Setting up your coding environment + +For now we have partial support for the Eclipse and IntelliJ IDEs for Java. We +don't have IDE support for other languages in Bazel right now. + +### Creating an Eclipse project + +To work with Eclipse: + +* Install the [e4b](https://github.com/bazelbuild/e4b) plugin. +* Change the path to the Bazel binary in the plugin preferences. +* Import the Bazel workspace as a Bazel project (`File` > `New` > `Other` > + `Import Bazel Workspace`). +* Select `src > main > java` and `src > test > java` as directories and add + `//src/main/java/...` and `//src/test/java/...` as targets. + +### Creating an IntelliJ project + +To work with IntelliJ: + +* Run `sh scripts/setup-intellij.sh` from the root of the source tree to create + the necessary project files. +* Open the folder as a project in IntelliJ. + +<a name="compile-bazel"></a> +### Compiling Bazel + +To test out bazel, you need to compile it. There are currently two ways of +compiling it: + +* `sh compile.sh` bootstraps Bazel from scratch, first compiling it without using + Bazel, then rebuilding it again using the just built Bazel and optionally runs + tests, too. The resulting binary can be found at `output/bazel`. +* `bazel build //src:bazel` builds the Bazel binary using `bazel` from your PATH + and the resulting binary can be found at `bazel-bin/src/bazel`. This is the + recommended way of rebuilding Bazel once you have bootstrapped it. + +In addition to the Bazel binary, you might want to build the various tools Bazel +uses. They are located in `//src/java_tools/...`, `//src/objc_tools/...` and +`//src/tools/...` and their directories contain README files describing their +respective utility. + +When modifying Bazel, you want to make sure that the following still works: + +* Bootstrap test with `sh compile.sh all` after having removed the + `output` directory: it rebuilds Bazel with `./compile.sh`, Bazel with the + `compile.sh` Bazel and Bazel with the Bazel-built binary. It compares if the + constructed Bazel builts are identical and then runs all bazel tests with + `bazel test //src/... //third_party/ijar/...`. This is what we use at Google + to ensure that we don't break Bazel when pushing new commits, too. + +### Debugging Bazel + +Start creating a debug configuration for both C++ and Java in your `.bazelrc` +with the following: + +``` +build:debug -c dbg +build:debug --javacopt="-g" +build:debug --copt="-g" +build:debug --strip="never" +``` + +Then you can rebuild Bazel with `bazel build --config debug //src:bazel` and use +your favorite debugger to start debugging. + +For debugging the C++ client you can just run it from gdb or lldb as you normally would. +But if you want to debug the Java code, you must attach to the server using the following: + +* Run Bazel with debugging option `--host_jvm_debug` before the + command (e.g., `bazel --batch --host_jvm_debug build //src:bazel`). +* Attach a debugger to the port 5005. With `jdb` for instance, + run `jdb -attach localhost:5005`. From within Eclipse, use the + [remote Java application launch + configuration](http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-remotejava_launch_config.htm). + For IntelliJ, you can refer to [Run/Debug Configuration: Remote](https://www.jetbrains.com/idea/help/run-debug-configuration-remote.html). + +## Bazel's code description + +Bazel is organized in several parts: + +* Client code in `src/main/cpp` provides the command-line interface. +* Protocol buffers in `src/main/protobuf`. +* Server code in `src/main/java` and `src/test/java`. + * Core code which is mostly composed of [SkyFrame](docs/skyframe.html) and some + utilities. + * Rules written in Bazel's extension language + [Skylark](docs/skylark/index.html) are defined in `tools/build_rules`. If + you want to add rules, consider using [Skylark](docs/skylark/index.html) + first. + * Builtin rules in `com.google.devtools.build.lib.rules` and in + `com.google.devtools.build.lib.bazel.rules`. You might want to read [Why is + it so difficult to write Bazel rules?](hard_to_write_rules.html) first. +* Java native interfaces in `src/main/native`. +* Various tooling for language support (see the list in the + [compiling Bazel](#compile-bazel) section). diff --git a/site/versions/master/docs/bazel-user-manual.html b/site/docs/bazel-user-manual.html index efdf1d1426..efdf1d1426 100644 --- a/site/versions/master/docs/bazel-user-manual.html +++ b/site/docs/bazel-user-manual.html diff --git a/site/docs/bazel-user-manual.md b/site/docs/bazel-user-manual.md deleted file mode 100644 index f9fea184a6..0000000000 --- a/site/docs/bazel-user-manual.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -layout: redirect -redirect: docs/bazel-user-manual.html ---- diff --git a/site/versions/master/docs/build-ref.html b/site/docs/build-ref.html index 6bb3e11926..6bb3e11926 100644 --- a/site/versions/master/docs/build-ref.html +++ b/site/docs/build-ref.html diff --git a/site/docs/build-ref.md b/site/docs/build-ref.md deleted file mode 100644 index e08473d1f5..0000000000 --- a/site/docs/build-ref.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -layout: redirect -redirect: docs/build-ref.html ---- diff --git a/site/docs/designs/_posts/2016-06-02-sandboxing.md b/site/docs/designs/_posts/2016-06-02-sandboxing.md index fb168d5813..ceacd3e6c8 100644 --- a/site/docs/designs/_posts/2016-06-02-sandboxing.md +++ b/site/docs/designs/_posts/2016-06-02-sandboxing.md @@ -1,4 +1,150 @@ --- -layout: redirect -redirect: docs/designs/2016/06/02/sandboxing.html +layout: documentation +title: Sandboxing --- + +# Bazel Sandboxing 2.0 + +This doc was written by [philwo@google.com](mailto:philwo@google.com). +Status: unimplemented, section "Handling of environment variables" superseded +by the +[Specifying environment variables](/docs/designs/2016/06/21/environment.html) +design document. + +## Current situation + +Tools that use undeclared input files (files that are not explicitly listed in +the dependencies of an action) are a problem, as Bazel cannot keep track of them +and thus they can cause builds to become incorrect: When one of the undeclared +input files changes, Bazel will still believe that the build is up-to-date and +won't rebuild the action - resulting in an incorrect incremental build. + +Bazel uses sandboxing to prevent tools (e.g. compilers, linkers, ...) from +accidentally working with input files that are not a declared dependency of an +action - the idea is to run each tool in an environment that contains only the +explicitly declared input files of the action. Thus, there simply are no other +files that a tool could access. + +In theory this works well, but as nearly all Bazel users rely at least on some +tools provided by their operating system (e.g. `/usr/bin/zip`, `/usr/bin/gcc`), +which in turn require shared libraries, helper tools or data from other parts +of the installed OS, Bazel currently mounts a number of hard-coded directories +from the operating system into the sandbox in addition to the explicitly +declared inputs. + +However, even with that some users continue to run into issues, making Bazel +hard to use - e.g. the compiler they want to use is in a directory that's not +part of the hard-coded list (such as `/usr/local` or `/opt`) or the tool needs +access to device files (e.g. the nVidia CUDA SDK). + +## Proposal + +We think that it's time to revisit how we do sandboxing in the default settings +of Bazel. Sandboxing was intended to protect the user from forgetting to +declare explicit dependencies between their targets and to protect from tests +or tools accidentally writing all over the hard-disk (e.g. a test that wants to +clean up its temporary work directory via rm -rf and unfortunately wipes the +whole disk), not so much for protecting against an operating system having any +influence on the build. For these users, the current sandboxing with its +hard-coded list of allowed directories is too strict. + +On the other hand, some people absolutely do want 100% reproducible and +hermetic builds - and for them the current sandboxing actually isn't strict +enough, as it allows access to various files from the operating system. + +We believe we have found a solution that satisfies the demands of all users: + + * Bazel sandboxing will by default recursively mount the root directory `/` + into each sandbox in read-only mode, excluding the workspace directory (so + that source files cannot be read from that well-known path) and with a new + empty, writable execroot that contains the declared inputs of the action. + * In addition, Bazel will allow to mount a 'base image' or 'base directory' as + the root directory of the sandbox, thus completely removing any connection + to the operating system the user is running Bazel under. For example, a + project might decide that all builds should be done inside a standardized + Ubuntu 16.04 LTS environment containing certain versions of gcc, etc., that + is shipped as a base image. Now, even if the developer uses Arch Linux or + CentOS on their machine, they can build using the same environment as + everyone else, thus getting the exact same and reproducible outputs. + +### Base images + +Base images are simply `.tar.gz`'s of a directory structure that contains all +files necessary to execute binaries in, e.g. the output of “debootstrap” or +what you would usually “chroot” in and then run a tool inside. They should be +referred to via labels and could for example be downloaded from somewhere via +a `http_file` rule in the WORKSPACE. + +We're investigating if we can reuse +[Docker images (OCI)](https://github.com/opencontainers/image-spec/blob/v0.1.0/serialization.md) +for this, which would make it easier for users to get started with this +feature. + +### Handling of environment variables + +As part of this project, we also propose to change the handling of environment +variables (e.g. `PATH`) in Bazel, as we believe they are an important part of +the configuration of the environment that the build runs in. + +As an example, Bazel currently [resets PATH to a hard-coded string] +(https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelConfiguration.java), +which may not be suitable for the environment that it actually runs in - e.g. +if a user installs a tool called `babel` in `/usr/local/bin` and they call +`babel` in a shell script or Skylark rule they wrote, [they expect it to just +work] (https://github.com/bazelbuild/bazel/issues/884). We can argue that they +instead should check in their tool to the repository and not rely on `PATH` +lookup to find it, however this is sometimes not possible due to: + + * Users just don't think it's feasible and instead want to take whatever is + installed on the system, + * Bazel's restrictions in valid package label identifiers ([you can't check in + nodejs](https://github.com/bazelbuild/bazel/issues/884#issuecomment-183378680) + into your repository or even make it part of a filegroup, because it + contains files that have characters like `$` that are currently illegal from + Bazel's point of view, though that may change in the future), + * Licensing restrictions that disallow users checking in certain tools (such + as XCode). + +The proposal how Bazel should decide whether an environment variable should be +included in the environment of a Spawn is: + + * If `use_default_shell_env` is `True`, set `PATH` and `TMPDIR` env vars + (as we currently do). + * If a rule declares its need for an environment variable, take it. + * We already have an [“env” attribute in Skylark actions] + (http://www.bazel.io/docs/skylark/lib/ctx.html#action) that allows one to + set variables to hard-coded strings, we have `use_default_shell_env` in + Skylark actions, which pulls in `PATH` and `TMPDIR`, but we don't have any + way to just say "This rule needs this environment variable". Laurent + suggested that we discuss this later, as adding yet another attribute is + annoying - maybe there's some way we can fold all these use cases into one + attribute. + * We might want to add the same attribute to genrule as well then. + * Don't include any other environment variables. + +If Bazel decided that an environment variable is needed by a rule, the next +step is to figure out its value. The proposal how Bazel should decide the value +of an environment variable is: + + * If an environment variable is overridden in the `WORKSPACE.local` file + ("machine-specific settings"), take it from there. + * If an environment variable is overridden in the `WORKSPACE` file + ("project-specific settings"), always take the value from there. + * If not and we use a base image, take the environment variable from its + specification (as in OCI). + * If not, take it from the user's environment. + +If an environment variable that is used by a rule changed compared to when it +was built last time, its target has to be rebuild for correctness. + +Bazel should instead use `PATH` from the environment and for correctness +trigger a rebuild when it changes. + +*Open question: Should the whitelist of environment variables be configurable, +e.g. in the WORKSPACE file?* + +### Known issues in this area of work + +[Bazel #577: genrules leaking PATH into environment] +(https://github.com/bazelbuild/bazel/issues/577) + diff --git a/site/docs/designs/_posts/2016-06-21-environment.md b/site/docs/designs/_posts/2016-06-21-environment.md index b182bebf70..a2ab48eb06 100644 --- a/site/docs/designs/_posts/2016-06-21-environment.md +++ b/site/docs/designs/_posts/2016-06-21-environment.md @@ -1,4 +1,279 @@ --- -layout: redirect -redirect: docs/designs/2016/06/21/environment.html +layout: documentation +title: Specifying environment variables --- + +# Specifying environment variables for actions + +This doc was written by [aehlig@google.com](mailto:aehlig@google.com). +Status: unimplemented. + +## Current shortcomings + +Currently, Bazel provides a cleaned set of environment variables to the +actions in order to obtain hermetic builds. This, however is not sufficient +for all use cases. + +* Projects often want to use tools which are not part of the repository; however, + their location varies from installation to installation. So, some sensible + value for the `PATH` environment variable has to be set. + +* Some set-ups depend on every program having access to specific variables, + e.g., indicating the homebrew paths, or library paths. + +* Commercial compilers sometimes need to be passed the location of a license + server through the environment. + +## Proposed solution + +### New flag `--action_env` + +We propose to add a new bazel flag, `--action_env` which has two +valid forms of usage, + +* specifying a variable with unspecified value, `--action_env=VARIABLE`, + and + +* specifying a variable with a value, `--action_env=VARIABLE=VALUE`; + in the latter case, the value can well be the empty string, but it is still + considered a specified value. + +This flag has a "latest wins" semantics in the sense that if the option is given +twice for the same variable, only the latest option will be used, regardless +whether specified or unspecified value. Options given for different variables +accumulate. + +In every action executed +with [`use_default_shell_env`] (/docs/skylark/lib/ctx.html#action) being true, +precisely the environment variables specified by +`--action_env` options are set as the default environment. +(Note that, therefore, by default, the environment for actions is empty.) + +* If the effective option for a variable has an unspecified value, + the value from the invocation environment of Bazel is taken. + +* If the effective option for a variable specifies a value, this value is + taken, regardless of the environment in which Bazel is invoked. + +Environment variables are considered an essential part of an action. In other +words, an action is expected to produce a different output, if the environment +it is invoked in differs; in particular, a previously cached value cannot be +taken if the effective environment changes. + +Given that normally a rule writer cannot know which tools might need fancy +environment variables (think of the commercial compiler use case), the default +for the [`use_default_shell_env`] (/docs/skylark/lib/ctx.html#action) +parameter will become true. + +### List of rc-files read by Bazel + +The list of rc-files that Bazel takes options from will include, at +least, the following files, where files later in the list take precedence over +the ones earlier in the list for conflicting options; for the +`--action_env` option the already described "latest wins" semantics is +applied. + +* A global rc-file. This file typically contains defaults for a whole group of + machines, like all machines of a company. On UNIX-like systems, it will be + located at `/etc/bazel.bazelrc`. + +* A machine-wide rc-file. This file is typically set by the administrator of + the machine or a group of machines with the same architecture. It typically + contains settings that are specific to that architecture and hardware. + On UNIX-like systems it will be next to be binary and called like the binary + with `.bazelrc` appended to the file name. + +* A user-specific file, located in `~/.bazelrc`. This file will be set by + each user for options desired for all Bazel invocations. + +* A project-specific file. This is the file `tools/bazel.rc` next to + the `WORKSPACE` file. This file is considered project-specific and + typically versioned in the same repository as the project. + +* A file specific to user, project, and checkout. This is the file + `.bazelrc` next to the `WORKSPACE` file. As it is specific to + the user and the machine he or she is working on, projects are advised + to ignore that file in the repository of the project (e.g., by adding + it to their `.gitignore` file, if they version the project with git). + +When looking for those rc-files, symbolic links are followed; files not +existing are silently assumed to be empty. Note that all those are regular +rc-files for Bazel, hence are not limited to the newly introduced +`--action_env` option. Also, the rule that options for more specific +invocations win over common options still applies; but, within each level of +specificness, precedence is given according to the mentioned order of rc-files. + +## Example usages of environment specifications + +The proposed solution allows for a variety of use cases, including the +following. + +* Systems using commercial compilers can set the environment variables with + information about the license server in the global rc file. + +* Users requiring special variables, like the ones used by homebrew, can set + them in their machine specific rc-file. In fact, once this proposal is + implemented, the homebrew port for Bazel could itself install that + machine-wide rc-file. + +* Projects depending on the environment, e.g., because they use tools assumed to + be already installed on the user's systm, have several options. + + * If they are optimistic about the environment, e.g., because they are not + very version dependent on the tools used, can just specify which environment + variables they depend on by adding declarations with unspecified values in + the `tools/bazel.rc` file. + + * If dependencies are more delicate, projects can provide a configure script + that does whatever analysis of the environment is necessary and then write + `--action_env` options with specified values to the user-project + local `.bazelrc` + file. As the configure script will only run when manually invoked by the + user and the syntax of the user-project local `.bazelrc` file is so that it + can be easily + be edited by a human, it is OK if that script only works in the majority of + the cases, as a user requiring an unusual setup for that project can easily + modify the user-project local `.bazelrc` by hand afterwards. + +* Irrespectively of the approach chosen by the project, a user where the + environment changes frequently (e.g., on clusters or other machines using a + traditional layout) can fix the environment by adding `--action_env` + options with specific values to the user-project local `.bazelrc`. + + To simplify this use case, Bazel might provide a script + `bazel_freeze_environment` that reads the + `tools/bazel.rc` and looks for `--action_env` options with + unspecified values and writes corresponding ones with specified values to the + user-project local `.bazelrc` file; the specified values are taken from the + environment of + the invocation of that script. + + To simplify "freeze on first use" approaches, there will be separate way of + invoking the `bazel_freeze_environment` script so that it only adds + `--action_env` options with specified values for variables not already + mentioned in the user-project local `.bazelrc` file. + +## Transition plan + +Currently, some users of Bazel already make use of the fact that `PATH`, +`LD_LIBRARY_PATH`, and `TMPDIR` are being passed to actions. To allow those +projects a smooth +transition to the new set up, the global Bazel rc-file provided by upstream +will have the following content. + +``` +common --action_env=PATH +common --action_env=LD_LIBRARY_PATH +common --action_env=TMPDIR +``` + + +## Bazel's own dependency on `PATH` + +Bazel itself also uses external tools, like `cat`, `echo`, `sh`, but also +tools like `bash` where the location differs between installations. In +particular, a value for `PATH` needs to be provided. This will be covered +by the setting of the global bazel configuration file. Should the need arise, a +configure-like script can be added; at the moment it seems that this will not +be necessary. + +## Reasons for the Design Choices, Risks, and Alternatives Considered + +### Conflicting Interests on the environment influencing actions + +There are conflicting requirements for the environment variables of an action. + +* Users expect Bazel to "just work", i.e., the expectation is that if a tool + works on the command line, it should also work when called from an action in + a Bazel invocation from the same environment. A lot of compilers, however, + depend, at least on some systems, on certain environment variables. + An approach used by quite a few other build systems is to pass through the + whole invocation environment. + +* Bazel wants to provide correct and reproducible builds. Therefore, everything + that potentially influences the outcome of an action needs to be controlled + and tracked; a cached result cannot be used if anything potentially changing + the outcome has changed. + +* Users expect Bazel to not do rebuilds they (i.e., the users) know are + unnecessary. And, while for a lot of users the environment variables that + actually influence the build stay stable, the full environment constantly + changes; take the `OLDPWD` environment variable as an example. + +This design tries to reconcile these needs by allowing arbitrary environment +variables being set for actions, but only in an opt-in way. Variables need to +be explicitly mentioned, either in a configuration file or on the command line, +to be provided to an action. + +### Generic Solutions versus Special Casing + +As Bazel already has quite a number of concepts, there is the valid concern +that the complexity might increase too much and newly added concepts might +become a maintenance burden. Another concern is that more configuration +mechanisms make it harder for the user to know which one is the correct one +to use for his or her problem. The general desire is to have few, but powerful +enough mechanisms to control the build behaviour and avoid special casing. + +* Putting the environment variables visible in actions in the hand of the + user avoids the need of special casing more and more "important" environment + variables. + +* Building on the already existing mechanism to specify, inherit, and override + command-line options reduces the amount newly introduced concepts. The main + addition is a command-line option. + +A corner case from that perspective is the `bazel_freeze_environment` script. +While it solves a valid use case, its only purpose is the management +of environment variables. At least it is strictly a user tool, in the sense +that Bazel itself does not depend on it: Bazel will happily read any +syntactically valid rc-file, regardless how it was created; so a user can +hand-code the user-project local `.bazelrc` file, use the help of +`bazel_freeze_environment`, or use a third-party tool to generate it. + +### Source of Knowledge for Needed Environment Variables + +Another aspect that went into the design is that different entities know +about environment variables that are essential for the build to work. + +* Some variables are "obviously" relevant, like `PATH` or `TMPDIR`. + However, there is no "obvious" value for them. + + * Both depend on the layout of the system in question. A special fast + file system for temporary files might be provided at a designated + location. Binaries might be installed under `/bin`, `/usr/bin`, + `/usr/local/bin`, or even versioned paths to allow parallel installations + of different versions of the same tool. For example, on Debian Gnu/Linux + the `bash` is installed in `/bin`, whereas on FreeBSD it is usually + installed in `/usr/local/bin` (but the prefix `/usr/local` is at the + discretion of the system administrator). + + * The user might have custom-built versions of tools somewhere in the + home directory, thus making the user the only one who knows an appropriate + value for the `PATH` variable. Moreover, a user who works on several + projects requiring different versions of the same tool may even require + different values of the `PATH` variable for each project. + +* The authors and users of a tool know about special variables the tools + need to work. While the tool itself might serve a standard purpose, like + compiling C code, the variables the tool depends on might be specific to + that tool (like passing information about a license server). + +* The maintainers of a porting or packaging system know about environment + variables a tool might additionally need (e.g., in the homebrew case). + These might not be needed if the same tool is packaged differently. + +* The project authors know about environment variables special to their + project that some of their actions need. + +These different sources of information make it hard to designate a +single maintainer for the action environment. This makes approaches +undesirable that are based on a single source specifying the action +environment, like the `WORKSPACE` file, or the rule definitions. While +those approaches make it easy to predict the environment an action will +have, they all require the user to merge in the specifics of the system +and his or her personal settings for each checkout (including rebasing +these changes for each upstream change of that file). Collecting environment +variables via the rc-file mechanism allows setting each variable within +the appropriate scope (global, machine-dependent, user-spefic, project-specific, +specific to the user-project pair) in a conflict-free way by the entity +in charge of that scope. diff --git a/site/docs/designs/index.md b/site/docs/designs/index.md index 8c20e82dc8..cd2a9d7e7e 100644 --- a/site/docs/designs/index.md +++ b/site/docs/designs/index.md @@ -1,4 +1,13 @@ --- -layout: redirect -redirect: docs/designs/index.html +layout: documentation +title: Design Documents --- + +# Bazel Design Documents + +<ul> +{% for doc in site.categories.designs %} + <li><a href="{{ doc.url }}">{{ doc.title }}</a> + {{ doc.date | date_to_long_string }}</a></li> +{% endfor %} +</ul> diff --git a/site/versions/master/docs/docs_style.css b/site/docs/docs_style.css index bb225e1fd9..bb225e1fd9 100644 --- a/site/versions/master/docs/docs_style.css +++ b/site/docs/docs_style.css diff --git a/site/docs/external.md b/site/docs/external.md index ec45348162..1bcdc683d7 100644 --- a/site/docs/external.md +++ b/site/docs/external.md @@ -1,4 +1,201 @@ --- -layout: redirect -redirect: docs/external.html +layout: documentation +title: External Dependencies --- + +# Working with external dependencies + +Bazel is designed to have absolutely everything needed for a build, from source +code to libraries to compilers, under one directory (the workspace directory). +This is impractical for some version control systems and goes against how many +existing projects are structured. Thus, Bazel has a system for pulling in +dependencies from outside of the workspace. + +External dependencies can be specified in a `WORKSPACE` file in the +[workspace directory](/docs/build-ref.html#workspaces). This `WORKSPACE` file +uses the same Python-like syntax of BUILD files, but allows a different set of +rules. See the full list of rules that are allowed in the +[Workspace](/docs/be/workspace.html) list of rules in the Build +Encyclopedia. + +External dependencies are all downloaded and symlinked under a directory named +`external`. You can see this directory by running: + +``` +ls $(bazel info output_base)/external +``` + +Note that running `bazel clean` will not actually delete the external +directory: to remove all external artifacts, use `bazel clean --expunge`. + +## Fetching dependencies + +By default, external dependencies are fetched as needed during `bazel build`. If +you would like to disable this behavior or prefetch dependencies, use +[`bazel fetch`](http://bazel.io/docs/bazel-user-manual.html#fetch). + +## Using Proxies + +Bazel will pick up proxy addresses from the `HTTPS_PROXY` and `HTTP_PROXY` +environment variables and use these to download HTTP/HTTPS files (if specified). + +<a name="transitive-dependencies"></a> +## Transitive dependencies + +Bazel only reads dependencies listed in your `WORKSPACE` file. This +means that if your project (`A`) depends on another project (`B`) which list a +dependency on project `C` in its `WORKSPACE` file, you'll have to add both `B` +and `C` to your project's `WORKSPACE` file. This can balloon the `WORKSPACE` +file size, but hopefully limits the chances of having one library include `C` +at version 1.0 and another include `C` at 2.0. + +Bazel provides a tool to help generate these expansive `WORKSPACE` files, called +`generate_workspace`. This is not included with the binary installer, so you'll +need to clone the [GitHub repo](https://github.com/bazelbuild/bazel) to use it. +We recommend using the tag corresponding to your current version of bazel, which +you can check by running `bazel version`. + +`cd` to the GitHub clone, `git checkout` the appropriate tag, and run the +following to build the tool and see usage: + +``` +bazel run //src/tools/generate_workspace +``` + +Note that you need run this from your Bazel source folder even if you build your binary from source. + +You can specify directories containing Bazel projects (i.e., directories +containing a `WORKSPACE` file), Maven projects (i.e., directories containing a +`pom.xml` file), or Maven artifact coordinates directly. For example: + +```bash +$ bazel run //src/tools/generate_workspace -- \ +> --maven_project=/path/to/my/project \ +> --bazel_project=/path/to/skunkworks \ +> --bazel_project=/path/to/teleporter/project \ +> --artifact=groupId:artifactId:version \ +> --artifact=groupId:artifactId:version +Wrote: +/tmp/1437415510621-0/2015-07-20-14-05-10.WORKSPACE +/tmp/1437415510621-0/2015-07-20-14-05-10.BUILD +``` + +The `WORKSPACE` file will contain the transitive dependencies of the given +projects and artifacts. The `BUILD` file will contain a single target, +`transitive-deps`, that contains all of the dependencies. You can copy these +files to your project and add `transitive-deps` as a dependency of your `java_` +targets in `BUILD` files. + +If you specify multiple Bazel projects, Maven projects, or artifacts, they will +all be combined into one `WORKSPACE` file (e.g., if the Bazel project depends on +junit and the Maven project also depends on junit, junit will only appear once +as a dependency in the output). + +You may wish to curate the generated `WORKSPACE` file to ensure it is using the +correct version of each dependency. If several different versions of an artifact +are requested (by different libraries that depend on it), then +`generate_workspace` chooses a version and annotates the `maven_jar` with the +other versions requested, for example: + +```python +# org.springframework:spring:2.5.6 +# javax.mail:mail:1.4 +# httpunit:httpunit:1.6 wanted version 1.0.2 +# org.springframework:spring-support:2.0.2 wanted version 1.0.2 +# org.slf4j:nlog4j:1.2.24 wanted version 1.0.2 +maven_jar( + name = "javax/activation/activation", + artifact = "javax.activation:activation:1.1", +) +``` + +This indicates that `org.springframework:spring:2.5.6`, `javax.mail:mail:1.4`, +`httpunit:httpunit:1.6`, `org.springframework:spring-support:2.0.2`, and +`org.slf4j:nlog4j:1.2.24` all depend on javax.activation. However, two of these +libraries wanted version 1.1 and three of them wanted 1.0.2. The `WORkSPACE` +file is using version 1.1, but that might not be the right version to use. + +You may also want to break `transitive-deps` into smaller targets, as it is +unlikely that all of your targets depend on the transitive closure of your +maven jars. + +# Types of external dependencies + +There are a few basic types of external dependencies that can be created. + +## Combining Bazel projects + +If you have a second Bazel project that you'd like to use targets from, you can +use +[`local_repository`](http://bazel.io/docs/be/workspace.html#local_repository) +or [`http_archive`](http://bazel.io/docs/be/workspace.html#http_archive) +to symlink it from the local filesystem or download it (respectively). + +For example, suppose you are working on a project, `my-project/`, and you want +to depend on targets from your coworker's project, `coworkers-project/`. Both +projects use Bazel, so you can add your coworker's project as an external +dependency and then use any targets your coworker has defined from your own +BUILD files. You would add the following to `my_project/WORKSPACE`: + +```python +local_repository( + name = "coworkers-project", + path = "/path/to/coworkers-project", +) +``` + +If your coworker has a target `//foo:bar`, your project can refer to it as +`@coworkers-project//foo:bar`. + +## Depending on non-Bazel projects + +Rules prefixed with `new_` (e.g., +[`new_local_repository`](http://bazel.io/docs/be/workspace.html#new_local_repository) +and [`new_http_archive`](http://bazel.io/docs/be/workspace.html#new_http_archive) +) allow you to create targets from projects that do not use Bazel. + +For example, suppose you are working on a project, `my-project/`, and you want +to depend on your coworker's project, `coworkers-project/`. Your coworker's +project uses `make` to build, but you'd like to depend on one of the .so files +it generates. To do so, add the following to `my_project/WORKSPACE`: + +```python +new_local_repository( + name = "coworkers-project", + path = "/path/to/coworkers-project", + build_file = "coworker.BUILD", +) +``` + +`build_file` specifies a BUILD file to overlay on the existing project, for +example: + +```python +java_library( + name = "some-lib", + srcs = glob(["**"]), + visibility = ["//visibility:public"], +) +``` + +You can then depend on `@coworkers-project//:some-lib` from your project's BUILD +files. + +# Caching of external dependencies + +Bazel caches external dependencies and only re-downloads or updates them when +the `WORKSPACE` file changes. If the `WORKSPACE` file does not change, Bazel +assumes that the external dependencies have not changed, either. This can cause +unexpected results, especially with local repositories. + +For instance, in the example above, suppose that `my-project/` has a target that +depends on `@coworkers-project//:a`, which you build. Then you change to +`coworkers-project/` and pull the latest updates to their library, which changes +the behavior of `@coworkers-project//:a`. If you go back to `my-project/` and +build your target again, it will assume `@coworkers-project//:a` is already +up-to-date and reuse the cached library (instead of realizing that the sources +have changed and, thus, rebuilding). + +To avoid this situation, prefer remote repositories to local ones and do not +manually change the files in `[output_base]/external`. If you change a file +in `[output_base]/external`, rerun `bazel fetch ...` to update the cache. diff --git a/site/docs/getting-started.md b/site/docs/getting-started.md index 1e69dce256..0e91dd3b13 100644 --- a/site/docs/getting-started.md +++ b/site/docs/getting-started.md @@ -1,4 +1,97 @@ --- -layout: redirect -redirect: docs/getting-started.html +layout: documentation +title: Getting Started --- + +# Getting Started with Bazel + +## Setup + +Use the [installation instructions](/docs/install.html) to install a copy of +Bazel on your machine. + +## Using a Workspace + +All Bazel builds take place in a [_workspace_](/docs/build-ref.html#workspaces), +a directory on your filesystem that contains source code for the software you +want to build, as well symbolic links to directories that contain the build +outputs (for example, `bazel-bin` and `bazel-out`). The location of the +workspace directory is not significant, but it must contain a file called +`WORKSPACE` in the top-level directory; an empty file is a valid workspace. +The `WORKSPACE` file can be used to reference +[external dependencies](/docs/external.html) required to build the outputs. +One workspace can be shared among multiple projects if desired. + +```bash +$ touch WORKSPACE +``` + +## Creating a Build File + +To know which targets can be built in your project, Bazel inspects `BUILD` +files. They are written in Bazel's build language which is syntactically +similar to Python. Usually they are just a sequence of declarations of rules. +Each rule specifies its inputs, outputs, and a way to compute the outputs from +the inputs. + +The rule probably most familiar to people who have used `Makefile`s before (as +it is the only rule available there) is the +[genrule](/docs/be/general.html#genrule), which specifies how the output can +be generated by invoking a shell command. + +``` +genrule( + name = "hello", + outs = ["hello_world.txt"], + cmd = "echo Hello World > $@", +) +``` + +The shell command may contain [Make variables](/docs/be/make-variables.html). + +Using the above `BUILD` file, you can ask Bazel to generate the target. + +``` +$ bazel build :hello +. +INFO: Found 1 target... +Target //:hello up-to-date: + bazel-genfiles/hello_world.txt +INFO: Elapsed time: 2.255s, Critical Path: 0.07s +``` + +We note two things. First, targets are normally referred to by their +[label](/docs/build- ref.html#labels), which is specified by the +[name](/docs/be/general.html#genrule.name) attribute of the rule. (Referencing +them by the output file name is also possible, but this is not the preferred +way.) Second, Bazel puts the generated files into a separate directory (the +`bazel-genfiles` directory is actually a symbolic link) so as not to pollute +your source tree. + +Rules may use the output of other rules as input, as in the following +example. Again, the generated sources are referred to by their label. + +``` +genrule( + name = "hello", + outs = ["hello_world.txt"], + cmd = "echo Hello World > $@", +) + +genrule( + name = "double", + srcs = [":hello"], + outs = ["double_hello.txt"], + cmd = "cat $< $< > $@", +) +``` + +Finally, note that, while the [genrule](/docs/be/general.html#genrule) might +seem familiar, it usually is _not_ the best rule to use. It is preferrable to +use one of the specialized [rules](/docs/be/overview.html#rules) for various +languages. + +# Next Steps + +Next, check out the tutorial on building [java](/docs/tutorial/java.html) +or [C++](/docs/tutorial/cpp.html) programs. diff --git a/site/docs/install.md b/site/docs/install.md index 1166fe133c..206226f282 100644 --- a/site/docs/install.md +++ b/site/docs/install.md @@ -1,4 +1,278 @@ --- -layout: redirect -redirect: docs/install.html +layout: documentation +title: Installing Bazel --- + +# Installing Bazel + +Supported platforms: + +* [Ubuntu Linux (Wily 15.10 and Trusty 14.04 LTS)](#ubuntu) +* [Mac OS X](#mac-os-x) +* [Windows (highly experimental)](windows.md) + +For other platforms, you can try to [compile from source](#compiling-from-source). + +Required Java version: + +* Java JDK 8 or later ([JDK 7](#jdk7) is still supported + but deprecated). + +Extras: + +* [Bash completion](#bash) +* [zsh completion](#zsh) + +For more information on using Bazel, see [Getting +started](getting-started.html). + + +## <a name="ubuntu"></a>Ubuntu + +Install Bazel on Ubuntu using one of the following methods: + + * [Using our custom APT repostiory](#install-on-ubuntu) + * [Using binary installer](#install-with-installer-ubuntu) + * [Compiling Bazel from source](#compiling-from-source) + +### <a name="install-on-ubuntu"></a> Using Bazel custom API repository (recommended) + +#### 1. Install JDK 8 + +If you are running **Ubuntu Wily (15.10)**, you can skip this step. +But for **Ubuntu Trusty (14.04 LTS)** users, since OpenJDK 8 is not available on Trusty, please install Oracle JDK 8: + +``` +$ sudo add-apt-repository ppa:webupd8team/java +$ sudo apt-get update +$ sudo apt-get install oracle-java8-installer +``` + +Note: You might need to `sudo apt-get install software-properties-common` if you don't have the `add-apt-repository` command. See [here](http://manpages.ubuntu.com/manpages/wily/man1/add-apt-repository.1.html). + +#### 2. Add Bazel distribution URI as a package source (one time setup) + +``` +$ echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list +$ curl https://storage.googleapis.com/bazel-apt/doc/apt-key.pub.gpg | sudo apt-key add - +``` + +If you want to use the JDK 7, please replace `jdk1.8` with `jdk1.7` and if you want to install the testing version of Bazel, replace `stable` with `testing`. + +#### 3. Update and install Bazel + +`$ sudo apt-get update && sudo apt-get install bazel` + +Once installed, you can upgrade to newer version of Bazel with: + +`$ sudo apt-get upgrade bazel` + +### <a name="install-with-installer-ubuntu"></a>Install with Installer + +We provide binary installers on our +<a href="https://github.com/bazelbuild/bazel/releases">GitHub releases page</a> + +The installer only contains Bazel binary, some additional libraries are required to be installed on the machine to work. + + +#### 1. Install JDK 8 + +**Ubuntu Trusty (14.04 LTS).** OpenJDK 8 is not available on Trusty. To +install Oracle JDK 8: + +``` +$ sudo add-apt-repository ppa:webupd8team/java +$ sudo apt-get update +$ sudo apt-get install oracle-java8-installer +``` + +Note: You might need to `sudo apt-get install software-properties-common` if you don't have the `add-apt-repository` command. See [here](http://manpages.ubuntu.com/manpages/wily/man1/add-apt-repository.1.html). + +**Ubuntu Wily (15.10).** To install OpenJDK 8: + +``` +$ sudo apt-get install openjdk-8-jdk +``` + +#### 2. Install other required packages + +``` +$ sudo apt-get install pkg-config zip g++ zlib1g-dev unzip +``` + +#### 3. Download Bazel + +Download the [Bazel installer](https://github.com/bazelbuild/bazel/releases) for +your operating system. + +#### 4. Run the installer + +Run the installer: + +<pre> +$ chmod +x bazel-<em>version</em>-installer-<em>os</em>.sh +$ ./bazel-<em>version</em>-installer-<em>os</em>.sh --user +</pre> + +The `--user` flag installs Bazel to the `$HOME/bin` directory on your +system and sets the `.bazelrc` path to `$HOME/.bazelrc`. Use the `--help` +command to see additional installation options. + +#### 5. Set up your environment + +If you ran the Bazel installer with the `--user` flag as above, the Bazel +executable is installed in your `$HOME/bin` directory. It's a good idea to add +this directory to your default paths, as follows: + +```bash +$ export PATH="$PATH:$HOME/bin" +``` + +You can also add this command to your `~/.bashrc` file. + + + +## <a name="mac-os-x"></a>Mac OS X + +Install Bazel on Mac OS X using one of the following methods: + + * [Using Homebrew](#install-on-mac-os-x-homebrew) + * [Using binary installer](#install-with-installer-mac-os-x) + * [Compiling Bazel from source](#compiling-from-source) + + +### <a name="install-on-mac-os-x-homebrew"></a>Using Homebrew + +#### 1. Install Homebrew on Mac OS X (one time setup) + +`$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` + +#### 2. Install Bazel Homebrew Package + +`$ brew install bazel` + +Once installed, you can upgrade to newer version of Bazel with: + +`$ brew upgrade bazel` + + +### <a name="install-with-installer-mac-os-x"></a>Install with installer + +We provide binary installers on our +<a href="https://github.com/bazelbuild/bazel/releases">GitHub releases page</a> + +The installer only contains Bazel binary, some additional libraries are required to be installed on the machine to work. + +#### 1. Install JDK 8 + +JDK 8 can be downloaded from +[Oracle's JDK Page](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html). +Look for "Mac OS X x64" under "Java SE Development Kit". This will download a +DMG image with an install wizard. + +#### 2. Install XCode command line tools + +Xcode can be downloaded from the +[Apple Developer Site](https://developer.apple.com/xcode/downloads/), which will +redirect to the App Store. + +For `objc_*` and `ios_*` rule support, you must have Xcode 6.1 or later with +iOS SDK 8.1 installed on your system. + +Once XCode is installed you can trigger signing the license with the following +command: + +``` +$ sudo gcc --version +``` + +#### 3. Download Bazel + +Download the [Bazel installer](https://github.com/bazelbuild/bazel/releases) for +your operating system. + +#### 4. Run the installer + +Run the installer: + +<pre> +$ chmod +x bazel-<em>version</em>-installer-<em>os</em>.sh +$ ./bazel-<em>version</em>-installer-<em>os</em>.sh --user +</pre> + +The `--user` flag installs Bazel to the `$HOME/bin` directory on your +system and sets the `.bazelrc` path to `$HOME/.bazelrc`. Use the `--help` +command to see additional installation options. + +#### 5. Set up your environment + +If you ran the Bazel installer with the `--user` flag as above, the Bazel +executable is installed in your `$HOME/bin` directory. It's a good idea to add +this directory to your default paths, as follows: + +```bash +$ export PATH="$PATH:$HOME/bin" +``` + +You can also add this command to your `~/.bashrc` file. + +## <a name="compiling-from-source"></a>Compiling from source + +If you would like to build Bazel from source, clone the source from GitHub and +run `./compile.sh` to build it: + +``` +$ git clone https://github.com/bazelbuild/bazel.git +$ cd bazel +$ ./compile.sh +``` + +This will create a bazel binary in `bazel-bin/src/bazel`. This binary is +self-contained, so it can be copied to a directory on the PATH (e.g., +`/usr/local/bin`) or used in-place. + +Check our [continuous integration](http://ci.bazel.io) for the current status of +the build. + + +## <a name="jdk7"></a>Using Bazel with JDK 7 (deprecated) + +Bazel version _0.1.0_ runs without any change with JDK 7. However, future +version will stop supporting JDK 7 when our CI cannot build for it anymore. +The installer for JDK 7 for Bazel versions after _0.1.0_ is labeled +<pre> +./bazel-<em>version</em>-jdk7-installer-<em>os</em>.sh +</pre> +If you wish to use JDK 7, follow the same steps as for JDK 8 but with the _jdk7_ installer or using a different APT repository as described [here](#1-add-bazel-distribution-uri-as-a-package-source-one-time-setup). + +## <a name="bash"></a>Getting bash completion + +Bazel comes with a bash completion script. To install it: + +1. Build it with Bazel: `bazel build //scripts:bazel-complete.bash`. +2. Copy the script `bazel-bin/scripts/bazel-complete.bash` to your + completion folder (`/etc/bash_completion.d` directory under Ubuntu). + If you don't have a completion folder, you can copy it wherever suits + you and simply insert `source /path/to/bazel-complete.bash` in your + `~/.bashrc` file (under OS X, put it in your `~/.bash_profile` file). + +## <a name="zsh"></a>Getting zsh completion + +Bazel also comes with a zsh completion script. To install it: + +1. Add this script to a directory on your $fpath: + + ``` + fpath[1,0]=~/.zsh/completion/ + mkdir -p ~/.zsh/completion/ + cp scripts/zsh_completion/_bazel ~/.zsh/completion + ``` + +2. Optionally, add the following to your .zshrc. + + ``` + # This way the completion script does not have to parse Bazel's options + # repeatedly. The directory in cache-path must be created manually. + zstyle ':completion:*' use-cache on + zstyle ':completion:*' cache-path ~/.zsh/cache + ``` diff --git a/site/docs/mobile-install.md b/site/docs/mobile-install.md index b209f182e5..f273871d0d 100644 --- a/site/docs/mobile-install.md +++ b/site/docs/mobile-install.md @@ -1,4 +1,220 @@ --- -layout: redirect -redirect: docs/mobile-install.html +layout: documentation +title: mobile-install --- + +# bazel mobile-install + +<p class="lead">Fast iterative development for Android</p> + +## TL;DR + +To install small changes to an Android app very quickly, do the following: + + 1. Find the `android_binary` rule of the app you want to install. + 2. Disable Proguard by removing the `proguard_specs` attribute. + 3. Set the `multidex` attribute to `native`. + 4. Set the `dex_shards` attribute to `10`. + 5. Connect your device running ART (not Dalvik) over USB and enable USB + debugging on it. + 6. Run `bazel mobile-install :your_target`. App startup will be a little + slower than usual. + 7. Edit the code or Android resources. + 8. Run `bazel mobile-install --incremental :your_target`. + 9. Enjoy not having to wait a lot. + +Some command line options to Bazel that may be useful: + + - `--adb` tells Bazel which adb binary to use + - `--adb_arg` can be used to add extra arguments to the command line of `adb`. + One useful application of this is to select which device you want to install + to if you have multiple devices connected to your workstation: + `bazel mobile-install --adb_arg=-s --adb_arg=<SERIAL> :your_target` + - `--start_app` automatically starts the app + +When in doubt, look at the +[example](https://github.com/bazelbuild/bazel/tree/master/examples/android) +or [contact us](https://groups.google.com/forum/#!forum/bazel-discuss). + +## Introduction + +One of the most important attributes of a developer's toolchain is speed: there +is a world of difference between changing the code and seeing it run within a +second and having to wait minutes, sometimes hours, before you get any feedback +on whether your changes do what you expect them to. + +Unfortunately, the traditional Android toolchain for building an .apk entails +many monolithic, sequential steps and all of these have to be done in order to +build an Android app. At Google, waiting five minutes to build a single-line +change was not unusual on larger projects like Google Maps. + +`bazel mobile-install` makes iterative development for Android much faster by +using a combination of change pruning, work sharding, and clever manipulation of +Android internals, all without changing any of your app's code. + +## Problems with traditional app installation + +We identified the following bottlenecks of building an Android app: + +- Dexing. By default, "dx" is invoked exactly once in the build and it does not +know how to reuse work from previous builds: it dexes every method again, even +though only one method was changed. + +- Uploading data to the device. adb does not use the full bandwidth of a USB 2.0 +connection, and larger apps can take a lot of time to upload. The entire app is +uploaded, even if only small parts have changed, for example, a resource or a +single method, so this can be a major bottleneck. + +- Compilation to native code. Android L introduced ART, a new Android runtime, +which compiles apps ahead-of-time rather than compiling them just-in-time like +Dalvik. This makes apps much faster at the cost of longer installation +time. This is a good tradeoff for users because they typically install an app +once and use it many times, but results in slower development where an app is +installed many times and each version is run at most a handful of times. + +## The approach of `bazel mobile-install` + +`bazel mobile-install `makes the following improvements: + + - Sharded dexing. After building the app's Java code, Bazel shards the class + files into approximately equal-sized parts and invokes `dx` separately on + them. `dx` is not invoked on shards that did not change since the last build. + + - Incremental file transfer. Android resources, .dex files, and native + libraries are removed from the main .apk and are stored in under a separate + mobile-install directory. This makes it possible to update code and Android + resources independently without reinstalling the whole app. Thus, + transferring the files takes less time and only the .dex files that have + changed are recompiled on-device. + + - Loading parts of the app from outside the .apk. A tiny stub application is + put into the .apk that loads Android resources, Java code and native code + from the on-device mobile-install directory, then transfers control to the + actual app. This is all transparent to the app, except in a few corner cases + described below. + +### Sharded Dexing + +Sharded dexing is reasonably straightforward: once the .jar files are built, a +[tool](https://github.com/bazelbuild/bazel/blob/master/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java) +shards them into separate .jar files of approximately equal size, then invokes +`dx` on those that were changed since the previous build. The logic that +determines which shards to dex is not specific to Android: it just uses the +general change pruning algorithm of Bazel. + +The first version of the sharding algorithm simply ordered the .class files +alphabetically, then cut the list up into equal-sized parts, but this proved to +be suboptimal: if a class was added or removed (even a nested or an anonymous +one), it would cause all the classes alphabetically after it to shift by one, +resulting in dexing those shards again. Thus, we settled upon sharding not +individual classes, but Java packages instead. Of course, this still results in +dexing many shards if a new package is added or removed, but that is much less +frequent than adding or removing a single class. + +The number of shards is controlled by the BUILD file (using the +`android_binary.dex_shards` attribute). In an ideal world, Bazel would +automatically determine how many shards are best, but Bazel currently must know +the set of actions (i.e. commands to be executed during the build) before +executing any of them, so it cannot determine the optimal number of shards +because it doesn't know how many Java classes there will eventually be in the +app. Generally speaking, the more shards, the faster the build and the +installation will be, but the slower app startup becomes, because the dynamic +linker has to do more work. The sweet spot is usually between 10 and 50 shards. + +### Incremental File Transfer + +After building the app, the next step is to install it, preferably with the +least effort possible. Installation consists of the following steps: + + 1. Installing the .apk (i.e. `adb install`) + 2. Uploading the .dex files, Android resources, and native libraries to the + mobile-install directory + +There is not much incrementality in the first step: the app is either installed +or not. Bazel currently relies on the user to indicate if it should do this step +through the `--incremental` command line option because it cannot determine in +all cases if it is necessary. + +In the second step, the app's files from the build are compared to an on-device +manifest file that lists which app files are on the device and their +checksums. Any new files are uploaded to the device, any files that have changed +are updated, and any files that have been removed are deleted from the +device. If the manifest is not present, it is assumed that every file needs to +be uploaded. + +Note that it is possible to fool the incremental installation algorithm by +changing a file on the device, but not its checksum in the manifest. We could +have safeguarded against this by computing the checksum of the files on the +device, but this was deemed to be not worth the increase in installation time. + +### The Stub Application + +The stub application is where the magic to load the dexes, native code and +Android resources from the on-device `mobile-install` directory happens. + +The actual loading is implemented by subclassing `BaseDexClassLoader` and is a +reasonably well-documented technique. This happens before any of the app's +classes are loaded, so that any application classes that are in the apk can be +placed in the on-device `mobile-install` directory so that they can be updated +without `adb install`. + +This needs to happen before any of the +classes of the app are loaded, so that no application class needs to be in the +.apk which would mean that changes to those classes would require a full +re-install. + +This is accomplished by replacing the `Application` class specified in +`AndroidManifest.xml` with the +[stub application](https://github.com/bazelbuild/bazel/blob/master/src/tools/android/java/com/google/devtools/build/android/incrementaldeployment/StubApplication.java). This +takes control when the app is started, and tweaks the class loader and the +resource manager appropriately at the earliest moment (its constructor) using +Java reflection on the internals of the Android framework. + +Another thing the stub application does is to copy the native libraries +installed by mobile-install to another location. This is necessary because the +dynamic linker needs the `X` bit to be set on the files, which is not possible to +do for any location accessible by a non-root `adb`. + +Once all these things are done, the stub application then instantiates the +actual `Application` class, changing all references to itself to the actual +application within the Android framework. + +## Results + +### Performance + +In general, `bazel mobile-install` results in a 4x to 10x speedup of building +and installing large apps after a small change. We computed the following +numbers for a few Google products: + +<img src="/assets/mobile-install-performance.svg"/> + +This, of course, depends on the nature of the change: recompilation after +changing a base library takes more time. + +### Limitations + +The tricks the stub application plays don't work in every case. We have +identified the following cases where it does not work as expected: + + - When `Context` is cast to the `Application` class in + `ContentProvider#onCreate()`. This method is called during application + startup before we have a chance to replace the instance of the `Application` + class, therefore, `ContentProvider` will still reference the stub application + instead of the real one. Arguably, this is not a bug since you are not + supposed to downcast `Context` like this, but this seems to happen in a few + apps at Google. + + - Resources installed by `bazel mobile-install` are only available from within + the app. If resources are accessed by other apps via + `PackageManager#getApplicationResources()`, these resources will be from the + last non-incremental install. + + - Devices that aren't running ART. While the stub application works well on + Froyo and later, Dalvik has a bug that makes it think that the app is + incorrect if its code is distributed over multiple .dex files in certain + cases, for example, when Java annotations are used in a + [specific](https://code.google.com/p/android/issues/detail?id=78144) way. As + long as your app doesn't tickle these bugs, it should work with Dalvik, too + (note, however, that support for old Android versions isn't exactly our + focus) diff --git a/site/docs/output_directories.md b/site/docs/output_directories.md index aa176bb43c..9b5f391cf7 100644 --- a/site/docs/output_directories.md +++ b/site/docs/output_directories.md @@ -1,4 +1,133 @@ --- -layout: redirect -redirect: docs/output_directories.html +layout: documentation +title: Output Directory Layout --- + +# Output Directory Layout + +## Requirements + +Requirements for an output directory layout: + +* Don't collide if multiple users are building on the same box. +* Support building in multiple workspaces at the same time. +* Support building for multiple target configurations in the same workspace. +* Don't collide with any other tools. +* Be easy to access. +* Be easy to clean, even selectively. +* Is unambiguous, even if the user relies on symbolic links when changing into + his/her client directory. +* All the build state per user should be underneath one directory ("I'd like to + clean all the .o files from all my clients.") + +## Documentation of the current Bazel output directory layout + +The solution that's currently implemented: + +* Bazel must be invoked from a directory containing a WORKSPACE file. It reports + an error if it is not. We call this the _workspace directory_. +* The _outputRoot_ directory is ~/.cache/bazel. (Unless `$TEST_TMPDIR` is + set, as in a test of bazel itself, in which case this directory is used + instead.) +* We stick the Bazel user's build state beneath `outputRoot/_bazel_$USER`. This + is called the _outputUserRoot_ directory. +* Beneath the `outputUserRoot` directory, we create an `installBase` directory + whose name is "install" plus the MD5 hash of the Bazel installation manifest. +* Beneath the `outputUserRoot` directory, we also create an `outputBase` + directory whose name is the MD5 hash of the path name of the workspace + directory. So, for example, if Bazel is running in the workspace directory + `/home/user/src/my-project` (or in a directory symlinked to that one), then we + create an output base directory called: + `/home/.cache/bazel/_bazel_user/7ffd56a6e4cb724ea575aba15733d113`. +* Users can use Bazel's `--output_base` startup option to override the default + output base directory. For example, + `bazel --output_base=/tmp/bazel/output build x/y:z`. +* Users can also use Bazel's `--output_user_root` startup option to override the + default install base and output base directories. For example: + `bazel --output_user_root=/tmp/bazel build x/y:z`. + +We put symlinks "bazel-<workspace-name>" and "bazel-out", as well as +"bazel-bin", "bazel-genfiles", and "bazel-includes" in the workspace directory; +these symlinks points to some directories inside a target-specific directory +inside the output directory. These symlinks are only for the user's convenience, +as Bazel itself does not use them. Also, we only do this if the workspace +directory is writable. The names of the "bazel-bin", "bazel-genfiles", and +"bazel-include" symlinks are affected by the `--symlink_prefix` option to bazel, +but "bazel-<workspace-name>" and "bazel-out" are not. + +## Bazel internals: Directory layout + +The directories are laid out as follows: + +<pre> +<workspace-name>/ <== The workspace directory + bazel-my-project => <...my-project> <== Symlink to execRoot + bazel-out => <...bin> <== Convenience symlink to outputPath + bazel-bin => <...bin> <== Convenience symlink to most recent written bin dir $(BINDIR) + bazel-genfiles => <...genfiles> <== Convenience symlink to most recent written genfiles dir $(GENDIR) + +/home/user/.cache/bazel/ <== Root for all Bazel output on a machine: outputRoot + _bazel_$USER/ <== Top level directory for a given user depends on the user name: + outputUserRoot + install/ + fba9a2c87ee9589d72889caf082f1029/ <== Hash of the Bazel install manifest: installBase + _embedded_binaries/ <== Contains binaries and scripts unpacked from the data section of + the bazel executable on first run (e.g. helper scripts and the + main Java file BazelServer_deploy.jar) + 7ffd56a6e4cb724ea575aba15733d113/ <== Hash of the client's workspace directory (e.g. + /home/some-user/src/my-project): outputBase + action_cache/ <== Action cache directory hierarchy + This contains the persistent record of the file metadata + (timestamps, and perhaps eventually also MD5 sums) used by the + FilesystemValueChecker. + action_outs/ <== Action output directory. This contains a file with the + stdout/stderr for every action from the most recent bazel run + that produced output. + command.log <== A copy of the stdout/stderr output from the most recent bazel + command. + external/ <== The directory that remote repositories are downloaded/symlinked + into. + server/ <== The Bazel server puts all server-related files (such as socket + file, logs, etc) here. + server.socket <== Socket file for the server. + server.log <== Server logs. + <workspace-name>/ <== Working tree for the Bazel build & root of symlink forest: execRoot + _bin/ <== Helper tools are linked from or copied to here. + + bazel-out/ <== All actual output of the build is under here: outputPath + local_linux-fastbuild/ <== one subdirectory per unique target BuildConfiguration instance; + this is currently encoded + bin/ <== Bazel outputs binaries for target configuration here: $(BINDIR) + foo/bar/_objs/baz/ <== Object files for a cc_* rule named //foo/bar:baz + foo/bar/baz1.o <== Object files from source //foo/bar:baz1.cc + other_package/other.o <== Object files from source //other_package:other.cc + foo/bar/baz <== foo/bar/baz might be the artifact generated by a cc_binary named + //foo/bar:baz + foo/bar/baz.runfiles/ <== The runfiles symlink farm for the //foo/bar:baz executable. + MANIFEST + <workspace-name>/ + ... + genfiles/ <== Bazel puts generated source for the target configuration here: + $(GENDIR) + foo/bar.h e.g. foo/bar.h might be a headerfile generated by //foo:bargen + testlogs/ <== Bazel internal test runner puts test log files here + foo/bartest.log e.g. foo/bar.log might be an output of the //foo:bartest test with + foo/bartest.status foo/bartest.status containing exit status of the test (e.g. + PASSED or FAILED (Exit 1), etc) + include/ <== a tree with include symlinks, generated as needed. The + bazel-include symlinks point to here. This is used for + linkstamp stuff, etc. + host/ <== BuildConfiguration for build host (user's workstation), for + building prerequisite tools, that will be used in later stages + of the build (ex: Protocol Compiler) + <packages>/ <== Packages referenced in the build appear as if under a regular workspace +</pre> + +The layout of the *.runfiles directories is documented in more detail in the places pointed to by RunfilesSupport. + +## `bazel clean` + +`bazel clean` does an `rm -rf` on the `outputPath` and the `action_cache` +directory. It also removes the workspace symlinks. The `--partial` option to +`bazel clean` will clean a configuration-specific `outputDir`, and the +`--expunge` option will clean the entire outputBase. diff --git a/site/versions/master/docs/query-how-to.html b/site/docs/query-how-to.html index 8920843812..8920843812 100644 --- a/site/versions/master/docs/query-how-to.html +++ b/site/docs/query-how-to.html diff --git a/site/docs/query-how-to.md b/site/docs/query-how-to.md deleted file mode 100644 index 26ba74e3c9..0000000000 --- a/site/docs/query-how-to.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -layout: redirect -redirect: docs/query-how-to.html ---- diff --git a/site/versions/master/docs/query.html b/site/docs/query.html index a5068c8eef..a5068c8eef 100644 --- a/site/versions/master/docs/query.html +++ b/site/docs/query.html diff --git a/site/docs/query.md b/site/docs/query.md deleted file mode 100644 index 7a42ae7ea5..0000000000 --- a/site/docs/query.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -layout: redirect -redirect: docs/query.html ---- diff --git a/site/docs/skyframe.md b/site/docs/skyframe.md index 3b8a1b1b74..ae3dc53aee 100644 --- a/site/docs/skyframe.md +++ b/site/docs/skyframe.md @@ -1,4 +1,189 @@ --- -layout: redirect -redirect: docs/skyframe.html +layout: contribute +title: Skyframe --- + +# Skyframe + +<p class="lead">The parallel evaluation and incrementality model of Bazel</p> + +## Data model + +The data model consists of the following items: + + - `SkyValue`. Also called nodes. `SkyValues` are immutable objects that contain all the data built + over the course of the build and the inputs of the build. Examples are: input files, output + files, targets and configured targets. + - `SkyKey`. A short immutable name to reference a `SkyValue`, for example, `FILECONTENTS:/tmp/foo` + or `PACKAGE://foo`. + - `SkyFunction`. Builds nodes based on their keys and dependent nodes. + - Node graph. A data structure containing the dependency relationship between nodes. + - `Skyframe`. Code name for the incremental evaluation framework Bazel is based on. + + +## Evaluation + +A build consists of evaluating the node that represents the build request (this is the state we are +striving for, but there is a lot of legacy code in the way). First its `SkyFunction` is found and +called with the key of the top-level `SkyKey`. The function then requests the evaluation of the +nodes it needs to evaluate the top-level node, which in turn result in other function invocations, +and so on, until the leaf nodes are reached (which are usually nodes representing input files in +the file system). Finally, we end up with the value of the top-level `SkyValue`, some side effects +(e.g. output files in the file system) and a directed acyclic graph of the dependencies between the +nodes that were involved in the build. + +A `SkyFunction` can request `SkyKeys` in multiple passes if it cannot tell in advance all of the +nodes it needs to do its job. A simple example is evaluating an input file node that turns out to +be a symlink: the function tries to read the file, realizes that it's a symlink, and thus fetches +the file system node representing the target of the symlink. But that itself can be a symlink, in +which case the original function will need to fetch its target, too. + +The functions are represented in the code by the interface `SkyFunction` and the services +provided to it by an interface called `SkyFunction.Environment`. These are the things functions can +do: + + - Request the evaluation of another node by way of calling `env.getValue`. If the node is + available, its value is returned, otherwise, `null` is returned and the function itself is + expected to return `null`. In the latter case, the dependent node is evaluated, and then the + original node builder is invoked again, but this time the same `env.getValue` call will return a + non-`null` value. + - Request the evaluation of multiple other nodes by calling `env.getValues()`. This does + essentially the same, except that the dependent nodes are evaluated in parallel. + - Do computation during their invocation + - Have side effects, for example, writing files to the file system. Care needs to be taken that two + different functions do not step on each other's toes. In general, write side effects (where + data flows outwards from Bazel) are okay, read side effects (where data flows inwards into Bazel + without a registered dependency) are not, because they are an unregistered dependency and as + such, can cause incorrect incremental builds. + +`SkyFunction` implementations should not access data in any other way than requesting dependencies +(e.g. by directly reading the file system), because that results in Bazel not registering the data +dependency on the file that was read, thus resulting in incorrect incremental builds. + +Once a function has enough data to do its job, it should return a non-`null` value indicating +completion. + +This evaluation strategy has a number of benefits: + + - Hermeticity. If functions only request input data by way of depending on other nodes, Bazel + can guarantee that if the input state is the same, the same data is returned. If all sky + functions are deterministic, this means that the whole build will also be deterministic. + - Correct and perfect incrementality. If all the input data of all functions is recorded, Bazel + can invalidate only the exact set of nodes that need to be invalidated when the input data + changes. + - Parallelism. Since functions can only interact with each other by way of requesting + dependencies, functions that do not depend on each other can be run in parallel and Bazel can + guarantee that the result is the same as if they were run sequentially. + +## Incrementality + +Since functions can only access input data by depending on other nodes, Bazel can build up a +complete data flow graph from the input files to the output files, and use this information to only +rebuild those nodes that actually need to be rebuilt: the reverse transitive closure of the set of +changed input files. + +In particular, two possible incrementality strategies exist: the bottom-up one and the top-down one. +Which one is optimal depends on how the dependency graph looks like. + + - During bottom-up invalidation, after a graph is built and the set of changed inputs is known, + all the nodes are invalidated that transitively depend on changed files. This is optimal + if we know that the same top-level node will be built again. + Note that bottom-up invalidation requires running `stat()` on all input files of the previous + build to determine if they were changed. This can be improved by using `inotify` or a similar + mechanism to learn about changed files. + + - During top-down invalidation, the transitive closure of the top-level node is checked and only + those nodes are kept whose transitive closure is clean. This is better if we know that the + current node graph is large, but we only need a small subset of it in the next build: bottom-up + invalidation would invalidate the larger graph of the first build, unlike top-down invalidation, + which just walks the small graph of second build. + +We currently only do bottom-up invalidation. + +To get further incrementality, we use _change pruning_: if a node is invalidated, but upon rebuild, +it is discovered that its new value is the same as its old value, the nodes that were invalidated +due to a change in this node are "resurrected". + +This is useful, for example, if one changes a comment in a C++ file: then the `.o` file generated +from it will be the same, thus, we don't need to call the linker again. + +## Incremental Linking / Compilation + +The main limitation of this model is that the invalidation of a node is an all-or-nothing affair: +when a dependency changes, the dependent node is always rebuilt from scratch, even if a better +algorithm would exist that would mutate the old value of the node based on the changes. A few +examples where this would be useful: + + - Incremental linking + - When a single `.class` file changes in a `.jar`, we could theoretically modify the `.jar` file + instead of building it from scratch again. + +The reason why Bazel currently does not support these things in a principled way (we have some +measure of support for incremental linking, but it's not implemented within Skyframe) is twofold: +we only had limited performance gains and it was hard to guarantee that the result of the mutation +is the same as that of a clean rebuild would be, and Google values builds that are bit-for-bit +repeatable. + +Until now, we could always achieve good enough performance by simply decomposing an expensive build +step and achieving partial re-evaluation that way: it splits all the classes in an app into +multiple groups and does dexing on them separately. This way, if classes in a group do not change, +the dexing does not have to be redone. + +## Restarting SkyFunctions + +Another inefficiency is that, currently, if a `SkyFunction` implementation cannot complete its job +because one of its dependencies is missing, it needs to be completely restarted instead of resuming +where it left off. This is currently not a big problem because we usually learn all the +dependencies after a small amount of work. The only exceptions are package loading and execution of +actions; these are both external processes that are expensive to restart. We allow package loading +to proceed fully, store the loaded package away, record the dependencies in the graph, and on +re-execution of the function return the already loaded package. I.e., we allow the function to keep +state between executions. + +If this turns out to be a significant performance or code health problem, there are alternative ways +to add a more principled mechanism to keep state between executions: + + - Splitting each node into multiple ones so that each smaller node only has to do one round of + dependency discovery (effectively continuation passing); this requires explicit code. + - By reimplementing Skyframe on some sort of lightweight thread infrastructure (e.g. + [Quasar](http://docs.paralleluniverse.co/quasar/)) so that function execution can be suspended + and resumed without a large performance hit and without requiring this to be explicit in the + code. + - By maintaining state for each `SkyFunction` instance between restarts (this is the workaround we + are using for package loading, but is not implemented as a first-class feature of the evaluation + framework). + +## Mapping to Bazel concepts + +This is a rough overview of some of the `SkyFunction` implementations Bazel uses to perform a build: + + - **FileStateValue**. The result of an `lstat()`. For existent files, we also compute additional + information in order to detect changes to the file. This is the lowest level node in the Skyframe + graph and has no dependencies. + - **FileValue**. Used by anything that cares about the actual contents and/or resolved path of a + file. Depends on the corresponding `FileStateValue` and any symlinks that need to be resolved + (e.g. the `FileValue` for `a/b` needs the resolved path of `a` and the resolved path of `a/b`). + The distinction between `FileStateValue` is important because in some cases (for example, + evaluating file system globs (e.g. `srcs=glob(["*/*.java"])`) the contents of the file are not + actually needed. + - **DirectoryListingValue**. Essentially the result of `readdir()`. Depends on the associated + `FileValue` associated with the directory. + - **PackageValue**. Represents the parsed version of a BUILD file. Depends on the `FileValue` of + the associated `BUILD` file, and also transitively on any `DirectoryListingValue` that is used + to resolve the globs in the package (the data structure representing the contents of a `BUILD` + file internally) + - **ConfiguredTargetValue**. Represents a configured target, which is a tuple of the set of actions + generated during the analysis of a target and information provided to configured targets that + depend on this one. Depends on the `PackageValue` the corresponding target is in, the + `ConfiguredTargetValues` of direct dependencies, and a special node representing the build + configuration. + - **ArtifactValue**. Represents a file in the build, be it a source or an output artifacts + (artifacts are almost equivalent to files, and are used to refer to files during the actual + execution of build steps). For source files, it depends on the `FileValue` of the associated + node, for output artifacts, it depends on the `ActionExecutionValue` of whatever action generates + the artifact. + - **ActionExecutionValue**. Represents the execution of an action. Depends on the `ArtifactValues` + of its input files. The action it executes is currently contained within its sky key, which is + contrary to the concept that sky keys should be small. We are working on solving this + discrepancy (note that `ActionExecutionValue` and `ArtifactValue` are unused if we do not run the + execution phase on Skyframe). diff --git a/site/docs/skylark/aspects.md b/site/docs/skylark/aspects.md index ba524f5cf6..6bafa20b65 100644 --- a/site/docs/skylark/aspects.md +++ b/site/docs/skylark/aspects.md @@ -1,4 +1,191 @@ --- -layout: redirect -redirect: docs/skylark/aspects.html +layout: documentation +title: Aspects --- +# Aspects + +**Status: Experimental**. We may make breaking changes to the API, but we will + help you update your code. + +Aspects allow augmenting build dependency graphs with additional information +and actions. Some typical scenarios when aspects can be useful: + +* IDEs that integrate Bazel can use aspects to collect information about the + project +* Code generation tools can leverage aspects to execute on their inputs in + "target-agnostic" manner. As an example, BUILD files can specify a hierarchy + of [protobuf](https://developers.google.com/protocol-buffers/) library + definitions, and language-specific rules can use aspects to attach + actions generating protobuf support code for a particular language + +## Aspect basics + +Bazel BUILD files provide a description of a project’s source code: what source +files are part of the project, what artifacts (_targets_) should be built from +those files, what the dependencies between those files are, etc. Bazel uses +this information to perform a build, that is, it figures out the set of actions +needed to produce the artifacts (such as running compiler or linker) and +executes those actions. Bazel accomplishes this by constructing a _dependency +graph_ between targets and visiting this graph to collect those actions. + +Consider the following BUILD file: + +```python +java_library(name = 'W', ...) +java_library(name = 'Y', deps = [':W'], ...) +java_library(name = 'Z', deps = [':W'], ...) +java_library(name = 'Q', ...) +java_library(name = 'T', deps = [':Q'], ...) +java_library(name = 'X', deps = [':Y',':Z'], runtime_deps = [':T'], ...) +``` + +This BUILD file defines a dependency graph shown in Fig 1. + +<img src="build-graph.png" alt="Build Graph" width="250px" /> + +Bazel analyzes this dependency graph by calling implementations of +[rules](rules.md) (in this case "java_library" starting from leaves of +the dependency graph). These implementations generate actions that build +artifacts (such as Jar files), and provide information (such as locations +and names of those artifacts) to their dependencies in providers that +they return. Their dependencies can access those providers through the +[Target object](lib/Target.html). In other words, every target +defined in the BUILD file generates a node in the dependency graph, and +the appropriate rule implementation function is called for every node. + +Aspects are similar to rules in that they have an implementation function that +generates actions and returns providers. However, their power comes from +the way the dependency graph is built for them. An aspect has an implementation +and a list of all attributes it propagates along. Consider an aspect A that +propagates along attributes named "deps". This aspect can be applied to +a target X, yielding an aspect application node A(X). During its application, +aspect A is applied recursively to all targets that X refers to in its "deps" +attribute (all attributes in A's propagation list). Thus a single act of +applying aspect A to a target X yields a "shadow graph" of the original +dependency graph of targets (see Fig.2). + +![Build Graph with Aspect](build-graph-aspects.png) + +The only edges that are shadowed are the edges along the attributes in +the propagation set, thus the `runtime_deps` edge is not shadowed in this +example. An aspect implementation function is then invoked on all nodes in +the shadow graph similar to how rule implementations are invoked on the nodes +of the original graph. + +## Defining aspects + +Aspect definitions are similiar to rule definitions. Let's take a look at +the example: + +```python +metal_proto_aspect = aspect(implementation = _metal_proto_aspect_impl, + attr_aspects = ["deps"], + attrs = { + "_protoc" : attr.label( + default=Label("//tools:metal_protoc"), + executable = True + ) + } +) +``` + +Just like a rule, an aspect has an implementation function. ``attr_aspects`` +specify the aspect's propagation set: a list of attributes of rules along which +the aspect propagates. + +``attrs`` defines a set of attributes for aspects. Aspects are only allowed +to have private attributes of types ``label`` or ``label_list``. Attributes +can be used to specify dependencies on tools or libraries that are needed +for actions generated by aspects. + +### Implementation functions + +Aspect implementation functions are similiar to the rule implementation +functions. They return [providers](rules.md#providers), can generate +[actions](rules.md#actions) and take two arguments: + +* `target`: the target the aspect is being applied to. +* [`ctx`](lib/ctx.html): `ctx` object that can be used to access attributes and + generate outputs and actions. + +Example: + +```python +def _metal_proto_aspect_impl(target, ctx): + # For every `src` in proto_library, generate an output file + proto_sources = [f for src in ctx.rule.attr.src + for f in src.files] + outputs = [ctx.new_file(f.short_path + ".metal") + for f in proto_sources] + ctx.action( + executable = ctx.executable._protoc, + argument = ... + inputs = proto_sources + outputs = outputs) + transitive_outputs = set(outputs) + for dep in ctx.attr.deps: + transitive_outputs = transitive_outputs | dep.metal_proto.transitive_outputs + return struct( + metal_proto = struct(direct_outputs = outputs, + transitive_outputs = transitive_outputs)) +``` + +The implementation function can access the attributes of the target rule via +[`ctx.rule.attr`](lib/ctx.html#rule). It can examine providers that are +provided by the target to which it is applied (via the `target` argument). + +Just like a rule implementation function, an aspect implementation function +returns a struct of providers that are accessible to its dependencies. + +* The set of providers for an aspect application A(X) is the union of providers + that come from the implementation of a rule for target X and from + the implementation of aspect A. It is an error if a target and an aspect that + is applied to it each provide a provider with the same name. +* For the aspect implementation, the values of attributes along which + the aspect is propagated (from the `attr_aspect` list) are replaced with + the results of an application of the aspect to them. For example, if target + X has Y and Z in its deps, `ctx.rule.attr.deps` for A(X) will be [A(Y), A(Z)]. + In the `_metal_proto_aspect_impl` function above, ctx.rule.attr.deps will be + Target objects that are the results of applying the aspect to the 'deps' + of the original target to which the aspect has been applied. + That allows the aspect to examine `metal_proto` provider on them. + + +## Applying aspects + +Aspect propagation can be initiated either from a rule or from the command line. + +### Applying aspects to rule attributes + +Rules can specify that they want to apply aspects to their dependencies. +The aspects to be applied to a particular attribute can be specified +using the `aspects` parameter to `attr.label` or `attr.label_list` function: + +```python +metal_proto_library = rule(implementation = _impl, + attrs = { + 'proto_deps' : attr.label_list(aspects = [metal_proto_aspect]), + }, +) +``` + +If a rule specifies an aspect on its attributes, the values of that attribute +will be replaced by the result of aspect application to them (similar to +what happens during aspect propagation). Thus implementation of +`metal_proto_library` will have access to `metal_proto` providers +on the target objects representing its `proto_deps` attribute values. + +### Applying aspects from command line. + +Aspects can also be applied on the command line, using the `--aspects` flag: + + +``` +bazel build //java/com/company/example:main \ + --aspects path/to/extension.bzl%metal_proto_aspect +``` + +`--aspects` flag takes one argument, which is a specification of the aspect in +the format `<extension file path>%<aspect top-level name>`. + + diff --git a/site/docs/skylark/build-style.md b/site/docs/skylark/build-style.md index 5a47a30eda..3cee2fc26e 100644 --- a/site/docs/skylark/build-style.md +++ b/site/docs/skylark/build-style.md @@ -1,4 +1,110 @@ ---- -layout: redirect -redirect: docs/skylark/build-style.html ---- + +# BUILD file style guide + +In `BUILD` files, we take the same approach as in Go: We let the machine take care +of most formatting issues. +[Buildifier](https://github.com/bazelbuild/buildifier) is a tool that parses and +emits the source code in a standard style. Every `BUILD` file is therefore +formatted in the same automated way, which makes formatting a non-issue during +code reviews. It also makes it easier for tools to understand, edit, and +generate `BUILD` files. + +`BUILD` file formatting must match the output of `buildifier`. + +## Formatting example + +```python +package(default_visibility = ["//visibility:public"]) + +py_test( + name = "foo_test", + srcs = glob(["*.py"]), + data = [ + "//data/production/foo:startfoo", + "//foo", + "//third_party/java/jdk:jdk-k8", + ], + flaky = 1, + deps = [ + ":check_bar_lib", + ":foo_data_check", + ":pick_foo_port", + "//pyglib", + "//testing/pybase", + ], +) +``` + +## File structure + +We recommend to use the following order (every element is optional): + + * Package description (a comment) + + * All `load()` statements + + * The `package()` function. + + * Calls to rules and macros + +Buildifier makes a distinction between a standalone comment and a comment +attached to an element. If a comment is not attached to a specific element, use +an empty line after it. The distinction is important when doing automated +changes (e.g. to decide if we keep or remove a comment when we delete a rule). + +```python +# Standalone comment (e.g. to make a section in a file) + +# Comment for the cc_library below +cc_library(name = "cc") +``` + +## Conventions + + * Use uppercase and underscores to declare constants (e.g. `GLOBAL_CONSTANT`), + use lowercase and underscores to declare variables (e.g. `my_variable`). + + * Labels should be canonicalized. Use `//foo/bar` instead of `//foo/bar:bar`. + Use `:bar` if it is defined in the same package. *Rationale*: It makes clear + if a label is local to a package. Sorting a list of labels is messy if all + labels do not use the same conventions. + + * Labels should never be split, even if they are longer than 79 characters. + Labels should be string literals whenever possible. Rationale: It makes + find and replace easy. It also improves readability. + + * The value of the name attribute should be a literal constant string (except + in macros). *Rationale*: External tools use the name attribute to refer a + rule. They need to find rules without having to interpret code. + +## Differences with Python style guide + +Although compatibility with +[Python style guide](https://www.python.org/dev/peps/pep-0008/) is a goal, there +are a few differences: + + * No strict line length limit. Long comments and long strings are often split + to 79 columns, but it is not required. It should not be enforced in code + reviews or presubmit scripts. *Rationale*: Labels can be long and exceed this + limit. It is common for `BUILD` files to be generated or edited by tools, which + does not go well with a line length limit. + + * Implicit string concatenation is not supported. Use the `+` operator. + *Rationale*: `BUILD` files contain many string lists. It is easy to forget a + comma, which leads to a complete different result. This has created many bugs + in the past. See also this discussion. + + * Use spaces around the `=` sign for keywords arguments in rules. *Rationale*: + Named arguments are much more frequent than in Python and are always on a + separate line. Spaces improve readability. This convention has been around + for a long time, and we don't think it is worth modifying all existing + `BUILD` files. + + * By default, use double quotation marks for strings. *Rationale*: This is not + specified in the Python style guide, but it recommends consistency. So we + decided to use only double-quoted strings. Many languages use double-quotes + for string literals. + + * Use a single blank line between two top-level definitions. *Rationale*: The + structure of a `BUILD` file is not like a typical Python file. It has only + top-level statements. Using a single-blank line makes `BUILD` files shorter. diff --git a/site/docs/skylark/bzl-style.md b/site/docs/skylark/bzl-style.md index c17600796b..a88dfcad76 100644 --- a/site/docs/skylark/bzl-style.md +++ b/site/docs/skylark/bzl-style.md @@ -1,4 +1,48 @@ ---- -layout: redirect -redirect: docs/skylark/bzl-style.html ---- + +# .bzl file style guide + +## Style + +* When in doubt, follow the + [Python style guide](https://www.python.org/dev/peps/pep-0008/). + +* Code should be documented using + [docstrings](https://www.python.org/dev/peps/pep-0257/). Use a docstring at + the top of the file, and a docstring for each public function. + +* Variables and function names use lowercase with words separated by underscores + (`[a-z][a-z0-9_]*`), e.g. `cc_library`. Top-level private values start with + one underscore. Bazel enforces that private values cannot be used from other + files. + +* As in BUILD files, there is no strict line length limit as labels can be long. + When possible, try to use at most 79 characters per line. + +* In keyword arguments, spaces around the equal sign are optional. In general, + we follow the BUILD file convention when calling macros and native rules, and + the Python convention for other functions, e.g. + +```python +def fct(name, srcs): + filtered_srcs = my_filter(source=srcs) + native.cc_library( + name = name, + srcs = filtered_srcs, + ) +``` + +## Macros + +A [macro](macros.md) is a function which instantiates one or many rules during +the loading phase. + +* Macros must accept a name attribute and each invocation should specify a name. + The generated name attribute of rules should include the name attribute as a + prefix. For example, `my_macro(name = "foo")` can generate a rule `foo` and a + rule `foo_gen`. *Rationale*: Users should be able to find easily which macro + generated a rule. Also, automated refactoring tools need a way to identify a + specific rule to edit. + +* When calling a macro, use only keyword arguments. *Rationale*: This is for + consistency with rules, it greatly improves readability. + diff --git a/site/docs/skylark/concepts.md b/site/docs/skylark/concepts.md index a1e5028f15..7388ab7e87 100644 --- a/site/docs/skylark/concepts.md +++ b/site/docs/skylark/concepts.md @@ -1,4 +1,190 @@ --- -layout: redirect -redirect: docs/skylark/concepts.html +layout: documentation +title: Extensions - Overview --- +# Overview + +## Loading an extension + +Extensions are files with the `.bzl` extension. Use the `load` statement to +import a symbol from an extension. + +```python +load("//build_tools/rules:maprule.bzl", "maprule") +``` + +This code will load the file `build_tools/rules/maprule.bzl` and add the +`maprule` symbol to the environment. This can be used to load new rules, +functions or constants (e.g. a string, a list, etc.). Multiple symbols can be +imported by using additional arguments to the call to `load`. Arguments must +be string literals (no variable) and `load` statements must appear at +top-level, i.e. they cannot be in a function body. + +`load` also supports aliases, i.e. you can assign different names to the +imported symbols. + +```python +load("//build_tools/rules:maprule.bzl", maprule_alias = "maprule") +``` + +You define multiple aliases within one `load` statement. Moreover, the argument +list can contain both aliases and regular symbol names. The following example is +perfectly legal (please note when to use quotation marks). + +```python +load("/path/to:my_rules.bzl", "some_rule", nice_alias = "some_other_rule") +``` + +Symbols starting with `_` are private and cannot be loaded from other files. +Visibility doesn't affect loading: you don't need to use `exports_files` to make +a `.bzl` file visible. + +## Macros and rules + +A [macro](macros.md) is a function that instantiates rules. The +function is evaluated as soon as the BUILD file is read. Bazel has little +information about macros: if your macro generates a `genrule`, Bazel will behave +as if you wrote the `genrule`. As a result, `bazel query` will only list the +generated genrule. + +A [rule](rules.md) is more powerful than a macro, as it can access +Bazel internals and have full control over what is going on. It may for example +pass information to other rules. + +If a macro becomes complex, it is often a good idea to make it a rule. + +## Evaluation model + +A build consists of three phases. + +* **Loading phase**. First, we load and evaluate all extensions and all BUILD + files that are needed for the build. The execution of the BUILD files simply + instantiates rules. This is where macros are evaluated. + +* **Analysis phase**. The code of the rules is executed (their `implementation` + function), and actions are instantiated. An action describes how to generate + a set of outputs from a set of inputs, e.g. "run gcc on hello.c and get + hello.o". It is important to note that we have to list explicitly which + files will be generated before executing the actual commands. + +* **Execution phase**. Actions are executed, when at least one of their outputs is + required. If a file is missing or if a command fails to generate one output, + the build fails. Tests are run during this phase, as they are actions. + +Bazel uses parallelism to read, parse and evaluate the `.bzl` files and `BUILD` +files. A file is read at most once per build and the result of the evaluation is +cached and reused. A file is evaluated only once all its dependencies (`load()` +statements) have been resolved. By design, loading a `.bzl` file has no visible +side-effect, it only defines values and functions. + +## Syntax + +The extension language (sometimes referred as "Skylark") is a superset of the +[Core Build Language](/docs/build-ref.html#core_build_language) +and its syntax is a subset of Python. +It is designed to be simple, thread-safe and integrated with the +BUILD language. It is not a general-purpose language and most Python +features are not included. + +The following constructs have been added to the Core Build Language: `if` +statements, `for` loops, and function definitions. They behave like in Python. +Here is an example to show the syntax: + +```python +def fizz_buzz(n): + """Print Fizz Buzz numbers from 1 to n.""" + for i in range(1, n + 1): + s = "" + if i % 3 == 0: + s += "Fizz" + if i % 5 == 0: + s += "Buzz" + print(s if s else i) + +fizz_buzz(20) +``` + +## Mutability + +Because evaluation of BUILD and .bzl files is performed in parallel, there are +some restrictions in order to guarantee thread-safety and determinism. Two +mutable data structures are available: [lists](lib/list.html) and +[dicts](lib/dict.html). Unlike in Python, [sets](lib/set.html) are not mutable. + +In a build, there are many "evaluation contexts": each `.bzl` file and each +`BUILD` file is loaded in a different context. Each rule is also analyzed in a +separate context. We allow side-effects (e.g. appending a value to a list or +deleting an entry in a dictionary) only on objects created during the current +evaluation context. + +For example, here is the content of the file `foo.bzl`: + +```python +var = [] + +def fct(): + var.append(5) + +fct() +``` + +The variable `var` is created when `foo.bzl` is loaded. `fct()` is called during +the same context, so it is safe. At the end of the evaluation, the definition +`var = [5]` is exported. Any other file can load it, and it is possible that +multiple files will load it at the same time. For this reason, the following +code is not legal: + +```python +load(":foo.bzl", "var", "fct") + +var.append(6) # not allowed + +fct() # not allowed +``` + +Since the call to `fct()` attempts to mutate the shared variable `var`, it will +fail. `fct()` can only be called during the evaluation of `foo.bzl`. It cannot +be called from another file. It is also forbidden to call it during the analysis +phase (i.e. when a custom rule is analyzed). + +## Differences with Python + +In addition to the mutability restrictions, there are also differences with +Python: + +* All global values are constant (they cannot be reassigned). + +* `x += y` is syntactic sugar for `x = x + y`. Even if `x` and `y` are lists, + dicts or sets, the original value is not mutated, so references to `x` + that were assigned before the operation will see the old value. This behavior + is temporary, and will follow Python semantics in the future. + +* The `+` operator is defined for dictionaries, returning an immutable + concatenated dictionary created from the entries of the original + dictionaries. In case of duplicate keys, we use values from the second + operand. If you need compatibility with Python, we suggest this syntax: + `dict(a.items() + b.items())`. + +* Dictionaries have deterministic order when iterating (sorted by key). + +* Sets use a custom order when iterating (see [documentation](lib/globals.html#set)). + +* Recursion is not allowed. + +* Loops iterate over a shallow copy of the collection. If the collection is a + list or dictionary that is modified during iteration, this will not affect + what values get bound to the loop variable or variables. The changes are + still visible if you directly access the collection. + +The following Python features are not supported: + +* `class` (see [`struct`](lib/globals.html#struct) function) +* `import` (see [`load`](#loading-a-skylark-extension) statement) +* `while`, `yield` +* `lambda` and nested functions +* `is` (use `==` instead) +* `try`, `raise`, `except`, `finally` (see [`fail`](lib/globals.html#fail) + for fatal errors). +* most builtin functions, most methods + + diff --git a/site/docs/skylark/cookbook.md b/site/docs/skylark/cookbook.md index a4a4dadcbb..a6950022d1 100644 --- a/site/docs/skylark/cookbook.md +++ b/site/docs/skylark/cookbook.md @@ -1,4 +1,920 @@ --- -layout: redirect -redirect: docs/skylark/cookbook.html +layout: documentation +title: Extensions examples --- +# Extensions examples + +## <a name="macro"></a>Macro creating a rule + +An example of a macro creating a rule. + +`empty.bzl`: + +```python +def _impl(ctx): + print("This rule does nothing") + +empty = rule(implementation=_impl) +``` + +`extension.bzl`: + +```python +# Loading the rule. The rule doesn't have to be in a separate file. +load("//pkg:empty.bzl", "empty") + +def macro(name, visibility=None): + # Creating the rule. + empty(name = name, visibility = visibility) +``` + +`BUILD`: + +```python +load("//pkg:extension.bzl", "macro") + +macro(name = "myrule") +``` + +## <a name="macro_native"></a>Macro creating a native rule + +An example of a macro creating a native rule. Native rules are special rules +that are automatically available (without <code>load</code>). They are +accessed using the <a href="lib/native.html">native</a> module. + +`extension.bzl`: + +```python +def macro(name, visibility=None): + # Creating a native genrule. + native.genrule( + name = name, + outs = [name + '.txt'], + cmd = 'echo hello > $@', + visibility = visibility, + ) +``` + +`BUILD`: + +```python +load("//pkg:extension.bzl", "macro") + +macro(name = "myrule") +``` + +## <a name="macro_compound"></a>Macro multiple rules + +There's currently no easy way to create a rule that directly uses the +action of a native rule. You can work around this using macros: + +```python +def cc_and_something_else_binary(name, srcs, deps, csrcs, cdeps) + cc_binary_name = "%s.cc_binary" % name + + native.cc_binary( + name = cc_binary_name, + srcs = csrcs, + deps = cdeps, + visibility = ["//visibility:private"] + ) + + _cc_and_something_else_binary( + name = name, + srcs = srcs, + deps = deps, + # A label attribute so that this depends on the internal rule. + cc_binary = cc_binary_name, + # Redundant labels attributes so that the rule with this target name knows + # about everything it would know about if cc_and_something_else_binary + # were an actual rule instead of a macro. + csrcs = csrcs, + cdeps = cdeps) + +def _impl(ctx): + return struct([...], + # When instrumenting this rule, again hide implementation from + # users. + instrumented_files( + source_attributes = ["srcs", "csrcs"], + dependency_attributes = ["deps", "cdeps"])) + +_cc_and_something_else_binary = rule(implementation=_impl) +``` + + +## <a name="conditional-instantiation"></a>Conditional instantiation + +Macros can look at previously instantiated rules. This is done with +`native.existing_rule`, which returns information on a single rule defined in the same +`BUILD` file, eg., + +```python +native.existing_rule("descriptor_proto") +``` + +This is useful to avoid instantiating the same rule twice, which is an +error. For example, the following macro will simulate a test suite, +instantiating tests for diverse flavors of the same test. + +`extension.bzl`: + +```python +def system_test(name, test_file, flavor): + n = "system_test_%s_%s_test" % (test_file, flavor) + if native.existing_rule(n) == None: + native.py_test( + name = n, + srcs = [ "test_driver.py", test_file ], + args = [ "--flavor=" + flavor]) + return n + +def system_test_suite(name, flavors=["default"], test_files): + ts = [] + for flavor in flavors: + for test in test_files: + ts.append(system_test(name, test, flavor)) + native.test_suite(name = name, tests = ts) +``` + +In the following BUILD file, note how `(basic_test.py, fast)` is emitted for +both the `smoke` test suite and the `thorough` test suite. + +```python +load("//pkg:extension.bzl", "system_test_suite") + +# Run all files through the 'fast' flavor. +system_test_suite("smoke", flavors=["fast"], glob(["*_test.py"])) + +# Run the basic test through all flavors. +system_test_suite("thorough", flavors=["fast", "debug", "opt"], ["basic_test.py"]) +``` + + +## <a name="aggregation"></a>Aggregating over the BUILD file + +Macros can collect information from the BUILD file as processed so far. We call +this aggregation. The typical example is collecting data from all rules of a +certain kind. This is done by calling +<a href="lib/native.html#existing_rules">native.existing\_rules</a>, which +returns a dictionary representing all rules defined so far in the current BUILD +file. The dictionary has entries of the form `name` => `rule`, with the values +using the same format as `native.existing_rule`. + +```python +def archive_cc_src_files(tag): + """Create an archive of all C++ sources that have the given tag.""" + all_src = [] + for r in native.existing_rules().values(): + if tag in r["tags"] and r["kind"] == "cc_library": + all_src.append(r["srcs"]) + native.genrule(cmd = "zip $@ $^", srcs = all_src, outs = ["out.zip"]) +``` + +Since `native.existing_rules` constructs a potentially large dictionary, you should avoid +calling it repeatedly within BUILD file. + +## <a name="empty"></a>Empty rule + +Minimalist example of a rule that does nothing. If you build it, the target will +succeed (with no generated file). + +`empty.bzl`: + +```python +def _impl(ctx): + # You may use print for debugging. + print("This rule does nothing") + +empty = rule(implementation=_impl) +``` + +`BUILD`: + +```python +load("//pkg:empty.bzl", "empty") + +empty(name = "nothing") +``` + +## <a name="attr"></a>Rule with attributes + +Example of a rule that shows how to declare attributes and access them. + +`printer.bzl`: + +```python +def _impl(ctx): + # You may use print for debugging. + print("Rule name = %s, package = %s" % (ctx.label.name, ctx.label.package)) + + # This prints the labels of the deps attribute. + print("There are %d deps" % len(ctx.attr.deps)) + for i in ctx.attr.deps: + print("- %s" % i.label) + # A label can represent any number of files (possibly 0). + print(" files = %s" % [f.path for f in i.files]) + +printer = rule( + implementation=_impl, + attrs={ + # Do not declare "name": It is added automatically. + "number": attr.int(default = 1), + "deps": attr.label_list(allow_files=True), + }) +``` + +`BUILD`: + +```python +load("//pkg:printer.bzl", "printer") + +printer( + name = "nothing", + deps = [ + "BUILD", + ":other", + ], +) + +printer(name = "other") +``` + +If you execute this file, some information is printed as a warning by the +rule. No file is generated. + +## <a name="shell"></a>Simple shell command + +Example of a rule that runs a shell command on an input file specified by +the user. The output has the same name as the rule, with a `.size` suffix. + +While convenient, Shell commands should be used carefully. Generating the +command-line can lead to escaping and injection issues. It can also create +portability problems. It is often better to declare a binary target in a +BUILD file and execute it. See the example [executing a binary](#execute-bin). + +`size.bzl`: + +```python +def _impl(ctx): + output = ctx.outputs.out + input = ctx.file.file + # The command may only access files declared in inputs. + ctx.action( + inputs=[input], + outputs=[output], + progress_message="Getting size of %s" % input.short_path, + command="stat -L -c%%s %s > %s" % (input.path, output.path)) + +size = rule( + implementation=_impl, + attrs={"file": attr.label(mandatory=True, allow_files=True, single_file=True)}, + outputs={"out": "%{name}.size"}, +) +``` + +`foo.txt`: + +``` +Hello +``` + +`BUILD`: + +```python +load("//pkg:size.bzl", "size") + +size( + name = "foo_size", + file = "foo.txt", +) +``` + +## <a name="file"></a>Write string to a file + +Example of a rule that writes a string to a file. + +`file.bzl`: + +```python +def _impl(ctx): + output = ctx.outputs.out + ctx.file_action(output=output, content=ctx.attr.content) + +file = rule( + implementation=_impl, + attrs={"content": attr.string()}, + outputs={"out": "%{name}.txt"}, +) +``` + +`BUILD`: + +```python +load("//pkg:file.bzl", "file") + +file( + name = "hello", + content = "Hello world", +) +``` + + +## <a name="execute-bin"></a>Execute a binary + +This rule executes an existing binary. In this particular example, the +binary is a tool that merges files. During the analysis phase, we cannot +access any arbitrary label: the dependency must have been previously +declared. To do so, the rule needs a label attribute. In this example, we +will give the label a default value and make it private (so that it is not +visible to end users). Keeping the label private can simplify maintenance, +since you can easily change the arguments and flags you pass to the tool. + +`execute.bzl`: + +```python +def _impl(ctx): + # The list of arguments we pass to the script. + args = [ctx.outputs.out.path] + [f.path for f in ctx.files.srcs] + # Action to call the script. + ctx.action( + inputs=ctx.files.srcs, + outputs=[ctx.outputs.out], + arguments=args, + progress_message="Merging into %s" % ctx.outputs.out.short_path, + executable=ctx.executable._merge_tool) + +concat = rule( + implementation=_impl, + attrs={ + "srcs": attr.label_list(allow_files=True), + "out": attr.output(mandatory=True), + "_merge_tool": attr.label(executable=True, allow_files=True, + default=Label("//pkg:merge")) + } +) +``` + +Any executable target can be used. In this example, we will use a +`sh_binary` rule that concatenates all the inputs. + +`BUILD`: + +``` +load("execute", "concat") + +concat( + name = "sh", + srcs = [ + "header.html", + "body.html", + "footer.html", + ], + out = "page.html", +) + +# This target is used by the shell rule. +sh_binary( + name = "merge", + srcs = ["merge.sh"], +) +``` + +`merge.sh`: + +```python +#!/bin/bash + +out=$1 +shift +cat $* > $out +``` + +`header.html`: + +``` +<html><body> +``` + +`body.html`: + +``` +content +``` + +`footer.html`: + +``` +</body></html> +``` + +## <a name="execute"></a>Execute an input binary + +This rule has a mandatory `binary` attribute. It is a label that can refer +only to executable rules or files. + +`execute.bzl`: + +```python +def _impl(ctx): + # ctx.new_file is used for temporary files. + # If it should be visible for user, declare it in rule.outputs instead. + f = ctx.new_file(ctx.configuration.bin_dir, "hello") + # As with outputs, each time you declare a file, + # you need an action to generate it. + ctx.file_action(output=f, content=ctx.attr.input_content) + + ctx.action( + inputs=[f], + outputs=[ctx.outputs.out], + executable=ctx.executable.binary, + progress_message="Executing %s" % ctx.executable.binary.short_path, + arguments=[ + f.path, + ctx.outputs.out.path, # Access the output file using + # ctx.outputs.<attribute name> + ] + ) + +execute = rule( + implementation=_impl, + attrs={ + "binary": attr.label(cfg="host", mandatory=True, allow_files=True, + executable=True), + "input_content": attr.string(), + "out": attr.output(mandatory=True), + }, +) +``` + +`a.sh`: + +```bash +#!/bin/bash + +tr 'a-z' 'A-Z' < $1 > $2 +``` + +`BUILD`: + +```python +load("//pkg:execute.bzl", "execute") + +execute( + name = "e", + input_content = "some text", + binary = "a.sh", + out = "foo", +) +``` + +## <a name="runfiles"></a>Define simple runfiles + +`execute.bzl`: + +```python +def _impl(ctx): + executable = ctx.outputs.executable + # Create the output executable file with command as its content. + ctx.file_action( + output=executable, + content=ctx.attr.command, + executable=True) + + return struct( + # Create runfiles from the files specified in the data attribute. + # The shell executable - the output of this rule - can use them at runtime. + # It is also possible to define data_runfiles and default_runfiles. + # However if runfiles is specified it's not possible to define the above + # ones since runfiles sets them both. + # Remember, that the struct returned by the implementation function needs + # to have a field named "runfiles" in order to create the actual runfiles + # symlink tree. + runfiles=ctx.runfiles(files=ctx.files.data) + ) + +execute = rule( + implementation=_impl, + executable=True, + attrs={ + "command": attr.string(), + "data": attr.label_list(cfg="data", allow_files=True), + }, +) +``` + +`data.txt`: + +``` +Hello World! +``` + +`BUILD`: + +```python +load("//pkg:execute.bzl", "execute") + +execute( + name = "e", + # The path to data.txt has to include the package directories as well. I.e. + # if the BUILD file is under foo/BUILD and the data file is foo/data.txt + # then it needs to be referred as foo/data.txt in the command. + command = "cat data.txt", + data = [':data.txt'] +) +``` + +## <a name="late-bound"></a>Computed dependencies + +Bazel needs to know about all dependencies before doing the analysis phase and +calling the implementation function. Dependencies can be computed based on the +rule attributes: to do so, use a function as the default +value of an attribute (the attribute must be private and have type `label` or +`list of labels`). The parameters of this function must correspond to the +attributes that are accessed in the function body. + +Note: For legacy reasons, the function takes the configuration as an additional +parameter. Please do not rely on the configuration since it will be removed in +the future. + +The example below computes the md5 sum of a file. The file can be preprocessed +using a filter. The exact dependencies depend on the filter chosen by the user. + +`hash.bzl`: + +```python +_filters = { + "comments": Label("//pkg:comments"), + "spaces": Label("//pkg:spaces"), + "none": None, +} + +def _get_filter(filter, cfg=None): # requires attribute "filter" + # Return the value for the attribute "_filter_bin" + # It can be a label or None. + return _filters[filter] + +def _impl(ctx): + src = ctx.file.src + + if not ctx.attr._filter_bin: + # Skip the processing + processed = src + else: + processed = ctx.new_file(ctx.label.name + "_processed") + # Run the selected binary + ctx.action( + outputs = [processed], + inputs = [ctx.file.src], + progress_message="Apply filter '%s'" % ctx.attr.filter, + arguments = [ctx.file.src.path, processed.path], + executable = ctx.executable._filter_bin) + + # Compute the hash + out = ctx.outputs.text + ctx.action( + outputs = [out], + inputs = [processed], + command = "md5sum < %s > %s" % (processed.path, out.path)) + +hash = rule( + implementation=_impl, + attrs={ + "filter": attr.string(values=_filters.keys(), default="none"), + "src": attr.label(mandatory=True, single_file=True, allow_files=True), + "_filter_bin": attr.label(default=_get_filter, executable=True), + }, + outputs = {"text": "%{name}.txt"}) +``` + +`BUILD`: + +```python +load("//pkg:hash.bzl", "hash") + +hash( + name = "hash", + src = "hello.txt", + filter = "spaces", +) + +sh_binary( + name = "comments", + srcs = ["comments.sh"], +) + +sh_binary( + name = "spaces", + srcs = ["spaces.sh"], +) +``` + +`hello.txt`: + +``` +Hello World! +``` + +`comments.sh`: + +``` +#!/bin/bash +grep -v '^ *#' $1 > $2 # Remove lines with only a Python-style comment +``` + +`spaces.sh`: + +``` +#!/bin/bash +tr -d ' ' < $1 > $2 # Remove spaces +``` + +## <a name="mandatory-providers"></a>Mandatory providers + +In this example, rules have a `number` attribute. Each rule adds its +number with the numbers of its transitive dependencies, and write the +result in a file. This shows how to transfer information from a dependency +to its dependents. + +`sum.bzl`: + +```python +def _impl(ctx): + result = ctx.attr.number + for i in ctx.attr.deps: + result += i.number + ctx.file_action(output=ctx.outputs.out, content=str(result)) + + # Fields in the struct will be visible by other rules. + return struct(number=result) + +sum = rule( + implementation=_impl, + attrs={ + "number": attr.int(default=1), + # All deps must provide all listed providers. + "deps": attr.label_list(providers=["number"]), + }, + outputs = {"out": "%{name}.sum"} +) +``` + +`BUILD`: + +```python +load("//pkg:sum.bzl", "sum") + +sum( + name = "n", + deps = ["n2", "n5"], +) + +sum( + name = "n2", + number = 2, +) + +sum( + name = "n5", + number = 5, +) +``` + +## <a name="optional-providers"></a>Optional providers + +This is a similar example, but dependencies may not provide a number. + +`sum.bzl`: + +```python +def _impl(ctx): + result = ctx.attr.number + for i in ctx.attr.deps: + if hasattr(i, "number"): + result += i.number + ctx.file_action(output=ctx.outputs.out, content=str(result)) + + # Fields in the struct will be visible by other rules. + return struct(number=result) + +sum = rule( + implementation=_impl, + attrs={ + "number": attr.int(default=1), + "deps": attr.label_list(), + }, + outputs = {"out": "%{name}.sum"} +) +``` + +`BUILD`: + +```python +load("//pkg:sum.bzl", "sum") + +sum( + name = "n", + deps = ["n2", "n5"], +) + +sum( + name = "n2", + number = 2, +) + +sum( + name = "n5", + number = 5, +) +``` + +## <a name="outputs-executable"></a>Default executable output + +This example shows how to create a default executable output. + +`extension.bzl`: + +```python +def _impl(ctx): + ctx.file_action( + # Access the executable output file using ctx.outputs.executable. + output=ctx.outputs.executable, + content="#!/bin/bash\necho Hello!", + executable=True + ) + # The executable output is added automatically to this target. + +executable_rule = rule( + implementation=_impl, + executable=True +) +``` + +`BUILD`: + +```python +load("//pkg:extension.bzl", "executable_rule") + +executable_rule(name = "my_rule") +``` + +## <a name="outputs-default"></a>Default outputs + +This example shows how to create default outputs for a rule. + +`extension.bzl`: + +```python +def _impl(ctx): + ctx.file_action( + # Access the default outputs using ctx.outputs.<output name>. + output=ctx.outputs.my_output, + content="Hello World!" + ) + # The default outputs are added automatically to this target. + +rule_with_outputs = rule( + implementation=_impl, + outputs = { + # %{name} is substituted with the rule's name + "my_output": "%{name}.txt" + } +) +``` + +`BUILD`: + +```python +load("//pkg:extension.bzl", "rule_with_outputs") + +rule_with_outputs(name = "my_rule") +``` + +## <a name="outputs-custom"></a>Custom outputs + +This example shows how to create custom (user defined) outputs for a rule. +This rule takes a list of output file name templates from the user and +creates each of them containing a "Hello World!" message. + +`extension.bzl`: + +```python +def _impl(ctx): + # Access the custom outputs using ctx.outputs.<attribute name>. + for output in ctx.outputs.outs: + ctx.file_action( + output=output, + content="Hello World!" + ) + # The custom outputs are added automatically to this target. + +rule_with_outputs = rule( + implementation=_impl, + attrs={ + "outs": attr.output_list() + } +) +``` + +`BUILD`: + +```python +load("//pkg:extension.bzl", "rule_with_outputs") + +rule_with_outputs( + name = "my_rule", + outs = ["my_output.txt"] +) +``` + +## <a name="master-rule"></a>Master rules + +This example shows how to create master rules to bind other rules together. The +code below uses genrules for simplicity, but this technique is more useful with +other rules. For example, if you need to compile C++ files, you can reuse +`cc_library`. + +`extension.bzl`: + +```python +def _impl(ctx): + # Aggregate the output files from the depending rules + files = set() + files += ctx.attr.dep_rule_1.files + files += ctx.attr.dep_rule_2.files + return struct(files=files) + +# This rule binds the depending rules together +master_rule = rule( + implementation=_impl, + attrs={ + "dep_rule_1": attr.label(), + "dep_rule_2": attr.label() + } +) + +def macro(name, cmd, input): + # Create the depending rules + name_1 = name + "_dep_1" + name_2 = name + "_dep_2" + native.genrule( + name = name_1, + cmd = cmd, + outs = [name_1 + ".txt"] + ) + native.genrule( + name = name_2, + cmd = "echo " + input + " >$@", + outs = [name_2 + ".txt"] + ) + # Create the master rule + master_rule( + name = name, + dep_rule_1 = ":" + name_1, + dep_rule_2 = ":" + name_2 + ) +``` + +`BUILD`: + +```python +load("//pkg:extension.bzl", "macro") + +# This creates the target :my_rule +macro( + name = "my_rule", + cmd = "echo something > $@", + input = "Hello World" +) +``` + +## <a name="debugging-tips"></a>Debugging tips + +Here are some examples on how to debug macros and rules using +<a href="lib/globals.html#print">print</a>. + +`debug.bzl`: + +```python +print("print something when the module is loaded") + +def _impl(ctx): + print("print something when the rule implementation is executed") + print(type("abc")) # prints string, the type of "abc" + print(dir(ctx)) # prints all the fields and methods of ctx + print(dir(ctx.attr)) # prints all the attributes of the rule + # prints the objects each separated with new line + print("object1", "object2", sep="\n") + +debug = rule(implementation=_impl) +``` + +`BUILD`: + +```python +load("//pkg:debug.bzl", "debug") + +debug( + name = "printing_rule" +) +``` diff --git a/site/docs/skylark/deploying.md b/site/docs/skylark/deploying.md index a56f7183ae..ad0831ccff 100644 --- a/site/docs/skylark/deploying.md +++ b/site/docs/skylark/deploying.md @@ -1,4 +1,144 @@ --- -layout: redirect -redirect: docs/skylark/deploying.html +layout: documentation +title: Deploying new Skylark rules --- +# Deploying new Skylark rules + +This documentation is for Skylark rule writers who are planning to make their +rules available to others. + +## Where to put new rules + +In general, new rules should go into their own GitHub repository under your +organization. Contact the [bazel-dev mailing +list](https://groups.google.com/forum/#!forum/bazel-dev) if you feel like your +rules belong in the bazelbuild organization. + +You can see lots of examples of what your repository should look like on GitHub: +see all of the repositories named `rules_whatever`. In particular, +[rules_scala](https://github.com/bazelbuild/rules_scala) is a nice example of +how to set up your repo. + +Rules can be grouped either by language (e.g., Scala) or some notion of platform +(e.g., Android). + +## What a rule repository should contain + +Every rule repository should have a certain layout so that users can quickly +understand new rules. + +For example, suppose we are writing new Skylark rules for the (make-believe) +chaiscript language. We would have the following structure: + +``` +.travis.yml +README.md +WORKSPACE +chaiscript/ + BUILD + chaiscript.bzl +tests/ + BUILD + some_test.sh + another_test.py +examples/ + BUILD + bin.chai + lib.chai + test.chai +``` + +### README.md + +At the top level, there should be a README.md that contains (at least) what +users will need to copy-paste into their WORKSPACE file to use your rule. +In general, this will be a `git_repository` pointing to your GitHub repo and +a macro call that downloads/configures any tools your rule needs. For example, +for the [Go +rules](https://github.com/bazelbuild/rules_go/blob/master/README.md#setup), this +looks like: + +``` +git_repository( + name = "io_bazel_rules_go", + remote = "https://github.com/bazelbuild/rules_go.git", + tag = "0.0.2", +) +load("@io_bazel_rules_go//go:def.bzl", "go_repositories") + +go_repositories() +``` + +If your rules depend on another repository's rules, specify both in the +`README.md` (see the [Skydoc rules](https://github.com/bazelbuild/skydoc#setup), +which depend on the Sass rules, for an example of this). + +### Tests + +There should be tests that verify that the rules are working as expected. This +can either be in the standard location for the language the rules are for or a +`tests/` directory at the top level. + +### Optional: Examples + +It is useful to users to have an `examples/` directory that shows users a couple +of basic ways that the rules can be used. + +## Testing + +Set up Travis as described in their [getting started +docs](https://docs.travis-ci.com/user/getting-started/). Then add a +`.travis.yml` file to your repository with the following content: + +``` +language: + - java +jdk: + - oraclejdk8 # Building Bazel requires JDK8. +before_install: + - wget https://github.com/bazelbuild/bazel/archive/0.3.0.zip # Replace with desired version + - unzip 0.3.0.zip + - cd bazel-0.3.0 + - ./compile.sh + - sudo cp output/bazel /usr/bin/bazel + - cd .. + - rm -rf bazel-0.3.0 +script: + - bazel build //... + - bazel test //... +``` + +Right now Bazel has to be compiled from source, as Travis does not support a +version of GCC that works with the precompiled Bazel binaries. Thus, the +`before_install` steps download the Bazel source, compile it, and "install" the +Bazel binary in /usr/bin. + +If your repository is under the [bazelbuild organization](https://github.com/bazelbuild), +contact the [bazel-dev](https://groups.google.com/forum/#!forum/bazel-dev) list +to have it added to [ci.bazel.io](http://ci.bazel.io). + +## Documentation + +See the [Skydoc documentation](https://github.com/bazelbuild/skydoc) for +instructions on how to comment your rules so that documentation can be generated +automatically. + +## FAQs + +### Why can't we add our rule to the Bazel GitHub repository? + +We want to decouple rules from Bazel releases as much as possible. It's clearer +who owns individual rules, reducing the load on Bazel developers. For our users, +decoupling makes it easier to modify, upgrade, downgrade, and replace rules. +Contributing to rules can be lighter weight than contributing to Bazel - +depending on the rules -, including full submit access to the corresponding +GitHub repository. Getting submit access to Bazel itself is a much more involved +process. + +The downside is a more complicated one-time installation process for our users: +they have to copy-paste a rule into their WORKSPACE file, as shown in the +README section above. + +We used to have all of the Skylark rules in the Bazel repository (under +`//tools/build_rules` or `//tools/build_defs`). We still have a couple rules +there, but we are working on moving the remaining rules out. diff --git a/site/docs/skylark/index.md b/site/docs/skylark/index.md index 541fcba640..b7d46a56f4 100644 --- a/site/docs/skylark/index.md +++ b/site/docs/skylark/index.md @@ -1,4 +1,16 @@ --- -layout: redirect -redirect: docs/skylark/index.html +layout: documentation +title: Extensions --- + +# Extensions +Skylark is the name of the extension mechanism in Bazel. It lets you add support +for new languages and tools by writing [custom build rules](rules.md). You can +also compose existing rules into [macros](macros.md). + +## Getting started + +Read the [concepts](concepts.md) behind Skylark and try the +[cookbook examples](cookbook.md). To go further, read about the +[standard library](lib/globals.html). + diff --git a/site/docs/skylark/macros.md b/site/docs/skylark/macros.md index b247e4b89f..6242af8d1a 100644 --- a/site/docs/skylark/macros.md +++ b/site/docs/skylark/macros.md @@ -1,4 +1,140 @@ --- -layout: redirect -redirect: docs/skylark/macros.html +layout: documentation +title: Macros --- +# Macros + +## Macro creation + +A macro is a function called from the BUILD file that can instantiate rules. +Macros don't give additional power, they are just used for encapsulation and +code reuse. By the end of the loading phase, macros don't exist anymore, and +Bazel sees only the set of rules they created. + +Native rules can be instantiated from the `native` module, e.g. + +```python +def my_macro(name, visibility=None): + native.cc_library( + name = name, + srcs = ["main.cc"], + visibility = visibility, + ) +``` + +If you need to know the package name (i.e. which BUILD file is calling the +macro), use the constant [PACKAGE_NAME](lib/globals.html#PACKAGE_NAME). + +## Examples + +* [Macro creating rules](cookbook.md#macro). + +* [Macro creating native rules](cookbook.md#macro_native). + +* [Macro combining multiple rules](cookbook.md#macro_compound). + +## Debugging + +* `bazel query --output=build //my/path:all` will show you how the BUILD +file looks like after evaluation. All macros, globs, loops are expanded. + +* You can also use [print](lib/globals.html#print) for debugging. It displays +the message as a warning during the loading phase. Except in rare cases, remove +your `print` calls before submitting the code to the depot. + +## Errors + +If you want to throw an error, use the [fail](lib/globals.html#fail) function. +Explain clearly to the user what went wrong and how to fix their BUILD file. It +is not possible to catch an error. + +``` +def my_macro(name, deps, visibility=None): + if len(deps) < 2: + fail("Expected at least two values in deps") + # ... +``` + +## Conventions + +* All public functions (functions that don't start with underscore) that +instantiate rules must have a `name` argument. This argument should not be +optional (don't give a default value). + +* Public functions should use a docstring following [Python + conventions](https://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Comments#Comments). + +* In BUILD files, the `name` argument of the macros must be a keyword + argument (not a positional argument). + +* The `name` attribute of rules generated by a macro should include the name + argument as a prefix. For example, `macro(name = "foo")` can generate a + `cc_library` `foo` and a genrule `foo_gen`. + +* In most cases, optional parameters should have a default value of `None`. + `None` can be passed directly to native rules, which treat it the same as if + you had not passed in any argument. Thus, there is no need to replace it with + `0`, `False`, or `[]` for this purpose. Instead, the macro should defer to the + rules it creates, as their defaults may be complex or may change over time. + Additionally, a parameter that is explicitly set to its default value looks + different than one that is never set (or set to `None`) when accessed through + the query language or build-system internals. + +* Macros should have an optional `visibility` argument. + +## Full example + +The typical use-case for a macro is when you want to reuse a genrule, e.g. + +``` +genrule( + name = "file", + outs = ["file.txt"], + cmd = "$(location generator) some_arg > $@", + tools = [":generator"], +) +``` + +If you want to generate another file with different arguments, you may want to +extract this code to a function. + +The BUILD file will become simply: + +``` +load("//path:generator.bzl", "file_generator") + +file_generator( + name = "file", + arg = "some_arg", +) +``` + +In order to keep BUILD files clean and declarative, you must put the function in +a separate `.bzl` file. For example, write the definition of the macro in +`path/generator.bzl`: + +``` +def file_generator(name, arg, visibility=None): + native.genrule( + name = name, + outs = [name + ".txt"], + cmd = "$(location generator) %s > $@" % arg, + tools = ["//test:generator"], + visibility = visibility, + ) +``` + +When you want to investigate what a macro does, use the following command to +see the expanded form: + +``` +$ bazel query --output=build :file +# /absolute/path/test/ext.bzl:42:3 +genrule( + name = "file", + tools = ["//test:generator"], + outs = ["//test:file.txt"], + cmd = "$(location generator) some_arg > $@", +) +``` + diff --git a/site/docs/skylark/repository_rules.md b/site/docs/skylark/repository_rules.md index 6af0109578..2ee876b687 100644 --- a/site/docs/skylark/repository_rules.md +++ b/site/docs/skylark/repository_rules.md @@ -1,4 +1,78 @@ --- -layout: redirect -redirect: docs/skylark/repository_rules.html +layout: documentation +title: Repository Rules --- +# Repository Rules + +**Status: Experimental**. We may make breaking changes to the API, but we will + announce them and help you update your code. + +An [external repository](/docs/external.md) is a rule that can be used only +in the `WORKSPACE` file and enable non-hermetic operation at the loading phase +of Bazel. Each external repository rule creates its own workspace, with its +own BUILD files and artifacts. They can be used to depend on third-party +libraries (such as Maven packaged libraries) but also to generate BUILD files +specific to the host Bazel is running on. + +## Repository Rule creation + +In a `.bzl` file, use the +[repository_rule](lib/globals.html#repository_rule) function to create a new +repository rule and store it in a global variable. + +A custom repository rule can be used just like a native repository rule. It +has a mandatory `name` attribute and every target present in its build files +can be referred as `@<name>//package:target` where `<name>` is the value of the +`name` attribute. + +The rule is loaded when you explicitly build it, or if it is a dependency of +the build. In this case, Bazel will execute its `implementation` function. This +function describe how to creates the repository, its content and BUILD files. + +## Attributes + +An attribute is a rule argument, such as `url` or `sha256`. You must list +the attributes and their types when you define a repository rule. + +```python +local_repository = repository_rule( + implementation=_impl, + local=True, + attrs={"path": attr.string(mandatory=True)}) +``` + +`name` attributes are implicitly defined for all `repository_rule`s. +To access an attribute, use `repository_ctx.attr.<attribute_name>`. +The name of a repository rule is accessible with `repository_ctx.name`. + +If an attribute name starts with `_` it is private and users cannot set it. + +## Implementation function + +Every repository rule requires an `implementation` function. It contains the +actual logic of the rule and is executed strictly in the Loading Phase. +The function has exactly one input parameter, `repository_ctx`, and should +always returns `None`. The input parameter `repository_ctx` can be used to +access attribute values, and non-hermetic functions (finding a binary, +executing a binary, creating a file in the repository or downloading a file +from the Internet). See [the library](lib/repository_ctx.html) for more +context. Example: + +```python +def _impl(repository_ctx): + repository_ctx.symlink(repository_ctx.attr.path, "") + +local_repository = repository_rule( + implementation=_impl, + ...) +``` + +## Examples + +For now, we only have one full example of usage of the `repository_rule`: +[C++ auto-configured toolchain](https://github.com/bazelbuild/bazel/blob/9116b3e99af2fd31d92c9bb7c37905a1675456c1/tools/cpp/cc_configure.bzl#L288). + +This example uses a repository rule to automatically create the +C++ configuration files for Bazel by looking for the local C++ compiler, the +environment and the flags the C++ compiler supports. + diff --git a/site/docs/skylark/rules.md b/site/docs/skylark/rules.md index 22b62057eb..809b8763da 100644 --- a/site/docs/skylark/rules.md +++ b/site/docs/skylark/rules.md @@ -1,4 +1,460 @@ --- -layout: redirect -redirect: docs/skylark/rules.html +layout: documentation +title: Rules --- +# Rules + +**Status: Experimental**. We may make breaking changes to the API, but we will + help you update your code. + +A rule defines a series of actions that Bazel should perform on inputs to get a +set of outputs. For example, a C++ binary rule might take a set of .cpp +files (the inputs), run `g++` on them (the action), and return an executable +file (the output). + +Note that, from Bazel's perspective, `g++` and the standard C++ libraries are +also inputs to this rule. As a rule writer, you must consider not only the +user-provided inputs to a rule, but also all of the tools and libraries required +to execute the actions (called _implicit inputs_). + +## Rule creation + +In a `.bzl` file, use the [rule](lib/globals.html#rule) +function to create a new rule and store it in a global variable: + +```python +my_rule = rule(...) +``` + +See [the cookbook](cookbook.md#empty) for examples. The rule can then be +loaded by BUILD files: + +```python +load('//some/pkg:whatever.bzl', 'my_rule') +``` + +A custom rule can be used just like a native rule. It has a mandatory `name` +attribute, you can refer to it with a label, and you can see it in +`bazel query`. + +The rule is analyzed when you explicitly build it, or if it is a dependency of +the build. In this case, Bazel will execute its `implementation` function. This +function decides what the outputs of the rule are and how to build them (using +`actions`). During analysis, no external command can be executed: actions will +be run in the execution phase. + +## Attributes + +An attribute is a rule argument, such as `srcs` or `deps`. You must list +the attributes and their types when you define a rule. + +```python +sum = rule( + implementation = impl, + attrs = { + "number": attr.int(default = 1), + "deps": attr.label_list(), + }, +) +``` + +The following attributes are implicitly added to every rule: `deprecation`, +`features`, `name`, `tags`, `testonly`, `visibility`. Test rules also have the +following attributes: `args`, `flaky`, `local`, `shard_count`, `size`, +`timeout`. + +Labels listed in `attr` will be inputs to the rule. + +To access an attribute in a rule's implementation, use +`ctx.attr.<attribute_name>`. The name and the package of a rule are available +with `ctx.label.name` and `ctx.label.package`. + +See [an example](cookbook.md#attr) of using `attr` in a rule. + +### <a name="private-attributes"></a> Private Attributes + +If an attribute name starts with `_` it is private and users cannot set it. It +is useful in particular for label attributes (your rule will have an +implicit dependency on this label). + +```python +metal_compile = rule( + implementation=impl, + attrs={ + "srcs": attr.label_list(), + "_compiler": attr.label( + default=Label("//tools:metalc"), + allow_single_file=True, + executable=True, + ), + }, +) +``` + +## Implementation function + +Every rule requires an `implementation` function. It contains the actual +logic of the rule and is executed strictly in the Analysis Phase. The function +has exactly one input parameter, `ctx`, and it may return +the [runfiles](#runfiles) and [providers](#providers) +of the rule. The input parameter `ctx` can be used to access attribute values, +outputs and dependent targets, and files. It also has some helper functions. +See [the library](lib/ctx.html) for more context. Example: + +```python +def impl(ctx): + ... + return struct( + runfiles=..., + my_provider=..., + ... + ) + +my_rule = rule( + implementation=impl, + ... +) +``` + +## Files + +There are two kinds of files: files stored in the file system and generated +files. For each generated file, there must be one and only one generating +action, and each action must generate one or more output files. Bazel will throw +an error otherwise. + +## Targets + +Every build rule corresponds to exactly one target. A target can create +[actions](#actions), can have dependencies (which can be files or +other build rules), [output files](#output-files) (generated by +its actions), and [providers](#providers). + +A target `y` depends on target `x` if `y` has a label or label list type +attribute where `x` is declared: + +```python +my_rule( + name = "x", +) + +my_rule( + name = "y", + deps = [":x"], +) +``` + +In the above case, it's possible to access targets declared in `my_rule.deps`: + +```python +def impl(ctx): + for dep in ctx.attr.deps: + # Do something with dep + ... + +my_rule = rule( + implementation=impl, + attrs={ + "deps": attr.label_list(), + }, + ... +) +``` + +## <a name="output-files"></a> Output files + +A target can declare output files, which must be generated by the target's +actions. There are three ways to create output files: + +* If the rule is marked `executable`, it creates an output file of the same name + as the rule's. [See example](cookbook.md#outputs-executable) + +* The rule can declare default `outputs`, which are always generated. + [See example](cookbook.md#outputs-default) + +* The rule can have output or output list type attributes. In that case the + output files come from the actual attribute values. + [See example](cookbook.md#outputs-custom) + +Each output file must have exactly one generating action. See the +[library](lib/ctx.html#outputs) for more context. + +## Default outputs + +Every rule has a set of default outputs. This is used: + +* When the user runs `bazel build` on your target. Bazel will build the default + outputs of the rule. + +* When the target is used as a dependency of another rule. A rule can access + the default outputs by using [target.files](lib/Target.html#files). + This is the case, for example, if you use a rule in the `srcs` attribute of a + `genrule`. + +Use the `files` provider to specify the default outputs of a rule. +If left unspecified, it will contain all the declared outputs. + +```python +def _impl(ctx): + # ... + return struct(files=set([file1, file2])) +``` + +This can be useful for exposing files generated with +[ctx.new_file](lib/ctx.html#new_file). You can also have "implicit +outputs", i.e., files that are declared in the rule, but not in the default +outputs (like `_deploy.jar` in `java_binary`). + +## Actions + +There are three ways to create actions: + +* [ctx.action](lib/ctx.html#action), to run a command. +* [ctx.file_action](lib/ctx.html#file_action), to write a string to a file. +* [ctx.template_action](lib/ctx.html#template_action), to generate a file from a template. + +Actions take a set (which can be empty) of input files and generate a (non-empty) +set of output files. +The set of input and output files must be known during the analysis phase. It +might depend on the value of attributes and information from dependencies, but +it cannot depend on the result of the execution. For example, if your action +runs the unzip command, you must specify which files you expect to be inflated +(before running unzip). + +Actions are comparable to pure functions: They should depend only on the +provided inputs, and avoid accessing computer information, username, clock, +network, or I/O devices (except for reading inputs and writing outputs). + +**If an action generates a file that is not listed in its outputs**: This is +fine, but the file will be ignored and cannot be used by other rules. + +**If an action does not generate a file that is listed in its outputs**: This is +an execution error and the build will fail. This happens for instance when a +compilation fails. + +**If an action generates an unknown number of outputs and you want to keep them +all**, you must group them in a single file (e.g., a zip, tar, or other +archive format). This way, you will be able to deterministically declare your +outputs. + +**If an action does not list a file it uses as an input**, the action execution +will most likely result in an error. The file is not guaranteed to be available +to the action, so if it **is** there, it's due to coincidence or error. + +**If an action lists a file as an input, but does not use it**: This is fine. +However, it can affect action execution order, resulting in sub-optimal +performance. + +Dependencies are resolved by Bazel, which will decide which actions are +executed. It is an error if there is a cycle in the dependency graph. Creating +an action does not guarantee that it will be executed: It depends on whether +its outputs are needed for the build. + +## Configurations + +By default, a target is built in the target configuration. For each label +attribute, you can decide whether the dependency should be built in the same +configuration, or in the host configuration. + +In general, sources, dependent libraries, and executables that will be needed at +runtime can use the same configuration. + +Tools that are executed as part of the build (e.g., compilers, code generators) +should be built for the host configuration. In this case, specify `cfg="host"` +in the attribute. + +The configuration `"data"` is present for legacy reasons and should be used for +the `data` attributes. + + +## <a name="fragments"></a> Configuration Fragments + +Rules may access configuration fragments such as `cpp`, `java` and `jvm`. +However, all required fragments must be declared in order to avoid access +errors: + +```python +def impl(ctx): + # Using ctx.fragments.cpp would lead to an error since it was not declared. + x = ctx.fragments.java + ... + +my_rule = rule( + implementation=impl, + fragments=["java"], # Required fragments of the target configuration + host_fragments=["java"], # Required fragments of the host configuration + ... +) +``` + +`ctx.fragments` only provides configuration fragments for the target +configuration. If you want to access fragments for the host configuration, +use `ctx.host_fragments` instead. + +## Providers + +Providers are used to access information from other rules. A rule depending on +another rule has access to the data the latter provides. These data can be e.g. +output files, the libraries the dependent rule is using to link or compile, or +anything the depending rule should know about. Using providers is the only way +to exchange data between rules. + +A rule can only access data provided by its direct dependencies, not that of +transitive dependencies: if rule `top` depends on `middle`, and `middle` depends +on `bottom`, then `middle` is a direct dependency of `top` and `bottom` is a +transitive dependency of `top`. In this scenario `top` can only access data +provided by `middle`. If `middle` also provides the data that `bottom` provided +to it, then and only then can `top` access it. + +The following data types can be passed using providers: + +* `bool` +* `integer` +* `string` +* `file` +* `label` +* `None` +* anything composed of these types and `lists`, `dicts`, `sets` or `structs` + +Providers are created from the return value of the rule implementation function: + +```python +def rule_implementation(ctx): + ... + return struct( + transitive_data=set(["a", "b", "c"]) + ) +``` + +A dependent rule might access these data as struct fields of the `target` being +depended upon: + +```python +def dependent_rule_implementation(ctx): + ... + s = set() + for dep_target in ctx.attr.deps: + # Use `print(dir(dep_target))` to see the list of providers. + s += dep_target.transitive_data + ... +``` + +Providers are only available during the analysis phase. Examples of usage: + +* [mandatory providers](cookbook.md#mandatory-providers) +* [optional providers](cookbook.md#optional-providers) + +## Runfiles + +Runfiles are a set of files used by the (often executable) output of a rule +during runtime (as opposed to build time, i.e. when the binary itself is +generated). +During execution, Bazel creates a directory tree containing symlinks pointing to +the runfiles, staging the environment for the binary so it can access the +runfiles during runtime. + +Runfiles can be added manually during rule creation and/or collected +transitively from the rule's dependencies: + +```python +def rule_implementation(ctx): + ... + transitive_runfiles = set() + for dep in ctx.attr.special_dependencies: + transitive_runfiles += dep.transitive_runtime_files + + runfiles = ctx.runfiles( + # Add some files manually. + files=[ctx.file.some_data_file], + # Add transitive files from dependencies manually. + transitive_files=transitive_runfiles, + # Collect runfiles from the common locations: transitively from srcs, + # deps and data attributes. + collect_default=True, + ) + # Add a field named "runfiles" to the return struct in order to actually + # create the symlink tree. + return struct(runfiles=runfiles) +``` + +Note that non-executable rule outputs can also have runfiles. For example, a +library might need some external files during runtime, and every dependent +binary should know about them. + +Also note that if an action uses an executable, the executable's runfiles can +be used when the action executes. + +Normally, the relative path of a file in the runfiles tree is the same as the +relative path of that file in the source tree or generated output tree. If these +need to be different for some reason, you can specify the `root_symlinks` or +`symlinks` arguments. The `root_symlinks` is a dictionary mapping paths to +files, where the paths are relative to the root of the runfiles directory. The +`symlinks` dictionary is the same, but paths are implicitly prefixed with the +name of the workspace. + +```python + ... + runfiles = ctx.runfiles( + root_symlinks={"some/path/here.foo": ctx.file.some_data_file2} + symlinks={"some/path/here.bar": ctx.file.some_data_file3} + ) + # Creates something like: + # sometarget.runfiles/ + # some/ + # path/ + # here.foo -> some_data_file2 + # <workspace_name>/ + # some/ + # path/ + # here.bar -> some_data_file3 +``` + +If `symlinks` or `root_symlinks` is used, be careful not to map two different +files to the same path in the runfiles tree. This will cause the build to fail +with an error describing the conflict. To fix, you will need to modify your +`ctx.runfiles` arguments to remove the collision. This checking will be done for +any targets using your rule, as well as targets of any kind that depend on those +targets. + +## Instrumented files + +Instrumented files are a set of files used by the coverage command. A rule can +use the `instrumented_files` provider to provide information about which files +should be used for measuring coverage. + +```python +def rule_implementation(ctx): + ... + return struct(instrumented_files=struct( + # Optional: File extensions used to filter files from source_attributes. + # If not provided, then all files from source_attributes will be + # added to instrumented files, if an empty list is provided, then + # no files from source attributes will be added. + extensions=["ext1", "ext2"], + # Optional: Attributes that contain source files for this rule. + source_attributes=["srcs"], + # Optional: Attributes for dependencies that could include instrumented + # files. + dependency_attributes=["data", "deps"])) +``` + +## Executable rules + +An executable rule is a rule that users can run using `bazel run`. + +To make a rule executable, set `executable=True` in the +[rule function](lib/globals.html#rule). During the analysis +phase, the rule must generate the output file `ctx.outputs.executable`. +[See example](cookbook.md#outputs-executable) + +## Test rules + +Test rules are run using `bazel test`. + +To create a test rule, set `test=True` in the +[rule function](lib/globals.html#rule). The name of the rule must +also end with `_test`. Test rules are implicitly executable, which means they +must generate the output file `ctx.outputs.executable`. + +Test rules inherit the following attributes: `args`, `flaky`, `local`, +`shard_count`, `size`, `timeout`. diff --git a/site/docs/support.md b/site/docs/support.md index 0d1b8cdaa6..fae80aa227 100644 --- a/site/docs/support.md +++ b/site/docs/support.md @@ -1,4 +1,255 @@ --- -layout: redirect -redirect: docs/support.html +layout: documentation +title: Get Support --- + +# Get Support + +* [User mailing list](https://groups.google.com/forum/#!forum/bazel-discuss) +* [Issue tracker](https://github.com/bazelbuild/bazel/issues) +* [Twitter](http://www.twitter.com/bazelbuild) +* [IRC](irc://irc.freenode.net/bazel) (freenode.net#bazel) + +# Support Policy + +We generally avoid making backwards-incompatible changes. We have several years of experience with +supporting a huge code base that is concurrently worked on by thousands of engineers every day, +and have successfully made significant changes to the core as well as to the rules without missing +a beat. We run hundreds of thousands of tests at Google before every single release to ensure that +it stays that way. + +That said, we occasionally have to make incompatible changes in order to fix bugs, to make further +improvements to the system, such as improving performance or usability, or to lock down APIs that +are known to be brittle. + +This document gives an overview of features that are widely used and that we consider stable. By +stable, we mean that the changes we make will be backwards compatible, or that we will provide a +migration path. + +It also covers features that are unstable. Either they are not yet widely used, or we are already +planning to change them significantly, possibly in ways that are not backwards compatible. + +We cannot cover everything that might change, but you can reasonably expect that we provide +advance notice on the mailing list before a major change happens. We're also happy to provide more +details, just ask on [bazel-discuss](https://groups.google.com/forum/#!forum/bazel-discuss). + +All undocumented features (attributes, rules, "Make" variables, and flags) are subject to change +at any time without prior notice. Features that are documented but marked *experimental* are also +subject to change at any time without prior notice. + +Bazel's extension language Skylark (anything you write in a `.bzl` file) is still subject to change. +We are in the process of migrating Google to Skylark, and expect the language part to extend macros +to stabilize as part of that process. Adding rules with skylark is still somewhat experimental. + +Help keep us honest: report bugs and regressions in the +[GitHub bugtracker](https://github.com/bazelbuild/bazel/issues). We will make an effort to triage all +reported issues within 2 business days. + +## Releases + +We regularly publish [binary releases of Bazel](https://github.com/bazelbuild/bazel/releases). To +that end, we announce release candidates on +[bazel-discuss](https://groups.google.com/forum/#!forum/bazel-discuss); these are binaries that have +passed all of our unit tests. Over the next few days, we regression test all applicable build +targets at Google. If you have a critical project using Bazel, we recommend that you establish an +automated testing process that tracks the current release candidate, and report any regressions. + +If no regressions are discovered, we officially release the candidate after a week. However, +regressions can delay the release of a release candidate. If regressions are found, we apply +corresponding cherry-picks to the release candidate to fix those regressions. If no further +regressions are found for two business days, but not before a week has elapsed since the first +release candidate, we release it. + +### Release versioning + +Version 0.1 is our first release marking the start of our beta phase. Until version 1.0.0, we +increase the MINOR version every time we reach a [new milestone](http://bazel.io/roadmap.html). + +Version 1.0.0 marks the end of our beta phase; afterwards, we will label each release with a +version number of the form MAJOR.MINOR.PATCH according to the +[semantic version 2.0.0 document](http://semver.org). + +## Current Status + +### Built-In Rules and the Internal API For Rules ### +We are planning a number of changes to the APIs between the core of Bazel and the built-in rules, +in order to make it easier for us to develop openly. This has the added benefit of also making it +easier for users to maintain their own rules (if written in Java instead of Skylark), if they don't +want to or cannot check this code into our repository. However, it also means our internal API is +not stable yet. In the long term, we want to move to Skylark wholesale, so we encourage contributors +to use Skylark instead of Java when writing new rules. Rewriting all of our built-in rules is going +to be a lengthy process however. + +1. We will fix the friction points that we know about, as well as those that we discover every time + we make changes that span both the internal and external depots. +2. We will drive a number of pending API cleanups to completion, as well as run anticipated cleanups + to the APIs, such as disallowing access to the file system from rule implementations (because + it's not hermetic). +3. We will enumerate the internal rule APIs, and make sure that they are appropriately marked (for + example with annotations) and documented. Just collecting a list will likely give us good + suggestions for further improvements, as well as opportunities for a more principled API review + process. +4. We will automatically check rule implementations against an API whitelist, with the intention + that API changes are implicitly flagged during code review. +5. We will work on removing (legacy) Google-internal features to reduce the amount of differences + between the internal and external rule sets. +6. We will encourage our engineers to make changes in the external depot first, and migrate them to + to the internal one afterwards. +7. We will move more of our rule implementations into the open source repository (Android, Go, + Python, the remaining C++ rules), even if we don't consider the code to be *ready* or if they are + still missing tools to work properly. +8. In order to be able to accept external contributions, our highest priority item for Skylark is a + testing framework. We encourage to write new rules in Skylark rather than in Java. + + +### Stable +We expect the following rules and features to be stable. They are widely used within Google, so +our internal testing should ensure that there are no major breakages. + +<table class="table table-condensed table-striped table-bordered"> + <colgroup> + <col class="support-col-rules" /> + <col class="support-col-notes" /> + </colgroup> + <thead> + <tr> + <th>Rules</th> + <th>Notes</th> + </tr> + </thead> + <tbody> + <tr> + <td>C/C++ rules except <code>cc_toolchain</code> and <code>cc_toolchain_suite</code></td> + <td></td> + </tr> + <tr> + <td>Java rules except <code>java_toolchain</code></td> + <td></td> + </tr> + <tr> + <td>Android rules except <code>android_ndk_repository</code> and + <code>android_sdk_repository</code></td> + <td></td> + </tr> + <tr> + <td><code>genrule</code></td> + <td></td> + </tr> + <tr> + <td><code>genquery</code></td> + <td></td> + </tr> + <tr> + <td><code>test_suite</code></td> + <td></td> + </tr> + <tr> + <td><code>filegroup</code></td> + <td></td> + </tr> + <tr> + <td><code>config_setting</code></td> + <td> + <ul> + <li>This rule is used in <code>select()</code> expressions. We have hundreds of uses, so + we expect the basic functionality to be stable. That said, there are some common use + cases that are not covered yet, or that require workarounds. For example, it's not + easily possible to select on information specified in a CROSSTOOL file, such as the + target abi. Another example is that it's not possible to OR multiple conditions, + leading to duplicated entries in the select. + </li> + </ul> + </td> + </tr> + </tbody> +</table> + + +### Unstable +These rules and features have known limitations that we will likely address in future releases. + +<table class="table table-condensed table-striped table-bordered"> + <colgroup> + <col class="support-col-rules" /> + <col class="support-col-notes" /> + </colgroup> + <thead> + <tr> + <th>Feature</th> + <th>Notes</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>cc_toolchain</code> and <code>cc_toolchain_suite</code></td> + <td> + <ul> + <li>We intend to make significant changes to the way C/C++ toolchains are defined; we will + keep our published C/C++ toolchain definition(s) up to date, but we make no guarantees for + custom ones.</li> + </ul> + </td> + </tr> + <tr> + <td>iOS/Objective C rules</td> + <td> + <ul> + <li>We cannot vouch for changes made by Apple ® to the underlying tools and + infrastructure.</li> + <li>The rules are fairly new and still subject to change; we try to avoid breaking changes, + but this may not always be possible.</li> + <li>No testing support yet.</li> + </ul> + </td> + </tr> + <tr> + <td>Python rules</td> + <td> + <ul> + <li>The rules support neither Python 3, C/C++ extensions, nor packaging. + </li> + </ul> + </td> + </tr> + <tr> + <td>Extra actions (<code>extra_action</code>, <code>action_listener</code>)</td> + <td> + <ul> + <li>Extra actions expose information about Bazel that we consider to be implementation + details, such as the exact interface between Bazel and the tools we provide; as such, + users will need to keep up with changes to tools to avoid breakage.</li> + </ul> + </td> + </tr> + <tr> + <td><code>environment_group</code></td> + <td> + <ul> + <li>We're planning to use it more extensively, replacing several machine-enforceable + constraint mechanism, but there's only a handful of uses so far. We fully expect it to + work, but there's a small chance that we have to go back to the drawing board.</li> + </ul> + </td> + </tr> + <tr> + <td><code>android_ndk_repository</code> and <code>android_sdk_repository</code></td> + <td> + <ul> + <li>We don't support pre-release NDKs or SDKs at this time. Furthermore, we may still + make backwards-incompatible changes to the attributes or the semantics.</li> + </ul> + </td> + </tr> + <tr> + <td><code>Fileset</code></td> + <td> + <ul> + <li>There are vestiges of Fileset / FilesetEntry in the source code, but we do not intend to + support them in Bazel, ever.</li> + <li>They're still widely used internally, and are therefore unlikely to go away in the near + future.</li> + </ul> + </td> + </tbody> +</table> + diff --git a/site/versions/master/docs/test-encyclopedia.html b/site/docs/test-encyclopedia.html index bdb7e787f6..bdb7e787f6 100644 --- a/site/versions/master/docs/test-encyclopedia.html +++ b/site/docs/test-encyclopedia.html diff --git a/site/docs/test-encyclopedia.md b/site/docs/test-encyclopedia.md deleted file mode 100644 index b87cc71ac7..0000000000 --- a/site/docs/test-encyclopedia.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -layout: redirect -redirect: docs/test-encyclopedia.html ---- diff --git a/site/docs/tutorial/android-app.md b/site/docs/tutorial/android-app.md index ea52e3ef1d..31e86475cc 100644 --- a/site/docs/tutorial/android-app.md +++ b/site/docs/tutorial/android-app.md @@ -1,4 +1,280 @@ --- -layout: redirect -redirect: docs/tutorial/android-app.html +layout: documentation +title: Tutorial - Build an Android App --- + +# Tutorial - Build an Android App + +The sample Android app in this tutorial is a very simple application that makes +an HTTP connection to the [backend server](backend-server.md) and displays the +resulting response. + +Here, you'll do the following: + +* Review the source files for the app +* Update the `WORKSPACE` file +* Create a `BUILD` file +* Run the build +* Find the build outputs +* Run the app + +## Review the source files + +Let's take a look at the source files for the app. These are located in +`$WORKSPACE/android/`. + +The key files and directories are: + +<table class="table table-condensed table-striped"> +<thead> +<tr> +<td>Name</td> +<td>Location</td> +</tr> +</thead> +<tbody> +<tr> +<td>Manifest file</td> +<td><code>src/main/java/com/google/bazel/example/android/AndroidManifest.xml</code></td> +</tr> +<tr> +<td>Activity source file</td> +<td><code>src/main/java/com/google/bazel/example/android/activities/MainActivity.java</code></td> +</tr> +<tr> +<td>Resource file directory</td> +<td><code>src/main/java/com/google/bazel/example/android/res/</code></td> +</tr> +</tbody> +</table> + +Note that you're just looking at these files now to become familiar with the +structure of the app. You don't have to edit any of the source files to complete +this tutorial. + +## Update the WORKSPACE file + +Bazel needs to run the Android SDK +[build tools](https://developer.android.com/tools/revisions/build-tools.html) +and uses the SDK libraries to build the app. This means that you need to add +some information to your `WORKSPACE` file so that Bazel knows where to find +them. Note that this step is not required when you build for other platforms. +For example, Bazel automatically detects the location of Java, C++ and +Objective-C compilers from settings in your environment. + +Add the following lines to your `WORKSPACE` file: + +```python +android_sdk_repository( + name = "androidsdk", + # Replace with path to Android SDK on your system + path = "/Users/username/Library/Android/sdk", + # Replace with the Android SDK API level + api_level = 23, + # Replace with the version in sdk/build-tools/ + build_tools_version="23.0.0" +) +``` + +**Optional:** This is not required by this tutorial, but if you want to compile +native code into your Android app, you also need to download the +[Android NDK](https://developer.android.com/ndk/downloads/index.html) and +tell Bazel where to find it by adding the following rule to your `WORKSPACE` +file: + +```python +android_ndk_repository( + name = "androidndk", + # Replace with path to Android NDK on your system + path = "/Users/username/Library/Android/ndk", + # Replace with the Android NDK API level + api_level = 21 +) +``` + +`api_level` is the version of the Android API the SDK and the NDK target +(for example, 19 for Android K and 21 for Android L). It's not necessary to set +the API levels to the same value for the SDK and NDK. +[This web page](https://developer.android.com/ndk/guides/stable_apis.html) +contains a map from Android releases to NDK-supported API levels. + +## Create a BUILD file + +A [`BUILD` file](/docs/build-ref.html#BUILD_files) is a text file that describes +the relationship between a set of build outputs -- for example, compiled +software libraries or executables -- and their dependencies. These dependencies +may be source files in your workspace or other build outputs. `BUILD` files are +written in the Bazel *build language*. + +`BUILD` files are part of concept in Bazel known as the *package hierarchy*. +The package hierarchy is a logical structure that overlays the directory +structure in your workspace. Each [package](/docs/build-ref.html#packages) is a +directory (and its subdirectories) that contains a related set of source files +and a `BUILD` file. The package also includes any subdirectories, excluding +those that contain their own `BUILD` file. The *package name* is the name of the +directory where the `BUILD` file is located. + +Note that this package hierarchy is distinct from, but coexists with, the Java +package hierarchy for your Android app. + +For the simple Android app in this tutorial, we'll consider all the source files +in `$WORKSPACE/android/` to comprise a single Bazel package. A more complex +project may have many nested packages. + +At a command-line prompt, open your new `BUILD` file for editing: + +```bash +$ vi $WORKSPACE/android/BUILD +``` + +### Add an android_library rule + +A `BUILD` file contains several different types of instructions for Bazel. The +most important type is the [build rule](/docs/build-ref.html#funcs), which tells +Bazel how to build an intermediate or final software output from a set of source +files or other dependencies. + +Bazel provides two build rules, `android_library` and `android_binary`, that you +can use to build an Android app. For this tutorial, you'll first use the +[`android_library`](/docs/be/android.html#android_library) rule to tell +Bazel how to build an +[Android library module](http://developer.android.com/tools/projects/index.html#LibraryProjects) +from the app source code and resource files. Then you'll use the +`android_binary` rule to tell it how to build the Android application package. + +Add the following to your `BUILD` file: + +```python +android_library( + name = "activities", + srcs = glob(["src/main/java/com/google/bazel/example/android/activities/*.java"]), + custom_package = "com.google.bazel.example.android.activities", + manifest = "src/main/java/com/google/bazel/example/android/activities/AndroidManifest.xml", + resource_files = glob(["src/main/java/com/google/bazel/example/android/activities/res/**"]), +) +``` + +As you can see, the `android_library` build rule contains a set of attributes +that specify the information that Bazel needs to build a library module from the +source files. Note also that the name of the rule is `activities`. You'll +reference the rule using this name as a dependency in the `android_binary` rule. + +### Add an android_binary rule + +The [`android_binary`](/docs/be/android.html#android_binary) rule builds +the Android application package (`.apk` file) for your app. + +Add the following to your build file: + +```python +android_binary( + name = "android", + custom_package = "com.google.bazel.example.android", + manifest = "src/main/java/com/google/bazel/example/android/AndroidManifest.xml", + resource_files = glob(["src/main/java/com/google/bazel/example/android/res/**"]), + deps = [":activities"], +) +``` + +Here, the `deps` attribute references the output of the `activities` rule you +added to the `BUILD` file above. This means that, when Bazel builds the output +of this rule, it checks first to see if the output of the `activities` library +rule has been built and is up-to-date. If not, it builds it and then uses that +output to build the application package file. + +Now, save and close the file. You can compare your `BUILD` file to the +[completed example](https://github.com/bazelbuild/examples/blob/master/tutorial/android/BUILD) +in the `master` branch of the GitHub repo. + +## Run the build + +You use the +[`bazel`](/docs/bazel-user-manual.html) command-line tool to run builds, execute +unit tests and perform other operations in Bazel. This tool is located in the +`output` subdirectory of the location where you installed Bazel. During +[installation](/docs/install.md), you probably added this location to your +path. + +Before you build the sample app, make sure that your current working directory +is inside your Bazel workspace: + +```bash +$ cd $WORKSPACE +``` + +Now, enter the following to build the sample app: + +```bash +$ bazel build //android:android +``` + +The [`build`](/docs/bazel-user-manual.html#build) subcommand instructs Bazel to +build the target that follows. The target is specified as the name of a build +rule inside a `BUILD` file, with along with the package path relative to +your workspace directory. Note that you can sometimes omit the package path +or target name, depending on your current working directory at the command +line and the name of the target. See [Labels](/docs/build-ref.html#labels) in +*Bazel Concepts and Terminology* page for more information about target labels +and paths. + +Bazel now launches and builds the sample app. During the build process, its +output will appear similar to the following: + +```bash +INFO: Found 1 target... +Target //android:android up-to-date: + bazel-bin/android/android_deploy.jar + bazel-bin/android/android_unsigned.apk + bazel-bin/android/android.apk +INFO: Elapsed time: 7.237s, Critical Path: 5.81s +``` + +## Find the build outputs + +Bazel stores the outputs of both intermediate and final build operations in +a set of per-user, per-workspace output directories. These directories are +symlinked from the following locations: + +* `$WORKSPACE/bazel-bin`, which stores binary executables and other runnable + build outputs +* `$WORKSPACE/bazel-genfiles`, which stores intermediary source files that are + generated by Bazel rules +* `$WORKSPACE/bazel-out`, which stores other types of build outputs + +Bazel stores the Android `.apk` file generated using the `android_binary` rule +in the `bazel-bin/android/` directory, where the subdirectory name `android` is +derived from the name of the Bazel package. + +At a command prompt, list the contents of this directory and find the +`android.apk` file: + +```bash +$ ls $WORKSPACE/bazel-bin/android +``` + +## Run the app + +You can now deploy the app to a connected Android device or emulator from the +command line using the +[`bazel mobile-install`](http://bazel.io/docs/bazel-user-manual.html#mobile-install) +command. This command uses the Android Debug Bridge (`adb`) to communicate with +the device. You must set up your device to use `adb` following the instructions +in +[Android Debug Bridge](http://developer.android.com/tools/help/adb.html) before +deployment. + +Enter the following: + +```bash +$ bazel mobile-install //android:android +``` + +Note that the `mobile-install` subcommand also supports the +[`--incremental`](http://bazel.io/docs/bazel-user-manual.html#mobile-install) +flag that can be used to deploy only those parts of the app that have changed +since the last deployment. + +## What's next + +Now that you've built a sample app for Android, it's time to do the same for +the [iOS app](ios-app.md). diff --git a/site/docs/tutorial/app.md b/site/docs/tutorial/app.md index d3c2872f6f..fdc33c5f83 100644 --- a/site/docs/tutorial/app.md +++ b/site/docs/tutorial/app.md @@ -1,4 +1,45 @@ --- -layout: redirect -redirect: docs/tutorial/app.html +layout: documentation +title: Build Mobile Application --- + +# Build Mobile Application + +You can use Bazel to build a variety of software outputs, including +Linux and Mac OS X applications written in Java, C++ and Objective-C. You can +also use Bazel to build software for other platforms or written in other +languages. + +This tutorial shows how to use Bazel to build the following: + +* An Android app +* An iOS app +* A mobile backend server running on App Engine + +In this tutorial, you'll learn how to: + +* Set up a Bazel workspace and create a `WORKSPACE` file +* Create `BUILD` files that contain the instructions used by Bazel to build + the software +* Run builds using the Bazel command line tool + +## Requirements + +You can follow the steps in this tutorial on either a Linux or Mac OS X system. +However, you can only build the iOS app if you are running Bazel on OS X. If +you are using Linux, you can skip the iOS instructions and still complete +the rest of the tutorial steps. + +## Sample project + +You don't have to write your own mobile apps and backend server to use this +tutorial. Instead, you'll use a sample project hosted on GitHub. The sample +project is hosted at the following location: + +[https://github.com/bazelbuild/examples/](https://github.com/bazelbuild/examples/) + +You'll grab the sample project files in the next step in this tutorial. + +## What's next + +Let's start off by [setting up](environment.md) the tutorial environment. diff --git a/site/docs/tutorial/backend-server.md b/site/docs/tutorial/backend-server.md index 150f9152ec..ad668a0d3b 100644 --- a/site/docs/tutorial/backend-server.md +++ b/site/docs/tutorial/backend-server.md @@ -1,4 +1,224 @@ --- -layout: redirect -redirect: docs/tutorial/backend-server.html +layout: documentation +title: Tutorial - Build the Backend Server --- + +# Tutorial - Build the Backend Server + +The backend server is a simple web application that runs on Google App Engine +and responds to incoming HTTP requests from the sample Android and iOS apps. + +Here, you'll do the following: + +* Review the source files for the app +* Update the `WORKSPACE` file +* Create the `appengine.BUILD` file +* Create a `BUILD` file +* Run the build +* Find the build outputs +* Deploy to a local development server +* Deploy to Google App Engine + +Bazel provides a set of [App Engine build rules](/docs/be/appengine.html) +written using the [Skylark](/docs/skylark/index.html) framework. You'll use +these in the steps below to build the application. + +## Review the source files + +The source files for the backend server are located in `$WORKSPACE/backend/`. + +The key files and directories are: + +<table class="table table-condensed table-striped"> +<thead> +<tr> +<td>Name</td> +<td>Location</td> +</tr> +</thead> +<tbody> +<tr> +<td>Source file directory</td> +<td><code>src/main/java/com/google/bazel/example/app/</code></td> +</tr> +<tr> +<td>Web application metadata directory</td> +<td><code>webapp/WEB-INF/</code></td> +</tr> +</tbody> +</table> + +## Update the WORKSPACE file + +As with the Android app, you must add references to +[external dependencies](http://bazel.io/docs/external.html) to your `WORKSPACE` +file. For the backend server, these are references to the App Engine SDK, +the Java Servlet SDK and other libraries needed to build the App Engine +applications. + +### Add a new\_http\_archive rule + +When you built the Android app, you added a reference to the location on your +filesystem where you downloaded and installed the Android SDK. For the +backend server, however, you'll give Bazel instructions for downloading the +required App Engine SDK package from a remote server. This is optional. You +can also download and install the SDK manually on your filesystem and reference +it from that location as described in the +[App Engine rule documentation](/docs/be/appengine.html). + +Add the following to your `WORKSPACE` file: + +```python +git_repository( + name = "io_bazel_rules_appengine", + remote = "https://github.com/bazelbuild/rules_appengine.git", + tag = "0.0.2", +) +load("@io_bazel_rules_appengine//appengine:appengine.bzl", "appengine_repositories") +appengine_repositories() +``` + +[`git_repository`](/docs/be/workspace.html#git_repository) downloads the +AppEngine rules from GitHub, then the next two lines use the +`appengine_repositories` function defined in these rules to download the +libraries and SDK needed to build AppEngine applications. + +Now, save and close the file. You can compare your `WORKSPACE` file to the +[completed example](https://github.com/bazelbuild/examples//blob/master/tutorial/WORKSPACE) +in the `master` branch of the GitHub repo. + +## Create a BUILD file + +Now that you have set up the external dependencies, you can go ahead and create +the `BUILD` file for the backend server, as you did previously for the sample +Android and iOS apps. + +Open your new `BUILD` file for editing: + +```bash +$ vi $WORKSPACE/backend/BUILD +``` + +### Add a java_binary rule + +Add the following to your `BUILD` file: + +```python +java_binary( + name = "app", + srcs = glob(["src/main/java/**/*.java"]), + main_class = "does.not.exist", + deps = [ + "@io_bazel_rules_appengine//appengine:javax.servlet.api", + ], +) +``` + +The [`java_binary`](/docs/be/java.html#java_binary) tells Bazel +how to build a Java `.jar` library for your application, plus a wrapper shell +script that launches the application code from the specified main class. Here, +we're using this rule instead of the +[`java_library`](/docs/be/java.html#java_library) because we need +the `.jar` file to contain all the dependencies required to build the final +App Engine `.war` file. For this reason, we specify a bogus class name +for the `main_class` attribute. + +### Add an appengine_war rule + +Add the following to your `BUILD` file: + +```python +load("@io_bazel_rules_appengine//appengine:appengine.bzl", "appengine_war") + +appengine_war( + name = "backend", + data = [":webapp"], + data_path = "/backend/webapp", + jars = [":app_deploy.jar"], +) + +filegroup( + name = "webapp", + srcs = glob(["webapp/**/*"]), +) +``` + +The [`appengine_war`](/docs/be/appengine.html#appengine_war) +rule builds the final App Engine `war` file from the library `.jar` file and web +application metadata files in the `webapp` directory. + +Save and close the file. Again, the +[completed example](https://github.com/google/bazel-examples/blob/master/tutorial/backend/BUILD) +is in the `master` branch of the GitHub repo. + +## Run the build + +Make sure that your current working directory is inside your Bazel workspace: + +```bash +$ cd $WORKSPACE +``` + +Now, enter the following to build the sample app: + +```bash +$ bazel build //backend:backend +``` + +Bazel now launches and builds the sample app. During the build process, its +output will appear similar to the following: + +```bash +INFO: Found 1 target... +Target //backend:backend up-to-date: + bazel-bin/backend/backend.war + bazel-bin/backend/backend.deploy + bazel-bin/backend/backend +INFO: Elapsed time: 56.867s, Critical Path: 2.72s +``` + +## Find the build outputs + +The `.war` file and other outputs are located in the +`$WORKSPACE/bazel-bin/backend` directory. + +## Deploy to a local development server + +The `appengine_war` rule generates an upload script that you can use to deploy +your backend server on Google App Engine. Here, you'll start a local App Engine +development server in your environment and deploy your application there. + +To deploy the application, enter the following: + +```bash +$ bazel-bin/backend/backend --port=12345 +``` + +Your application URL will be `http://localhost:12345` + +## Deploy to Google App Engine + +You can also deploy the application to the live App Engine serving +environment on Google Cloud Platform. For this scenario, you must first create +a project in the +[Google Developers Console](https://console.developers.google.com). + +To deploy the application, enter the following: + +```bash +$ $WORKSPACE/bazel-bin/backend/backend.deploy <project-id> +``` + +The deployment script prompts you to authorize access to Google Cloud Platform. +After you have authorized access the first time, you can deploy the application +using the `bazel` command and the following rule target: + +```bash +$ bazel run //backend:backend.deploy <project-id> +``` + +Your application URL will be `http://<project-id>.appspot.com`. + +## What's next + +Now let's [review](review.md) the tutorial steps. diff --git a/site/docs/tutorial/cpp.md b/site/docs/tutorial/cpp.md index 6ec737f93d..3d6effbd68 100644 --- a/site/docs/tutorial/cpp.md +++ b/site/docs/tutorial/cpp.md @@ -1,4 +1,360 @@ --- -layout: redirect -redirect: docs/tutorial/cpp.html +layout: documentation +title: Build C++ --- + +Build C++ +========= + +You can use Bazel to build your C++ application. In this tutorial you'll learn how to: + +* Build your first C++ target +* Use external libraries +* Write and run C++ tests +* Use precompiled libraries + +## Setting up your workspace + +Suppose that you have an existing project in a directory, say, +`~/gitroot/my-project/`. Create an empty file at +`~/gitroot/my-project/WORKSPACE` to show Bazel where your project's root is. +We are going to create a small hello world project with the following directory structure: +{% highlight bash %} +└── my-project + ├── lib + │ ├── BUILD + │ ├── hello-greet.cc + │ └── hello-greet.h + ├── main + │ ├── BUILD + │ ├── hello-time.cc + │ ├── hello-time.h + │ └── hello-world.cc + └── WORKSPACE +{% endhighlight %} + +## Creating source files + +Using the following commands to create the necessary source files: +{% highlight bash %} +$ # If you're not already there, move to your workspace directory. +$ cd ~/gitroot/my-project +$ mkdir ./main +$ cat > main/hello-world.cc <<'EOF' +#include "lib/hello-greet.h" +#include "main/hello-time.h" +#include <iostream> +#include <string> + +int main(int argc, char** argv) { + std::string who = "world"; + if (argc > 1) { + who = argv[1]; + } + std::cout << get_greet(who) <<std::endl; + print_localtime(); + return 0; +} +EOF +$ cat > main/hello-time.h <<'EOF' +#ifndef MAIN_HELLO_TIME_H_ +#define MAIN_HELLO_TIME_H_ + +void print_localtime(); + +#endif +EOF +$ cat > main/hello-time.cc <<'EOF' +#include "main/hello-time.h" +#include <ctime> +#include <iostream> + +void print_localtime() { + std::time_t result = std::time(nullptr); + std::cout << std::asctime(std::localtime(&result)); +} +EOF +$ mkdir ./lib +$ cat > lib/hello-greet.h <<'EOF' +#ifndef LIB_HELLO_GREET_H_ +#define LIB_HELLO_GREET_H_ + +#include <string> + +std::string get_greet(const std::string &thing); + +#endif +EOF +$ cat > lib/hello-greet.cc <<'EOF' +#include "lib/hello-greet.h" +#include <string> + +std::string get_greet(const std::string& who) { + return "Hello " + who; +} +EOF +{% endhighlight %} + +## Adding BUILD files + +As you can see from the source code, `main/hello-world.cc` needs to include both `lib/hello-greet.h` and `main/hello-time.h`. +First we create `lib/BUILD` for hello-greet.cc: + +{% highlight python %} +cc_library( + name = "hello-greet", + srcs = ["hello-greet.cc"], + hdrs = ["hello-greet.h"], + visibility = ["//main:__pkg__"], +) +{% endhighlight %} + +Note that `visibility = ["//main:__pkg__"]` indicates `hello-greet` is visible from `main/BUILD`. +Then we'd create the following `main/BUILD` file: + +{% highlight python %} +cc_library( + name = "hello-time", + srcs = ["hello-time.cc"], + hdrs = ["hello-time.h"], +) + +cc_binary( + name = "hello-world", + srcs = ["hello-world.cc"], + deps = [ + ":hello-time", + "//lib:hello-greet", + ], +) +{% endhighlight %} + +Note when depending on a target in the same package, we can just use `:hello-time`. +When the target is in other package, a full path from root should be used, like `//lib:hello-greet`. + +Now you are ready to build your hello world C++ binary: + +{% highlight bash %} +$ bazel build main:hello-world +INFO: Found 1 target... +Target //main:hello-world up-to-date: + bazel-bin/main/hello-world +INFO: Elapsed time: 2.869s, Critical Path: 1.00s +$ ./bazel-bin/main/hello-world +Hello world +Thu Jun 23 18:51:46 2016 +$ ./bazel-bin/main/hello-world Bazel +Hello Bazel +Thu Jun 23 18:52:10 2016 +{% endhighlight %} + +Congratulations, you've just built your first Bazel target! + +## Transitive includes + +If a file includes a header, then the file's rule should depend on that header's +library. Conversely, only direct dependencies need to be specified as +dependencies. For example, suppose `sandwich.h` includes `bread.h` and +`bread.h` includes `flour.h`. `sandwich.h` doesn't include `flour.h` (who wants +flour in their sandwich?), so the BUILD file would look like: + +```python +cc_library( + name = "sandwich", + srcs = ["sandwich.cc"], + hdrs = ["sandwich.h"], + deps = [":bread"], +) + +cc_library( + name = "bread", + srcs = ["bread.cc"], + hdrs = ["bread.h"], + deps = [":flour"], +) + +cc_library( + name = "flour", + srcs = ["flour.cc"], + hdrs = ["flour.h"], +) +``` + +Here, the `sandwich` library depends on the `bread` library, which depends +on the `flour` library. + +## Adding include paths + +Sometimes you cannot (or do not want to) base include paths at the workspace +root. Existing libraries might already have a include directory that doesn't +match its path in your workspace. For example, suppose you have the following +directory structure: + +``` +└── my-project + ├── third_party + │ └── some_lib + │ ├── BUILD + │ ├── include + │ │ └── some_lib.h + │ └── some_lib.cc + └── WORKSPACE +``` + +Bazel will expect `some_lib.h` to be included as +`third_party/some_lib/include/some_lib.h`, but suppose `some_lib.cc` includes +`"include/some_lib.h"`. To make that include path valid, +`third_party/some_lib/BUILD` will need to specify that the `some_lib/` +directory is an include directory: + +```python +cc_library( + name = "some_lib", + srcs = ["some_lib.cc"], + hdrs = ["some_lib.h"], + copts = ["-Ithird_party/some_lib"], +) +``` + +This is especially useful for external dependencies, as their header files +must otherwise be included with an `external/[repository-name]/` prefix. + +## Including external libraries + +Suppose you are using [Google Test](https://code.google.com/p/googletest/). You +can use one of the `new_` repository functions in the `WORKSPACE` file to +download Google Test and make it available in your repository: + +```python +new_http_archive( + name = "gtest", + url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip", + sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d", + build_file = "gtest.BUILD", +) +``` + +Then create `gtest.BUILD`, a BUILD file to use to compile Google Test. +Google Test has several "special" requirements that make its `cc_library` rule +more complicated: + +* `gtest-1.7.0/src/gtest-all.cc` `#include`s all of the other files in + `gtest-1.7.0/src/`, so we need to exclude it from the compile or we'll get + link errors for duplicate symbols. +* It uses header files that relative to the `gtest-1.7.0/include/` directory + (`"gtest/gtest.h"`), so we must add that directory the include paths. +* It needs to link in pthread, so we add that as a `linkopt`. + +The final rule looks like this: + +```python +cc_library( + name = "main", + srcs = glob( + ["gtest-1.7.0/src/*.cc"], + exclude = ["gtest-1.7.0/src/gtest-all.cc"] + ), + hdrs = glob([ + "gtest-1.7.0/include/**/*.h", + "gtest-1.7.0/src/*.h" + ]), + copts = [ + "-Iexternal/gtest/gtest-1.7.0/include" + ], + linkopts = ["-pthread"], + visibility = ["//visibility:public"], +) +``` + +This is somewhat messy: everything is prefixed with gtest-1.7.0 as a byproduct +of the archive's structure. You can make `new_http_archive` strip this prefix by +adding the `strip_prefix` attribute: + +```python +new_http_archive( + name = "gtest", + url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip", + sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d", + build_file = "gtest.BUILD", + strip_prefix = "gtest-1.7.0", +) +``` + +Then `gtest.BUILD` would look like this: + +```python +cc_library( + name = "main", + srcs = glob( + ["src/*.cc"], + exclude = ["src/gtest-all.cc"] + ), + hdrs = glob([ + "include/**/*.h", + "src/*.h" + ]), + copts = ["-Iexternal/gtest/include"], + linkopts = ["-pthread"], + visibility = ["//visibility:public"], +) +``` + +Now `cc_` rules can depend on `//external:gtest/main`. + +## Writing and running C++ tests + +For example, we could create a test `./test/hello-test.cc` such as: + +```cpp +#include "gtest/gtest.h" +#include "lib/hello-greet.h" + +TEST(FactorialTest, Negative) { + EXPECT_EQ(get_greet("Bazel"), "Hello Bazel"); +} +``` + +Then create `./test/BUILD` file for your tests: + +```python +cc_test( + name = "hello-test", + srcs = ["hello-test.cc"], + copts = ["-Iexternal/gtest/include"], + deps = [ + "@gtest//:main", + "//lib:hello-greet", + ], +) +``` + +Note in order to make `hello-greet` visible to `hello-test`, we have to add `"//test:__pkg__",` to `visibility` attribute in `./lib/BUILD`. + +Now you can use `bazel test` to run the test. + +{% highlight bash %} +$ bazel test test:hello-test +INFO: Found 1 test target... +Target //test:hello-test up-to-date: + bazel-bin/test/hello-test +INFO: Elapsed time: 4.497s, Critical Path: 2.53s +//test:hello-test PASSED in 0.3s + +Executed 1 out of 1 tests: 1 test passes. +{% endhighlight %} + + +## Adding dependencies on precompiled libraries + +If you want to use a library that you only have a compiled version of (e.g., +headers and a .so) wrap it in a `cc_library` rule: + +```python +cc_library( + name = "mylib", + srcs = ["mylib.so"], + hdrs = ["mylib.h"], +) +``` + +Then other C++ targets in your workspace can depend on this rule. diff --git a/site/docs/tutorial/environment.md b/site/docs/tutorial/environment.md index 8ce35d68a2..219060de7c 100644 --- a/site/docs/tutorial/environment.md +++ b/site/docs/tutorial/environment.md @@ -1,4 +1,91 @@ --- -layout: redirect -redirect: docs/tutorial/environment.html +layout: documentation +title: Tutorial - Set Up Your Environment --- + +# Tutorial - Set Up Your Environment + +The first step in this tutorial is to set up your environment. + +Here, you'll do the following: + +* Install Bazel +* Install Android Studio and the Android SDK +* Install Xcode (OS X only) +* Get the sample project from the GitHub repo + +## Install Bazel + +Follow the [installation instructions](/docs/install.md) to install Bazel and +its dependencies. + +## Install the Android SDK tools + +Do the following: + +1. Download and install the + [Android SDK Tools](https://developer.android.com/sdk/index.html#Other). + +2. Run the Android SDK Manager and install the following packages: + + <table class="table table-condensed table-striped"> + <thead> + <tr> + <td>Package</td> + <td>SDK directory</td> + </tr> + </thead> + <tbody> + <tr> + <td>Android SDK Platform Tools</td> + <td><code>platform-tools</code></td> + </tr> + <tr> + <td>Android SDK Build Tools</td> + <td><code>build-tools</code></td> + </tr> + <tr> + <td>Android SDK Platform</td> + <td><code>platform</code></td> + </tr> + </tbody> + </table> + + The SDK Manager is an executable named `android` located in the `tools` + directory. + +## Install Xcode (OS X only) + +If you are following the steps in this tutorial on Mac OS X, download and +install [Xcode](https://developer.apple.com/xcode/downloads/). The Xcode +download contains the iOS libraries, Objective-C compiler other tools +required by Bazel to build the iOS app. + +## Get the sample project + +You also need to get the sample project for the tutorial from GitHub: + +[https://github.com/bazelbuild/examples/](https://github.com/bazelbuild/examples/) + +The GitHub repo has two branches: `source-only` and `master`. The `source-only` +branch contains the source files for the project only. You'll use the files in +this branch in this tutorial. The `master` branch contains both the source files +and completed Bazel `WORKSPACE` and `BUILD` files. You can use the files in this +branch to check your work when you've completed the tutorial steps. + +Enter the following at the command line to get the files in the `source-only` +branch: + +```bash +$ cd $HOME +$ git clone -b source-only https://github.com/bazelbuild/examples +``` + +The `git clone` command creates a directory named `$HOME/examples/`. This +directory contains several sample projects for Bazel. The project files for this +tutorial are in `$HOME/examples/tutorial`. + +## What's next + +Now that you have set up your environment, you can +[set up a Bazel workspace](workspace.md). diff --git a/site/docs/tutorial/ios-app.md b/site/docs/tutorial/ios-app.md index e77b36907e..51774e9312 100644 --- a/site/docs/tutorial/ios-app.md +++ b/site/docs/tutorial/ios-app.md @@ -1,4 +1,206 @@ --- -layout: redirect -redirect: docs/tutorial/ios-app.html +layout: documentation +title: Tutorial - Build an iOS App --- + +# Tutorial - Build an iOS App + +Like the [Android app](android-app.md) you built in the previous step, the iOS +app is a simple mobile app that communicates with the +[backend server](backend-server.md). + +Here, you'll do the following: + +* Review the source files for the app +* Create a `BUILD` file +* Build the app for the simulator +* Find the build outputs +* Run/Debug the app on the simulator +* Build the app for a device +* Install the app on a device + +Note that, unlike with the Android app, you don't have to modify your +`WORKSPACE` file to add iOS-specific external dependencies. + +If you're following the steps in this tutorial on Mac OS X, you can go ahead +and build the sample iOS app as described below. If you are on Linux, skip ahead +to the [next step](backend-server.md). + +## Review the source files + +Let's take a look at the source files for the app. These are located in +`$WORKSPACE/ios-app/UrlGet`. Again, you're just looking at these files now to +become familiar with the structure of the app. You don't have to edit any of the +source files to complete this tutorial. + +## Create a BUILD file + +At a command-line prompt, open your new `BUILD` file for editing: + +```bash +$ vi $WORKSPACE/ios-app/BUILD +``` + +## Add an objc_library rule + +Bazel provides several build rules that you can use to build an app for the +iOS platform. For this tutorial, you'll first use the +[`objc_library`](/docs/be/objective-c.html#objc_library) rule to tell Bazel +how to build an +[static library](https://developer.apple.com/library/ios/technotes/iOSStaticLibraries/Introduction.html) +from the app source code and Xib files. Then you'll use the +`objc_binary` rule to tell it how to bundle the iOS application. (Note that +this is a minimal use case of the Objective-C rules in Bazel. For example, you +have to use the `ios_application` rule to build multi-architecture iOS +apps.) + +Add the following to your `BUILD` file: + +```python +objc_library( + name = "UrlGetClasses", + srcs = [ + "UrlGet/AppDelegate.m", + "UrlGet/UrlGetViewController.m", + ], + hdrs = glob(["UrlGet/*.h"]), + xibs = ["UrlGet/UrlGetViewController.xib"], +) +``` + +Note the name of the rule, `UrlGetClasses`. + +## Add an objc_binary rule + +The [`objc_binary`](/docs/be/objective-c.html#objc_binary) rule creates a +binary to be bundled in the application. + +Add the following to your `BUILD` file: + +```python +objc_binary( + name = "ios-app-binary", + srcs = [ + "UrlGet/main.m", + ], + deps = [ + ":UrlGetClasses", + ], +) + +``` +Note how the `deps` attribute references the output of the +`UrlGetClasses` rule you added to the `BUILD` file above. + +## Add an ios_application rule + +The [`ios_application`](/docs/be/objective-c.html#ios_application) rule +creates the bundled `.ipa` archive file for the application and also generates +an Xcode project file. + +Add the following to your `BUILD` file: + +```python +ios_application( + name = "ios-app", + binary = ":ios-app-binary", + infoplist = "UrlGet/UrlGet-Info.plist", +) +``` + +Now, save and close the file. You can compare your `BUILD` file to the +[completed example](https://github.com/bazelbuild/examples/blob/master/tutorial/ios-app/BUILD) +in the `master` branch of the GitHub repo. + +## Build the app for the simulator + +Make sure that your current working directory is inside your Bazel workspace: + +```bash +$ cd $WORKSPACE +``` + +Now, enter the following to build the sample app: + +```bash +$ bazel build //ios-app:ios-app +``` + +Bazel now launches and builds the sample app. During the build process, its +output will appear similar to the following: + +```bash +INFO: Found 1 target... +Target //ios-app:ios-app up-to-date: + bazel-bin/ios-app/ios-app.ipa + bazel-bin/ios-app/ios-app.xcodeproj/project.pbxproj +INFO: Elapsed time: 3.765s, Critical Path: 3.44s +``` + +## Find the build outputs + +The `.ipa` file and other outputs are located in the +`$WORKSPACE/bazel-bin/ios-app` directory. + +## Run/Debug the app on the simulator + +You can now run the app from Xcode using the iOS Simulator. To run the app, +open the project directory `$WORKSPACE/bazel-bin/ios-app/ios-app.xcodeproj` in +Xcode, choose an iOS Simulator as the runtime scheme and then click the **Run** +button. + +**Note:** If you change anything about the project file set in Xcode (for +example, if you add or remove a file, or add or change a dependency), you must +rebuild the app using Bazel and then re-open the project. + +## Build the app for a device + +You need to set up bazel so that it can find the appropriate provisioning +profile for the device you want to build for. To set up the "default" +provisioning profile for all bazel builds: + + 1. Go to [Apple Profiles](https://developer.apple.com/account/ios/profile/profileList.action) + and download the appropriate provisioning profile for your device. + If this is confusing, please refer to [Apple's documentation](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingProfiles/MaintainingProfiles.html). + 1. Move your profile into `$WORKSPACE/tools/objc`. + 1. Optional - You may want to add your profile to your `.gitignore`. + 1. Edit `$WORKSPACE/tools/objc/BUILD` and add: + + ```python + filegroup( + name = "default_provisioning_profile", + srcs = ["<NAME OF YOUR PROFILE>.mobileprovision"], + ) + ``` + +Now you should be able to build the app for your device: + +```bash +$ bazel build //ios-app:ios-app --ios_multi_cpus=armv7,arm64 +``` + +This will build the app "fat". If you would prefer just to build for +your specific device architecture you can designate a single architecture. + +If you would like to select a specific Xcode version/SDK version you can do so +with the `--xcode_version=7.2 --ios_sdk_version=9.2` options. Make sure that +the Xcode version that you select has the appropriate SDK installed in it. + +If you would like to specify a minimum version of iOS to run against, you can +do so with the `--ios_minimum_os=7.0` option. + +## Install the app on a device + +The easiest way to install the app on the device is to launch Xcode and use the +`Windows > Devices` command. Select your plugged in device from the list on the +left, and then add the app by clicking on the "plus" sign under installed apps +and selecting the `.ipa` that you built. + +If your app does not launch, please make sure that your device was on your +provisioning profile. The `View Device Logs` button on the `Devices` screen in +Xcode may provide other information as to what has gone wrong. + +## What's next + +The next step is to build a [backend server](backend-server.md) for the two +mobile apps you built in this tutorial. diff --git a/site/docs/tutorial/java.md b/site/docs/tutorial/java.md index aeeac5483a..ce916667e1 100644 --- a/site/docs/tutorial/java.md +++ b/site/docs/tutorial/java.md @@ -1,4 +1,245 @@ --- -layout: redirect -redirect: docs/tutorial/java.html +layout: documentation +title: Build Java --- + +Build Java +========== + +You can use Bazel to build your Java application. In this tutorial you'll learn how to: + +* Build your first Java target +* Add dependencies to your target +* Use multiple packages +* Deploy your target + +## Setting up your workspace + +Suppose that you have an existing project in a directory, say, +`~/gitroot/my-project/`. Create an empty file at +`~/gitroot/my-project/WORKSPACE` to show Bazel where your project's root is. + +## Creating Your Own Build File + +Use the following commands to make a small Java project for this example: + +{% highlight bash %} +$ # If you're not already there, move to your workspace directory. +$ cd ~/gitroot/my-project +$ mkdir -p src/main/java/com/example +$ cat > src/main/java/com/example/ProjectRunner.java <<'EOF' +package com.example; + +public class ProjectRunner { + public static void main(String args[]) { + Greeting.sayHi(); + } +} +EOF +$ cat > src/main/java/com/example/Greeting.java <<'EOF' +package com.example; + +public class Greeting { + public static void sayHi() { + System.out.println("Hi!"); + } +} +EOF +{% endhighlight %} + +Bazel figures out what to build by looking for files named `BUILD` in your +workspace, so we'll create a `BUILD` file in the `~/gitroot/my-project` +directory. Add the following lines to this BUILD file: + +{% highlight python %} +# ~/gitroot/my-project/BUILD +java_binary( + name = "my-runner", + srcs = glob(["**/*.java"]), + main_class = "com.example.ProjectRunner", +) +{% endhighlight %} + +`java_binary` is the type of thing this rule will build. +`glob(["**/*.java"])` is a handy shorthand for "recursively include every file +that ends with .java" (see the +[build encyclopedia](be/functions.html#glob) for more information about +globbing). `com.example.ProjectRunner` specifies the class that contains the +main method. + +Now you are ready to build your Java binary: + +{% highlight bash %} +$ cd ~/gitroot/my-project +$ bazel build //:my-runner +INFO: Found 1 target... +Target //:my-runner up-to-date: + bazel-bin/my-runner.jar + bazel-bin/my-runner +INFO: Elapsed time: 1.021s, Critical Path: 0.83s +$ bazel-bin/my-runner +Hi! +{% endhighlight %} + +Congratulations, you've just built your first Bazel target! + +## Adding Dependencies + +Creating one rule to build your entire project may be sufficient for small +projects, but as projects get larger it's important to break up the build into +self-contained libraries that can be assembled into a final product. This way +the entire world doesn't need to be rebuilt on small changes and Bazel can +parallelize more of the build steps. + +To break up a project, create separate rules for each subcomponent and then +make them depend on each other. For the example above, add the following rules +to the `BUILD` file: + +{% highlight python %} +java_binary( + name = "my-other-runner", + srcs = ["src/main/java/com/example/ProjectRunner.java"], + main_class = "com.example.ProjectRunner", + deps = [":greeter"], +) + +java_library( + name = "greeter", + srcs = ["src/main/java/com/example/Greeting.java"], +) +{% endhighlight %} + +This builds the same files as before, but in a different way: now Bazel will +build the `greeter` library first and then build `my-other-runner`. Try building +and running `//:my-other-runner`: + +{% highlight bash %} +$ bazel run //:my-other-runner +INFO: Found 1 target... +Target //:my-other-runner up-to-date: + bazel-bin/my-other-runner.jar + bazel-bin/my-other-runner +INFO: Elapsed time: 2.454s, Critical Path: 1.58s + +INFO: Running command line: bazel-bin/my-other-runner +Hi! +{% endhighlight %} + +Now if you edit `ProjectRunner.java` and rebuild `my-other-runner`, +`Greeting.java` will not need to be recompiled. + +## Using Multiple Packages + +For larger projects, you will often be dealing with several directories. You +can refer to targets defined in other BUILD files using the syntax +`//path/to/directory:target-name`. For example, suppose +`src/main/java/com/example/` has a `cmdline/` subdirectory with the following +file: + +{% highlight bash %} +$ mkdir -p src/main/java/com/example/cmdline +$ cat > src/main/java/com/example/cmdline/Runner.java <<'EOF' +package com.example.cmdline; + +import com.example.Greeting; + +public class Runner { + public static void main(String args[]) { + Greeting.sayHi(); + } +} +EOF +{% endhighlight %} + +`Runner.java` depends on `com.example.Greeting`, so we could add a `BUILD` file +at `src/main/java/com/example/cmdline/BUILD` that contained the following rule: + +{% highlight python %} +# ~/gitroot/my-project/src/main/java/com/example/cmdline/BUILD +java_binary( + name = "runner", + srcs = ["Runner.java"], + main_class = "com.example.cmdline.Runner", + deps = ["//:greeter"] +) +{% endhighlight %} + +However, by default, build rules are _private_. This means that they can only be +referred to by rules in the same BUILD file. This prevents libraries that are +implementation details from leaking into public APIs, but it also means that you +must explicitly allow `runner` to depend on `//:greeter`. As is, if we +build `runner` we'll get a permissions error: + +{% highlight bash %} +$ bazel build //src/main/java/com/example/cmdline:runner +ERROR: /home/user/gitroot/my-project/src/main/java/com/example/cmdline/BUILD:2:1: + Target '//:greeter' is not visible from target '//src/main/java/com/example/cmdline:runner'. + Check the visibility declaration of the former target if you think the dependency is legitimate. +ERROR: Analysis of target '//src/main/java/com/example/cmdline:runner' failed; build aborted. +INFO: Elapsed time: 0.091s +{% endhighlight %} + +You can make a rule visible to rules in other BUILD files by adding a +`visibility = level` attribute. Change the `greeter` rule in +`~/gitroot/my-project/BUILD` to be visible to our new rule: + +{% highlight python %} +java_library( + name = "greeter", + srcs = ["src/main/java/com/example/Greeting.java"], + visibility = ["//src/main/java/com/example/cmdline:__pkg__"], +) +{% endhighlight %} + +This makes `//:greeter` visible to any rule in the +`//src/main/java/com/example/cmdline` package. Now we can build and +run the `runner` binary: + +{% highlight bash %} +$ bazel run //src/main/java/com/example/cmdline:runner +INFO: Found 1 target... +Target //src/main/java/com/example/cmdline:runner up-to-date: + bazel-bin/src/main/java/com/example/cmdline/runner.jar + bazel-bin/src/main/java/com/example/cmdline/runner +INFO: Elapsed time: 1.576s, Critical Path: 0.81s + +INFO: Running command line: bazel-bin/src/main/java/com/example/cmdline/runner +Hi! +{% endhighlight %} + +See the [build encyclopedia](be/common-definitions.html#common.visibility) for more +visibility options. + +## Deploying + +If you look at the contents of +_bazel-bin/src/main/java/com/example/cmdline/runner.jar_, you can see that it +only contains `Runner.class`, not its dependencies (`Greeting.class`): + +{% highlight bash %} +$ jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar +META-INF/ +META-INF/MANIFEST.MF +com/ +com/example/ +com/example/cmdline/ +com/example/cmdline/Runner.class +{% endhighlight %} + +This works for running locally (the `runner` script Bazel generates adds the +greeter jar to the classpath) but will not work if we want to copy `runner.jar` +to another machine and use it as a standalone binary. To build a self-contained +jar that can be deployed, build `runner_deploy.jar` (or, more generally, +`<target-name>_deploy.jar`): + +{% highlight bash %} +$ bazel build //src/main/java/com/example/cmdline:runner_deploy.jar +INFO: Found 1 target... +Target //src/main/java/com/example/cmdline:runner_deploy.jar up-to-date: + bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar +INFO: Elapsed time: 1.700s, Critical Path: 0.23s +{% endhighlight %} + +`runner_deploy.jar` will contain all of its dependencies. + + diff --git a/site/docs/tutorial/review.md b/site/docs/tutorial/review.md index 16557f7527..62d4501ad4 100644 --- a/site/docs/tutorial/review.md +++ b/site/docs/tutorial/review.md @@ -1,4 +1,29 @@ --- -layout: redirect -redirect: docs/tutorial/review.html +layout: documentation +title: Tutorial - Review --- + +# Tutorial - Review + +In this tutorial, you used Bazel to build an [Android app](android-app.md), +an [iOS app](ios-app.md) and a [backend server](backend-server.md) that runs on +Google App Engine. + +To build these software outputs, you: + +* Set up a Bazel [workspace](workspace.md) that contained the source code + for the components and a `WORKSPACE` that identifies the top level of the + workspace directory +* Created a `BUILD` file for each component +* Updated the `WORKSPACE` file to contain references to the required + external dependencies +* Ran Bazel to build the software components + +The built mobile apps and backend server application files are located in the +`$WORKSPACE/bazel-bin` directory. + +Note that completed `WORKSPACE` and `BUILD` files for this tutorial are located +in the +[master branch](https://github.com/bazelbuild/examples/tree/master/tutorial) +of the GitHub repo. You can compare your work to the completed files for +additional help or troubleshooting. diff --git a/site/docs/tutorial/workspace.md b/site/docs/tutorial/workspace.md index 76a2a7cd14..ff3f6da510 100644 --- a/site/docs/tutorial/workspace.md +++ b/site/docs/tutorial/workspace.md @@ -1,4 +1,53 @@ --- -layout: redirect -redirect: docs/tutorial/workspace.html +layout: documentation +title: Tutorial - Set Up a Workspace --- + +# Tutorial - Set Up a Workspace + +A [workspace](/docs/build-ref.html#workspaces) is a directory that contains the +source files for one or more software projects, as well as a `WORKSPACE` file +and `BUILD` files that contain the instructions that Bazel uses to build +the software. It also contains symbolic links to output directories in the +Bazel home directory. + +A workspace directory can be located anywhere on your filesystem. In this +tutorial, your workspace directory is `$HOME/examples/tutorial/`, which +contains the sample project files you cloned from the GitHub repo in the +previous step. + +Note that Bazel itself doesn't make any requirements about how you organize +source files in your workspace. The sample source files in this tutorial are +organized according to common conventions for Android apps, iOS apps and App +Engine applications. + +For your convenience, set the `$WORKSPACE` environment variable now to refer to +your workspace directory. At the command line, enter: + +```bash +$ export WORKSPACE=$HOME/examples/tutorial +``` + +## Create a WORKSPACE file + +Every workspace must have a text file named `WORKSPACE` located in the top-level +workspace directory. This file may be empty or it may contain references +to [external dependencies](/docs/external.html) required to build the +software. + +For now, you'll create an empty `WORKSPACE` file, which simply serves to +identify the workspace directory. In later steps, you'll update the file to add +external dependency information. + +Enter the following at the command line: + +```bash +$ touch $WORKSPACE/WORKSPACE +``` + +This creates the empty `WORKSPACE` file. + +## What's next + +Now that you've set up your workspace, you can +[build the Android app](android-app.md). diff --git a/site/docs/windows.md b/site/docs/windows.md index 8bf61e0e3b..ca7f0241d9 100644 --- a/site/docs/windows.md +++ b/site/docs/windows.md @@ -1,4 +1,37 @@ --- -layout: redirect -redirect: docs/windows.html +layout: documentation +title: Windows --- + +Building Bazel on Windows +========================= + +Windows support is highly experimental. Known issues are [marked with +label "Windows"](https://github.com/bazelbuild/bazel/issues?q=is%3Aissue+is%3Aopen+label%3AWindows) +on github issues. + +We currently support only 64 bit Windows 7 or higher and we can only compile +msys2 binaries. + +To bootstrap Bazel on Windows, you will need: + +* Java JDK 8 or later +* Visual Studio (Community Edition is okay, only `CL.EXE` is needed) +* [msys2](https://msys2.github.io/) (need to be installed at + ``C:\tools\msys64\``). +* Several msys2 packages. Use the ``pacman`` command to install them: + ``pacman -S gcc git curl zip unzip zlib-devel`` + +To build Bazel: + +* Open the msys2 shell. +* Clone the Bazel git repository as normal. +* Set the environment variables: + +```bash +export JAVA_HOME="$(ls -d C:/Program\ Files/Java/jdk* | sort | tail -n 1)" +export BAZEL_SH=c:/tools/msys64/usr/bin/bash.exe +``` + +* Run ``compile.sh`` in Bazel directory. +* If all works fine, bazel will be built at ``output\bazel.exe``. diff --git a/site/faq.md b/site/faq.md index 7177290208..ff9939ae96 100644 --- a/site/faq.md +++ b/site/faq.md @@ -1,4 +1,424 @@ --- -layout: redirect -redirect: faq.html +layout: default +title: FAQ +nav: faq --- + +What is Bazel? +-------------- + +Bazel is a tool that automates software builds and tests. Supported build tasks +include running compilers and linkers to produce executable programs and +libraries, and assembling deployable packages for Android, iOS and other target +environments. Bazel is similar to other tools like Make, Ant, Gradle, Buck, +Pants and Maven. + +What is special about Bazel? +---------------------------- + +Bazel was designed to fit the way software is developed at Google. It +has the following features: + +* Multi-language support: Bazel supports Java, Objective-C and C++ out + of the box, and can be extended to support arbitrary programming + languages. + +* High-level build language: Projects are described in the BUILD + language, a concise text format that describes a project as sets of + small interconnected libraries, binaries and tests. In contrast, with + tools like Make, you have to describe individual files and compiler + invocations. + +* Multi-platform support: The same tool and the same BUILD files can + be used to build software for different architectures, and even + different platforms. At Google, we use Bazel to build everything from + server applications running on systems in our data centers to client apps + running on mobile phones. + +* Reproducibility: In BUILD files, each library, test and binary must + specify its direct dependencies completely. Bazel uses this + dependency information to know what must be rebuilt when you make + changes to a source file, and which tasks can run in parallel. This + means that all builds are incremental and will always produce the + same result. + +* Scalable: Bazel can handle large builds; at Google, it is common for + a server binary to have 100k source files, and builds where no files + were changed take about ~200ms. + + +Why doesn't Google use ...? +--------------------------- + +* Make, Ninja: These tools give very exact control over what commands + get invoked to build files, but it's up to the user to write rules + that are correct. + + Users interact with Bazel on a higher level. For example, Bazel has + built-in rules for "Java test", "C++ binary", and notions such as + "target platform" and "host platform". These rules have been battle + tested to be foolproof. + +* Ant and Maven: Ant and Maven are primarily geared toward Java, while + Bazel handles multiple languages. Bazel encourages subdividing + codebases in smaller reusable units, and can rebuild only ones that + need rebuilding. This speeds up development when working with larger + codebases. + +* Gradle: Bazel configuration files are much more structured than + Gradle's, letting Bazel understand exactly what each action does. + This allows for more parallelism and better reproducibility. + +* Pants, Buck: Both tools were created and developed by ex-Googlers at + Twitter and Foursquare, and Facebook respectively. They have been modeled + after Bazel, but their feature sets are different, so they aren't viable + alternatives for us. + + +Where did Bazel come from? +-------------------------- + +Bazel is a flavor of the tool that Google uses to build its server +software internally. It has expanded to build other software as well, +like mobile apps (iOS, Android) that connect to our servers. + +Did you rewrite your internal tool as open-source? Is it a fork? +---------------------------------------------------------------- + +Bazel shares most of its code with the internal tool and its rules +are used for millions of builds every day. + +Why did Google build Bazel? +--------------------------- + +A long time ago, Google built its software using large, generated +Makefiles. These led to slow and unreliable builds, which began to +interfere with our developers' productivity and the company's +agility. Bazel was a way to solve these problems. + +Does Bazel require a build cluster? +----------------------------------- + +Google's in-house flavor of Bazel does use [build +clusters](http://google-engtools.blogspot.com/2011/09/build-in-cloud-distributing-build-steps.html), +so Bazel does have hooks in the code base to plug in a remote build +cache or a remote execution system. + +The open source Bazel code runs build operations locally. We believe +that this is fast enough for most of our users. + +How does the Google development process work? +---------------------------------------------- + +For our server code base, we use the following development workflow: + +* All our server code is in a single, gigantic version control + system. + +* Everybody builds their software with Bazel. + +* Different teams own different parts of the source tree, and make + their components available as BUILD targets. + +* Branching is primarily used for managing releases, so everybody + develops their software at the head revision. + +Bazel is a cornerstone of this philosophy: since Bazel requires all +dependencies to be fully specified, we can predict which programs and +tests are affected by a change, and vet them before submission. + +More background on the development process at Google can be found on +the [eng tools blog](http://google-engtools.blogspot.com/). + +Why are you opening up Bazel? +----------------------------- + +Building software should be fun and easy. Slow and unpredictable +builds take the fun out of programming. + +Why would I want to use Bazel? +------------------------------ + +* Bazel may give you faster build times because it can recompile only + the files that need to be recompiled. Similarly, it can skip + re-running tests that it knows haven't changed. + +* Bazel produces deterministic results. This eliminates skew + between incremental and clean builds, laptop and CI system, etc. + +* Bazel can build different client and server apps with the same tool + from the same workspace. For example, you can change a client/server + protocol in a single commit, and test that the updated mobile app + works with the updated server, building both with the same tool, + reaping all the aforementioned benefits of Bazel. + +Can I see examples? +------------------- + +Yes. For a simple example, see: + + <https://github.com/bazelbuild/bazel/blob/master/examples/cpp/BUILD> + +The Bazel source code itself provides a more complex example: + + <https://github.com/bazelbuild/bazel/blob/master/src/BUILD> + +What is Bazel best at? +---------------------- + +Bazel shines at building and testing projects with the following properties: + +* Projects with a large codebase +* Projects written in (multiple) compiled languages +* Projects that deploy on multiple platforms +* Projects that have extensive tests + +Where can I run Bazel? +--------------------------------- + +Currently, Linux and Mac OS X. Porting to other UNIX platforms should be +straightforward, as long as a JDK is available for the platform. + +What about Windows? +------------------- + +Due to its UNIX heritage, porting Bazel to Windows is significant work. For +example, Bazel uses symlinks extensively, which has varying levels of support +across Windows versions. + +We are currently actively working on improving Windows support, but it's still +ways from being usable. + +What should I not use Bazel for? +-------------------------------- + +* Bazel tries to be smart about caching. This means that it is not good + for running build operations whose outputs should not be cached. For example, + the following steps should not be run from Bazel: + + * A compilation step that fetches data from the internet. + * A test step that connects to the QA instance of your site. + * A deployment step that changes your site's cloud configuration. + +* Bazel tries to minimize expensive compilation steps. If you are only + using interpreted languages directly, such as JavaScript or Python, + Bazel will likely not interest you. + +How stable is Bazel's feature set? +---------------------------------- + +The core features (C++, Java, and shell rules) have extensive use +inside Google, so they are thoroughly tested and have very little +churn. Similarly, we test new versions of Bazel across hundreds of +thousands of targets every day to find regressions, and we release new +versions multiple times every month. + +In short, except for features marked as experimental, Bazel should Just Work. +Changes to non-experimental rules will be backward compatible. A more detailed +list of feature support statuses can be found in our +[support document](support.html). + +How stable is Bazel as a binary? +-------------------------------- + +Inside Google, we make sure that Bazel crashes are very rare. This +should also hold for our open source codebase. + +How can I start using Bazel? +---------------------------- + +See our [getting started document](docs/getting-started.html). + +Doesn't Docker solve the reproducibility problems? +-------------------------------------------------- + +With Docker you can easily create sandboxes with fixed OS releases, +for example, Ubuntu 12.04, Fedora 21. This solves the problem of +reproducibility for the system environment -- that is, "which version of +/usr/bin/c++ do I need?" + +Docker does not address reproducibility with regard to changes in the +source code. Running Make with an imperfectly written Makefile inside a +Docker container can still yield unpredictable results. + +Inside Google, we check tools into source control for reproducibility. +In this way, we can vet changes to tools ("upgrade GCC to 4.6.1") with +the same mechanism as changes to base libraries ("fix bounds check in +OpenSSL"). + +Can I build binaries for deployment on Docker? +---------------------------------------------- + +With Bazel, you can build standalone, statically linked binaries in +C/C++, and self-contained jar files for Java. These run with few +dependencies on normal UNIX systems, and as such should be simple to +install inside a Docker container. + +Bazel has conventions for structuring more complex programs, for example, a +Java program that consumes a set of data files, or runs another +program as subprocess. It is possible to package up such environments +as standalone archives, so they can be deployed on different systems, +including Docker images. + +Can I build Docker images with Bazel? +------------------------------------- + +Yes, you can use our +[Docker rules](http://bazel.io/docs/be/docker.html) +to build reproducible Docker images. + +Will Bazel make my builds reproducible automatically? +----------------------------------------------------- + +For Java and C++ binaries, yes, assuming you do not change the +toolchain. If you have build steps that involve custom recipes +(for example, executing binaries through a shell script inside a rule), you +will need to take some extra care: + + * Do not use dependencies that were not declared. Sandboxed + execution (--spawn_strategy=sandboxed, only on Linux) can + help find undeclared dependencies. + + * Avoid storing timestamps and user-IDs in generated files. ZIP files and + other archives are especially prone to this. + + * Avoid connecting to the network. Sandboxed execution can help here + too. + + * Avoid processes that use random numbers, in particular, dictionary + traversal is randomized in many programming languages. + +Do you have binary releases? +---------------------------- + +Yes, you can find the latest release binaries +[here](https://github.com/bazelbuild/bazel/releases/latest). Our release +policy is documented [here](http://bazel.io/support.html). + +I use Eclipse/IntelliJ. How does Bazel interoperate with IDEs? +-------------------------------------------------------------- + +We currently have no IDE integration API as such but the iOS rules generate +Xcode projects based on Bazel BUILD targets (see below). + +How does Bazel interact with Xcode? +----------------------------------- + +Bazel generates Xcode projects that you can use to work with any inputs and +dependencies for the target, to build apps from Xcode directly and to deploy to +an iOS simulator and devices. Simply open the project file whose path is printed +by Bazel after building any iOS target. There is no support to invoke Bazel from +Xcode (for example to re-generate generated sources such as Objective-C files +based on protos), nor to open Xcode from Bazel directly. + +I use Jenkins/CircleCI/TravisCI. How does Bazel interoperate with CI systems? +----------------------------------------------------------------------------- + +Bazel returns a non-zero exit code if the build or test invocation +fails, and this should be enough for basic CI integration. Since +Bazel does not need clean builds for correctness, the CI system should not +be configured to clean before starting a build/test run. + +Further details on exit codes are in the [User Manual](docs/bazel-user-manual.html). + +What future features can we expect in Bazel? +-------------------------------------------- + +Our initial goal is to work on Google's internal use-cases. This +includes Google's principal languages (C++, Java, Go) and major +platforms (Linux, Android, iOS). For practical reasons, not all of +these are currently open-sourced. For more details see our +[roadmap](roadmap.html). + +What about Python? +------------------ + +It is possible to write Python rules as extensions (see below). See +the following files for an example of generating self-contained zip +files for python: + + <https://github.com/bazelbuild/bazel/blob/master/tools/build_rules/py_rules.bzl>\\ + <https://github.com/bazelbuild/bazel/tree/master/examples/py> + +We have opened up a subset of our internal Python rules, so they +can be used as helper scripts as part of a build. + +Simplistic support for PEX-style binaries is at +[here](https://github.com/bazelbuild/bazel/blob/master/tools/build_rules/py_rules.bzl). + + +What about Go? +-------------- + +If your codebase is 100% Go, the `go` tool has excellent support for +building and testing, and Bazel will not bring you much benefit. + +The server code written in Go at Google is built with Bazel. However, the rules +that accomplish this are rather complex due to their interactions with our C++ +libraries, and are incompatible with the conventions of the `go` tool. We are +working on improving this situation. + +Can I use Bazel for my [INSERT LANGUAGE HERE] project? +------------------------------------------------------ + +We have an extension mechanism called Skylark that allows you to add new rules +without recompiling Bazel. + +For documentation: see [here](/docs/skylark/index.html). We have support for +several languages that use that extension mechanism, see our +[build encyclopedia](/docs/be/overview.html) for the full +list of supported languages. + +I need more functionality. Can I add rules that are compiled into Bazel? +------------------------------------------------------------------------ + +If our extension mechanism is insufficient for your use case, email +the mailing list for advice: <bazel-discuss@googlegroups.com>. + +Can I contribute to the Bazel code base? +---------------------------------------- + +See our [contribution guidelines](contributing.html). + +Why isn't all development done in the open? +------------------------------------------- + +We still have to refactor the interfaces between the public code in +Bazel and our internal extensions frequently. This makes it hard to do +much development in the open. See our [governance plan](governance.html) +for more details. + +How do I contact the team? +-------------------------- + +We are reachable at <bazel-discuss@googlegroups.com>. + +Where do I report bugs? +----------------------- + +Send an e-mail to <bazel-discuss@googlegroups.com> or file a bug +[on GitHub](https://github.com/bazelbuild/bazel/issues). + + + +What's up with the word "Blaze" in the codebase? +------------------------------------------------ + +This is an internal name for the tool. Please refer to Bazel as +Bazel. + + +Why do other Google projects (Android, Chrome) use other build tools? +--------------------------------------------------------------------- + +Until now, Bazel was not available externally, so open source projects +such as Chromium, Android, etc. could not use it. In addition, lack of +Windows support is a problem for building Windows applications, such +as Chrome. + + +How do you pronounce "Bazel"? +----------------------------- + +The same way as "basil" (the herb) in US English: "BAY-zel". It rhymes with +"hazel". IPA: /ˈbeɪzˌəl/ diff --git a/site/governance.md b/site/governance.md index 8f893aa856..ce49e7481b 100644 --- a/site/governance.md +++ b/site/governance.md @@ -1,4 +1,94 @@ --- -layout: redirect -redirect: governance.html +layout: contribute +title: Governance --- + +# Governance + +The Bazel project is led by a core group of contributors, initially Googlers, and managed by the +community. The group of core contributors is self-managing - core contributors are added by two +supporting votes from core contributors on the mailing list and no veto within four business days. +We expect that new contributors will submit a number of patches before they become core +contributors. + +## Accepting Contributions + +Please also see our [contribution guidelines](contributing.html). + +### Policy + +We use the following rules for accepting code contributions. This is written from the perspective +that there is a group of people who cooperatively support the project (the *core contributors*). In +contrast, external contributors are not actively supporting the project, but just contributing +individual changes. At this time, all core contributors work for Google (see below for the full +list), but this will hopefully change over time. + +1. We require all contributors to sign [Google's Contributor License + Agreement](https://cla.developers.google.com/). + +2. We accept well-written, well-tested contributions of rules written in + [Skylark](docs/skylark/concepts.html), in a `contrib/` directory or similar with clearly documented + support policies. + +3. We accept well-written, well-tested bug fixes to built-in rules. + +4. We accept well-written, well-tested feature contributions if a core contributor assumes support + responsibilities, i.e., readily answers support questions and works on bugs. This includes + feature contributions from external contributors. If there is no core contributor to support a + feature, then we will deprecate and subsequently delete the feature - we will give three months' + notice in such cases. + +5. We will not accept untested changes, except in very rare cases. + +6. We require a pre-commit code review from a core contributor for all changes. For the time being, + we will have to continue making changes across the internal and external code bases, which will + be reviewed internal to Google. + +7. We will roll back changes if they break the internal development processes of any of the core + contributors. + +8. We will move towards an open governance model where multiple parties have commit access, + roll-back rights, and can provide explicit support for features or rules. + +9. We will work with interested parties to improve existing extension points and to establish new + extension points if they do not run counter to the internal requirements of any of the core + contributors. + +## Are you done open sourcing Bazel? + +Open sourcing Bazel is a work-in-progress. In particular, we're still working on open sourcing: + +* Many of our unit and integration tests (which should make contributing patches easier). +* Full IDE integration. + +Beyond code, we'd like to eventually have all code reviews, bug tracking, and design decisions +happen publicly, with the Bazel community involved. We are not there yet, so some changes will +simply appear in the Bazel repository without clear explanation. Despite this lack of +transparency, we want to support external developers and collaborate. Thus, we are opening up the +code, even though some of the development is still happening internal to Google. Please let us know +if anything seems unclear or unjustified as we transition to an open model. + +## Are there parts of Bazel that will never be open sourced? + +Yes, some of the code base either integrates with Google-specific technology or we have been looking +for an excuse to get rid of (or is some combination of the two). These parts of the code base are +not available on GitHub and probably never will be. + +### Core Contributors + +<p class="lead"> +Contact the core team at <a href="mailto:bazel-dev@googlegroups.com"> +bazel-dev@googlegroups.com</a>. +</p> + +The current group is: + + - [damienmg](https://github.com/damienmg) + - [hanwen](https://github.com/hanwen) + - [jhfield](https://github.com/jhfield) + - [kchodorow](https://github.com/kchodorow) + - [laszlocsomor](https://github.com/laszlocsomor) + - [laurentlb](https://github.com/laurentlb) + - [lberki](https://github.com/lberki) + - [philwo](https://github.com/philwo) + - [ulfjack](https://github.com/ulfjack) diff --git a/site/hard_to_write_rules.md b/site/hard_to_write_rules.md index 5409b7766b..040098569d 100644 --- a/site/hard_to_write_rules.md +++ b/site/hard_to_write_rules.md @@ -1,4 +1,214 @@ --- -layout: redirect -redirect: hard_to_write_rules.html +layout: contribute +title: Why is it so difficult to write Bazel rules? --- + +# Why is it difficult to write Bazel rules? + +We have heard feedback from various people multiple times that Bazel rules are +hard to write. There is no single root cause, but it’s due to a combination of +historical circumstances and intrinsic complexity in the problem domain. This +document attempts to give a high level overview of the specific issues that we +believe to be the main contributors. + +* Assumption: Aim for Correctness, Throughput, Ease of Use & Latency +* Assumption: Large Scale Repositories +* Assumption: BUILD-like Description Language +* Intrinsic: Remote Execution and Caching are Hard +* Historic: Hard Separation between Loading, Analysis, and Execution is + Outdated, but still affects the API +* Intrinsic: Using Change Information for Correct and Fast Incremental Builds + requires Unusual Coding Patterns +* Intrinsic: Avoiding Quadratic Time and Memory Consumption is Hard + +## Assumption: Aim for Correctness, Throughput, Ease of Use & Latency + +We assume that the build system needs to be first and foremost correct with +respect to incremental builds, i.e., for a given source tree, the output of the +same build should always be the same, regardless of what the output tree looks +like. In the first approximation, this means Bazel needs to know every single +input that goes into a given build step, such that it can rerun that step if any +of the inputs change. There are limits to how correct Bazel can get, as it leaks +some information such as date / time of the build, and ignores certain types of +changes such as changes to file attributes. Sandboxing helps ensure correctness +by preventing reads to undeclared input files. Besides the intrinsic limits of +the system, there are a few known correctness issues, most of which are related +to Fileset or the C++ rules, which are both hard problems. We have long-term +efforts to fix these. + +The second goal of the build system is to have high throughput; we are +permanently pushing the boundaries of what can be done within the current +machine allocation for a remote execution service. If the remote execution +service gets overloaded, nobody can get work done. + +Ease of use comes next, i.e., of multiple correct approaches with the same (or +similar) footprint of the remote execution service, we choose the one that is +easier to use. + +For the purpose of this document, latency denotes the time it takes from +starting a build to getting the intended result, whether that is a test log from +a passing or failing test, or an error message that a BUILD file has a +typo. + +Note that these goals often overlap; latency is as much a function of throughput +of the remote execution service as is correctness relevant for ease of use. + + +## Assumption: Large Scale Repositories + +The build system needs to operate at the scale of large repositories where large +scale means that it does not fit on a single hard drive, so it is impossible to +do a full checkout on virtually all developer machines. A medium-sized build +will need to read and parse tens of thousands of BUILD files, and evaluate +hundreds of thousands of globs. While it is theoretically possible to read all +BUILD files on a single machine, we have not yet been able to do so within a +reasonable amount of time and memory. As such, it is critical that BUILD files +can be loaded and parsed independently. + + +## Assumption: BUILD-like Description Language + +For the purpose of this document, we assume a configuration language that is +roughly similar to BUILD files, i.e., declaration of library and binary rules +and their interdependencies. BUILD files can be read and parsed independently, +and we avoid even looking at source files whenever we can (except for +existence). + + +## Intrinsic: Remote Execution and Caching are Hard + +Remote execution and caching improve build times in large repositories by +roughly two orders of magnitude compared to running the build on a single +machine. However, the scale at which it needs to perform is staggering: Google's +remote execution service is designed to handle a huge number of requests per +second, and the protocol carefully avoids unnecessary roundtrips as well as +unnecessary work on the service side. + +At this time, the protocol requires that the build system knows all inputs to a +given action ahead of time; the build system then computes a unique action +fingerprint, and asks the scheduler for a cache hit. If a cache hit is found, +the scheduler replies with the digests of the output files; the files itself are +addressed by digest later on. However, this imposes restrictions on the Bazel +rules, which need to declare all input files ahead of time. + + +## Historic: Hard Separation between Loading, Analysis, and Execution is Outdated, but still affects the API + +Technically, it is sufficient for a rule to know the input and output files of +an action just before the action is sent to remote execution. However, the +original Bazel code base had a strict separation of loading packages, then +analyzing rules using a configuration (command-line flags, essentially), and +only then running any actions. This distinction is still part of the rules API +today, even though the core of Bazel no longer requires it (more details below). + +That means that the rules API requires a declarative description of the rule +interface (what attributes it has, types of attributes). There are some +exceptions where the API allows custom code to run during the loading phase to +compute implicit names of output files and implicit values of attributes. For +example, a java_library rule named ‘foo’ implicitly generates an output named +‘libfoo.jar’, which can be referenced from other rules in the build graph. + +Furthermore, the analysis of a rule cannot read any source files or inspect the +output of an action; instead, it needs to generate a partial directed bipartite +graph of build steps and output file names that is only determined from the rule +itself and its dependencies. + + +## Intrinsic: Using Change Information for Correct and Fast Incremental Builds requires Unusual Coding Patterns + +Above, we argued that in order to be correct, Bazel needs to know all the input +files that go into a build step in order to detect whether that build step is +still up-to-date. The same is true for package loading and rule analysis, and we +have designed [Skyframe] (http://www.bazel.io/docs/skyframe.html) to handle this +in general. Skyframe is a graph library and evaluation framework that takes a +goal node (such as ‘build //foo with these options’), and breaks it down into +its constituent parts, which are then evaluated and combined to yield this +result. As part of this process, Skyframe reads packages, analyzes rules, and +executes actions. + +At each node, Skyframe tracks exactly which nodes any given node used to compute +its own output, all the way from the goal node down to the input files (which +are also Skyframe nodes). Having this graph explicitly represented in memory +allows the build system to identify exactly which nodes are affected by a given +change to an input file (including creation or deletion of an input file), doing +the minimal amount of work to restore the output tree to its intended state. + +As part of this, each node performs a dependency discovery process; i.e., each +node can declare dependencies, and then use the contents of those dependencies +to declare even further dependencies. In principle, this maps well to a +thread-per-node model. However, medium-sized builds contain hundreds of +thousands of Skyframe nodes, which isn’t easily possible with current Java +technology (and for historical reasons, we’re currently tied to using Java, so +no lightweight threads and no continuations). + +Instead, Bazel uses a fixed-size thread pool. However, that means that if a node +declares a dependency that isn’t available yet, we may have to abort that +evaluation and restart it (possibly in another thread), when the dependency is +available. This, in turn, means that nodes should not do this excessively; a +node that declares N dependencies serially can potentially be restarted N times, +costing O(N^2) time. Instead, we aim for up-front bulk declaration of +dependencies, which sometimes requires reorganizing the code, or even splitting +a node into multiple nodes to limit the number of restarts. + +Note that this technology isn’t currently available in the rules API; instead, +the rules API is still defined using the legacy concepts of loading, analysis, +and execution phases. However, a fundamental restriction is that all accesses to +other nodes have to go through the framework so that it can track the +corresponding dependencies. Regardless of the language in which the build system +is implemented or in which the rules are written (they don’t have to be the +same), rule authors must not use standard libraries or patterns that bypass +Skyframe. For Java, that means avoiding java.io.File as well as any form of +reflection, and any library that does either. Libraries that support dependency +injection of these low-level interfaces still need to be setup correctly for +Skyframe. + +This strongly suggests to avoid exposing rule authors to a full language runtime +in the first place. The danger of accidental use of such APIs is just too big - +several Bazel bugs in the past were caused by rules using unsafe APIs, even +though the rules were written by the Bazel team, i.e., by the domain experts. + + +## Intrinsic: Avoiding Quadratic Time and Memory Consumption is Hard + +To make matters worse, apart from the requirements imposed by Skyframe, the +historical constraints of using Java, and the outdatedness of the rules API, +accidentally introducing quadratic time or memory consumption is a fundamental +problem in any build system based on library and binary rules. There are two +very common patterns that introduce quadratic memory consumption (and therefore +quadratic time consumption). + +1. Chains of Library Rules +Consider the case of a chain of library rules A depends on B, depends on C, and +so on. Then, we want to compute some property over the transitive closure of +these rules, such as the Java runtime classpath, or the C++ linker command for +each library. Naively, we might take a standard list implementation; however, +this already introduces quadratic memory consumption: the first library +contains one entry on the classpath, the second two, the third three, and so +on, for a total of 1+2+3+...+N = O(N^2) entries. + +2. Binary Rules Depending on the Same Library Rules +Consider the case where a set of binaries that depend on the same library +rules; for example, you might have a number of test rules that test the same +library code. Let’s say out of N rules, half the rules are binary rules, and +the other half library rules. Now consider that each binary makes a copy of +some property computed over the transitive closure of library rules, such as +the Java runtime classpath, or the C++ linker command line. For example, it +could expand the command line string representation of the C++ link action. N/2 +copies of N/2 elements is O(N^2) memory. + + +### Custom Collections Classes to Avoid Quadratic Complexity + +Bazel is heavily affected by both of these scenarios, so we introduced a set of +custom collection classes that effectively compress the information in memory by +avoiding the copy at each step. Almost all of these data structures have set +semantics, so we called the class NestedSet. The majority of changes to reduce +Bazel’s memory consumption over the past several years were changes to use +NestedSet instead of whatever was previously used. + +Unfortunately, usage of NestedSet does not automatically solve all the issues; +in particular, even just iterating over a NestedSet in each rule re-introduces +quadratic time consumption. NestedSet also has some helper methods to facilitate +interoperability with normal collections classes; unfortunately, accidentally +passing a NestedSet to one of these methods leads to copying behavior, and +reintroduces quadratic memory consumption. diff --git a/site/jekyll-tree.sh b/site/jekyll-tree.sh index 2e53f9bcc2..d077345fcb 100755 --- a/site/jekyll-tree.sh +++ b/site/jekyll-tree.sh @@ -40,48 +40,24 @@ function setup { # Unpack the Build Encyclopedia into docs/be function unpack_build_encyclopedia { - local be_dir="$OUT_DIR/versions/master/docs/be" + local be_dir="$OUT_DIR/docs/be" mkdir -p "$be_dir" unzip -qq "$BE_ZIP" -d "$be_dir" mv "$be_dir/be-nav.html" "$OUT_DIR/_includes" - - # Create redirects to each page in the Build Encyclopedia - mkdir -p "$OUT_DIR/docs/be" - for f in $(find "$OUT_DIR/versions/master/docs/be" -name "*.html"); do - local filename=$(basename "$f") - cat > "$OUT_DIR/docs/be/${filename}" <<EOF ---- -layout: redirect -redirect: docs/be/${filename} ---- -EOF - done } # Unpack the Skylark Library into docs/skylark/lib function unpack_skylark_library { - local sl_dir="$OUT_DIR/versions/master/docs/skylark/lib" + local sl_dir="$OUT_DIR/docs/skylark/lib" mkdir -p "$sl_dir" unzip -qq "$SL_ZIP" -d "$sl_dir" mv "$sl_dir/skylark-nav.html" "$OUT_DIR/_includes" - - # Create redirects to each page in the Skylark Library - mkdir -p "$OUT_DIR/docs/skylark/lib" - for f in $(find "$OUT_DIR/versions/master/docs/skylark/lib" -name "*.html"); do - local filename=$(basename "$f") - cat > "$OUT_DIR/docs/skylark/lib/${filename}" <<EOF ---- -layout: redirect -redirect: docs/skylark/lib/${filename} ---- -EOF - done } function copy_skylark_rule_doc { local rule_family=$1 local rule_family_name=$2 - local be_dir="$OUT_DIR/versions/master/docs/be" + local be_dir="$OUT_DIR/docs/be" ( cat <<EOF --- @@ -111,10 +87,10 @@ function process_doc { } function process_docs { - for f in $(find "$OUT_DIR/versions/master/docs" -name "*.html"); do + for f in $(find "$OUT_DIR/docs" -name "*.html"); do process_doc $f done - for f in $(find "$OUT_DIR/versions/master/docs" -name "*.md"); do + for f in $(find "$OUT_DIR/docs" -name "*.md"); do process_doc $f done } @@ -129,7 +105,7 @@ function main { unpack_build_encyclopedia unpack_skylark_library unpack_skylark_rule_docs - cp ${CLR_HTML} ${OUT_DIR}/versions/master/docs + cp ${CLR_HTML} ${OUT_DIR}/docs process_docs package_output } diff --git a/site/roadmap.md b/site/roadmap.md index 2972d9974b..1eec7a2498 100644 --- a/site/roadmap.md +++ b/site/roadmap.md @@ -1,4 +1,152 @@ --- -layout: redirect -redirect: roadmap.html +layout: contribute +title: Roadmap --- + +# Bazel Feature Roadmap + +This document describes the Bazel team's plans for introducing features that +will be incorporated into version 1.0. Note that this roadmap only includes +features that the Bazel team itself intends to support. We anticipate that a +number of other features will be added by code contributors. + +For the alpha and beta releases, the Bazel team will maintain two code +repositories: + +* A Google-internal repository, containing both Bazel code and + Google-specific extensions and features +* An external [GitHub repository](https://github.com/bazelbuild/bazel), + containing only the Bazel code. + +We anticipate making the external repository *primary* in the future, that is, +code from Google and non-Google contributors will be committed and tested in the +external repository first, then imported into the internal repository. For +the alpha and beta releases, however, the internal repository will be primary. +Changes to Bazel code will be frequently pushed from the internal to +the external repository. + +## Feature list + +In the following table, each feature is associated with a corresponding +milestone. The convention for the priorities are: + +* P0 feature will block the milestone; we will delay the milestone date + until the feature is shipped. +* P1 feature can delay the milestone if the feature can be shipped with a + reasonable delay (2 months max). +* P2 feature will be dropped and rescheduled for later rather than delaying + the milestone. + +We will update this list when reaching each milestone; some milestones may also +be refined if appropriate. + +<table class="table table-condensed table-bordered"> + <colgroup> + <col class="roadmap-col-phase"/> + <col class="roadmap-col-milestone"/> + <col class="roadmap-col-date"/> + <col class="roadmap-col-features"/> + </colgroup> + <thead> + <tr> + <th>Phase</th> + <th>Milestone</th> + <th>Target date</th> + <th>Features</th> + </tr> + </thead> + <tbody> + <tr> + <td rowspan="9"><b><a name="alpha"></a>Alpha</b></td> + <td rowspan="9"><b>Alpha</b><br/><span class="label label-default">Released</span></td> + <td rowspan="9"><b>2015‑03‑24</b></td> + <td>Linux & OS X Support</td> + </tr> + <tr><td>C++ (<a href="http://bazel.io/docs/be/c-cpp.html#cc_binary">build</a> and <a href="http://bazel.io/docs/be/c-cpp.html#cc_test">test</a>)</td></tr> + <tr><td>Java (<a href="http://bazel.io/docs/be/java.html#java_binary">build</a> and <a href="http://bazel.io/docs/be/java.html#java_test">test</a>)</td></tr> + <tr><td>Objective-C for iOS (<a href="http://bazel.io/docs/be/objective-c.html#objc_binary">build</a>)</td></tr> + <tr><td>Python (<a href="http://bazel.io/docs/be/python.html#py_binary">build</a>)</td></tr> + <tr><td>iOS applications (<a href="http://bazel.io/docs/be/objective-c.html#ios_application">build</a>)</td></tr> + <tr><td>Skylark extension mechanism (<a href="http://bazel.io/docs/skylark/index.html">build</a>)</td></tr> + <tr><td>Basic test suite on GitHub</td></tr> + <tr><td>Support for fetching dependencies from <a href="http://bazel.io/docs/be/workspace.html#maven_jar">Maven repositories</a> + and <a href="http://bazel.io/docs/be/workspace.html#http_archive">web servers</a></td></tr> + <tr> + <td rowspan="30"><b><a name="beta"></a>Beta</b></td> + <td rowspan="9"> + <a href="https://github.com/bazelbuild/bazel/releases/tag/0.1.0"><b>0.1</b> + <br/><span class="label label-default">Released</span></a> + </td> + <td rowspan="9"><b>2015‑09‑01</b></td> + <td>P0. Binary distribution for Linux & OS X</td< + </tr> + <tr><td>P0. Public <a href="http://ci.bazel.io">continuous integration system</a></td></tr> + <tr><td>P0. Support for <a href="http://bazel.io/docs/external.html">fetching transitive dependencies from Maven Central</a></td></tr> + <tr><td>P0. Android application (<a href="http://bazel.io/docs/be/android.html#android_binary">build</a> + and <a href="http://bazel.io/docs/bazel-user-manual.html#mobile-install">install</a>)</td></tr> + <tr><td>P1. Support for <a href="http://bazel.io/docs/external.html">prefetching and caching remote dependencies</a></td></tr> + <tr><td>P1. Docker (<a href="http://bazel.io/docs/be/docker.html">build and load</a>)</td></tr> + <tr><td>P2. <a href="http://bazel.io/docs/bazel-user-manual.html#sandboxing">Sandboxing of actions for Linux</a></td></tr> + <tr><td>P2. AppEngine (<a href="http://bazel.io/docs/be/appengine.html">build and load</a>)</td></tr> + <tr><td>P2. <a href="http://bazel.io/blog/2015/07/29/dashboard-dogfood.html">Test result dashboard</a></tr></td> + <tr> + <td rowspan="5"> + <a href="https://github.com/bazelbuild/bazel/releases/tag/0.2.0"><b>0.2</b> + <br/><span class="label label-default">Released</span></a> + </td> + <td rowspan="5"><b>2016‑02‑18</b></td> + <td>P0. <a href="https://github.com/bazelbuild/bazel/tree/master/src/test/java/com/google/devtools">Significantly increase test coverage</a></td> + </tr> + <tr><td>P0. Support for fetching <a href="http://bazel.io/docs/external.html">remote</a> <a href="http://bazel.io/docs/be/functions.html#load">Skylark rules</a></td></tr> + <tr><td>P2. <a href="http://bazel.io/docs/be/go.html">Go language support (build and tests)</a></td></tr> + <tr><td>P2. <a href="https://github.com/bazelbuild/bazel/releases/latest">Debian packages for Bazel</a></td></tr> + <tr><td>P2. <a href="http://braumeister.org/formula/bazel">OS X homebrew recipe for distributing Bazel</a></td></tr> + <tr> + <td rowspan="5"> + <a href="https://github.com/bazelbuild/bazel/releases/tag/0.3.0"><b>0.3</b> + <br/><span class="label label-default">Released</span></a> + </td> + <td rowspan="5"><b>2016‑06‑10</b></td> + <td>P0. <a href="http://bazel.io/docs/windows.html">Bazel can bootstrap itself on Windows without requiring admin privileges</a></td></tr> + </tr> + <tr><td>P1. <a href="http://bazel.io/blog/2016/06/10/ide-support.html">Interface for IDE support</a></td></tr> + <tr><td>P1. IDE support for <a href="http://tulsi.bazel.io">Xcode (stable)</a> and <a href="https://github.com/bazelbuild/e4b">Eclipse (experimental)</a></td></tr> + <tr><td>P1. <a href="https://docs.google.com/document/d/1jKbNXOVp2T1zJD_iRnVr8k5D0xZKgO8blMVDlXOksJg">Custom remote repositories using Skylark</a></td></tr> + <tr><td>P2. <a href="https://github.com/bazelbuild/bazel/commit/79adf59e2973754c8c0415fcab45cd58c7c34697">Prototype for distributed caching of build artifact</a></td></tr> + <tr> + <td rowspan="2"><b>0.4</b></td> + <td rowspan="2"><b>2016‑08</b></td> + <td>P0. Persistent Java compiler is enabled</td> + </tr> + <tr><td>P2. Sandboxing of action for OS X</td></tr> + <tr> + <td rowspan="4"><b>0.5</b></td> + <td rowspan="4"><b>2016‑10</b></td> + <td>P0. Support for testing Android apps</td> + </tr> + <tr><td>P0. Bazel supports building Java, C++ and Python on Windows</td></tr> + <tr><td>P1. Distributed execution of actions</td></tr> + <tr><td>P2. Support for Swift language</td></tr> + <tr> + <td rowspan="2"><b>0.6</b></td> + <td rowspan="2"><b>2016‑11</b></td> + <td>P0. Searchable "hub" of Skylark rules</td> + </tr> + <tr><td>P2. Reference ("pull") remote docker images as an input to the build process</td></tr> + <tr> + <td rowspan="3"><b>0.7</b></td> + <td rowspan="3"><b>2017 Q1</b></td> + <td>P0. Full Windows support for Android: Android feature set is identical for Windows and Linux/OS X</tr> + </tr> + <tr><td>P1. Android Studio interoperability</td></tr> + <tr><td>P1. Support for testing iOS apps</td></tr> + <tr> + <td rowspan="3"><b><a name="stable"></a>Stable</b></td> + <td rowspan="3"><b>1.0</b></td> + <td rowspan="3"><b>2017 Q4</b></td> + <td>P0. Github repository is primary</td> + </tr> + <tr><td>P0. Extension APIs are stable and versioned</td></tr> + <tr><td>P1. Bazel is available in the Ubuntu and Debian package managers</td></tr> + </tbody> +</table> diff --git a/site/users.md b/site/users.md index c280fbc10a..cc96d5895b 100644 --- a/site/users.md +++ b/site/users.md @@ -1,4 +1,126 @@ --- -layout: redirect -redirect: users.html +layout: contribute +title: Bazel Users --- + +# Corporate users of Bazel + +## [Ascend.io](https://ascend.io) + +Ascend is a Palo Alto startup that offers solutions for large data sets +analysis. Their motto is _Big data is hard. We make it easy_. + +## [Beeswax](https://www.beeswax.com/) (_in their own words_) + +"_Beeswax is a New York based startup that provides real time bidding as +service. Bazel powers their Jenkins based continuous integration and deployment +framework. Beeswax loves Bazel because it is blazingly fast, correct and well +supported across many languages and platforms._" + +## [Braintree](https://www.braintreepayments.com) + +Braintree, a PayPal subsidiary, develops payment solutions for websites and +applications. They use Bazel for parts of their internal build and Paul Gross +even posted a [nice piece about how their switch to +Bazel went](https://www.pgrs.net/2015/09/01/migrating-from-gradle-to-bazel/). + +## [Databricks](https://databricks.com) + +Databricks provides cloud-based integrated workspaces based on Apache Spark™. + +## [Interaxon](https://www.choosemuse.com/) + +InteraXon is a thought-controlled computing firm that creates hardware and +software platforms to convert brainwaves into digital signals. + +## [Improbable.io](https://improbable.io/) + +Improbable.io develops SpatialOS, a distributed operating system that enables +creating huge simulations inhabited by millions of complex entities. + +## [Makani](https://www.google.com/makani) + +Makani, now a Google subsidiary, develops energy kites and uses +Bazel to build their software (including their embedded C++ software). + +## [Peloton Technology](http://www.peloton-tech.com) + +Peloton Technology is an automated vehicle technology company that tackles +truck accidents and fuel use. They use Bazel to _enable reliable builds for +automotive safety systems_. + +## [Stripe](https://stripe.com) + +Stripe provides mobile payment solutions. They are the main maintainers of the +[Bazel Scala rules](https://github.com/bazelbuild/rules_scala). + +# Open-source projects using Bazel + +If you'd like your project listed here, please +[let us know](mailto:kchodorow@google.com?subject=My project uses Bazel)! + +## [CallBuilder](https://github.com/google/CallBuilder) + +A Java code generator that allows you to create a builder by writing one +function. + +## [Error Prone](https://github.com/google/error-prone) + +Catches common Java mistakes as compile-time errors. (Migration to Bazel is +in progress.) + +## [FFruit](https://gitlab.com/perezd/ffruit/) + +FFruit is a free & open source Android application to the popular service +[Falling Fruit](https://fallingfruit.org). + +## [GRPC](http://www.grpc.io) + +A language-and-platform-neutral remote procedure call system. (Bazel is a +supported, although not primary, build system.) + +## [Gulava](http://www.github.com/google/gulava/) + +A Java code generator that lets you write Prolog-style predicates and use them +seamlessly from normal Java code. + +## [Heron](http://twitter.github.io/heron/) + +Heron is a realtime, distributed, fault-tolerant stream processing engine +from Twitter. + +## [Jsonnet](http://google.github.io/jsonnet/doc/) + +An elegant, formally-specified config generation language for JSON. (Bazel is a +supported build system.) + +## [Kythe](https://github.com/google/kythe) + +An ecosystem for building tools that work with code. + +## [PetitParser for Java](https://github.com/petitparser/java-petitparser) + +Grammars for programming languages are traditionally specified statically. They +are hard to compose and reuse due to ambiguities that inevitably arise. +PetitParser combines ideas from scannnerless parsing, parser combinators, +parsing expression grammars and packrat parsers to model grammars and parsers +as objects that can be reconfigured dynamically. + +## [TensorFlow](http://tensorflow.org) + +An open source software library for machine intelligence. + +## [Trunk](https://github.com/mzhaom/trunk) + +A collection of C++/Java opensource projects with BUILD files so they +can be built with Bazel with out of box support for protobuf and +grpc (maybe thrift). + +## [Turbo Santa](https://github.com/turbo-santa/turbo-santa-common) + +A platform-independent GameBoy emulator. + +## [XIOSim](https://github.com/s-kanev/XIOSim) + +XIOSim is a detailed user-mode microarchitectural simulator for the x86 architecture. + diff --git a/site/versions/master/contributing.md b/site/versions/master/contributing.md deleted file mode 100644 index 6ea17d48a5..0000000000 --- a/site/versions/master/contributing.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -layout: contribute -title: Contributing to Bazel ---- - -# Contributing to Bazel - -<p class="lead">We welcome contributions! This page covers setting up your -machine to develop Bazel and, when you've made a patch, how to submit it.</p> - -## How can I contribute to Bazel? - -In general, we prefer contributions that fix bugs or add features (as opposed to -stylistic, refactoring, or "cleanup" changes). Please check with us on the -[dev list](https://groups.google.com/forum/#!forum/bazel-dev) before investing -a lot of time in a patch. - -## Patch Acceptance Process - -<!-- Our markdown parser doesn't support nested lists. --> -<ol> -<li>Read the <a href="governance.html">Bazel governance plan</a>.</li> -<li>Discuss your plan and design, and get agreement on our <a href="https://groups.google.com/forum/#!forum/bazel-dev">mailing list</a>. -<li>Prepare a git commit that implements the feature. Don't forget to add tests. -<li>Create a new code review on <a href="https://bazel-review.googlesource.com">Gerrit</a> - by running: - <pre>$ git push https://bazel.googlesource.com/bazel HEAD:refs/for/master</pre> - Gerrit upload requires that you: - <ul> - <li>Have signed a - <a href="https://cla.developers.google.com">Contributor License Agreement</a>. - <li>Have an automatically generated "Change Id" line in your commit message. - If you haven't used Gerrit before, it will print a bash command to create - the git hook and then you will need to run `git commit --amend` to add the - line. - </ul> - The HTTP password required by Gerrit can be obtained from your - <a href="https://bazel-review.googlesource.com/#/settings/http-password">Gerrit settings page</a>. - See the - <a href="https://gerrit-review.googlesource.com/Documentation/user-upload.html">Gerrit documentation</a> - for more information about uploading changes. -<li>Complete a code review with a - <a href="governance.html#core-contributors">core contributor</a>. Amend your existing - commit and re-push to make changes to your patch. -<li>An engineer at Google applies the patch to our internal version control - system. -<li>The patch is exported as a Git commit, at which point the Gerrit code review - is closed. -</ol> - -## Setting up your coding environment - -For now we have partial support for the Eclipse and IntelliJ IDEs for Java. We -don't have IDE support for other languages in Bazel right now. - -### Creating an Eclipse project - -To work with Eclipse: - -* Install the [e4b](https://github.com/bazelbuild/e4b) plugin. -* Change the path to the Bazel binary in the plugin preferences. -* Import the Bazel workspace as a Bazel project (`File` > `New` > `Other` > - `Import Bazel Workspace`). -* Select `src > main > java` and `src > test > java` as directories and add - `//src/main/java/...` and `//src/test/java/...` as targets. - -### Creating an IntelliJ project - -To work with IntelliJ: - -* Run `sh scripts/setup-intellij.sh` from the root of the source tree to create - the necessary project files. -* Open the folder as a project in IntelliJ. - -<a name="compile-bazel"></a> -### Compiling Bazel - -To test out bazel, you need to compile it. There are currently two ways of -compiling it: - -* `sh compile.sh` bootstraps Bazel from scratch, first compiling it without using - Bazel, then rebuilding it again using the just built Bazel and optionally runs - tests, too. The resulting binary can be found at `output/bazel`. -* `bazel build //src:bazel` builds the Bazel binary using `bazel` from your PATH - and the resulting binary can be found at `bazel-bin/src/bazel`. This is the - recommended way of rebuilding Bazel once you have bootstrapped it. - -In addition to the Bazel binary, you might want to build the various tools Bazel -uses. They are located in `//src/java_tools/...`, `//src/objc_tools/...` and -`//src/tools/...` and their directories contain README files describing their -respective utility. - -When modifying Bazel, you want to make sure that the following still works: - -* Bootstrap test with `sh compile.sh all` after having removed the - `output` directory: it rebuilds Bazel with `./compile.sh`, Bazel with the - `compile.sh` Bazel and Bazel with the Bazel-built binary. It compares if the - constructed Bazel builts are identical and then runs all bazel tests with - `bazel test //src/... //third_party/ijar/...`. This is what we use at Google - to ensure that we don't break Bazel when pushing new commits, too. - -### Debugging Bazel - -Start creating a debug configuration for both C++ and Java in your `.bazelrc` -with the following: - -``` -build:debug -c dbg -build:debug --javacopt="-g" -build:debug --copt="-g" -build:debug --strip="never" -``` - -Then you can rebuild Bazel with `bazel build --config debug //src:bazel` and use -your favorite debugger to start debugging. - -For debugging the C++ client you can just run it from gdb or lldb as you normally would. -But if you want to debug the Java code, you must attach to the server using the following: - -* Run Bazel with debugging option `--host_jvm_debug` before the - command (e.g., `bazel --batch --host_jvm_debug build //src:bazel`). -* Attach a debugger to the port 5005. With `jdb` for instance, - run `jdb -attach localhost:5005`. From within Eclipse, use the - [remote Java application launch - configuration](http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-remotejava_launch_config.htm). - For IntelliJ, you can refer to [Run/Debug Configuration: Remote](https://www.jetbrains.com/idea/help/run-debug-configuration-remote.html). - -## Bazel's code description - -Bazel is organized in several parts: - -* Client code in `src/main/cpp` provides the command-line interface. -* Protocol buffers in `src/main/protobuf`. -* Server code in `src/main/java` and `src/test/java`. - * Core code which is mostly composed of [SkyFrame](docs/skyframe.html) and some - utilities. - * Rules written in Bazel's extension language - [Skylark](docs/skylark/index.html) are defined in `tools/build_rules`. If - you want to add rules, consider using [Skylark](docs/skylark/index.html) - first. - * Builtin rules in `com.google.devtools.build.lib.rules` and in - `com.google.devtools.build.lib.bazel.rules`. You might want to read [Why is - it so difficult to write Bazel rules?](hard_to_write_rules.html) first. -* Java native interfaces in `src/main/native`. -* Various tooling for language support (see the list in the - [compiling Bazel](#compile-bazel) section). diff --git a/site/versions/master/docs/_posts/2016-06-02-sandboxing.md b/site/versions/master/docs/_posts/2016-06-02-sandboxing.md deleted file mode 100644 index 9fa47e89d4..0000000000 --- a/site/versions/master/docs/_posts/2016-06-02-sandboxing.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -layout: documentation -title: Sandboxing ---- - -# Bazel Sandboxing 2.0 - -This doc was written by [philwo@google.com](mailto:philwo@google.com). -Status: unimplemented, section "Handling of environment variables" superseeded -by the -[Specifying environment variables](/docs/designs/2016/06/21/environment.html) -design document. - -## Current situation - -Tools that use undeclared input files (files that are not explicitly listed in -the dependencies of an action) are a problem, as Bazel cannot keep track of them -and thus they can cause builds to become incorrect: When one of the undeclared -input files changes, Bazel will still believe that the build is up-to-date and -won't rebuild the action - resulting in an incorrect incremental build. - -Bazel uses sandboxing to prevent tools (e.g. compilers, linkers, ...) from -accidentally working with input files that are not a declared dependency of an -action - the idea is to run each tool in an environment that contains only the -explicitly declared input files of the action. Thus, there simply are no other -files that a tool could access. - -In theory this works well, but as nearly all Bazel users rely at least on some -tools provided by their operating system (e.g. `/usr/bin/zip`, `/usr/bin/gcc`), -which in turn require shared libraries, helper tools or data from other parts -of the installed OS, Bazel currently mounts a number of hard-coded directories -from the operating system into the sandbox in addition to the explicitly -declared inputs. - -However, even with that some users continue to run into issues, making Bazel -hard to use - e.g. the compiler they want to use is in a directory that's not -part of the hard-coded list (such as `/usr/local` or `/opt`) or the tool needs -access to device files (e.g. the nVidia CUDA SDK). - -## Proposal - -We think that it's time to revisit how we do sandboxing in the default settings -of Bazel. Sandboxing was intended to protect the user from forgetting to -declare explicit dependencies between their targets and to protect from tests -or tools accidentally writing all over the hard-disk (e.g. a test that wants to -clean up its temporary work directory via rm -rf and unfortunately wipes the -whole disk), not so much for protecting against an operating system having any -influence on the build. For these users, the current sandboxing with its -hard-coded list of allowed directories is too strict. - -On the other hand, some people absolutely do want 100% reproducible and -hermetic builds - and for them the current sandboxing actually isn't strict -enough, as it allows access to various files from the operating system. - -We believe we have found a solution that satisfies the demands of all users: - - * Bazel sandboxing will by default recursively mount the root directory `/` - into each sandbox in read-only mode, excluding the workspace directory (so - that source files cannot be read from that well-known path) and with a new - empty, writable execroot that contains the declared inputs of the action. - * In addition, Bazel will allow to mount a 'base image' or 'base directory' as - the root directory of the sandbox, thus completely removing any connection - to the operating system the user is running Bazel under. For example, a - project might decide that all builds should be done inside a standardized - Ubuntu 16.04 LTS environment containing certain versions of gcc, etc., that - is shipped as a base image. Now, even if the developer uses Arch Linux or - CentOS on their machine, they can build using the same environment as - everyone else, thus getting the exact same and reproducible outputs. - -### Base images - -Base images are simply `.tar.gz`'s of a directory structure that contains all -files necessary to execute binaries in, e.g. the output of “debootstrap” or -what you would usually “chroot” in and then run a tool inside. They should be -referred to via labels and could for example be downloaded from somewhere via -a `http_file` rule in the WORKSPACE. - -We're investigating if we can reuse -[Docker images (OCI)](https://github.com/opencontainers/image-spec/blob/v0.1.0/serialization.md) -for this, which would make it easier for users to get started with this -feature. - -### Handling of environment variables - -As part of this project, we also propose to change the handling of environment -variables (e.g. `PATH`) in Bazel, as we believe they are an important part of -the configuration of the environment that the build runs in. - -As an example, Bazel currently [resets PATH to a hard-coded string] -(https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelConfiguration.java), -which may not be suitable for the environment that it actually runs in - e.g. -if a user installs a tool called `babel` in `/usr/local/bin` and they call -`babel` in a shell script or Skylark rule they wrote, [they expect it to just -work] (https://github.com/bazelbuild/bazel/issues/884). We can argue that they -instead should check in their tool to the repository and not rely on `PATH` -lookup to find it, however this is sometimes not possible due to: - - * Users just don't think it's feasible and instead want to take whatever is - installed on the system, - * Bazel's restrictions in valid package label identifiers ([you can't check in - nodejs](https://github.com/bazelbuild/bazel/issues/884#issuecomment-183378680) - into your repository or even make it part of a filegroup, because it - contains files that have characters like `$` that are currently illegal from - Bazel's point of view, though that may change in the future), - * Licensing restrictions that disallow users checking in certain tools (such - as XCode). - -The proposal how Bazel should decide whether an environment variable should be -included in the environment of a Spawn is: - - * If `use_default_shell_env` is `True`, set `PATH` and `TMPDIR` env vars - (as we currently do). - * If a rule declares its need for an environment variable, take it. - * We already have an [“env” attribute in Skylark actions] - (http://www.bazel.io/docs/skylark/lib/ctx.html#action) that allows one to - set variables to hard-coded strings, we have `use_default_shell_env` in - Skylark actions, which pulls in `PATH` and `TMPDIR`, but we don't have any - way to just say "This rule needs this environment variable". Laurent - suggested that we discuss this later, as adding yet another attribute is - annoying - maybe there's some way we can fold all these use cases into one - attribute. - * We might want to add the same attribute to genrule as well then. - * Don't include any other environment variables. - -If Bazel decided that an environment variable is needed by a rule, the next -step is to figure out its value. The proposal how Bazel should decide the value -of an environment variable is: - - * If an environment variable is overridden in the `WORKSPACE.local` file - ("machine-specific settings"), take it from there. - * If an environment variable is overridden in the `WORKSPACE` file - ("project-specific settings"), always take the value from there. - * If not and we use a base image, take the environment variable from its - specification (as in OCI). - * If not, take it from the user's environment. - -If an environment variable that is used by a rule changed compared to when it -was built last time, its target has to be rebuild for correctness. - -Bazel should instead use `PATH` from the environment and for correctness -trigger a rebuild when it changes. - -*Open question: Should the whitelist of environment variables be configurable, -e.g. in the WORKSPACE file?* - -### Known issues in this area of work - -[Bazel #577: genrules leaking PATH into environment] -(https://github.com/bazelbuild/bazel/issues/577) - diff --git a/site/versions/master/docs/_posts/2016-06-21-environment.md b/site/versions/master/docs/_posts/2016-06-21-environment.md deleted file mode 100644 index 5ee8e5a322..0000000000 --- a/site/versions/master/docs/_posts/2016-06-21-environment.md +++ /dev/null @@ -1,279 +0,0 @@ ---- -layout: documentation -title: Specifying environment variables ---- - -# Specifying environment variables for actions - -This doc was written by [aehlig@google.com](mailto:aehlig@google.com). -Status: unimplemented. - -## Current shortcomings - -Currently, Bazel provides a cleaned set of environment variables to the -actions in order to obtain hermetic builds. This, however is not sufficent -for all use cases. - -* Projects often want to use tools which are not part of the repository; however, - their location varies from installation to installation. So, some sensible - value for the `PATH` environment variable has to be set. - -* Some set-ups depend on every program having access to specific variables, - e.g., indicating the homebrew paths, or library paths. - -* Commercial compilers sometimes need to be passed the location of a license - server through the environment. - -## Proposed solution - -### New flag `--action_env` - -We propose to add a new bazel flag, `--action_env` which has two -valid forms of usage, - -* specifying a variable with unspecified value, `--action_env=VARIABLE`, - and - -* specifying a variable with a value, `--action_env=VARIABLE=VALUE`; - in the latter case, the value can well be the empty string, but it is still - considered a specified value. - -This flag has a "latest wins" semantics in the sense that if the option is given -twice for the same variable, only the latest option will be used, regardless -whether specified or unspecified value. Options given for different variables -accumulate. - -In every action executed -with [`use_default_shell_env`] (/docs/skylark/lib/ctx.html#action) being true, -precisely the environment variables specified by -`--action_env` options are set as the default environment. -(Note that, therefore, by default, the environment for actions is empty.) - -* If the effective option for a variable has an unspecified value, - the value from the invocation environment of Bazel is taken. - -* If the effective option for a variable specifies a value, this value is - taken, regardless of the environment in which Bazel is invoked. - -Environment variables are considered an essential part of an action. In other -words, an action is expected to produce a different output, if the environment -it is invoked in differs; in particular, a previously cached value cannot be -taken if the effective environment changes. - -Given that normally a rule writer cannot know which tools might need fancy -environment variables (think of the commercial compiler use case), the default -for the [`use_default_shell_env`] (/docs/skylark/lib/ctx.html#action) -parameter will become true. - -### List of rc-files read by Bazel - -The list of rc-files that Bazel takes options from will include, at -least, the following files, where files later in the list take precedence over -the ones earlier in the list for conflicting options; for the -`--action_env` option the already described "latest wins" semantics is -applied. - -* A global rc-file. This file typically contains defaults for a whole group of - machines, like all machines of a company. On UNIX-like systems, it will be - located at `/etc/bazel.bazelrc`. - -* A machine-wide rc-file. This file is typically set by the administrator of - the machine or a group of machines with the same architecture. It typically - contains settings that are specific to that architecture and hardware. - On UNIX-like systems it will be next to be binary and called like the binary - with `.bazelrc` appended to the file name. - -* A user-specific file, located in `~/.bazelrc`. This file will be set by - each user for options desired for all Bazel invocations. - -* A project-specific file. This is the file `tools/bazel.rc` next to - the `WORKSPACE` file. This file is considered project-specific and - typically versioned in the same repository as the project. - -* A file specific to user, project, and checkout. This is the file - `.bazelrc` next to the `WORKSPACE` file. As it is specific to - the user and the machine he or she is working on, projects are advised - to ignore that file in the repository of the project (e.g., by adding - it to their `.gitignore` file, if they version the project with git). - -When looking for those rc-files, symbolic links are followed; files not -existing are silently assumed to be empty. Note that all those are regular -rc-files for Bazel, hence are not limited to the newly introduced -`--action_env` option. Also, the rule that options for more specific -invocations win over common options still applies; but, within each level of -specificness, precedence is given according to the mentioned order of rc-files. - -## Example usages of environment specifications - -The proposed solution allows for a variety of use cases, including the -following. - -* Systems using commercial compilers can set the environment variables with - information about the license server in the global rc file. - -* Users requiring special variables, like the ones used by homebrew, can set - them in their machine specific rc-file. In fact, once this proposal is - implemented, the homebrew port for Bazel could itself install that - machine-wide rc-file. - -* Projects depending on the environment, e.g., because they use tools assumed to - be already installed on the user's systm, have several options. - - * If they are optimistic about the environment, e.g., because they are not - very version dependent on the tools used, can just specify which environment - variables they depend on by adding declarations with unspecified values in - the `tools/bazel.rc` file. - - * If dependencies are more delicate, projects can provide a configure script - that does whatever analysis of the environment is necessary and then write - `--action_env` options with specified values to the user-project - local `.bazelrc` - file. As the configure script will only run when manually invoked by the - user and the syntax of the user-project local `.bazelrc` file is so that it - can be easily - be edited by a human, it is OK if that script only works in the majority of - the cases, as a user requiring an unusual setup for that project can easily - modify the user-project local `.bazelrc` by hand afterwards. - -* Irrespectively of the approach chosen by the project, a user where the - environment changes frequently (e.g., on clusters or other machines using a - traditional layout) can fix the environment by adding `--action_env` - options with specific values to the user-project local `.bazelrc`. - - To simplify this use case, Bazel might provide a script - `bazel_freeze_environment` that reads the - `tools/bazel.rc` and looks for `--action_env` options with - unspecified values and writes corresponding ones with specified values to the - user-project local `.bazelrc` file; the specified values are taken from the - environment of - the invocation of that script. - - To simplify "freeze on first use" approaches, there will be separate way of - invoking the `bazel_freeze_environment` script so that it only adds - `--action_env` options with specified values for variables not already - mentioned in the user-project local `.bazelrc` file. - -## Transition plan - -Currently, some users of Bazel already make use of the fact that `PATH`, -`LD_LIBRARY_PATH`, and `TMPDIR` are being passed to actions. To allow those -projects a smooth -transition to the new set up, the global Bazel rc-file provided by upstream -will have the following content. - -``` -common --action_env=PATH -common --action_env=LD_LIBRARY_PATH -common --action_env=TMPDIR -``` - - -## Bazel's own dependency on `PATH` - -Bazel itself also uses external tools, like `cat`, `echo`, `sh`, but also -tools like `bash` where the location differs between installations. In -particular, a value for `PATH` needs to be provided. This will be covered -by the setting of the global bazel configuration file. Should the need arise, a -configure-like script can be added; at the moment it seems that this will not -be necessary. - -## Reasons for the Design Choices, Risks, and Alternatives Considered - -### Conflicting Interests on the environment influencing actions - -There are conflicting requirements for the environment variables of an action. - -* Users expect Bazel to "just work", i.e., the expectation is that if a tool - works on the command line, it should also work when called from an action in - a Bazel invocation from the same environment. A lot of compilers, however, - depend, at least on some systems, on certain environment variables. - An approach used by quite a few other build systems is to pass through the - whole invocation environment. - -* Bazel wants to provide correct and reproducible builds. Therefore, everything - that potentially influences the outcome of an action needs to be controlled - and tracked; a cached result cannot be used if anything potentially changing - the outcome has changed. - -* Users expect Bazel to not do rebuilds they (i.e., the users) know are - unnecessary. And, while for a lot of users the environment variables that - actually influence the build stay stable, the full environment constantly - changes; take the `OLDPWD` environment variable as an example. - -This design tries to reconcile these needs by allowing arbitrary environment -variables being set for actions, but only in an opt-in way. Variables need to -be explicitly mentioned, either in a configuration file or on the command line, -to be provided to an action. - -### Generic Solutions versus Special Casing - -As Bazel already has quite a number of concepts, there is the valid concern -that the complexity might increase too much and newly added concepts might -become a maintenance burden. Another concern is that more configuration -mechanisms make it harder for the user to know which one is the correct one -to use for his or her problem. The general desire is to have few, but powerful -enough mechanisms to control the build behaviour and avoid special casing. - -* Putting the environment variables visible in actions in the hand of the - user avoids the need of special casing more and more "important" environment - variables. - -* Building on the already existing mechanism to specify, inherit, and override - command-line options reduces the amount newly introduced concepts. The main - addition is a command-line option. - -A corner case from that perspective is the `bazel_freeze_environment` script. -While it solves a valid use case, its only purpose is the management -of environment variables. At least it is strictly a user tool, in the sense -that Bazel itself does not depend on it: Bazel will happily read any -syntactically valid rc-file, regardless how it was created; so a user can -hand-code the user-project local `.bazelrc` file, use the help of -`bazel_freeze_environment`, or use a third-party tool to generate it. - -### Source of Knowledge for Needed Environment Variables - -Another aspect that went into the design is that different entities know -about environment variables that are essential for the build to work. - -* Some variables are "obviously" relevant, like `PATH` or `TMPDIR`. - However, there is no "obvious" value for them. - - * Both depend on the layout of the system in question. A special fast - file system for temporary files might be provided at a designated - location. Binaries might be installed under `/bin`, `/usr/bin`, - `/usr/local/bin`, or even versioned paths to allow parallel installations - of different versions of the same tool. For example, on Debian Gnu/Linux - the `bash` is installed in `/bin`, whereas on FreeBSD it is usually - installed in `/usr/local/bin` (but the prefix `/usr/local` is at the - discretion of the system administrator). - - * The user might have custom-built versions of tools somewhere in the - home directory, thus making the user the only one who knows an appropriate - value for the `PATH` variable. Moreover, a user who works on several - projects requiring different versions of the same tool may even require - different values of the `PATH` variable for each project. - -* The authors and users of a tool know about special variables the tools - need to work. While the tool itself might serve a standard purpose, like - compiling C code, the variables the tool depends on might be specific to - that tool (like passing information about a license server). - -* The maintainers of a porting or packaging system know about environment - variables a tool might additionally need (e.g., in the homebrew case). - These might not be needed if the same tool is packaged differently. - -* The project authors know about environment variables special to their - project that some of their actions need. - -These different sources of information make it hard to designate a -single maintainer for the action environment. This makes approaches -undesireable that are based on a single source specifying the action -environment, like the `WORKSPACE` file, or the rule definitions. While -those approaches make it easy to predict the environment an action will -have, they all require the user to merge in the specifics of the system -and his or her personal settings for each checkout (including rebasing -these changes for each upstream change of that file). Collecting environment -variables via the rc-file mechanism allows setting each variable within -the appropriate scope (global, machine-dependent, user-spefic, project-specific, -specific to the user-project pair) in a conflict-free way by the entity -in charge of that scope. diff --git a/site/versions/master/docs/designs/index.md b/site/versions/master/docs/designs/index.md deleted file mode 100644 index cd2a9d7e7e..0000000000 --- a/site/versions/master/docs/designs/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -layout: documentation -title: Design Documents ---- - -# Bazel Design Documents - -<ul> -{% for doc in site.categories.designs %} - <li><a href="{{ doc.url }}">{{ doc.title }}</a> - {{ doc.date | date_to_long_string }}</a></li> -{% endfor %} -</ul> diff --git a/site/versions/master/docs/external.md b/site/versions/master/docs/external.md deleted file mode 100644 index 1bcdc683d7..0000000000 --- a/site/versions/master/docs/external.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -layout: documentation -title: External Dependencies ---- - -# Working with external dependencies - -Bazel is designed to have absolutely everything needed for a build, from source -code to libraries to compilers, under one directory (the workspace directory). -This is impractical for some version control systems and goes against how many -existing projects are structured. Thus, Bazel has a system for pulling in -dependencies from outside of the workspace. - -External dependencies can be specified in a `WORKSPACE` file in the -[workspace directory](/docs/build-ref.html#workspaces). This `WORKSPACE` file -uses the same Python-like syntax of BUILD files, but allows a different set of -rules. See the full list of rules that are allowed in the -[Workspace](/docs/be/workspace.html) list of rules in the Build -Encyclopedia. - -External dependencies are all downloaded and symlinked under a directory named -`external`. You can see this directory by running: - -``` -ls $(bazel info output_base)/external -``` - -Note that running `bazel clean` will not actually delete the external -directory: to remove all external artifacts, use `bazel clean --expunge`. - -## Fetching dependencies - -By default, external dependencies are fetched as needed during `bazel build`. If -you would like to disable this behavior or prefetch dependencies, use -[`bazel fetch`](http://bazel.io/docs/bazel-user-manual.html#fetch). - -## Using Proxies - -Bazel will pick up proxy addresses from the `HTTPS_PROXY` and `HTTP_PROXY` -environment variables and use these to download HTTP/HTTPS files (if specified). - -<a name="transitive-dependencies"></a> -## Transitive dependencies - -Bazel only reads dependencies listed in your `WORKSPACE` file. This -means that if your project (`A`) depends on another project (`B`) which list a -dependency on project `C` in its `WORKSPACE` file, you'll have to add both `B` -and `C` to your project's `WORKSPACE` file. This can balloon the `WORKSPACE` -file size, but hopefully limits the chances of having one library include `C` -at version 1.0 and another include `C` at 2.0. - -Bazel provides a tool to help generate these expansive `WORKSPACE` files, called -`generate_workspace`. This is not included with the binary installer, so you'll -need to clone the [GitHub repo](https://github.com/bazelbuild/bazel) to use it. -We recommend using the tag corresponding to your current version of bazel, which -you can check by running `bazel version`. - -`cd` to the GitHub clone, `git checkout` the appropriate tag, and run the -following to build the tool and see usage: - -``` -bazel run //src/tools/generate_workspace -``` - -Note that you need run this from your Bazel source folder even if you build your binary from source. - -You can specify directories containing Bazel projects (i.e., directories -containing a `WORKSPACE` file), Maven projects (i.e., directories containing a -`pom.xml` file), or Maven artifact coordinates directly. For example: - -```bash -$ bazel run //src/tools/generate_workspace -- \ -> --maven_project=/path/to/my/project \ -> --bazel_project=/path/to/skunkworks \ -> --bazel_project=/path/to/teleporter/project \ -> --artifact=groupId:artifactId:version \ -> --artifact=groupId:artifactId:version -Wrote: -/tmp/1437415510621-0/2015-07-20-14-05-10.WORKSPACE -/tmp/1437415510621-0/2015-07-20-14-05-10.BUILD -``` - -The `WORKSPACE` file will contain the transitive dependencies of the given -projects and artifacts. The `BUILD` file will contain a single target, -`transitive-deps`, that contains all of the dependencies. You can copy these -files to your project and add `transitive-deps` as a dependency of your `java_` -targets in `BUILD` files. - -If you specify multiple Bazel projects, Maven projects, or artifacts, they will -all be combined into one `WORKSPACE` file (e.g., if the Bazel project depends on -junit and the Maven project also depends on junit, junit will only appear once -as a dependency in the output). - -You may wish to curate the generated `WORKSPACE` file to ensure it is using the -correct version of each dependency. If several different versions of an artifact -are requested (by different libraries that depend on it), then -`generate_workspace` chooses a version and annotates the `maven_jar` with the -other versions requested, for example: - -```python -# org.springframework:spring:2.5.6 -# javax.mail:mail:1.4 -# httpunit:httpunit:1.6 wanted version 1.0.2 -# org.springframework:spring-support:2.0.2 wanted version 1.0.2 -# org.slf4j:nlog4j:1.2.24 wanted version 1.0.2 -maven_jar( - name = "javax/activation/activation", - artifact = "javax.activation:activation:1.1", -) -``` - -This indicates that `org.springframework:spring:2.5.6`, `javax.mail:mail:1.4`, -`httpunit:httpunit:1.6`, `org.springframework:spring-support:2.0.2`, and -`org.slf4j:nlog4j:1.2.24` all depend on javax.activation. However, two of these -libraries wanted version 1.1 and three of them wanted 1.0.2. The `WORkSPACE` -file is using version 1.1, but that might not be the right version to use. - -You may also want to break `transitive-deps` into smaller targets, as it is -unlikely that all of your targets depend on the transitive closure of your -maven jars. - -# Types of external dependencies - -There are a few basic types of external dependencies that can be created. - -## Combining Bazel projects - -If you have a second Bazel project that you'd like to use targets from, you can -use -[`local_repository`](http://bazel.io/docs/be/workspace.html#local_repository) -or [`http_archive`](http://bazel.io/docs/be/workspace.html#http_archive) -to symlink it from the local filesystem or download it (respectively). - -For example, suppose you are working on a project, `my-project/`, and you want -to depend on targets from your coworker's project, `coworkers-project/`. Both -projects use Bazel, so you can add your coworker's project as an external -dependency and then use any targets your coworker has defined from your own -BUILD files. You would add the following to `my_project/WORKSPACE`: - -```python -local_repository( - name = "coworkers-project", - path = "/path/to/coworkers-project", -) -``` - -If your coworker has a target `//foo:bar`, your project can refer to it as -`@coworkers-project//foo:bar`. - -## Depending on non-Bazel projects - -Rules prefixed with `new_` (e.g., -[`new_local_repository`](http://bazel.io/docs/be/workspace.html#new_local_repository) -and [`new_http_archive`](http://bazel.io/docs/be/workspace.html#new_http_archive) -) allow you to create targets from projects that do not use Bazel. - -For example, suppose you are working on a project, `my-project/`, and you want -to depend on your coworker's project, `coworkers-project/`. Your coworker's -project uses `make` to build, but you'd like to depend on one of the .so files -it generates. To do so, add the following to `my_project/WORKSPACE`: - -```python -new_local_repository( - name = "coworkers-project", - path = "/path/to/coworkers-project", - build_file = "coworker.BUILD", -) -``` - -`build_file` specifies a BUILD file to overlay on the existing project, for -example: - -```python -java_library( - name = "some-lib", - srcs = glob(["**"]), - visibility = ["//visibility:public"], -) -``` - -You can then depend on `@coworkers-project//:some-lib` from your project's BUILD -files. - -# Caching of external dependencies - -Bazel caches external dependencies and only re-downloads or updates them when -the `WORKSPACE` file changes. If the `WORKSPACE` file does not change, Bazel -assumes that the external dependencies have not changed, either. This can cause -unexpected results, especially with local repositories. - -For instance, in the example above, suppose that `my-project/` has a target that -depends on `@coworkers-project//:a`, which you build. Then you change to -`coworkers-project/` and pull the latest updates to their library, which changes -the behavior of `@coworkers-project//:a`. If you go back to `my-project/` and -build your target again, it will assume `@coworkers-project//:a` is already -up-to-date and reuse the cached library (instead of realizing that the sources -have changed and, thus, rebuilding). - -To avoid this situation, prefer remote repositories to local ones and do not -manually change the files in `[output_base]/external`. If you change a file -in `[output_base]/external`, rerun `bazel fetch ...` to update the cache. diff --git a/site/versions/master/docs/getting-started.md b/site/versions/master/docs/getting-started.md deleted file mode 100644 index 0e91dd3b13..0000000000 --- a/site/versions/master/docs/getting-started.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -layout: documentation -title: Getting Started ---- - -# Getting Started with Bazel - -## Setup - -Use the [installation instructions](/docs/install.html) to install a copy of -Bazel on your machine. - -## Using a Workspace - -All Bazel builds take place in a [_workspace_](/docs/build-ref.html#workspaces), -a directory on your filesystem that contains source code for the software you -want to build, as well symbolic links to directories that contain the build -outputs (for example, `bazel-bin` and `bazel-out`). The location of the -workspace directory is not significant, but it must contain a file called -`WORKSPACE` in the top-level directory; an empty file is a valid workspace. -The `WORKSPACE` file can be used to reference -[external dependencies](/docs/external.html) required to build the outputs. -One workspace can be shared among multiple projects if desired. - -```bash -$ touch WORKSPACE -``` - -## Creating a Build File - -To know which targets can be built in your project, Bazel inspects `BUILD` -files. They are written in Bazel's build language which is syntactically -similar to Python. Usually they are just a sequence of declarations of rules. -Each rule specifies its inputs, outputs, and a way to compute the outputs from -the inputs. - -The rule probably most familiar to people who have used `Makefile`s before (as -it is the only rule available there) is the -[genrule](/docs/be/general.html#genrule), which specifies how the output can -be generated by invoking a shell command. - -``` -genrule( - name = "hello", - outs = ["hello_world.txt"], - cmd = "echo Hello World > $@", -) -``` - -The shell command may contain [Make variables](/docs/be/make-variables.html). - -Using the above `BUILD` file, you can ask Bazel to generate the target. - -``` -$ bazel build :hello -. -INFO: Found 1 target... -Target //:hello up-to-date: - bazel-genfiles/hello_world.txt -INFO: Elapsed time: 2.255s, Critical Path: 0.07s -``` - -We note two things. First, targets are normally referred to by their -[label](/docs/build- ref.html#labels), which is specified by the -[name](/docs/be/general.html#genrule.name) attribute of the rule. (Referencing -them by the output file name is also possible, but this is not the preferred -way.) Second, Bazel puts the generated files into a separate directory (the -`bazel-genfiles` directory is actually a symbolic link) so as not to pollute -your source tree. - -Rules may use the output of other rules as input, as in the following -example. Again, the generated sources are referred to by their label. - -``` -genrule( - name = "hello", - outs = ["hello_world.txt"], - cmd = "echo Hello World > $@", -) - -genrule( - name = "double", - srcs = [":hello"], - outs = ["double_hello.txt"], - cmd = "cat $< $< > $@", -) -``` - -Finally, note that, while the [genrule](/docs/be/general.html#genrule) might -seem familiar, it usually is _not_ the best rule to use. It is preferrable to -use one of the specialized [rules](/docs/be/overview.html#rules) for various -languages. - -# Next Steps - -Next, check out the tutorial on building [java](/docs/tutorial/java.html) -or [C++](/docs/tutorial/cpp.html) programs. diff --git a/site/versions/master/docs/mobile-install.md b/site/versions/master/docs/mobile-install.md deleted file mode 100644 index f273871d0d..0000000000 --- a/site/versions/master/docs/mobile-install.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -layout: documentation -title: mobile-install ---- - -# bazel mobile-install - -<p class="lead">Fast iterative development for Android</p> - -## TL;DR - -To install small changes to an Android app very quickly, do the following: - - 1. Find the `android_binary` rule of the app you want to install. - 2. Disable Proguard by removing the `proguard_specs` attribute. - 3. Set the `multidex` attribute to `native`. - 4. Set the `dex_shards` attribute to `10`. - 5. Connect your device running ART (not Dalvik) over USB and enable USB - debugging on it. - 6. Run `bazel mobile-install :your_target`. App startup will be a little - slower than usual. - 7. Edit the code or Android resources. - 8. Run `bazel mobile-install --incremental :your_target`. - 9. Enjoy not having to wait a lot. - -Some command line options to Bazel that may be useful: - - - `--adb` tells Bazel which adb binary to use - - `--adb_arg` can be used to add extra arguments to the command line of `adb`. - One useful application of this is to select which device you want to install - to if you have multiple devices connected to your workstation: - `bazel mobile-install --adb_arg=-s --adb_arg=<SERIAL> :your_target` - - `--start_app` automatically starts the app - -When in doubt, look at the -[example](https://github.com/bazelbuild/bazel/tree/master/examples/android) -or [contact us](https://groups.google.com/forum/#!forum/bazel-discuss). - -## Introduction - -One of the most important attributes of a developer's toolchain is speed: there -is a world of difference between changing the code and seeing it run within a -second and having to wait minutes, sometimes hours, before you get any feedback -on whether your changes do what you expect them to. - -Unfortunately, the traditional Android toolchain for building an .apk entails -many monolithic, sequential steps and all of these have to be done in order to -build an Android app. At Google, waiting five minutes to build a single-line -change was not unusual on larger projects like Google Maps. - -`bazel mobile-install` makes iterative development for Android much faster by -using a combination of change pruning, work sharding, and clever manipulation of -Android internals, all without changing any of your app's code. - -## Problems with traditional app installation - -We identified the following bottlenecks of building an Android app: - -- Dexing. By default, "dx" is invoked exactly once in the build and it does not -know how to reuse work from previous builds: it dexes every method again, even -though only one method was changed. - -- Uploading data to the device. adb does not use the full bandwidth of a USB 2.0 -connection, and larger apps can take a lot of time to upload. The entire app is -uploaded, even if only small parts have changed, for example, a resource or a -single method, so this can be a major bottleneck. - -- Compilation to native code. Android L introduced ART, a new Android runtime, -which compiles apps ahead-of-time rather than compiling them just-in-time like -Dalvik. This makes apps much faster at the cost of longer installation -time. This is a good tradeoff for users because they typically install an app -once and use it many times, but results in slower development where an app is -installed many times and each version is run at most a handful of times. - -## The approach of `bazel mobile-install` - -`bazel mobile-install `makes the following improvements: - - - Sharded dexing. After building the app's Java code, Bazel shards the class - files into approximately equal-sized parts and invokes `dx` separately on - them. `dx` is not invoked on shards that did not change since the last build. - - - Incremental file transfer. Android resources, .dex files, and native - libraries are removed from the main .apk and are stored in under a separate - mobile-install directory. This makes it possible to update code and Android - resources independently without reinstalling the whole app. Thus, - transferring the files takes less time and only the .dex files that have - changed are recompiled on-device. - - - Loading parts of the app from outside the .apk. A tiny stub application is - put into the .apk that loads Android resources, Java code and native code - from the on-device mobile-install directory, then transfers control to the - actual app. This is all transparent to the app, except in a few corner cases - described below. - -### Sharded Dexing - -Sharded dexing is reasonably straightforward: once the .jar files are built, a -[tool](https://github.com/bazelbuild/bazel/blob/master/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java) -shards them into separate .jar files of approximately equal size, then invokes -`dx` on those that were changed since the previous build. The logic that -determines which shards to dex is not specific to Android: it just uses the -general change pruning algorithm of Bazel. - -The first version of the sharding algorithm simply ordered the .class files -alphabetically, then cut the list up into equal-sized parts, but this proved to -be suboptimal: if a class was added or removed (even a nested or an anonymous -one), it would cause all the classes alphabetically after it to shift by one, -resulting in dexing those shards again. Thus, we settled upon sharding not -individual classes, but Java packages instead. Of course, this still results in -dexing many shards if a new package is added or removed, but that is much less -frequent than adding or removing a single class. - -The number of shards is controlled by the BUILD file (using the -`android_binary.dex_shards` attribute). In an ideal world, Bazel would -automatically determine how many shards are best, but Bazel currently must know -the set of actions (i.e. commands to be executed during the build) before -executing any of them, so it cannot determine the optimal number of shards -because it doesn't know how many Java classes there will eventually be in the -app. Generally speaking, the more shards, the faster the build and the -installation will be, but the slower app startup becomes, because the dynamic -linker has to do more work. The sweet spot is usually between 10 and 50 shards. - -### Incremental File Transfer - -After building the app, the next step is to install it, preferably with the -least effort possible. Installation consists of the following steps: - - 1. Installing the .apk (i.e. `adb install`) - 2. Uploading the .dex files, Android resources, and native libraries to the - mobile-install directory - -There is not much incrementality in the first step: the app is either installed -or not. Bazel currently relies on the user to indicate if it should do this step -through the `--incremental` command line option because it cannot determine in -all cases if it is necessary. - -In the second step, the app's files from the build are compared to an on-device -manifest file that lists which app files are on the device and their -checksums. Any new files are uploaded to the device, any files that have changed -are updated, and any files that have been removed are deleted from the -device. If the manifest is not present, it is assumed that every file needs to -be uploaded. - -Note that it is possible to fool the incremental installation algorithm by -changing a file on the device, but not its checksum in the manifest. We could -have safeguarded against this by computing the checksum of the files on the -device, but this was deemed to be not worth the increase in installation time. - -### The Stub Application - -The stub application is where the magic to load the dexes, native code and -Android resources from the on-device `mobile-install` directory happens. - -The actual loading is implemented by subclassing `BaseDexClassLoader` and is a -reasonably well-documented technique. This happens before any of the app's -classes are loaded, so that any application classes that are in the apk can be -placed in the on-device `mobile-install` directory so that they can be updated -without `adb install`. - -This needs to happen before any of the -classes of the app are loaded, so that no application class needs to be in the -.apk which would mean that changes to those classes would require a full -re-install. - -This is accomplished by replacing the `Application` class specified in -`AndroidManifest.xml` with the -[stub application](https://github.com/bazelbuild/bazel/blob/master/src/tools/android/java/com/google/devtools/build/android/incrementaldeployment/StubApplication.java). This -takes control when the app is started, and tweaks the class loader and the -resource manager appropriately at the earliest moment (its constructor) using -Java reflection on the internals of the Android framework. - -Another thing the stub application does is to copy the native libraries -installed by mobile-install to another location. This is necessary because the -dynamic linker needs the `X` bit to be set on the files, which is not possible to -do for any location accessible by a non-root `adb`. - -Once all these things are done, the stub application then instantiates the -actual `Application` class, changing all references to itself to the actual -application within the Android framework. - -## Results - -### Performance - -In general, `bazel mobile-install` results in a 4x to 10x speedup of building -and installing large apps after a small change. We computed the following -numbers for a few Google products: - -<img src="/assets/mobile-install-performance.svg"/> - -This, of course, depends on the nature of the change: recompilation after -changing a base library takes more time. - -### Limitations - -The tricks the stub application plays don't work in every case. We have -identified the following cases where it does not work as expected: - - - When `Context` is cast to the `Application` class in - `ContentProvider#onCreate()`. This method is called during application - startup before we have a chance to replace the instance of the `Application` - class, therefore, `ContentProvider` will still reference the stub application - instead of the real one. Arguably, this is not a bug since you are not - supposed to downcast `Context` like this, but this seems to happen in a few - apps at Google. - - - Resources installed by `bazel mobile-install` are only available from within - the app. If resources are accessed by other apps via - `PackageManager#getApplicationResources()`, these resources will be from the - last non-incremental install. - - - Devices that aren't running ART. While the stub application works well on - Froyo and later, Dalvik has a bug that makes it think that the app is - incorrect if its code is distributed over multiple .dex files in certain - cases, for example, when Java annotations are used in a - [specific](https://code.google.com/p/android/issues/detail?id=78144) way. As - long as your app doesn't tickle these bugs, it should work with Dalvik, too - (note, however, that support for old Android versions isn't exactly our - focus) diff --git a/site/versions/master/docs/output_directories.md b/site/versions/master/docs/output_directories.md deleted file mode 100644 index 9b5f391cf7..0000000000 --- a/site/versions/master/docs/output_directories.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -layout: documentation -title: Output Directory Layout ---- - -# Output Directory Layout - -## Requirements - -Requirements for an output directory layout: - -* Don't collide if multiple users are building on the same box. -* Support building in multiple workspaces at the same time. -* Support building for multiple target configurations in the same workspace. -* Don't collide with any other tools. -* Be easy to access. -* Be easy to clean, even selectively. -* Is unambiguous, even if the user relies on symbolic links when changing into - his/her client directory. -* All the build state per user should be underneath one directory ("I'd like to - clean all the .o files from all my clients.") - -## Documentation of the current Bazel output directory layout - -The solution that's currently implemented: - -* Bazel must be invoked from a directory containing a WORKSPACE file. It reports - an error if it is not. We call this the _workspace directory_. -* The _outputRoot_ directory is ~/.cache/bazel. (Unless `$TEST_TMPDIR` is - set, as in a test of bazel itself, in which case this directory is used - instead.) -* We stick the Bazel user's build state beneath `outputRoot/_bazel_$USER`. This - is called the _outputUserRoot_ directory. -* Beneath the `outputUserRoot` directory, we create an `installBase` directory - whose name is "install" plus the MD5 hash of the Bazel installation manifest. -* Beneath the `outputUserRoot` directory, we also create an `outputBase` - directory whose name is the MD5 hash of the path name of the workspace - directory. So, for example, if Bazel is running in the workspace directory - `/home/user/src/my-project` (or in a directory symlinked to that one), then we - create an output base directory called: - `/home/.cache/bazel/_bazel_user/7ffd56a6e4cb724ea575aba15733d113`. -* Users can use Bazel's `--output_base` startup option to override the default - output base directory. For example, - `bazel --output_base=/tmp/bazel/output build x/y:z`. -* Users can also use Bazel's `--output_user_root` startup option to override the - default install base and output base directories. For example: - `bazel --output_user_root=/tmp/bazel build x/y:z`. - -We put symlinks "bazel-<workspace-name>" and "bazel-out", as well as -"bazel-bin", "bazel-genfiles", and "bazel-includes" in the workspace directory; -these symlinks points to some directories inside a target-specific directory -inside the output directory. These symlinks are only for the user's convenience, -as Bazel itself does not use them. Also, we only do this if the workspace -directory is writable. The names of the "bazel-bin", "bazel-genfiles", and -"bazel-include" symlinks are affected by the `--symlink_prefix` option to bazel, -but "bazel-<workspace-name>" and "bazel-out" are not. - -## Bazel internals: Directory layout - -The directories are laid out as follows: - -<pre> -<workspace-name>/ <== The workspace directory - bazel-my-project => <...my-project> <== Symlink to execRoot - bazel-out => <...bin> <== Convenience symlink to outputPath - bazel-bin => <...bin> <== Convenience symlink to most recent written bin dir $(BINDIR) - bazel-genfiles => <...genfiles> <== Convenience symlink to most recent written genfiles dir $(GENDIR) - -/home/user/.cache/bazel/ <== Root for all Bazel output on a machine: outputRoot - _bazel_$USER/ <== Top level directory for a given user depends on the user name: - outputUserRoot - install/ - fba9a2c87ee9589d72889caf082f1029/ <== Hash of the Bazel install manifest: installBase - _embedded_binaries/ <== Contains binaries and scripts unpacked from the data section of - the bazel executable on first run (e.g. helper scripts and the - main Java file BazelServer_deploy.jar) - 7ffd56a6e4cb724ea575aba15733d113/ <== Hash of the client's workspace directory (e.g. - /home/some-user/src/my-project): outputBase - action_cache/ <== Action cache directory hierarchy - This contains the persistent record of the file metadata - (timestamps, and perhaps eventually also MD5 sums) used by the - FilesystemValueChecker. - action_outs/ <== Action output directory. This contains a file with the - stdout/stderr for every action from the most recent bazel run - that produced output. - command.log <== A copy of the stdout/stderr output from the most recent bazel - command. - external/ <== The directory that remote repositories are downloaded/symlinked - into. - server/ <== The Bazel server puts all server-related files (such as socket - file, logs, etc) here. - server.socket <== Socket file for the server. - server.log <== Server logs. - <workspace-name>/ <== Working tree for the Bazel build & root of symlink forest: execRoot - _bin/ <== Helper tools are linked from or copied to here. - - bazel-out/ <== All actual output of the build is under here: outputPath - local_linux-fastbuild/ <== one subdirectory per unique target BuildConfiguration instance; - this is currently encoded - bin/ <== Bazel outputs binaries for target configuration here: $(BINDIR) - foo/bar/_objs/baz/ <== Object files for a cc_* rule named //foo/bar:baz - foo/bar/baz1.o <== Object files from source //foo/bar:baz1.cc - other_package/other.o <== Object files from source //other_package:other.cc - foo/bar/baz <== foo/bar/baz might be the artifact generated by a cc_binary named - //foo/bar:baz - foo/bar/baz.runfiles/ <== The runfiles symlink farm for the //foo/bar:baz executable. - MANIFEST - <workspace-name>/ - ... - genfiles/ <== Bazel puts generated source for the target configuration here: - $(GENDIR) - foo/bar.h e.g. foo/bar.h might be a headerfile generated by //foo:bargen - testlogs/ <== Bazel internal test runner puts test log files here - foo/bartest.log e.g. foo/bar.log might be an output of the //foo:bartest test with - foo/bartest.status foo/bartest.status containing exit status of the test (e.g. - PASSED or FAILED (Exit 1), etc) - include/ <== a tree with include symlinks, generated as needed. The - bazel-include symlinks point to here. This is used for - linkstamp stuff, etc. - host/ <== BuildConfiguration for build host (user's workstation), for - building prerequisite tools, that will be used in later stages - of the build (ex: Protocol Compiler) - <packages>/ <== Packages referenced in the build appear as if under a regular workspace -</pre> - -The layout of the *.runfiles directories is documented in more detail in the places pointed to by RunfilesSupport. - -## `bazel clean` - -`bazel clean` does an `rm -rf` on the `outputPath` and the `action_cache` -directory. It also removes the workspace symlinks. The `--partial` option to -`bazel clean` will clean a configuration-specific `outputDir`, and the -`--expunge` option will clean the entire outputBase. diff --git a/site/versions/master/docs/skyframe.md b/site/versions/master/docs/skyframe.md deleted file mode 100644 index ae3dc53aee..0000000000 --- a/site/versions/master/docs/skyframe.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -layout: contribute -title: Skyframe ---- - -# Skyframe - -<p class="lead">The parallel evaluation and incrementality model of Bazel</p> - -## Data model - -The data model consists of the following items: - - - `SkyValue`. Also called nodes. `SkyValues` are immutable objects that contain all the data built - over the course of the build and the inputs of the build. Examples are: input files, output - files, targets and configured targets. - - `SkyKey`. A short immutable name to reference a `SkyValue`, for example, `FILECONTENTS:/tmp/foo` - or `PACKAGE://foo`. - - `SkyFunction`. Builds nodes based on their keys and dependent nodes. - - Node graph. A data structure containing the dependency relationship between nodes. - - `Skyframe`. Code name for the incremental evaluation framework Bazel is based on. - - -## Evaluation - -A build consists of evaluating the node that represents the build request (this is the state we are -striving for, but there is a lot of legacy code in the way). First its `SkyFunction` is found and -called with the key of the top-level `SkyKey`. The function then requests the evaluation of the -nodes it needs to evaluate the top-level node, which in turn result in other function invocations, -and so on, until the leaf nodes are reached (which are usually nodes representing input files in -the file system). Finally, we end up with the value of the top-level `SkyValue`, some side effects -(e.g. output files in the file system) and a directed acyclic graph of the dependencies between the -nodes that were involved in the build. - -A `SkyFunction` can request `SkyKeys` in multiple passes if it cannot tell in advance all of the -nodes it needs to do its job. A simple example is evaluating an input file node that turns out to -be a symlink: the function tries to read the file, realizes that it's a symlink, and thus fetches -the file system node representing the target of the symlink. But that itself can be a symlink, in -which case the original function will need to fetch its target, too. - -The functions are represented in the code by the interface `SkyFunction` and the services -provided to it by an interface called `SkyFunction.Environment`. These are the things functions can -do: - - - Request the evaluation of another node by way of calling `env.getValue`. If the node is - available, its value is returned, otherwise, `null` is returned and the function itself is - expected to return `null`. In the latter case, the dependent node is evaluated, and then the - original node builder is invoked again, but this time the same `env.getValue` call will return a - non-`null` value. - - Request the evaluation of multiple other nodes by calling `env.getValues()`. This does - essentially the same, except that the dependent nodes are evaluated in parallel. - - Do computation during their invocation - - Have side effects, for example, writing files to the file system. Care needs to be taken that two - different functions do not step on each other's toes. In general, write side effects (where - data flows outwards from Bazel) are okay, read side effects (where data flows inwards into Bazel - without a registered dependency) are not, because they are an unregistered dependency and as - such, can cause incorrect incremental builds. - -`SkyFunction` implementations should not access data in any other way than requesting dependencies -(e.g. by directly reading the file system), because that results in Bazel not registering the data -dependency on the file that was read, thus resulting in incorrect incremental builds. - -Once a function has enough data to do its job, it should return a non-`null` value indicating -completion. - -This evaluation strategy has a number of benefits: - - - Hermeticity. If functions only request input data by way of depending on other nodes, Bazel - can guarantee that if the input state is the same, the same data is returned. If all sky - functions are deterministic, this means that the whole build will also be deterministic. - - Correct and perfect incrementality. If all the input data of all functions is recorded, Bazel - can invalidate only the exact set of nodes that need to be invalidated when the input data - changes. - - Parallelism. Since functions can only interact with each other by way of requesting - dependencies, functions that do not depend on each other can be run in parallel and Bazel can - guarantee that the result is the same as if they were run sequentially. - -## Incrementality - -Since functions can only access input data by depending on other nodes, Bazel can build up a -complete data flow graph from the input files to the output files, and use this information to only -rebuild those nodes that actually need to be rebuilt: the reverse transitive closure of the set of -changed input files. - -In particular, two possible incrementality strategies exist: the bottom-up one and the top-down one. -Which one is optimal depends on how the dependency graph looks like. - - - During bottom-up invalidation, after a graph is built and the set of changed inputs is known, - all the nodes are invalidated that transitively depend on changed files. This is optimal - if we know that the same top-level node will be built again. - Note that bottom-up invalidation requires running `stat()` on all input files of the previous - build to determine if they were changed. This can be improved by using `inotify` or a similar - mechanism to learn about changed files. - - - During top-down invalidation, the transitive closure of the top-level node is checked and only - those nodes are kept whose transitive closure is clean. This is better if we know that the - current node graph is large, but we only need a small subset of it in the next build: bottom-up - invalidation would invalidate the larger graph of the first build, unlike top-down invalidation, - which just walks the small graph of second build. - -We currently only do bottom-up invalidation. - -To get further incrementality, we use _change pruning_: if a node is invalidated, but upon rebuild, -it is discovered that its new value is the same as its old value, the nodes that were invalidated -due to a change in this node are "resurrected". - -This is useful, for example, if one changes a comment in a C++ file: then the `.o` file generated -from it will be the same, thus, we don't need to call the linker again. - -## Incremental Linking / Compilation - -The main limitation of this model is that the invalidation of a node is an all-or-nothing affair: -when a dependency changes, the dependent node is always rebuilt from scratch, even if a better -algorithm would exist that would mutate the old value of the node based on the changes. A few -examples where this would be useful: - - - Incremental linking - - When a single `.class` file changes in a `.jar`, we could theoretically modify the `.jar` file - instead of building it from scratch again. - -The reason why Bazel currently does not support these things in a principled way (we have some -measure of support for incremental linking, but it's not implemented within Skyframe) is twofold: -we only had limited performance gains and it was hard to guarantee that the result of the mutation -is the same as that of a clean rebuild would be, and Google values builds that are bit-for-bit -repeatable. - -Until now, we could always achieve good enough performance by simply decomposing an expensive build -step and achieving partial re-evaluation that way: it splits all the classes in an app into -multiple groups and does dexing on them separately. This way, if classes in a group do not change, -the dexing does not have to be redone. - -## Restarting SkyFunctions - -Another inefficiency is that, currently, if a `SkyFunction` implementation cannot complete its job -because one of its dependencies is missing, it needs to be completely restarted instead of resuming -where it left off. This is currently not a big problem because we usually learn all the -dependencies after a small amount of work. The only exceptions are package loading and execution of -actions; these are both external processes that are expensive to restart. We allow package loading -to proceed fully, store the loaded package away, record the dependencies in the graph, and on -re-execution of the function return the already loaded package. I.e., we allow the function to keep -state between executions. - -If this turns out to be a significant performance or code health problem, there are alternative ways -to add a more principled mechanism to keep state between executions: - - - Splitting each node into multiple ones so that each smaller node only has to do one round of - dependency discovery (effectively continuation passing); this requires explicit code. - - By reimplementing Skyframe on some sort of lightweight thread infrastructure (e.g. - [Quasar](http://docs.paralleluniverse.co/quasar/)) so that function execution can be suspended - and resumed without a large performance hit and without requiring this to be explicit in the - code. - - By maintaining state for each `SkyFunction` instance between restarts (this is the workaround we - are using for package loading, but is not implemented as a first-class feature of the evaluation - framework). - -## Mapping to Bazel concepts - -This is a rough overview of some of the `SkyFunction` implementations Bazel uses to perform a build: - - - **FileStateValue**. The result of an `lstat()`. For existent files, we also compute additional - information in order to detect changes to the file. This is the lowest level node in the Skyframe - graph and has no dependencies. - - **FileValue**. Used by anything that cares about the actual contents and/or resolved path of a - file. Depends on the corresponding `FileStateValue` and any symlinks that need to be resolved - (e.g. the `FileValue` for `a/b` needs the resolved path of `a` and the resolved path of `a/b`). - The distinction between `FileStateValue` is important because in some cases (for example, - evaluating file system globs (e.g. `srcs=glob(["*/*.java"])`) the contents of the file are not - actually needed. - - **DirectoryListingValue**. Essentially the result of `readdir()`. Depends on the associated - `FileValue` associated with the directory. - - **PackageValue**. Represents the parsed version of a BUILD file. Depends on the `FileValue` of - the associated `BUILD` file, and also transitively on any `DirectoryListingValue` that is used - to resolve the globs in the package (the data structure representing the contents of a `BUILD` - file internally) - - **ConfiguredTargetValue**. Represents a configured target, which is a tuple of the set of actions - generated during the analysis of a target and information provided to configured targets that - depend on this one. Depends on the `PackageValue` the corresponding target is in, the - `ConfiguredTargetValues` of direct dependencies, and a special node representing the build - configuration. - - **ArtifactValue**. Represents a file in the build, be it a source or an output artifacts - (artifacts are almost equivalent to files, and are used to refer to files during the actual - execution of build steps). For source files, it depends on the `FileValue` of the associated - node, for output artifacts, it depends on the `ActionExecutionValue` of whatever action generates - the artifact. - - **ActionExecutionValue**. Represents the execution of an action. Depends on the `ArtifactValues` - of its input files. The action it executes is currently contained within its sky key, which is - contrary to the concept that sky keys should be small. We are working on solving this - discrepancy (note that `ActionExecutionValue` and `ArtifactValue` are unused if we do not run the - execution phase on Skyframe). diff --git a/site/versions/master/docs/skylark/aspects.md b/site/versions/master/docs/skylark/aspects.md deleted file mode 100644 index 71589cbacc..0000000000 --- a/site/versions/master/docs/skylark/aspects.md +++ /dev/null @@ -1,191 +0,0 @@ ---- -layout: documentation -title: Aspects ---- -# Aspects - -**Status: Experimental**. We may make breaking changes to the API, but we will - help you update your code. - -Aspects allow augmenting build dependency graphs with additional information -and actions. Some typical scenarios when aspects can be useful: - -* IDEs that integrate Bazel can use aspects to collect information about the - project -* Code generation tools can leverage aspects to execute on their inputs in - "target-agnostic" manner. As an example, BUILD files can specify a hierarchy - of [protobuf](https://developers.google.com/protocol-buffers/) library - definitions, and language-specific rules can use aspects to attach - actions generating protobuf support code for a particular language - -## Aspect basics - -Bazel BUILD files provide a description of a project’s source code: what source -files are part of the project, what artifacts (_targets_) should be built from -those files, what the dependencies between those files are, etc. Bazel uses -this information to perform a build, that is, it figures out the set of actions -needed to produce the artifacts (such as running compiler or linker) and -executes those actions. Bazel accomplishes this by constructing a _dependency -graph_ between targets and visiting this graph to collect those actions. - -Consider the following BUILD file: - -```python -java_library(name = 'W', ...) -java_library(name = 'Y', deps = [':W'], ...) -java_library(name = 'Z', deps = [':W'], ...) -java_library(name = 'Q', ...) -java_library(name = 'T', deps = [':Q'], ...) -java_library(name = 'X', deps = [':Y',':Z'], runtime_deps = [':T'], ...) -``` - -This BUILD file defines a dependency graph shown in Fig 1. - -<img src="build-graph.png" alt="Build Graph" width="250px" /> - -Bazel analyzes this dependency graph by calling implementations of -[rules](rules.md) (in this case "java_library" starting from leaves of -the dependency graph). These implementations generate actions that build -artifacts (such as Jar files), and provide information (such as locations -and names of those artifacts) to their dependencies in providers that -they return. Their dependencies can access those providers through the -[Target object](lib/Target.html). In other words, every target -defined in the BUILD file generates a node in the dependency graph, and -the appropriate rule implementation function is called for every node. - -Aspects are similar to rules in that they have an implementation function that -generates actions and returns providers. However, their power comes from -the way the dependency graph is built for them. An aspect has an implementation -and a list of all attributes it propagates along. Consider an aspect A that -propagates along attributes named "deps". This aspect can be applied to -a target X, yielding an aspect application node A(X). During its application, -aspect A is applied recursively to all targets that X refers to in its "deps" -attribute (all attributes in A's propagation list). Thus a single act of -applying aspect A to a target X yields a "shadow graph" of the original -dependency graph of targets (see Fig.2). - -![Build Graph with Aspect](build-graph-aspects.png) - -The only edges that are shadowed are the edges along the attributes in -the propagation set, thus the `runtime_deps` edge is not shadowed in this -example. An aspect implementation function is then invoked on all nodes in -the shadow graph similar to how rule implementations are invoked on the nodes -of the original graph. - -## Defining aspects - -Aspect defintions are similiar to rule definitions. Let's take a look at -the example: - -```python -metal_proto_aspect = aspect(implementation = _metal_proto_aspect_impl, - attr_aspects = ["deps"], - attrs = { - "_protoc" : attr.label( - default=Label("//tools:metal_protoc"), - executable = True - ) - } -) -``` - -Just like a rule, an aspect has an implementation function. ``attr_aspects`` -specify the aspect's propagation set: a list of attributes of rules along which -the aspect propagates. - -``attrs`` defines a set of attributes for aspects. Aspects are only allowed -to have private attributes of types ``label`` or ``label_list``. Attributes -can be used to specify dependencies on tools or libraries that are needed -for actions generated by aspects. - -### Implementation functions - -Aspect implementation functions are similiar to the rule implementation -functions. They return [providers](rules.md#providers), can generate -[actions](rules.md#actions) and take two arguments: - -* `target`: the target the aspect is being applied to. -* [`ctx`](lib/ctx.html): `ctx` object that can be used to access attributes and - generate outputs and actions. - -Example: - -```python -def _metal_proto_aspect_impl(target, ctx): - # For every `src` in proto_library, generate an output file - proto_sources = [f for src in ctx.rule.attr.src - for f in src.files] - outputs = [ctx.new_file(f.short_path + ".metal") - for f in proto_sources] - ctx.action( - executable = ctx.executable._protoc, - argument = ... - inputs = proto_sources - outputs = outputs) - transitive_outputs = set(outputs) - for dep in ctx.attr.deps: - transitive_outputs = transitive_outputs | dep.metal_proto.transitive_outputs - return struct( - metal_proto = struct(direct_outputs = outputs, - transitive_outputs = transitive_outputs)) -``` - -The implementation function can access the attributes of the target rule via -[`ctx.rule.attr`](lib/ctx.html#rule). It can examine providers that are -provided by the target to which it is applied (via the `target` argument). - -Just like a rule implementation function, an aspect implementation function -returns a struct of providers that are accessible to its dependencies. - -* The set of providers for an aspect application A(X) is the union of providers - that come from the implementation of a rule for target X and from - the implementation of aspect A. It is an error if a target and an aspect that - is applied to it each provide a provider with the same name. -* For the aspect implementation, the values of attributes along which - the aspect is propagated (from the `attr_aspect` list) are replaced with - the results of an application of the aspect to them. For example, if target - X has Y and Z in its deps, `ctx.rule.attr.deps` for A(X) will be [A(Y), A(Z)]. - In the `_metal_proto_aspect_impl` function above, ctx.rule.attr.deps will be - Target objects that are the results of applying the aspect to the 'deps' - of the original target to which the aspect has been applied. - That allows the aspect to examine `metal_proto` provider on them. - - -## Applying aspects - -Aspect propagation can be initiated either from a rule or from the command line. - -### Applying aspects to rule attributes - -Rules can specify that they want to apply aspects to their depenedencies. -The aspects to be applied to a particular attribute can be specified -using the `aspects` parameter to `attr.label` or `attr.label_list` function: - -```python -metal_proto_library = rule(implementation = _impl, - attrs = { - 'proto_deps' : attr.label_list(aspects = [metal_proto_aspect]), - }, -) -``` - -If a rule specifies an aspect on its attributes, the values of that attribute -will be replaced by the result of aspect application to them (similiar to -what happens during aspect propagation). Thus implementaion of -`metal_proto_library` will have access to `metal_proto` providers -on the target objects representing its `proto_deps` attribute values. - -### Applying aspects from command line. - -Aspects can also be applied on the command line, using the `--aspects` flag: - - -``` -bazel build //java/com/company/example:main \ - --aspects path/to/extension.bzl%metal_proto_aspect -``` - -`--aspects` flag takes one argument, which is a specification of the aspect in -the format `<extension file path>%<aspect top-level name>`. - - diff --git a/site/versions/master/docs/skylark/build-graph-aspect.svg b/site/versions/master/docs/skylark/build-graph-aspect.svg deleted file mode 100644 index 508a916bd3..0000000000 --- a/site/versions/master/docs/skylark/build-graph-aspect.svg +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" standalone="yes"?> - -<svg version="1.1" viewBox="0.0 0.0 960.0 720.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m110.0 326.28873l0 0c0 -8.288635 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192383 23.496063 15.007874l0 0c0 8.288605 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.719269 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m110.0 326.28873l0 0c0 -8.288635 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192383 23.496063 15.007874l0 0c0 8.288605 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.719269 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m127.3524 333.2087l5.265625 -7.09375l-4.640625 -6.5l2.140625 0l2.46875 3.484375q0.78125 1.078125 1.09375 1.671875q0.453125 -0.75 1.078125 -1.546875l2.734375 -3.609375l1.96875 0l-4.78125 6.40625l5.140625 7.1875l-2.21875 0l-3.421875 -4.859375q-0.296875 -0.40625 -0.59375 -0.90625q-0.453125 0.75 -0.65625 1.03125l-3.40625 4.734375l-2.171875 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m79.0 141.00787l0 0c0 -8.28862 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m79.0 141.00787l0 0c0 -8.28862 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m101.57115 147.92787l0 -5.765625l-5.234375 -7.828125l2.1875 0l2.671875 4.09375q0.75 1.15625 1.390625 2.296875q0.609375 -1.0625 1.484375 -2.40625l2.625 -3.984375l2.109375 0l-5.4375 7.828125l0 5.765625l-1.796875 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m163.51181 141.00787l0 0c0 -8.28862 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m163.51181 141.00787l0 0c0 -8.28862 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m181.68489 147.92787l0 -1.671875l6.96875 -8.703125q0.75 -0.9375 1.421875 -1.625l-7.59375 0l0 -1.59375l9.734375 0l0 1.59375l-7.625 9.4375l-0.828125 0.953125l8.6875 0l0 1.609375l-10.765625 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m0 141.00787l0 0c0 -8.28862 10.519546 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976518 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m0 141.00787l0 0c0 -8.28862 10.519546 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976518 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m22.719948 147.92787l0 -12.0l-4.46875 0l0 -1.59375l10.765625 0l0 1.59375l-4.5 0l0 12.0l-1.796875 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m110.0 19.007874l0 0c0 -8.288619 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192545 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m110.0 19.007874l0 0c0 -8.288619 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192545 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m128.53548 25.927872l-3.6093674 -13.59375l1.84375 0l2.0624924 8.90625q0.34375 1.40625 0.578125 2.78125q0.515625 -2.171875 0.609375 -2.515625l2.59375 -9.171875l2.171875 0l1.953125 6.875q0.734375 2.5625 1.046875 4.8125q0.265625 -1.28125 0.6875 -2.953125l2.125 -8.734375l1.8125 0l-3.734375 13.59375l-1.734375 0l-2.859375 -10.359375q-0.359375 -1.296875 -0.421875 -1.59375q-0.21875 0.9375 -0.40625 1.59375l-2.890625 10.359375l-1.828125 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m133.49606 311.28085l-30.992126 -155.2756" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m133.49606 311.28085l-29.817726 -149.39166" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m105.29812 161.56589l-2.5080414 -4.127014l-0.7315216 4.7736206z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m133.49606 311.28085l53.51181 -155.2756" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m133.49606 311.28085l51.5569 -149.60301" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m186.61456 162.216l-0.08300781 -4.8286285l-3.0401917 3.752304z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m102.49606 126.0l30.992126 -92.0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m102.49606 126.0l29.076675 -86.313965" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m133.13803 40.21334l-0.11654663 -4.8279343l-3.0140533 3.7733269z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m187.00787 126.0l-53.51181 -92.0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m187.00787 126.0l-50.495102 -86.81353" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m137.94055 38.356003l-3.7094727 -3.0923195l0.85391235 4.75325z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m110.0 326.28873l-86.48819 -170.26773" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m110.0 326.28873l-83.77092 -164.9183" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m27.701717 160.6224l-3.5278435 -3.2980194l0.5825653 4.7940826z" fill-rule="evenodd"></path><path fill="#cfe2f3" d="m0 19.007874l0 0c0 -8.288619 10.519546 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192545 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976518 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m0 19.007874l0 0c0 -8.288619 10.519546 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192545 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976518 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m28.005974 24.474747q1.265625 0.859375 2.3125 1.265625l-0.53125 1.25q-1.453125 -0.53125 -2.921875 -1.671875q-1.5 0.84375 -3.328125 0.84375q-1.84375 0 -3.359375 -0.890625q-1.5 -0.890625 -2.3125 -2.5q-0.8125 -1.625 -0.8125 -3.640625q0 -2.015625 0.8125 -3.65625q0.828125 -1.65625 2.328125 -2.515625q1.515625 -0.875 3.375 -0.875q1.890625 0 3.390625 0.90625q1.515625 0.890625 2.3125 2.5q0.796875 1.609375 0.796875 3.625q0 1.6875 -0.515625 3.03125q-0.515625 1.328125 -1.546875 2.328125zm-3.953125 -2.296875q1.5625 0.421875 2.5625 1.296875q1.59375 -1.453125 1.59375 -4.359375q0 -1.65625 -0.5625 -2.875q-0.5625 -1.234375 -1.640625 -1.921875q-1.078125 -0.6875 -2.421875 -0.6875q-2.015625 0 -3.34375 1.390625q-1.328125 1.375 -1.328125 4.109375q0 2.65625 1.3125 4.078125q1.3125 1.40625 3.359375 1.40625q0.953125 0 1.8125 -0.359375q-0.84375 -0.546875 -1.78125 -0.78125l0.4375 -1.296875z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m23.496063 126.0l0 -92.0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m23.496063 126.0l0 -86.0" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m25.147795 40.0l-1.6517315 -4.5380974l-1.6517334 4.5380974z" fill-rule="evenodd"></path><path fill="#ffff00" d="m244.7559 329.46457l0 0c0 -8.288635 20.82051 -15.007874 46.503952 -15.007874l0 0c25.68341 0 46.503937 6.7192383 46.503937 15.007874l0 0c0 8.288605 -20.820526 15.007874 -46.503937 15.007874l0 0c-25.683441 0 -46.503952 -6.719269 -46.503952 -15.007874z" fill-rule="nonzero"></path><path stroke="#ff0000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m244.7559 329.46457l0 0c0 -8.288635 20.82051 -15.007874 46.503952 -15.007874l0 0c25.68341 0 46.503937 6.7192383 46.503937 15.007874l0 0c0 8.288605 -20.820526 15.007874 -46.503937 15.007874l0 0c-25.683441 0 -46.503952 -6.719269 -46.503952 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m272.57236 336.38455l5.234375 -13.59375l1.9375 0l5.5625 13.59375l-2.046875 0l-1.59375 -4.125l-5.6875 0l-1.484375 4.125l-1.921875 0zm3.921875 -5.578125l4.609375 0l-1.40625 -3.78125q-0.65625 -1.703125 -0.96875 -2.8125q-0.265625 1.3125 -0.734375 2.59375l-1.5 4.0zm12.990448 9.578125q-1.375 -1.75 -2.328125 -4.078125q-0.953125 -2.34375 -0.953125 -4.84375q0 -2.21875 0.703125 -4.234375q0.84375 -2.34375 2.578125 -4.671875l1.2030945 0q-1.1249695 1.921875 -1.4843445 2.75q-0.5625 1.28125 -0.890625 2.671875q-0.40625 1.734375 -0.40625 3.484375q0 4.46875 2.7812195 8.921875l-1.2030945 0zm1.8532715 -4.0l5.265625 -7.09375l-4.640625 -6.5l2.140625 0l2.46875 3.484375q0.78125 1.078125 1.09375 1.671875q0.453125 -0.75 1.078125 -1.546875l2.734375 -3.609375l1.96875 0l-4.78125 6.40625l5.140625 7.1875l-2.21875 0l-3.421875 -4.859375q-0.296875 -0.40625 -0.59375 -0.90625q-0.453125 0.75 -0.65625 1.03125l-3.40625 4.734375l-2.171875 0zm14.709198 4.0l-1.1875 0q2.765625 -4.453125 2.765625 -8.921875q0 -1.734375 -0.390625 -3.453125q-0.328125 -1.390625 -0.890625 -2.671875q-0.359375 -0.84375 -1.484375 -2.78125l1.1875 0q1.75 2.328125 2.578125 4.671875q0.71875 2.015625 0.71875 4.234375q0 2.5 -0.96875 4.84375q-0.953125 2.328125 -2.328125 4.078125z" fill-rule="nonzero"></path><path fill="#ffff00" d="m217.57217 216.36745l0 0c0 -8.28862 20.820526 -15.007874 46.503937 -15.007874l0 0c25.68341 0 46.503937 6.7192535 46.503937 15.007874l0 0c0 8.28862 -20.820526 15.007889 -46.503937 15.007889l0 0c-25.68341 0 -46.503937 -6.719269 -46.503937 -15.007889z" fill-rule="nonzero"></path><path stroke="#ff0000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m217.57217 216.36745l0 0c0 -8.28862 20.820526 -15.007874 46.503937 -15.007874l0 0c25.68341 0 46.503937 6.7192535 46.503937 15.007874l0 0c0 8.28862 -20.820526 15.007889 -46.503937 15.007889l0 0c-25.68341 0 -46.503937 -6.719269 -46.503937 -15.007889z" fill-rule="nonzero"></path><path fill="#000000" d="m245.38861 223.28745l5.234375 -13.59375l1.9375 0l5.5625 13.59375l-2.046875 0l-1.59375 -4.125l-5.6875 0l-1.484375 4.125l-1.921875 0zm3.921875 -5.578125l4.609375 0l-1.40625 -3.78125q-0.65625 -1.703125 -0.96875 -2.8125q-0.265625 1.3125 -0.734375 2.59375l-1.5 4.0zm12.990448 9.578125q-1.375 -1.75 -2.328125 -4.078125q-0.953125 -2.34375 -0.953125 -4.84375q0 -2.21875 0.703125 -4.234375q0.84375 -2.34375 2.578125 -4.671875l1.203125 0q-1.125 1.921875 -1.484375 2.75q-0.5625 1.28125 -0.890625 2.671875q-0.40625 1.734375 -0.40625 3.484375q0 4.46875 2.78125 8.921875l-1.203125 0zm7.072052 -4.0l0 -5.765625l-5.234375 -7.828125l2.1875 0l2.671875 4.09375q0.75 1.15625 1.390625 2.296875q0.609375 -1.0625 1.484375 -2.40625l2.625 -3.984375l2.109375 0l-5.4375 7.828125l0 5.765625l-1.796875 0zm9.490448 4.0l-1.1875 0q2.765625 -4.453125 2.765625 -8.921875q0 -1.734375 -0.390625 -3.453125q-0.328125 -1.390625 -0.890625 -2.671875q-0.359375 -0.84375 -1.484375 -2.78125l1.1875 0q1.75 2.328125 2.578125 4.671875q0.71875 2.015625 0.71875 4.234375q0 2.5 -0.96875 4.84375q-0.953125 2.328125 -2.328125 4.078125z" fill-rule="nonzero"></path><path fill="#ffff00" d="m372.01575 141.00787l0 0c0 -8.28862 20.820526 -15.007874 46.503937 -15.007874l0 0c25.68341 0 46.503937 6.7192535 46.503937 15.007874l0 0c0 8.28862 -20.820526 15.007874 -46.503937 15.007874l0 0c-25.68341 0 -46.503937 -6.7192535 -46.503937 -15.007874z" fill-rule="nonzero"></path><path stroke="#ff0000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m372.01575 141.00787l0 0c0 -8.28862 20.820526 -15.007874 46.503937 -15.007874l0 0c25.68341 0 46.503937 6.7192535 46.503937 15.007874l0 0c0 8.28862 -20.820526 15.007874 -46.503937 15.007874l0 0c-25.68341 0 -46.503937 -6.7192535 -46.503937 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m400.356 147.92787l5.234375 -13.59375l1.9375 0l5.5625 13.59375l-2.046875 0l-1.59375 -4.125l-5.6875 0l-1.484375 4.125l-1.921875 0zm3.921875 -5.578125l4.609375 0l-1.40625 -3.78125q-0.65625 -1.703125 -0.96875 -2.8125q-0.265625 1.3125 -0.734375 2.59375l-1.5 4.0zm12.990448 9.578125q-1.375 -1.75 -2.328125 -4.078125q-0.953125 -2.34375 -0.953125 -4.84375q0 -2.21875 0.703125 -4.234375q0.84375 -2.34375 2.578125 -4.671875l1.203125 0q-1.125 1.921875 -1.484375 2.75q-0.5625 1.28125 -0.890625 2.671875q-0.40625 1.734375 -0.40625 3.484375q0 4.46875 2.78125 8.921875l-1.203125 0zm2.150177 -4.0l0 -1.671875l6.96875 -8.703125q0.75 -0.9375 1.421875 -1.625l-7.59375 0l0 -1.59375l9.734375 0l0 1.59375l-7.625 9.4375l-0.828125 0.953125l8.6875 0l0 1.609375l-10.765625 0zm13.364716 4.0l-1.1875 0q2.765625 -4.453125 2.765625 -8.921875q0 -1.734375 -0.390625 -3.453125q-0.328125 -1.390625 -0.890625 -2.671875q-0.359375 -0.84375 -1.484375 -2.78125l1.1875 0q1.75 2.328125 2.578125 4.671875q0.71875 2.015625 0.71875 4.234375q0 2.5 -0.96875 4.84375q-0.953125 2.328125 -2.328125 4.078125z" fill-rule="nonzero"></path><path fill="#ffff00" d="m295.0 19.007874l0 0c0 -8.288619 20.820526 -15.007874 46.503937 -15.007874l0 0c25.68341 0 46.503937 6.7192545 46.503937 15.007874l0 0c0 8.28862 -20.820526 15.007874 -46.503937 15.007874l0 0c-25.68341 0 -46.503937 -6.7192535 -46.503937 -15.007874z" fill-rule="nonzero"></path><path stroke="#ff0000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m295.0 19.007874l0 0c0 -8.288619 20.820526 -15.007874 46.503937 -15.007874l0 0c25.68341 0 46.503937 6.7192545 46.503937 15.007874l0 0c0 8.28862 -20.820526 15.007874 -46.503937 15.007874l0 0c-25.68341 0 -46.503937 -6.7192535 -46.503937 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m320.2339 25.927872l5.234375 -13.59375l1.9375 0l5.5625 13.59375l-2.046875 0l-1.59375 -4.125l-5.6875 0l-1.484375 4.125l-1.921875 0zm3.921875 -5.578125l4.609375 0l-1.40625 -3.78125q-0.65625 -1.703125 -0.96875 -2.8125q-0.265625 1.3125 -0.734375 2.59375l-1.5 4.0zm12.990448 9.578125q-1.375 -1.75 -2.328125 -4.078125q-0.953125 -2.34375 -0.953125 -4.84375q0 -2.21875 0.703125 -4.234375q0.84375 -2.34375 2.578125 -4.671875l1.203125 0q-1.125 1.921875 -1.484375 2.75q-0.5625 1.28125 -0.890625 2.671875q-0.40625 1.734375 -0.40625 3.484375q0 4.46875 2.78125 8.921875l-1.203125 0zm5.618927 -4.0l-3.609375 -13.59375l1.84375 0l2.0625 8.90625q0.34375 1.40625 0.578125 2.78125q0.515625 -2.171875 0.609375 -2.515625l2.59375 -9.171875l2.171875 0l1.953125 6.875q0.734375 2.5625 1.046875 4.8125q0.265625 -1.28125 0.6875 -2.953125l2.125 -8.734375l1.8125 0l-3.734375 13.59375l-1.734375 0l-2.859375 -10.359375q-0.359375 -1.296875 -0.421875 -1.59375q-0.21875 0.9375 -0.40625 1.59375l-2.890625 10.359375l-1.828125 0zm16.108673 4.0l-1.1875 0q2.765625 -4.453125 2.765625 -8.921875q0 -1.734375 -0.390625 -3.453125q-0.328125 -1.390625 -0.890625 -2.671875q-0.359375 -0.84375 -1.484375 -2.78125l1.1875 0q1.75 2.328125 2.578125 4.671875q0.71875 2.015625 0.71875 4.234375q0 2.5 -0.96875 4.84375q-0.953125 2.328125 -2.328125 4.078125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m244.7559 329.46457l-87.74803 -3.1810913" fill-rule="nonzero"></path><path stroke="#ff0000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m244.7559 329.46457l-81.75197 -2.9637146" fill-rule="evenodd"></path><path fill="#ff0000" stroke="#ff0000" stroke-width="1.0" stroke-linecap="butt" d="m163.06378 324.8502l-4.5949707 1.4862366l4.475281 1.8150635z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m291.25986 314.4567l-27.181122 -83.086624" fill-rule="nonzero"></path><path stroke="#0000ff" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m291.25986 314.4567l-25.315552 -77.384" fill-rule="evenodd"></path><path fill="#0000ff" stroke="#0000ff" stroke-width="1.0" stroke-linecap="butt" d="m267.51416 236.55911l-2.9808655 -3.799591l-0.158844 4.826721z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m291.25986 314.4567l127.27557 -158.4252" fill-rule="nonzero"></path><path stroke="#0000ff" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m291.25986 314.4567l123.51779 -153.74771" fill-rule="evenodd"></path><path fill="#0000ff" stroke="#0000ff" stroke-width="1.0" stroke-linecap="butt" d="m416.06528 161.74347l1.5545654 -4.572296l-4.129883 2.5033264z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m231.19287 205.75528l-112.09449 -54.141724" fill-rule="nonzero"></path><path stroke="#ff0000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m231.19287 205.7553l-106.6917 -51.53218" fill-rule="evenodd"></path><path fill="#ff0000" stroke="#ff0000" stroke-width="1.0" stroke-linecap="butt" d="m125.21955 152.73578l-4.8047867 -0.48640442l3.3680267 3.4610596z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m372.01575 141.00787l-161.51181 0" fill-rule="nonzero"></path><path stroke="#ff0000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m372.01575 141.00787l-155.51181 0" fill-rule="evenodd"></path><path fill="#ff0000" stroke="#ff0000" stroke-width="1.0" stroke-linecap="butt" d="m216.50394 139.35614l-4.538101 1.6517334l4.538101 1.6517334z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m264.0761 201.35957l77.41733 -167.33858" fill-rule="nonzero"></path><path stroke="#0000ff" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m264.0761 201.35957l74.89804 -161.8931" fill-rule="evenodd"></path><path fill="#0000ff" stroke="#0000ff" stroke-width="1.0" stroke-linecap="butt" d="m340.47324 40.160004l0.40637207 -4.812214l-3.404541 3.4251518z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m418.51968 126.0l-77.00787 -92.0" fill-rule="nonzero"></path><path stroke="#0000ff" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m418.51968 126.0l-73.15671 -87.39908" fill-rule="evenodd"></path><path fill="#0000ff" stroke="#0000ff" stroke-width="1.0" stroke-linecap="butt" d="m346.62955 37.54074l-4.179413 -2.4197235l1.6462708 4.5400887z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m295.0 19.007874l-138.01575 0" fill-rule="nonzero"></path><path stroke="#ff0000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m295.0 19.007874l-132.01575 0" fill-rule="evenodd"></path><path fill="#ff0000" stroke="#ff0000" stroke-width="1.0" stroke-linecap="butt" d="m162.98425 17.356142l-4.538101 1.6517315l4.538101 1.6517334z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m137.17401 206.24611l11.842514 46.771652l-29.102364 7.3700867l-11.842514 -46.771667z" fill-rule="nonzero"></path><path fill="#000000" d="m121.81724 223.98074l0.69675446 -0.17645264q-0.9483261 -0.30786133 -1.2091141 -1.3378601q-0.16491699 -0.6513214 0.05670166 -1.3038177q0.22162628 -0.65249634 0.79623413 -1.1203918q0.57460785 -0.46788025 1.4228363 -0.6826935q0.83306885 -0.21096802 1.5685654 -0.10710144q0.75447845 0.11517334 1.240921 0.57225037q0.50159454 0.4532318 0.6741791 1.1348419q0.1265564 0.4998474 0.014221191 0.94737244q-0.112342834 0.44752502 -0.38420868 0.77427673l2.7415695 -0.6943054l0.23779297 0.93911743l-7.6340103 1.9332886l-0.22244263 -0.8785248zm2.0088654 -3.6517944q-1.0602798 0.2685089 -1.4792023 0.84202576q-0.39993286 0.5848236 -0.24652863 1.1907043q0.15724182 0.6210327 0.76447296 0.91856384q0.60723877 0.29753113 1.6372223 0.036697388q1.1360092 -0.2876892 1.5549316 -0.8612213q0.42275238 -0.55836487 0.2578354 -1.2096863q-0.15724182 -0.6210327 -0.7796173 -0.9147186q-0.6034012 -0.2823944 -1.7091141 -0.0023651123zm1.2829971 9.141266l0.12427521 1.0000916q-0.90574646 -0.012390137 -1.5325394 -0.5145111q-0.62680054 -0.5021057 -0.86841583 -1.4563751q-0.3068161 -1.2117615 0.25512695 -2.111618q0.5619354 -0.8998718 1.9100037 -1.241272q1.4086609 -0.35673523 2.3462524 0.16337585q0.9565811 0.5314331 1.2442245 1.6674652q0.28379822 1.1208649 -0.29711914 2.00943q-0.56578064 0.88471985 -1.9441376 1.2337799q-0.075737 0.019180298 -0.24235535 0.06138611l-1.0431747 -4.119995q-0.8973007 0.275589 -1.2669449 0.8527527q-0.36580658 0.5923004 -0.18938446 1.2890625q0.13039398 0.5149994 0.4799347 0.813324q0.36468506 0.29447937 1.0242538 0.35310364zm0.7361374 -3.458435l0.78237915 3.0899963q0.6814194 -0.23704529 0.95692444 -0.61305237q0.41508484 -0.5886688 0.23482513 -1.3005829q-0.16490936 -0.6513214 -0.71539307 -0.9793396q-0.5353317 -0.3318634 -1.2587357 -0.19702148zm-4.1481476 6.40654l7.649147 -1.9371185l0.21861267 0.8633728l-0.7118988 0.1802826q0.485672 0.19937134 0.7936096 0.524353q0.30792236 0.32496643 0.44599915 0.8702698q0.17642212 0.6967621 -0.049041748 1.3341064q-0.22544861 0.6373596 -0.822876 1.0787811q-0.58229065 0.43759155 -1.3850708 0.6408844q-0.8482208 0.21481323 -1.6065292 0.084487915q-0.74316406 -0.13415527 -1.2562637 -0.63282776q-0.5092621 -0.4835205 -0.6703415 -1.1197052q-0.118888855 -0.46955872 -0.017860413 -0.8981018q0.10486603 -0.4133911 0.34643555 -0.7324524l-2.6961365 0.68278503l-0.23778534 -0.93911743zm5.06176 -0.3792572q-1.0602798 0.26852417 -1.4640503 0.8381958q-0.3886261 0.56585693 -0.23521423 1.1717377q0.15724182 0.62101746 0.7834549 0.9298706q0.645195 0.32014465 1.7660599 0.03630066q1.0451355 -0.26467896 1.4640503 -0.8381958q0.42276 -0.5583801 0.26934814 -1.1642609q-0.15341187 -0.60588074 -0.83273315 -0.9335022q-0.67549133 -0.31248474 -1.7509155 -0.040145874zm0.07243347 4.805786l0.38542175 0.8856201q-0.54125977 0.21765137 -0.7559891 0.64276123q-0.19573975 0.43640137 -0.03466797 1.072586q0.16491699 0.6513214 0.499115 0.8890381q0.33803558 0.2528839 0.701561 0.16082764q0.31808472 -0.080566406 0.43081665 -0.39923096q0.07131958 -0.2276001 0.07646179 -1.0348206q-0.0032958984 -1.0951996 0.074920654 -1.5502014q0.09718323 -0.44369507 0.37672424 -0.7401428q0.28337097 -0.28129578 0.69233704 -0.38487244q0.37867737 -0.09588623 0.72380066 -0.005996704q0.36026 0.08607483 0.6490326 0.3353119q0.2203064 0.16986084 0.4222107 0.52168274q0.2019043 0.3518219 0.30929565 0.77593994q0.16491699 0.6513214 0.10588074 1.1820526q-0.0552063 0.5458832 -0.3309021 0.8574829q-0.25672913 0.3229065 -0.763855 0.54803467l-0.35128784 -0.87812805q0.40493774 -0.18313599 0.5554352 -0.5436249q0.16947937 -0.34916687 0.031417847 -0.89445496q-0.16491699 -0.6513214 -0.4460144 -0.8702698q-0.28108215 -0.2189331 -0.5688782 -0.14605713q-0.1817627 0.046035767 -0.29122925 0.18658447q-0.120788574 0.15953064 -0.16545105 0.42874146q-0.010925293 0.14782715 -0.031417847 0.89445496q-0.0082092285 1.0497589 -0.07510376 1.4857788q-0.06690979 0.4360199 -0.3426056 0.7476196q-0.26055908 0.30775452 -0.7452545 0.43049622q-0.4695511 0.118927 -0.9475479 -0.05015564q-0.47799683 -0.16908264 -0.8356018 -0.62654114q-0.35759735 -0.4574585 -0.5225067 -1.1087799q-0.27230072 -1.0754395 0.021217346 -1.7622681q0.3125 -0.6755066 1.1526642 -1.049469z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m120.55516 255.70743l18.960632 -44.377945l28.283463 12.094482l-18.960632 44.377945z" fill-rule="nonzero"></path><path fill="#000000" d="m143.51901 250.92964l-0.6608734 -0.28259277q0.56707764 0.8202667 0.14962769 1.7973175q-0.26397705 0.6178436 -0.83592224 1.0020447q-0.5719452 0.3841858 -1.3124847 0.4073944q-0.74053955 0.023208618 -1.5450745 -0.3208313q-0.79016113 -0.33789062 -1.3117828 -0.8668213q-0.52986145 -0.54945374 -0.6392975 -1.2080231q-0.123794556 -0.66470337 0.15246582 -1.3112946q0.20259094 -0.4741516 0.56333923 -0.761734q0.36073303 -0.28756714 0.7750244 -0.38230896l-2.600357 -1.1119537l0.3806305 -0.8908539l7.240753 3.096283l-0.35604858 0.833374zm-3.8118286 1.6837463q1.005661 0.43003845 1.6865234 0.2283783q0.67263794 -0.22218323 0.91819763 -0.7969208q0.25169373 -0.5891113 -0.05050659 -1.1941528q-0.30221558 -0.60505676 -1.2791443 -1.0228119q-1.0774994 -0.4607544 -1.7583466 -0.25907898q-0.6747284 0.18730164 -0.93870544 0.80514526q-0.25169373 0.5891113 0.06488037 1.2003021q0.30833435 0.590683 1.3571014 1.0391388zm4.5248566 -8.045364l0.50782776 -0.8704376q0.7124481 0.55955505 0.9061127 1.3391113q0.19366455 0.7795563 -0.19308472 1.6847687q-0.49111938 1.1494751 -1.4836121 1.5237732q-0.9924927 0.37428284 -2.2711334 -0.1724701q-1.3360901 -0.5713501 -1.7658844 -1.553833q-0.4380188 -1.003006 0.022399902 -2.0806427q0.45428467 -1.0632629 1.4550018 -1.417038q0.98635864 -0.35992432 2.2937164 0.1991272q0.07183838 0.030715942 0.22987366 0.09828186l-1.6697998 3.9082336q0.8804016 0.3255005 1.5243073 0.091033936q0.6500397 -0.24884033 0.9324341 -0.90979004q0.20872498 -0.4885254 0.111831665 -0.9378052q-0.11126709 -0.45542908 -0.59999084 -0.90231323zm-2.6828613 2.3024597l1.2523499 -2.9311676q-0.6854248 -0.22512817 -1.1324921 -0.093429565q-0.6870117 0.21603394 -0.97554016 0.8913574q-0.26397705 0.6178436 -0.025375366 1.2126923q0.22424316 0.58869934 0.88105774 0.9205475zm7.183197 -2.5752563l-7.255142 -3.102417l0.3499298 -0.81900024l0.67523193 0.28874207q-0.26512146 -0.45324707 -0.31277466 -0.898468q-0.047668457 -0.44522095 0.17333984 -0.96247864q0.2823944 -0.6609497 0.8481903 -1.030777q0.56581116 -0.36982727 1.3084412 -0.3581543q0.7282715 0.0055389404 1.4897003 0.33113098q0.80451965 0.34403992 1.3282471 0.90786743q0.50935364 0.5576782 0.61473083 1.2654877q0.11151123 0.69343567 -0.14633179 1.2969208q-0.19030762 0.4454193 -0.5305481 0.72476196q-0.3340912 0.26498413 -0.71965027 0.37200928l2.557251 1.0935364l-0.38061523 0.8908386zm-4.253525 -2.770523q1.005661 0.43003845 1.6721497 0.222229q0.6521301 -0.21395874 0.8976898 -0.7886963q0.25169373 -0.5891113 -0.05873108 -1.2146606q-0.31866455 -0.64608765 -1.3817902 -1.1006927q-0.9913025 -0.42388916 -1.6721649 -0.222229q-0.67471313 0.18730164 -0.9202728 0.7620392q-0.24555969 0.57473755 0.095687866 1.247467q0.34739685 0.6583557 1.3674316 1.0945435zm2.8573914 -3.8642426l0.2308197 -0.937912q0.56225586 0.15545654 0.9907837 -0.05215454q0.42030334 -0.2281189 0.67814636 -0.83158875q0.26397705 -0.6178436 0.14251709 -1.0096588q-0.11531067 -0.4061737 -0.46011353 -0.5536194q-0.30169678 -0.1289978 -0.5845947 0.055908203q-0.19474792 0.13764954 -0.6884613 0.77619934q-0.6616821 0.8726196 -0.99983215 1.1868439q-0.3463745 0.29371643 -0.74838257 0.35972595q-0.39587402 0.051635742 -0.78378296 -0.114227295q-0.35916138 -0.15359497 -0.57896423 -0.43450928q-0.23416138 -0.2870636 -0.31251526 -0.66044617q-0.07209778 -0.2687378 -0.019180298 -0.6709595q0.05290222 -0.40220642 0.22479248 -0.8045349q0.26397705 -0.6178436 0.63282776 -1.0039062q0.37498474 -0.4004364 0.7831421 -0.4808197q0.3999176 -0.100875854 0.9395752 0.027923584l-0.2534027 0.91127014q-0.43295288 -0.10017395 -0.77124023 0.09503174q-0.34649658 0.17471313 -0.5675049 0.6919861q-0.26397705 0.6178436 -0.1733551 0.96247864q0.09063721 0.344635 0.36360168 0.46136475q0.1723938 0.07371521 0.3446808 0.028427124q0.19276428 -0.053512573 0.3915558 -0.24040222q0.098358154 -0.11088562 0.56752014 -0.6919708q0.6432648 -0.82951355 0.960907 -1.1355133q0.3176422 -0.306015 0.72579956 -0.38638306q0.39378357 -0.086517334 0.8535156 0.110076904q0.44535828 0.19044495 0.72276306 0.61494446q0.27738953 0.42451477 0.28416443 1.005188q0.0067749023 0.5806885 -0.25720215 1.1985321q-0.4358673 1.0201569 -1.0857849 1.3880005q-0.6581421 0.34733582 -1.5527954 0.13470459z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m81.12184 104.50765l17.41732 -44.976383l28.692917 11.118114l-17.41732 44.97637z" fill-rule="nonzero"></path><path fill="#000000" d="m103.909035 98.94311l-0.6701889 -0.25969696q0.59490204 0.80026245 0.21121216 1.7910614q-0.24263 0.6265335 -0.80107117 1.030159q-0.55844116 0.40361786 -1.2977829 0.45227814q-0.7393341 0.04865265 -1.5552292 -0.2674942q-0.8013153 -0.3105011 -1.340805 -0.8211746q-0.54842377 -0.5308838 -0.6803894 -1.1852722q-0.14653015 -0.6600342 0.10738373 -1.315712q0.186203 -0.48082733 0.5368805 -0.7806244q0.3506775 -0.29979706 0.76148224 -0.40872955l-2.6370697 -1.0218277l0.34983826 -0.90338135l7.34301 2.8453217l-0.3272705 0.8450928zm-3.7519302 1.8137894q1.0198593 0.39518738 1.6934204 0.17022705q0.66464233 -0.2451706 0.8903427 -0.8279953q0.23134613 -0.59739685 -0.09146118 -1.1916733q-0.32279968 -0.5942764 -1.3135223 -0.9781647q-1.0927124 -0.42341614 -1.7662735 -0.19845581q-0.667923 0.21038055 -0.910553 0.8369217q-0.23134613 0.5973892 0.106025696 1.197319q0.32844543 0.5797043 1.3920212 0.9918213zm4.246277 -8.195946l0.47768402 -0.887352q0.73124695 0.5347061 0.951561 1.307106q0.2203064 0.77240753 -0.13516998 1.6903534q-0.4514084 1.1656494 -1.4305115 1.5738373q-0.9791031 0.4081955 -2.2757797 -0.09425354q-1.3549652 -0.52503204 -1.8182373 -1.4921188q-0.4721985 -0.9873123 -0.04901123 -2.080101q0.41754913 -1.0782242 1.4055786 -1.4662018q0.97345734 -0.39362335 2.2992783 0.12011719q0.07285309 0.02822876 0.23311615 0.09033203l-1.5347672 3.9631958q0.8910904 0.29502106 1.5265884 0.03855896q0.6411438 -0.27103424 0.90070343 -0.9412842q0.19184113 -0.49539948 0.079582214 -0.94107056q-0.12683105 -0.4513092 -0.63061523 -0.8811188zm-2.6023788 2.3932877l1.1510773 -2.9724045q-0.6927643 -0.20140839 -1.1350708 -0.05441284q-0.67920685 0.23952484 -0.9444046 0.9243469q-0.24263 0.6265335 0.01625061 1.2127991q0.24430847 0.5806198 0.9121475 0.8896713zm7.0908585 -2.820671l-7.3575745 -2.8509598l0.32162476 -0.83052826l0.68476105 0.26533508q-0.2805252 -0.44384003 -0.34342957 -0.88713837q-0.06291199 -0.44330597 0.14022064 -0.9678421q0.259552 -0.67024994 0.81235504 -1.0593033q0.5527954 -0.38904572 1.2954178 -0.40291595q0.72805023 -0.019515991 1.5002365 0.2796936q0.81588745 0.31614685 1.3586655 0.8616028q0.5282059 0.5398102 0.657814 1.2435608q0.13524628 0.68917084 -0.101737976 1.3011398q-0.17491913 0.45168304 -0.50538635 0.74256134q-0.32482147 0.27629852 -0.70648956 0.39652252l2.593361 1.0048904l-0.34983826 0.90338135zm-4.346245 -2.6225052q1.019867 0.39517975 1.6788559 0.1645813q0.64443207 -0.2362442 0.87013245 -0.8190689q0.2313385 -0.59739685 -0.10038757 -1.2118912q-0.34065247 -0.6347122 -1.4187927 -1.052475q-1.0052948 -0.389534 -1.6788559 -0.1645813q-0.667923 0.21038818 -0.893631 0.7932129q-0.22570038 0.5828247 0.13845062 1.243393q0.36979675 0.6460037 1.4042282 1.0468292zm2.7232208 -3.9600906l0.19850159 -0.9452667q0.56728363 0.1360321 0.9884491 -0.08618164q0.41223907 -0.24243164 0.64923096 -0.854393q0.24262238 -0.62654114 0.107795715 -1.0139236q-0.12918854 -0.40195465 -0.47885895 -0.53744507q-0.30595398 -0.11856079 -0.5823517 0.07596588q-0.18991089 0.14425659 -0.661438 0.7993927q-0.6313782 0.8948288 -0.9585571 1.2204895q-0.33611298 0.3054428 -0.73563385 0.38523102q-0.39388275 0.065223694 -0.78725433 -0.08720398q-0.36424255 -0.14113617 -0.59355927 -0.41432953q-0.24388885 -0.27882385 -0.33501434 -0.64927673q-0.08126831 -0.2660904 -0.04219055 -0.66986847q0.03907776 -0.4037857 0.19706726 -0.81175995q0.24263 -0.62654114 0.59802246 -1.0250549q0.3610382 -0.4130783 0.76620483 -0.50743866q0.39624023 -0.11457825 0.9400253 -0.00440979l-0.2219925 0.9194031q-0.43615723 -0.08522034 -0.76755524 0.12150574q-0.34031677 0.18651581 -0.5434494 0.7110596q-0.24263 0.6265335 -0.14022064 0.9678421q0.10240173 0.3413086 0.37922668 0.44857025q0.1748352 0.06774902 0.34545135 0.016563416q0.19084167 -0.060112 0.38310242 -0.25372314q0.09449768 -0.11419678 0.54345703 -0.7110596q0.6144409 -0.85111237 0.9214096 -1.1678467q0.30697632 -0.3167343 0.71214294 -0.41109467q0.39059448 -0.1000061 0.85681915 0.08065033q0.45165253 0.17501068 0.7434616 0.5897064q0.29180908 0.41469574 0.31850433 0.9947815q0.026695251 0.58008575 -0.21593475 1.2066193q-0.4006195 1.0345078 -1.0375519 1.4244766q-0.64585876 0.36975098 -1.5473099 0.1880188z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m171.07939 43.463318l21.732285 43.08661l-26.803146 13.511818l-21.732285 -43.086617z" fill-rule="nonzero"></path><path fill="#000000" d="m159.94344 64.10798l0.6417999 -0.32354355q-0.9926758 -0.094516754 -1.4711609 -1.0431747q-0.30256653 -0.59988785 -0.22807312 -1.284874q0.07450867 -0.6849899 0.5337219 -1.2664528q0.45922852 -0.58145905 1.2405548 -0.9753418q0.76737976 -0.38684464 1.5079498 -0.4452057q0.7615509 -0.051445007 1.3357697 0.2890129q0.58818054 0.3334236 0.90483093 0.96121216q0.23220825 0.46038055 0.21983337 0.92157364q-0.012390137 0.46119308 -0.20675659 0.83914566l2.5253906 -1.2730789l0.43626404 0.8649521l-7.032013 3.5449257l-0.40811157 -0.8091507zm1.1671906 -4.0005302q-0.9766693 0.49235153 -1.2609406 1.1431007q-0.26327515 0.65766907 0.018188477 1.215702q0.28849792 0.57198715 0.94595337 0.7305031q0.65745544 0.15851593 1.6062164 -0.319767q1.0464325 -0.5275192 1.3307037 -1.1782722q0.29130554 -0.63679886 -0.011276245 -1.2366867q-0.28849792 -0.57198334 -0.9598999 -0.72346497q-0.65042114 -0.14456558 -1.6689453 0.36888504zm3.239624 8.643436l0.33872986 0.94911957q-0.8868866 0.18462372 -1.6079102 -0.16932678q-0.72102356 -0.35394287 -1.1643372 -1.2328491q-0.56292725 -1.116066 -0.2099762 -2.1164017q0.3529358 -1.0003357 1.594696 -1.6263275q1.2975769 -0.6541214 2.3259277 -0.35011292q1.0493164 0.31093597 1.5770721 1.3572464q0.5207062 1.0323639 0.14677429 2.0257797q-0.35998535 0.98638916 -1.6296539 1.626442q-0.06976318 0.03517151 -0.22323608 0.1125412l-1.9139557 -3.7946396q-0.81604004 0.46387482 -1.0514221 1.1074753q-0.22833252 0.657547 0.09535217 1.2992859q0.23924255 0.47433472 0.64530945 0.6895828q0.4200287 0.2082138 1.0766296 0.12218475zm-0.033187866 -3.5353851l1.4354706 2.8459778q0.6136627 -0.37934875 0.8008728 -0.8061905q0.27722168 -0.66469574 -0.053497314 -1.3203888q-0.30256653 -0.59989166 -0.9112549 -0.80049133q-0.59472656 -0.20763397 -1.2715912 0.081092834zm-2.656723 7.153839l7.0459595 -3.5519638l0.40109253 0.79520416l-0.6557617 0.33057404q0.5174408 0.08911133 0.88868713 0.3394165q0.37124634 0.25029755 0.62457275 0.75253296q0.3236847 0.6417389 0.24214172 1.3127747q-0.08154297 0.67103577 -0.5687866 1.2316284q-0.47329712 0.55355835 -1.2127686 0.9263382q-0.78134155 0.39388275 -1.5499268 0.4313736q-0.7546387 0.030464172 -1.3639221 -0.3448105q-0.60224915 -0.36132812 -0.8977814 -0.9472656q-0.21813965 -0.43247986 -0.212677 -0.8726883q0.012496948 -0.42625427 0.17897034 -0.79013824l-2.4835358 1.251976l-0.43626404 -0.8649521zm4.8588104 -1.4694977q-0.9766693 0.49234772 -1.2469788 1.1360626q-0.25636292 0.63668823 0.025100708 1.1947174q0.28849792 0.57199097 0.9669342 0.7374191q0.6994324 0.17235565 1.7319183 -0.34812927q0.9627075 -0.48532104 1.2469788 -1.1360703q0.2913208 -0.6368027 0.009841919 -1.1948318q-0.28146362 -0.5580368 -1.0158386 -0.7302704q-0.72732544 -0.15828705 -1.7179565 0.3411026zm1.1154175 4.67482l0.5687561 0.78066254q-0.48104858 0.33000183 -0.5982666 0.79154205q-0.096206665 0.46846008 0.19932556 1.0543976q0.3025818 0.59988403 0.6804962 0.75933075q0.384964 0.17339325 0.7198181 0.0045928955q0.29299927 -0.14770508 0.33377075 -0.48322296q0.020141602 -0.23763275 -0.15029907 -1.0266113q-0.24130249 -1.0682297 -0.26387024 -1.5293045q-0.0015716553 -0.4541626 0.20687866 -0.8042145q0.21546936 -0.33609772 0.5921936 -0.5260086q0.34880066 -0.17583466 0.70526123 -0.16304779q0.37039185 0.0057525635 0.7064667 0.18630219q0.25198364 0.11794281 0.52557373 0.41748047q0.27357483 0.29953766 0.4705963 0.690155q0.3025818 0.59989166 0.36032104 1.130722q0.06477356 0.5447769 -0.1366272 0.90878296q-0.18040466 0.37091827 -0.6265259 0.70079803l-0.5338135 -0.7807846q0.355484 -0.26669312 0.42404175 -0.6512146q0.089538574 -0.37760162 -0.16378784 -0.87983704q-0.30256653 -0.59988403 -0.6245575 -0.7525253q-0.32199097 -0.15264893 -0.58709717 -0.019012451q-0.16741943 0.08440399 -0.2437439 0.24536133q-0.083221436 0.1819458 -0.06829834 0.45439148q0.021469116 0.14665985 0.16377258 0.87983704q0.22018433 1.0263748 0.2496643 1.4664688q0.02947998 0.440094 -0.17193604 0.8040924q-0.18743896 0.35697174 -0.6339264 0.5820465q-0.43252563 0.21804047 -0.9358978 0.15682983q-0.5033722 -0.061210632 -0.9519043 -0.43003845q-0.4485321 -0.3688202 -0.75109863 -0.96871185q-0.49960327 -0.99050903 -0.36238098 -1.724617q0.15821838 -0.7271881 0.8970947 -1.274643z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m61.231503 170.96638l41.700787 76.44095l-26.330704 14.362198l-41.70079 -76.44093z" fill-rule="nonzero"></path><path fill="#000000" d="m48.99513 188.71129l5.006748 -2.730957l0.41156006 0.75442505l-0.7544441 0.41151428q0.6995926 0.009963989 0.9988899 0.16706848q0.29929733 0.15711975 0.45643616 0.44517517q0.23945236 0.43893433 0.20455933 1.0275116l-0.93901443 0.13842773q0.006214142 -0.41275024 -0.16588974 -0.72824097q-0.1496582 -0.27433777 -0.43398666 -0.40402222q-0.28433228 -0.12966919 -0.63848877 -0.061080933q-0.5274925 0.10974121 -1.0624619 0.40153503l-2.6199684 1.4290771l-0.46393967 -0.85043335zm3.495327 6.4072113l0.7407265 -0.40402222q-1.172226 -0.12593079 -1.7184715 -1.1272583q-0.23945236 -0.43893433 -0.29185104 -0.9264984q-0.031196594 -0.4813385 0.11095047 -0.80804443q0.16334915 -0.32048035 0.49629593 -0.5910797q0.21697617 -0.18954468 0.76566315 -0.4888153l3.1000671 -1.6909485l0.46393967 0.85043335l-2.7708588 1.511383q-0.6721382 0.36660767 -0.87540054 0.54867554q-0.2843132 0.26187134 -0.34165955 0.6135254q-0.049865723 0.36535645 0.15965271 0.74942017q0.20952225 0.38407898 0.58115005 0.6085205q0.39282608 0.23069763 0.7968674 0.18829346q0.41775513 -0.04989624 1.0487442 -0.39405823l2.6885529 -1.4664917l0.46393967 0.85043335l-5.006748 2.730957l-0.41156006 -0.75442505zm1.0423317 1.9106903l5.006748 -2.730957l0.41904068 0.76812744l-0.71329117 0.3890686q1.1223412 0.099746704 1.69104 1.1422119q0.24693298 0.45265198 0.29184723 0.9264984q0.058631897 0.46636963 -0.11843109 0.79434204q-0.15586472 0.33418274 -0.46761322 0.61102295q-0.2244606 0.17582703 -0.8142967 0.4975586l-3.0726357 1.6759796l-0.46393585 -0.85043335l3.0452003 -1.661026q0.5212517 -0.28431702 0.71577835 -0.51501465q0.20824432 -0.23817444 0.2169609 -0.5810852q0.029911041 -0.33668518 -0.1571579 -0.6796112q-0.29183197 -0.5349426 -0.8517647 -0.74568176q-0.5599289 -0.21072388 -1.533844 0.3204956l-2.7297058 1.4889374l-0.46393967 -0.85043335zm4.6103287 6.6566315l-0.6808624 0.5137634q-0.27685547 -0.31173706 -0.42651367 -0.5860748q-0.25441742 -0.46636963 -0.24570465 -0.8092804q0.016197205 -0.32920837 0.1895256 -0.5661316q0.18081284 -0.22322083 0.9489708 -0.6422119l2.8805962 -1.571228l-0.34421158 -0.6309662l0.65842056 -0.35914612l0.34421158 0.6309662l1.234539 -0.6733856l0.9777069 0.5523987l-1.7557907 0.95770264l0.4714203 0.864151l-0.6584244 0.35914612l-0.4714203 -0.864151l-2.935463 1.6011505q-0.35664368 0.1945343 -0.44393158 0.2955475q-0.06608963 0.10723877 -0.082294464 0.24066162q0.0049934387 0.1396637 0.10227203 0.3179779q0.08230972 0.15089417 0.23695374 0.3691101zm5.5927467 -2.0809174l0.9739151 -0.5312195l0.46393585 0.85043335l-0.9739151 0.5312195l-0.46393585 -0.85043335zm-5.9395103 3.2397308l5.006748 -2.7309418l0.46393585 0.85043335l-5.006748 2.7309418l-0.46393585 -0.85043335zm1.1263084 2.064621l5.006748 -2.730957l0.41904068 0.7681427l-0.6995735 0.38157654q0.49757004 0.031173706 0.92656326 0.29553223q0.43647766 0.2780609 0.7058563 0.77186584q0.30680084 0.5623779 0.2681656 1.0462189q-0.024925232 0.47633362 -0.36784363 0.8591614q1.1996613 0.11097717 1.7159805 1.0574188q0.41155243 0.75442505 0.21704102 1.3766632q-0.19451141 0.6222534 -1.0449677 1.0861359l-3.442997 1.878006l-0.45645523 -0.8367157l3.1549377 -1.7208862q0.5075302 -0.27682495 0.682106 -0.47885132q0.18829346 -0.20948792 0.20574188 -0.5037689q0.017448425 -0.29429626 -0.13969421 -0.5823517q-0.29183197 -0.5349426 -0.84303284 -0.697052q-0.54371643 -0.14837646 -1.3118744 0.27061462l-2.9080276 1.5861969l-0.46393585 -0.85043335l3.2509575 -1.7732391q0.562397 -0.3067627 0.7382164 -0.6696472q0.1758194 -0.36286926 -0.07859802 -0.8292389q-0.19455719 -0.35662842 -0.55870056 -0.56736755q-0.35666275 -0.19702148 -0.8018532 -0.13217163q-0.43147278 0.057373047 -1.1173286 0.43147278l-2.592537 1.4141083l-0.46393585 -0.85043335zm7.740425 10.338898l0.36917114 0.9377136q-0.8804016 0.21325684 -1.6124344 -0.1171875q-0.73202515 -0.33044434 -1.2034454 -1.1945953q-0.598629 -1.0973358 -0.27818298 -2.1086426q0.3204422 -1.0113068 1.5412674 -1.6772003q1.2756958 -0.6958313 2.31324 -0.4252472q1.058754 0.2768097 1.6199646 1.3055573q0.5537338 1.0150299 0.21208954 2.020111q-0.32792664 0.9975891 -1.5761871 1.6784515q-0.06858063 0.03741455 -0.21947479 0.11972046l-2.0353317 -3.7309418q-0.8005829 0.49006653 -1.0150452 1.1409912q-0.20697784 0.6646576 0.13723755 1.2956238q0.2544098 0.46635437 0.66719055 0.6683655q0.4264984 0.19451904 1.0799408 0.08728027zm-0.14730835 -3.5326996l1.5265045 2.7982025q0.60105896 -0.3990326 0.7743759 -0.83174133q0.25561523 -0.67337036 -0.096076965 -1.3180542q-0.32176208 -0.5898285 -0.9365616 -0.7706299q-0.60108185 -0.1882782 -1.2682419 0.1222229zm-2.850727 6.454727l0.61727524 -0.33668518l3.0679703 5.6238403l-0.6172714 0.33668518l-3.067974 -5.6238403zm6.958576 8.187897l0.6309891 -0.34417725q-0.9951477 -0.062332153 -1.5039749 -0.9950714q-0.3217697 -0.58981323 -0.26942444 -1.2769012q0.052345276 -0.687088 0.49253082 -1.2831421q0.44017792 -0.59606934 1.2083359 -1.0150604q0.7544403 -0.41151428 1.4926834 -0.4938202q0.7594452 -0.07608032 1.3443222 0.24563599q0.59859467 0.31422424 0.9353256 0.9314728q0.24693298 0.45265198 0.24944305 0.914032q0.0025177002 0.46139526 -0.17953491 0.845459l2.4827957 -1.354248l0.46394348 0.85043335l-6.9134293 3.7709656l-0.43400574 -0.795578zm1.0373535 -4.036484q-0.96019745 0.5237427 -1.2232895 1.1833954q-0.24189758 0.66589355 0.057418823 1.2145538q0.3067932 0.5623932 0.9689789 0.69955444q0.66218567 0.13716125 1.5949478 -0.3716278q1.0287857 -0.5611572 1.2918854 -1.2208099q0.27057648 -0.64593506 -0.051185608 -1.2357483q-0.30680084 -0.5623932 -0.98270416 -0.6920624q-0.65470123 -0.1234436 -1.6560516 0.42274475zm3.5167618 8.534607l0.3691635 0.9377136q-0.8804016 0.21325684 -1.6124268 -0.1171875q-0.7320328 -0.33044434 -1.2034531 -1.1945953q-0.5986252 -1.0973358 -0.27818298 -2.1086426q0.32044983 -1.0113068 1.5412674 -1.6772003q1.2756958 -0.6958313 2.3132477 -0.4252472q1.0587463 0.2768097 1.6199646 1.3055573q0.5537262 1.0150452 0.21208191 2.020111q-0.32792664 0.9975891 -1.5761871 1.6784515q-0.06858063 0.03741455 -0.21946716 0.11972046l-2.0353394 -3.7309418q-0.8005829 0.49006653 -1.0150452 1.1410065q-0.20697784 0.66464233 0.13723755 1.2956085q0.25441742 0.46636963 0.6671982 0.6683655q0.42649078 0.19451904 1.0799408 0.08728027zm-0.14730835 -3.5326996l1.5264969 2.7982025q0.60105896 -0.3990326 0.7743759 -0.83174133q0.25561523 -0.67337036 -0.096076965 -1.3180542q-0.32176208 -0.5898285 -0.9365616 -0.7706299q-0.60108185 -0.1882782 -1.2682343 0.1222229zm-2.4242096 7.2365875l6.927147 -3.7784576l0.4265213 0.78186035l-0.6447067 0.35165405q0.52001953 0.07232666 0.8991318 0.31048584q0.37911224 0.23817444 0.64849854 0.7319641q0.34420776 0.63098145 0.28437805 1.3043518q-0.059822083 0.67337036 -0.5286865 1.2494812q-0.4551468 0.5686188 -1.1821518 0.9651642q-0.76815796 0.41900635 -1.5350876 0.48136902q-0.753212 0.054870605 -1.3742523 -0.3005066q-0.6135559 -0.3416748 -0.9278412 -0.9177704q-0.23196411 -0.42521667 -0.24071503 -0.8654022q-0.0012664795 -0.4264679 0.15335083 -0.795578l-2.4416504 1.3318176l-0.46393585 -0.85043335zm4.8085175 -1.6261292q-0.96019745 0.5237427 -1.2095795 1.1759186q-0.23565674 0.64468384 0.06365967 1.1933594q0.3067932 0.5623779 0.99018097 0.70578q0.7045822 0.14962769 1.7196503 -0.40405273q0.9464798 -0.51626587 1.2095795 -1.1759186q0.27057648 -0.64593506 -0.02873993 -1.1946106q-0.2993164 -0.5486603 -1.0388184 -0.69703674q-0.7320175 -0.13467407 -1.7059326 0.39656067zm1.2656784 4.636566l0.5936203 0.76190186q-0.47011566 0.3454132 -0.5723572 0.8105469q-0.0810318 0.47135925 0.23324585 1.0474548q0.32176208 0.58981323 0.70461273 0.73695374q0.39032745 0.16085815 0.71954346 -0.018707275q0.28805542 -0.15711975 0.31797028 -0.49380493q0.012458801 -0.23817444 -0.18335724 -1.021286q-0.27565002 -1.0599213 -0.31307983 -1.5200653q-0.016227722 -0.45388794 0.18078613 -0.8105316q0.20449829 -0.34292603 0.5748596 -0.54493713q0.34293365 -0.1870575 0.69958496 -0.18580627q0.37036896 -0.0062408447 0.71206665 0.16334534q0.25564575 0.10972595 0.53874207 0.40026855q0.28308868 0.2905426 0.49260712 0.6746063q0.32176208 0.58981323 0.39661407 1.1185455q0.0823288 0.5424347 -0.10720825 0.91278076q-0.16833496 0.3765869 -0.6035385 0.72076416l-0.5587082 -0.7631378q0.34666443 -0.27809143 0.402771 -0.6646576q0.077293396 -0.38032532 -0.19208527 -0.87413025q-0.32176208 -0.58981323 -0.64849854 -0.7319641q-0.32672882 -0.14215088 -0.58735657 1.5258789E-5q-0.16460419 0.089782715 -0.23567963 0.25312805q-0.077308655 0.18455505 -0.053596497 0.45640564q0.026191711 0.14588928 0.19207764 0.87413025q0.25319672 1.0187836 0.29685974 1.4577179q0.043670654 0.43893433 -0.1458664 0.8092804q-0.17581177 0.36288452 -0.61476135 0.6023102q-0.42523193 0.2319336 -0.9302826 0.1870575q-0.5050583 -0.044891357 -0.96523285 -0.39901733q-0.46017456 -0.35414124 -0.78193665 -0.94395447q-0.5312805 -0.9738922 -0.41783142 -1.7120972q0.13464355 -0.73197937 0.85541534 -1.3031158z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m53.480316 46.299507l0 50.92914l-29.984253 0l0 -50.92914z" fill-rule="nonzero"></path><path fill="#000000" d="m34.240314 59.721382l0.71875 0q-0.84375 -0.53125 -0.84375 -1.59375q0 -0.671875 0.375 -1.25q0.375 -0.578125 1.046875 -0.890625q0.671875 -0.3125 1.546875 -0.3125q0.859375 0 1.546875 0.28125q0.703125 0.296875 1.0625 0.859375q0.375 0.5625 0.375 1.265625q0 0.515625 -0.21875 0.921875q-0.21875 0.40625 -0.5625 0.65625l2.828125 0l0 0.96875l-7.875 0l0 -0.90625zm2.84375 -3.046875q-1.09375 0 -1.640625 0.453125q-0.53125 0.46875 -0.53125 1.09375q0 0.640625 0.515625 1.078125q0.515625 0.4375 1.578125 0.4375q1.171875 0 1.71875 -0.453125q0.546875 -0.4375 0.546875 -1.109375q0 -0.640625 -0.53125 -1.078125q-0.515625 -0.421875 -1.65625 -0.421875zm-1.0 9.176498l-0.125 1.0q-0.875 -0.234375 -1.359375 -0.875q-0.484375 -0.640625 -0.484375 -1.625q0 -1.25 0.765625 -1.984375q0.765625 -0.734375 2.15625 -0.734375q1.453125 0 2.234375 0.734375q0.796875 0.75 0.796875 1.921875q0 1.15625 -0.78125 1.875q-0.765625 0.71875 -2.1875 0.71875q-0.078125 0 -0.25 0l0 -4.25q-0.9375 0.046875 -1.4375 0.515625q-0.5 0.484375 -0.5 1.203125q0 0.53125 0.265625 0.90625q0.28125 0.375 0.90625 0.59375zm1.5625 -3.171875l0 3.1875q0.71875 -0.0625 1.078125 -0.359375q0.546875 -0.46875 0.546875 -1.203125q0 -0.671875 -0.453125 -1.125q-0.4375 -0.453125 -1.171875 -0.5zm-5.59375 5.1921234l7.890625 0l0 0.890625l-0.734375 0q0.421875 0.3125 0.640625 0.703125q0.21875 0.390625 0.21875 0.953125q0 0.71875 -0.375 1.28125q-0.375 0.5625 -1.0625 0.84375q-0.671875 0.28125 -1.5 0.28125q-0.875 0 -1.578125 -0.3125q-0.6875 -0.3125 -1.0625 -0.921875q-0.375 -0.59375 -0.375 -1.25q0 -0.484375 0.203125 -0.875q0.203125 -0.375 0.515625 -0.625l-2.78125 0l0 -0.96875zm5.0 0.875q-1.09375 0 -1.625 0.453125q-0.515625 0.453125 -0.515625 1.078125q0 0.640625 0.53125 1.09375q0.546875 0.46875 1.703125 0.46875q1.078125 0 1.625 -0.453125q0.546875 -0.4375 0.546875 -1.0625q0 -0.625 -0.578125 -1.109375q-0.578125 -0.46875 -1.6875 -0.46875zm-1.109375 4.6764984l0.15625 0.953125q-0.578125 0.078125 -0.890625 0.4375q-0.296875 0.375 -0.296875 1.03125q0 0.671875 0.265625 0.984375q0.265625 0.328125 0.640625 0.328125q0.328125 0 0.515625 -0.28125q0.125 -0.203125 0.328125 -0.984375q0.265625 -1.0625 0.453125 -1.484375q0.203125 -0.40625 0.546875 -0.625q0.34375 -0.203125 0.765625 -0.203125q0.390625 0 0.703125 0.171875q0.328125 0.171875 0.546875 0.484375q0.171875 0.21875 0.28125 0.609375q0.109375 0.390625 0.109375 0.828125q0 0.671875 -0.1875 1.171875q-0.1875 0.515625 -0.53125 0.75q-0.328125 0.25 -0.875 0.34375l-0.125 -0.9375q0.4375 -0.078125 0.671875 -0.390625q0.25 -0.296875 0.25 -0.859375q0 -0.671875 -0.21875 -0.953125q-0.21875 -0.28125 -0.515625 -0.28125q-0.1875 0 -0.328125 0.109375q-0.15625 0.125 -0.265625 0.375q-0.046875 0.140625 -0.25 0.859375q-0.265625 1.015625 -0.4375 1.421875q-0.171875 0.40625 -0.515625 0.640625q-0.328125 0.234375 -0.828125 0.234375q-0.484375 0 -0.90625 -0.28125q-0.421875 -0.28125 -0.65625 -0.8125q-0.234375 -0.53125 -0.234375 -1.203125q0 -1.109375 0.453125 -1.703125q0.46875 -0.578125 1.375 -0.734375z" fill-rule="nonzero"></path></g></svg> - diff --git a/site/versions/master/docs/skylark/build-graph-aspects.png b/site/versions/master/docs/skylark/build-graph-aspects.png Binary files differdeleted file mode 100644 index fb8042a5b7..0000000000 --- a/site/versions/master/docs/skylark/build-graph-aspects.png +++ /dev/null diff --git a/site/versions/master/docs/skylark/build-graph.png b/site/versions/master/docs/skylark/build-graph.png Binary files differdeleted file mode 100644 index 2efd68ac59..0000000000 --- a/site/versions/master/docs/skylark/build-graph.png +++ /dev/null diff --git a/site/versions/master/docs/skylark/build-graph.svg b/site/versions/master/docs/skylark/build-graph.svg deleted file mode 100644 index cbad06dcb2..0000000000 --- a/site/versions/master/docs/skylark/build-graph.svg +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" standalone="yes"?> - -<svg version="1.1" viewBox="0.0 0.0 960.0 720.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m105.04724 275.39633l0 0c0 -8.288635 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192383 23.496063 15.007874l0 0c0 8.288605 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.719269 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m105.04724 275.39633l0 0c0 -8.288635 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192383 23.496063 15.007874l0 0c0 8.288605 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.719269 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m122.39964 282.3163l5.265625 -7.09375l-4.640625 -6.5l2.140625 0l2.46875 3.484375q0.78125 1.078125 1.09375 1.671875q0.453125 -0.75 1.078125 -1.546875l2.734375 -3.609375l1.96875 0l-4.78125 6.40625l5.140625 7.1875l-2.21875 0l-3.421875 -4.859375q-0.296875 -0.40625 -0.59375 -0.90625q-0.453125 0.75 -0.65625 1.03125l-3.40625 4.734375l-2.171875 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m79.0 141.00787l0 0c0 -8.28862 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m79.0 141.00787l0 0c0 -8.28862 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m101.57115 147.92787l0 -5.765625l-5.234375 -7.828125l2.1875 0l2.671875 4.09375q0.75 1.15625 1.390625 2.296875q0.609375 -1.0625 1.484375 -2.40625l2.625 -3.984375l2.109375 0l-5.4375 7.828125l0 5.765625l-1.796875 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m163.51181 141.00787l0 0c0 -8.28862 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m163.51181 141.00787l0 0c0 -8.28862 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m181.68489 147.92787l0 -1.671875l6.96875 -8.703125q0.75 -0.9375 1.421875 -1.625l-7.59375 0l0 -1.59375l9.734375 0l0 1.59375l-7.625 9.4375l-0.828125 0.953125l8.6875 0l0 1.609375l-10.765625 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m0 141.00787l0 0c0 -8.28862 10.519546 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976518 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m0 141.00787l0 0c0 -8.28862 10.519546 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192535 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976518 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m22.719948 147.92787l0 -12.0l-4.46875 0l0 -1.59375l10.765625 0l0 1.59375l-4.5 0l0 12.0l-1.796875 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m110.0 19.007874l0 0c0 -8.288619 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192545 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m110.0 19.007874l0 0c0 -8.288619 10.5195465 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192545 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976517 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m128.53548 25.927872l-3.6093674 -13.59375l1.84375 0l2.0624924 8.90625q0.34375 1.40625 0.578125 2.78125q0.515625 -2.171875 0.609375 -2.515625l2.59375 -9.171875l2.171875 0l1.953125 6.875q0.734375 2.5625 1.046875 4.8125q0.265625 -1.28125 0.6875 -2.953125l2.125 -8.734375l1.8125 0l-3.734375 13.59375l-1.734375 0l-2.859375 -10.359375q-0.359375 -1.296875 -0.421875 -1.59375q-0.21875 0.9375 -0.40625 1.59375l-2.890625 10.359375l-1.828125 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m128.5433 260.38846l-26.047241 -104.37796" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m128.5433 260.38846l-24.594505 -98.55649" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m105.551384 161.43205l-2.7013626 -4.0031433l-0.5038147 4.8029785z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m128.5433 260.38846l58.456696 -104.37796" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m128.5433 260.38846l55.52487 -99.143036" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m185.50931 162.05252l0.7763519 -4.7665253l-3.6585846 3.1523438z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m102.49606 126.0l30.992126 -92.0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m102.49606 126.0l29.076675 -86.313965" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m133.13803 40.21334l-0.11654663 -4.8279343l-3.0140533 3.7733269z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m187.00787 126.0l-53.51181 -92.0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m187.00787 126.0l-50.495102 -86.81353" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m137.94055 38.356003l-3.7094727 -3.0923195l0.85391235 4.75325z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m105.04724 275.39633l-81.543304 -119.37009" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m105.04724 275.39633l-78.158905 -114.41571" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m28.25222 160.04893l-3.9236736 -2.8155518l1.1959076 4.6789246z" fill-rule="evenodd"></path><path fill="#cfe2f3" d="m0 19.007874l0 0c0 -8.288619 10.519546 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192545 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976518 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m0 19.007874l0 0c0 -8.288619 10.519546 -15.007874 23.496063 -15.007874l0 0c12.976517 0 23.496063 6.7192545 23.496063 15.007874l0 0c0 8.28862 -10.5195465 15.007874 -23.496063 15.007874l0 0c-12.976518 0 -23.496063 -6.7192535 -23.496063 -15.007874z" fill-rule="nonzero"></path><path fill="#000000" d="m28.005974 24.474747q1.265625 0.859375 2.3125 1.265625l-0.53125 1.25q-1.453125 -0.53125 -2.921875 -1.671875q-1.5 0.84375 -3.328125 0.84375q-1.84375 0 -3.359375 -0.890625q-1.5 -0.890625 -2.3125 -2.5q-0.8125 -1.625 -0.8125 -3.640625q0 -2.015625 0.8125 -3.65625q0.828125 -1.65625 2.328125 -2.515625q1.515625 -0.875 3.375 -0.875q1.890625 0 3.390625 0.90625q1.515625 0.890625 2.3125 2.5q0.796875 1.609375 0.796875 3.625q0 1.6875 -0.515625 3.03125q-0.515625 1.328125 -1.546875 2.328125zm-3.953125 -2.296875q1.5625 0.421875 2.5625 1.296875q1.59375 -1.453125 1.59375 -4.359375q0 -1.65625 -0.5625 -2.875q-0.5625 -1.234375 -1.640625 -1.921875q-1.078125 -0.6875 -2.421875 -0.6875q-2.015625 0 -3.34375 1.390625q-1.328125 1.375 -1.328125 4.109375q0 2.65625 1.3125 4.078125q1.3125 1.40625 3.359375 1.40625q0.953125 0 1.8125 -0.359375q-0.84375 -0.546875 -1.78125 -0.78125l0.4375 -1.296875z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m23.496063 126.0l0 -92.0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m23.496063 126.0l0 -86.0" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m25.147795 40.0l-1.6517315 -4.5380974l-1.6517334 4.5380974z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m137.17401 181.13062l11.842514 46.771652l-29.102364 7.3700867l-11.842514 -46.771652z" fill-rule="nonzero"></path><path fill="#000000" d="m121.81724 198.86525l0.69675446 -0.17643738q-0.9483261 -0.30786133 -1.2091141 -1.3378601q-0.16491699 -0.6513214 0.05670166 -1.303833q0.22162628 -0.65249634 0.79623413 -1.1203766q0.57460785 -0.46788025 1.4228363 -0.6826935q0.83306885 -0.21096802 1.5685654 -0.10710144q0.75447845 0.11517334 1.240921 0.5722351q0.50159454 0.4532318 0.6741791 1.1348572q0.1265564 0.4998474 0.014221191 0.94737244q-0.112342834 0.44752502 -0.38420868 0.7742615l2.7415695 -0.69429016l0.23779297 0.93911743l-7.6340103 1.9332886l-0.22244263 -0.87854004zm2.0088654 -3.6517944q-1.0602798 0.2685089 -1.4792023 0.842041q-0.39993286 0.5848236 -0.24652863 1.1907043q0.15724182 0.6210327 0.76447296 0.91856384q0.60723877 0.29753113 1.6372223 0.03668213q1.1360092 -0.2876892 1.5549316 -0.86120605q0.42275238 -0.5583801 0.2578354 -1.2097015q-0.15724182 -0.62101746 -0.7796173 -0.9147186q-0.6034012 -0.28237915 -1.7091141 -0.0023651123zm1.2829971 9.141281l0.12427521 1.0000916q-0.90574646 -0.012390137 -1.5325394 -0.5145111q-0.62680054 -0.502121 -0.86841583 -1.4563751q-0.3068161 -1.2117615 0.25512695 -2.1116333q0.5619354 -0.8998718 1.9100037 -1.2412567q1.4086609 -0.35673523 2.3462524 0.16337585q0.9565811 0.53141785 1.2442245 1.66745q0.28379822 1.1208801 -0.29711914 2.00943q-0.56578064 0.88471985 -1.9441376 1.2337952q-0.075737 0.019180298 -0.24235535 0.06137085l-1.0431747 -4.11998q-0.8973007 0.275589 -1.2669449 0.8527527q-0.36580658 0.5923004 -0.18938446 1.2890625q0.13039398 0.5149994 0.4799347 0.813324q0.36468506 0.29447937 1.0242538 0.35310364zm0.7361374 -3.458435l0.78237915 3.089981q0.6814194 -0.23703003 0.95692444 -0.61305237q0.41508484 -0.5886688 0.23482513 -1.3005676q-0.16490936 -0.6513214 -0.71539307 -0.97935486q-0.5353317 -0.33184814 -1.2587357 -0.19700623zm-4.1481476 6.40654l7.649147 -1.9371338l0.21861267 0.86338806l-0.7118988 0.1802826q0.485672 0.19937134 0.7936096 0.52433777q0.30792236 0.3249817 0.44599915 0.8702698q0.17642212 0.6967621 -0.049041748 1.3341217q-0.22544861 0.63734436 -0.822876 1.0787811q-0.58229065 0.4375763 -1.3850708 0.6408844q-0.8482208 0.21481323 -1.6065292 0.084487915q-0.74316406 -0.13417053 -1.2562637 -0.632843q-0.5092621 -0.4835205 -0.6703415 -1.11969q-0.118888855 -0.46955872 -0.017860413 -0.8981018q0.10486603 -0.4133911 0.34643555 -0.73246765l-2.6961365 0.68278503l-0.23778534 -0.9391022zm5.06176 -0.3792572q-1.0602798 0.2685089 -1.4640503 0.8381958q-0.3886261 0.5658417 -0.23521423 1.1717224q0.15724182 0.6210327 0.7834549 0.9298706q0.645195 0.3201599 1.7660599 0.03630066q1.0451355 -0.26467896 1.4640503 -0.8381958q0.42276 -0.55836487 0.26934814 -1.1642456q-0.15341187 -0.60588074 -0.83273315 -0.93351746q-0.67549133 -0.31248474 -1.7509155 -0.040130615zm0.07243347 4.805786l0.38542175 0.88560486q-0.54125977 0.21766663 -0.7559891 0.64276123q-0.19573975 0.43641663 -0.03466797 1.072586q0.16491699 0.6513214 0.499115 0.88905334q0.33803558 0.2528839 0.701561 0.16081238q0.31808472 -0.08055115 0.43081665 -0.39923096q0.07131958 -0.2276001 0.07646179 -1.0348053q-0.0032958984 -1.0952148 0.074920654 -1.5502167q0.09718323 -0.4436798 0.37672424 -0.74012756q0.28337097 -0.28131104 0.69233704 -0.38487244q0.37867737 -0.09590149 0.72380066 -0.005996704q0.36026 0.08605957 0.6490326 0.33529663q0.2203064 0.16986084 0.4222107 0.52168274q0.2019043 0.35183716 0.30929565 0.77593994q0.16491699 0.6513214 0.10588074 1.1820679q-0.0552063 0.5458832 -0.3309021 0.85746765q-0.25672913 0.3229065 -0.763855 0.5480499l-0.35128784 -0.8781433q0.40493774 -0.18313599 0.5554352 -0.5436096q0.16947937 -0.34916687 0.031417847 -0.89445496q-0.16491699 -0.6513214 -0.4460144 -0.8702698q-0.28108215 -0.21894836 -0.5688782 -0.14605713q-0.1817627 0.046020508 -0.29122925 0.18656921q-0.120788574 0.1595459 -0.16545105 0.42874146q-0.010925293 0.1478424 -0.031417847 0.8944702q-0.0082092285 1.0497589 -0.07510376 1.4857788q-0.06690979 0.4360199 -0.3426056 0.74760437q-0.26055908 0.30776978 -0.7452545 0.43051147q-0.4695511 0.11891174 -0.9475479 -0.0501709q-0.47799683 -0.16906738 -0.8356018 -0.6265259q-0.35759735 -0.4574585 -0.5225067 -1.1087799q-0.27230072 -1.0754395 0.021217346 -1.7622681q0.3125 -0.67552185 1.1526642 -1.049469z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m136.62865 226.32948l18.960632 -44.37796l28.283463 12.094498l-18.960632 44.377945z" fill-rule="nonzero"></path><path fill="#000000" d="m159.5925 221.55168l-0.66085815 -0.28259277q0.5670624 0.8202667 0.14961243 1.7973328q-0.26397705 0.6178436 -0.83592224 1.0020294q-0.57192993 0.38420105 -1.3124847 0.4073944q-0.74053955 0.023208618 -1.5450745 -0.32081604q-0.79016113 -0.33789062 -1.3117828 -0.86683655q-0.52986145 -0.54945374 -0.6392822 -1.2080078q-0.123794556 -0.6647186 0.15245056 -1.3112946q0.20259094 -0.47416687 0.56333923 -0.761734q0.3607483 -0.28756714 0.7750397 -0.38230896l-2.600357 -1.111969l0.38061523 -0.8908386l7.2407684 3.0962677l-0.35606384 0.833374zm-3.8118286 1.6837616q1.005661 0.43003845 1.6865234 0.22836304q0.67263794 -0.22216797 0.91819763 -0.7969055q0.25169373 -0.5891113 -0.05050659 -1.1941681q-0.30220032 -0.6050415 -1.2791443 -1.0227966q-1.0774841 -0.4607544 -1.7583466 -0.25909424q-0.6747284 0.18730164 -0.93870544 0.80514526q-0.25169373 0.5891113 0.06488037 1.2003021q0.3083496 0.590683 1.3571014 1.039154zm4.524872 -8.04538l0.50782776 -0.8704376q0.71243286 0.55955505 0.9061127 1.3391113q0.19366455 0.7795563 -0.19309998 1.6847687q-0.49111938 1.1494751 -1.4836121 1.5237732q-0.9924927 0.3742981 -2.2711182 -0.1724701q-1.3361053 -0.57133484 -1.7658997 -1.5538177q-0.4380188 -1.003006 0.022399902 -2.0806427q0.45428467 -1.0632629 1.4550171 -1.4170532q0.9863434 -0.35992432 2.2937164 0.1991272q0.07182312 0.030715942 0.2298584 0.09829712l-1.6697998 3.9082336q0.88041687 0.32548523 1.5243073 0.091033936q0.6500397 -0.24884033 0.9324341 -0.90979004q0.20872498 -0.4885254 0.111831665 -0.9378052q-0.11126709 -0.45542908 -0.5999756 -0.9023285zm-2.6828766 2.3024597l1.2523499 -2.9311676q-0.6854248 -0.22512817 -1.1324921 -0.09341431q-0.68699646 0.21603394 -0.9755249 0.8913574q-0.26397705 0.6178436 -0.025390625 1.212677q0.22424316 0.5887146 0.88105774 0.9205475zm7.183197 -2.575241l-7.255127 -3.102417l0.34991455 -0.8190155l0.67523193 0.28874207q-0.26512146 -0.4532318 -0.31277466 -0.89845276q-0.0476532 -0.44522095 0.17333984 -0.9624939q0.2823944 -0.6609497 0.84820557 -1.030777q0.5657959 -0.369812 1.3084259 -0.35813904q0.7282715 0.0055236816 1.4897003 0.33113098q0.8045349 0.34402466 1.3282471 0.9078522q0.50935364 0.5576782 0.61473083 1.2654877q0.11151123 0.6934509 -0.14631653 1.2969208q-0.19030762 0.44543457 -0.5305481 0.7247772q-0.33410645 0.26498413 -0.7196655 0.37200928l2.557251 1.0935211l-0.38061523 0.8908539zm-4.253525 -2.770523q1.005661 0.43003845 1.6721497 0.22221375q0.6521301 -0.21394348 0.8976898 -0.78868103q0.25170898 -0.5891113 -0.05873108 -1.2146759q-0.31866455 -0.6460724 -1.3817902 -1.1006775q-0.9913025 -0.42390442 -1.6721497 -0.222229q-0.6747284 0.18728638 -0.9202881 0.7620392q-0.24555969 0.57473755 0.095687866 1.247467q0.34739685 0.6583557 1.3674316 1.0945435zm2.8574066 -3.8642578l0.23080444 -0.937912q0.56225586 0.1554718 0.9907837 -0.052139282q0.42030334 -0.2281189 0.67814636 -0.831604q0.26397705 -0.6178436 0.14251709 -1.0096436q-0.11531067 -0.4061737 -0.46011353 -0.5536194q-0.30169678 -0.12901306 -0.5845947 0.055892944q-0.19473267 0.13764954 -0.68844604 0.7762146q-0.6616974 0.8726196 -0.9998474 1.1868439q-0.3463745 0.29371643 -0.74838257 0.35972595q-0.39587402 0.051635742 -0.7837677 -0.11424255q-0.35917664 -0.15357971 -0.5789795 -0.43450928q-0.23416138 -0.2870636 -0.31251526 -0.66044617q-0.07208252 -0.26872253 -0.019180298 -0.6709442q0.05290222 -0.40222168 0.22480774 -0.8045349q0.2639618 -0.6178436 0.6328125 -1.0039215q0.37498474 -0.4004364 0.7831421 -0.48080444q0.3999176 -0.10089111 0.93959045 0.027923584l-0.25341797 0.9112549q-0.43295288 -0.10017395 -0.77124023 0.095047q-0.34649658 0.17471313 -0.5675049 0.6919708q-0.26397705 0.6178436 -0.17333984 0.96247864q0.09062195 0.34465027 0.36358643 0.46138q0.17240906 0.07371521 0.3446808 0.028427124q0.19277954 -0.053512573 0.39157104 -0.24040222q0.098342896 -0.11088562 0.5675049 -0.6919861q0.6432648 -0.82951355 0.960907 -1.1355133q0.31765747 -0.30599976 0.72579956 -0.3863678q0.39378357 -0.086517334 0.8535156 0.110061646q0.44535828 0.19044495 0.72276306 0.6149597q0.27738953 0.4244995 0.28416443 1.005188q0.0067749023 0.5806732 -0.25720215 1.1985168q-0.4358673 1.0201569 -1.0857849 1.3880005q-0.65812683 0.34733582 -1.5527802 0.13470459z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m81.12184 104.50765l17.41732 -44.976383l28.692917 11.118114l-17.41732 44.97637z" fill-rule="nonzero"></path><path fill="#000000" d="m103.909035 98.94311l-0.6701889 -0.25969696q0.59490204 0.80026245 0.21121216 1.7910614q-0.24263 0.6265335 -0.80107117 1.030159q-0.55844116 0.40361786 -1.2977829 0.45227814q-0.7393341 0.04865265 -1.5552292 -0.2674942q-0.8013153 -0.3105011 -1.340805 -0.8211746q-0.54842377 -0.5308838 -0.6803894 -1.1852722q-0.14653015 -0.6600342 0.10738373 -1.315712q0.186203 -0.48082733 0.5368805 -0.7806244q0.3506775 -0.29979706 0.76148224 -0.40872955l-2.6370697 -1.0218277l0.34983826 -0.90338135l7.34301 2.8453217l-0.3272705 0.8450928zm-3.7519302 1.8137894q1.0198593 0.39518738 1.6934204 0.17022705q0.66464233 -0.2451706 0.8903427 -0.8279953q0.23134613 -0.59739685 -0.09146118 -1.1916733q-0.32279968 -0.5942764 -1.3135223 -0.9781647q-1.0927124 -0.42341614 -1.7662735 -0.19845581q-0.667923 0.21038055 -0.910553 0.8369217q-0.23134613 0.5973892 0.106025696 1.197319q0.32844543 0.5797043 1.3920212 0.9918213zm4.246277 -8.195946l0.47768402 -0.887352q0.73124695 0.5347061 0.951561 1.307106q0.2203064 0.77240753 -0.13516998 1.6903534q-0.4514084 1.1656494 -1.4305115 1.5738373q-0.9791031 0.4081955 -2.2757797 -0.09425354q-1.3549652 -0.52503204 -1.8182373 -1.4921188q-0.4721985 -0.9873123 -0.04901123 -2.080101q0.41754913 -1.0782242 1.4055786 -1.4662018q0.97345734 -0.39362335 2.2992783 0.12011719q0.07285309 0.02822876 0.23311615 0.09033203l-1.5347672 3.9631958q0.8910904 0.29502106 1.5265884 0.03855896q0.6411438 -0.27103424 0.90070343 -0.9412842q0.19184113 -0.49539948 0.079582214 -0.94107056q-0.12683105 -0.4513092 -0.63061523 -0.8811188zm-2.6023788 2.3932877l1.1510773 -2.9724045q-0.6927643 -0.20140839 -1.1350708 -0.05441284q-0.67920685 0.23952484 -0.9444046 0.9243469q-0.24263 0.6265335 0.01625061 1.2127991q0.24430847 0.5806198 0.9121475 0.8896713zm7.0908585 -2.820671l-7.3575745 -2.8509598l0.32162476 -0.83052826l0.68476105 0.26533508q-0.2805252 -0.44384003 -0.34342957 -0.88713837q-0.06291199 -0.44330597 0.14022064 -0.9678421q0.259552 -0.67024994 0.81235504 -1.0593033q0.5527954 -0.38904572 1.2954178 -0.40291595q0.72805023 -0.019515991 1.5002365 0.2796936q0.81588745 0.31614685 1.3586655 0.8616028q0.5282059 0.5398102 0.657814 1.2435608q0.13524628 0.68917084 -0.101737976 1.3011398q-0.17491913 0.45168304 -0.50538635 0.74256134q-0.32482147 0.27629852 -0.70648956 0.39652252l2.593361 1.0048904l-0.34983826 0.90338135zm-4.346245 -2.6225052q1.019867 0.39517975 1.6788559 0.1645813q0.64443207 -0.2362442 0.87013245 -0.8190689q0.2313385 -0.59739685 -0.10038757 -1.2118912q-0.34065247 -0.6347122 -1.4187927 -1.052475q-1.0052948 -0.389534 -1.6788559 -0.1645813q-0.667923 0.21038818 -0.893631 0.7932129q-0.22570038 0.5828247 0.13845062 1.243393q0.36979675 0.6460037 1.4042282 1.0468292zm2.7232208 -3.9600906l0.19850159 -0.9452667q0.56728363 0.1360321 0.9884491 -0.08618164q0.41223907 -0.24243164 0.64923096 -0.854393q0.24262238 -0.62654114 0.107795715 -1.0139236q-0.12918854 -0.40195465 -0.47885895 -0.53744507q-0.30595398 -0.11856079 -0.5823517 0.07596588q-0.18991089 0.14425659 -0.661438 0.7993927q-0.6313782 0.8948288 -0.9585571 1.2204895q-0.33611298 0.3054428 -0.73563385 0.38523102q-0.39388275 0.065223694 -0.78725433 -0.08720398q-0.36424255 -0.14113617 -0.59355927 -0.41432953q-0.24388885 -0.27882385 -0.33501434 -0.64927673q-0.08126831 -0.2660904 -0.04219055 -0.66986847q0.03907776 -0.4037857 0.19706726 -0.81175995q0.24263 -0.62654114 0.59802246 -1.0250549q0.3610382 -0.4130783 0.76620483 -0.50743866q0.39624023 -0.11457825 0.9400253 -0.00440979l-0.2219925 0.9194031q-0.43615723 -0.08522034 -0.76755524 0.12150574q-0.34031677 0.18651581 -0.5434494 0.7110596q-0.24263 0.6265335 -0.14022064 0.9678421q0.10240173 0.3413086 0.37922668 0.44857025q0.1748352 0.06774902 0.34545135 0.016563416q0.19084167 -0.060112 0.38310242 -0.25372314q0.09449768 -0.11419678 0.54345703 -0.7110596q0.6144409 -0.85111237 0.9214096 -1.1678467q0.30697632 -0.3167343 0.71214294 -0.41109467q0.39059448 -0.1000061 0.85681915 0.08065033q0.45165253 0.17501068 0.7434616 0.5897064q0.29180908 0.41469574 0.31850433 0.9947815q0.026695251 0.58008575 -0.21593475 1.2066193q-0.4006195 1.0345078 -1.0375519 1.4244766q-0.64585876 0.36975098 -1.5473099 0.1880188z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m171.07939 43.463318l21.732285 43.08661l-26.803146 13.511818l-21.732285 -43.086617z" fill-rule="nonzero"></path><path fill="#000000" d="m159.94344 64.10798l0.6417999 -0.32354355q-0.9926758 -0.094516754 -1.4711609 -1.0431747q-0.30256653 -0.59988785 -0.22807312 -1.284874q0.07450867 -0.6849899 0.5337219 -1.2664528q0.45922852 -0.58145905 1.2405548 -0.9753418q0.76737976 -0.38684464 1.5079498 -0.4452057q0.7615509 -0.051445007 1.3357697 0.2890129q0.58818054 0.3334236 0.90483093 0.96121216q0.23220825 0.46038055 0.21983337 0.92157364q-0.012390137 0.46119308 -0.20675659 0.83914566l2.5253906 -1.2730789l0.43626404 0.8649521l-7.032013 3.5449257l-0.40811157 -0.8091507zm1.1671906 -4.0005302q-0.9766693 0.49235153 -1.2609406 1.1431007q-0.26327515 0.65766907 0.018188477 1.215702q0.28849792 0.57198715 0.94595337 0.7305031q0.65745544 0.15851593 1.6062164 -0.319767q1.0464325 -0.5275192 1.3307037 -1.1782722q0.29130554 -0.63679886 -0.011276245 -1.2366867q-0.28849792 -0.57198334 -0.9598999 -0.72346497q-0.65042114 -0.14456558 -1.6689453 0.36888504zm3.239624 8.643436l0.33872986 0.94911957q-0.8868866 0.18462372 -1.6079102 -0.16932678q-0.72102356 -0.35394287 -1.1643372 -1.2328491q-0.56292725 -1.116066 -0.2099762 -2.1164017q0.3529358 -1.0003357 1.594696 -1.6263275q1.2975769 -0.6541214 2.3259277 -0.35011292q1.0493164 0.31093597 1.5770721 1.3572464q0.5207062 1.0323639 0.14677429 2.0257797q-0.35998535 0.98638916 -1.6296539 1.626442q-0.06976318 0.03517151 -0.22323608 0.1125412l-1.9139557 -3.7946396q-0.81604004 0.46387482 -1.0514221 1.1074753q-0.22833252 0.657547 0.09535217 1.2992859q0.23924255 0.47433472 0.64530945 0.6895828q0.4200287 0.2082138 1.0766296 0.12218475zm-0.033187866 -3.5353851l1.4354706 2.8459778q0.6136627 -0.37934875 0.8008728 -0.8061905q0.27722168 -0.66469574 -0.053497314 -1.3203888q-0.30256653 -0.59989166 -0.9112549 -0.80049133q-0.59472656 -0.20763397 -1.2715912 0.081092834zm-2.656723 7.153839l7.0459595 -3.5519638l0.40109253 0.79520416l-0.6557617 0.33057404q0.5174408 0.08911133 0.88868713 0.3394165q0.37124634 0.25029755 0.62457275 0.75253296q0.3236847 0.6417389 0.24214172 1.3127747q-0.08154297 0.67103577 -0.5687866 1.2316284q-0.47329712 0.55355835 -1.2127686 0.9263382q-0.78134155 0.39388275 -1.5499268 0.4313736q-0.7546387 0.030464172 -1.3639221 -0.3448105q-0.60224915 -0.36132812 -0.8977814 -0.9472656q-0.21813965 -0.43247986 -0.212677 -0.8726883q0.012496948 -0.42625427 0.17897034 -0.79013824l-2.4835358 1.251976l-0.43626404 -0.8649521zm4.8588104 -1.4694977q-0.9766693 0.49234772 -1.2469788 1.1360626q-0.25636292 0.63668823 0.025100708 1.1947174q0.28849792 0.57199097 0.9669342 0.7374191q0.6994324 0.17235565 1.7319183 -0.34812927q0.9627075 -0.48532104 1.2469788 -1.1360703q0.2913208 -0.6368027 0.009841919 -1.1948318q-0.28146362 -0.5580368 -1.0158386 -0.7302704q-0.72732544 -0.15828705 -1.7179565 0.3411026zm1.1154175 4.67482l0.5687561 0.78066254q-0.48104858 0.33000183 -0.5982666 0.79154205q-0.096206665 0.46846008 0.19932556 1.0543976q0.3025818 0.59988403 0.6804962 0.75933075q0.384964 0.17339325 0.7198181 0.0045928955q0.29299927 -0.14770508 0.33377075 -0.48322296q0.020141602 -0.23763275 -0.15029907 -1.0266113q-0.24130249 -1.0682297 -0.26387024 -1.5293045q-0.0015716553 -0.4541626 0.20687866 -0.8042145q0.21546936 -0.33609772 0.5921936 -0.5260086q0.34880066 -0.17583466 0.70526123 -0.16304779q0.37039185 0.0057525635 0.7064667 0.18630219q0.25198364 0.11794281 0.52557373 0.41748047q0.27357483 0.29953766 0.4705963 0.690155q0.3025818 0.59989166 0.36032104 1.130722q0.06477356 0.5447769 -0.1366272 0.90878296q-0.18040466 0.37091827 -0.6265259 0.70079803l-0.5338135 -0.7807846q0.355484 -0.26669312 0.42404175 -0.6512146q0.089538574 -0.37760162 -0.16378784 -0.87983704q-0.30256653 -0.59988403 -0.6245575 -0.7525253q-0.32199097 -0.15264893 -0.58709717 -0.019012451q-0.16741943 0.08440399 -0.2437439 0.24536133q-0.083221436 0.1819458 -0.06829834 0.45439148q0.021469116 0.14665985 0.16377258 0.87983704q0.22018433 1.0263748 0.2496643 1.4664688q0.02947998 0.440094 -0.17193604 0.8040924q-0.18743896 0.35697174 -0.6339264 0.5820465q-0.43252563 0.21804047 -0.9358978 0.15682983q-0.5033722 -0.061210632 -0.9519043 -0.43003845q-0.4485321 -0.3688202 -0.75109863 -0.96871185q-0.49960327 -0.99050903 -0.36238098 -1.724617q0.15821838 -0.7271881 0.8970947 -1.274643z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m62.48595 164.64017l52.724415 69.291336l-23.874016 18.173233l-52.724415 -69.29135z" fill-rule="nonzero"></path><path fill="#000000" d="m53.061855 184.02805l4.53796 -3.4543457l0.52038574 0.6838989l-0.68379974 0.5205231q0.6930313 -0.09553528 1.0125313 0.014709473q0.31950378 0.11026001 0.5181961 0.37138367q0.30277252 0.39790344 0.35688782 0.98509216l-0.9073601 0.2783203q-0.055992126 -0.4090271 -0.27360916 -0.6950226q-0.18923187 -0.24868774 -0.48981094 -0.33407593q-0.30057907 -0.08538818 -0.64033127 0.03578186q-0.50489426 0.18797302 -0.9897728 0.5570679l-2.3746567 1.8076172l-0.58662033 -0.7709503zm4.4196167 5.8083496l0.67136765 -0.5110626q-1.1776772 0.052078247 -1.8683739 -0.85565186q-0.30277252 -0.39790344 -0.42796326 -0.8720703q-0.10329819 -0.47120667 -0.01197052 -0.8156433q0.113220215 -0.34146118 0.40159607 -0.6591644q0.1859436 -0.22007751 0.68325424 -0.5986481l2.809803 -2.138855l0.58662033 0.77093506l-2.5114174 1.9117279q-0.60920715 0.46374512 -0.78271484 0.6743622q-0.24161911 0.30174255 -0.24536896 0.6580658q0.005710602 0.36875916 0.2706375 0.71691895q0.2649231 0.34817505 0.6660614 0.5140991q0.42303085 0.1689148 0.8160324 0.06611633q0.40543365 -0.11224365 0.9773407 -0.54759216l2.436821 -1.85495l0.58662033 0.7709503l-4.53796 3.454361l-0.52038574 -0.6838989zm1.3179626 1.7320862l4.537956 -3.454361l0.52985 0.69633484l-0.64650345 0.49212646q1.1244316 -0.07044983 1.8435097 0.87457275q0.31223297 0.41033936 0.42796326 0.8720856q0.1281662 0.4522705 0.0025100708 0.80319214q-0.103759766 0.3538971 -0.3702469 0.6745758q-0.19540405 0.20765686 -0.730011 0.61460876l-2.7849388 2.119934l-0.5866165 -0.7709503l2.7600708 -2.100998q0.47244644 -0.3596344 0.6300087 -0.6170349q0.16999054 -0.26686096 0.12697601 -0.60720825q-0.021110535 -0.33740234 -0.25765228 -0.6482544q-0.3690033 -0.48495483 -0.9542084 -0.608963q-0.5852051 -0.12399292 -1.4679298 0.5479431l-2.474121 1.8833313l-0.5866165 -0.77093506zm5.5593147 5.886963l-0.5956726 0.61053467q-0.3205986 -0.26651 -0.5098305 -0.515213q-0.32169342 -0.42277527 -0.36470413 -0.7631378q-0.033546448 -0.32792664 0.10211563 -0.58828735q0.14512634 -0.2479248 0.841362 -0.7779083l2.6108818 -1.987442l-0.43523407 -0.57199097l0.59677124 -0.4542694l0.43523407 0.57199097l1.1189499 -0.85176086l1.0495987 0.39888l-1.5913925 1.2113953l0.59607697 0.783371l-0.59677124 0.4542694l-0.59607697 -0.783371l-2.660614 2.025299q-0.32324982 0.24606323 -0.39432907 0.35906982q-0.04918289 0.115982056 -0.04511261 0.25035095q0.025959015 0.1373291 0.14896011 0.2989807q0.1040802 0.13677979 0.2897873 0.3292389zm5.215065 -2.8999329l0.8827286 -0.67193604l0.5866165 0.77093506l-0.88272095 0.6719513l-0.58662415 -0.7709503zm-5.3833847 4.0979156l4.537964 -3.454361l0.5866165 0.7709503l-4.537956 3.4543457l-0.58662415 -0.77093506zm1.4241486 1.8716278l4.537956 -3.454361l0.5298462 0.6963501l-0.6340637 0.48265076q0.49652863 -0.044128418 0.9603729 0.15261841q0.47331238 0.20916748 0.8139343 0.6568146q0.3879242 0.50982666 0.42256927 0.9940033q0.047073364 0.47473145 -0.23426056 0.90489197q1.2025452 -0.071014404 1.8553925 0.78697205q0.52038574 0.6839142 0.42179108 1.3284302q-0.098594666 0.644516 -0.86943054 1.2312927l-3.1206207 2.3754578l-0.57715607 -0.7585144l2.8595352 -2.176712q0.4600067 -0.35017395 0.6021652 -0.5762024q0.15458679 -0.23548889 0.12753296 -0.52908325q-0.027061462 -0.29359436 -0.22575378 -0.554718q-0.3690033 -0.48495483 -0.9382553 -0.5621948q-0.55979156 -0.06478882 -1.2560272 0.4651947l-2.6357422 2.006363l-0.58662415 -0.7709503l2.9465637 -2.2429657q0.50974274 -0.38801575 0.6289139 -0.7732849q0.11916351 -0.3852539 -0.2025299 -0.8080292q-0.2460022 -0.32330322 -0.63768005 -0.47680664q-0.3822174 -0.1410675 -0.81251526 -0.009887695q-0.41786957 0.12171936 -1.039505 0.5949249l-2.3497925 1.7886963l-0.5866165 -0.7709503zm9.207695 9.056122l0.5060806 0.87153625q-0.83815765 0.34346008 -1.611496 0.12702942q-0.7733383 -0.21644592 -1.3694229 -0.9998169q-0.7569275 -0.99476624 -0.59241486 -2.042923q0.16451263 -1.048172 1.2710266 -1.8904572q1.1562424 -0.8801575 2.22258 -0.76893616q1.0882263 0.11419678 1.7978439 1.0467987q0.70015717 0.92015076 0.5137558 1.9653473q-0.17397308 1.0357208 -1.3053589 1.8969574q-0.062156677 0.047317505 -0.1989212 0.15141296l-2.573555 -3.3822021q-0.7175751 0.6051483 -0.8315811 1.2810211q-0.104537964 0.688324 0.3306961 1.260315q0.32169342 0.42277527 0.76013184 0.560318q0.4508667 0.12808228 1.0806351 -0.07640076zm-0.67742157 -3.4706116l1.9301605 2.5366516q0.53406525 -0.4850769 0.64024353 -0.9390106q0.15129852 -0.7042694 -0.293396 -1.2886963q-0.4068451 -0.5346985 -1.0417786 -0.62083435q-0.6225052 -0.09561157 -1.2352295 0.31188965zm-1.8461914 6.8112946l0.55947113 -0.4258728l3.8792496 5.098175l-0.55947113 0.4258728l-3.8792496 -5.098175zm8.111038 7.0471954l0.57190704 -0.43533325q-0.9930649 0.088272095 -1.6364517 -0.75727844q-0.40685272 -0.5346832 -0.45854187 -1.2219086q-0.051696777 -0.6872101 0.2936859 -1.3428497q0.34537506 -0.65563965 1.0416107 -1.1856232q0.68379974 -0.5205231 1.4011459 -0.7131195q0.7392502 -0.18962097 1.3658218 0.04034424q0.63899994 0.22052002 1.0647736 0.7800751q0.31223297 0.41033936 0.38417053 0.86613464q0.07194519 0.4557953 -0.050186157 0.8629608l2.250328 -1.7129822l0.5866165 0.77093506l-6.2661133 4.7698517l-0.5487671 -0.72120667zm0.4177475 -4.1471863q-0.87029266 0.6624756 -1.0310516 1.3543243q-0.13887024 0.69480896 0.2395935 1.1921997q0.38793182 0.5098114 1.0631332 0.54566956q0.67520905 0.035858154 1.5206375 -0.60769653q0.932457 -0.7097931 1.093216 -1.4016418q0.17021942 -0.67941284 -0.23662567 -1.2140961q-0.3879242 -0.5098114 -1.0755692 -0.5362091q-0.66574097 -0.023422241 -1.5733337 0.66744995zm4.761055 7.908478l0.5060806 0.871521q-0.83815765 0.34346008 -1.611496 0.12702942q-0.77334595 -0.21643066 -1.3694229 -0.9998169q-0.7569275 -0.99476624 -0.59241486 -2.042923q0.16451263 -1.0481567 1.2710266 -1.8904572q1.1562424 -0.8801422 2.22258 -0.7689209q1.0882263 0.11419678 1.7978439 1.0467834q0.70015717 0.920166 0.5137558 1.9653625q-0.17397308 1.0357208 -1.3053589 1.8969421q-0.062164307 0.047317505 -0.1989212 0.15142822l-2.573555 -3.3822174q-0.7175751 0.6051483 -0.8315811 1.2810364q-0.104537964 0.688324 0.3306961 1.260315q0.32169342 0.42277527 0.76013184 0.560318q0.4508667 0.12806702 1.0806351 -0.07640076zm-0.67742157 -3.4706268l1.9301605 2.5366669q0.53406525 -0.48509216 0.64024353 -0.9390106q0.15129852 -0.70428467 -0.293396 -1.2887115q-0.4068451 -0.5346832 -1.0417862 -0.62083435q-0.62249756 -0.09561157 -1.2352219 0.31188965zm-1.3068848 7.5200806l6.278549 -4.779312l0.53930664 0.70877075l-0.58434296 0.4447937q0.5249176 -0.0068359375 0.93551636 0.1715393q0.41059875 0.17837524 0.7512207 0.62602234q0.43523407 0.57199097 0.47746277 1.2467651q0.0422287 0.67477417 -0.33450317 1.3150177q-0.3643036 0.6307678 -1.0232391 1.13237q-0.69623566 0.5299835 -1.4449387 0.7071686q-0.7362747 0.16772461 -1.4036636 -0.09008789q-0.65792084 -0.24537659 -1.0553131 -0.76763916q-0.29330444 -0.38546753 -0.36821747 -0.81936646q-0.065452576 -0.421463 0.031814575 -0.8096924l-2.2130356 1.6845856l-0.5866165 -0.77093506zm4.5083313 -2.332138q-0.87029266 0.6624756 -1.0186157 1.3448486q-0.13589478 0.6729126 0.24256897 1.1703033q0.3879242 0.5098114 1.085022 0.548645q0.71899414 0.041793823 1.6390152 -0.6585388q0.8578644 -0.65301514 1.0186234 -1.3448639q0.17022705 -0.6793976 -0.2082367 -1.1767883q-0.37846375 -0.4973755 -1.1317902 -0.5326843q-0.74385834 -0.022872925 -1.6265869 0.64907837zm1.949089 4.3935547l0.7014847 0.6638794q-0.41270447 0.41233826 -0.44374084 0.88760376q-0.009140015 0.47825623 0.38824463 1.0005035q0.4068451 0.5346832 0.8074341 0.62249756q0.41004944 0.100234985 0.70843506 -0.12690735q0.26109314 -0.19874573 0.23997498 -0.5361328q-0.023536682 -0.23736572 -0.33499146 -0.9821167q-0.43202972 -1.0064392 -0.53829956 -1.4557495q-0.084373474 -0.44631958 0.056678772 -0.8286133q0.15052032 -0.3698578 0.48620605 -0.6253967q0.31082153 -0.23658752 0.66355133 -0.28909302q0.3651657 -0.061965942 0.7284546 0.054229736q0.26922607 0.06997681 0.5927963 0.3146057q0.32357025 0.24461365 0.58849335 0.59277344q0.4068451 0.5346985 0.5604248 1.0461731q0.16304016 0.5239105 0.031440735 0.9186249q-0.109703064 0.39770508 -0.48807526 0.8035431l-0.66716003 -0.6703491q0.30081177 -0.32717896 0.2980652 -0.7178192q0.01915741 -0.38768005 -0.3214569 -0.83532715q-0.40685272 -0.5346832 -0.7512207 -0.62602234q-0.34436798 -0.09132385 -0.5805893 0.08850098q-0.14919281 0.11355591 -0.19485474 0.28578186q-0.04863739 0.19410706 0.015724182 0.45932007q0.047851562 0.14030457 0.3214569 0.83532715q0.40364838 0.96913147 0.5128937 1.3965302q0.10923767 0.42741394 -0.022361755 0.8221283q-0.11916351 0.38526917 -0.51701355 0.68811035q-0.38541412 0.29338074 -0.8914032 0.3250885q-0.5059967 0.031707764 -1.014183 -0.24909973q-0.50818634 -0.28082275 -0.91503143 -0.815506q-0.6717758 -0.8828583 -0.6707611 -1.6298218q0.022903442 -0.7440033 0.64938354 -1.4172668z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m53.480316 55.42551l0 49.165356l-29.984253 0l0 -49.165356z" fill-rule="nonzero"></path><path fill="#000000" d="m34.240314 68.84738l0.71875 0q-0.84375 -0.53125 -0.84375 -1.59375q0 -0.671875 0.375 -1.25q0.375 -0.578125 1.046875 -0.890625q0.671875 -0.3125 1.546875 -0.3125q0.859375 0 1.546875 0.28125q0.703125 0.296875 1.0625 0.859375q0.375 0.5625 0.375 1.265625q0 0.515625 -0.21875 0.921875q-0.21875 0.40625 -0.5625 0.65625l2.828125 0l0 0.96875l-7.875 0l0 -0.90625zm2.84375 -3.046875q-1.09375 0 -1.640625 0.453125q-0.53125 0.46875 -0.53125 1.09375q0 0.640625 0.515625 1.078125q0.515625 0.4375 1.578125 0.4375q1.171875 0 1.71875 -0.453125q0.546875 -0.4375 0.546875 -1.109375q0 -0.640625 -0.53125 -1.078125q-0.515625 -0.421875 -1.65625 -0.421875zm-1.0 9.176498l-0.125 1.0q-0.875 -0.234375 -1.359375 -0.875q-0.484375 -0.640625 -0.484375 -1.625q0 -1.25 0.765625 -1.984375q0.765625 -0.734375 2.15625 -0.734375q1.453125 0 2.234375 0.734375q0.796875 0.75 0.796875 1.921875q0 1.15625 -0.78125 1.875q-0.765625 0.71875 -2.1875 0.71875q-0.078125 0 -0.25 0l0 -4.25q-0.9375 0.046875 -1.4375 0.515625q-0.5 0.484375 -0.5 1.203125q0 0.53125 0.265625 0.90625q0.28125 0.375 0.90625 0.59375zm1.5625 -3.171875l0 3.1875q0.71875 -0.0625 1.078125 -0.359375q0.546875 -0.46875 0.546875 -1.203125q0 -0.671875 -0.453125 -1.125q-0.4375 -0.453125 -1.171875 -0.5zm-5.59375 5.1921234l7.890625 0l0 0.890625l-0.734375 0q0.421875 0.3125 0.640625 0.703125q0.21875 0.390625 0.21875 0.953125q0 0.71875 -0.375 1.28125q-0.375 0.5625 -1.0625 0.84375q-0.671875 0.28125 -1.5 0.28125q-0.875 0 -1.578125 -0.3125q-0.6875 -0.3125 -1.0625 -0.921875q-0.375 -0.59375 -0.375 -1.25q0 -0.484375 0.203125 -0.875q0.203125 -0.375 0.515625 -0.625l-2.78125 0l0 -0.96875zm5.0 0.875q-1.09375 0 -1.625 0.453125q-0.515625 0.453125 -0.515625 1.078125q0 0.640625 0.53125 1.09375q0.546875 0.46875 1.703125 0.46875q1.078125 0 1.625 -0.453125q0.546875 -0.4375 0.546875 -1.0625q0 -0.625 -0.578125 -1.109375q-0.578125 -0.46875 -1.6875 -0.46875zm-1.109375 4.6764984l0.15625 0.953125q-0.578125 0.078125 -0.890625 0.4375q-0.296875 0.375 -0.296875 1.03125q0 0.671875 0.265625 0.984375q0.265625 0.328125 0.640625 0.328125q0.328125 0 0.515625 -0.28125q0.125 -0.203125 0.328125 -0.984375q0.265625 -1.0625 0.453125 -1.484375q0.203125 -0.40625 0.546875 -0.625q0.34375 -0.203125 0.765625 -0.203125q0.390625 0 0.703125 0.171875q0.328125 0.171875 0.546875 0.484375q0.171875 0.21875 0.28125 0.609375q0.109375 0.390625 0.109375 0.828125q0 0.671875 -0.1875 1.171875q-0.1875 0.515625 -0.53125 0.75q-0.328125 0.25 -0.875 0.34375l-0.125 -0.9375q0.4375 -0.078125 0.671875 -0.390625q0.25 -0.296875 0.25 -0.859375q0 -0.671875 -0.21875 -0.953125q-0.21875 -0.28125 -0.515625 -0.28125q-0.1875 0 -0.328125 0.109375q-0.15625 0.125 -0.265625 0.375q-0.046875 0.140625 -0.25 0.859375q-0.265625 1.015625 -0.4375 1.421875q-0.171875 0.40625 -0.515625 0.640625q-0.328125 0.234375 -0.828125 0.234375q-0.484375 0 -0.90625 -0.28125q-0.421875 -0.28125 -0.65625 -0.8125q-0.234375 -0.53125 -0.234375 -1.203125q0 -1.109375 0.453125 -1.703125q0.46875 -0.578125 1.375 -0.734375z" fill-rule="nonzero"></path></g></svg> - diff --git a/site/versions/master/docs/skylark/build-style.md b/site/versions/master/docs/skylark/build-style.md deleted file mode 100644 index 3cee2fc26e..0000000000 --- a/site/versions/master/docs/skylark/build-style.md +++ /dev/null @@ -1,110 +0,0 @@ - -# BUILD file style guide - -In `BUILD` files, we take the same approach as in Go: We let the machine take care -of most formatting issues. -[Buildifier](https://github.com/bazelbuild/buildifier) is a tool that parses and -emits the source code in a standard style. Every `BUILD` file is therefore -formatted in the same automated way, which makes formatting a non-issue during -code reviews. It also makes it easier for tools to understand, edit, and -generate `BUILD` files. - -`BUILD` file formatting must match the output of `buildifier`. - -## Formatting example - -```python -package(default_visibility = ["//visibility:public"]) - -py_test( - name = "foo_test", - srcs = glob(["*.py"]), - data = [ - "//data/production/foo:startfoo", - "//foo", - "//third_party/java/jdk:jdk-k8", - ], - flaky = 1, - deps = [ - ":check_bar_lib", - ":foo_data_check", - ":pick_foo_port", - "//pyglib", - "//testing/pybase", - ], -) -``` - -## File structure - -We recommend to use the following order (every element is optional): - - * Package description (a comment) - - * All `load()` statements - - * The `package()` function. - - * Calls to rules and macros - -Buildifier makes a distinction between a standalone comment and a comment -attached to an element. If a comment is not attached to a specific element, use -an empty line after it. The distinction is important when doing automated -changes (e.g. to decide if we keep or remove a comment when we delete a rule). - -```python -# Standalone comment (e.g. to make a section in a file) - -# Comment for the cc_library below -cc_library(name = "cc") -``` - -## Conventions - - * Use uppercase and underscores to declare constants (e.g. `GLOBAL_CONSTANT`), - use lowercase and underscores to declare variables (e.g. `my_variable`). - - * Labels should be canonicalized. Use `//foo/bar` instead of `//foo/bar:bar`. - Use `:bar` if it is defined in the same package. *Rationale*: It makes clear - if a label is local to a package. Sorting a list of labels is messy if all - labels do not use the same conventions. - - * Labels should never be split, even if they are longer than 79 characters. - Labels should be string literals whenever possible. Rationale: It makes - find and replace easy. It also improves readability. - - * The value of the name attribute should be a literal constant string (except - in macros). *Rationale*: External tools use the name attribute to refer a - rule. They need to find rules without having to interpret code. - -## Differences with Python style guide - -Although compatibility with -[Python style guide](https://www.python.org/dev/peps/pep-0008/) is a goal, there -are a few differences: - - * No strict line length limit. Long comments and long strings are often split - to 79 columns, but it is not required. It should not be enforced in code - reviews or presubmit scripts. *Rationale*: Labels can be long and exceed this - limit. It is common for `BUILD` files to be generated or edited by tools, which - does not go well with a line length limit. - - * Implicit string concatenation is not supported. Use the `+` operator. - *Rationale*: `BUILD` files contain many string lists. It is easy to forget a - comma, which leads to a complete different result. This has created many bugs - in the past. See also this discussion. - - * Use spaces around the `=` sign for keywords arguments in rules. *Rationale*: - Named arguments are much more frequent than in Python and are always on a - separate line. Spaces improve readability. This convention has been around - for a long time, and we don't think it is worth modifying all existing - `BUILD` files. - - * By default, use double quotation marks for strings. *Rationale*: This is not - specified in the Python style guide, but it recommends consistency. So we - decided to use only double-quoted strings. Many languages use double-quotes - for string literals. - - * Use a single blank line between two top-level definitions. *Rationale*: The - structure of a `BUILD` file is not like a typical Python file. It has only - top-level statements. Using a single-blank line makes `BUILD` files shorter. diff --git a/site/versions/master/docs/skylark/bzl-style.md b/site/versions/master/docs/skylark/bzl-style.md deleted file mode 100644 index a88dfcad76..0000000000 --- a/site/versions/master/docs/skylark/bzl-style.md +++ /dev/null @@ -1,48 +0,0 @@ - -# .bzl file style guide - -## Style - -* When in doubt, follow the - [Python style guide](https://www.python.org/dev/peps/pep-0008/). - -* Code should be documented using - [docstrings](https://www.python.org/dev/peps/pep-0257/). Use a docstring at - the top of the file, and a docstring for each public function. - -* Variables and function names use lowercase with words separated by underscores - (`[a-z][a-z0-9_]*`), e.g. `cc_library`. Top-level private values start with - one underscore. Bazel enforces that private values cannot be used from other - files. - -* As in BUILD files, there is no strict line length limit as labels can be long. - When possible, try to use at most 79 characters per line. - -* In keyword arguments, spaces around the equal sign are optional. In general, - we follow the BUILD file convention when calling macros and native rules, and - the Python convention for other functions, e.g. - -```python -def fct(name, srcs): - filtered_srcs = my_filter(source=srcs) - native.cc_library( - name = name, - srcs = filtered_srcs, - ) -``` - -## Macros - -A [macro](macros.md) is a function which instantiates one or many rules during -the loading phase. - -* Macros must accept a name attribute and each invocation should specify a name. - The generated name attribute of rules should include the name attribute as a - prefix. For example, `my_macro(name = "foo")` can generate a rule `foo` and a - rule `foo_gen`. *Rationale*: Users should be able to find easily which macro - generated a rule. Also, automated refactoring tools need a way to identify a - specific rule to edit. - -* When calling a macro, use only keyword arguments. *Rationale*: This is for - consistency with rules, it greatly improves readability. - diff --git a/site/versions/master/docs/skylark/concepts.md b/site/versions/master/docs/skylark/concepts.md deleted file mode 100644 index 355a15f8c2..0000000000 --- a/site/versions/master/docs/skylark/concepts.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -layout: documentation -title: Extensions - Overview ---- -# Overview - -## Loading an extension - -Extensions are files with the `.bzl` extension. Use the `load` statement to -import a symbol from an extension. - -```python -load("//build_tools/rules:maprule.bzl", "maprule") -``` - -This code will load the file `build_tools/rules/maprule.bzl` and add the -`maprule` symbol to the environment. This can be used to load new rules, -functions or constants (e.g. a string, a list, etc.). Multiple symbols can be -imported by using additional arguments to the call to `load`. Arguments must -be string literals (no variable) and `load` statements must appear at -top-level, i.e. they cannot be in a function body. - -`load` also supports aliases, i.e. you can assign different names to the -imported symbols. - -```python -load("//build_tools/rules:maprule.bzl", maprule_alias = "maprule") -``` - -You define multiple aliases within one `load` statement. Moreover, the argument -list can contain both aliases and regular symbol names. The following example is -perfectly legal (please note when to use quotation marks). - -```python -load("/path/to:my_rules.bzl", "some_rule", nice_alias = "some_other_rule") -``` - -Symbols starting with `_` are private and cannot be loaded from other files. -Visibility doesn't affect loading: you don't need to use `exports_files` to make -a `.bzl` file visible. - -## Macros and rules - -A [macro](macros.md) is a function that instantiates rules. The -function is evaluated as soon as the BUILD file is read. Bazel has little -information about macros: if your macro generates a `genrule`, Bazel will behave -as if you wrote the `genrule`. As a result, `bazel query` will only list the -generated genrule. - -A [rule](rules.md) is more powerful than a macro, as it can access -Bazel internals and have full control over what is going on. It may for example -pass information to other rules. - -If a macro becomes complex, it is often a good idea to make it a rule. - -## Evaluation model - -A build consists of three phases. - -* **Loading phase**. First, we load and evaluate all extensions and all BUILD - files that are needed for the build. The execution of the BUILD files simply - instantiates rules. This is where macros are evaluated. - -* **Analysis phase**. The code of the rules is executed (their `implementation` - function), and actions are instantiated. An action describes how to generate - a set of outputs from a set of inputs, e.g. "run gcc on hello.c and get - hello.o". It is important to note that we have to list explicitly which - files will be generated before executing the actual commands. - -* **Execution phase**. Actions are executed, when at least one of their outputs is - required. If a file is missing or if a command fails to generate one output, - the build fails. Tests are run during this phase, as they are actions. - -Bazel uses parallelism to read, parse and evaluate the `.bzl` files and `BUILD` -files. A file is read at most once per build and the result of the evaluation is -cached and reused. A file is evaluated only once all its dependencies (`load()` -statements) have been resolved. By design, loading a `.bzl` file has no visible -side-effect, it only defines values and functions. - -## Syntax - -The extension language (sometimes referred as "Skylark") is a superset of the -[Core Build Language](/docs/build-ref.html#core_build_language) -and its syntax is a subset of Python. -It is designed to be simple, thread-safe and integrated with the -BUILD language. It is not a general-purpose language and most Python -features are not included. - -The following constructs have been added to the Core Build Language: `if` -statements, `for` loops, and function definitions. They behave like in Python. -Here is an example to show the syntax: - -```python -def fizz_buzz(n): - """Print Fizz Buzz numbers from 1 to n.""" - for i in range(1, n + 1): - s = "" - if i % 3 == 0: - s += "Fizz" - if i % 5 == 0: - s += "Buzz" - print(s if s else i) - -fizz_buzz(20) -``` - -## Mutability - -Because evaluation of BUILD and .bzl files is performed in parallel, there are -some restrictions in order to guarantee thread-safety and determinism. Two -mutable data structures are available: [lists](lib/list.html) and -[dicts](lib/dict.html). Unlike in Python, [sets](lib/set.html) are not mutable. - -In a build, there are many "evaluation contexts": each `.bzl` file and each -`BUILD` file is loaded in a different context. Each rule is also analyzed in a -separate context. We allow side-effects (e.g. appending a value to a list or -deleting an entry in a dictionary) only on objects created during the current -evaluation context. - -For example, here is the content of the file `foo.bzl`: - -```python -var = [] - -def fct(): - var.append(5) - -fct() -``` - -The variable `var` is created when `foo.bzl` is loaded. `fct()` is called during -the same context, so it is safe. At the end of the evaluation, the definition -`var = [5]` is exported. Any other file can load it, and it is possible that -multiple files will load it at the same time. For this reason, the following -code is not legal: - -```python -load(":foo.bzl", "var", "fct") - -var.append(6) # not allowed - -fct() # not allowed -``` - -Since the call to `fct()` attempts to mutate the shared variable `var`, it will -fail. `fct()` can only be called during the evaluation of `foo.bzl`. It cannot -be called from another file. It is also forbidden to call it during the analysis -phase (i.e. when a custom rule is analyzed). - -## Differences with Python - -In addition to the mutability restrictions, there are also differences with -Python: - -* All global values are constant (they cannot be reassigned). - -* `x += y` is syntactic sugar for `x = x + y`. Even if `x` and `y` are lists, - dicts or sets, the original value is not mutated, so references to `x` - that were assigned before the operation will see the old value. This behavior - is temporary, and will follow Python semantics in the future. - -* The `+` operator is defined for dictionaries, returning an immutable - concatenated dictionary created from the entries of the original - dictionaries. In case of duplicate keys, we use values from the second - operand. If you need compatibility with Python, we suggest this syntax: - `dict(a.items() + b.items())`. - -* Dictionaries have deterministic order when iterating (sorted by key). - -* Sets use a custom order when iterating (see [documentation](lib/globals.html#set)). - -* Recursion is not allowed. - -* Loops iterate on a shallow copy of the elements. If the list is modified - during the iteration, you will only see the old values. - -The following Python features are not supported: - -* `class` (see [`struct`](lib/globals.html#struct) function) -* `import` (see [`load`](#loading-a-skylark-extension) statement) -* `while`, `yield` -* `lambda` and nested functions -* `is` (use `==` instead) -* `try`, `raise`, `except`, `finally` (see [`fail`](lib/globals.html#fail) - for fatal errors). -* most builtin functions, most methods - - diff --git a/site/versions/master/docs/skylark/cookbook.md b/site/versions/master/docs/skylark/cookbook.md deleted file mode 100644 index e243396b53..0000000000 --- a/site/versions/master/docs/skylark/cookbook.md +++ /dev/null @@ -1,919 +0,0 @@ ---- -layout: documentation -title: Extensions examples ---- -# Extensions examples - -## <a name="macro"></a>Macro creating a rule - -An example of a macro creating a rule. - -`empty.bzl`: - -```python -def _impl(ctx): - print("This rule does nothing") - -empty = rule(implementation=_impl) -``` - -`extension.bzl`: - -```python -# Loading the rule. The rule doesn't have to be in a separate file. -load("//pkg:empty.bzl", "empty") - -def macro(name, visibility=None): - # Creating the rule. - empty(name = name, visibility = visibility) -``` - -`BUILD`: - -```python -load("//pkg:extension.bzl", "macro") - -macro(name = "myrule") -``` - -## <a name="macro_native"></a>Macro creating a native rule - -An example of a macro creating a native rule. Native rules are special rules -that are automatically available (without <code>load</code>). They are -accessed using the <a href="lib/native.html">native</a> module. - -`extension.bzl`: - -```python -def macro(name, visibility=None): - # Creating a native genrule. - native.genrule( - name = name, - outs = [name + '.txt'], - cmd = 'echo hello > $@', - visibility = visibility, - ) -``` - -`BUILD`: - -```python -load("//pkg:extension.bzl", "macro") - -macro(name = "myrule") -``` - -## <a name="macro_compound"></a>Macro multiple rules - -There's currently no easy way to create a rule that directly uses the -action of a native rule. You can work around this using macros: - -```python -def cc_and_something_else_binary(name, srcs, deps, csrcs, cdeps) - cc_binary_name = "%s.cc_binary" % name - - native.cc_binary( - name = cc_binary_name, - srcs = csrcs, - deps = cdeps - ) - - _cc_and_something_else_binary( - name = name, - srcs = srcs, - deps = deps, - # A label attribute so that this depends on the internal rule - cc_binary = cc_binary, - # Redundant labels attributes so that the rule with this target name knows - # about everything it would know about if cc_and_something_else_binary - # were an actual rule instead of a macro. - csrcs = csrcs, - cdeps = cdeps) - -def _impl(ctx): - return struct([...], - # When instrumenting this rule, again hide implementation from - # users. - instrumented_files( - source_attributes = ["srcs", "csrcs"], - dependency_attributes = ["deps", "cdeps"])) - -_cc_and_something_else_binary = rule(implementation=_impl) -``` - - -## <a name="conditional-instantiation"></a>Conditional instantiation - -Macros can look at previously instantiated rules. This is done with -`native.existing_rule`, which returns information on a single rule defined in the same -`BUILD` file, eg., - -```python -native.existing_rule("descriptor_proto") -``` - -This is useful to avoid instantiating the same rule twice, which is an -error. For example, the following macro will simulate a test suite, -instantiating tests for diverse flavors of the same test. - -`extension.bzl`: - -```python -def system_test(name, test_file, flavor): - n = "system_test_%s_%s_test" % (test_file, flavor) - if native.existing_rule(n) == None: - native.py_test( - name = n, - srcs = [ "test_driver.py", test_file ], - args = [ "--flavor=" + flavor]) - return n - -def system_test_suite(name, flavors=["default"], test_files): - ts = [] - for flavor in flavors: - for test in test_files: - ts.append(system_test(name, test, flavor)) - native.test_suite(name = name, tests = ts) -``` - -In the following BUILD file, note how `(basic_test.py, fast)` is emitted for -both the `smoke` test suite and the `thorough` test suite. - -```python -load("//pkg:extension.bzl", "system_test_suite") - -# Run all files through the 'fast' flavor. -system_test_suite("smoke", flavors=["fast"], glob(["*_test.py"])) - -# Run the basic test through all flavors. -system_test_suite("thorough", flavors=["fast", "debug", "opt"], ["basic_test.py"]) -``` - - -## <a name="aggregation"></a>Aggregating over the BUILD file - -Macros can collect information from the BUILD file as processed so far. We call -this aggregation. The typical example is collecting data from all rules of a -certain kind. This is done by calling -<a href="lib/native.html#existing_rules">native.existing\_rules</a>, which -returns a dictionary representing all rules defined so far in the current BUILD -file. The dictionary has entries of the form `name` => `rule`, with the values -using the same format as `native.existing_rule`. - -```python -def archive_cc_src_files(tag): - """Create an archive of all C++ sources that have the given tag.""" - all_src = [] - for r in native.existing_rules().values(): - if tag in r["tags"] and r["kind"] == "cc_library": - all_src.append(r["srcs"]) - native.genrule(cmd = "zip $@ $^", srcs = all_src, outs = ["out.zip"]) -``` - -Since `native.existing_rules` constructs a potentially large dictionary, you should avoid -calling it repeatedly within BUILD file. - -## <a name="empty"></a>Empty rule - -Minimalist example of a rule that does nothing. If you build it, the target will -succeed (with no generated file). - -`empty.bzl`: - -```python -def _impl(ctx): - # You may use print for debugging. - print("This rule does nothing") - -empty = rule(implementation=_impl) -``` - -`BUILD`: - -```python -load("//pkg:empty.bzl", "empty") - -empty(name = "nothing") -``` - -## <a name="attr"></a>Rule with attributes - -Example of a rule that shows how to declare attributes and access them. - -`printer.bzl`: - -```python -def _impl(ctx): - # You may use print for debugging. - print("Rule name = %s, package = %s" % (ctx.label.name, ctx.label.package)) - - # This prints the labels of the deps attribute. - print("There are %d deps" % len(ctx.attr.deps)) - for i in ctx.attr.deps: - print("- %s" % i.label) - # A label can represent any number of files (possibly 0). - print(" files = %s" % [f.path for f in i.files]) - -printer = rule( - implementation=_impl, - attrs={ - # Do not declare "name": It is added automatically. - "number": attr.int(default = 1), - "deps": attr.label_list(allow_files=True), - }) -``` - -`BUILD`: - -```python -load("//pkg:printer.bzl", "printer") - -printer( - name = "nothing", - deps = [ - "BUILD", - ":other", - ], -) - -printer(name = "other") -``` - -If you execute this file, some information is printed as a warning by the -rule. No file is generated. - -## <a name="shell"></a>Simple shell command - -Example of a rule that runs a shell command on an input file specified by -the user. The output has the same name as the rule, with a `.size` suffix. - -While convenient, Shell commands should be used carefully. Generating the -command-line can lead to escaping and injection issues. It can also create -portability problems. It is often better to declare a binary target in a -BUILD file and execute it. See the example [executing a binary](#execute-bin). - -`size.bzl`: - -```python -def _impl(ctx): - output = ctx.outputs.out - input = ctx.file.file - # The command may only access files declared in inputs. - ctx.action( - inputs=[input], - outputs=[output], - progress_message="Getting size of %s" % input.short_path, - command="stat -L -c%%s %s > %s" % (input.path, output.path)) - -size = rule( - implementation=_impl, - attrs={"file": attr.label(mandatory=True, allow_files=True, single_file=True)}, - outputs={"out": "%{name}.size"}, -) -``` - -`foo.txt`: - -``` -Hello -``` - -`BUILD`: - -```python -load("//pkg:size.bzl", "size") - -size( - name = "foo_size", - file = "foo.txt", -) -``` - -## <a name="file"></a>Write string to a file - -Example of a rule that writes a string to a file. - -`file.bzl`: - -```python -def _impl(ctx): - output = ctx.outputs.out - ctx.file_action(output=output, content=ctx.attr.content) - -file = rule( - implementation=_impl, - attrs={"content": attr.string()}, - outputs={"out": "%{name}.txt"}, -) -``` - -`BUILD`: - -```python -load("//pkg:file.bzl", "file") - -file( - name = "hello", - content = "Hello world", -) -``` - - -## <a name="execute-bin"></a>Execute a binary - -This rule executes an existing binary. In this particular example, the -binary is a tool that merges files. During the analysis phase, we cannot -access any arbitrary label: the dependency must have been previously -declared. To do so, the rule needs a label attribute. In this example, we -will give the label a default value and make it private (so that it is not -visible to end users). Keeping the label private can simplify maintenance, -since you can easily change the arguments and flags you pass to the tool. - -`execute.bzl`: - -```python -def _impl(ctx): - # The list of arguments we pass to the script. - args = [ctx.outputs.out.path] + [f.path for f in ctx.files.srcs] - # Action to call the script. - ctx.action( - inputs=ctx.files.srcs, - outputs=[ctx.outputs.out], - arguments=args, - progress_message="Merging into %s" % ctx.outputs.out.short_path, - executable=ctx.executable._merge_tool) - -concat = rule( - implementation=_impl, - attrs={ - "srcs": attr.label_list(allow_files=True), - "out": attr.output(mandatory=True), - "_merge_tool": attr.label(executable=True, allow_files=True, - default=Label("//pkg:merge")) - } -) -``` - -Any executable target can be used. In this example, we will use a -`sh_binary` rule that concatenates all the inputs. - -`BUILD`: - -``` -load("execute", "concat") - -concat( - name = "sh", - srcs = [ - "header.html", - "body.html", - "footer.html", - ], - out = "page.html", -) - -# This target is used by the shell rule. -sh_binary( - name = "merge", - srcs = ["merge.sh"], -) -``` - -`merge.sh`: - -```python -#!/bin/bash - -out=$1 -shift -cat $* > $out -``` - -`header.html`: - -``` -<html><body> -``` - -`body.html`: - -``` -content -``` - -`footer.html`: - -``` -</body></html> -``` - -## <a name="execute"></a>Execute an input binary - -This rule has a mandatory `binary` attribute. It is a label that can refer -only to executable rules or files. - -`execute.bzl`: - -```python -def _impl(ctx): - # ctx.new_file is used for temporary files. - # If it should be visible for user, declare it in rule.outputs instead. - f = ctx.new_file(ctx.configuration.bin_dir, "hello") - # As with outputs, each time you declare a file, - # you need an action to generate it. - ctx.file_action(output=f, content=ctx.attr.input_content) - - ctx.action( - inputs=[f], - outputs=[ctx.outputs.out], - executable=ctx.executable.binary, - progress_message="Executing %s" % ctx.executable.binary.short_path, - arguments=[ - f.path, - ctx.outputs.out.path, # Access the output file using - # ctx.outputs.<attribute name> - ] - ) - -execute = rule( - implementation=_impl, - attrs={ - "binary": attr.label(cfg="host", mandatory=True, allow_files=True, - executable=True), - "input_content": attr.string(), - "out": attr.output(mandatory=True), - }, -) -``` - -`a.sh`: - -```bash -#!/bin/bash - -tr 'a-z' 'A-Z' < $1 > $2 -``` - -`BUILD`: - -```python -load("//pkg:execute.bzl", "execute") - -execute( - name = "e", - input_content = "some text", - binary = "a.sh", - out = "foo", -) -``` - -## <a name="runfiles"></a>Define simple runfiles - -`execute.bzl`: - -```python -def _impl(ctx): - executable = ctx.outputs.executable - # Create the output executable file with command as its content. - ctx.file_action( - output=executable, - content=ctx.attr.command, - executable=True) - - return struct( - # Create runfiles from the files specified in the data attribute. - # The shell executable - the output of this rule - can use them at runtime. - # It is also possible to define data_runfiles and default_runfiles. - # However if runfiles is specified it's not possible to define the above - # ones since runfiles sets them both. - # Remember, that the struct returned by the implementation function needs - # to have a field named "runfiles" in order to create the actual runfiles - # symlink tree. - runfiles=ctx.runfiles(files=ctx.files.data) - ) - -execute = rule( - implementation=_impl, - executable=True, - attrs={ - "command": attr.string(), - "data": attr.label_list(cfg="data", allow_files=True), - }, -) -``` - -`data.txt`: - -``` -Hello World! -``` - -`BUILD`: - -```python -load("//pkg:execute.bzl", "execute") - -execute( - name = "e", - # The path to data.txt has to include the package directories as well. I.e. - # if the BUILD file is under foo/BUILD and the data file is foo/data.txt - # then it needs to be referred as foo/data.txt in the command. - command = "cat data.txt", - data = [':data.txt'] -) -``` - -## <a name="late-bound"></a>Computed dependencies - -Bazel needs to know about all dependencies before doing the analysis phase and -calling the implementation function. Dependencies can be computed based on the -rule attributes: to do so, use a function as the default -value of an attribute (the attribute must be private and have type `label` or -`list of labels`). The parameters of this function must correspond to the -attributes that are accessed in the function body. - -Note: For legacy reasons, the function takes the configuration as an additional -parameter. Please do not rely on the configuration since it will be removed in -the future. - -The example below computes the md5 sum of a file. The file can be preprocessed -using a filter. The exact dependencies depend on the filter chosen by the user. - -`hash.bzl`: - -```python -_filters = { - "comments": Label("//pkg:comments"), - "spaces": Label("//pkg:spaces"), - "none": None, -} - -def _get_filter(filter, cfg=None): # requires attribute "filter" - # Return the value for the attribute "_filter_bin" - # It can be a label or None. - return _filters[filter] - -def _impl(ctx): - src = ctx.file.src - - if not ctx.attr._filter_bin: - # Skip the processing - processed = src - else: - processed = ctx.new_file(ctx.label.name + "_processed") - # Run the selected binary - ctx.action( - outputs = [processed], - inputs = [ctx.file.src], - progress_message="Apply filter '%s'" % ctx.attr.filter, - arguments = [ctx.file.src.path, processed.path], - executable = ctx.executable._filter_bin) - - # Compute the hash - out = ctx.outputs.text - ctx.action( - outputs = [out], - inputs = [processed], - command = "md5sum < %s > %s" % (processed.path, out.path)) - -hash = rule( - implementation=_impl, - attrs={ - "filter": attr.string(values=_filters.keys(), default="none"), - "src": attr.label(mandatory=True, single_file=True, allow_files=True), - "_filter_bin": attr.label(default=_get_filter, executable=True), - }, - outputs = {"text": "%{name}.txt"}) -``` - -`BUILD`: - -```python -load("//pkg:hash.bzl", "hash") - -hash( - name = "hash", - src = "hello.txt", - filter = "spaces", -) - -sh_binary( - name = "comments", - srcs = ["comments.sh"], -) - -sh_binary( - name = "spaces", - srcs = ["spaces.sh"], -) -``` - -`hello.txt`: - -``` -Hello World! -``` - -`comments.sh`: - -``` -#!/bin/bash -grep -v '^ *#' $1 > $2 # Remove lines with only a Python-style comment -``` - -`spaces.sh`: - -``` -#!/bin/bash -tr -d ' ' < $1 > $2 # Remove spaces -``` - -## <a name="mandatory-providers"></a>Mandatory providers - -In this example, rules have a `number` attribute. Each rule adds its -number with the numbers of its transitive dependencies, and write the -result in a file. This shows how to transfer information from a dependency -to its dependents. - -`sum.bzl`: - -```python -def _impl(ctx): - result = ctx.attr.number - for i in ctx.attr.deps: - result += i.number - ctx.file_action(output=ctx.outputs.out, content=str(result)) - - # Fields in the struct will be visible by other rules. - return struct(number=result) - -sum = rule( - implementation=_impl, - attrs={ - "number": attr.int(default=1), - # All deps must provide all listed providers. - "deps": attr.label_list(providers=["number"]), - }, - outputs = {"out": "%{name}.sum"} -) -``` - -`BUILD`: - -```python -load("//pkg:sum.bzl", "sum") - -sum( - name = "n", - deps = ["n2", "n5"], -) - -sum( - name = "n2", - number = 2, -) - -sum( - name = "n5", - number = 5, -) -``` - -## <a name="optional-providers"></a>Optional providers - -This is a similar example, but dependencies may not provide a number. - -`sum.bzl`: - -```python -def _impl(ctx): - result = ctx.attr.number - for i in ctx.attr.deps: - if hasattr(i, "number"): - result += i.number - ctx.file_action(output=ctx.outputs.out, content=str(result)) - - # Fields in the struct will be visible by other rules. - return struct(number=result) - -sum = rule( - implementation=_impl, - attrs={ - "number": attr.int(default=1), - "deps": attr.label_list(), - }, - outputs = {"out": "%{name}.sum"} -) -``` - -`BUILD`: - -```python -load("//pkg:sum.bzl", "sum") - -sum( - name = "n", - deps = ["n2", "n5"], -) - -sum( - name = "n2", - number = 2, -) - -sum( - name = "n5", - number = 5, -) -``` - -## <a name="outputs-executable"></a>Default executable output - -This example shows how to create a default executable output. - -`extension.bzl`: - -```python -def _impl(ctx): - ctx.file_action( - # Access the executable output file using ctx.outputs.executable. - output=ctx.outputs.executable, - content="#!/bin/bash\necho Hello!", - executable=True - ) - # The executable output is added automatically to this target. - -executable_rule = rule( - implementation=_impl, - executable=True -) -``` - -`BUILD`: - -```python -load("//pkg:extension.bzl", "executable_rule") - -executable_rule(name = "my_rule") -``` - -## <a name="outputs-default"></a>Default outputs - -This example shows how to create default outputs for a rule. - -`extension.bzl`: - -```python -def _impl(ctx): - ctx.file_action( - # Access the default outputs using ctx.outputs.<output name>. - output=ctx.outputs.my_output, - content="Hello World!" - ) - # The default outputs are added automatically to this target. - -rule_with_outputs = rule( - implementation=_impl, - outputs = { - # %{name} is substituted with the rule's name - "my_output": "%{name}.txt" - } -) -``` - -`BUILD`: - -```python -load("//pkg:extension.bzl", "rule_with_outputs") - -rule_with_outputs(name = "my_rule") -``` - -## <a name="outputs-custom"></a>Custom outputs - -This example shows how to create custom (user defined) outputs for a rule. -This rule takes a list of output file name templates from the user and -creates each of them containing a "Hello World!" message. - -`extension.bzl`: - -```python -def _impl(ctx): - # Access the custom outputs using ctx.outputs.<attribute name>. - for output in ctx.outputs.outs: - ctx.file_action( - output=output, - content="Hello World!" - ) - # The custom outputs are added automatically to this target. - -rule_with_outputs = rule( - implementation=_impl, - attrs={ - "outs": attr.output_list() - } -) -``` - -`BUILD`: - -```python -load("//pkg:extension.bzl", "rule_with_outputs") - -rule_with_outputs( - name = "my_rule", - outs = ["my_output.txt"] -) -``` - -## <a name="master-rule"></a>Master rules - -This example shows how to create master rules to bind other rules together. The -code below uses genrules for simplicity, but this technique is more useful with -other rules. For example, if you need to compile C++ files, you can reuse -`cc_library`. - -`extension.bzl`: - -```python -def _impl(ctx): - # Aggregate the output files from the depending rules - files = set() - files += ctx.attr.dep_rule_1.files - files += ctx.attr.dep_rule_2.files - return struct(files=files) - -# This rule binds the depending rules together -master_rule = rule( - implementation=_impl, - attrs={ - "dep_rule_1": attr.label(), - "dep_rule_2": attr.label() - } -) - -def macro(name, cmd, input): - # Create the depending rules - name_1 = name + "_dep_1" - name_2 = name + "_dep_2" - native.genrule( - name = name_1, - cmd = cmd, - outs = [name_1 + ".txt"] - ) - native.genrule( - name = name_2, - cmd = "echo " + input + " >$@", - outs = [name_2 + ".txt"] - ) - # Create the master rule - master_rule( - name = name, - dep_rule_1 = ":" + name_1, - dep_rule_2 = ":" + name_2 - ) -``` - -`BUILD`: - -```python -load("//pkg:extension.bzl", "macro") - -# This creates the target :my_rule -macro( - name = "my_rule", - cmd = "echo something > $@", - input = "Hello World" -) -``` - -## <a name="debugging-tips"></a>Debugging tips - -Here are some examples on how to debug macros and rules using -<a href="lib/globals.html#print">print</a>. - -`debug.bzl`: - -```python -print("print something when the module is loaded") - -def _impl(ctx): - print("print something when the rule implementation is executed") - print(type("abc")) # prints string, the type of "abc" - print(dir(ctx)) # prints all the fields and methods of ctx - print(dir(ctx.attr)) # prints all the attributes of the rule - # prints the objects each separated with new line - print("object1", "object2", sep="\n") - -debug = rule(implementation=_impl) -``` - -`BUILD`: - -```python -load("//pkg:debug.bzl", "debug") - -debug( - name = "printing_rule" -) -``` diff --git a/site/versions/master/docs/skylark/deploying.md b/site/versions/master/docs/skylark/deploying.md deleted file mode 100644 index ad0831ccff..0000000000 --- a/site/versions/master/docs/skylark/deploying.md +++ /dev/null @@ -1,144 +0,0 @@ ---- -layout: documentation -title: Deploying new Skylark rules ---- -# Deploying new Skylark rules - -This documentation is for Skylark rule writers who are planning to make their -rules available to others. - -## Where to put new rules - -In general, new rules should go into their own GitHub repository under your -organization. Contact the [bazel-dev mailing -list](https://groups.google.com/forum/#!forum/bazel-dev) if you feel like your -rules belong in the bazelbuild organization. - -You can see lots of examples of what your repository should look like on GitHub: -see all of the repositories named `rules_whatever`. In particular, -[rules_scala](https://github.com/bazelbuild/rules_scala) is a nice example of -how to set up your repo. - -Rules can be grouped either by language (e.g., Scala) or some notion of platform -(e.g., Android). - -## What a rule repository should contain - -Every rule repository should have a certain layout so that users can quickly -understand new rules. - -For example, suppose we are writing new Skylark rules for the (make-believe) -chaiscript language. We would have the following structure: - -``` -.travis.yml -README.md -WORKSPACE -chaiscript/ - BUILD - chaiscript.bzl -tests/ - BUILD - some_test.sh - another_test.py -examples/ - BUILD - bin.chai - lib.chai - test.chai -``` - -### README.md - -At the top level, there should be a README.md that contains (at least) what -users will need to copy-paste into their WORKSPACE file to use your rule. -In general, this will be a `git_repository` pointing to your GitHub repo and -a macro call that downloads/configures any tools your rule needs. For example, -for the [Go -rules](https://github.com/bazelbuild/rules_go/blob/master/README.md#setup), this -looks like: - -``` -git_repository( - name = "io_bazel_rules_go", - remote = "https://github.com/bazelbuild/rules_go.git", - tag = "0.0.2", -) -load("@io_bazel_rules_go//go:def.bzl", "go_repositories") - -go_repositories() -``` - -If your rules depend on another repository's rules, specify both in the -`README.md` (see the [Skydoc rules](https://github.com/bazelbuild/skydoc#setup), -which depend on the Sass rules, for an example of this). - -### Tests - -There should be tests that verify that the rules are working as expected. This -can either be in the standard location for the language the rules are for or a -`tests/` directory at the top level. - -### Optional: Examples - -It is useful to users to have an `examples/` directory that shows users a couple -of basic ways that the rules can be used. - -## Testing - -Set up Travis as described in their [getting started -docs](https://docs.travis-ci.com/user/getting-started/). Then add a -`.travis.yml` file to your repository with the following content: - -``` -language: - - java -jdk: - - oraclejdk8 # Building Bazel requires JDK8. -before_install: - - wget https://github.com/bazelbuild/bazel/archive/0.3.0.zip # Replace with desired version - - unzip 0.3.0.zip - - cd bazel-0.3.0 - - ./compile.sh - - sudo cp output/bazel /usr/bin/bazel - - cd .. - - rm -rf bazel-0.3.0 -script: - - bazel build //... - - bazel test //... -``` - -Right now Bazel has to be compiled from source, as Travis does not support a -version of GCC that works with the precompiled Bazel binaries. Thus, the -`before_install` steps download the Bazel source, compile it, and "install" the -Bazel binary in /usr/bin. - -If your repository is under the [bazelbuild organization](https://github.com/bazelbuild), -contact the [bazel-dev](https://groups.google.com/forum/#!forum/bazel-dev) list -to have it added to [ci.bazel.io](http://ci.bazel.io). - -## Documentation - -See the [Skydoc documentation](https://github.com/bazelbuild/skydoc) for -instructions on how to comment your rules so that documentation can be generated -automatically. - -## FAQs - -### Why can't we add our rule to the Bazel GitHub repository? - -We want to decouple rules from Bazel releases as much as possible. It's clearer -who owns individual rules, reducing the load on Bazel developers. For our users, -decoupling makes it easier to modify, upgrade, downgrade, and replace rules. -Contributing to rules can be lighter weight than contributing to Bazel - -depending on the rules -, including full submit access to the corresponding -GitHub repository. Getting submit access to Bazel itself is a much more involved -process. - -The downside is a more complicated one-time installation process for our users: -they have to copy-paste a rule into their WORKSPACE file, as shown in the -README section above. - -We used to have all of the Skylark rules in the Bazel repository (under -`//tools/build_rules` or `//tools/build_defs`). We still have a couple rules -there, but we are working on moving the remaining rules out. diff --git a/site/versions/master/docs/skylark/index.md b/site/versions/master/docs/skylark/index.md deleted file mode 100644 index b7d46a56f4..0000000000 --- a/site/versions/master/docs/skylark/index.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -layout: documentation -title: Extensions ---- - -# Extensions -Skylark is the name of the extension mechanism in Bazel. It lets you add support -for new languages and tools by writing [custom build rules](rules.md). You can -also compose existing rules into [macros](macros.md). - -## Getting started - -Read the [concepts](concepts.md) behind Skylark and try the -[cookbook examples](cookbook.md). To go further, read about the -[standard library](lib/globals.html). - diff --git a/site/versions/master/docs/skylark/macros.md b/site/versions/master/docs/skylark/macros.md deleted file mode 100644 index 6242af8d1a..0000000000 --- a/site/versions/master/docs/skylark/macros.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -layout: documentation -title: Macros ---- -# Macros - -## Macro creation - -A macro is a function called from the BUILD file that can instantiate rules. -Macros don't give additional power, they are just used for encapsulation and -code reuse. By the end of the loading phase, macros don't exist anymore, and -Bazel sees only the set of rules they created. - -Native rules can be instantiated from the `native` module, e.g. - -```python -def my_macro(name, visibility=None): - native.cc_library( - name = name, - srcs = ["main.cc"], - visibility = visibility, - ) -``` - -If you need to know the package name (i.e. which BUILD file is calling the -macro), use the constant [PACKAGE_NAME](lib/globals.html#PACKAGE_NAME). - -## Examples - -* [Macro creating rules](cookbook.md#macro). - -* [Macro creating native rules](cookbook.md#macro_native). - -* [Macro combining multiple rules](cookbook.md#macro_compound). - -## Debugging - -* `bazel query --output=build //my/path:all` will show you how the BUILD -file looks like after evaluation. All macros, globs, loops are expanded. - -* You can also use [print](lib/globals.html#print) for debugging. It displays -the message as a warning during the loading phase. Except in rare cases, remove -your `print` calls before submitting the code to the depot. - -## Errors - -If you want to throw an error, use the [fail](lib/globals.html#fail) function. -Explain clearly to the user what went wrong and how to fix their BUILD file. It -is not possible to catch an error. - -``` -def my_macro(name, deps, visibility=None): - if len(deps) < 2: - fail("Expected at least two values in deps") - # ... -``` - -## Conventions - -* All public functions (functions that don't start with underscore) that -instantiate rules must have a `name` argument. This argument should not be -optional (don't give a default value). - -* Public functions should use a docstring following [Python - conventions](https://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Comments#Comments). - -* In BUILD files, the `name` argument of the macros must be a keyword - argument (not a positional argument). - -* The `name` attribute of rules generated by a macro should include the name - argument as a prefix. For example, `macro(name = "foo")` can generate a - `cc_library` `foo` and a genrule `foo_gen`. - -* In most cases, optional parameters should have a default value of `None`. - `None` can be passed directly to native rules, which treat it the same as if - you had not passed in any argument. Thus, there is no need to replace it with - `0`, `False`, or `[]` for this purpose. Instead, the macro should defer to the - rules it creates, as their defaults may be complex or may change over time. - Additionally, a parameter that is explicitly set to its default value looks - different than one that is never set (or set to `None`) when accessed through - the query language or build-system internals. - -* Macros should have an optional `visibility` argument. - -## Full example - -The typical use-case for a macro is when you want to reuse a genrule, e.g. - -``` -genrule( - name = "file", - outs = ["file.txt"], - cmd = "$(location generator) some_arg > $@", - tools = [":generator"], -) -``` - -If you want to generate another file with different arguments, you may want to -extract this code to a function. - -The BUILD file will become simply: - -``` -load("//path:generator.bzl", "file_generator") - -file_generator( - name = "file", - arg = "some_arg", -) -``` - -In order to keep BUILD files clean and declarative, you must put the function in -a separate `.bzl` file. For example, write the definition of the macro in -`path/generator.bzl`: - -``` -def file_generator(name, arg, visibility=None): - native.genrule( - name = name, - outs = [name + ".txt"], - cmd = "$(location generator) %s > $@" % arg, - tools = ["//test:generator"], - visibility = visibility, - ) -``` - -When you want to investigate what a macro does, use the following command to -see the expanded form: - -``` -$ bazel query --output=build :file -# /absolute/path/test/ext.bzl:42:3 -genrule( - name = "file", - tools = ["//test:generator"], - outs = ["//test:file.txt"], - cmd = "$(location generator) some_arg > $@", -) -``` - diff --git a/site/versions/master/docs/skylark/repository_rules.md b/site/versions/master/docs/skylark/repository_rules.md deleted file mode 100644 index 762069d95d..0000000000 --- a/site/versions/master/docs/skylark/repository_rules.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -layout: documentation -title: Repository Rules ---- -# Repository Rules - -**Status: Experimental**. We may make breaking changes to the API, but we will - announce them and help you update your code. - -An [external repository](/docs/external.md) is a rule that can be used only -in the `WORKSPACE` file and enable non-hermetic operation at the loading phase -of Bazel. Each external repository rule creates its own workspace, with its -own BUILD files and artifacts. They can be used to depend on third-party -libraries (such as Maven packaged libraries) but also to generate BUILD files -specific to the host Bazel is running on. - -## Repository Rule creation - -In a `.bzl` file, use the -[repository_rule](lib/globals.html#repository_rule) function to create a new -repository rule and store it in a global variable. - -A custom repository rule can be used just like a native repository rule. It -has a mandatory `name` attribute and every target present in its build files -can be refered as `@<name>//package:target` where `<name>` is the value of the -`name` attribute. - -The rule is loaded when you explictly build it, or if it is a dependency of -the build. In this case, Bazel will execute its `implementation` function. This -function describe how to creates the repository, its content and BUILD files. - -## Attributes - -An attribute is a rule argument, such as `url` or `sha256`. You must list -the attributes and their types when you define a repository rule. - -```python -local_repository = repository_rule( - implementation=_impl, - local=True, - attrs={"path": attr.string(mandatory=True)}) -``` - -`name` attributes are implicitely defined for all `repository_rule`s. -To access an attribute, use `repository_ctx.attr.<attribute_name>`. -The name of a repository rule is accessible with `repository_ctx.name`. - -If an attribute name starts with `_` it is private and users cannot set it. - -## Implementation function - -Every repository rule requires an `implementation` function. It contains the -actual logic of the rule and is executed strictly in the Loading Phase. -The function has exactly one input parameter, `repository_ctx`, and should -always returns `None`. The input parameter `repository_ctx` can be used to -access attribute values, and non-hermetic functions (finding a binary, -exuting a binary, creating a file in the repository or downloading a file -from the Internet). See [the library](lib/repository_ctx.html) for more -context. Example: - -```python -def _impl(repository_ctx): - repository_ctx.symlink(repository_ctx.attr.path, "") - -local_repository = repository_rule( - implementation=_impl, - ...) -``` - -## Examples - -For now, we only have one full example of usage of the `repository_rule`: -[C++ auto-configured toolchain](https://github.com/bazelbuild/bazel/blob/9116b3e99af2fd31d92c9bb7c37905a1675456c1/tools/cpp/cc_configure.bzl#L288). - -This example uses a repository rule to automatically create the -C++ configuration files for Bazel by looking for the local C++ compiler, the -environment and the flags the C++ compiler supports. - diff --git a/site/versions/master/docs/skylark/rules.md b/site/versions/master/docs/skylark/rules.md deleted file mode 100644 index c2f191423f..0000000000 --- a/site/versions/master/docs/skylark/rules.md +++ /dev/null @@ -1,460 +0,0 @@ ---- -layout: documentation -title: Rules ---- -# Rules - -**Status: Experimental**. We may make breaking changes to the API, but we will - help you update your code. - -A rule defines a series of actions that Bazel should perform on inputs to get a -set of outputs. For example, a C++ binary rule might take a set of .cpp -files (the inputs), run `g++` on them (the action), and return an executable -file (the output). - -Note that, from Bazel's perspective, `g++` and the standard C++ libraries are -also inputs to this rule. As a rule writer, you must consider not only the -user-provided inputs to a rule, but also all of the tools and libraries required -to execute the actions (called _implicit inputs_). - -## Rule creation - -In a `.bzl` file, use the [rule](lib/globals.html#rule) -function to create a new rule and store it in a global variable: - -```python -my_rule = rule(...) -``` - -See [the cookbook](cookbook.md#empty) for examples. The rule can then be -loaded by BUILD files: - -```python -load('//some/pkg:whatever.bzl', 'my_rule') -``` - -A custom rule can be used just like a native rule. It has a mandatory `name` -attribute, you can refer to it with a label, and you can see it in -`bazel query`. - -The rule is analyzed when you explictly build it, or if it is a dependency of -the build. In this case, Bazel will execute its `implementation` function. This -function decides what the outputs of the rule are and how to build them (using -`actions`). During analysis, no external command can be executed: actions will -be run in the execution phase. - -## Attributes - -An attribute is a rule argument, such as `srcs` or `deps`. You must list -the attributes and their types when you define a rule. - -```python -sum = rule( - implementation = impl, - attrs = { - "number": attr.int(default = 1), - "deps": attr.label_list(), - }, -) -``` - -The following attributes are implicitly added to every rule: `deprecation`, -`features`, `name`, `tags`, `testonly`, `visibility`. Test rules also have the -following attributes: `args`, `flaky`, `local`, `shard_count`, `size`, -`timeout`. - -Labels listed in `attr` will be inputs to the rule. - -To access an attribute in a rule's implementation, use -`ctx.attr.<attribute_name>`. The name and the package of a rule are available -with `ctx.label.name` and `ctx.label.package`. - -See [an example](cookbook.md#attr) of using `attr` in a rule. - -### <a name="private-attributes"></a> Private Attributes - -If an attribute name starts with `_` it is private and users cannot set it. It -is useful in particular for label attributes (your rule will have an -implicit dependency on this label). - -```python -metal_compile = rule( - implementation=impl, - attrs={ - "srcs": attr.label_list(), - "_compiler": attr.label( - default=Label("//tools:metalc"), - allow_single_file=True, - executable=True, - ), - }, -) -``` - -## Implementation function - -Every rule requires an `implementation` function. It contains the actual -logic of the rule and is executed strictly in the Analysis Phase. The function -has exactly one input parameter, `ctx`, and it may return -the [runfiles](#runfiles) and [providers](#providers) -of the rule. The input parameter `ctx` can be used to access attribute values, -outputs and dependent targets, and files. It also has some helper functions. -See [the library](lib/ctx.html) for more context. Example: - -```python -def impl(ctx): - ... - return struct( - runfiles=..., - my_provider=..., - ... - ) - -my_rule = rule( - implementation=impl, - ... -) -``` - -## Files - -There are two kinds of files: files stored in the file system and generated -files. For each generated file, there must be one and only one generating -action, and each action must generate one or more output files. Bazel will throw -an error otherwise. - -## Targets - -Every build rule corresponds to exactly one target. A target can create -[actions](#actions), can have dependencies (which can be files or -other build rules), [output files](#output-files) (generated by -its actions), and [providers](#providers). - -A target `y` depends on target `x` if `y` has a label or label list type -attribute where `x` is declared: - -```python -my_rule( - name = "x", -) - -my_rule( - name = "y", - deps = [":x"], -) -``` - -In the above case, it's possible to access targets declared in `my_rule.deps`: - -```python -def impl(ctx): - for dep in ctx.attr.deps: - # Do something with dep - ... - -my_rule = rule( - implementation=impl, - attrs={ - "deps": attr.label_list(), - }, - ... -) -``` - -## <a name="output-files"></a> Output files - -A target can declare output files, which must be generated by the target's -actions. There are three ways to create output files: - -* If the rule is marked `executable`, it creates an output file of the same name - as the rule's. [See example](cookbook.md#outputs-executable) - -* The rule can declare default `outputs`, which are always generated. - [See example](cookbook.md#outputs-default) - -* The rule can have output or output list type attributes. In that case the - output files come from the actual attribute values. - [See example](cookbook.md#outputs-custom) - -Each output file must have exactly one generating action. See the -[library](lib/ctx.html#outputs) for more context. - -## Default outputs - -Every rule has a set of default outputs. This is used: - -* When the user runs `bazel build` on your target. Bazel will build the default - outputs of the rule. - -* When the target is used as a dependency of another rule. A rule can access - the default outputs by using [target.files](lib/Target.html#files). - This is the case, for example, if you use a rule in the `srcs` attribute of a - `genrule`. - -Use the `files` provider to specify the default outputs of a rule. -If left unspecified, it will contain all the declared outputs. - -```python -def _impl(ctx): - # ... - return struct(files=set([file1, file2])) -``` - -This can be useful for exposing files generated with -[ctx.new_file](lib/ctx.html#new_file). You can also have "implicit -outputs", i.e., files that are declared in the rule, but not in the default -outputs (like `_deploy.jar` in `java_binary`). - -## Actions - -There are three ways to create actions: - -* [ctx.action](lib/ctx.html#action), to run a command. -* [ctx.file_action](lib/ctx.html#file_action), to write a string to a file. -* [ctx.template_action](lib/ctx.html#template_action), to generate a file from a template. - -Actions take a set (which can be empty) of input files and generate a (non-empty) -set of output files. -The set of input and output files must be known during the analysis phase. It -might depend on the value of attributes and information from dependencies, but -it cannot depend on the result of the execution. For example, if your action -runs the unzip command, you must specify which files you expect to be inflated -(before running unzip). - -Actions are comparable to pure functions: They should depend only on the -provided inputs, and avoid accessing computer information, username, clock, -network, or I/O devices (except for reading inputs and writing outputs). - -**If an action generates a file that is not listed in its outputs**: This is -fine, but the file will be ignored and cannot be used by other rules. - -**If an action does not generate a file that is listed in its outputs**: This is -an execution error and the build will fail. This happens for instance when a -compilation fails. - -**If an action generates an unknown number of outputs and you want to keep them -all**, you must group them in a single file (e.g., a zip, tar, or other -archive format). This way, you will be able to deterministically declare your -outputs. - -**If an action does not list a file it uses as an input**, the action execution -will most likely result in an error. The file is not guaranteed to be available -to the action, so if it **is** there, it's due to coincidence or error. - -**If an action lists a file as an input, but does not use it**: This is fine. -However, it can affect action execution order, resulting in sub-optimal -performance. - -Dependencies are resolved by Bazel, which will decide which actions are -executed. It is an error if there is a cycle in the dependency graph. Creating -an action does not guarantee that it will be executed: It depends on whether -its outputs are needed for the build. - -## Configurations - -By default, a target is built in the target configuration. For each label -attribute, you can decide whether the dependency should be built in the same -configuration, or in the host configuration. - -In general, sources, dependent libraries, and executables that will be needed at -runtime can use the same configuration. - -Tools that are executed as part of the build (e.g., compilers, code generators) -should be built for the host configuration. In this case, specify `cfg="host"` -in the attribute. - -The configuration `"data"` is present for legacy reasons and should be used for -the `data` attributes. - - -## <a name="fragments"></a> Configuration Fragments - -Rules may access configuration fragments such as `cpp`, `java` and `jvm`. -However, all required fragments must be declared in order to avoid access -errors: - -```python -def impl(ctx): - # Using ctx.fragments.cpp would lead to an error since it was not declared. - x = ctx.fragments.java - ... - -my_rule = rule( - implementation=impl, - fragments=["java"], # Required fragments of the target configuration - host_fragments=["java"], # Required fragments of the host configuration - ... -) -``` - -`ctx.fragments` only provides configuration fragments for the target -configuration. If you want to access fragments for the host configuration, -use `ctx.host_fragments` instead. - -## Providers - -Providers are used to access information from other rules. A rule depending on -another rule has access to the data the latter provides. These data can be e.g. -output files, the libraries the dependent rule is using to link or compile, or -anything the depending rule should know about. Using providers is the only way -to exchange data between rules. - -A rule can only access data provided by its direct dependencies, not that of -transitive dependencies: if rule `top` depends on `middle`, and `middle` depends -on `bottom`, then `middle` is a direct dependency of `top` and `bottom` is a -transitive dependency of `top`. In this scenario `top` can only access data -provided by `middle`. If `middle` also provides the data that `bottom` provided -to it, then and only then can `top` access it. - -The following data types can be passed using providers: - -* `bool` -* `integer` -* `string` -* `file` -* `label` -* `None` -* anything composed of these types and `lists`, `dicts`, `sets` or `structs` - -Providers are created from the return value of the rule implementation function: - -```python -def rule_implementation(ctx): - ... - return struct( - transitive_data=set(["a", "b", "c"]) - ) -``` - -A dependent rule might access these data as struct fields of the `target` being -dependened upon: - -```python -def dependent_rule_implementation(ctx): - ... - s = set() - for dep_target in ctx.attr.deps: - # Use `print(dir(dep_target))` to see the list of providers. - s += dep_target.transitive_data - ... -``` - -Providers are only available during the analysis phase. Examples of usage: - -* [mandatory providers](cookbook.md#mandatory-providers) -* [optional providers](cookbook.md#optional-providers) - -## Runfiles - -Runfiles are a set of files used by the (often executable) output of a rule -during runtime (as opposed to build time, i.e. when the binary itself is -generated). -During execution, Bazel creates a directory tree containing symlinks pointing to -the runfiles, staging the environment for the binary so it can access the -runfiles during runtime. - -Runfiles can be added manually during rule creation and/or collected -transitively from the rule's dependencies: - -```python -def rule_implementation(ctx): - ... - transitive_runfiles = set() - for dep in ctx.attr.special_dependencies: - transitive_runfiles += dep.transitive_runtime_files - - runfiles = ctx.runfiles( - # Add some files manually. - files=[ctx.file.some_data_file], - # Add transitive files from dependencies manually. - transitive_files=transitive_runfiles, - # Collect runfiles from the common locations: transitively from srcs, - # deps and data attributes. - collect_default=True, - ) - # Add a field named "runfiles" to the return struct in order to actually - # create the symlink tree. - return struct(runfiles=runfiles) -``` - -Note that non-executable rule outputs can also have runfiles. For example, a -library might need some external files during runtime, and every dependent -binary should know about them. - -Also note that if an action uses an executable, the executable's runfiles can -be used when the action executes. - -Normally, the relative path of a file in the runfiles tree is the same as the -relative path of that file in the source tree or generated output tree. If these -need to be different for some reason, you can specify the `root_symlinks` or -`symlinks` arguments. The `root_symlinks` is a dictionary mapping paths to -files, where the paths are relative to the root of the runfiles directory. The -`symlinks` dictionary is the same, but paths are implicitly prefixed with the -name of the workspace. - -```python - ... - runfiles = ctx.runfiles( - root_symlinks={"some/path/here.foo": ctx.file.some_data_file2} - symlinks={"some/path/here.bar": ctx.file.some_data_file3} - ) - # Creates something like: - # sometarget.runfiles/ - # some/ - # path/ - # here.foo -> some_data_file2 - # <workspace_name>/ - # some/ - # path/ - # here.bar -> some_data_file3 -``` - -If `symlinks` or `root_symlinks` is used, be careful not to map two different -files to the same path in the runfiles tree. This will cause the build to fail -with an error describing the conflict. To fix, you will need to modify your -`ctx.runfiles` arguments to remove the collision. This checking will be done for -any targets using your rule, as well as targets of any kind that depend on those -targets. - -## Instrumented files - -Instrumented files are a set of files used by the coverage command. A rule can -use the `instrumented_files` provider to provide information about which files -should be used for measuring coverage. - -```python -def rule_implementation(ctx): - ... - return struct(instrumented_files=struct( - # Optional: File extensions used to filter files from source_attributes. - # If not provided, then all files from source_attributes will be - # added to instrumented files, if an empty list is provided, then - # no files from source attributes will be added. - extensions=["ext1", "ext2"], - # Optional: Attributes that contain source files for this rule. - source_attributes=["srcs"], - # Optional: Attributes for dependencies that could include instrumented - # files. - dependency_attributes=["data", "deps"])) -``` - -## Executable rules - -An executable rule is a rule that users can run using `bazel run`. - -To make a rule executable, set `executable=True` in the -[rule function](lib/globals.html#rule). During the analysis -phase, the rule must generate the output file `ctx.outputs.executable`. -[See example](cookbook.md#outputs-executable) - -## Test rules - -Test rules are run using `bazel test`. - -To create a test rule, set `test=True` in the -[rule function](lib/globals.html#rule). The name of the rule must -also end with `_test`. Test rules are implicitly executable, which means they -must generate the output file `ctx.outputs.executable`. - -Test rules inherit the following attributes: `args`, `flaky`, `local`, -`shard_count`, `size`, `timeout`. diff --git a/site/versions/master/docs/support.md b/site/versions/master/docs/support.md deleted file mode 100644 index 7946ddddbd..0000000000 --- a/site/versions/master/docs/support.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -layout: documentation -title: Get Support ---- - -# Get Support - -* [User mailing list](https://groups.google.com/forum/#!forum/bazel-discuss) -* [Issue tracker](https://github.com/bazelbuild/bazel/issues) -* [Twitter](http://www.twitter.com/bazelbuild) -* [IRC](irc://irc.freenode.net/bazel) (freenode.net#bazel) - -# Support Policy - -We generally avoid making backwards-incompatible changes. We have several years of experience with -supporting a huge code base that is concurrently worked on by thousands of engineers every day, -and have successfully made significant changes to the core as well as to the rules without missing -a beat. We run hundreds of thousands of tests at Google before every single release to ensure that -it stays that way. - -That said, we occasionally have to make incompatible changes in order to fix bugs, to make further -improvements to the system, such as improving performance or usability, or to lock down APIs that -are known to be brittle. - -This document gives an overview of features that are widely used and that we consider stable. By -stable, we mean that the changes we make will be backwards compatible, or that we will provide a -migration path. - -It also covers features that are unstable. Either they are not yet widely used, or we are already -planning to change them significantly, possibly in ways that are not backwards compatible. - -We cannot cover everything that might change, but you can reasonably expect that we provide -advance notice on the mailing list before a major change happens. We're also happy to provide more -details, just ask on [bazel-discuss](https://groups.google.com/forum/#!forum/bazel-discuss). - -All undocumented features (attributes, rules, "Make" variables, and flags) are subject to change -at any time without prior notice. Features that are documented but marked *experimental* are also -subject to change at any time without prior notice. - -Bazel's extension language Skylark (anything you write in a `.bzl` file) is still subject to change. -We are in the process of migrating Google to Skylark, and expect the language part to extend macros -to stabilize as part of that process. Adding rules with skylark is still somewhat experimental. - -Help keep us honest: report bugs and regressions in the -[GitHub bugtracker](https://github.com/bazelbuild/bazel/issues). We will make an effort to triage all -reported issues within 2 business days. - -## Releases - -We regularly publish [binary releases of Bazel](https://github.com/bazelbuild/bazel/releases). To -that end, we announce release candidates on -[bazel-discuss](https://groups.google.com/forum/#!forum/bazel-discuss); these are binaries that have -passed all of our unit tests. Over the next few days, we regression test all applicable build -targets at Google. If you have a critical project using Bazel, we recommend that you establish an -automated testing process that tracks the current release candidate, and report any regressions. - -If no regressions are discovered, we officially release the candidate after a week. However, -regressions can delay the release of a release candidate. If regressions are found, we apply -corresponding cherry-picks to the release candidate to fix those regressions. If no further -regressions are found for two business days, but not before a week has elapsed since the first -release candidate, we release it. - -### Release versioning - -Version 0.1 is our first release marking the start of our beta phase. Until version 1.0.0, we -increase the MINOR version every time we reach a [new milestone](http://bazel.io/roadmap.html). - -Version 1.0.0 marks the end of our beta phase; afterwards, we will label each release with a -version number of the form MAJOR.MINOR.PATCH according to the -[semantic version 2.0.0 document](http://semver.org). - -## Current Status - -### Built-In Rules and the Internal API For Rules ### -We are planning a number of changes to the APIs between the core of Bazel and the built-in rules, -in order to make it easier for us to develop openly. This has the added benefit of also making it -easier for users to maintain their own rules (if written in Java instead of Skylark), if they don't -want to or cannot check this code into our repository. However, it also means our internal API is -not stable yet. In the long term, we want to move to Skylark wholesale, so we encourage contributors -to use Skylark instead of Java when writing new rules. Rewriting all of our built-in rules is going -to be a lengthy process however. - -1. We will fix the friction points that we know about, as well as those that we discover every time - we make changes that span both the internal and external depots. -2. We will drive a number of pending API cleanups to completion, as well as run anticipated cleanups - to the APIs, such as disallowing access to the file system from rule implementations (because - it's not hermetic). -3. We will enumerate the internal rule APIs, and make sure that they are appropriately marked (for - example with annotations) and documented. Just collecting a list will likely give us good - suggestions for further improvements, as well as opportunities for a more principled API review - process. -4. We will automatically check rule implementations against an API whitelist, with the intention - that API changes are implicitly flagged during code review. -5. We will work on removing (legacy) Google-internal features to reduce the amount of differences - between the internal and external rule sets. -6. We will encourage our engineers to make changes in the external depot first, and migrate them to - to the internal one afterwards. -7. We will move more of our rule implementations into the open source repository (Android, Go, - Python, the remaining C++ rules), even if we don't consider the code to be *ready* or if they are - still missing tools to work properly. -8. In order to be able to accept external contributions, our highest priority item for Skylark is a - testing framework. We encourage to write new rules in Skylark rather than in Java. - - -### Stable -We expect the following rules and features to be stable. They are widely used within Google, so -our internal testing should ensure that there are no major breakages. - -<table class="table table-condensed table-striped table-bordered"> - <colgroup> - <col class="support-col-rules" /> - <col class="support-col-notes" /> - </colgroup> - <thead> - <tr> - <th>Rules</th> - <th>Notes</th> - </tr> - </thead> - <tbody> - <tr> - <td>C/C++ rules except <code>cc_toolchain</code> and <code>cc_toolchain_suite</code></td> - <td></td> - </tr> - <tr> - <td>Java rules except <code>java_toolchain</code></td> - <td></td> - </tr> - <tr> - <td>Android rules except <code>android_ndk_repository</code> and - <code>android_sdk_repository</code></td> - <td></td> - </tr> - <tr> - <td><code>genrule</code></td> - <td></td> - </tr> - <tr> - <td><code>genquery</code></td> - <td></td> - </tr> - <tr> - <td><code>test_suite</code></td> - <td></td> - </tr> - <tr> - <td><code>filegroup</code></td> - <td></td> - </tr> - <tr> - <td><code>config_setting</code></td> - <td> - <ul> - <li>This rule is used in <code>select()</code> expressions. We have hundreds of uses, so - we expect the basic functionality to be stable. That said, there are some common use - cases that are not covered yet, or that require workarounds. For example, it's not - easily possible to select on information specified in a CROSSTOOL file, such as the - target abi. Another example is that it's not possible to OR multiple conditions, - leading to duplicated entries in the select. - </li> - </ul> - </td> - </tr> - </tbody> -</table> - - -### Unstable -These rules and features have known limitations that we will likely address in future releases. - -<table class="table table-condensed table-striped table-bordered"> - <colgroup> - <col class="support-col-rules" /> - <col class="support-col-notes" /> - </colgroup> - <thead> - <tr> - <th>Feature</th> - <th>Notes</th> - </tr> - </thead> - <tbody> - <tr> - <td><code>cc_toolchain</code> and <code>cc_toolchain_suite</code></td> - <td> - <ul> - <li>We intend to make significant changes to the way C/C++ toolchains are defined; we will - keep our published C/C++ toolchain definition(s) up to date, but we make no guarantees for - custom ones.</li> - </ul> - </td> - </tr> - <tr> - <td>iOS/Objective C rules</td> - <td> - <ul> - <li>We cannot vouch for changes made by Apple ® to the underlying tools and - infrastructure.</li> - <li>The rules are fairly new and still subject to change; we try to avoid breaking changes, - but this may not always be possible.</li> - <li>No testing support yet.</li> - </ul> - </td> - </tr> - <tr> - <td>Python rules</td> - <td> - <ul> - <li>The rules support neither Python 3, C/C++ extensions, nor packaging. - </li> - </ul> - </td> - </tr> - <tr> - <td>Extra actions (<code>extra_action</code>, <code>action_listener</code>)</td> - <td> - <ul> - <li>Extra actions expose information about Bazel that we consider to be implementation - details, such as the exact interface between Bazel and the tools we provide; as such, - users will need to keep up with changes to tools to avoid breakage.</li> - </ul> - </td> - </tr> - <tr> - <td><code>environment_group</code></td> - <td> - <ul> - <li>We're planning to use it more extensively, replacing several machine-enforable - constraint mechanism, but there's only a handful of uses so far. We fully expect it to - work, but there's a small chance that we have to go back to the drawing board.</li> - </ul> - </td> - </tr> - <tr> - <td><code>android_ndk_repository</code> and <code>android_sdk_repository</code></td> - <td> - <ul> - <li>We don't support pre-release NDKs or SDKs at this time. Furthermore, we may still - make backwards-incompatible changes to the attributes or the semantics.</li> - </ul> - </td> - </tr> - <tr> - <td><code>Fileset</code></td> - <td> - <ul> - <li>There are vestiges of Fileset / FilesetEntry in the source code, but we do not intend to - support them in Bazel, ever.</li> - <li>They're still widely used internally, and are therefore unlikely to go away in the near - future.</li> - </ul> - </td> - </tbody> -</table> - diff --git a/site/versions/master/docs/tutorial/android-app.md b/site/versions/master/docs/tutorial/android-app.md deleted file mode 100644 index 31e86475cc..0000000000 --- a/site/versions/master/docs/tutorial/android-app.md +++ /dev/null @@ -1,280 +0,0 @@ ---- -layout: documentation -title: Tutorial - Build an Android App ---- - -# Tutorial - Build an Android App - -The sample Android app in this tutorial is a very simple application that makes -an HTTP connection to the [backend server](backend-server.md) and displays the -resulting response. - -Here, you'll do the following: - -* Review the source files for the app -* Update the `WORKSPACE` file -* Create a `BUILD` file -* Run the build -* Find the build outputs -* Run the app - -## Review the source files - -Let's take a look at the source files for the app. These are located in -`$WORKSPACE/android/`. - -The key files and directories are: - -<table class="table table-condensed table-striped"> -<thead> -<tr> -<td>Name</td> -<td>Location</td> -</tr> -</thead> -<tbody> -<tr> -<td>Manifest file</td> -<td><code>src/main/java/com/google/bazel/example/android/AndroidManifest.xml</code></td> -</tr> -<tr> -<td>Activity source file</td> -<td><code>src/main/java/com/google/bazel/example/android/activities/MainActivity.java</code></td> -</tr> -<tr> -<td>Resource file directory</td> -<td><code>src/main/java/com/google/bazel/example/android/res/</code></td> -</tr> -</tbody> -</table> - -Note that you're just looking at these files now to become familiar with the -structure of the app. You don't have to edit any of the source files to complete -this tutorial. - -## Update the WORKSPACE file - -Bazel needs to run the Android SDK -[build tools](https://developer.android.com/tools/revisions/build-tools.html) -and uses the SDK libraries to build the app. This means that you need to add -some information to your `WORKSPACE` file so that Bazel knows where to find -them. Note that this step is not required when you build for other platforms. -For example, Bazel automatically detects the location of Java, C++ and -Objective-C compilers from settings in your environment. - -Add the following lines to your `WORKSPACE` file: - -```python -android_sdk_repository( - name = "androidsdk", - # Replace with path to Android SDK on your system - path = "/Users/username/Library/Android/sdk", - # Replace with the Android SDK API level - api_level = 23, - # Replace with the version in sdk/build-tools/ - build_tools_version="23.0.0" -) -``` - -**Optional:** This is not required by this tutorial, but if you want to compile -native code into your Android app, you also need to download the -[Android NDK](https://developer.android.com/ndk/downloads/index.html) and -tell Bazel where to find it by adding the following rule to your `WORKSPACE` -file: - -```python -android_ndk_repository( - name = "androidndk", - # Replace with path to Android NDK on your system - path = "/Users/username/Library/Android/ndk", - # Replace with the Android NDK API level - api_level = 21 -) -``` - -`api_level` is the version of the Android API the SDK and the NDK target -(for example, 19 for Android K and 21 for Android L). It's not necessary to set -the API levels to the same value for the SDK and NDK. -[This web page](https://developer.android.com/ndk/guides/stable_apis.html) -contains a map from Android releases to NDK-supported API levels. - -## Create a BUILD file - -A [`BUILD` file](/docs/build-ref.html#BUILD_files) is a text file that describes -the relationship between a set of build outputs -- for example, compiled -software libraries or executables -- and their dependencies. These dependencies -may be source files in your workspace or other build outputs. `BUILD` files are -written in the Bazel *build language*. - -`BUILD` files are part of concept in Bazel known as the *package hierarchy*. -The package hierarchy is a logical structure that overlays the directory -structure in your workspace. Each [package](/docs/build-ref.html#packages) is a -directory (and its subdirectories) that contains a related set of source files -and a `BUILD` file. The package also includes any subdirectories, excluding -those that contain their own `BUILD` file. The *package name* is the name of the -directory where the `BUILD` file is located. - -Note that this package hierarchy is distinct from, but coexists with, the Java -package hierarchy for your Android app. - -For the simple Android app in this tutorial, we'll consider all the source files -in `$WORKSPACE/android/` to comprise a single Bazel package. A more complex -project may have many nested packages. - -At a command-line prompt, open your new `BUILD` file for editing: - -```bash -$ vi $WORKSPACE/android/BUILD -``` - -### Add an android_library rule - -A `BUILD` file contains several different types of instructions for Bazel. The -most important type is the [build rule](/docs/build-ref.html#funcs), which tells -Bazel how to build an intermediate or final software output from a set of source -files or other dependencies. - -Bazel provides two build rules, `android_library` and `android_binary`, that you -can use to build an Android app. For this tutorial, you'll first use the -[`android_library`](/docs/be/android.html#android_library) rule to tell -Bazel how to build an -[Android library module](http://developer.android.com/tools/projects/index.html#LibraryProjects) -from the app source code and resource files. Then you'll use the -`android_binary` rule to tell it how to build the Android application package. - -Add the following to your `BUILD` file: - -```python -android_library( - name = "activities", - srcs = glob(["src/main/java/com/google/bazel/example/android/activities/*.java"]), - custom_package = "com.google.bazel.example.android.activities", - manifest = "src/main/java/com/google/bazel/example/android/activities/AndroidManifest.xml", - resource_files = glob(["src/main/java/com/google/bazel/example/android/activities/res/**"]), -) -``` - -As you can see, the `android_library` build rule contains a set of attributes -that specify the information that Bazel needs to build a library module from the -source files. Note also that the name of the rule is `activities`. You'll -reference the rule using this name as a dependency in the `android_binary` rule. - -### Add an android_binary rule - -The [`android_binary`](/docs/be/android.html#android_binary) rule builds -the Android application package (`.apk` file) for your app. - -Add the following to your build file: - -```python -android_binary( - name = "android", - custom_package = "com.google.bazel.example.android", - manifest = "src/main/java/com/google/bazel/example/android/AndroidManifest.xml", - resource_files = glob(["src/main/java/com/google/bazel/example/android/res/**"]), - deps = [":activities"], -) -``` - -Here, the `deps` attribute references the output of the `activities` rule you -added to the `BUILD` file above. This means that, when Bazel builds the output -of this rule, it checks first to see if the output of the `activities` library -rule has been built and is up-to-date. If not, it builds it and then uses that -output to build the application package file. - -Now, save and close the file. You can compare your `BUILD` file to the -[completed example](https://github.com/bazelbuild/examples/blob/master/tutorial/android/BUILD) -in the `master` branch of the GitHub repo. - -## Run the build - -You use the -[`bazel`](/docs/bazel-user-manual.html) command-line tool to run builds, execute -unit tests and perform other operations in Bazel. This tool is located in the -`output` subdirectory of the location where you installed Bazel. During -[installation](/docs/install.md), you probably added this location to your -path. - -Before you build the sample app, make sure that your current working directory -is inside your Bazel workspace: - -```bash -$ cd $WORKSPACE -``` - -Now, enter the following to build the sample app: - -```bash -$ bazel build //android:android -``` - -The [`build`](/docs/bazel-user-manual.html#build) subcommand instructs Bazel to -build the target that follows. The target is specified as the name of a build -rule inside a `BUILD` file, with along with the package path relative to -your workspace directory. Note that you can sometimes omit the package path -or target name, depending on your current working directory at the command -line and the name of the target. See [Labels](/docs/build-ref.html#labels) in -*Bazel Concepts and Terminology* page for more information about target labels -and paths. - -Bazel now launches and builds the sample app. During the build process, its -output will appear similar to the following: - -```bash -INFO: Found 1 target... -Target //android:android up-to-date: - bazel-bin/android/android_deploy.jar - bazel-bin/android/android_unsigned.apk - bazel-bin/android/android.apk -INFO: Elapsed time: 7.237s, Critical Path: 5.81s -``` - -## Find the build outputs - -Bazel stores the outputs of both intermediate and final build operations in -a set of per-user, per-workspace output directories. These directories are -symlinked from the following locations: - -* `$WORKSPACE/bazel-bin`, which stores binary executables and other runnable - build outputs -* `$WORKSPACE/bazel-genfiles`, which stores intermediary source files that are - generated by Bazel rules -* `$WORKSPACE/bazel-out`, which stores other types of build outputs - -Bazel stores the Android `.apk` file generated using the `android_binary` rule -in the `bazel-bin/android/` directory, where the subdirectory name `android` is -derived from the name of the Bazel package. - -At a command prompt, list the contents of this directory and find the -`android.apk` file: - -```bash -$ ls $WORKSPACE/bazel-bin/android -``` - -## Run the app - -You can now deploy the app to a connected Android device or emulator from the -command line using the -[`bazel mobile-install`](http://bazel.io/docs/bazel-user-manual.html#mobile-install) -command. This command uses the Android Debug Bridge (`adb`) to communicate with -the device. You must set up your device to use `adb` following the instructions -in -[Android Debug Bridge](http://developer.android.com/tools/help/adb.html) before -deployment. - -Enter the following: - -```bash -$ bazel mobile-install //android:android -``` - -Note that the `mobile-install` subcommand also supports the -[`--incremental`](http://bazel.io/docs/bazel-user-manual.html#mobile-install) -flag that can be used to deploy only those parts of the app that have changed -since the last deployment. - -## What's next - -Now that you've built a sample app for Android, it's time to do the same for -the [iOS app](ios-app.md). diff --git a/site/versions/master/docs/tutorial/app.md b/site/versions/master/docs/tutorial/app.md deleted file mode 100644 index fdc33c5f83..0000000000 --- a/site/versions/master/docs/tutorial/app.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: documentation -title: Build Mobile Application ---- - -# Build Mobile Application - -You can use Bazel to build a variety of software outputs, including -Linux and Mac OS X applications written in Java, C++ and Objective-C. You can -also use Bazel to build software for other platforms or written in other -languages. - -This tutorial shows how to use Bazel to build the following: - -* An Android app -* An iOS app -* A mobile backend server running on App Engine - -In this tutorial, you'll learn how to: - -* Set up a Bazel workspace and create a `WORKSPACE` file -* Create `BUILD` files that contain the instructions used by Bazel to build - the software -* Run builds using the Bazel command line tool - -## Requirements - -You can follow the steps in this tutorial on either a Linux or Mac OS X system. -However, you can only build the iOS app if you are running Bazel on OS X. If -you are using Linux, you can skip the iOS instructions and still complete -the rest of the tutorial steps. - -## Sample project - -You don't have to write your own mobile apps and backend server to use this -tutorial. Instead, you'll use a sample project hosted on GitHub. The sample -project is hosted at the following location: - -[https://github.com/bazelbuild/examples/](https://github.com/bazelbuild/examples/) - -You'll grab the sample project files in the next step in this tutorial. - -## What's next - -Let's start off by [setting up](environment.md) the tutorial environment. diff --git a/site/versions/master/docs/tutorial/backend-server.md b/site/versions/master/docs/tutorial/backend-server.md deleted file mode 100644 index 689cc89d8b..0000000000 --- a/site/versions/master/docs/tutorial/backend-server.md +++ /dev/null @@ -1,224 +0,0 @@ ---- -layout: documentation -title: Tutorial - Build the Backend Server ---- - -# Tutorial - Build the Backend Server - -The backend server is a simple web application that runs on Google App Engine -and responds to incoming HTTP requests from the sample Android and iOS apps. - -Here, you'll do the following: - -* Review the source files for the app -* Update the `WORKSPACE` file -* Create the `appengine.BUILD` file -* Create a `BUILD` file -* Run the build -* Find the build outputs -* Deploy to a local development server -* Deploy to Google App Engine - -Bazel provides a set of [App Engine build rules](/docs/be/appengine.html) -written using the [Skylark](/docs/skylark/index.html) framework. You'll use -these in the steps below to build the application. - -## Review the source files - -The source files for the backend server are located in `$WORKSPACE/backend/`. - -The key files and directories are: - -<table class="table table-condensed table-striped"> -<thead> -<tr> -<td>Name</td> -<td>Location</td> -</tr> -</thead> -<tbody> -<tr> -<td>Source file directory</td> -<td><code>src/main/java/com/google/bazel/example/app/</code></td> -</tr> -<tr> -<td>Web application metadata directory</td> -<td><code>webapp/WEB-INF/</code></td> -</tr> -</tbody> -</table> - -## Update the WORKSPACE file - -As with the Android app, you must add references to -[external dependencies](http://bazel.io/docs/external.html) to your `WORKSPACE` -file. For the backend server, these are references to the App Engine SDK, -the Java Servlet SDK and other libraries needed to build the App Engine -applications. - -### Add a new\_http\_archive rule - -When you built the Android app, you added a reference to the location on your -filesystem where you downloaded and installed the Android SDK. For the -backend server, however, you'll give Bazel instructions for downloading the -required App Engine SDK package from a remote server. This is optional. You -can also download and install the SDK manually on your filesystem and reference -it from that location as described in the -[App Engine rule documentation](/docs/be/appengine.html). - -Add the following to your `WORKSPACE` file: - -```python -git_repository( - name = "io_bazel_rules_appengine", - remote = "https://github.com/bazelbuild/rules_appengine.git", - tag = "0.0.2", -) -load("@io_bazel_rules_appengine//appengine:appengine.bzl", "appengine_repositories") -appengine_repositories() -``` - -[`git_repository`](/docs/be/workspace.html#git_repository) downloads the -AppEngine rules from GitHub, then the next two lines use the -`appengine_repostories` function defined in these rules to download the -libraries and SDK needed to build AppEngine applications. - -Now, save and close the file. You can compare your `WORKSPACE` file to the -[completed example](https://github.com/bazelbuild/examples//blob/master/tutorial/WORKSPACE) -in the `master` branch of the GitHub repo. - -## Create a BUILD file - -Now that you have set up the external dependencies, you can go ahead and create -the `BUILD` file for the backend server, as you did previously for the sample -Android and iOS apps. - -Open your new `BUILD` file for editing: - -```bash -$ vi $WORKSPACE/backend/BUILD -``` - -### Add a java_binary rule - -Add the following to your `BUILD` file: - -```python -java_binary( - name = "app", - srcs = glob(["src/main/java/**/*.java"]), - main_class = "does.not.exist", - deps = [ - "@io_bazel_rules_appengine//appengine:javax.servlet.api", - ], -) -``` - -The [`java_binary`](/docs/be/java.html#java_binary) tells Bazel -how to build a Java `.jar` library for your application, plus a wrapper shell -script that launches the application code from the specified main class. Here, -we're using this rule instead of the -[`java_library`](/docs/be/java.html#java_library) because we need -the `.jar` file to contain all the dependencies required to build the final -App Engine `.war` file. For this reason, we specify a bogus class name -for the `main_class` attribute. - -### Add an appengine_war rule - -Add the following to your `BUILD` file: - -```python -load("@io_bazel_rules_appengine//appengine:appengine.bzl", "appengine_war") - -appengine_war( - name = "backend", - data = [":webapp"], - data_path = "/backend/webapp", - jars = [":app_deploy.jar"], -) - -filegroup( - name = "webapp", - srcs = glob(["webapp/**/*"]), -) -``` - -The [`appengine_war`](/docs/be/appengine.html#appengine_war) -rule builds the final App Engine `war` file from the library `.jar` file and web -application metadata files in the `webapp` directory. - -Save and close the file. Again, the -[completed example](https://github.com/google/bazel-examples/blob/master/tutorial/backend/BUILD) -is in the `master` branch of the GitHub repo. - -## Run the build - -Make sure that your current working directory is inside your Bazel workspace: - -```bash -$ cd $WORKSPACE -``` - -Now, enter the following to build the sample app: - -```bash -$ bazel build //backend:backend -``` - -Bazel now launches and builds the sample app. During the build process, its -output will appear similar to the following: - -```bash -INFO: Found 1 target... -Target //backend:backend up-to-date: - bazel-bin/backend/backend.war - bazel-bin/backend/backend.deploy - bazel-bin/backend/backend -INFO: Elapsed time: 56.867s, Critical Path: 2.72s -``` - -## Find the build outputs - -The `.war` file and other outputs are located in the -`$WORKSPACE/bazel-bin/backend` directory. - -## Deploy to a local development server - -The `appengine_war` rule generates an upload script that you can use to deploy -your backend server on Google App Engine. Here, you'll start a local App Engine -development server in your environment and deploy your application there. - -To deploy the application, enter the following: - -```bash -$ bazel-bin/backend/backend --port=12345 -``` - -Your application URL will be `http://localhost:12345` - -## Deploy to Google App Engine - -You can also deploy the application to the live App Engine serving -environment on Google Cloud Platform. For this scenario, you must first create -a project in the -[Google Developers Console](https://console.developers.google.com). - -To deploy the application, enter the following: - -```bash -$ $WORKSPACE/bazel-bin/backend/backend.deploy <project-id> -``` - -The deployment script prompts you to authorize access to Google Cloud Platform. -After you have authorized access the first time, you can deploy the application -using the `bazel` command and the following rule target: - -```bash -$ bazel run //backend:backend.deploy <project-id> -``` - -Your application URL will be `http://<project-id>.appspot.com`. - -## What's next - -Now let's [review](review.md) the tutorial steps. diff --git a/site/versions/master/docs/tutorial/cpp.md b/site/versions/master/docs/tutorial/cpp.md deleted file mode 100644 index 419315e499..0000000000 --- a/site/versions/master/docs/tutorial/cpp.md +++ /dev/null @@ -1,360 +0,0 @@ ---- -layout: documentation -title: Build C++ ---- - -Build C++ -========= - -You can use Bazel to build your C++ application. In this tutorial you'll learn how to: - -* Build your first C++ target -* Use external libraries -* Write and run C++ tests -* Use precompiled libraries - -## Setting up your workspace - -Suppose that you have an existing project in a directory, say, -`~/gitroot/my-project/`. Create an empty file at -`~/gitroot/my-project/WORKSPACE` to show Bazel where your project's root is. -We are going to create a small hello world project with the following directory structure: -{% highlight bash %} -└── my-project - ├── lib - │ ├── BUILD - │ ├── hello-greet.cc - │ └── hello-greet.h - ├── main - │ ├── BUILD - │ ├── hello-time.cc - │ ├── hello-time.h - │ └── hello-world.cc - └── WORKSPACE -{% endhighlight %} - -## Creating source files - -Using the following commands to create the necessary source files: -{% highlight bash %} -$ # If you're not already there, move to your workspace directory. -$ cd ~/gitroot/my-project -$ mkdir ./main -$ cat > main/hello-world.cc <<'EOF' -#include "lib/hello-greet.h" -#include "main/hello-time.h" -#include <iostream> -#include <string> - -int main(int argc, char** argv) { - std::string who = "world"; - if (argc > 1) { - who = argv[1]; - } - std::cout << get_greet(who) <<std::endl; - print_localtime(); - return 0; -} -EOF -$ cat > main/hello-time.h <<'EOF' -#ifndef MAIN_HELLO_TIME_H_ -#define MAIN_HELLO_TIME_H_ - -void print_localtime(); - -#endif -EOF -$ cat > main/hello-time.cc <<'EOF' -#include "main/hello-time.h" -#include <ctime> -#include <iostream> - -void print_localtime() { - std::time_t result = std::time(nullptr); - std::cout << std::asctime(std::localtime(&result)); -} -EOF -$ mkdir ./lib -$ cat > lib/hello-greet.h <<'EOF' -#ifndef LIB_HELLO_GREET_H_ -#define LIB_HELLO_GREET_H_ - -#include <string> - -std::string get_greet(const std::string &thing); - -#endif -EOF -$ cat > lib/hello-greet.cc <<'EOF' -#include "lib/hello-greet.h" -#include <string> - -std::string get_greet(const std::string& who) { - return "Hello " + who; -} -EOF -{% endhighlight %} - -## Adding BUILD files - -As you can see from the source code, `main/hello-world.cc` needs to include both `lib/hello-greet.h` and `main/hello-time.h`. -First we create `lib/BUILD` for hello-greet.cc: - -{% highlight python %} -cc_library( - name = "hello-greet", - srcs = ["hello-greet.cc"], - hdrs = ["hello-greet.h"], - visibility = ["//main:__pkg__"], -) -{% endhighlight %} - -Note that `visibility = ["//main:__pkg__"]` indicates `hello-greet` is visible from `main/BUILD`. -Then we'd create the following `main/BUILD` file: - -{% highlight python %} -cc_library( - name = "hello-time", - srcs = ["hello-time.cc"], - hdrs = ["hello-time.h"], -) - -cc_binary( - name = "hello-world", - srcs = ["hello-world.cc"], - deps = [ - ":hello-time", - "//lib:hello-greet", - ], -) -{% endhighlight %} - -Note when depending on a target in the same package, we can just use `:hello-time`. -When the target is in other package, a full path from root should be used, like `//lib:hello-greet`. - -Now you are ready to build your hello world C++ binary: - -{% highlight bash %} -$ bazel build main:hello-world -INFO: Found 1 target... -Target //main:hello-world up-to-date: - bazel-bin/main/hello-world -INFO: Elapsed time: 2.869s, Critical Path: 1.00s -$ ./bazel-bin/main/hello-world -Hello world -Thu Jun 23 18:51:46 2016 -$ ./bazel-bin/main/hello-world Bazel -Hello Bazel -Thu Jun 23 18:52:10 2016 -{% endhighlight %} - -Congratulations, you've just built your first Bazel target! - -## Transitive includes - -If a file includes a header, then the file's rule should depend on that header's -library. Conversely, only direct dependencies need to be specified as -dependencies. For example, suppose `sandwich.h` includes `bread.h` and -`bread.h` includes `flour.h`. `sandwich.h` doesn't include `flour.h` (who wants -flour in their sandwich?), so the BUILD file would look like: - -```python -cc_library( - name = "sandwich", - srcs = ["sandwich.cc"], - hdrs = ["sandwich.h"], - deps = [":bread"], -) - -cc_library( - name = "bread", - srcs = ["bread.cc"], - hdrs = ["bread.h"], - deps = [":flour"], -) - -cc_library( - name = "flour", - srcs = ["flour.cc"], - hdrs = ["flour.h"], -) -``` - -Here, the `sandwich` library depends on the `bread` library, which depends -on the `flour` library. - -## Adding include paths - -Sometimes you cannot (or do not want to) base include paths at the workspace -root. Existing libaries might already have a include directory that doesn't -match its path in your workspace. For example, suppose you have the following -directory structure: - -``` -└── my-project - ├── third_party - │ └── some_lib - │ ├── BUILD - │ ├── include - │ │ └── some_lib.h - │ └── some_lib.cc - └── WORKSPACE -``` - -Bazel will expect `some_lib.h` to be included as -`third_party/some_lib/include/some_lib.h`, but suppose `some_lib.cc` includes -`"include/some_lib.h"`. To make that include path valid, -`third_party/some_lib/BUILD` will need to specify that the `some_lib/` -directory is an include directory: - -```python -cc_library( - name = "some_lib", - srcs = ["some_lib.cc"], - hdrs = ["some_lib.h"], - copts = ["-Ithird_party/some_lib"], -) -``` - -This is especially useful for external dependencies, as their header files -must otherwise be included with an `external/[repository-name]/` prefix. - -## Including external libraries - -Suppose you are using [Google Test](https://code.google.com/p/googletest/). You -can use one of the `new_` repository functions in the `WORKSPACE` file to -download Google Test and make it available in your repository: - -```python -new_http_archive( - name = "gtest", - url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip", - sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d", - build_file = "gtest.BUILD", -) -``` - -Then create `gtest.BUILD`, a BUILD file to use to compile Google Test. -Google Test has several "special" requirements that make its `cc_library` rule -more complicated: - -* `gtest-1.7.0/src/gtest-all.cc` `#include`s all of the other files in - `gtest-1.7.0/src/`, so we need to exclude it from the compile or we'll get - link errors for duplicate symbols. -* It uses header files that relative to the `gtest-1.7.0/include/` directory - (`"gtest/gtest.h"`), so we must add that directory the include paths. -* It needs to link in pthread, so we add that as a `linkopt`. - -The final rule looks like this: - -```python -cc_library( - name = "main", - srcs = glob( - ["gtest-1.7.0/src/*.cc"], - exclude = ["gtest-1.7.0/src/gtest-all.cc"] - ), - hdrs = glob([ - "gtest-1.7.0/include/**/*.h", - "gtest-1.7.0/src/*.h" - ]), - copts = [ - "-Iexternal/gtest/gtest-1.7.0/include" - ], - linkopts = ["-pthread"], - visibility = ["//visibility:public"], -) -``` - -This is somewhat messy: everything is prefixed with gtest-1.7.0 as a byproduct -of the archive's structure. You can make `new_http_archive` strip this prefix by -adding the `strip_prefix` attribute: - -```python -new_http_archive( - name = "gtest", - url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip", - sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d", - build_file = "gtest.BUILD", - strip_prefix = "gtest-1.7.0", -) -``` - -Then `gtest.BUILD` would look like this: - -```python -cc_library( - name = "main", - srcs = glob( - ["src/*.cc"], - exclude = ["src/gtest-all.cc"] - ), - hdrs = glob([ - "include/**/*.h", - "src/*.h" - ]), - copts = ["-Iexternal/gtest/include"], - linkopts = ["-pthread"], - visibility = ["//visibility:public"], -) -``` - -Now `cc_` rules can depend on `//external:gtest/main`. - -## Writing and running C++ tests - -For example, we could create a test `./test/hello-test.cc` such as: - -```cpp -#include "gtest/gtest.h" -#include "lib/hello-greet.h" - -TEST(FactorialTest, Negative) { - EXPECT_EQ(get_greet("Bazel"), "Hello Bazel"); -} -``` - -Then create `./test/BUILD` file for your tests: - -```python -cc_test( - name = "hello-test", - srcs = ["hello-test.cc"], - copts = ["-Iexternal/gtest/include"], - deps = [ - "@gtest//:main", - "//lib:hello-greet", - ], -) -``` - -Note in order to make `hello-greet` visible to `hello-test`, we have to add `"//test:__pkg__",` to `visibility` attribute in `./lib/BUILD`. - -Now you can use `bazel test` to run the test. - -{% highlight bash %} -$ bazel test test:hello-test -INFO: Found 1 test target... -Target //test:hello-test up-to-date: - bazel-bin/test/hello-test -INFO: Elapsed time: 4.497s, Critical Path: 2.53s -//test:hello-test PASSED in 0.3s - -Executed 1 out of 1 tests: 1 test passes. -{% endhighlight %} - - -## Adding dependencies on precompiled libraries - -If you want to use a library that you only have a compiled version of (e.g., -headers and a .so) wrap it in a `cc_library` rule: - -```python -cc_library( - name = "mylib", - srcs = ["mylib.so"], - hdrs = ["mylib.h"], -) -``` - -Then other C++ targets in your workspace can depend on this rule. diff --git a/site/versions/master/docs/tutorial/environment.md b/site/versions/master/docs/tutorial/environment.md deleted file mode 100644 index 219060de7c..0000000000 --- a/site/versions/master/docs/tutorial/environment.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -layout: documentation -title: Tutorial - Set Up Your Environment ---- - -# Tutorial - Set Up Your Environment - -The first step in this tutorial is to set up your environment. - -Here, you'll do the following: - -* Install Bazel -* Install Android Studio and the Android SDK -* Install Xcode (OS X only) -* Get the sample project from the GitHub repo - -## Install Bazel - -Follow the [installation instructions](/docs/install.md) to install Bazel and -its dependencies. - -## Install the Android SDK tools - -Do the following: - -1. Download and install the - [Android SDK Tools](https://developer.android.com/sdk/index.html#Other). - -2. Run the Android SDK Manager and install the following packages: - - <table class="table table-condensed table-striped"> - <thead> - <tr> - <td>Package</td> - <td>SDK directory</td> - </tr> - </thead> - <tbody> - <tr> - <td>Android SDK Platform Tools</td> - <td><code>platform-tools</code></td> - </tr> - <tr> - <td>Android SDK Build Tools</td> - <td><code>build-tools</code></td> - </tr> - <tr> - <td>Android SDK Platform</td> - <td><code>platform</code></td> - </tr> - </tbody> - </table> - - The SDK Manager is an executable named `android` located in the `tools` - directory. - -## Install Xcode (OS X only) - -If you are following the steps in this tutorial on Mac OS X, download and -install [Xcode](https://developer.apple.com/xcode/downloads/). The Xcode -download contains the iOS libraries, Objective-C compiler other tools -required by Bazel to build the iOS app. - -## Get the sample project - -You also need to get the sample project for the tutorial from GitHub: - -[https://github.com/bazelbuild/examples/](https://github.com/bazelbuild/examples/) - -The GitHub repo has two branches: `source-only` and `master`. The `source-only` -branch contains the source files for the project only. You'll use the files in -this branch in this tutorial. The `master` branch contains both the source files -and completed Bazel `WORKSPACE` and `BUILD` files. You can use the files in this -branch to check your work when you've completed the tutorial steps. - -Enter the following at the command line to get the files in the `source-only` -branch: - -```bash -$ cd $HOME -$ git clone -b source-only https://github.com/bazelbuild/examples -``` - -The `git clone` command creates a directory named `$HOME/examples/`. This -directory contains several sample projects for Bazel. The project files for this -tutorial are in `$HOME/examples/tutorial`. - -## What's next - -Now that you have set up your environment, you can -[set up a Bazel workspace](workspace.md). diff --git a/site/versions/master/docs/tutorial/ios-app.md b/site/versions/master/docs/tutorial/ios-app.md deleted file mode 100644 index 51774e9312..0000000000 --- a/site/versions/master/docs/tutorial/ios-app.md +++ /dev/null @@ -1,206 +0,0 @@ ---- -layout: documentation -title: Tutorial - Build an iOS App ---- - -# Tutorial - Build an iOS App - -Like the [Android app](android-app.md) you built in the previous step, the iOS -app is a simple mobile app that communicates with the -[backend server](backend-server.md). - -Here, you'll do the following: - -* Review the source files for the app -* Create a `BUILD` file -* Build the app for the simulator -* Find the build outputs -* Run/Debug the app on the simulator -* Build the app for a device -* Install the app on a device - -Note that, unlike with the Android app, you don't have to modify your -`WORKSPACE` file to add iOS-specific external dependencies. - -If you're following the steps in this tutorial on Mac OS X, you can go ahead -and build the sample iOS app as described below. If you are on Linux, skip ahead -to the [next step](backend-server.md). - -## Review the source files - -Let's take a look at the source files for the app. These are located in -`$WORKSPACE/ios-app/UrlGet`. Again, you're just looking at these files now to -become familiar with the structure of the app. You don't have to edit any of the -source files to complete this tutorial. - -## Create a BUILD file - -At a command-line prompt, open your new `BUILD` file for editing: - -```bash -$ vi $WORKSPACE/ios-app/BUILD -``` - -## Add an objc_library rule - -Bazel provides several build rules that you can use to build an app for the -iOS platform. For this tutorial, you'll first use the -[`objc_library`](/docs/be/objective-c.html#objc_library) rule to tell Bazel -how to build an -[static library](https://developer.apple.com/library/ios/technotes/iOSStaticLibraries/Introduction.html) -from the app source code and Xib files. Then you'll use the -`objc_binary` rule to tell it how to bundle the iOS application. (Note that -this is a minimal use case of the Objective-C rules in Bazel. For example, you -have to use the `ios_application` rule to build multi-architecture iOS -apps.) - -Add the following to your `BUILD` file: - -```python -objc_library( - name = "UrlGetClasses", - srcs = [ - "UrlGet/AppDelegate.m", - "UrlGet/UrlGetViewController.m", - ], - hdrs = glob(["UrlGet/*.h"]), - xibs = ["UrlGet/UrlGetViewController.xib"], -) -``` - -Note the name of the rule, `UrlGetClasses`. - -## Add an objc_binary rule - -The [`objc_binary`](/docs/be/objective-c.html#objc_binary) rule creates a -binary to be bundled in the application. - -Add the following to your `BUILD` file: - -```python -objc_binary( - name = "ios-app-binary", - srcs = [ - "UrlGet/main.m", - ], - deps = [ - ":UrlGetClasses", - ], -) - -``` -Note how the `deps` attribute references the output of the -`UrlGetClasses` rule you added to the `BUILD` file above. - -## Add an ios_application rule - -The [`ios_application`](/docs/be/objective-c.html#ios_application) rule -creates the bundled `.ipa` archive file for the application and also generates -an Xcode project file. - -Add the following to your `BUILD` file: - -```python -ios_application( - name = "ios-app", - binary = ":ios-app-binary", - infoplist = "UrlGet/UrlGet-Info.plist", -) -``` - -Now, save and close the file. You can compare your `BUILD` file to the -[completed example](https://github.com/bazelbuild/examples/blob/master/tutorial/ios-app/BUILD) -in the `master` branch of the GitHub repo. - -## Build the app for the simulator - -Make sure that your current working directory is inside your Bazel workspace: - -```bash -$ cd $WORKSPACE -``` - -Now, enter the following to build the sample app: - -```bash -$ bazel build //ios-app:ios-app -``` - -Bazel now launches and builds the sample app. During the build process, its -output will appear similar to the following: - -```bash -INFO: Found 1 target... -Target //ios-app:ios-app up-to-date: - bazel-bin/ios-app/ios-app.ipa - bazel-bin/ios-app/ios-app.xcodeproj/project.pbxproj -INFO: Elapsed time: 3.765s, Critical Path: 3.44s -``` - -## Find the build outputs - -The `.ipa` file and other outputs are located in the -`$WORKSPACE/bazel-bin/ios-app` directory. - -## Run/Debug the app on the simulator - -You can now run the app from Xcode using the iOS Simulator. To run the app, -open the project directory `$WORKSPACE/bazel-bin/ios-app/ios-app.xcodeproj` in -Xcode, choose an iOS Simulator as the runtime scheme and then click the **Run** -button. - -**Note:** If you change anything about the project file set in Xcode (for -example, if you add or remove a file, or add or change a dependency), you must -rebuild the app using Bazel and then re-open the project. - -## Build the app for a device - -You need to set up bazel so that it can find the appropriate provisioning -profile for the device you want to build for. To set up the "default" -provisioning profile for all bazel builds: - - 1. Go to [Apple Profiles](https://developer.apple.com/account/ios/profile/profileList.action) - and download the appropriate provisioning profile for your device. - If this is confusing, please refer to [Apple's documentation](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingProfiles/MaintainingProfiles.html). - 1. Move your profile into `$WORKSPACE/tools/objc`. - 1. Optional - You may want to add your profile to your `.gitignore`. - 1. Edit `$WORKSPACE/tools/objc/BUILD` and add: - - ```python - filegroup( - name = "default_provisioning_profile", - srcs = ["<NAME OF YOUR PROFILE>.mobileprovision"], - ) - ``` - -Now you should be able to build the app for your device: - -```bash -$ bazel build //ios-app:ios-app --ios_multi_cpus=armv7,arm64 -``` - -This will build the app "fat". If you would prefer just to build for -your specific device architecture you can designate a single architecture. - -If you would like to select a specific Xcode version/SDK version you can do so -with the `--xcode_version=7.2 --ios_sdk_version=9.2` options. Make sure that -the Xcode version that you select has the appropriate SDK installed in it. - -If you would like to specify a minimum version of iOS to run against, you can -do so with the `--ios_minimum_os=7.0` option. - -## Install the app on a device - -The easiest way to install the app on the device is to launch Xcode and use the -`Windows > Devices` command. Select your plugged in device from the list on the -left, and then add the app by clicking on the "plus" sign under installed apps -and selecting the `.ipa` that you built. - -If your app does not launch, please make sure that your device was on your -provisioning profile. The `View Device Logs` button on the `Devices` screen in -Xcode may provide other information as to what has gone wrong. - -## What's next - -The next step is to build a [backend server](backend-server.md) for the two -mobile apps you built in this tutorial. diff --git a/site/versions/master/docs/tutorial/java.md b/site/versions/master/docs/tutorial/java.md deleted file mode 100644 index e78400f521..0000000000 --- a/site/versions/master/docs/tutorial/java.md +++ /dev/null @@ -1,245 +0,0 @@ ---- -layout: documentation -title: Build Java ---- - -Build Java -========== - -You can use Bazel to build your Java application. In this tutorial you'll learn how to: - -* Build your first Java target -* Add dependencies to your target -* Use multiple packages -* Deploy your target - -## Setting up your workspace - -Suppose that you have an existing project in a directory, say, -`~/gitroot/my-project/`. Create an empty file at -`~/gitroot/my-project/WORKSPACE` to show Bazel where your project's root is. - -## Creating Your Own Build File - -Use the following commands to make a small Java project for this example: - -{% highlight bash %} -$ # If you're not already there, move to your workspace directory. -$ cd ~/gitroot/my-project -$ mkdir -p src/main/java/com/example -$ cat > src/main/java/com/example/ProjectRunner.java <<'EOF' -package com.example; - -public class ProjectRunner { - public static void main(String args[]) { - Greeting.sayHi(); - } -} -EOF -$ cat > src/main/java/com/example/Greeting.java <<'EOF' -package com.example; - -public class Greeting { - public static void sayHi() { - System.out.println("Hi!"); - } -} -EOF -{% endhighlight %} - -Bazel figures out what to build by looking for files named `BUILD` in your -workspace, so we'll create a `BUILD` file in the `~/gitroot/my-project` -directory. Add the following lines to this BUILD file: - -{% highlight python %} -# ~/gitroot/my-project/BUILD -java_binary( - name = "my-runner", - srcs = glob(["**/*.java"]), - main_class = "com.example.ProjectRunner", -) -{% endhighlight %} - -`java_binary` is the type of thing this rule will build. -`glob(["**/*.java"])` is a handy shorthand for "recursively include every file -that ends with .java" (see the -[build encyclopedia](be/functions.html#glob) for more information about -globbing). `com.example.ProjectRunner` specifies the class that contains the -main method. - -Now you are ready to build your Java binary: - -{% highlight bash %} -$ cd ~/gitroot/my-project -$ bazel build //:my-runner -INFO: Found 1 target... -Target //:my-runner up-to-date: - bazel-bin/my-runner.jar - bazel-bin/my-runner -INFO: Elapsed time: 1.021s, Critical Path: 0.83s -$ bazel-bin/my-runner -Hi! -{% endhighlight %} - -Congratulations, you've just built your first Bazel target! - -## Adding Dependencies - -Creating one rule to build your entire project may be sufficient for small -projects, but as projects get larger it's important to break up the build into -self-contained libraries that can be assembled into a final product. This way -the entire world doesn't need to be rebuilt on small changes and Bazel can -parallelize more of the build steps. - -To break up a project, create separate rules for each subcomponent and then -make them depend on each other. For the example above, add the following rules -to the `BUILD` file: - -{% highlight python %} -java_binary( - name = "my-other-runner", - srcs = ["src/main/java/com/example/ProjectRunner.java"], - main_class = "com.example.ProjectRunner", - deps = [":greeter"], -) - -java_library( - name = "greeter", - srcs = ["src/main/java/com/example/Greeting.java"], -) -{% endhighlight %} - -This builds the same files as before, but in a different way: now Bazel will -build the `greeter` library first and then build `my-other-runner`. Try building -and running `//:my-other-runner`: - -{% highlight bash %} -$ bazel run //:my-other-runner -INFO: Found 1 target... -Target //:my-other-runner up-to-date: - bazel-bin/my-other-runner.jar - bazel-bin/my-other-runner -INFO: Elapsed time: 2.454s, Critical Path: 1.58s - -INFO: Running command line: bazel-bin/my-other-runner -Hi! -{% endhighlight %} - -Now if you edit `ProjectRunner.java` and rebuild `my-other-runner`, -`Greeting.java` will not need to be recompiled. - -## Using Multiple Packages - -For larger projects, you will often be dealing with several directories. You -can refer to targets defined in other BUILD files using the syntax -`//path/to/directory:target-name`. For example, suppose -`src/main/java/com/example/` has a `cmdline/` subdirectory with the following -file: - -{% highlight bash %} -$ mkdir -p src/main/java/com/example/cmdline -$ cat > src/main/java/com/example/cmdline/Runner.java <<'EOF' -package com.example.cmdline; - -import com.example.Greeting; - -public class Runner { - public static void main(String args[]) { - Greeting.sayHi(); - } -} -EOF -{% endhighlight %} - -`Runner.java` depends on `com.example.Greeting`, so we could add a `BUILD` file -at `src/main/java/com/example/cmdline/BUILD` that contained the following rule: - -{% highlight python %} -# ~/gitroot/my-project/src/main/java/com/example/cmdline/BUILD -java_binary( - name = "runner", - srcs = ["Runner.java"], - main_class = "com.example.cmdline.Runner", - deps = ["//:greeter"] -) -{% endhighlight %} - -However, by default, build rules are _private_. This means that they can only be -referred to by rules in the same BUILD file. This prevents libraries that are -implementation details from leaking into public APIs, but it also means that you -must explicitly allow `runner` to depend on `//:greeter`. As is, if we -build `runner` we'll get a permissions error: - -{% highlight bash %} -$ bazel build //src/main/java/com/example/cmdline:runner -ERROR: /home/user/gitroot/my-project/src/main/java/com/example/cmdline/BUILD:2:1: - Target '//:greeter' is not visible from target '//src/main/java/com/example/cmdline:runner'. - Check the visibility declaration of the former target if you think the dependency is legitimate. -ERROR: Analysis of target '//src/main/java/com/example/cmdline:runner' failed; build aborted. -INFO: Elapsed time: 0.091s -{% endhighlight %} - -You can make a rule visibile to rules in other BUILD files by adding a -`visibility = level` attribute. Change the `greeter` rule in -`~/gitroot/my-project/BUILD` to be visible to our new rule: - -{% highlight python %} -java_library( - name = "greeter", - srcs = ["src/main/java/com/example/Greeting.java"], - visibility = ["//src/main/java/com/example/cmdline:__pkg__"], -) -{% endhighlight %} - -This makes `//:greeter` visible to any rule in the -`//src/main/java/com/example/cmdline` package. Now we can build and -run the `runner` binary: - -{% highlight bash %} -$ bazel run //src/main/java/com/example/cmdline:runner -INFO: Found 1 target... -Target //src/main/java/com/example/cmdline:runner up-to-date: - bazel-bin/src/main/java/com/example/cmdline/runner.jar - bazel-bin/src/main/java/com/example/cmdline/runner -INFO: Elapsed time: 1.576s, Critical Path: 0.81s - -INFO: Running command line: bazel-bin/src/main/java/com/example/cmdline/runner -Hi! -{% endhighlight %} - -See the [build encyclopedia](be/common-definitions.html#common.visibility) for more -visibility options. - -## Deploying - -If you look at the contents of -_bazel-bin/src/main/java/com/example/cmdline/runner.jar_, you can see that it -only contains `Runner.class`, not its dependencies (`Greeting.class`): - -{% highlight bash %} -$ jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar -META-INF/ -META-INF/MANIFEST.MF -com/ -com/example/ -com/example/cmdline/ -com/example/cmdline/Runner.class -{% endhighlight %} - -This works for running locally (the `runner` script Bazel generates adds the -greeter jar to the classpath) but will not work if we want to copy `runner.jar` -to another machine and use it as a standalone binary. To build a self-contained -jar that can be deployed, build `runner_deploy.jar` (or, more generally, -`<target-name>_deploy.jar`): - -{% highlight bash %} -$ bazel build //src/main/java/com/example/cmdline:runner_deploy.jar -INFO: Found 1 target... -Target //src/main/java/com/example/cmdline:runner_deploy.jar up-to-date: - bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar -INFO: Elapsed time: 1.700s, Critical Path: 0.23s -{% endhighlight %} - -`runner_deploy.jar` will contain all of its dependencies. - - diff --git a/site/versions/master/docs/tutorial/review.md b/site/versions/master/docs/tutorial/review.md deleted file mode 100644 index 62d4501ad4..0000000000 --- a/site/versions/master/docs/tutorial/review.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -layout: documentation -title: Tutorial - Review ---- - -# Tutorial - Review - -In this tutorial, you used Bazel to build an [Android app](android-app.md), -an [iOS app](ios-app.md) and a [backend server](backend-server.md) that runs on -Google App Engine. - -To build these software outputs, you: - -* Set up a Bazel [workspace](workspace.md) that contained the source code - for the components and a `WORKSPACE` that identifies the top level of the - workspace directory -* Created a `BUILD` file for each component -* Updated the `WORKSPACE` file to contain references to the required - external dependencies -* Ran Bazel to build the software components - -The built mobile apps and backend server application files are located in the -`$WORKSPACE/bazel-bin` directory. - -Note that completed `WORKSPACE` and `BUILD` files for this tutorial are located -in the -[master branch](https://github.com/bazelbuild/examples/tree/master/tutorial) -of the GitHub repo. You can compare your work to the completed files for -additional help or troubleshooting. diff --git a/site/versions/master/docs/tutorial/workspace.md b/site/versions/master/docs/tutorial/workspace.md deleted file mode 100644 index ff3f6da510..0000000000 --- a/site/versions/master/docs/tutorial/workspace.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -layout: documentation -title: Tutorial - Set Up a Workspace ---- - -# Tutorial - Set Up a Workspace - -A [workspace](/docs/build-ref.html#workspaces) is a directory that contains the -source files for one or more software projects, as well as a `WORKSPACE` file -and `BUILD` files that contain the instructions that Bazel uses to build -the software. It also contains symbolic links to output directories in the -Bazel home directory. - -A workspace directory can be located anywhere on your filesystem. In this -tutorial, your workspace directory is `$HOME/examples/tutorial/`, which -contains the sample project files you cloned from the GitHub repo in the -previous step. - -Note that Bazel itself doesn't make any requirements about how you organize -source files in your workspace. The sample source files in this tutorial are -organized according to common conventions for Android apps, iOS apps and App -Engine applications. - -For your convenience, set the `$WORKSPACE` environment variable now to refer to -your workspace directory. At the command line, enter: - -```bash -$ export WORKSPACE=$HOME/examples/tutorial -``` - -## Create a WORKSPACE file - -Every workspace must have a text file named `WORKSPACE` located in the top-level -workspace directory. This file may be empty or it may contain references -to [external dependencies](/docs/external.html) required to build the -software. - -For now, you'll create an empty `WORKSPACE` file, which simply serves to -identify the workspace directory. In later steps, you'll update the file to add -external dependency information. - -Enter the following at the command line: - -```bash -$ touch $WORKSPACE/WORKSPACE -``` - -This creates the empty `WORKSPACE` file. - -## What's next - -Now that you've set up your workspace, you can -[build the Android app](android-app.md). diff --git a/site/versions/master/faq.md b/site/versions/master/faq.md deleted file mode 100644 index ff9939ae96..0000000000 --- a/site/versions/master/faq.md +++ /dev/null @@ -1,424 +0,0 @@ ---- -layout: default -title: FAQ -nav: faq ---- - -What is Bazel? --------------- - -Bazel is a tool that automates software builds and tests. Supported build tasks -include running compilers and linkers to produce executable programs and -libraries, and assembling deployable packages for Android, iOS and other target -environments. Bazel is similar to other tools like Make, Ant, Gradle, Buck, -Pants and Maven. - -What is special about Bazel? ----------------------------- - -Bazel was designed to fit the way software is developed at Google. It -has the following features: - -* Multi-language support: Bazel supports Java, Objective-C and C++ out - of the box, and can be extended to support arbitrary programming - languages. - -* High-level build language: Projects are described in the BUILD - language, a concise text format that describes a project as sets of - small interconnected libraries, binaries and tests. In contrast, with - tools like Make, you have to describe individual files and compiler - invocations. - -* Multi-platform support: The same tool and the same BUILD files can - be used to build software for different architectures, and even - different platforms. At Google, we use Bazel to build everything from - server applications running on systems in our data centers to client apps - running on mobile phones. - -* Reproducibility: In BUILD files, each library, test and binary must - specify its direct dependencies completely. Bazel uses this - dependency information to know what must be rebuilt when you make - changes to a source file, and which tasks can run in parallel. This - means that all builds are incremental and will always produce the - same result. - -* Scalable: Bazel can handle large builds; at Google, it is common for - a server binary to have 100k source files, and builds where no files - were changed take about ~200ms. - - -Why doesn't Google use ...? ---------------------------- - -* Make, Ninja: These tools give very exact control over what commands - get invoked to build files, but it's up to the user to write rules - that are correct. - - Users interact with Bazel on a higher level. For example, Bazel has - built-in rules for "Java test", "C++ binary", and notions such as - "target platform" and "host platform". These rules have been battle - tested to be foolproof. - -* Ant and Maven: Ant and Maven are primarily geared toward Java, while - Bazel handles multiple languages. Bazel encourages subdividing - codebases in smaller reusable units, and can rebuild only ones that - need rebuilding. This speeds up development when working with larger - codebases. - -* Gradle: Bazel configuration files are much more structured than - Gradle's, letting Bazel understand exactly what each action does. - This allows for more parallelism and better reproducibility. - -* Pants, Buck: Both tools were created and developed by ex-Googlers at - Twitter and Foursquare, and Facebook respectively. They have been modeled - after Bazel, but their feature sets are different, so they aren't viable - alternatives for us. - - -Where did Bazel come from? --------------------------- - -Bazel is a flavor of the tool that Google uses to build its server -software internally. It has expanded to build other software as well, -like mobile apps (iOS, Android) that connect to our servers. - -Did you rewrite your internal tool as open-source? Is it a fork? ----------------------------------------------------------------- - -Bazel shares most of its code with the internal tool and its rules -are used for millions of builds every day. - -Why did Google build Bazel? ---------------------------- - -A long time ago, Google built its software using large, generated -Makefiles. These led to slow and unreliable builds, which began to -interfere with our developers' productivity and the company's -agility. Bazel was a way to solve these problems. - -Does Bazel require a build cluster? ------------------------------------ - -Google's in-house flavor of Bazel does use [build -clusters](http://google-engtools.blogspot.com/2011/09/build-in-cloud-distributing-build-steps.html), -so Bazel does have hooks in the code base to plug in a remote build -cache or a remote execution system. - -The open source Bazel code runs build operations locally. We believe -that this is fast enough for most of our users. - -How does the Google development process work? ----------------------------------------------- - -For our server code base, we use the following development workflow: - -* All our server code is in a single, gigantic version control - system. - -* Everybody builds their software with Bazel. - -* Different teams own different parts of the source tree, and make - their components available as BUILD targets. - -* Branching is primarily used for managing releases, so everybody - develops their software at the head revision. - -Bazel is a cornerstone of this philosophy: since Bazel requires all -dependencies to be fully specified, we can predict which programs and -tests are affected by a change, and vet them before submission. - -More background on the development process at Google can be found on -the [eng tools blog](http://google-engtools.blogspot.com/). - -Why are you opening up Bazel? ------------------------------ - -Building software should be fun and easy. Slow and unpredictable -builds take the fun out of programming. - -Why would I want to use Bazel? ------------------------------- - -* Bazel may give you faster build times because it can recompile only - the files that need to be recompiled. Similarly, it can skip - re-running tests that it knows haven't changed. - -* Bazel produces deterministic results. This eliminates skew - between incremental and clean builds, laptop and CI system, etc. - -* Bazel can build different client and server apps with the same tool - from the same workspace. For example, you can change a client/server - protocol in a single commit, and test that the updated mobile app - works with the updated server, building both with the same tool, - reaping all the aforementioned benefits of Bazel. - -Can I see examples? -------------------- - -Yes. For a simple example, see: - - <https://github.com/bazelbuild/bazel/blob/master/examples/cpp/BUILD> - -The Bazel source code itself provides a more complex example: - - <https://github.com/bazelbuild/bazel/blob/master/src/BUILD> - -What is Bazel best at? ----------------------- - -Bazel shines at building and testing projects with the following properties: - -* Projects with a large codebase -* Projects written in (multiple) compiled languages -* Projects that deploy on multiple platforms -* Projects that have extensive tests - -Where can I run Bazel? ---------------------------------- - -Currently, Linux and Mac OS X. Porting to other UNIX platforms should be -straightforward, as long as a JDK is available for the platform. - -What about Windows? -------------------- - -Due to its UNIX heritage, porting Bazel to Windows is significant work. For -example, Bazel uses symlinks extensively, which has varying levels of support -across Windows versions. - -We are currently actively working on improving Windows support, but it's still -ways from being usable. - -What should I not use Bazel for? --------------------------------- - -* Bazel tries to be smart about caching. This means that it is not good - for running build operations whose outputs should not be cached. For example, - the following steps should not be run from Bazel: - - * A compilation step that fetches data from the internet. - * A test step that connects to the QA instance of your site. - * A deployment step that changes your site's cloud configuration. - -* Bazel tries to minimize expensive compilation steps. If you are only - using interpreted languages directly, such as JavaScript or Python, - Bazel will likely not interest you. - -How stable is Bazel's feature set? ----------------------------------- - -The core features (C++, Java, and shell rules) have extensive use -inside Google, so they are thoroughly tested and have very little -churn. Similarly, we test new versions of Bazel across hundreds of -thousands of targets every day to find regressions, and we release new -versions multiple times every month. - -In short, except for features marked as experimental, Bazel should Just Work. -Changes to non-experimental rules will be backward compatible. A more detailed -list of feature support statuses can be found in our -[support document](support.html). - -How stable is Bazel as a binary? --------------------------------- - -Inside Google, we make sure that Bazel crashes are very rare. This -should also hold for our open source codebase. - -How can I start using Bazel? ----------------------------- - -See our [getting started document](docs/getting-started.html). - -Doesn't Docker solve the reproducibility problems? --------------------------------------------------- - -With Docker you can easily create sandboxes with fixed OS releases, -for example, Ubuntu 12.04, Fedora 21. This solves the problem of -reproducibility for the system environment -- that is, "which version of -/usr/bin/c++ do I need?" - -Docker does not address reproducibility with regard to changes in the -source code. Running Make with an imperfectly written Makefile inside a -Docker container can still yield unpredictable results. - -Inside Google, we check tools into source control for reproducibility. -In this way, we can vet changes to tools ("upgrade GCC to 4.6.1") with -the same mechanism as changes to base libraries ("fix bounds check in -OpenSSL"). - -Can I build binaries for deployment on Docker? ----------------------------------------------- - -With Bazel, you can build standalone, statically linked binaries in -C/C++, and self-contained jar files for Java. These run with few -dependencies on normal UNIX systems, and as such should be simple to -install inside a Docker container. - -Bazel has conventions for structuring more complex programs, for example, a -Java program that consumes a set of data files, or runs another -program as subprocess. It is possible to package up such environments -as standalone archives, so they can be deployed on different systems, -including Docker images. - -Can I build Docker images with Bazel? -------------------------------------- - -Yes, you can use our -[Docker rules](http://bazel.io/docs/be/docker.html) -to build reproducible Docker images. - -Will Bazel make my builds reproducible automatically? ------------------------------------------------------ - -For Java and C++ binaries, yes, assuming you do not change the -toolchain. If you have build steps that involve custom recipes -(for example, executing binaries through a shell script inside a rule), you -will need to take some extra care: - - * Do not use dependencies that were not declared. Sandboxed - execution (--spawn_strategy=sandboxed, only on Linux) can - help find undeclared dependencies. - - * Avoid storing timestamps and user-IDs in generated files. ZIP files and - other archives are especially prone to this. - - * Avoid connecting to the network. Sandboxed execution can help here - too. - - * Avoid processes that use random numbers, in particular, dictionary - traversal is randomized in many programming languages. - -Do you have binary releases? ----------------------------- - -Yes, you can find the latest release binaries -[here](https://github.com/bazelbuild/bazel/releases/latest). Our release -policy is documented [here](http://bazel.io/support.html). - -I use Eclipse/IntelliJ. How does Bazel interoperate with IDEs? --------------------------------------------------------------- - -We currently have no IDE integration API as such but the iOS rules generate -Xcode projects based on Bazel BUILD targets (see below). - -How does Bazel interact with Xcode? ------------------------------------ - -Bazel generates Xcode projects that you can use to work with any inputs and -dependencies for the target, to build apps from Xcode directly and to deploy to -an iOS simulator and devices. Simply open the project file whose path is printed -by Bazel after building any iOS target. There is no support to invoke Bazel from -Xcode (for example to re-generate generated sources such as Objective-C files -based on protos), nor to open Xcode from Bazel directly. - -I use Jenkins/CircleCI/TravisCI. How does Bazel interoperate with CI systems? ------------------------------------------------------------------------------ - -Bazel returns a non-zero exit code if the build or test invocation -fails, and this should be enough for basic CI integration. Since -Bazel does not need clean builds for correctness, the CI system should not -be configured to clean before starting a build/test run. - -Further details on exit codes are in the [User Manual](docs/bazel-user-manual.html). - -What future features can we expect in Bazel? --------------------------------------------- - -Our initial goal is to work on Google's internal use-cases. This -includes Google's principal languages (C++, Java, Go) and major -platforms (Linux, Android, iOS). For practical reasons, not all of -these are currently open-sourced. For more details see our -[roadmap](roadmap.html). - -What about Python? ------------------- - -It is possible to write Python rules as extensions (see below). See -the following files for an example of generating self-contained zip -files for python: - - <https://github.com/bazelbuild/bazel/blob/master/tools/build_rules/py_rules.bzl>\\ - <https://github.com/bazelbuild/bazel/tree/master/examples/py> - -We have opened up a subset of our internal Python rules, so they -can be used as helper scripts as part of a build. - -Simplistic support for PEX-style binaries is at -[here](https://github.com/bazelbuild/bazel/blob/master/tools/build_rules/py_rules.bzl). - - -What about Go? --------------- - -If your codebase is 100% Go, the `go` tool has excellent support for -building and testing, and Bazel will not bring you much benefit. - -The server code written in Go at Google is built with Bazel. However, the rules -that accomplish this are rather complex due to their interactions with our C++ -libraries, and are incompatible with the conventions of the `go` tool. We are -working on improving this situation. - -Can I use Bazel for my [INSERT LANGUAGE HERE] project? ------------------------------------------------------- - -We have an extension mechanism called Skylark that allows you to add new rules -without recompiling Bazel. - -For documentation: see [here](/docs/skylark/index.html). We have support for -several languages that use that extension mechanism, see our -[build encyclopedia](/docs/be/overview.html) for the full -list of supported languages. - -I need more functionality. Can I add rules that are compiled into Bazel? ------------------------------------------------------------------------- - -If our extension mechanism is insufficient for your use case, email -the mailing list for advice: <bazel-discuss@googlegroups.com>. - -Can I contribute to the Bazel code base? ----------------------------------------- - -See our [contribution guidelines](contributing.html). - -Why isn't all development done in the open? -------------------------------------------- - -We still have to refactor the interfaces between the public code in -Bazel and our internal extensions frequently. This makes it hard to do -much development in the open. See our [governance plan](governance.html) -for more details. - -How do I contact the team? --------------------------- - -We are reachable at <bazel-discuss@googlegroups.com>. - -Where do I report bugs? ------------------------ - -Send an e-mail to <bazel-discuss@googlegroups.com> or file a bug -[on GitHub](https://github.com/bazelbuild/bazel/issues). - - - -What's up with the word "Blaze" in the codebase? ------------------------------------------------- - -This is an internal name for the tool. Please refer to Bazel as -Bazel. - - -Why do other Google projects (Android, Chrome) use other build tools? ---------------------------------------------------------------------- - -Until now, Bazel was not available externally, so open source projects -such as Chromium, Android, etc. could not use it. In addition, lack of -Windows support is a problem for building Windows applications, such -as Chrome. - - -How do you pronounce "Bazel"? ------------------------------ - -The same way as "basil" (the herb) in US English: "BAY-zel". It rhymes with -"hazel". IPA: /ˈbeɪzˌəl/ diff --git a/site/versions/master/governance.md b/site/versions/master/governance.md deleted file mode 100644 index ce49e7481b..0000000000 --- a/site/versions/master/governance.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -layout: contribute -title: Governance ---- - -# Governance - -The Bazel project is led by a core group of contributors, initially Googlers, and managed by the -community. The group of core contributors is self-managing - core contributors are added by two -supporting votes from core contributors on the mailing list and no veto within four business days. -We expect that new contributors will submit a number of patches before they become core -contributors. - -## Accepting Contributions - -Please also see our [contribution guidelines](contributing.html). - -### Policy - -We use the following rules for accepting code contributions. This is written from the perspective -that there is a group of people who cooperatively support the project (the *core contributors*). In -contrast, external contributors are not actively supporting the project, but just contributing -individual changes. At this time, all core contributors work for Google (see below for the full -list), but this will hopefully change over time. - -1. We require all contributors to sign [Google's Contributor License - Agreement](https://cla.developers.google.com/). - -2. We accept well-written, well-tested contributions of rules written in - [Skylark](docs/skylark/concepts.html), in a `contrib/` directory or similar with clearly documented - support policies. - -3. We accept well-written, well-tested bug fixes to built-in rules. - -4. We accept well-written, well-tested feature contributions if a core contributor assumes support - responsibilities, i.e., readily answers support questions and works on bugs. This includes - feature contributions from external contributors. If there is no core contributor to support a - feature, then we will deprecate and subsequently delete the feature - we will give three months' - notice in such cases. - -5. We will not accept untested changes, except in very rare cases. - -6. We require a pre-commit code review from a core contributor for all changes. For the time being, - we will have to continue making changes across the internal and external code bases, which will - be reviewed internal to Google. - -7. We will roll back changes if they break the internal development processes of any of the core - contributors. - -8. We will move towards an open governance model where multiple parties have commit access, - roll-back rights, and can provide explicit support for features or rules. - -9. We will work with interested parties to improve existing extension points and to establish new - extension points if they do not run counter to the internal requirements of any of the core - contributors. - -## Are you done open sourcing Bazel? - -Open sourcing Bazel is a work-in-progress. In particular, we're still working on open sourcing: - -* Many of our unit and integration tests (which should make contributing patches easier). -* Full IDE integration. - -Beyond code, we'd like to eventually have all code reviews, bug tracking, and design decisions -happen publicly, with the Bazel community involved. We are not there yet, so some changes will -simply appear in the Bazel repository without clear explanation. Despite this lack of -transparency, we want to support external developers and collaborate. Thus, we are opening up the -code, even though some of the development is still happening internal to Google. Please let us know -if anything seems unclear or unjustified as we transition to an open model. - -## Are there parts of Bazel that will never be open sourced? - -Yes, some of the code base either integrates with Google-specific technology or we have been looking -for an excuse to get rid of (or is some combination of the two). These parts of the code base are -not available on GitHub and probably never will be. - -### Core Contributors - -<p class="lead"> -Contact the core team at <a href="mailto:bazel-dev@googlegroups.com"> -bazel-dev@googlegroups.com</a>. -</p> - -The current group is: - - - [damienmg](https://github.com/damienmg) - - [hanwen](https://github.com/hanwen) - - [jhfield](https://github.com/jhfield) - - [kchodorow](https://github.com/kchodorow) - - [laszlocsomor](https://github.com/laszlocsomor) - - [laurentlb](https://github.com/laurentlb) - - [lberki](https://github.com/lberki) - - [philwo](https://github.com/philwo) - - [ulfjack](https://github.com/ulfjack) diff --git a/site/versions/master/hard_to_write_rules.md b/site/versions/master/hard_to_write_rules.md deleted file mode 100644 index dd341d31ad..0000000000 --- a/site/versions/master/hard_to_write_rules.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -layout: contribute -title: Why is it so difficult to write Bazel rules? ---- - -# Why is it difficult to write Bazel rules? - -We have heard feedback from various people multiple times that Bazel rules are -hard to write. There is no single root cause, but it’s due to a combination of -historical circumstances and intrinsic complexity in the problem domain. This -document attempts to give a high level overview of the specific issues that we -believe to be the main contributors. - -* Assumption: Aim for Correctness, Throughput, Ease of Use & Latency -* Assumption: Large Scale Repositories -* Assumption: BUILD-like Description Language -* Intrinsic: Remote Execution and Caching are Hard -* Historic: Hard Separation between Loading, Analysis, and Execution is - Outdated, but still affects the API -* Intrinsic: Using Change Information for Correct and Fast Incremental Builds - requires Unusual Coding Patterns -* Intrinsic: Avoiding Quadratic Time and Memory Consumption is Hard - -## Assumption: Aim for Correctness, Throughput, Ease of Use & Latency - -We assume that the build system needs to be first and foremost correct with -respect to incremental builds, i.e., for a given source tree, the output of the -same build should always be the same, regardless of what the output tree looks -like. In the first approximation, this means Bazel needs to know every single -input that goes into a given build step, such that it can rerun that step if any -of the inputs change. There are limits to how correct Bazel can get, as it leaks -some information such as date / time of the build, and ignores certain types of -changes such as changes to file attributes. Sandboxing helps ensure correctness -by preventing reads to undeclared input files. Besides the intrinsic limits of -the system, there are a few known correctness issues, most of which are related -to Fileset or the C++ rules, which are both hard problems. We have long-term -efforts to fix these. - -The second goal of the build system is to have high throughput; we are -permanently pushing the boundaries of what can be done within the current -machine allocation for a remote execution service. If the remote execution -service gets overloaded, nobody can get work done. - -Ease of use comes next, i.e., of multiple correct approaches with the same (or -similar) footprint of the remote execution service, we choose the one that is -easier to use. - -For the purpose of this document, latency denotes the time it takes from -starting a build to getting the intended result, whether that is a test log from -a passing or failing test, or an error message that a BUILD file has a -typo. - -Note that these goals often overlap; latency is as much a function of throughput -of the remote execution service as is correctness relevant for ease of use. - - -## Assumption: Large Scale Repositories - -The build system needs to operate at the scale of large repositories where large -scale means that it does not fit on a single hard drive, so it is impossible to -do a full checkout on virtually all developer machines. A medium-sized build -will need to read and parse tens of thousands of BUILD files, and evaluate -hundreds of thousands of globs. While it is theoretically possible to read all -BUILD files on a single machine, we have not yet been able to do so within a -reasonable amount of time and memory. As such, it is critical that BUILD files -can be loaded and parsed independently. - - -## Assumption: BUILD-like Description Language - -For the purpose of this document, we assume a configuration language that is -roughly similar to BUILD files, i.e., declaration of library and binary rules -and their interdependencies. BUILD files can be read and parsed independently, -and we avoid even looking at source files whenever we can (except for -existence). - - -## Intrinsic: Remote Execution and Caching are Hard - -Remote execution and caching improve build times in large repositories by -roughly two orders of magnitude compared to running the build on a single -machine. However, the scale at which it needs to perform is staggering: Google's -remote execution service is designed to handle a huge number of requests per -second, and the protocol carefully avoids unnecessary roundtrips as well as -unnecessary work on the service side. - -At this time, the protocol requires that the build system knows all inputs to a -given action ahead of time; the build system then computes a unique action -fingerprint, and asks the scheduler for a cache hit. If a cache hit is found, -the scheduler replies with the digests of the output files; the files itself are -addressed by digest later on. However, this imposes restrictions on the Bazel -rules, which need to declare all input files ahead of time. - - -## Historic: Hard Separation between Loading, Analysis, and Execution is Outdated, but still affects the API - -Technically, it is sufficient for a rule to know the input and output files of -an action just before the action is sent to remote execution. However, the -original Bazel code base had a strict separation of loading packages, then -analyzing rules using a configuration (command-line flags, essentially), and -only then running any actions. This distinction is still part of the rules API -today, even though the core of Bazel no longer requires it (more details below). - -That means that the rules API requires a declarative description of the rule -interface (what attributes it has, types of attributes). There are some -exceptions where the API allows custom code to run during the loading phase to -compute implicit names of output files and implicit values of attributes. For -example, a java_library rule named ‘foo’ implicitly generates an output named -‘libfoo.jar’, which can be referenced from other rules in the build graph. - -Furthermore, the analysis of a rule cannot read any source files or inspect the -output of an action; instead, it needs to generate a partial directed bipartite -graph of build steps and output file names that is only determined from the rule -itself and its dependencies. - - -## Intrinsic: Using Change Information for Correct and Fast Incremental Builds requires Unusual Coding Patterns - -Above, we argued that in order to be correct, Bazel needs to know all the input -files that go into a build step in order to detect whether that build step is -still up-to-date. The same is true for package loading and rule analysis, and we -have designed [Skyframe] (http://www.bazel.io/docs/skyframe.html) to handle this -in general. Skyframe is a graph library and evaluation framework that takes a -goal node (such as ‘build //foo with these options’), and breaks it down into -its constituent parts, which are then evaluated and combined to yield this -result. As part of this process, Skyframe reads packages, analyzes rules, and -executes actions. - -At each node, Skyframe tracks exactly which nodes any given node used to compute -its own output, all the way from the goal node down to the input files (which -are also Skyframe nodes). Having this graph explicitly represented in memory -allows the build system to identify exactly which nodes are affected by a given -change to an input file (including creation or deletion of an input file), doing -the minimal amount of work to restore the output tree to its intended state. - -As part of this, each node performs a dependency discovery process; i.e., each -node can declare dependencies, and then use the contents of those dependencies -to declare even further dependencies. In principle, this maps well to a -thread-per-node model. However, medium-sized builds contain hundreds of -thousands of Skyframe nodes, which isn’t easily possible with current Java -technology (and for historical reasons, we’re currently tied to using Java, so -no lightweight threads and no continuations). - -Instead, Bazel uses a fixed-size thread pool. However, that means that if a node -declares a dependency that isn’t available yet, we may have to abort that -evaluation and restart it (possibly in another thread), when the dependency is -available. This, in turn, means that nodes should not do this excessively; a -node that declares N dependencies serially can potentially be restarted N times, -costing O(N^2) time. Instead, we aim for up-front bulk declaration of -dependencies, which sometimes requires reorganizing the code, or even splitting -a node into multiple nodes to limit the number of restarts. - -Note that this technology isn’t currently available in the rules API; instead, -the rules API is still defined using the legacy concepts of loading, analysis, -and execution phases. However, a fundamental restriction is that all accesses to -other nodes have to go through the framework so that it can track the -corresponding dependencies. Regardless of the language in which the build system -is implemented or in which the rules are written (they don’t have to be the -same), rule authors must not use standard libraries or patterns that bypass -Skyframe. For Java, that means avoiding java.io.File as well as any form of -reflection, and any library that does either. Libraries that support dependency -injection of these low-level interfaces still need to be setup correctly for -Skyframe. - -This strongly suggests to avoid exposing rule authors to a full language runtime -in the first place. The danger of accidental use of such APIs is just too big - -several Bazel bugs in the past were caused by rules using unsafe APIs, even -though the rules were written by the Bazel team, i.e., by the domain experts. - - -## Intrinsic: Avoiding Quadratic Time and Memory Consumption is Hard - -To make matters worse, apart from the requirements imposed by Skyframe, the -historical constraints of using Java, and the outdatedness of the rules API, -accidentally introducting quadratic time or memory consumption is a fundamental -problem in any build system based on library and binary rules. There are two -very common patterns that introduce quadratic memory consumption (and therefore -quadratic time consumption). - -1. Chains of Library Rules -Consider the case of a chain of library rules A depends on B, depends on C, and -so on. Then, we want to compute some property over the transitive closure of -these rules, such as the Java runtime classpath, or the C++ linker command for -each library. Naively, we might take a standard list implementation; however, -this already introduces quadratic memory consumption: the first library -contains one entry on the classpath, the second two, the third three, and so -on, for a total of 1+2+3+...+N = O(N^2) entries. - -2. Binary Rules Depending on the Same Library Rules -Consider the case where a set of binaries that depend on the same library -rules; for example, you might have a number of test rules that test the same -library code. Let’s say out of N rules, half the rules are binary rules, and -the other half library rules. Now consider that each binary makes a copy of -some property computed over the transitive closure of library rules, such as -the Java runtime classpath, or the C++ linker command line. For example, it -could expand the command line string representation of the C++ link action. N/2 -copies of N/2 elements is O(N^2) memory. - - -### Custom Collections Classes to Avoid Quadratic Complexity - -Bazel is heavily affected by both of these scenarios, so we introduced a set of -custom collection classes that effectively compress the information in memory by -avoiding the copy at each step. Almost all of these data structures have set -semantics, so we called the class NestedSet. The majority of changes to reduce -Bazel’s memory consumption over the past several years were changes to use -NestedSet instead of whatever was previously used. - -Unfortunately, usage of NestedSet does not automatically solve all the issues; -in particular, even just iterating over a NestedSet in each rule re-introduces -quadratic time consumption. NestedSet also has some helper methods to facilitate -interoperability with normal collections classes; unfortunately, accidentally -passing a NestedSet to one of these methods leads to copying behavior, and -reintroduces quadratic memory consumption. diff --git a/site/versions/master/roadmap.md b/site/versions/master/roadmap.md deleted file mode 100644 index 1eec7a2498..0000000000 --- a/site/versions/master/roadmap.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -layout: contribute -title: Roadmap ---- - -# Bazel Feature Roadmap - -This document describes the Bazel team's plans for introducing features that -will be incorporated into version 1.0. Note that this roadmap only includes -features that the Bazel team itself intends to support. We anticipate that a -number of other features will be added by code contributors. - -For the alpha and beta releases, the Bazel team will maintain two code -repositories: - -* A Google-internal repository, containing both Bazel code and - Google-specific extensions and features -* An external [GitHub repository](https://github.com/bazelbuild/bazel), - containing only the Bazel code. - -We anticipate making the external repository *primary* in the future, that is, -code from Google and non-Google contributors will be committed and tested in the -external repository first, then imported into the internal repository. For -the alpha and beta releases, however, the internal repository will be primary. -Changes to Bazel code will be frequently pushed from the internal to -the external repository. - -## Feature list - -In the following table, each feature is associated with a corresponding -milestone. The convention for the priorities are: - -* P0 feature will block the milestone; we will delay the milestone date - until the feature is shipped. -* P1 feature can delay the milestone if the feature can be shipped with a - reasonable delay (2 months max). -* P2 feature will be dropped and rescheduled for later rather than delaying - the milestone. - -We will update this list when reaching each milestone; some milestones may also -be refined if appropriate. - -<table class="table table-condensed table-bordered"> - <colgroup> - <col class="roadmap-col-phase"/> - <col class="roadmap-col-milestone"/> - <col class="roadmap-col-date"/> - <col class="roadmap-col-features"/> - </colgroup> - <thead> - <tr> - <th>Phase</th> - <th>Milestone</th> - <th>Target date</th> - <th>Features</th> - </tr> - </thead> - <tbody> - <tr> - <td rowspan="9"><b><a name="alpha"></a>Alpha</b></td> - <td rowspan="9"><b>Alpha</b><br/><span class="label label-default">Released</span></td> - <td rowspan="9"><b>2015‑03‑24</b></td> - <td>Linux & OS X Support</td> - </tr> - <tr><td>C++ (<a href="http://bazel.io/docs/be/c-cpp.html#cc_binary">build</a> and <a href="http://bazel.io/docs/be/c-cpp.html#cc_test">test</a>)</td></tr> - <tr><td>Java (<a href="http://bazel.io/docs/be/java.html#java_binary">build</a> and <a href="http://bazel.io/docs/be/java.html#java_test">test</a>)</td></tr> - <tr><td>Objective-C for iOS (<a href="http://bazel.io/docs/be/objective-c.html#objc_binary">build</a>)</td></tr> - <tr><td>Python (<a href="http://bazel.io/docs/be/python.html#py_binary">build</a>)</td></tr> - <tr><td>iOS applications (<a href="http://bazel.io/docs/be/objective-c.html#ios_application">build</a>)</td></tr> - <tr><td>Skylark extension mechanism (<a href="http://bazel.io/docs/skylark/index.html">build</a>)</td></tr> - <tr><td>Basic test suite on GitHub</td></tr> - <tr><td>Support for fetching dependencies from <a href="http://bazel.io/docs/be/workspace.html#maven_jar">Maven repositories</a> - and <a href="http://bazel.io/docs/be/workspace.html#http_archive">web servers</a></td></tr> - <tr> - <td rowspan="30"><b><a name="beta"></a>Beta</b></td> - <td rowspan="9"> - <a href="https://github.com/bazelbuild/bazel/releases/tag/0.1.0"><b>0.1</b> - <br/><span class="label label-default">Released</span></a> - </td> - <td rowspan="9"><b>2015‑09‑01</b></td> - <td>P0. Binary distribution for Linux & OS X</td< - </tr> - <tr><td>P0. Public <a href="http://ci.bazel.io">continuous integration system</a></td></tr> - <tr><td>P0. Support for <a href="http://bazel.io/docs/external.html">fetching transitive dependencies from Maven Central</a></td></tr> - <tr><td>P0. Android application (<a href="http://bazel.io/docs/be/android.html#android_binary">build</a> - and <a href="http://bazel.io/docs/bazel-user-manual.html#mobile-install">install</a>)</td></tr> - <tr><td>P1. Support for <a href="http://bazel.io/docs/external.html">prefetching and caching remote dependencies</a></td></tr> - <tr><td>P1. Docker (<a href="http://bazel.io/docs/be/docker.html">build and load</a>)</td></tr> - <tr><td>P2. <a href="http://bazel.io/docs/bazel-user-manual.html#sandboxing">Sandboxing of actions for Linux</a></td></tr> - <tr><td>P2. AppEngine (<a href="http://bazel.io/docs/be/appengine.html">build and load</a>)</td></tr> - <tr><td>P2. <a href="http://bazel.io/blog/2015/07/29/dashboard-dogfood.html">Test result dashboard</a></tr></td> - <tr> - <td rowspan="5"> - <a href="https://github.com/bazelbuild/bazel/releases/tag/0.2.0"><b>0.2</b> - <br/><span class="label label-default">Released</span></a> - </td> - <td rowspan="5"><b>2016‑02‑18</b></td> - <td>P0. <a href="https://github.com/bazelbuild/bazel/tree/master/src/test/java/com/google/devtools">Significantly increase test coverage</a></td> - </tr> - <tr><td>P0. Support for fetching <a href="http://bazel.io/docs/external.html">remote</a> <a href="http://bazel.io/docs/be/functions.html#load">Skylark rules</a></td></tr> - <tr><td>P2. <a href="http://bazel.io/docs/be/go.html">Go language support (build and tests)</a></td></tr> - <tr><td>P2. <a href="https://github.com/bazelbuild/bazel/releases/latest">Debian packages for Bazel</a></td></tr> - <tr><td>P2. <a href="http://braumeister.org/formula/bazel">OS X homebrew recipe for distributing Bazel</a></td></tr> - <tr> - <td rowspan="5"> - <a href="https://github.com/bazelbuild/bazel/releases/tag/0.3.0"><b>0.3</b> - <br/><span class="label label-default">Released</span></a> - </td> - <td rowspan="5"><b>2016‑06‑10</b></td> - <td>P0. <a href="http://bazel.io/docs/windows.html">Bazel can bootstrap itself on Windows without requiring admin privileges</a></td></tr> - </tr> - <tr><td>P1. <a href="http://bazel.io/blog/2016/06/10/ide-support.html">Interface for IDE support</a></td></tr> - <tr><td>P1. IDE support for <a href="http://tulsi.bazel.io">Xcode (stable)</a> and <a href="https://github.com/bazelbuild/e4b">Eclipse (experimental)</a></td></tr> - <tr><td>P1. <a href="https://docs.google.com/document/d/1jKbNXOVp2T1zJD_iRnVr8k5D0xZKgO8blMVDlXOksJg">Custom remote repositories using Skylark</a></td></tr> - <tr><td>P2. <a href="https://github.com/bazelbuild/bazel/commit/79adf59e2973754c8c0415fcab45cd58c7c34697">Prototype for distributed caching of build artifact</a></td></tr> - <tr> - <td rowspan="2"><b>0.4</b></td> - <td rowspan="2"><b>2016‑08</b></td> - <td>P0. Persistent Java compiler is enabled</td> - </tr> - <tr><td>P2. Sandboxing of action for OS X</td></tr> - <tr> - <td rowspan="4"><b>0.5</b></td> - <td rowspan="4"><b>2016‑10</b></td> - <td>P0. Support for testing Android apps</td> - </tr> - <tr><td>P0. Bazel supports building Java, C++ and Python on Windows</td></tr> - <tr><td>P1. Distributed execution of actions</td></tr> - <tr><td>P2. Support for Swift language</td></tr> - <tr> - <td rowspan="2"><b>0.6</b></td> - <td rowspan="2"><b>2016‑11</b></td> - <td>P0. Searchable "hub" of Skylark rules</td> - </tr> - <tr><td>P2. Reference ("pull") remote docker images as an input to the build process</td></tr> - <tr> - <td rowspan="3"><b>0.7</b></td> - <td rowspan="3"><b>2017 Q1</b></td> - <td>P0. Full Windows support for Android: Android feature set is identical for Windows and Linux/OS X</tr> - </tr> - <tr><td>P1. Android Studio interoperability</td></tr> - <tr><td>P1. Support for testing iOS apps</td></tr> - <tr> - <td rowspan="3"><b><a name="stable"></a>Stable</b></td> - <td rowspan="3"><b>1.0</b></td> - <td rowspan="3"><b>2017 Q4</b></td> - <td>P0. Github repository is primary</td> - </tr> - <tr><td>P0. Extension APIs are stable and versioned</td></tr> - <tr><td>P1. Bazel is available in the Ubuntu and Debian package managers</td></tr> - </tbody> -</table> diff --git a/site/versions/master/users.md b/site/versions/master/users.md deleted file mode 100644 index cc96d5895b..0000000000 --- a/site/versions/master/users.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -layout: contribute -title: Bazel Users ---- - -# Corporate users of Bazel - -## [Ascend.io](https://ascend.io) - -Ascend is a Palo Alto startup that offers solutions for large data sets -analysis. Their motto is _Big data is hard. We make it easy_. - -## [Beeswax](https://www.beeswax.com/) (_in their own words_) - -"_Beeswax is a New York based startup that provides real time bidding as -service. Bazel powers their Jenkins based continuous integration and deployment -framework. Beeswax loves Bazel because it is blazingly fast, correct and well -supported across many languages and platforms._" - -## [Braintree](https://www.braintreepayments.com) - -Braintree, a PayPal subsidiary, develops payment solutions for websites and -applications. They use Bazel for parts of their internal build and Paul Gross -even posted a [nice piece about how their switch to -Bazel went](https://www.pgrs.net/2015/09/01/migrating-from-gradle-to-bazel/). - -## [Databricks](https://databricks.com) - -Databricks provides cloud-based integrated workspaces based on Apache Spark™. - -## [Interaxon](https://www.choosemuse.com/) - -InteraXon is a thought-controlled computing firm that creates hardware and -software platforms to convert brainwaves into digital signals. - -## [Improbable.io](https://improbable.io/) - -Improbable.io develops SpatialOS, a distributed operating system that enables -creating huge simulations inhabited by millions of complex entities. - -## [Makani](https://www.google.com/makani) - -Makani, now a Google subsidiary, develops energy kites and uses -Bazel to build their software (including their embedded C++ software). - -## [Peloton Technology](http://www.peloton-tech.com) - -Peloton Technology is an automated vehicle technology company that tackles -truck accidents and fuel use. They use Bazel to _enable reliable builds for -automotive safety systems_. - -## [Stripe](https://stripe.com) - -Stripe provides mobile payment solutions. They are the main maintainers of the -[Bazel Scala rules](https://github.com/bazelbuild/rules_scala). - -# Open-source projects using Bazel - -If you'd like your project listed here, please -[let us know](mailto:kchodorow@google.com?subject=My project uses Bazel)! - -## [CallBuilder](https://github.com/google/CallBuilder) - -A Java code generator that allows you to create a builder by writing one -function. - -## [Error Prone](https://github.com/google/error-prone) - -Catches common Java mistakes as compile-time errors. (Migration to Bazel is -in progress.) - -## [FFruit](https://gitlab.com/perezd/ffruit/) - -FFruit is a free & open source Android application to the popular service -[Falling Fruit](https://fallingfruit.org). - -## [GRPC](http://www.grpc.io) - -A language-and-platform-neutral remote procedure call system. (Bazel is a -supported, although not primary, build system.) - -## [Gulava](http://www.github.com/google/gulava/) - -A Java code generator that lets you write Prolog-style predicates and use them -seamlessly from normal Java code. - -## [Heron](http://twitter.github.io/heron/) - -Heron is a realtime, distributed, fault-tolerant stream processing engine -from Twitter. - -## [Jsonnet](http://google.github.io/jsonnet/doc/) - -An elegant, formally-specified config generation language for JSON. (Bazel is a -supported build system.) - -## [Kythe](https://github.com/google/kythe) - -An ecosystem for building tools that work with code. - -## [PetitParser for Java](https://github.com/petitparser/java-petitparser) - -Grammars for programming languages are traditionally specified statically. They -are hard to compose and reuse due to ambiguities that inevitably arise. -PetitParser combines ideas from scannnerless parsing, parser combinators, -parsing expression grammars and packrat parsers to model grammars and parsers -as objects that can be reconfigured dynamically. - -## [TensorFlow](http://tensorflow.org) - -An open source software library for machine intelligence. - -## [Trunk](https://github.com/mzhaom/trunk) - -A collection of C++/Java opensource projects with BUILD files so they -can be built with Bazel with out of box support for protobuf and -grpc (maybe thrift). - -## [Turbo Santa](https://github.com/turbo-santa/turbo-santa-common) - -A platform-independent GameBoy emulator. - -## [XIOSim](https://github.com/s-kanev/XIOSim) - -XIOSim is a detailed user-mode microarchitectural simulator for the x86 architecture. - diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html index 0e7ab18d05..e447335010 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html +++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html @@ -10,7 +10,7 @@ <i>Tags</i> on non-test rules are used to control sandboxed execution of <code>genrule</code>s and -<a href="{{ page.version_prefix }}/docs/skylark/index.html">Skylark</a> +<a href="/docs/skylark/index.html">Skylark</a> actions, and for parsing by humans and/or external tools. </p> diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/be-nav.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/be-nav.vm index c8951e6c3c..cd7eabb1bc 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/be/be-nav.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/be-nav.vm @@ -1,4 +1,4 @@ -#set ($path = "{{ page.version_prefix }}/docs/be") +#set ($path = "/docs/be") #set ($bazelbuildGithub = "https://github.com/bazelbuild") <h3>Build Encyclopedia</h3> diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm index 07a666da68..780716cfe1 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm @@ -40,7 +40,7 @@ build_test(name = ...) <p>This will execute the - <a href="{{ page.version_prefix }}/docs/skylark/index.html">Skylark</a> + <a href="/docs/skylark/index.html">Skylark</a> module <code>tools/build_rules/build_test.bzl</code> and import the symbol <code>build_test</code> in the local environment. This is useful for using macros or for sharing values between multiple BUILD files. By @@ -684,7 +684,7 @@ sh_binary( com_example_some_project as the workspace name. </p> -<p><a href="workspace.html">Remote repository</a> rule names must be +<p><a href="/docs/be/workspace.html">Remote repository</a> rule names must be valid workspace names. For example, you could have <code>maven_jar(name = "foo")</code>, but not <code>maven_jar(name = "foo.bar")</code>, as Bazel would attempt to write a diff --git a/src/main/java/com/google/devtools/build/docgen/templates/skylark-category.vm b/src/main/java/com/google/devtools/build/docgen/templates/skylark-category.vm index 604f89abf5..b635e48e7d 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/skylark-category.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/skylark-category.vm @@ -10,7 +10,7 @@ ${category.description} <ul> #foreach ($module in $modules) -<li><a href="{{ page.version_prefix }}/docs/skylark/lib/${module.name}.html">${module.title}</a></li> +<li><a href="/docs/skylark/lib/${module.name}.html">${module.title}</a></li> #end </ul> </div> diff --git a/src/main/java/com/google/devtools/build/docgen/templates/skylark-nav.vm b/src/main/java/com/google/devtools/build/docgen/templates/skylark-nav.vm index 82e8240b82..96730fefdc 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/skylark-nav.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/skylark-nav.vm @@ -1,5 +1,5 @@ -<li><a href="{{ page.version_prefix }}/docs/skylark/lib/skylark-builtin.html">Builtin Types and Modules</a></li> -<li><a href="{{ page.version_prefix }}/docs/skylark/lib/skylark-configuration-fragment.html">Configuration fragments</a></li> -<li><a href="{{ page.version_prefix }}/docs/skylark/lib/skylark-provider.html">Providers</a></li> -<li><a href="{{ page.version_prefix }}/docs/skylark/lib/globals.html">Globals</a></li> -<li><a href="{{ page.version_prefix }}/docs/skylark/lib/native.html">Native Module</a></li> +<li><a href="/docs/skylark/lib/skylark-builtin.html">Builtin Types and Modules</a></li> +<li><a href="/docs/skylark/lib/skylark-configuration-fragment.html">Configuration fragments</a></li> +<li><a href="/docs/skylark/lib/skylark-provider.html">Providers</a></li> +<li><a href="/docs/skylark/lib/globals.html">Globals</a></li> +<li><a href="/docs/skylark/lib/native.html">Native Module</a></li> diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD index be6bc984fa..3af477b4eb 100644 --- a/src/test/java/com/google/devtools/build/lib/BUILD +++ b/src/test/java/com/google/devtools/build/lib/BUILD @@ -776,7 +776,7 @@ java_test( size = "medium", srcs = ["packages/BazelDocumentationTest.java"], data = [ - "//site:versions/master/docs/bazel-user-manual.html", + "//site:docs/bazel-user-manual.html", ], test_class = "com.google.devtools.build.lib.packages.BazelDocumentationTest", deps = [ diff --git a/src/test/java/com/google/devtools/build/lib/packages/BazelDocumentationTest.java b/src/test/java/com/google/devtools/build/lib/packages/BazelDocumentationTest.java index 8167bd25d7..70fe645b37 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/BazelDocumentationTest.java +++ b/src/test/java/com/google/devtools/build/lib/packages/BazelDocumentationTest.java @@ -42,7 +42,7 @@ public class BazelDocumentationTest { */ @Test public void testBazelUserManual() throws Exception { - String documentationFilePath = "site/versions/master/docs/bazel-user-manual.html"; + String documentationFilePath = "site/docs/bazel-user-manual.html"; if (OS.getCurrent() == OS.WINDOWS) { documentationFilePath = WindowsTestUtil.getRunfile("io_bazel/" + documentationFilePath); } |