WebRTC編譯器GN介紹

GN

使用gn編譯項(xiàng)目的過程:

  1. 編寫.gn文件

    模塊化各個模塊,分別寫一個build.gn,添加進(jìn)主目錄的build.gn的依賴中。

  2. gn gen out/Default

  3. 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)

  1. 即使是非常大的項(xiàng)目,也可以非??焖伲醇磿r)的增量構(gòu)建。
  2. 關(guān)于如何構(gòu)建代碼的選擇很少。對于不同項(xiàng)目,可能有不同的構(gòu)建策略,ninja簡化了這些選擇。
  3. 讓依賴正確,在一些特殊情況下Makefiles很難解決的。
  4. 速度和簡單之間,選擇速度。

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。上面的例子里面in代表輸入列表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ì)原則
  1. 模塊化

創(chuàng)建一個反映代碼組件和子組件的目錄結(jié)構(gòu),把BUILD文件放在每個目錄中。

  1. 明確模塊之間的關(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代碼中

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容