|
|
1 năm trước cách đây | |
|---|---|---|
| .. | ||
| .gitignore | 1 năm trước cách đây | |
| README.md | 1 năm trước cách đây | |
该仓库基于 google 的 gn 仓库进行的翻译
GN 使用非常简单、动态类型的语言
true、false)字符串以双引号括起来,并使用反斜杠作为转义字符
但是反斜杠只支持 \"、 \$、 \\,反斜杠任何其他的用途都会被视为字面反斜杠
"C:\foo\bar.h"这里的\b没有被转义
字符串支持跟随 $ 符号的词被变量的值替换,也可以使用 {} 来替换变量值
以 a = "my_path" 为例
| 写法 | 实际值 |
|---|---|
b = "$a/foo.cc" |
b = "my_path/foo.cc" |
c = "$foo_{a}_bar.cc" |
c = "foo_my_path_bar.cc" |
列表支持增加、删除、索引操作,但是不支持获取列表长度
# 增加
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", "fourth" ]
# 索引
a = [ "first", "second", "third" ]
b = a[1] # -> "second"
[] 运算符是只读的,不能用于对列表进行改变,这种i情况的主要用途是当外部脚本返回几个已知值时,可以提取
a = [ "one" ]
a = [ "two" ] # Error: overwriting nonempty list with a nonempty list.
a = [] # OK
a = [ "two" ] # OK
if (is_linux || (is_win && target_cpu == "x86")) {
sources -= [ "something.cc" ]
} else if (...) {
...
} else {
...
}
foreach(i, mylist) {
print(i) # Note: i is a copy of each element, not a reference to it.
}
"foo.cc"
"src/foo.cc"
"../src/foo.cc"
"//net/foo.cc"
"//base/test/foo.cc"
"/usr/local/include/"
"/C:/Program Files/Windows Kits/Include"
| 命令 | 作用 |
|---|---|
| action | 运行脚本生成文件. |
| action_foreach | 为每个源文件运行一次脚本. |
| bundle_dat | 一个声明数据进入 MAC/iOS 包. |
| create_bundle | 创建一个 Mac/IOS 包. |
| executable | 生成一个可执行文件. |
| group | 是指一个或多个其他目标的虚拟依赖节点. |
| shared_library | 一个 . DLL 或.SO. |
| loadable_module | 一个 .DLL 或.SO ,只能在运行时加载. |
| source_set | 一个轻量级的虚拟静态库(通常比实际静态库更可取,因为它将更快地构建). |
| static_library | 是.LIB 或.file(通常你需要一个source_set取而代之) |
# 定义 config
config("my_config") {
# 预处理器宏定义
defines = [
"USE_FEATURE_X",
"ENABLE_LOGGING"
]
# 包含目录
include_dirs = [
"//include",
"//third_party/lib/include"
]
# 编译选项
cflags = [
"-Wall",
"-O2"
]
# 链接选项
ldflags = [
"-lmylib"
]
}
# 将 config 应用到目标
# 引用自定义配置文件
import("//configs/my_config.gni")
executable("my_app") {
sources = [
"main.cc",
"app.cc"
]
# 使用定义的 config
configs += [ ":my_config" ]
}
为什么上面例子应用 config 时要用 configs += [":my_config"] ?
这里 += 表示向现有的 configs 属性追加 :my_config,保留之前的所有设置。如果直接使用 = 则表示直接覆盖掉之前的配置
为什么应用 config 时要写 :my_config ?
:config_name 表示当前文件中的配置//path/to:config_name 表示绝对路劲的配置//path/to/configs:config_name 表示绝对路径下特定目录中的配置以下面的路劲为例子
my_project/
├── BUILD.gn
├── config/
│ └── my_config.gni
└── src/
└── main.cc
在 config/my_config.gni 中定义
config("my_config") {
cflags = [
"-Wall",
"-O2"
]
}
在 BUILD.gn 中
# 导入配置文件
import("//config/my_config.gni")
executable("my_app") {
sources = [
"src/main.cc"
]
# 正确的使用方式:使用绝对路径或当前作用域
configs = [ "//config:my_config" ] # 绝对路径
# 或
configs += [ ":my_config" ] # 当前作用域,假设 my_config 在当前文件中定义
}
假设模块A依赖于某个配置B,希望所有依赖于 A 模块的其他模块都依赖配置 B,这个时候应该使用 公共配置
# 配置B
config("my_external_library_config") {
includes = "."
defines = [ "DISABLE_JANK" ]
}
# 模块A
shared_library("my_external_library") {
...
# 所有依赖于这个库的目标都拿到了公共配置.
public_configs = [ ":my_external_library_config" ]
}
# 其他模块
static_library("intermediate_library") {
...
# Targets that depend on this one also get the configs from "my external library".
public_deps = [ ":my_external_library" ]
}
template 㻾创建自定义的符合构建目标。通过定义模板,可以将一组常用的构建配置封装起来,然后再多个地方复用,减少重复代码并提高构建文件的可维护性
# 定义 template
# my_templates.gni
template("my_executable_with_tests") {
# 定义模板参数
declare_args() {
sources = []
test_sources = []
}
# 创建可执行文件目标
executable(target_name) {
sources = sources
}
# 创建测试可执行文件目标
executable(target_name + "_test") {
sources = test_sources
deps = [ ":$target_name" ]
}
}
使用 template
# 引用模板文件
import("//path/to/my_templates.gni")
# 使用模板来创建构建目标
my_executable_with_tests("my_app") {
sources = [ "main.cc", "app.cc" ]
test_sources = [ "app_test.cc" ]
}
模板的第一个参数会被用作 target_name,即目标名称。所以 template 中定义的 target_name 对应的就是 my_app
除了定义之外,template 中还能定义 条件判断、循环、嵌套模板
# templates/my_templates.gni
template("my_executable_with_tests") {
declare_args() {
sources = []
test_sources = []
use_optimization = false
}
if (use_optimization) {
config("optimization_config") {
cflags = [ "-O2" ]
}
}
executable(target_name) {
sources = sources
if (use_optimization) {
configs += [ ":optimization_config" ]
}
}
executable(target_name + "_test") {
sources = test_sources
deps = [ ":$target_name" ]
}
}