blob: ca0f5786554ded6c59a0036699142b79f2bac86b [file] [log] [blame] [view]
fweacae1cd2022-02-17 09:45:38 -08001Project: /_project.yaml
2Book: /_book.yaml
3
4# Best Practices
5
6This page assumes you are familiar with Bazel and provides guidelines and
7advice on structuring your projects to take full advantage of Bazel's features.
8
9The overall goals are:
10
11- To use fine-grained dependencies to allow parallelism and incrementality.
12- To keep dependencies well-encapsulated.
13- To make code well-structured and testable.
14- To create a build configuration that is easy to understand and maintain.
15
16These guidelines are not requirements: few projects will be able to adhere to
17all of them. As the man page for lint says, "A special reward will be presented
18to the first person to produce a real program that produces no errors with
19strict checking." However, incorporating as many of these principles as possible
20should make a project more readable, less error-prone, and faster to build.
21
22This page uses the requirement levels described in
23[this RFC](https://www.ietf.org/rfc/rfc2119.txt){: .external}.
24
25## Running builds and tests {:#running-builds-tests}
26
27A project should always be able to run `bazel build //...` and
28`bazel test //...` successfully on its stable branch. Targets that are necessary
29but do not build under certain circumstances (such as,require specific build
30flags, don't build on a certain platform, require license agreements) should be
31tagged as specifically as possible (for example, "`requires-osx`"). This
32tagging allows targets to be filtered at a more fine-grained level than the
33"manual" tag and allows someone inspecting the `BUILD` file to understand what
34a target's restrictions are.
35
36## Third-party dependencies {:#third-party-dependencies}
37
38You may declare third-party dependencies:
39
40* Either declare them as remote repositories in the `WORKSPACE` file.
41* Or put them in a directory called `third_party/` under your workspace directory.
42
43## Depending on binaries {:#binaries}
44
45Everything should be built from source whenever possible. Generally this means
46that, instead of depending on a library `some-library.so`, you'd create a
47`BUILD` file and build `some-library.so` from its sources, then depend on that
48target.
49
50Always building from source ensures that a build is not using a library that
51was built with incompatible flags or a different architecture. There are also
52some features like coverage, static analysis, or dynamic analysis that only
53work on the source.
54
55## Versioning {:#versioning}
56
57Prefer building all code from head whenever possible. When versions must be
58used, avoid including the version in the target name (for example, `//guava`,
59not `//guava-20.0`). This naming makes the library easier to update (only one
60target needs to be updated). It's also more resilient to diamond dependency
61issues: if one library depends on `guava-19.0` and one depends on `guava-20.0`,
62you could end up with a library that tries to depend on two different versions.
63If you created a misleading alias to point both targets to one `guava` library,
64then the `BUILD` files are misleading.
65
66## Using the `.bazelrc` file {:#bazelrc-file}
67
68For project-specific options, use the configuration file your
69`{{ '<var>' }}workspace{{ '</var>' }}/.bazelrc` (see [bazelrc format](/docs/bazelrc)).
70
71If you want to support per-user options for your project that you **do not**
72want to check into source control, include the line:
73
74```
75try-import %workspace%/user.bazelrc
76```
77(or any other file name) in your `{{ '<var>' }}workspace{{ '</var>' }}/.bazelrc`
78and add `user.bazelrc` to your `.gitignore`.
79
80## Packages {:#packages}
81
82Every directory that contains buildable files should be a package. If a `BUILD`
83file refers to files in subdirectories (such as, `srcs = ["a/b/C.java"]`) it's
84a sign that a `BUILD` file should be added to that subdirectory. The longer
85this structure exists, the more likely circular dependencies will be
86inadvertently created, a target's scope will creep, and an increasing number
87of reverse dependencies will have to be updated.