Bazel WORKSPACE文件编写

WORKSPACE文件主要就是命名workspace以及声明外部的依赖,这就包括外部依赖的获取方式及获取方法。

外部依赖

https://docs.bazel.build/versions/master/external.html
WORKSPACE文件告诉Bazel如何去得到其他的工程源,然后package中的BUILD文件就可以根据WORKSPACE中的外部target名字写依赖关系。

先举个例子来看下在本地的两个工程如何实现依赖关系:
/
  home/
    user/
      project1/
        WORKSPACE
        BUILD
        srcs/
          ...
      project2/
        WORKSPACE
        BUILD
        my-libs/
project1希望能依赖project2/BUILD下的target :foo,需要指明project2可以在/home/user/project2中被找到,而且接下来project1的BUILD就可以写依赖关系:@project2//:foo
WORKSPACE文件允许用户的目标依赖其他文件系统的目标或者从网上下载的目标。
WORKSPACE文件的语法和BUILD文件一致,不过会用到一些特定的内置rule,细节参考下一个章节的内容。

一共有三种外部依赖的主要类型:


  • 依赖于其他Bazel工程
根据这个Bazel工程所处的位置不同,调用不同的内置rule来获得:
git_repository:git仓库
http_archive:网络下载

假如现在有个工程my-project/,需要依赖与另一个工程coworkers-project/。这两个都是Bazel工程,那么需要在my_project/WORKSPACE下添加:
local_repository(
    name = "coworkers_project",
    path = "/path/to/coworkers-project",
)
然后对于coworker的target //foo:bar就可以在自己的工程中通过@coworkers_project//foo:bar来依赖引用。
  • 依赖于其他非Bazel工程
还有一种情况是另外一个工程不是Bazel工程,那么就需要另外一种方法来添加依赖引用
new_git_repository:git仓库
new_http_archive:网络下载
还是上面那两个工程,不同的是工程coworkers-project/不再是Bazel工程,此时需要在工程上做两个改动:
1、在my_project/WORKSPACE上添加
new_local_repository(
    name = "coworkers_project",
    path = "/path/to/coworkers-project",
    build_file = "coworker.BUILD",
)
其中build_file属性是规定了一个BUILD文件让bazel来build处理依赖工程
2、添加coworker.BUILD
cc_library(
    name = "some-lib",
    srcs = glob(["**"]),
    visibility = ["//visibility:public"],
)
这样就可以通过@coworkers_project//:some-lib来添加依赖。
  • 依赖于外部包

Maven仓库:Use the rule maven_jar (and optionally the rule maven_server) to download a jar from a Maven repository and make it available as a Java dependency.


获取外部依赖

除了通过bazel build可以自动获取外部依赖之外,还可以通过bazel fetch来获得。


传递依赖

Bazel只会读取自己workspace下面的WORKSPACE依赖,假如我们的工程是A,依赖于一个工程B,在B的工程WORKSPACE中写了依赖C,那么我们需要把B和C都加入到WORKSPACE中。这样会使得WORKSPACE很大,但是至少也避免了对于C的依赖版本不同。
另外可以使用git上一个工程,来根据已有的Maven pom.xml自动产生WORKSPACE文件: Generate external dependencies from Maven projects.

缓存外部依赖

Bazel会缓存外部依赖,并且只有在WORKSPACE文件更改后才再次下载和更新。

存放位置

所有的外部依赖会都下载到一个名为的软连接目录。具体的内容可以通过命令行获得:
ls $(bazel info output_base)/external
另外使用bazel clean不会删除外部依赖,如果想要删除需要使用bazel clean --expunge


Workspace Rules

https://docs.bazel.build/versions/master/be/workspace.html

  • bind
给target命别名,不推荐使用
  • git_repository
git_repository(namecommitinit_submodulesremotesha256tag)
这个有很多限制不推荐使用,用http_archive 来代替使得更加鲁棒以及安全性能。
  • http_archive
http_archive(namesha256strip_prefixtypeurlurls)
下载一个压缩格式的Bazel仓库,并解压出来,然后绑定使用。
比如:

http_archive(
    name = "my_ssl",
    url = "http://example.com/openssl.zip",
    sha256 = "03a58ac630e59778f328af4bcc4acb4f80208ed4",
)

然后可以通过@my_ssl//package:target来依赖索引
这个Rule有一个属性strip_prefix,用来消除前缀目录。
  • maven_jar
maven_jar(nameartifactrepositoryserversha1)

从Maven下载jar并且可以被使用
举例:
Suppose that the current repostory contains a java_library target that needs to depend on Guava. Using Maven, this dependency would be defined in the pom.xml file as:
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>18.0</version>
</dependency>
With Bazel, add the following lines to the WORKSPACE file:
maven_jar(
    name = "com_google_guava_guava",
    artifact = "com.google.guava:guava:18.0",
    sha1 = "cce0823396aa693798f8882e64213b1772032b09",
)
Targets can specify @com_google_guava_guava//jar as a dependency to depend on this jar.
属性介绍:
name:rule的唯一名字
artifact <groupId>:<artifactId>:<version>
repository:下载jar的Maven仓库url,默认是central.maven.org
server:使用的maven_server,这个属性和repository配置一个就好

  • maven_server

maven_server(namesettings_fileurl)
定义怎么链接到Maven仓库。
举例使用:
maven_jar(
    name = "junit",
    artifact = "junit:junit-dep:4.10",
    server = "my_server",
)

maven_server(
    name = "my_server",
    url = "http://intranet.mycorp.net",
)
另外需要注意的是,如果把maven_server的name值设置为"default",那么在maven_jar中即使不指定server也会默认使用这个default的仓库。




评论

此博客中的热门博文

Bazel的概念和技术

Bazel BUILD文件的编写