自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

[GN+Ninja學(xué)習(xí) 0x03] GN語(yǔ)法與操作學(xué)習(xí)

數(shù)據(jù)庫(kù) MySQL
這一篇,我們來(lái)學(xué)習(xí)GN的語(yǔ)法和操作行為等,GN提供了擴(kuò)展的內(nèi)置幫助文檔系統(tǒng),提供每一個(gè)函數(shù)功能和內(nèi)置變量的詳細(xì)的參考引用。

??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??

??51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)??

??https://ost.51cto.com??

OpenHarmony使用gn+ninja來(lái)維護(hù)開(kāi)源項(xiàng)目的構(gòu)建。之前沒(méi)有接觸過(guò)gn+ninja,是時(shí)候系統(tǒng)性的來(lái)學(xué)習(xí)下了。邊學(xué)邊記錄下學(xué)習(xí)過(guò)程,希望對(duì)同樣需要學(xué)習(xí)gn+ninja的朋友有所幫助。

這一篇,我們來(lái)學(xué)習(xí)GN的語(yǔ)法和操作行為等,建議也可以閱讀原版文檔??GN Language and Operation??。
GN提供了擴(kuò)展的內(nèi)置幫助文檔系統(tǒng),提供每一個(gè)函數(shù)功能和內(nèi)置變量的詳細(xì)的參考引用??梢允褂胓n help來(lái)查看幫助,可以進(jìn)一步使用gn help <command>、gn help <function>、gn help <variable>來(lái)查看具體的命令、函數(shù)、變量的使用幫助信息。

1、Design philosophy設(shè)計(jì)理念

  • 編寫構(gòu)建文件不應(yīng)該是一項(xiàng)創(chuàng)造性的工作。理想情況下,兩個(gè)人應(yīng)該在相同的要求下生成相同的構(gòu)建文件。除非絕對(duì)需要,否則不應(yīng)該有靈活性。盡可能多的事情應(yīng)該是致命的錯(cuò)誤。
  • 構(gòu)建定義應(yīng)該讀起來(lái)更像代碼而不是規(guī)則。我不想編寫或調(diào)試Prolog。但是我們團(tuán)隊(duì)中的每個(gè)人都可以編寫和調(diào)試C++和Python。
  • 構(gòu)建語(yǔ)言應(yīng)該對(duì)構(gòu)建應(yīng)該如何工作持固執(zhí)己見(jiàn)。表達(dá)武斷的東西不一定容易,甚至不可能。我們應(yīng)該改變?cè)创a和工具使構(gòu)建更簡(jiǎn)單,而不是使一切都更復(fù)雜以符合外部要求(在合理范圍內(nèi))。
  • 在有意義的時(shí)候,需要像Blaze一樣。

2、Language語(yǔ)言

GN使用機(jī)器簡(jiǎn)單的,動(dòng)態(tài)類型的語(yǔ)言。支持的類型有:

  • Boolean (true, false). 布爾值。
  • 64-bit signed integers. 64位有符號(hào)整數(shù)。
  • Strings. 字符串。
  • Lists (of any other types). 上述類型的列表。
  • Scopes (sort of like a dictionary, only for built-in stuff). 作用域(類似字典)。

(1)Strings 字符串

字符串括在雙引號(hào)中,并使用反斜杠作為轉(zhuǎn)義字符。僅僅支持如下轉(zhuǎn)義序列是:

- \"(雙引號(hào))
- \$(美元符號(hào)$)
- \\(反斜杠)

反斜杠的任何其他用法都被視為反斜杠。因此,例如,\b不需要轉(zhuǎn)義,大多數(shù) Windows 路徑如 "C:\foo\bar.h")不需要轉(zhuǎn)義。

通過(guò)符號(hào)$支持簡(jiǎn)單變量替換,其中美元符號(hào)$后面的單詞被替換為變量的值。如果沒(méi)有非變量名稱字符來(lái)終止變量名稱,則可以選擇${}將名稱括起來(lái)。不支持更復(fù)雜的表達(dá)式,僅支持變量名稱替換。

a = "mypath"
b = "$a/foo.cc" # b -> "mypath/foo.cc"
c = "foo${a}bar.cc" # c -> "foomypathbar.cc"

(2)Lists列表

除了把非空列表賦值給空列表(a == [])之外,沒(méi)有辦法獲得列表的長(zhǎng)度。如果你發(fā)現(xiàn)自己想做這種事情,意味著在構(gòu)建中做太多的工作。— 注:說(shuō)的是,列表不提供獲取長(zhǎng)度,也不應(yīng)該獲取長(zhǎng)度。

列表追加

列表支持追加,如下所示。將一個(gè)列表追加到另一個(gè)列表,會(huì)把每一個(gè)列表項(xiàng)追加為第二個(gè)列表中的項(xiàng),而不是將該列表追加為嵌套成員。

a = [ "first" ]
a += [ "second" ] # [ "first", "second" ]
a += [ "third", "fourth" ] # [ "first", "second", "third", "fourth" ]
b = a + [ "fifth" ] # [ "first", "second", "third", "fourth", "fifth" ]

列表刪除

還可以從列表中刪除項(xiàng)目,如下。列表中的減號(hào)運(yùn)算符“-”搜索匹配項(xiàng)并刪除所有匹配項(xiàng)。從另一個(gè)列表中減去一個(gè)列表將刪除第二個(gè)列表中的每個(gè)項(xiàng)目。如果未找到匹配的項(xiàng)目,則會(huì)引發(fā)錯(cuò)誤,因此您需要在刪除列表項(xiàng)之前,需要提前知道該列表項(xiàng)是否存在。

a = [ "first", "second", "third", "first" ]
b = a - [ "first" ] # [ "second", "third" ]
a -= [ "second" ] # [ "first", "third", "first" ]

鑒于無(wú)法測(cè)試列表項(xiàng)的添加引入,可以這樣使用:設(shè)置一個(gè)文件或標(biāo)志的主列表,然后根據(jù)各種條件刪除不適用于當(dāng)前版本的文件或標(biāo)志。— 注:這算是推薦做法,維護(hù)一個(gè)主列表,然后只做減法,排除不適合的列表項(xiàng)。這個(gè)和下文的GYP提供的建議一樣。這里讀起來(lái)有些奇怪。

在風(fēng)格上,更喜歡只添加到列表中,讓每個(gè)源文件或依賴項(xiàng)出現(xiàn)一次。這與Chrome團(tuán)隊(duì)過(guò)去為GYP提供的建議相反(GYP更愿意列出所有文件,然后基于條件刪除您不需要的文件)。

列表項(xiàng)獲取

列表支持從零開(kāi)始的下標(biāo)來(lái)提取值:

a = [ "first", "second", "third" ]
b = a[1] # -> "second"

[] 運(yùn)算符是只讀的,不能用于改變列表。其主要使用場(chǎng)景是當(dāng)外部腳本返回多個(gè)已知值,并且您想要提取它們時(shí)。

在某些情況下,覆蓋一個(gè)列表比追加到一個(gè)列表更容易。為了幫助滿足這種情況,將非空列表賦值給值為非空列表的變量,會(huì)產(chǎn)生錯(cuò)誤。如果要繞過(guò)此限制,請(qǐng)首先將目標(biāo)變量賦值給一個(gè)空列表。如下:

a = [ "one" ]
a = [ "two" ] # Error: overwriting nonempty list with a nonempty list.
a = [] # OK
a = [ "two" ] # OK

(3)Conditionals條件

條件語(yǔ)句類似于 C語(yǔ)言,如下??梢栽诖蠖鄶?shù)情況下,使用條件語(yǔ)句。甚至可以把整個(gè)target目標(biāo)放在條件里,如果這些target只在特定的條件下才需要聲明。

if (is_linux || (is_win && target_cpu == "x86")) {
sources -= [ "something.cc" ]
} else if (...) {
...
} else {
...
}

(4)Looping循環(huán)

您可以使用foreach循環(huán)訪問(wèn)列表。這是不鼓勵(lì)的。構(gòu)建應(yīng)該做的大多數(shù)事情通常都可以在不這樣做的情況下來(lái)完成,如果你覺(jué)得有必要,這可能表明你在元構(gòu)建中做了太多的工作。

foreach(i, mylist) {
print(i) # Note: i is a copy of each element, not a reference to it.
}

(5)Function calls函數(shù)調(diào)用

簡(jiǎn)單的函數(shù)調(diào)用看起來(lái)像大多數(shù)其他語(yǔ)言:

print("hello, world")
assert(is_win, "This should only be executed on Windows")

這些函數(shù)是內(nèi)置的,用戶無(wú)法定義新的函數(shù)。一些函數(shù)采用以下代碼塊括起來(lái):{ }。

static_library("mylibrary") {
sources = [ "a.cc" ]
}

大多數(shù)函數(shù)定義了目標(biāo)target。用戶可以使用下面討論的template模板機(jī)制定義這樣的新功能。

準(zhǔn)確地說(shuō),上面說(shuō)的代碼塊{}作為函數(shù)參數(shù)來(lái)執(zhí)行函數(shù)的。大多數(shù)塊樣式的函數(shù)執(zhí)行代碼塊,并將生成的作用域做為供讀取的變量字典。

(6)Scoping and execution作用域與執(zhí)行

文件和函數(shù)調(diào)用后面跟的{}塊引入新的作用域。作用域是嵌套的。讀取變量時(shí),將按相反的順序搜索包含作用域,直到找到匹配的名稱。變量寫入始終轉(zhuǎn)到最內(nèi)層的作用域。

除了最里面的作用域之外,無(wú)法修改任何封閉作用域。這意味著,例如,當(dāng)您定義target目標(biāo)時(shí),您在塊內(nèi)執(zhí)行的任何操作都不會(huì)“泄漏”到文件的其余部分。

if/else/foreach語(yǔ)句,即使它們使用{}塊,也不會(huì)引入新的作用域,因此更改將保留在語(yǔ)句之外。

3、Naming things文件和目錄名稱

文件名和目錄名是字符串,被解釋為相對(duì)于當(dāng)前構(gòu)建文件的目錄。有三種可能的形式:

  • 相對(duì)名稱:
"foo.cc"
"src/foo.cc"
"../src/foo.cc"
  • 源樹(shù)絕對(duì)名稱:
"http://net/foo.cc"
"http://base/test/foo.cc"
  • 系統(tǒng)絕對(duì)名稱(罕見(jiàn),通常用于包含目錄):
"/usr/local/include/"
"/C:/Program Files/Windows Kits/Include"

4、Build configuration構(gòu)建配置

(1)Targets目標(biāo)

一個(gè)目標(biāo)target是構(gòu)建圖中的一個(gè)節(jié)點(diǎn)。它通常表示將生成的某種可執(zhí)行文件或庫(kù)文件。目標(biāo)依賴于其他目標(biāo)。內(nèi)置目標(biāo)類型如下所示。可以使用命令gn help <targettype>以獲取更多幫助??梢允褂媚0鍎?chuàng)建自定義目標(biāo)類型,來(lái)擴(kuò)充內(nèi)置的目標(biāo)類型。

  • action:運(yùn)行腳本以生成文件。
  • action_foreach:為每個(gè)源文件運(yùn)行一次腳本。
  • bundle_data:聲明數(shù)據(jù)以進(jìn)入 Mac/iOS 捆綁包。
  • create_bundle:創(chuàng)建蘋果/iOS 捆綁包。
  • executable:生成可執(zhí)行文件。
  • group:引用一個(gè)或多個(gè)其他目標(biāo)的虛擬依賴關(guān)系節(jié)點(diǎn)。
  • shared_library:共享庫(kù).dll或 .so。
  • loadable_module:僅在運(yùn)行時(shí)可加載.dll或 .so。
  • source_set:輕量級(jí)虛擬靜態(tài)庫(kù)(通常比真正的靜態(tài)庫(kù)更可取,因?yàn)樗臉?gòu)建速度更快)。
  • static_library:.lib 或 .a 文件(通??梢允褂靡粋€(gè)source_set替代)。

(2)Configs配置

Configs配置是命名對(duì)象,用于指定flags、include目錄和defines。它們可以應(yīng)用于目標(biāo)target并推送到依賴目標(biāo)。

要定義配置,示例如下:

config("myconfig") {
includes = [ "src/include" ]
defines = [ "ENABLE_DOOM_MELON" ]
}

要將配置應(yīng)用于目標(biāo),可以這樣做:

executable("doom_melon") {
configs = [ ":myconfig" ]
}

構(gòu)建配置文件通常會(huì)為target目標(biāo)指定包含默認(rèn)配置的列表。目標(biāo)可以根據(jù)需要向此列表中添加或刪除。因此,在實(shí)踐中,您通常會(huì)使用configs += ":myconfig"附加到默認(rèn)值列表中。有關(guān)如何聲明和應(yīng)用配置的詳細(xì)信息,請(qǐng)參閱gn help config。

(3)Public configs公共配置

一個(gè)target目標(biāo)可以將配置項(xiàng)應(yīng)用于依賴于它的其他target目標(biāo)上。最常見(jiàn)的示例是第三方目標(biāo),它需要一些定義define或包含頭文件的include目錄,才能正確編譯。您希望這些配置項(xiàng)既應(yīng)用于第三方庫(kù)本身的編譯,也應(yīng)用于使用該庫(kù)的所有目標(biāo)。

為此,您需要使用要應(yīng)用的配置項(xiàng)編寫一個(gè)配置config:

config("my_external_library_config") {
includes = "."
defines = [ "DISABLE_JANK" ]
}

然后,此配置將作為“公共”配置添加到目標(biāo)中。它將既適用于目標(biāo),也適用于直接依賴于它的目標(biāo)。注:使用的配置項(xiàng)是public_configs。

shared_library("my_external_library") {
...
# Targets that depend on this get this config applied.
public_configs = [ ":my_external_library_config" ]
}

反過(guò)來(lái),依賴目標(biāo)可以通過(guò)將目標(biāo)添加為“公共”依賴項(xiàng),將其向上推進(jìn)到依賴項(xiàng)樹(shù)的另一個(gè)級(jí)別。注:使用的配置項(xiàng)是public_deps。

static_library("intermediate_library") {
...
# Targets that depend on this one also get the configs from "my external library".
public_deps = [ ":my_external_library" ]
}

(4)Templates模板

模板是 GN 重用代碼的主要方式。通常,模板會(huì)擴(kuò)展一個(gè)或多個(gè)其他target目標(biāo)類型。

# Declares a script that compiles IDL files to source, and then compiles those
# source files.
template("idl") {
# Always base helper targets on target_name so they're unique. Target name
# will be the string passed as the name when the template is invoked.
idl_target_name = "${target_name}_generate"
action_foreach(idl_target_name) {
...
}
# Your template should always define a target with the name target_name.
# When other targets depend on your template invocation, this will be the
# destination of that dependency.
source_set(target_name) {
...
deps = [ ":$idl_target_name" ] # Require the sources to be compiled.
}
}

通常,模板定義將放在一個(gè).gni文件中,用戶將導(dǎo)入該文件以查看模板定義:

import("http://tools/idl_compiler.gni")
idl("my_interfaces") {
sources = [ "a.idl", "b.idl" ]
}

聲明模板會(huì)在此Scope作用域內(nèi)的變量周圍創(chuàng)建一個(gè)閉包。調(diào)用模板時(shí),魔術(shù)變量invoker用于讀取Scope作用域外的變量。模板通常會(huì)將其感興趣的值復(fù)制到自己的Scope作用域內(nèi):

template("idl") {
source_set(target_name) {
sources = invoker.sources
}
}

執(zhí)行模板時(shí)的當(dāng)前工作目錄將是調(diào)用的構(gòu)建文件的目錄,而不是模板源文件的目錄。因此,從模板調(diào)用程序傳入的文件將是正確的(這通常占模板中的大多數(shù)文件處理)。但是,如果模板本身具有文件(也許它會(huì)生成運(yùn)行腳本的操作),則需要使用絕對(duì)路徑(“//foo/...”)來(lái)引用這些文件,以說(shuō)明當(dāng)前目錄在調(diào)用期間是不可預(yù)測(cè)的。有關(guān)詳細(xì)信息和更完整的示例,請(qǐng)參閱gn help template幫助。

5、Other features其他特性

(1)Imports導(dǎo)入

您可以使用該import函數(shù)將.gni文件導(dǎo)入到當(dāng)前作用域中。這不是C意義上的包含。導(dǎo)入的文件將獨(dú)立執(zhí)行,生成的作用域?qū)?fù)制到當(dāng)前文件中(C當(dāng)包含指令出現(xiàn)時(shí),在當(dāng)前上下文中執(zhí)行包含的文件)。這允許緩存導(dǎo)入的結(jié)果,并且還阻止了一些更“創(chuàng)造性”的包含使用,如多次包含的文件。

通常,.gni文件將定義構(gòu)建參數(shù)和模板。有關(guān)詳細(xì)信息,請(qǐng)參閱gn help import。

您的.gni文件可以通過(guò)在名稱中使用前置下劃線(如_this)來(lái)表明該臨時(shí)變量不會(huì)到導(dǎo)入文件使用。

(2)Path processing路徑處理

通常,您需要相對(duì)于其他目錄創(chuàng)建文件名或文件名列表。這在運(yùn)行腳本時(shí)尤其常見(jiàn),腳本是使用構(gòu)建輸出目錄作為當(dāng)前目錄執(zhí)行的,而構(gòu)建文件通常引用相對(duì)于其包含目錄的文件。

您可以使用rebase_path轉(zhuǎn)換目錄。有關(guān)更多幫助和示例,請(qǐng)參閱gn help rebase_path。將相對(duì)于當(dāng)前目錄的文件名轉(zhuǎn)換為相對(duì)于根構(gòu)建目錄的典型用法是:new_paths = rebase_path("myfile.c", root_build_dir)。

(3)Patterns模式

模式用于為自定義target目標(biāo)類型的一組給定輸入生成輸出文件名,并自動(dòng)從列表值中刪除文件(請(qǐng)參見(jiàn)gn help filter_include和gn help filter_exclude)。

它們就像簡(jiǎn)單的正則表達(dá)式。有關(guān)詳細(xì)信息,請(qǐng)參閱gn help label_pattern。

(4)Executing scripts執(zhí)行腳本

有兩種方法可以執(zhí)行腳本。GN 中的所有外部腳本都是Python編寫的。第一種方法是作為構(gòu)建步驟。這樣的腳本將接受一些輸入并生成一些作為構(gòu)建部分的輸出。調(diào)用腳本的目標(biāo)使用“action”目標(biāo)類型進(jìn)行聲明(請(qǐng)參見(jiàn)gn help action)。

執(zhí)行腳本的第二種方法是在構(gòu)建文件執(zhí)行期間同步執(zhí)行。在某些情況下,需要確定要編譯的文件集,或者獲取構(gòu)建文件可能依賴的某些系統(tǒng)配置。構(gòu)建文件可以讀取腳本的stdout標(biāo)準(zhǔn)輸出,并據(jù)此以不同的方式對(duì)其進(jìn)行操作。

同步腳本執(zhí)行由函數(shù)exec_script完成(有關(guān)詳細(xì)信息和示例,請(qǐng)參閱gn help exec_script)。由于同步執(zhí)行腳本需要暫停當(dāng)前構(gòu)建文件的執(zhí)行,直到Python進(jìn)程完成執(zhí)行,因此外部腳本的速度很慢,應(yīng)將其最小化。

為防止濫用,允許調(diào)用exec_script的文件可以在頂級(jí).gn文件中列入白名單。更多信息參考gn help dotfile。

您可以同步讀取和寫入文件,這是不鼓勵(lì)的,但在同步運(yùn)行腳本時(shí)偶爾是必需的。典型的用例是傳遞一個(gè)長(zhǎng)度超過(guò)當(dāng)前平臺(tái)命令行限制的文件名列表。請(qǐng)參閱gn help read_file和gn help write_file了解如何讀取和寫入文件。如果可能的話,應(yīng)避免使用這些功能。

超過(guò)命令行長(zhǎng)度限制的操作可以使用響應(yīng)文件來(lái)繞過(guò)此限制,而無(wú)需同步寫入文件。查閱gn help response_file_contents了解更多內(nèi)容。

6、小結(jié)

本篇,我們學(xué)習(xí)了GN語(yǔ)言語(yǔ)法與腳本操作,支持的變量類型,命名、構(gòu)建配置等等。

??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??

??51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)??

??https://ost.51cto.com??。

責(zé)任編輯:jianghua 來(lái)源: 51CTO開(kāi)源基礎(chǔ)軟件社區(qū)
相關(guān)推薦

2022-10-26 15:33:27

GN鴻蒙

2022-10-21 15:23:41

GN入門示例鴻蒙

2024-01-18 15:24:06

Rust開(kāi)發(fā)鴻蒙OH4.0

2021-02-02 10:13:56

鴻蒙HarmonyOS應(yīng)用開(kāi)發(fā)

2012-05-16 15:03:53

WA2110-GN

2012-05-10 15:35:29

WA2110-GNH3C

2020-12-01 15:54:08

鴻蒙構(gòu)建系統(tǒng)

2009-06-12 15:13:12

Hibernate學(xué)習(xí)

2022-06-10 14:37:24

鴻蒙操作系統(tǒng)

2016-12-27 15:16:49

損失函數(shù)課程

2009-09-04 09:00:29

Java基礎(chǔ)語(yǔ)法

2024-01-11 16:02:38

OHOS依賴關(guān)系檢查編譯構(gòu)建系統(tǒng)

2011-06-15 15:55:36

PHP

2010-07-20 15:18:41

Perl基本語(yǔ)法

2017-03-24 10:23:37

Python語(yǔ)法機(jī)器學(xué)習(xí)環(huán)境搭建

2023-06-12 15:43:44

鴻蒙智能家居開(kāi)發(fā)

2020-12-10 12:12:32

鴻蒙開(kāi)發(fā)板init_lite

2017-04-14 14:57:03

機(jī)器學(xué)習(xí)學(xué)習(xí)資源

2010-02-05 16:04:45

X86 Android

2009-09-10 13:54:27

LINQ語(yǔ)法
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)