build.ninja 识别的文件
变量
cflags = -g
使用的时候可以用$cflags或者${cflags},当然有${in}和${out}
最底层的例子
cflags = -Wall #声明变量
rule cc
command = gcc $cflags -c $in -o $out #声明规则
build foo.o: cc foo.c #声明输入输出等依赖关系,build能引用cc规则
覆盖变量的例子
cflags = -Wall -Werror
rule cc
command = gcc $cflags -c $in -o $out
build foo.o: cc foo.c #在这个build拿的是原始的cflags变量
build special.o: cc special.c #但是在这个build拿的是覆盖的cflags变量
cflags = -Wall
build bar.o: cc bar.c #在这个build拿的是原始的cflags变量
phony(假) rule是个语法糖
可以将文件分组,再用这些分组的文件做另一个build的输入
还可以用来判断构建时所需要的文件是否存在
可以引入make生成的中间文件,以便ninja使用他,例子
rule cc
depfile = $out.d
command = gcc -MD -MF $out.d [other gcc flags here]
有个pool的配置可以限制并发任务数
# No more than 4 links at a time.
pool link_pool
depth = 4
# No more than 1 heavy object at a time.
pool heavy_object_pool
depth = 1
rule link
...
pool = link_pool
rule cc
...
# The link_pool is used here. Only 4 links will run concurrently.
build foo.exe: link input.obj
# A build statement can be exempted from its rule's pool by setting an
# empty pool. This effectively puts the build statement back into the default
# pool, which has infinite depth.恢复默认数,即无限个任务数
build other.exe: link input.obj
pool =
# A build statement can specify a pool directly.
# Only one of these builds will run at a time.
build heavy_object1.obj: cc heavy_obj1.cc
pool = heavy_object_pool
build heavy_object2.obj: cc heavy_obj2.cc
pool = heavy_object_pool
还有个console pool可以跟用户交互,并且还能重定向标准输入输出和错误
当任务运行在consol pool下时其他的ninja常规输出都缓存在内存中
直到console pool中的任务完成
$a==${a}
$
$ #可以转义换行符,认为就是两个$相当于一个$
$$ #转义$
#spaced先把foo和bar以空格切割,再补上空格
#即foo空格bar这个整体==$spaced
spaced = foo bar
build $spaced/baz other$ file: ...
# The above build line has two outputs: "foo bar/baz" and "other file".
two_words_with_one_space = foo $
bar #等价于two_words_with_one_space = foo $bar
one_word_with_no_space = foo$
bar #等价于two_words_with_one_space = foo$bar
当上一行a比下一行b缩进更少时,即更靠近左边时,a称为b的父作用域
当b更靠近左边时,b关闭a的父作用域,即用自己的作用域
builddir可以指定中间文件生成的目录
#rspfile和rspfile_content是为了windows对命令行中字符个数的限制而搞出来的
#即在调用命令之前将选定的字符串(rspfile_content)写入给定文件(rspfile ),并在成功执行命令后删除该文件。
rule link
command = link.exe /OUT$out [usual link flags here] @$out.rsp
rspfile = $out.rsp
rspfile_content = $in
build myapp.exe: link a.obj b.obj [possibly many other .obj files]
command变量在unixes类系统下与windows下的处理是不一样的
在unixes系统下直接给到sh -c,即输进来的变量会被处理成
命令数组,就可以当成是在shell下运行一样
但在windows系统下,command变量代表的是字符串
内部调用了createprocess,如果想用cmd的命令,得在命令前面
加上cmd /c来启动cmd外壳,当他报错为无效参数时,通常表示超出命令行长度
build outputs有隐式输出与显示输出
ninja认为绝对路径与相对路径是不同的
这么说的话,这个路径是一张表中的字段喽
可以用include或subninja来包含另一个.ninja文件来引入变量和规则
subninja用于包含另一个.ninja文件,其表示新的边界.被包含的subninja文件可以使用父文件中的变量,
在文件边界中覆盖他们的值,但是这不影响父文件中变量的值。
同时,可以用#include语句在当前边界内,引入另一个.ninja文件。这个有点像C中的#include语句。
构建块中声明的变量的边界,就是其所属的块。一个构建块中展开的变量的所有查询次序为:
特殊内建变量($in, $out);
build/rule块中构建层的变量;
构建行所在文件中的文件层变量(File-level);
使用subninja关键字引入那个文件的(父)文件中的变量。
ninja笔记
于 2022-10-21 00:11:03 首次发布