Change log
目錄
[bazel]-導(dǎo)讀
[bazel]-概念和術(shù)語(yǔ)
[bazel]-bazel的使用
[bazel]-tulsi的使用
[bazel]-如何編譯
[bazel]-緩存
[bazel]-影響緩存命中的因素
[bazel]-優(yōu)化
項(xiàng)目地址
原文: https://docs.bazel.build/versions/master/build-ref.html
介紹
本文主要講述Workspace. Packages. Targets(file; rule; package_group)都是些啥
Bazel在一個(gè)workspace(項(xiàng)目根目錄)里構(gòu)建軟件.
workspace里的源文件以package(包)的嵌套層次結(jié)構(gòu)來(lái)組織.
每個(gè)package(包)都是一個(gè)文件夾.里面包含了相關(guān)源文件和一個(gè)BUILD文件.
每個(gè)BUILD文件指定這個(gè)源文件可以構(gòu)建出來(lái)什么樣的輸出.
Workspace, Packages and Targets
Workspace (根文件夾)
一個(gè)workspace就是一個(gè)project(項(xiàng)目)的根目錄.
workspace里包含構(gòu)建這個(gè)項(xiàng)目所需的源文件.以及symbolic links(符號(hào)鏈接).
每個(gè)workspace目錄都必須有一個(gè)名為WORKSPACE的文件.
這個(gè)WORKSPACE文件可能是空的.
也可能包含構(gòu)建項(xiàng)目所需的外部依賴(lài).
(WORKSPACE文件怎么添加依賴(lài)請(qǐng)見(jiàn)Workspace Rules https://docs.bazel.build/versions/master/be/workspace.html)
Package (子文件夾)
在一個(gè)workspace中package是主要的代碼組織單元.
一個(gè)package就是一個(gè)相關(guān)文件的集合.也是一個(gè)這些相關(guān)文件之間的規(guī)范.
一個(gè)package被定義為一個(gè)目錄.這個(gè)目錄里必須包含一個(gè)名為BUILD的文件.
package目錄必須在workspace目錄下.
package包含其目錄中的所有文件.以及其下的所有子目錄.
但是不包含那些包含了BUILD文件的子目錄.
例子:
workspace為: GXShell根目錄
package為: universal_target; GXLive; GXLiveBase; GXPhone; GXPhoneBase

target
package是一個(gè)容器.即目錄.
他里面的元素被稱(chēng)為target.
target可以分為三類(lèi): file(文件)和rule(規(guī)則).package group(數(shù)量很少)
file
file進(jìn)一步分類(lèi)又可以分為兩種:源文件和派生文件.
源文件通常就是程序員編寫(xiě)的類(lèi)文件.會(huì)被上傳到遠(yuǎn)程倉(cāng)庫(kù).
派生文件是由編譯器根據(jù)指定規(guī)則生成的文件.不會(huì)被上傳到遠(yuǎn)程倉(cāng)庫(kù).
例子:
如在universal_target這個(gè)package里的info.plist和main.m都屬于file

rule
rule不是一個(gè)文件.
他是被保存在BUILD文件里的一個(gè)函數(shù)或者叫方法.
他是一個(gè)規(guī)則.
如下例子中universal_lib和universal都是一個(gè)rule.
1.rule指定輸入和輸出之間的關(guān)系.以及構(gòu)建輸出的步驟.
rule的輸出始終是派生文件.
rule的輸入可以是源文件.也可以是派生文件.
也就是說(shuō).rule的輸出也可能是另一個(gè)rule的輸入.Bazel允許構(gòu)建長(zhǎng)鏈規(guī)則.
2.rule的輸入還可以包含其他rule.
即A rule可能有另一個(gè)B rule作為輸入.
在編譯期間B的頭文件可用于A(yíng)
在鏈接期間B的符號(hào)可用于A(yíng)
在執(zhí)行期間B的運(yùn)行時(shí)數(shù)據(jù)可用于A(yíng)
3.通過(guò)rule生成的文件始終屬于該rule所屬的package.
不能將生成文件放到另一個(gè)package里.
但是rule的輸入?yún)s可以來(lái)自另一個(gè)package
4.每個(gè)rule都有一個(gè)name.由name屬性指定.類(lèi)型為string.
這個(gè)被你指定的名字將作為生成的文件的名稱(chēng).
所以推薦名稱(chēng)可以遵守一定的規(guī)則: 如: _binary和_test.
讓人看名字就知道你要生成的文件的作用.
5.每個(gè)規(guī)則都有一組屬性.每個(gè)屬性都是rule類(lèi)里的函數(shù).
每個(gè)屬性都有一個(gè)名稱(chēng)和一個(gè)類(lèi)型.
類(lèi)型可以是: 整數(shù); label; label列表; 字符串; 字符串列表; 輸出label; 輸出label列表.
在每個(gè)規(guī)則中不是每個(gè)屬性都需要被實(shí)現(xiàn)的.即有的屬性是可選的.
例子:
其中srcs這個(gè)屬性會(huì)出現(xiàn)在很多rule里.
他的類(lèi)型是label列表.
每個(gè)出現(xiàn)在這里的target都是該rule的輸入文件.
如下"universal/mian.m"; "universal/AppDelegate.m"; "universal/ViewController.m"都是universal_lib這個(gè)rule的輸入

例子:
如下universal和universal_lib各是一個(gè)rule
其中universal這個(gè)rule里就引用了universal_lib這個(gè)rule

package group
package group顧名思義就是一組package.
他的目的是限制某些規(guī)則的可訪(fǎng)問(wèn)性.
package group由package_group函數(shù)定義.
他有兩個(gè)屬性: 他包含的包列表及其名稱(chēng).
唯一能決定他能否被引用的屬性是: rule里的visibility屬性 或者 package函數(shù)里的default_visibility屬性.
他不生成或者使用文件.僅僅是定義.
例子:
如下在//srcs/business/目錄下有4個(gè)package.
分別是GXLive; GXLiveBase; GXPhone; GXPhoneBase;
其中GXLive和GXLiveBase是成對(duì)出現(xiàn)的.
GXPhone和GXPhoneBase也是成對(duì)出現(xiàn)的.是一個(gè)整體.
那么我們就可以在//srcs/business目錄下創(chuàng)建一個(gè)BUILD文件.
聲明package_group規(guī)則.
這樣外界就可以通過(guò)live_group和phone_group來(lái)引用他們了.

BUILD內(nèi)容如下:

label
所有的target屬于一個(gè)package.
target的名字被稱(chēng)為label.
一個(gè)典型target的label如下所示:
//src/business/GXPhone:GXPhone_binary
每個(gè)label有兩個(gè)部分
src/business/GXPhone被稱(chēng)為package name.
GXPhone_binary被稱(chēng)為target name.
每個(gè)label都是獨(dú)一無(wú)二的.如下即一個(gè)完整的label
//src/business/GXPhone:GXPhone_binary
有時(shí)如果target name和package name一樣.那么label可以有以下四種表示形式.他們是等價(jià)的.
//src/business/GXPhone:GXPhone
//src/business/GXPhone
:GXPhone
GXPhone
'//'代表根目錄
label在某些情況下可以簡(jiǎn)寫(xiě).但是更推薦寫(xiě)完整.所以如果想知道怎么簡(jiǎn)寫(xiě)就自己看官方文檔把.