Chromium整体的构建过程大体如下:
这个过程大体为,先由gn工具根据各个模块的.gn配置文件,或gyp工具根据各个模块的.gyp配置文件,产生.ninja文件,再由ninja工具产生最终的目标文件,比如静态库、动态库、exe可执行文件或者是apk文件等等。gyp工具是用Python写的,gn是用C写的,gn增量构建最快。整个Chromium项目,在构建系统方面,也是逐渐在全部转向gn构建。
gn工具不仅仅在我们构建chromium时可以用来产生.ninja文件,它还可以帮助我们描绘chromium的项目地图,比如获取某个模块依赖的所有其它模块,依赖某个模块的所有其它模块、构建参数等信息,可以帮助我们对构建配置的有效性进行检查等。在基于chromium模块进行开发时,gn工具可以为我们提供巨大的帮助。
这里我们来看一下gn工具的用法,逐个来看gn提供的每个命令。
gn args
这个命令有两个作用,一是生成.ninja构建配置文件,二是查看当前构建环境的配置参数。
生成.ninja
生成.ninja是gn工具的基本功能。如在 Chromium Android编译指南 中所示,要构建chromium,或其中的模块,需要先生成.ninja文件对整个构建环境进行配置。为Android版chromium做构建配置时,所执行的命令为:
这个命令的参数是输出目录的路径。这个命令启动系统的默认编辑器,创建out/Default/args.gn
文件,我们在编辑器中加入我们自己的配置项,如:
gn根据创建的out/Default/args.gn
文件,及系统中其它的配置,产生ninja文件。
查看当前构建环境的配置参数
gn args命令还可以查看当前构建环境的可以配置的参数,参数的默认值及默认值的配置文件等。chromium用到了许多的配置参数。对于这些配置参数中的大多数,即使用户不指定,chromium的构建系统也会提供默认值。当我们在为不知道可以对构建做些什么样的配置,各个配置项的含义,或者配置项默认值的设置位置而抓狂时,这个命令会显得非常有价值。
对于Chromium的Android构建环境,能配置的参数及其相关信息大体如下:
这个功能的gn args命令参数为--list [output_dir]
。可见gn向我们展示了能为构建定制的每个参数,参数的默认值,及设置参数默认值的文件的位置。
这个工具展示了每一个标记配置项的名称,默认值,创建该标记配置项的配置文件,以及标记配置项作用的说明。
gn gen
这个命令也是用于产生.ninja文件的,其参数如下:
这个命令根据当前的代码树及配置,产生ninja文件,并把它们放在给定的目录下。输出目录可以是源码库的绝对地址,比如//out/foo
,也可以是相对于当前目录的地址,如:out/foo
。上面的gn args out/Default
实际上等价于,启动编辑器编辑参数创建out/Default/args.gn
文件之后,执行gn gen <out_dir>
。
实际在构建chromium及其子模块时,这个命令会更加常用。对于特定的平台,通常我们在完成构建环境的配置之后,就不会经常有修改构建配置参数文件的需要了。
gn clean
这个命令用于对历史构建进行清理。
它会删除输出目录下除args.gn
文件外的所有内容,并创建一个可以重新产生构建配置的ninja构建环境。这个命令也比较常用,用来消除历史构建的影响。
gn desc
这个命令用于显示关于一个给定target或config的信息。
构建参数等相关信息,取自给出的<out_dir>
。<label or pattern>
可以是一个target标签,一个config标签,或一个标签模式 (参考”gn help label_pattern”)。标签模式只匹配targets。
比如我们要查看chromium的net模块相关的信息:
可以看到gn desc命令向我们展示了,编译net模块时,包含的所有源文件,该模块发布的头文件,依赖的库,依赖的头文件路径,依赖的库文件的路径,依赖的其它模块,编译参数,链接参数,预定义宏等等等,应有尽有。在我们不喜欢chromium的构建系统及其项目的文件组织结构,而想要将某个模块转换为其它的文件组织结构,比如Eclipse或其它IDE常见的项目文件组织方式时,或者要将编译出来的动态链接库so文件用在其它项目里,被预定义宏的差异搞得焦头烂额时,这个命令就能派上用场了。
借助于这个工具,我们可以很方便的开发自动化的工具,来将chromium的模块单独抽出来用在其它地方,比如我们可以提取net模块发布的头文件,将net模块用在android中。我们之前就有做过这样一个小工具:
这个命令还可以帮我们dump出模块的整个依赖树,如net模块的依赖树:
这个命令可以为我们展示不同类型信息的每一项具体来自于哪个文件。如net模块的C编译标记选项(cflags)的信息如下:
gn ls
这个命令展示给定构建目录下,匹配某个模式的所有targets。
默认情况下,除非明确地提供了工具链参数,只有默认工具链中的target会被匹配。如果没有指定标签参数,则显示所有的targets。标签模式不是常规的正则表达式 (可以参考”gn help label_pattern”)。如net下的targets:
其它一些关于gn ls命令的例子:
gn path
这命令查找两个taregets之间的依赖路径。
每个依赖路径输出为一个组,组与组之间用新行分割。参数中两个targets的顺序不限。默认情况下,只打印一个路径。如果某个路径只包含公共依赖,则会输出最短的公共路径。否则,输出最短的公共或私有路径。如果指定了–with-data,则数据依赖也会考虑。如果有多个最短路径,则会从中选出一个。加上–all则会输出两个targets之间的所有依赖路径。
|
|
gn refs
这个命令可以用来查找反向的依赖(也就是引用了某些东西的targets)。
输入可以是如下这些:
- Target标签
- Config标签
- 标签模式
- 文件名
- 响应文件
这个命令输出依赖于参数中的输入得targets,比如:
其它一些关于gn refs命令的例子:
gn check
这个命令可以用来检查头文件依赖的有效性。其参数为:
如:
gn help
这个命令会向我们展示gn工具的帮助信息,可以用来获取关于上面所有的gn命令,及内置得targets,内建预定义变量的所有相关信息。如: