update something of Openthos, update some cmds
This commit is contained in:
parent
95e4bdc217
commit
2b8478050d
|
@ -0,0 +1,102 @@
|
|||
在Android7.0之前,使用的是GNU Make。从Android7.0开始,引入Soong。
|
||||
|
||||
#### Android.bp文件的格式
|
||||
|
||||
Android.bp的设计原则是简约,它不包含条件或控制流语句,所有的复杂性都是由go语言写的内在逻辑来控制的。
|
||||
|
||||
##### 模块Modules
|
||||
|
||||
模块类型详见:[module type](https://ci.android.com/builds/submitted/6066704/linux/latest/view/soong_build.html)。模块是由模块类型+一组键值对组成的。格式如下:
|
||||
|
||||
```
|
||||
cc_binary {
|
||||
name: "gzip",
|
||||
srcs: ["src/test/minigzip.c"],
|
||||
shared_libs: ["libz"],
|
||||
stl: "none",
|
||||
}
|
||||
```
|
||||
|
||||
- 模块名
|
||||
|
||||
cc_binary用于生成可以在设备上跑的二进制。
|
||||
|
||||
filegroup包含一个文件的列表,用于其它模块里属性的引用(使用`:<name>`语法),或者在包之间导出文件。
|
||||
|
||||
- 属性
|
||||
|
||||
`name`属性是必须的,它表示模块的名称。其值在所有模块里必须是唯一的。
|
||||
|
||||
`srcs`,表示用来编译C/C++模块的源文件列表。也可以使用语法`:module`来引用其它模块的输出。
|
||||
|
||||
`shared_libs`,表示其它模块的列表,这些模块将被动态链接到本模块中。
|
||||
|
||||
`stl`,选项要使用的STL库。可能的值是"libc++", "libc++_static", "libstdc++"或"none"。
|
||||
|
||||
##### 类型Types
|
||||
|
||||
变量和属性是强制类型的,变量的类型由第一次赋值时自动设定,属性的类型由模块类型静态设定。支持的类型有:
|
||||
|
||||
- 布尔型(true, false)
|
||||
- 整型(int)
|
||||
- 字符串(string)
|
||||
- 字符串列表(["string1","string2"])
|
||||
- Maps ({key1: "value1", key2: ["value2"]})
|
||||
|
||||
Maps可以包含任何类型的值,包括嵌套maps。
|
||||
|
||||
##### Globs
|
||||
|
||||
Glob模式是包含通配符的匹配模式。`*`可以匹配多个字符,`**`可以匹配多个路径。
|
||||
|
||||
##### 变量Variables
|
||||
|
||||
变量的作用域为文件的剩余部分,以及子bp文件里。变量是不可变的,但有一个例外:可以使用`+=`来追加一个值,但仅限于它们被引用前。
|
||||
|
||||
##### 注释Comments
|
||||
|
||||
支持`/* */`和`//`。
|
||||
|
||||
##### 操作符Operators
|
||||
|
||||
可以使用`+`操作符追加字符串,字符串列表或maps。也可以用`+`给整数求和。两个map执行`+`操作将使它们各自拥有对方的键值。
|
||||
|
||||
##### 条件判断Conditionals
|
||||
|
||||
大多数情况下,条件判断都可以写成map里的一个属性,由顶层的属性来决定使用哪一个的值。
|
||||
|
||||
例如,为了支持不同架构:
|
||||
|
||||
```
|
||||
cc_library {
|
||||
...
|
||||
srcs: ["generic.cpp"],
|
||||
arch: {
|
||||
arm: {
|
||||
srcs: ["arm.cpp"],
|
||||
},
|
||||
x86: {
|
||||
srcs: ["x86.cpp"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 规范化Formatter
|
||||
|
||||
```
|
||||
bpfmt -w . # 递归地重新格式化当前目录下的所有的Android.bp文件
|
||||
```
|
||||
|
||||
规范的格式包括:
|
||||
|
||||
- 四个空格的缩进
|
||||
- 多元素列表中每个元素后的新行
|
||||
- 列表和maps里的尾随逗号
|
||||
|
||||
#### 参考文档
|
||||
|
||||
- [Soong build system](https://source.android.com/setup/build)
|
|
@ -54,7 +54,7 @@ init是第一个进程,也叫root进程或所有进程的父进程。在此阶
|
|||
|
||||
如果当前运行的程序名是modprobe,则执行`modprobe_main`,应该是用来加载内核模块的。
|
||||
|
||||
如果当前运行的程序名是ueventd,则执行`ueventd_main`,进行设备节点的创建和权限设定。
|
||||
如果当前运行的程序名是ueventd,则执行`ueventd_main`,进行设备节点的创建和权限设定。对于ueventd_main,首先把umask修改为0;然后使用InitKernelLogging函数初始化内核的Log系统,这样ueventd就能通过内核的Log系统输出到串口了;然后注册selinux的回调函数用于打印Log;CreateDeviceHandler使用parser.ParseConfig来解析rc文件,。
|
||||
|
||||
如果当前运行的程序名是watchdogd,则执行`watchdogd_main`,用于系统出问题时重启系统。
|
||||
|
||||
|
@ -162,13 +162,23 @@ init是第一个进程,也叫root进程或所有进程的父进程。在此阶
|
|||
|
||||
2. 加入一些事件和Action
|
||||
|
||||
am.QueueEventTrigger("early-init")用于触发early-init事件。
|
||||
am.QueueEventTrigger("early-init")用于把early-init事件放到事件队列里。
|
||||
|
||||
am.QueueBuiltinAction用于添加Action,第一个参数是要执行的command,第二个参数是trigger。
|
||||
|
||||
am.QueueEventTrigger("init")用来触发所有的boot actions。
|
||||
am.QueueEventTrigger("init")用来把init事件放到事件队列里,init事件的作用触发所有的boot actions。
|
||||
|
||||
bootmode是个全局静态变量,用来标示启动模式,android的启动模式分为正常开机流程和关机充电流程。
|
||||
bootmode是个全局静态变量,用来标示启动模式,android的启动模式分为正常开机流程和关机充电流程。如果bootmode为"charge"则是关机充电流程,则把事件charge放到事件队列里;否则就是就是正常开机流程,这会把事件late-init放到事件队列里。
|
||||
|
||||
3. 事件队列里Action的执行过程
|
||||
|
||||
Action的执行次序是early-init, init, late-init。
|
||||
|
||||
在early-init里,首先是设置init进程及其子进程的oom_adj,然后禁用键盘中断,然后是创建一些目录挂载一些设备,最后启动uenventd服务。uenventd在/sbin/uenventd,是指向init的软链接,在init的main函数里可见最终调用的是ueventd_main函数。
|
||||
|
||||
在init里干了大部分的初始化工作。
|
||||
|
||||
在late-init里是把更多的Action加到了事件队列里。
|
||||
|
||||
##### init进程第二阶段之服务处理
|
||||
|
||||
|
@ -207,7 +217,7 @@ Zygote是一个虚拟机进程,由init进程启动。Zygote预加载以及初
|
|||
|
||||
zygote程序是app_process64,zygote_secondary程序是app_process32。两者的参数和属性基本相同。
|
||||
|
||||
- 在init.cpp的main里触发late-init,在init.rc的late-init里触发zygote-start,在init.rc的zygote-start里启动zygote进程和zygote_secondary进程。
|
||||
- 在init.cpp的main里把late-init加入运行队列,在init.rc的late-init里把zygote-start加入运行队列,在init.rc的zygote-start里启动zygote进程和zygote_secondary进程。
|
||||
|
||||
- 在init/builtins.cpp的builtin_functions里定义了start命令对应的函数do_start,do_start函数最终是调用对应server的Start方法,Start方法主要是fork一个新进程然后执行对应server的二进制文件。
|
||||
|
||||
|
@ -296,7 +306,7 @@ Zygote启动系统服务,即ZygoteInit类里的startSystemServer方法。
|
|||
从整体来看,一个rc文件是由若干个段组成的。一个段只能是Actions或Server其中之一:
|
||||
|
||||
- Actions,由trigger和它下面的一堆Commands组成。
|
||||
- Servers,由一堆Options组成。
|
||||
- Servers,由一堆Options组成。需要注意的是,Servers的启动也是在Actions里指定的(使用class_start命令或者start命令).
|
||||
|
||||
注意:Actions和Servers不能重名。如果重名了,后出现的定义将会作为错误而忽略掉。
|
||||
|
||||
|
@ -338,43 +348,21 @@ name是程序名,pathname是程序所在的路径,argument是程序的参数
|
|||
|
||||
Options是Services的修改器,它们影响init进程如何运行service以及何时运行service。
|
||||
|
||||
- console,此服务需要一个console。默认设备为`/dev/console`。也可自己指定,如`console /dev/tty0`,其中`/dev/`是可忽略的,即等同于`console tty0`。
|
||||
|
||||
- ctitical,此服务是一个设备关键服务。如果在4分钟内退出4次,设备将会重启进入recovery模式。
|
||||
|
||||
- disabled,此服务无法通过它所属的类型(class)来启动,必须通过它的名字来启动。这就意味着启动一个类型的服务时这种服务是不会被启动的,也就是它被disable掉了。
|
||||
|
||||
- setenv,在启动的进程里设置环境变量。
|
||||
|
||||
- socket \<name> \<type> \<perm> [\<user> [\<group>]]
|
||||
|
||||
创建一个unix域socket,它的名字叫/dev/socket/\<name>,并将它的fd传给启动的进程。
|
||||
|
||||
- file,打开一个文件并将它的fd传给启动的进程。
|
||||
|
||||
- user,在执行服务前改变用户(user),默认的用户是root。
|
||||
|
||||
- group,在执行服务前改变组名。
|
||||
- animation,将会包含所有启动和关闭animation所必须的服务。
|
||||
|
||||
- capabilities,在执行服务的时候设置capabilities.
|
||||
|
||||
- seclabel,在执行服务前改变为seclabel。
|
||||
|
||||
- oneshot,当服务退出后不要重启它。
|
||||
|
||||
- class,为服务指定所属的类型。在同一个类型里的服务可以同时打开或关闭。如不使用此选项明确指定服务所属的类型,则默认在default里。
|
||||
|
||||
- animation,将会包含所有启动和关闭animation所必须的服务。
|
||||
- console,此服务需要一个console。默认设备为`/dev/console`。也可自己指定,如`console /dev/tty0`,其中`/dev/`是可忽略的,即等同于`console tty0`。
|
||||
|
||||
- onrestart当服务重启的时候执行一条命令。
|
||||
- critical,此服务是一个设备关键服务。如果在4分钟内退出4次,设备将会重启进入recovery模式。
|
||||
|
||||
- writepid,当子进程forks的时候将其pid写到给定文件中。
|
||||
- disabled,此服务无法通过它所属的类型(class)来启动,必须通过它的名字来启动。这就意味着启动一个类型的服务时这种服务是不会被启动的,也就是它被disable掉了。
|
||||
|
||||
- priority,调度service进程的优先级。
|
||||
- file,打开一个文件并将它的fd传给启动的进程。
|
||||
|
||||
- namespace,当forking一个服务的时候,进入一个新的PID或挂载namespace。
|
||||
|
||||
- oom_score_adjust,设置子进程的变量值。
|
||||
- group,在执行服务前改变组名,默认的组是root。
|
||||
|
||||
- memcg.swappiness,设置子进程的变量值。
|
||||
|
||||
|
@ -382,8 +370,30 @@ Options是Services的修改器,它们影响init进程如何运行service以及
|
|||
|
||||
- memcg.limit_in_bytes,设置子进程的变量值。
|
||||
|
||||
- namespace,当forking一个服务的时候,进入一个新的PID或挂载namespace。
|
||||
|
||||
- oneshot,当服务退出后不要重启它。如果一个程序不是守护进程,应该使用这个选项。
|
||||
|
||||
- onrestart当服务重启的时候执行一条命令。
|
||||
|
||||
- oom_score_adjust,设置子进程的变量值。
|
||||
|
||||
- priority,调度service进程的优先级。
|
||||
|
||||
- seclabel,在执行服务前改变为seclabel。
|
||||
|
||||
- setenv,在启动的进程里设置环境变量。
|
||||
|
||||
- shutdown,设置关机的时候此service进程的行为。默认是关机进程通过传递SIGTERM和SIGKILL来杀死此服务。
|
||||
|
||||
- socket \<name> \<type> \<perm> [\<user> [\<group>]]
|
||||
|
||||
创建一个unix域socket,它的名字叫/dev/socket/\<name>,并将它的fd传给启动的进程。
|
||||
|
||||
- user,在执行服务前改变用户(user),默认的用户是root。
|
||||
|
||||
- writepid,当子进程forks的时候将其pid写到给定文件中。
|
||||
|
||||
##### Triggers
|
||||
|
||||
Triggers就是个字符串,用来匹配特定事件和触发一个action。分为事件触发器和权限触发器。
|
||||
|
@ -552,11 +562,10 @@ Triggers就是个字符串,用来匹配特定事件和触发一个action。分
|
|||
> Create a symbolic link at _path_ with the value _target_
|
||||
|
||||
`sysclktz <mins_west_of_gmt>`
|
||||
> Set the system clock base (0 if system clock ticks in GMT)
|
||||
> 设置系统时钟基础(0代表GMT,GMT的意思是格林尼治标准时间)。
|
||||
|
||||
`trigger <event>`
|
||||
> Trigger an event. Used to queue an action from another
|
||||
> action.
|
||||
> 触发一个事件。用于从其它动作里把一个动作加到队列里。
|
||||
|
||||
`umount <path>`
|
||||
> Unmount the filesystem mounted at that path.
|
||||
|
@ -580,11 +589,19 @@ Triggers就是个字符串,用来匹配特定事件和触发一个action。分
|
|||
> immediately.
|
||||
|
||||
`write <path> <content>`
|
||||
|
||||
> 把<content>写到<path>里。<content>里的属性将会展开。
|
||||
|
||||
##### Imports
|
||||
|
||||
解析init配置文件,扩展当前配置。
|
||||
`import <path>`
|
||||
|
||||
> 解析init配置文件,扩展当前配置。如果path是目录,此目录下的所有文件都将作为配置文件被解析,但这样的解析不是递归的,下级目录将不会被解析。
|
||||
>
|
||||
> import是个关键字(keyword)而不是命令(command),它不会是Action的一部分,它本身就是个独立的段(section),它的执行逻辑如下:
|
||||
>
|
||||
> - 如果是一个文件则解析这个文件,如果是一个目录则按字母序解析这个目录下的所有文件
|
||||
> - 如果文件里依然有import语句,则继续解析之(这意味着import不管出现在文件的什么位置,它总是最后执行的)
|
||||
|
||||
#### 参考文档
|
||||
|
||||
|
|
|
@ -56,76 +56,74 @@ lunch命令定义在build/envsetup.sh里,用来让用户选择编译设备与
|
|||
|
||||
### make
|
||||
|
||||
Android.mk和Android.bp都会转化成ninja文件,ninja才是真正的编译配置文件。
|
||||
- make命令定义在build/envsetup.sh里。
|
||||
|
||||
Android.mk收集生成out/build-openthos_x86_64.ninja。Android.bp收集生成out/soong/build.ninja.d,进而生成out/soong/build.ninja。out/combined-openthos_x86_64.ninja用于将如上两个文件组织起来。
|
||||
```
|
||||
function make()
|
||||
{
|
||||
_wrap_build $(get_make_command) "$@"
|
||||
}
|
||||
```
|
||||
|
||||
#### 构建的起点
|
||||
- 依据`get_make_command`函数的定义,$(get_make_command)的值是"build/soong/soong_ui.bash --make-mode"。
|
||||
|
||||
在`build/core/main.mk`,如没有指定编译目标,则默认编译目标是droid。droid的目标是编译出整个系统的镜像,对于openthos来说就会编译出openthos的镜像。
|
||||
- 在`_wrap_build`函数可见,第二行"$@"已经执行完所有的编译过程了,其它部分只不过是输出一些统计信息而已。
|
||||
|
||||
droid依赖droid_targets,droid_targets依赖blueprint_tools, apps_only, droidcore, dist_files。blueprint_tools是编译工具;apps_only会编译出不含user, userdebug和eng参数的应用程序;droidcore用来构建整个系统,它依赖了更多的目标,本身不进行任何处理;dist_files用来复制文件到out/dist目录,默认的编译目标是不会产生out/dist目录的,out/dist目录用于存放为多种分发而准备的包。
|
||||
- build/soonn/soong_ui.bash。首先执行build/soong/cmd/microfactory/microfactory.bash,定义了两个工具函数,`getoutdir`用来查找out目录,`build_go`用来编译所需的二进制(参数1是所要编译的二进制的名字,参数2是包名);然后用build_go来编译soong_ui,最后执行的是`out/soong_ui $@`完成构建的过程。
|
||||
|
||||
droidcore依赖files, systemimage和一堆$(INSTALLED_*)。files依赖了更多的目标,本身不进行任何处理;systemimage用来生成system.img,将被挂载为/system;其它依赖作用如下:
|
||||
- 函数build_go的执行逻辑:如果$mf_bin存在且$mf_version的值等于$mf_version_file里保存的值,说明$mf_bin存在且是最新的,此时它就是$mf_cmd;否则说明$mf_bin不存在或它的版本不是最新的,这时就需要构建新的$mf_cmd,它的值为`go run $mf_src/microfactory.go`。`$mf_cmd ...`那行是真正干活的,-s用来指示microfactory的源码目录,-b用来指示microfactory二进制的位置,-pkg-path是从包前缀到文件路径的映射,-trimpath用于从记录的源文件路径中删除前缀,-o用于指定输出文件的名称。
|
||||
|
||||
- $(INSTALLED_BOOTIMAGE_TARGET) :生成boot.img
|
||||
- $(INSTALLED_RECOVERYIMAGE_TARGET):生成recovery.img
|
||||
- $(INSTALLED_VBMETAIMAGE_TARGET)
|
||||
- $(INSTALLED_USERDATAIMAGE_TARGET) :生成userdata.img
|
||||
- $(INSTALLED_CACHEIMAGE_TARGET) :生成cache.img
|
||||
- $(INSTALLED_BPTIMAGE_TARGET)
|
||||
- $(INSTALLED_VENDORIMAGE_TARGET)
|
||||
- $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)
|
||||
- $(INSTALLED_FILES_FILE) :生成installed-files.txt文件,记录了当前镜像中已安装的文件列表。
|
||||
- $(INSTALLED_FILES_FILE_VENDOR)
|
||||
- $(INSTALLED_FILES_FILE_SYSTEMOTHER)
|
||||
#### 构建的过程
|
||||
|
||||
files依赖的目标如下:
|
||||
|
||||
- $(modules_to_install) :编译当前配置下所有需要被安装的模块
|
||||
- $(INSTALLED_ANDROID_INFO_TXT_TARGET):生成android-info.txt文件,记录当前build配置的设备信息。
|
||||
构建的起点在`build/core/main.mk`,可以看到整个文件的结构如下:
|
||||
|
||||
```
|
||||
49 include $(BUILD_SYSTEM)/config.mk # 定义基于配置和宿主信息的变量
|
||||
86 include $(BUILD_SYSTEM)/cleanbuild.mk # 定义删除编译结果的函数和目标
|
||||
133 include $(BUILD_SYSTEM)/definitions.mk # 定义编译过程中用到的变量和宏
|
||||
138~283 # 检查TARGET_BUILD_VARIANT变量有效性
|
||||
根据make参数决定编译目标
|
||||
419~423 # 加载所有子目录下的Android.mk
|
||||
从Android.md中筛选出TARGET_BUILD_VARIANT目标
|
||||
包含Makefile
|
||||
930~1183 定义一些目标
|
||||
ifndef KATI
|
||||
...
|
||||
else # KATI
|
||||
...
|
||||
endif # KATI
|
||||
```
|
||||
|
||||
由于没有定义KATI,所以走的是ifndef流程。MAKECMDGOALS是make执行时后面的参数,这意味着不管执行什么目标最终都执行的都是run_soong_ui这个目标。这样编译的控制权就交到了soong手上,后面的事就跟make没有关系了。
|
||||
|
||||
soong_ui代码在`build/soong/cmd/soong_ui/main.go`,真正干活的是main函数里的最后一句:
|
||||
|
||||
```
|
||||
build.Build(buildCtx, config, build.BuildAll)
|
||||
```
|
||||
|
||||
build.Build在`ui/build/build.go`,从中可以看到执行soong的流程:
|
||||
|
||||
1. `runMakeProductConfig`在ui/build/make.go,用来配置编译参数。在这里可以看到[第一段输出](# 第一段输出)
|
||||
|
||||
2. `runSoongBootstrap`和`runSoong`在ui/build/soong.go,分别运行的是`./bootstrap.bash`和`soong`两个命令。在这里可以看到[第二段输出](# 第二段输出)和[第三段输出](# 第三段输出)
|
||||
|
||||
`./bootstrap.bash`的最后一句会执行`build/blueprint/bootstrap.bash $@`,如不带参数则生成minibp,如带参数则生成一个基于Blueprint的构建系统。
|
||||
|
||||
3. `runKati`在ui/build/kati.go,运行的是ckati命令。把所有的Android.mk文件生成ninja文件。
|
||||
|
||||
4. `createCombinedBuildNinjaFile`在ui/build/build.go,在out/combined-openthos_x86_64.ninja文件里用include关键字把前两步生成的ninja文件包含进来。
|
||||
|
||||
5. `runNinja`在ui/build/ninja.go,运行ninja命令执行构建过程,所使用的配置文件就是第四步生成的combined-openthos_x86_64.ninja。在这里看到[第四段输出](# 第四段输出)
|
||||
|
||||
#### 第一段输出
|
||||
|
||||
在`build/core/dumpvar.mk`,输出的是关于编译环境的若干变量。
|
||||
|
||||
包含的次序main.mk --> config.mk --> dumpvar.mk
|
||||
输出的是关于编译环境的若干变量。
|
||||
|
||||
#### 第二段输出
|
||||
|
||||
在`build/soong/build.ninja.in`,编译生成`out/soong/.bootstrap`下的文件。源文件在build/blueprint。
|
||||
|
||||
包含的次序main.mk -->
|
||||
|
||||
#### 第三段输出
|
||||
|
||||
搜集所有的`Android.bp`文件生成build.ninja。
|
||||
|
||||
#### 第四段输出
|
||||
|
||||
编译生成`out/soong/.bootstrap`下的文件。
|
||||
|
||||
#### 第五段输出
|
||||
|
||||
看起来是包含更多的文件,包括`*.h *.cpp Android.bp`等。
|
||||
|
||||
#### 第六段输出
|
||||
|
||||
详细的编译过程
|
||||
|
||||
#### 第七段编译目标oto_img
|
||||
##### 第四段之生成oto_img
|
||||
|
||||
在bootable/newinstaller/Android.mk
|
||||
|
||||
|
@ -224,4 +222,6 @@ unsquashfs system.sfs
|
|||
|
||||
[理解安卓build系统](https://www.ibm.com/developerworks/cn/opensource/os-cn-android-build/)
|
||||
|
||||
[Android.bp及其工具链](http://note.qidong.name/2017/08/android-blueprint/)
|
||||
[Android.bp及其工具链](http://note.qidong.name/2017/08/android-blueprint/)
|
||||
|
||||
[Android Soong build系统介绍](https://www.jianshu.com/p/80013a768a45)
|
|
@ -0,0 +1,5 @@
|
|||
```
|
||||
source <filename> [arguments] # 在当前shell下执行filename里的命令
|
||||
# 返回filename里最后一条命令的返回值。如果filename不可读则错误。
|
||||
```
|
||||
|
|
@ -21,6 +21,9 @@ ctrl + b
|
|||
c # 创建新窗口
|
||||
& # 关闭当前窗口
|
||||
数字键 # 切换到指定窗口
|
||||
l # 切换到上一个窗口
|
||||
f # 依据窗口编号向前切换
|
||||
n # 住所窗口编号向后切换
|
||||
```
|
||||
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ V # 选择,以行为单位
|
|||
|
||||
w //移动到下个单词的第一个字符
|
||||
e //移动到下个单词的最后一个字符
|
||||
b # 移到上一个单词
|
||||
0 //移动到行首
|
||||
```
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ $(findstring)
|
|||
$(firstword)
|
||||
$(patsubst PATTERN,REPLACEMENT,TEXT)
|
||||
# 将TEXT中符合PATTERN的单词替换为PEPLACEMENT
|
||||
$(sort)
|
||||
$(sort <list>)
|
||||
# 给字符串<list>中的单词按升序排序,返回排序后的字符串。
|
||||
$(strip)
|
||||
$(subst)
|
||||
$(wildcard <PATTERN...>)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
```
|
||||
go <command> [arguments]
|
||||
```
|
||||
|
||||
#### 命令
|
||||
|
||||
```
|
||||
clean
|
||||
doc
|
||||
env
|
||||
fix
|
||||
fmt
|
||||
get
|
||||
install
|
||||
list
|
||||
test
|
||||
tool
|
||||
version
|
||||
vet
|
||||
```
|
||||
|
||||
##### build
|
||||
|
||||
```
|
||||
go build [-o output] [build flags] [packages] # 编译包和依赖
|
||||
# 选项
|
||||
```
|
||||
|
||||
##### run
|
||||
|
||||
```
|
||||
run [build flags] <gofiles> [arguments]
|
||||
# 编译和运行Go程序。关于[build flags]请查询"go-build"。
|
||||
```
|
||||
|
|
@ -39,12 +39,12 @@
|
|||
-o file
|
||||
-O [type]
|
||||
-p, --print-data-base
|
||||
-q
|
||||
-q, --question # 不运行任何命令,也不打印任何东西,只返回一个退出的状态。如果编译目标已经更新则返回0,否则返回其它数字。
|
||||
-r
|
||||
-R
|
||||
-s
|
||||
-S
|
||||
-t
|
||||
-t, --touch # 更新文件的日期,从而不执行它所依赖的命令。这实际上就是假装命令已经执行过了,以便make将来调用的时候欺骗它。
|
||||
--trace
|
||||
-v
|
||||
-w
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
一个构建工具,它的作用和make命令是一样的。
|
||||
|
||||
#### ninja文件介绍
|
||||
|
||||
```
|
||||
# 规则(rule)
|
||||
rule <rule_name>
|
||||
command = gcc ...
|
||||
description =
|
||||
|
||||
# build语句
|
||||
build <target_name> : <rule_name> <inputs>
|
||||
|
||||
# subninja和include,都是用来引入其它的ninja文件。不同点是,subninja引入的子模块可以使用父模块的变量,include引入的子模块不可以使用交模块中的变量。
|
||||
```
|
||||
|
Loading…
Reference in New Issue