// Copyright 2014 Google Inc. 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.workspace; import static com.google.devtools.build.lib.packages.Attribute.attr; import static com.google.devtools.build.lib.packages.Type.LABEL; import com.google.devtools.build.lib.analysis.BaseRuleClasses.BaseRule; import com.google.devtools.build.lib.analysis.BlazeRule; 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; /** * Binds an existing target to a target in the virtual //external package. */ @BlazeRule(name = "bind", type = RuleClassType.WORKSPACE, ancestors = {BaseRule.class}, factoryClass = Bind.class) 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).
*/ .add(attr("actual", LABEL).allowedFileTypes()) .setWorkspaceOnly() .build(); } } /* ${ATTRIBUTE_SIGNATURE}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 could 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 binding 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 refer to external repositories' targets. For example, if there is a
remote repository named @my-ssl
imported in the WORKSPACE file. If the
@my-ssl
repository has a cc_library target //src:openssl-lib
, you
could make this target accessible for your program to depend on by using bind
:
bind( name = "openssl", actual = "@my-ssl//src:openssl-lib", )
BUILD files cannot use labels that include a repository name
("@repository-name//package-name:target-name"), so the only way to depend on a target from
another repository is to bind
it in the WORKSPACE file and then refer to it by its
aliased name in //external
from a BUILD file.
For example, in a BUILD file, the bound target could 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 by 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 first lines might look like this:
#include "sign_in.h" #include "src/openssl.h"*/