Bazel基础
简介
- Bazel是Google开源的,类似于Make、Maven或Gradle的构建和测试工具。它使用可读性强的、高层次的构建语言,支持多种编程语言,以及为多种平台进行交叉编译。
-
大致工作流程:
- 根据目标,加载WORKSPACE和BUILD文件
- 分享目标相关BUILD文件
- 构建BUILD依赖关系,并产生构建图(Action图)
- 构建产物(outputs)
概念
-
BUILD文件
BUILD文件定义了包的所有元数据。其中的语句被从上而下的逐条解释(变量必须先定义后使用,但是规则声明的顺序无所谓。)
BUILD文件仅能包含ASCII字符,且不得声明函数、使用for/if语句;
可以在Bazel扩展——扩展名为 .bzl 的文件中声明函数、控制结构等,并在BUILD文件中用 load 语句加载Bazel扩展。
-
Rule
规则指定输入和输出之间的关系,并且说明产生输出的步骤。
规则有很多类型。每个规则都具有一个名称属性,此名称亦即目标名称。对于某些规则,此名称就是产生的输出的文件名。
规则的类型,一般以编程语言为前缀,例如cc,java,后缀通常有:
- *_binary 用于构建目标语言的可执行文件
- *_test 用于自动化测试,其目标是可执行文件,如果测试通过应该退出0
- *_library 用于构建目标语言的库
-
Workspace
-
工作空间是一个目录(可以为空以及包含对外部依赖的引用等),它包含:
- 构建目标所需要的源码文件,以及相应的BUILD文件
- 指向构建结果的符号链接
-
-
Package
- 包是工作空间中主要的代码组织单元,是工作空间的子目录
- 其中包含一系列相关的文件(主要是代码)以及描述这些文件之间关系的BUILD文件
- 除了那些具有BUILD文件的子目录——子包——以外,其它子目录属于包的一部分
-
Target
-
包是一个容器,它的元素定义在BUILD文件中
- 包括:规则、文件(源文件和由构建工具自动生成的文件)、包组(一组包,用于限制特定规则的可见性)
- 任何包生成的文件都属于当前包,不能为其它包生成文件,但可以从其它包中读取输入
-
-
Label
-
引用一个特定目标(Target)时需要使用“标签”。
-
标签的规范化表示:@project_name//xx/yy/zz:name
- 冒号前面是所属的包名,后面是目标名
- 在BUILD文件中,引用当前包中定义的规则时,冒号不能省略;引用当前包中文件时,冒号可以省略。
- @project_name这一部分通常不需要使用,引用外部存储库中的目标时,project_name填写外部存储库的名字。
-
-
Dependency
- 目标A依赖B,就意味着A在构建或执行期间需要B。所有目标的依赖关系构成非环有向图(DAG)称为依赖图。
- 距离为1的依赖称为直接依赖,大于1的依赖则称为传递性依赖。
- 依赖分为以下几种:
- srcs依赖:直接被当前规则消费的文件
- deps依赖:独立编译的模块,为当前规则提供头文件、符号、库、数据
- data依赖:不属于源码,不影响目标如何构建,但是目标在运行时可能依赖之
常用指令
- 安装指令
# 1 MacOS
brew install bazel
brew install bazelisk bazel version
- Bazel指令
# bazel clean
bazel clean # 不会删除外部依赖
bazel clean --expunge # 会删除外部依赖
bazel clean --expunge --async
# bazel build
bazel build :<exe name> # 在BUILD所在的package目录下执行,编译指定的target
bazel build :all # 编译该package下的所有target
bazel build ... # 编译该package下的所有target
bazel build <//path/to/package>:<exe name> # 在workspace下的任意目录执行,“//”表示workspace所在目录
bazel build :<exe name> --compilation_mode=dbg # debug mode
bazel build :<exe name> -c dbg # debug mode
bazel build :<exe name> --keep_going # 看到所有的错误
bazel build :<exe name> --config=<asan/tsan/msan> # Build the project with sanitizers by adding the --config=<asan/tsan/msan> build flag to select AddressSanitizer (asan), ThreadSanitizer (tsan) or MemorySanitizer (msan) accordingly.
bazel build :<exe name> --config local_first
#bazel run (不需要先执行build,在执行run,run的时候会自动先build再执行)
bazel run :<target name>
bazel run -- :<target name>
# action graph: bazel依赖这个图来追踪文件变化,以及是否需要重新编译,并且还可以为用户提供代码之间的依赖关系图。
bazel query 'deps(//<path_to_package>:<target_name>)' # 查看target的依赖
bazel query "somepath(//<path_to_package>:<target1_name>, //<path_to_package>:<target2_name>)"
Build文件相关规则
通用
iOS
ios_application
ios_application(name, additional_linker_inputs, alternate_icons, app_clips, app_icons, bundle_id,
bundle_name, codesign_inputs, codesignopts, deps, entitlements,
entitlements_validation, executable_name, exported_symbols_lists, extensions,
families, frameworks, include_symbols_in_bundle, infoplists, ipa_post_processor,
launch_images, launch_storyboard, linkopts, minimum_deployment_os_version,
minimum_os_version, platform_type, provisioning_profile, resources, sdk_frameworks,
settings_bundle, stamp, strings, version, watch_application)
名称 | 描述 | 备注 | 类型 |
---|---|---|---|
name | 目标名称 | Name[required,unique] | |
app_icons | app的图标文件 | 每个文件必须有一个名为 ..xcassets/..appiconset 的包含目录,并且列表中可能只有一个这样的 ..appiconset 目录。 | List of labels[optional] |
bundle_id | APP的bundle_id | String,[required] | |
bundle_name | APP的bundle_name | 如果未设置此属性,则将使用目标的名称。 | String,[optional] |
deps | 依赖项 | List of labels[optional] | |
families | 在哪些类型的设备上生效 | 「iphone」或者「iPad」,至少得有一个 | List of strings[required] |
frameworks | 所依赖的ios_framework | List of labels[optional] | |
infoplists | .plist 文件 | List of labels[optional] | |
launch_images | 包含应用程序启动图像的文件 | List of labels[optional] | |
launch_storyboard | 应用作应用程序启动屏幕的 .storyboard 或 .xib 文件。 | Label[optional] | |
minimum_os_version | app支持的最低操作系统版本的必需字符串,表示为点分版本号(例如,“9.0”) | String,[required] | |
minimum_deployment_os_version | app支持的最低部署操作系统版本的必需字符串,表示为点分版本号(例如,“9.0”)。 | 这与在编译时有效的 minimum_os_version 不同。此选项确保版本特定的 API 受到可用子句的保护。 | String,[optional] |
resources | 资源或文件的列表 | List of labels[optional] | |
strings | .strings 文件列表,通常做本地化 | List of labels[optional] |
(tips:只列入了一些常见的属性,详见官方文档里关于 ios_application 所有规则的解释)
objc_library
属性 | 说明 | 备注 | 类型 |
---|---|---|---|
name | (必填项)库的名称 | Name; required | |
deps | 需要链接到(into)当前库的其它库 | 所依赖的其他模块(非苹果官方库) | List of labels; optional |
srcs | 头文件和源码列表 | 正在处理的 C、C++、Objective-C 和 Objective-C++ 源文件和头文件和/或(“s.”、“ .S`”或“.asm”)汇编源文件列表。以创建库目标。 这些是您已签入的文件以及生成的任何文件。 使用 Clang 将源文件编译为 .o 文件。此目标的 srcs 属性中的任何源文件或头文件均可包含/导入头文件,但不能由 hdrs 中的头文件或依赖此规则的任何目标包含/导入头文件。 此外,预编译的 .o 文件可能会以 src 的形式提供。 请务必注意所提供的 .o 文件架构和 build 架构的一致性,以避免缺少符号链接器错误。 | List of labels; optional |
hdrs | 导出的头文件列表,如果启用了该模块,这些将与源文件分开编译。 | 声明的头文件构成库的公共接口 | List of labels; optional |
alwayslink | (bool,默认为False)如果为True,任何依赖(直接或间接)依赖此库的捆绑包或二进制文件都将链接到srcs和非_arc_srcs中列出的文件的所有对象文件中,即使有些文件不包含二进制文件引用的符号。如果您的代码没有被二进制文件中的代码显式调用。例如,您的代码注册以接收某些服务提供的一些回调,这将非常有用。 | Boolean; optional; default is False | |
copts | 编译参数列表 | 常用的:-no-warnings-as-errors,-iquote,-Wno-swift-name-attribute,"-ObjC" | List of strings; optional |
defines | 宏定义列表 | List of strings; optional | |
enable_modules | (bool,默认为False)启用clang模块支持(通过-fmodules)。设置为"1"将允许你@导入系统头文件和其他目标:@import UIKit; @import path_to_package_target; | Boolean; optional; default is False | |
includes | (字符串列表)需要添加到编译命令所包含的文件列表,即要添加到此目标和所有依赖目标的#include/#import搜索路径列表。这是为了支持那些没有在他们的#import/#include语句中指定整个工作空间路径的第三方和开源库。与copts 不同,这些标志是为该规则以及依赖于该规则的所有规则添加的。(注意:不是它所依赖的规则!)。如果不确定,可以在copts中添加“-iquote”标志。 | 别的模块需要引用到该模块的头文件时 | List of strings; optional |
linkopts | 链接选项 | List of strings; optional | |
module_map | (标签)这个目标的自定义Clang模块映射。不鼓励使用自定义模块映射。大多数用户应该使用由Bazel生成的模块映射。如果指定了,Bazel将不会为这个目标生成模块映射,而是将提供的模块映射传递给编译器。 | Label; optional | |
module_name | 模块名称 | String; optional | |
non_arc_srcs | (标签列表)用于创建不使用ARC的目标库的Objective-C文件列表。该属性中的文件处理方式与srcs属性中的文件非常相似,但在编译时不启用ARC。 | List of labels; optional | |
pch | (标签)要编译的每个源文件前面的头文件。不鼓励在BUILD文件中使用pch文件,这应该被认为是不可取的。由于pch文件实际上没有预编译,这并不能提高构建速度,而只是一个全局依赖。从构建效率的角度来看,在需要的地方直接将需要的内容包含在资源中实际上更好 | 独立的SDK,需要用到? | Label; optional |
runtime_deps | (标签列表)在运行时延迟加载的框架目标列表。它们包含在应用包中,但在构建时没有链接。 | List of labels; optional | |
sdk_dylibs | (字符串列表)要链接的SDK .dylib库的名称。例如,“libz”或“libarchive”。 | List of strings; optional | |
sdk_frameworks | (字符串列表)要链接的SDK框架的名称(例:“AddressBook”、“QuartzCore”)对于iOS, tvOS和watchOS平台构建时,“UIKit”和“Foundation”总是被包含在内对于macOS,只包含"Foundation"当链接一个顶级的Apple二进制文件时,该二进制文件的传递依赖关系图中列出的所有SDK框架都会被链接。 | 即当模块内需要用到<QuartzCore/**>时,就需要添加引用“QuartzCore”引用 | List of strings; optional |
sdk_includes | (字符串列表)要添加到此目标和所有依赖目标的#include/#import搜索路径列表,其中每个路径相对于$(SDKROOT)/usr/include。 | List of strings; optional | |
textual_hdrs | (字符串列表)头文件列表,这些头文件是不能独立编译的。依赖此库的目标,直接以文本形式包含这些头文件到它的源码列表中,这样才能正确编译这些头文件 | List of labels; optional |
copts-相关编译参数:GCC指令
Swift
Learning....
实战
bbstudy-oc
bbstudy-swift
Learning...
bbstudy-oc-swift
Learning...
相关文档