bazel官网
dagger构建采用bazel构建 如图所示,每个bazel项目都会在根目录有一个WORKSPACE文件——工作区间,它包含了源文件、符号链接以及项目的输出目录。
一.local_repository作用
local_repository外部依赖类型中的一种,在这里表示根目录WORKSPACE引入了examples/bazel下的工作区间
local_repository( name = "examples_bazel", path = "examples/bazel", )1.查看examples/bazel的工作区间
1.1如下代码块所示,local_repository属于外部引入,引入了dagger,这里的"…/…/"定位到了dagger根目录;下面的load(@dagger//:workspace_defs.bzl…)则表示引用dagger目录下workspace_defs.bzl,后面的DAGGER_ARTIFACTS等参数可以到该文件下查找
######################## # Load Dagger repository ######################## # TODO(bcorso): Replace with `http_archive` pointing to tagged released. local_repository( name = "dagger", path = "../../", ) load( "@dagger//:workspace_defs.bzl", "DAGGER_ARTIFACTS", "DAGGER_REPOSITORIES", "HILT_ANDROID_ARTIFACTS", "HILT_ANDROID_REPOSITORIES", )在workspace_defs.bzl中查找以上对应的
DAGGER_ARTIFACTS = [ "com.google.dagger:dagger:" + _DAGGER_VERSION, "com.google.dagger:dagger-compiler:" + _DAGGER_VERSION, "com.google.dagger:dagger-producers:" + _DAGGER_VERSION, "com.google.dagger:dagger-spi:" + _DAGGER_VERSION, ] DAGGER_REPOSITORIES = [ "https://maven.google.com", "https://repo1.maven.org/maven2", ] HILT_ANDROID_ARTIFACTS = [ "androidx.test:core:1.1.0", # Export for ApplicationProvider "javax.annotation:jsr250-api:1.0", # Export for @Generated "androidx.annotation:annotation:1.1.0", # Export for @CallSuper/@Nullable "com.google.dagger:dagger:" + _DAGGER_VERSION, "com.google.dagger:dagger-compiler:" + _DAGGER_VERSION, "com.google.dagger:hilt-android:" + _HILT_VERSION, "com.google.dagger:hilt-android-testing:" + _HILT_VERSION, "com.google.dagger:hilt-android-compiler:" + _HILT_VERSION, ] HILT_ANDROID_REPOSITORIES = DAGGER_REPOSITORIES分析下以上这段代码的目的,首先我们知道WORKSPACE工作区间的作用,bazel的构建输出,那么我们是否可以理解为bazel构建后的输出,或者说是我们实际开发可使用的引用
小说明_DAGGER_VERSION信息从何而来,我们,具代码所述来自build_defs.bzl,在查找build_defs.bzl代码,来自于${project.version},里面又有一段注解“DO NOT remove the comment on the next line. It’s used in deploy-to-maven-central.sh”,由此可见_DAGGER_VERSION来自于执行脚本,开发者在提交代码的时候输入一个版本信息,啊哈,具体是不是这么操作的俺也不清除,反正肯定是这么个思路
1.2Load Android repository
本地android sdk支持的构建目标
######################### # Load Android repository ######################### android_sdk_repository( name = "androidsdk", api_level = 29, build_tools_version = "29.0.2", )1.3 Load Robolectric repository
作用:引入robolectric。Robolectric里,定义了大量对应android源码的shadow类。 shadow类,如其名“影子”。 当一个android类的方法被调用的时候,Robolectric就会尝试寻找该类相应的影子类,替代对应的android类,执行相应的方法。
############################# # Load Robolectric repository ############################# load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "robolectric", strip_prefix = "robolectric-bazel-4.1", urls = ["https://github.com/robolectric/robolectric-bazel/archive/4.1.tar.gz"], ) load("@robolectric//bazel:robolectric.bzl", "robolectric_repositories") robolectric_repositories()1.4Load Maven repositories
使用rules_jvm_external规则集,我们可以引入外部依赖Guava。Guava正是这样一个现代的库,它简单易用,对Java语言是一个非常好的补充,可以说只要你在使用Java语言开发任何项目都应该使用Guava。
######################### # Load Maven repositories ######################### RULES_JVM_EXTERNAL_TAG = "2.7" RULES_JVM_EXTERNAL_SHA = "f04b1466a00a2845106801e0c5cec96841f49ea4e7d1df88dc8e4bf31523df74" http_archive( name = "rules_jvm_external", sha256 = RULES_JVM_EXTERNAL_SHA, strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG, url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG, ) load("@rules_jvm_external//:defs.bzl", "maven_install") maven_install( artifacts = DAGGER_ARTIFACTS + HILT_ANDROID_ARTIFACTS + [ "androidx.test.ext:junit:1.1.1", "androidx.test:runner:1.1.1", "com.google.truth:truth:1.0.1", "junit:junit:4.13", "org.robolectric:robolectric:4.1", "org.robolectric:annotations:4.1", ], repositories = DAGGER_REPOSITORIES + HILT_ANDROID_REPOSITORIES, )我们总结一下examples\bazel的WORKSPACE工作区间做了什么事情:主要是为当前examples\bazel区间引入了依赖后面我们在分析当前区间,该区间的分析也非常有必要,因为根据字面意思理解,它相当于dagger的一个实例代码,一个小的或者说袖珍版dagger,后面可以验证到底是不是
2.执行google_common_workspace_rules
鬼知道它干啥的~~~
首先在浏览器访问https://github.com/google/bazel-common/archive/d58641d120c2ad3d0afd77b57fbaa78f3a97d914.zip,解压后在其目录中查找workspace_defs.bzl,打开该文件然后找google_common_workspace_rules方法:为Google开源库引入WORKSPACE规则。
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "google_bazel_common", sha256 = "7e5584a1527390d55c972c246471cffd4c68b4c234d288f6afb52af8619c4560", strip_prefix = "bazel-common-d58641d120c2ad3d0afd77b57fbaa78f3a97d914", urls = ["https://github.com/google/bazel-common/archive/d58641d120c2ad3d0afd77b57fbaa78f3a97d914.zip"], ) load("@google_bazel_common//:workspace_defs.bzl", "google_common_workspace_rules") google_common_workspace_rules()google_common_workspace_rules规则代码
def google_common_workspace_rules(): """Defines WORKSPACE rules for Google open-source libraries. Call this once at the top of your WORKSPACE file to load all of the repositories. Note that you should not refer to these repositories directly and instead prefer to use the targets defined in //third_party. """ native.android_sdk_repository( name = "androidsdk", api_level = 29, build_tools_version = "29.0.2", ) _maven_import( artifact = "javax.annotation:jsr250-api:1.0", licenses = ["notice"], sha256 = "a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f", ) _maven_import( artifact = "com.google.code.findbugs:jsr305:3.0.1", licenses = ["notice"], sha256 = "c885ce34249682bc0236b4a7d56efcc12048e6135a5baf7a9cde8ad8cda13fcd", ) ...太长只截取部分,有兴趣可自行查看3.执行引入protobuf必须的依赖
在WORKSPACE 引入rules_python和zlib,是项目中使用protobuf的必要条件
# rules_python and zlib are required by protobuf. # TODO(ronshapiro): Figure out if zlib is in fact necessary, or if proto can depend on the # @bazel_tools library directly. See discussion in # https://github.com/protocolbuffers/protobuf/pull/5389#issuecomment-481785716 # TODO(cpovirk): Should we eventually get rules_python from "Bazel Federation?" # https://github.com/bazelbuild/rules_python#getting-started http_archive( name = "rules_python", sha256 = "e5470e92a18aa51830db99a4d9c492cc613761d5bdb7131c04bd92b9834380f6", strip_prefix = "rules_python-4b84ad270387a7c439ebdccfd530e2339601ef27", urls = ["https://github.com/bazelbuild/rules_python/archive/4b84ad270387a7c439ebdccfd530e2339601ef27.tar.gz"], ) http_archive( name = "zlib", build_file = "@com_google_protobuf//:third_party/zlib.BUILD", sha256 = "629380c90a77b964d896ed37163f5c3a34f6e6d897311f1df2a7016355c45eff", strip_prefix = "zlib-1.2.11", urls = ["https://github.com/madler/zlib/archive/v1.2.11.tar.gz"], )4.使用rules_jvm_external规则集,我们可以引入外部依赖Guava。
maven_install这里artifacts 表示项目中引入了maven中这些文件,而这些文件来源于repositories中的信息
RULES_JVM_EXTERNAL_TAG = "2.7" RULES_JVM_EXTERNAL_SHA = "f04b1466a00a2845106801e0c5cec96841f49ea4e7d1df88dc8e4bf31523df74" http_archive( name = "rules_jvm_external", sha256 = RULES_JVM_EXTERNAL_SHA, strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG, url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG, ) load("@rules_jvm_external//:defs.bzl", "maven_install") ANDROID_LINT_VERSION = "26.6.2" maven_install( artifacts = [ "androidx.annotation:annotation:1.1.0", "androidx.appcompat:appcompat:1.1.0", "androidx.activity:activity:1.1.0", "androidx.fragment:fragment:1.2.0", "androidx.lifecycle:lifecycle-viewmodel:2.2.0", "androidx.multidex:multidex:2.0.1", "androidx.test:monitor:1.1.1", "androidx.test:core:1.1.0", "com.google.auto:auto-common:0.11", "com.android.support:appcompat-v7:25.0.0", "com.android.support:support-annotations:25.0.0", "com.android.support:support-fragment:25.0.0", "com.android.tools.external.org-jetbrains:uast:%s" % ANDROID_LINT_VERSION, "com.android.tools.external.com-intellij:intellij-core:%s" % ANDROID_LINT_VERSION, "com.android.tools.external.com-intellij:kotlin-compiler:%s" % ANDROID_LINT_VERSION, "com.android.tools.lint:lint:%s" % ANDROID_LINT_VERSION, "com.android.tools.lint:lint-api:%s" % ANDROID_LINT_VERSION, "com.android.tools.lint:lint-checks:%s" % ANDROID_LINT_VERSION, "com.android.tools.lint:lint-tests:%s" % ANDROID_LINT_VERSION, "com.android.tools:testutils:%s" % ANDROID_LINT_VERSION, "com.github.tschuchortdev:kotlin-compile-testing:1.2.8", "com.google.guava:guava:27.1-android", "org.jetbrains.kotlin:kotlin-stdlib:1.3.50", "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0", "org.robolectric:robolectric:4.3.1", ], repositories = [ "https://repo1.maven.org/maven2", "https://maven.google.com", "https://jcenter.bintray.com/", # Lint has one trove4j dependency in jCenter ], )5.引入kotlin规则 可以点击https://github.com/bazelbuild/rules_kotlin/archive/186c1e1e27d699a8953b75461f2de7c295987cfb.zip,下载并解压,找到kotlin:kotlin.bzl文件,然后找到kotlin_repositories和kt_register_toolchains方法
调用kotlin_repositories:引入kotin规则
调用kt_register_toolchains:注册kotlin工具链
# TODO(user): Remove once Google publishes internal Kotlin rules. RULES_KOTLIN_VERSION = "186c1e1e27d699a8953b75461f2de7c295987cfb" RULES_KOTLIN_SHA = "ef2f9cfb724b1f1eaf0ede2636515969eb4c6e10b75a71d1850f6e692a7d5f06" http_archive( name = "io_bazel_rules_kotlin", sha256 = RULES_KOTLIN_SHA, strip_prefix = "rules_kotlin-%s" % RULES_KOTLIN_VERSION, type = "zip", urls = ["https://github.com/bazelbuild/rules_kotlin/archive/%s.zip" % RULES_KOTLIN_VERSION], ) load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains") kotlin_repositories() kt_register_toolchains()6.bazel_skylib_workspace调用
注册bazel_skylib并引入该依赖,将https://github.com/bazelbuild/bazel-skylib/releases/download/{version}/bazel-skylib-{version}.tar.gz下载解压,自行查看
BAZEL_SKYLIB_VERSION = "1.0.2" BAZEL_SKYLIB_SHA = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44" http_archive( name = "bazel_skylib", sha256 = BAZEL_SKYLIB_SHA, urls = [ "https://github.com/bazelbuild/bazel-skylib/releases/download/{version}/bazel-skylib-{version}.tar.gz".format(version = BAZEL_SKYLIB_VERSION), ], ) load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace()从以上代码都可以看出,WORKSPACE主要引入源文件和一些规则信息,具体作用还承接下文BUILD