GN
使用gn編譯項(xiàng)目的過程:
-
編寫.gn文件
模塊化各個模塊,分別寫一個build.gn,添加進(jìn)主目錄的build.gn的依賴中。
gn gen out/Default
ninja -C out/Default base
1. Ninja
ninja一個構(gòu)建系統(tǒng),它以文件(通常是源代碼和輸出可執(zhí)行文件)的相互依賴性為輸入,并快速地構(gòu)建它們。Ninja通過將編譯任務(wù)并行組織,大大提高了構(gòu)建速度。
源于在Chromium瀏覽器項(xiàng)目中的工作,該項(xiàng)目具有30,000多個源文件,并且其其他構(gòu)建系統(tǒng)(包括從自定義非遞歸Makefile構(gòu)建的一個)在更改一個文件后將需要十秒鐘才能開始構(gòu)建。 而用ninja構(gòu)建不到一秒鐘。
1.1 設(shè)計(jì)目標(biāo)
- 即使是非常大的項(xiàng)目,也可以非??焖伲醇磿r)的增量構(gòu)建。
- 關(guān)于如何構(gòu)建代碼的選擇很少。對于不同項(xiàng)目,可能有不同的構(gòu)建策略,ninja簡化了這些選擇。
- 讓依賴正確,在一些特殊情況下Makefiles很難解決的。
- 速度和簡單之間,選擇速度。
1.2 示例
cflags = -Wall
rule cc
command = gcc $cflags -c $in -o $out
build foo.o: cc foo.c
為字符串生成一個更可讀的名字
cflags = -g
使用$符號取值
rule cc
command = gcc $cflags -c $in -o $out
? 定義一個叫cc的rule,然后這條rule的內(nèi)容是一個可執(zhí)行的命令,$in 展開為輸入文件(foo.c),$out 展開為輸出文件(foo.o) for the command.
? Build語句聲明輸入文件和輸出文件之間的關(guān)系,以build關(guān)鍵詞開始,格式是build outputs: rulename inputs這個規(guī)則說明所有的輸出文件都是從輸入文件產(chǎn)生的。當(dāng)output不存在或者input改變時,都會重新創(chuàng)建output。上面的例子里面out代表輸出列表。
2. GN
GN是一個用來生成ninja構(gòu)建文件的工具。
2.1 運(yùn)行參數(shù)
生成構(gòu)建目錄
gn gen out/my_build
設(shè)置構(gòu)建參數(shù)
gn gen out/my_build --args="..."
可以設(shè)置多個target os以及target cpugn args out/Default(或者使用--args方式)
target_os = "chromeos"
target_os = "android"
target_cpu = "arm"
target_cpu = "x86"
target_cpu = "x64"
查看所有的參數(shù)
gn args --list out/Default
2.1 Build文件
示例
static_library(“base”) {
sources = [
“a.cc”,
“b.cc”,
]
}
加上依賴
static_library(“base”) {
sources = [
“a.cc”,
“b.cc”,
]
deps = [
“//fancypants”,
“//foo/bar:baz”,
]
}
設(shè)計(jì)原則
- 模塊化
創(chuàng)建一個反映代碼組件和子組件的目錄結(jié)構(gòu),把BUILD文件放在每個目錄中。
- 明確模塊之間的關(guān)系
內(nèi)置的target類型
-
executable
定義一個可執(zhí)行target
-
shared_library
在鏈接器行上為目標(biāo)指定共享庫,該目標(biāo)在“ deps”中列出了共享庫。
-
static_library
創(chuàng)建.a以及.lib文件
-
loadable_module
創(chuàng)建一個目標(biāo)文件,只能(并且只能)在運(yùn)行時加載和卸載。
-
source_set:
編譯沒有中間庫的源文件,將其視為靜態(tài)庫,但沒有靜態(tài)庫鏈接規(guī)則。是經(jīng)過編譯但未鏈接的一組源,相反,生成的目標(biāo)文件是隱式添加到依賴源的所有目標(biāo)的鏈接器中。
-
group
把一些依賴合并起來并命名
copy
action, action_foreach
bundle_data, create_bundle: Mac & iOS
另外,我們也可以創(chuàng)建自定義類型。
標(biāo)簽說明
- 完整標(biāo)簽
//chrome/browser:version
- 隱式標(biāo)簽
//base, //base::base的縮寫
- 當(dāng)前目錄
:bar,表示當(dāng)前目錄下的bar文件
依賴放到一個group中
gorup是沒有被編譯或者依賴的集合。
group("tools") {
deps = [
# This will expand to the name "http://tutorial:tutorial" which is the full name
# of our new target. Run "gn help labels" for more.
"http://tutorial",
]
}
條件語句
component(“base”) {
sources = [
“a.cc”,
“b.cc”,
]
if (is_win || is_linux) {
sources += [ “win_helper.cc” ]
} else {
sources -= [ “a.cc” ]
}
}
Config
Config持有flag, defines, include directories這樣一些東西,但不包含源文件和依賴。
添加移除配置
executable(“doom_melon”) {
configs -= [
"http://build/config/compiler:chromium_code",
]
configs += [
"http://build/config/compiler:no_chromium_code",
]
}
把配置放到一個group中
config(“myconfig”) {
defines = [ “EVIL_BIT=1” ]
}
executable(“doom_melon”) {
...
configs += [ “:myconfig” ]
}
test(“doom_melon_tests”) {
...
configs += [ “:myconfig” ]
}
動態(tài)加載一些外部的數(shù)據(jù)文件
shared_library(“icu”) {
# This target is loaded @ runtime.
data_deps = [
“:icu_data_tables”,
]
}
權(quán)限控制
- deps vs public_deps
控制依賴的可見性
- visibility
設(shè)置當(dāng)前文件可以被其他文件依賴
- assert_no_deps
依賴項(xiàng)都不應(yīng)該鏈接
- testonly
不鏈接到production代碼中