blob: fb05cfa5c9f20b1a00adda8d6a2542e4c8a1048c [file] [log] [blame]
---
title: 'Workspace Rules'
---
Workspace rules are used to pull in [external dependencies](/versions/8.4.2/docs/external), typically
source code located outside the main repository.
*Note:* besides the native workspace rules, Bazel also embeds various
[Starlark workspace rules](/versions/8.4.2/rules/lib/repo/index), in particular those to deal
with git repositories or archives hosted on the web.
## Rules
* [bind](#bind)
* [local\_repository](#local_repository)
* [new\_local\_repository](#new_local_repository)
## bind
[View rule sourceopen\_in\_new](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/repository/BindRule.java)
```
bind(name, actual, compatible_with, deprecation, distribs, features, licenses, restricted_to, tags, target_compatible_with, testonly, visibility)
```
*Warning: use of `bind()` is not recommended. See "[Consider removing bind](https://github.com/bazelbuild/bazel/issues/1952)" for a long
discussion of its issues and alternatives. In particular, consider the use of
[`repo_mapping`
repository attributes](https://bazel.build/versions/8.4.2/rules/repository_rules#attributes).*
*Warning: `select()` cannot be used in `bind()`. See the [Configurable Attributes FAQ](/versions/8.4.2/docs/configurable-attributes#bind-select) for
details.*
Gives a target an alias in the `//external` package.
The `//external` package is not a "normal" package: there is no external/ directory,
so it can be thought of as a "virtual package" that contains all bound targets.
#### Examples
To give a target an alias, `bind` it in the *WORKSPACE* file. For example,
suppose there is a `java_library` target called
`//third_party/javacc-v2`. This can be aliased by adding the following to the
*WORKSPACE* file:
```
bind(
name = "javacc-latest",
actual = "//third_party/javacc-v2",
)
```
Now targets can depend on `//external:javacc-latest` instead of
`//third_party/javacc-v2`. If javacc-v3 is released, the `bind` rule can be
updated and all of the BUILD files depending on `//external:javacc-latest` will now
depend on javacc-v3 without needing to be edited.
Bind can also be used to make targets in external repositories available to your workspace.
For example, if there is a remote repository named `@my-ssl` imported in the
*WORKSPACE* file and it has a cc\_library target `//src:openssl-lib`, you can
create an alias for this target using `bind`:
```
bind(
name = "openssl",
actual = "@my-ssl//src:openssl-lib",
)
```
Then, in a BUILD file in your workspace, the bound target can be used as follows:
```
cc_library(
name = "sign-in",
srcs = ["sign_in.cc"],
hdrs = ["sign_in.h"],
deps = ["//external:openssl"],
)
```
Within `sign_in.cc` and `sign_in.h`, the header files exposed by
`//external:openssl` can be referred to using their path relative to their repository
root. For example, if the rule definition for `@my-ssl//src:openssl-lib` looks like
this:
```
cc_library(
name = "openssl-lib",
srcs = ["openssl.cc"],
hdrs = ["openssl.h"],
)
```
Then `sign_in.cc`'s includes might look like this:
```
#include "sign_in.h"
#include "src/openssl.h"
```
### Arguments
| Attributes | |
| --- | --- |
| `name` | [Name](/versions/8.4.2/concepts/labels#target-names); required A unique name for this target. |
| `actual` | [Label](/versions/8.4.2/concepts/labels); default is `None` The target to be aliased. This target must exist, but can be any type of rule (including bind). If this attribute is omitted, rules referring to this target in `//external` will simply not see this dependency edge. Note that this is different from omitting the `bind` rule completely: it is an error if an `//external` dependency does not have an associated `bind` rule. |
## local\_repository
[View rule sourceopen\_in\_new](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryRule.java)
```
local_repository(name, path, repo_mapping)
```
Allows targets from a local directory to be bound. This means that the current repository can
use targets defined in this other directory. See the [bind
section](/versions/8.4.2/reference/be/workspace#bind_examples) for more details.
#### Examples
Suppose the current repository is a chat client, rooted at the directory *~/chat-app*. It
would like to use an SSL library which is defined in a different repository: *~/ssl*. The
SSL library has a target `//src:openssl-lib`.
The user can add a dependency on this target by adding the following lines to
*~/chat-app/WORKSPACE*:
```
local_repository(
name = "my-ssl",
path = "/home/user/ssl",
)
```
Targets would specify `@my-ssl//src:openssl-lib` as a dependency to depend on this
library.
### Arguments
| Attributes | |
| --- | --- |
| `name` | [Name](/versions/8.4.2/concepts/labels#target-names); required A unique name for this target. |
| `path` | String; required The path to the local repository's directory. This must be a path to the directory containing the repository's *WORKSPACE* file. The path can be either absolute or relative to the main repository's *WORKSPACE* file. |
| `repo_mapping` | Dictionary: String -> String; default is `{}` A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository. For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `"@foo"` (such as a dependency on `"@foo//some:target"`), it should actually resolve that dependency within globally-declared `"@bar"` (`"@bar//some:target"`). |
## new\_local\_repository
[View rule sourceopen\_in\_new](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryRule.java)
```
new_local_repository(name, build_file, build_file_content, path, repo_mapping, workspace_file, workspace_file_content)
```
Allows a local directory to be turned into a Bazel repository. This means that the current
repository can define and use targets from anywhere on the filesystem.
This rule creates a Bazel repository by creating a WORKSPACE file and subdirectory containing
symlinks to the BUILD file and path given. The build file should create targets relative to the
`path`. For directories that already contain a WORKSPACE file and a BUILD file, the
[`local_repository`](#local_repository) rule can be used.
#### Examples
Suppose the current repository is a chat client, rooted at the directory *~/chat-app*. It
would like to use an SSL library which is defined in a different directory: *~/ssl*.
The user can add a dependency by creating a BUILD file for the SSL library
(~/chat-app/BUILD.my-ssl) containing:
```
java_library(
name = "openssl",
srcs = glob(['*.java'])
visibility = ["//visibility:public"],
)
```
Then they can add the following lines to *~/chat-app/WORKSPACE*:
```
new_local_repository(
name = "my-ssl",
path = "/home/user/ssl",
build_file = "BUILD.my-ssl",
)
```
This will create a `@my-ssl` repository that symlinks to */home/user/ssl*.
Targets can depend on this library by adding `@my-ssl//:openssl` to a target's
dependencies.
You can also use `new_local_repository` to include single files, not just
directories. For example, suppose you had a jar file at /home/username/Downloads/piano.jar. You
could add just that file to your build by adding the following to your WORKSPACE file:
```
new_local_repository(
name = "piano",
path = "/home/username/Downloads/piano.jar",
build_file = "BUILD.piano",
)
```
And creating the following BUILD.piano file:
```
java_import(
name = "play-music",
jars = ["piano.jar"],
visibility = ["//visibility:public"],
)
```
Then targets can depend on `@piano//:play-music` to use piano.jar.
### Arguments
| Attributes | |
| --- | --- |
| `name` | [Name](/versions/8.4.2/concepts/labels#target-names); required A unique name for this target. |
| `build_file` | [Name](/versions/8.4.2/concepts/labels#target-names); default is `None` A file to use as a BUILD file for this directory. Either build\_file or build\_file\_content must be specified. This attribute is a label relative to the main workspace. The file does not need to be named BUILD, but can be. (Something like BUILD.new-repo-name may work well for distinguishing it from the repository's actual BUILD files.) |
| `build_file_content` | String; default is `""` The content for the BUILD file for this repository. Either build\_file or build\_file\_content must be specified. |
| `path` | String; required A path on the local filesystem. This can be either absolute or relative to the main repository's WORKSPACE file. |
| `repo_mapping` | Dictionary: String -> String; default is `{}` A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository. For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `"@foo"` (such as a dependency on `"@foo//some:target"`), it should actually resolve that dependency within globally-declared `"@bar"` (`"@bar//some:target"`). |
| `workspace_file` | [Name](/versions/8.4.2/concepts/labels#target-names); default is `None` The file to use as the WORKSPACE file for this repository. Either workspace\_file or workspace\_file\_content can be specified, but not both. This attribute is a label relative to the main workspace. The file does not need to be named WORKSPACE, but can be. (Something like WORKSPACE.new-repo-name may work well for distinguishing it from the repository's actual WORKSPACE files.) |
| `workspace_file_content` | String; default is `""` The content for the WORKSPACE file for this repository. Either workspace\_file or workspace\_file\_content can be specified, but not both. |