成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

[GN+Ninja學習 0x03] GN語法與操作學習

數據庫 MySQL
這一篇,我們來學習GN的語法和操作行為等,GN提供了擴展的內置幫助文檔系統,提供每一個函數功能和內置變量的詳細的參考引用。

??想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區??

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

OpenHarmony使用gn+ninja來維護開源項目的構建。之前沒有接觸過gn+ninja,是時候系統性的來學習下了。邊學邊記錄下學習過程,希望對同樣需要學習gn+ninja的朋友有所幫助。

這一篇,我們來學習GN的語法和操作行為等,建議也可以閱讀原版文檔??GN Language and Operation??。
GN提供了擴展的內置幫助文檔系統,提供每一個函數功能和內置變量的詳細的參考引用。可以使用gn help來查看幫助,可以進一步使用gn help <command>、gn help <function>、gn help <variable>來查看具體的命令、函數、變量的使用幫助信息。

1、Design philosophy設計理念

  • 編寫構建文件不應該是一項創造性的工作。理想情況下,兩個人應該在相同的要求下生成相同的構建文件。除非絕對需要,否則不應該有靈活性。盡可能多的事情應該是致命的錯誤。
  • 構建定義應該讀起來更像代碼而不是規則。我不想編寫或調試Prolog。但是我們團隊中的每個人都可以編寫和調試C++和Python。
  • 構建語言應該對構建應該如何工作持固執己見。表達武斷的東西不一定容易,甚至不可能。我們應該改變源代碼和工具使構建更簡單,而不是使一切都更復雜以符合外部要求(在合理范圍內)。
  • 在有意義的時候,需要像Blaze一樣。

2、Language語言

GN使用機器簡單的,動態類型的語言。支持的類型有:

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

(1)Strings 字符串

字符串括在雙引號中,并使用反斜杠作為轉義字符。僅僅支持如下轉義序列是:

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

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

通過符號$支持簡單變量替換,其中美元符號$后面的單詞被替換為變量的值。如果沒有非變量名稱字符來終止變量名稱,則可以選擇${}將名稱括起來。不支持更復雜的表達式,僅支持變量名稱替換。

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

(2)Lists列表

除了把非空列表賦值給空列表(a == [])之外,沒有辦法獲得列表的長度。如果你發現自己想做這種事情,意味著在構建中做太多的工作?!?注:說的是,列表不提供獲取長度,也不應該獲取長度。

列表追加

列表支持追加,如下所示。將一個列表追加到另一個列表,會把每一個列表項追加為第二個列表中的項,而不是將該列表追加為嵌套成員。

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

列表刪除

還可以從列表中刪除項目,如下。列表中的減號運算符“-”搜索匹配項并刪除所有匹配項。從另一個列表中減去一個列表將刪除第二個列表中的每個項目。如果未找到匹配的項目,則會引發錯誤,因此您需要在刪除列表項之前,需要提前知道該列表項是否存在。

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

鑒于無法測試列表項的添加引入,可以這樣使用:設置一個文件或標志的主列表,然后根據各種條件刪除不適用于當前版本的文件或標志。— 注:這算是推薦做法,維護一個主列表,然后只做減法,排除不適合的列表項。這個和下文的GYP提供的建議一樣。這里讀起來有些奇怪。

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

列表項獲取

列表支持從零開始的下標來提取值:

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

[] 運算符是只讀的,不能用于改變列表。其主要使用場景是當外部腳本返回多個已知值,并且您想要提取它們時。

在某些情況下,覆蓋一個列表比追加到一個列表更容易。為了幫助滿足這種情況,將非空列表賦值給值為非空列表的變量,會產生錯誤。如果要繞過此限制,請首先將目標變量賦值給一個空列表。如下:

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

(3)Conditionals條件

條件語句類似于 C語言,如下。可以在大多數情況下,使用條件語句。甚至可以把整個target目標放在條件里,如果這些target只在特定的條件下才需要聲明。

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

(4)Looping循環

您可以使用foreach循環訪問列表。這是不鼓勵的。構建應該做的大多數事情通常都可以在不這樣做的情況下來完成,如果你覺得有必要,這可能表明你在元構建中做了太多的工作。

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

(5)Function calls函數調用

簡單的函數調用看起來像大多數其他語言:

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

這些函數是內置的,用戶無法定義新的函數。一些函數采用以下代碼塊括起來:{ }。

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

大多數函數定義了目標target。用戶可以使用下面討論的template模板機制定義這樣的新功能。

準確地說,上面說的代碼塊{}作為函數參數來執行函數的。大多數塊樣式的函數執行代碼塊,并將生成的作用域做為供讀取的變量字典。

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

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

除了最里面的作用域之外,無法修改任何封閉作用域。這意味著,例如,當您定義target目標時,您在塊內執行的任何操作都不會“泄漏”到文件的其余部分。

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

3、Naming things文件和目錄名稱

文件名和目錄名是字符串,被解釋為相對于當前構建文件的目錄。有三種可能的形式:

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

4、Build configuration構建配置

(1)Targets目標

一個目標target是構建圖中的一個節點。它通常表示將生成的某種可執行文件或庫文件。目標依賴于其他目標。內置目標類型如下所示??梢允褂妹頶n help <targettype>以獲取更多幫助??梢允褂媚0鍎摻ㄗ远x目標類型,來擴充內置的目標類型。

  • action:運行腳本以生成文件。
  • action_foreach:為每個源文件運行一次腳本。
  • bundle_data:聲明數據以進入 Mac/iOS 捆綁包。
  • create_bundle:創建蘋果/iOS 捆綁包。
  • executable:生成可執行文件。
  • group:引用一個或多個其他目標的虛擬依賴關系節點。
  • shared_library:共享庫.dll或 .so。
  • loadable_module:僅在運行時可加載.dll或 .so。
  • source_set:輕量級虛擬靜態庫(通常比真正的靜態庫更可取,因為它的構建速度更快)。
  • static_library:.lib 或 .a 文件(通??梢允褂靡粋€source_set替代)。

(2)Configs配置

Configs配置是命名對象,用于指定flags、include目錄和defines。它們可以應用于目標target并推送到依賴目標。

要定義配置,示例如下:

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

要將配置應用于目標,可以這樣做:

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

構建配置文件通常會為target目標指定包含默認配置的列表。目標可以根據需要向此列表中添加或刪除。因此,在實踐中,您通常會使用configs += ":myconfig"附加到默認值列表中。有關如何聲明和應用配置的詳細信息,請參閱gn help config。

(3)Public configs公共配置

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

為此,您需要使用要應用的配置項編寫一個配置config:

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

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

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

反過來,依賴目標可以通過將目標添加為“公共”依賴項,將其向上推進到依賴項樹的另一個級別。注:使用的配置項是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 重用代碼的主要方式。通常,模板會擴展一個或多個其他target目標類型。

# 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.
}
}

通常,模板定義將放在一個.gni文件中,用戶將導入該文件以查看模板定義:

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

聲明模板會在此Scope作用域內的變量周圍創建一個閉包。調用模板時,魔術變量invoker用于讀取Scope作用域外的變量。模板通常會將其感興趣的值復制到自己的Scope作用域內:

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

執行模板時的當前工作目錄將是調用的構建文件的目錄,而不是模板源文件的目錄。因此,從模板調用程序傳入的文件將是正確的(這通常占模板中的大多數文件處理)。但是,如果模板本身具有文件(也許它會生成運行腳本的操作),則需要使用絕對路徑(“//foo/...”)來引用這些文件,以說明當前目錄在調用期間是不可預測的。有關詳細信息和更完整的示例,請參閱gn help template幫助。

5、Other features其他特性

(1)Imports導入

您可以使用該import函數將.gni文件導入到當前作用域中。這不是C意義上的包含。導入的文件將獨立執行,生成的作用域將復制到當前文件中(C當包含指令出現時,在當前上下文中執行包含的文件)。這允許緩存導入的結果,并且還阻止了一些更“創造性”的包含使用,如多次包含的文件。

通常,.gni文件將定義構建參數和模板。有關詳細信息,請參閱gn help import。

您的.gni文件可以通過在名稱中使用前置下劃線(如_this)來表明該臨時變量不會到導入文件使用。

(2)Path processing路徑處理

通常,您需要相對于其他目錄創建文件名或文件名列表。這在運行腳本時尤其常見,腳本是使用構建輸出目錄作為當前目錄執行的,而構建文件通常引用相對于其包含目錄的文件。

您可以使用rebase_path轉換目錄。有關更多幫助和示例,請參閱gn help rebase_path。將相對于當前目錄的文件名轉換為相對于根構建目錄的典型用法是:new_paths = rebase_path("myfile.c", root_build_dir)。

(3)Patterns模式

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

它們就像簡單的正則表達式。有關詳細信息,請參閱gn help label_pattern。

(4)Executing scripts執行腳本

有兩種方法可以執行腳本。GN 中的所有外部腳本都是Python編寫的。第一種方法是作為構建步驟。這樣的腳本將接受一些輸入并生成一些作為構建部分的輸出。調用腳本的目標使用“action”目標類型進行聲明(請參見gn help action)。

執行腳本的第二種方法是在構建文件執行期間同步執行。在某些情況下,需要確定要編譯的文件集,或者獲取構建文件可能依賴的某些系統配置。構建文件可以讀取腳本的stdout標準輸出,并據此以不同的方式對其進行操作。

同步腳本執行由函數exec_script完成(有關詳細信息和示例,請參閱gn help exec_script)。由于同步執行腳本需要暫停當前構建文件的執行,直到Python進程完成執行,因此外部腳本的速度很慢,應將其最小化。

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

您可以同步讀取和寫入文件,這是不鼓勵的,但在同步運行腳本時偶爾是必需的。典型的用例是傳遞一個長度超過當前平臺命令行限制的文件名列表。請參閱gn help read_file和gn help write_file了解如何讀取和寫入文件。如果可能的話,應避免使用這些功能。

超過命令行長度限制的操作可以使用響應文件來繞過此限制,而無需同步寫入文件。查閱gn help response_file_contents了解更多內容。

6、小結

本篇,我們學習了GN語言語法與腳本操作,支持的變量類型,命名、構建配置等等。

??想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區??

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

責任編輯:jianghua 來源: 51CTO開源基礎軟件社區
相關推薦

2022-10-21 15:23:41

GN入門示例鴻蒙

2022-10-26 15:33:27

GN鴻蒙

2024-01-18 15:24:06

Rust開發鴻蒙OH4.0

2021-02-02 10:13:56

鴻蒙HarmonyOS應用開發

2012-05-10 15:35:29

WA2110-GNH3C

2012-05-16 15:03:53

WA2110-GN

2020-12-01 15:54:08

鴻蒙構建系統

2022-06-10 14:37:24

鴻蒙操作系統

2009-06-12 15:13:12

Hibernate學習

2024-01-11 16:02:38

OHOS依賴關系檢查編譯構建系統

2023-06-12 15:43:44

鴻蒙智能家居開發

2009-09-04 09:00:29

Java基礎語法

2016-12-27 15:16:49

損失函數課程

2017-09-13 10:06:36

人工智能阿里云

2020-12-10 12:12:32

鴻蒙開發板init_lite

2011-06-15 15:55:36

PHP

2010-07-20 15:18:41

Perl基本語法

2017-03-24 10:23:37

Python語法機器學習環境搭建

2017-06-22 09:45:58

阿里云GN5實例深度學習

2017-04-14 14:57:03

機器學習學習資源
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲日韩中文字幕一区 | 中文字幕日本一区二区 | 成人免费看片网 | 免费观看黄a一级视频 | 久草精品视频 | 成人欧美一区二区三区色青冈 | 九九av| 91av视频在线播放 | 国产免费国产 | 在线一区二区三区 | 亚洲女人的天堂 | 国产999在线观看 | 国产成人影院 | 国产四区 | 成年人精品视频 | 亚洲欧美在线观看 | 91精品久久久久久久久 | 成人黄色在线观看 | 九九精品网 | 亚洲一区二区三区四区五区午夜 | 精品国产免费一区二区三区五区 | 日韩在线观看中文字幕 | 91在线最新 | 激情欧美日韩一区二区 | 天天综合久久 | 精品亚洲国产成av人片传媒 | 国产精品1区2区3区 国产在线观看一区 | 国产美女精品视频 | 另类专区亚洲 | 亚洲国产18 | 在线免费中文字幕 | 青青草精品视频 | 毛片视频网站 | 国产精品免费视频一区 | 嫩草视频网 | 欧美日韩亚洲在线 | 精品欧美乱码久久久久久1区2区 | 在线观看视频一区 | 久久久久久亚洲欧洲 | 亚洲 欧美 日韩 在线 | 视频精品一区二区三区 |