I'm having trouble understanding how to construct proper label
forms when dealing with external repositories (directories with their own WORKSPACE
).
What is the semantic meaning of characters like /
, :
, //
or @
?
For example:
@foo/bar
@foo:bar
//foo
foo
Do they preserve their meaning when used in an external repository? Also, is //external
special in any way?
/
is a separator for package and target names.
relative/package/to/my:target
//absolute/package/to:my/file/target.java
A package is defined as a directory containing a BUILD
or BUILD.bazel
file.
:
is the lexeme for selecting a rule or file target in a package.
//my/package:my_java_binary
Selects the target my_java_binary
defined in <workspace root>/my/package/BUILD
//my/package:file.go
Selects the file <workspace root>/my/package/file.go
if <workspace root>/my/package/BUILD
exists, and if there's a rule in that BUILD file that references it.
//:my/nested/file.txt
Selects the file <workspace root>/my/nested/file.txt
if <workspace root>/BUILD
exists, but not in the my
and my/nested
subdirectories.
//
is the location of the current or closest parent directory containing a WORKSPACE file.
Otherwise known as workspace root.
@
is used for referencing a repository by its name when used to the left of //
@io_bazel_rules_scala//scala:scala.bzl
: look into your WORKSPACE file for a repository named io_bazel_rules_scala
. Usually defined using http_archive
or git_repository
.@//my/package:target
: @
alone refers to the current workspace.As of Bazel 0.16.0, @
can be used in package names.
Do they preserve their meaning when used in an external repository?
Yes, think of the @<repository>
syntax as a namespace mechanism.
Also, is //external special in any way?
Yes, it's used for the bind
function, which is not recommended anymore. bind
lets you give a target an alias in //external
.