Skip to content

Why bazel import jar package using @jar_name//jar #4

@lyj289

Description

@lyj289

如何在bazel中引用一个jar包呢?

首先在workspace文件中定义:

maven_jar(
    name = "sqlite_jdbc",
    artifact = "org.xerial:sqlite-jdbc:3.32.3.2",
    sha1 = "ee9912c1bdec16fe5978b0abd9f4063ce9eedf8b",
)

bind(
    name = "sqlite_jdbc_java",
    actual = "@sqlite_jdbc//jar", // jar表示引用jar包,应该是一种约定
)

// bind也可以不加,在build文件中直播使用 @sqlite_jdbc//jar

编写build文件

deps = [
        "//external:sqlite_jdbc_java",
    ],

看到这里,有个疑问,为什么要使用@sqlite_jdbc//jar的形式?

一起来追踪一个这个问题吧。

首先查看下bazel 的 output_base目录,所有build的结果都会被放在这里。

bazel info output_base

# output:   /private/var/tmp/_bazel_user/7b98e93d50eb18176ee48c9364a7f2e2

以ndsmap converter为例,它的原始路径为${repo_base}/java/java/main/ai/lyj289/converter/ndsmap/Converter.java

build后结果如下:

bazel-bin/java/main/ai/lyj289/converter/ndsmap/
├── Converter
├── Converter.jar
├── Converter.jar-0.params
├── Converter.jar_manifest_proto
├── Converter.jdeps
├── Converter.runfiles
├── Converter.runfiles_manifest
├── _javac

其中:

  • Converter.jar 是入口
  • Converter.runfiles, 包含了它的依赖文件和data,

其中就包括sqlite_jdbc, 路径为

bazel-bin/java/main/ai/lyj289/converter/ndsmap/Converter.runfiles/main/external/sqlite_jdbc
└── jar
└── sqlite-jdbc-3.32.3.2.jar -> /private/var/tmp/_bazel_user/7b98e93d50eb18176ee48c9364a7f2e2/external/sqlite_jdbc/jar/sqlite-jdbc-3.32.3.2.jar

被软链到outpu_base下的external目录, 这里是存放所有jar包的地方。

# 只列出第一层文件夹
tree -d -L 1 /private/var/tmp/_bazel_user/7b98e93d50eb18176ee48c9364a7f2e2/external

结果如下,这里有许多包,都是bazel download下来的,作为cache, 后面如果有其他task引用,可以直接在这里查找使用,而不用再重新下载了。

├── args4j
├── com_google_guava
├── com_google_protobuf
├── com_google_protobuf_java
├── grpc_java_archive
├── guava
├── io_bazel_rules_closure
├── io_bazel_rules_python
├── jcommander
├── maven
├── mysql_connector_java
├── openssl_archive
├── org_apache_commons_commons_lang3_3_4
├── org_javassist_javassist_3_18_2_GA
├── org_jsoup
├── org_jsoup_jsoup_1_8_1
├── org_pubref_rules_node
├── org_slf4j_slf4j_api_1_7_12
├── rules_jvm_external
├── slf4j_log4j12
├── sqlite_jdbc

Ok, 继续,查看sqlite_jdbc目录

tree /private/var/tmp/_bazel_user/7b98e93d50eb18176ee48c9364a7f2e2/external/sqlite_jdbc/

├── WORKSPACE
├── jar
│   ├── BUILD.bazel
│   ├── sqlite-jdbc-3.32.3.2-sources.jar -> /private/var/tmp/_bazel_user/7b98e93d50eb18176ee48c9364a7f2e2/external/sqlite_jdbc/org/xerial/sqlite-jdbc/3.32.3.2/sqlite-jdbc-3.32.3.2-sources.jar
│   └── sqlite-jdbc-3.32.3.2.jar -> /private/var/tmp/_bazel_user/7b98e93d50eb18176ee48c9364a7f2e2/external/sqlite_jdbc/org/xerial/sqlite-jdbc/3.32.3.2/sqlite-jdbc-3.32.3.2.jar
└── org
└── xerial
└── sqlite-jdbc
└── 3.32.3.2
├── _remote.repositories
├── sqlite-jdbc-3.32.3.2-sources.jar
├── sqlite-jdbc-3.32.3.2-sources.jar.sha1
├── sqlite-jdbc-3.32.3.2.jar
└── sqlite-jdbc-3.32.3.2.jar.sha1

有两个目录,

  • org是jar包下载后,原始存储目录
  • jar是bazel 后生成的目录,是为了添加build rule,以方便被bazel当作一个普通task使用

打开jar目录下的BUILD.bazel文件

# DO NOT EDIT: automatically generated BUILD.bazel file for maven_jar rule sqlite_jdbc
java_import(
    name = 'jar',
    jars = ['sqlite-jdbc-3.32.3.2.jar'],
    srcjar = 'sqlite-jdbc-3.32.3.2-sources.jar',
    visibility = ['//visibility:public']
)

filegroup(
    name = 'file',
    srcs = [
        'sqlite-jdbc-3.32.3.2.jar',
        'sqlite-jdbc-3.32.3.2-sources.jar',
    ],
    visibility = ['//visibility:public']
)

Ok,定义了一个jar的task,它的label为@sqlite_jdbc//jar, 上面在被引用时,就是用的这个label

如此,清楚了,总结下:

  • external目录是存放第三方jar包的地方,
  • 一个jar包被下载下来后,会生成两个目录
    • 原始包结构目录
    • bazel 自动生成一个jar目录,用来定义task
  • jar包被引用时,要使用如@sqlite_jdbc//jar的形式

Metadata

Metadata

Assignees

No one assigned

    Labels

    dailydaily update

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions