Change log
目录
[bazel]-导读
[bazel]-概念和术语
[bazel]-bazel的使用
[bazel]-tulsi的使用
[bazel]-如何编译
[bazel]-缓存
[bazel]-影响缓存命中的因素
[bazel]-优化
项目地址
原文: https://docs.bazel.build/versions/master/build-ref.html
介绍
本文主要讲述Workspace. Packages. Targets(file; rule; package_group)都是些啥
Bazel在一个workspace(项目根目录)里构建软件.
workspace里的源文件以package(包)的嵌套层次结构来组织.
每个package(包)都是一个文件夹.里面包含了相关源文件和一个BUILD文件.
每个BUILD文件指定这个源文件可以构建出来什么样的输出.
Workspace, Packages and Targets
Workspace (根文件夹)
一个workspace就是一个project(项目)的根目录.
workspace里包含构建这个项目所需的源文件.以及symbolic links(符号链接).
每个workspace目录都必须有一个名为WORKSPACE的文件.
这个WORKSPACE文件可能是空的.
也可能包含构建项目所需的外部依赖.
(WORKSPACE文件怎么添加依赖请见Workspace Rules https://docs.bazel.build/versions/master/be/workspace.html)
Package (子文件夹)
在一个workspace中package是主要的代码组织单元.
一个package就是一个相关文件的集合.也是一个这些相关文件之间的规范.
一个package被定义为一个目录.这个目录里必须包含一个名为BUILD的文件.
package目录必须在workspace目录下.
package包含其目录中的所有文件.以及其下的所有子目录.
但是不包含那些包含了BUILD文件的子目录.
例子:
workspace为: GXShell根目录
package为: universal_target; GXLive; GXLiveBase; GXPhone; GXPhoneBase
target
package是一个容器.即目录.
他里面的元素被称为target.
target可以分为三类: file(文件)和rule(规则).package group(数量很少)
file
file进一步分类又可以分为两种:源文件和派生文件.
源文件通常就是程序员编写的类文件.会被上传到远程仓库.
派生文件是由编译器根据指定规则生成的文件.不会被上传到远程仓库.
例子:
如在universal_target这个package里的info.plist和main.m都属于file
rule
rule不是一个文件.
他是被保存在BUILD文件里的一个函数或者叫方法.
他是一个规则.
如下例子中universal_lib和universal都是一个rule.
1.rule指定输入和输出之间的关系.以及构建输出的步骤.
rule的输出始终是派生文件.
rule的输入可以是源文件.也可以是派生文件.
也就是说.rule的输出也可能是另一个rule的输入.Bazel允许构建长链规则.
2.rule的输入还可以包含其他rule.
即A rule可能有另一个B rule作为输入.
在编译期间B的头文件可用于A
在链接期间B的符号可用于A
在执行期间B的运行时数据可用于A
3.通过rule生成的文件始终属于该rule所属的package.
不能将生成文件放到另一个package里.
但是rule的输入却可以来自另一个package
4.每个rule都有一个name.由name属性指定.类型为string.
这个被你指定的名字将作为生成的文件的名称.
所以推荐名称可以遵守一定的规则: 如: _binary和_test.
让人看名字就知道你要生成的文件的作用.
5.每个规则都有一组属性.每个属性都是rule类里的函数.
每个属性都有一个名称和一个类型.
类型可以是: 整数; label; label列表; 字符串; 字符串列表; 输出label; 输出label列表.
在每个规则中不是每个属性都需要被实现的.即有的属性是可选的.
例子:
其中srcs这个属性会出现在很多rule里.
他的类型是label列表.
每个出现在这里的target都是该rule的输入文件.
如下"universal/mian.m"; "universal/AppDelegate.m"; "universal/ViewController.m"都是universal_lib这个rule的输入
例子:
如下universal和universal_lib各是一个rule
其中universal这个rule里就引用了universal_lib这个rule
package group
package group顾名思义就是一组package.
他的目的是限制某些规则的可访问性.
package group由package_group函数定义.
他有两个属性: 他包含的包列表及其名称.
唯一能决定他能否被引用的属性是: rule里的visibility属性 或者 package函数里的default_visibility属性.
他不生成或者使用文件.仅仅是定义.
例子:
如下在//srcs/business/目录下有4个package.
分别是GXLive; GXLiveBase; GXPhone; GXPhoneBase;
其中GXLive和GXLiveBase是成对出现的.
GXPhone和GXPhoneBase也是成对出现的.是一个整体.
那么我们就可以在//srcs/business目录下创建一个BUILD文件.
声明package_group规则.
这样外界就可以通过live_group和phone_group来引用他们了.
BUILD内容如下:
label
所有的target属于一个package.
target的名字被称为label.
一个典型target的label如下所示:
//src/business/GXPhone:GXPhone_binary
每个label有两个部分
src/business/GXPhone被称为package name.
GXPhone_binary被称为target name.
每个label都是独一无二的.如下即一个完整的label
//src/business/GXPhone:GXPhone_binary
有时如果target name和package name一样.那么label可以有以下四种表示形式.他们是等价的.
//src/business/GXPhone:GXPhone
//src/business/GXPhone
:GXPhone
GXPhone
'//'代表根目录
label在某些情况下可以简写.但是更推荐写完整.所以如果想知道怎么简写就自己看官方文档把.