# Workspace Rules

Workspace rules are used to pull in external dependencies, typically source code located outside the main repository.

Note: besides the native workspace rules, Bazel also embeds various Starlark workspace rules, in particular those to deal with git repositories or archives hosted on the web.

## Rules

- bind
- local_repository
- new_local_repository

## bind

    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" for a long discussion of its issues and alternatives. In particular, consider the use of `repo_mapping` repository attributes.

Warning: `select()` cannot be used in `bind()`. See the Configurable Attributes FAQ 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; required` A unique name for this target.
`actual` | `Label; optional` 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

    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 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; 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; optional` 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

    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` 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; required` A unique name for this target.
`build_file` | `String; optional` 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; optional` 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; optional` 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` | `String; optional` 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; optional` The content for the WORKSPACE file for this repository. Either workspace_file or workspace_file_content can be specified, but not both.