// Copyright 2014 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.lib.rules.repository; import static com.google.devtools.build.lib.packages.Attribute.attr; import static com.google.devtools.build.lib.packages.BuildType.LABEL; import com.google.devtools.build.lib.analysis.BaseRuleClasses.BaseRule; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; import com.google.devtools.build.lib.util.FileTypeSet; /** * Binds an existing target to a target in the virtual //external package. */ public final class BindRule implements RuleDefinition { @Override public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) { return builder /* 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.
Warning: use of bind()
is not recommended. See "Consider removing bind" for a long
discussion of its issues and alternatives.
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.
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"*/