ninja工具_构建和谐社会最核心的是

ninja工具_构建和谐社会最核心的是转自:http://guiquanz.me/2014/07/28/a_intro_to_Ninja/Ninja-chromium核心构建工具Jul28,2014[在线编辑]缘由经过上次对chr

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

转自:http://guiquanz.me/2014/07/28/a_intro_to_Ninja/

 

Ninja – chromium核心构建工具Jul 28, 2014

[在线编辑]

缘由

经过上次对chromium核心代码的初步了解之后,我转头去研究了一番ninja,并对其进行了一些改造(爱折腾的,都是小NB)。今天就来简单介绍一下ninja及其使用。(BTW: 细节的内容,大家阅读ninja 的手册就好了,我这里不会关注。)

ninja一个专注于速度的小型构建系统(Ninja is a small build system with a focus on speed)。ninja是其作者为了解决chromium代码编译慢这个问题(具体一点,就是发生在将Chrome移植到非Windows平台过程中的事情。欲知详情,请阅读Ninja, a new build system)而诞生的。其设计受到the tup build systemredo的启发。ninja核心是由C/C++编写的,同时有一部分辅助功能由pythonshell实现。

ninja可以很好的组合gypCMake一起使用,后者为其生成.ninja文件。

ninja项目的最终编译产出物是一个可执行文件ninja。

下载代码 并 编译


mkdir -p ~/ninja && cd ~/ninja
git clone https://github.com/martine/ninja
cd ninja
python ./bootstrap.py

(BTW:以上过程编译生成可执行文件ninja。需要预先安装 graphviz及其开发库,gtestgitre2cpython

测试

由于在编译ninja的过程中bootstrap.py脚本通过调用configure.pyplatform_helper.py生成了ninja项目的构建文件build.ninja,所以我们只需要执行./ninja ninja_test就可以通过ninja构建生成测试文件ninja_test。这样就可以执行测试了。


./ninja ninja_test
./ninja all

ninja 工具介绍

在介绍ninja的文法之前,还是先了解一下ninja的使用吧。执行./ninja -h显示帮助信息。具体参数说明,如下:


usage: ninja [options] [targets...]

if targets are unspecified, builds the 'default' target (see manual).

options:
  --version  # 打印版本信息(如当前版本是1.5.1)

  -C DIR   # 在执行操作之前,切换到`DIR`目录
  -f FILE  # 制定`FILE`为构建输入文件。默认文件为当前目录下的`build.ninja`。如 ./ninja -f demo.ninja

  -j N     # 并行执行 N 个作业。默认N=3(需要对应的CPU支持)。如 ./ninja -j 2 all
  -l N     # 如果平均负载大于N,不启动新的作业
  -k N     # 持续构建直到N个作业失败为止。默认N=1
  -n       # 排练(dry run)(不执行命令,视其成功执行。如 ./ninja -n -t clean)
  -v       # 显示构建中的所有命令行(这个对实际构建的命令核对非常有用)

  -d MODE  # 开启调试模式 (用 -d list 罗列所有的模式)
  -t TOOL  # 执行一个子工具(用 -t list 罗列所有子命令工具)。如 ./ninja -t query all

ninja还集成了graphviz等一些对开发非常有用的工具。具体如下:(也就是执行 ./ninja -t list 的结果)


ninja subtools:
    browse  # 在浏览器中浏览依赖关系图。(默认会在8080端口启动一个基于python的http服务)
     clean  # 清除构建生成的文件
  commands  # 罗列重新构建制定目标所需的所有命令
      deps  # 显示存储在deps日志中的依赖关系
     graph  # 为指定目标生成 graphviz dot 文件。如 ninja -t graph all |dot -Tpng -o graph.png
     query  # 显示一个路径的inputs/outputs
   targets  # 通过DAG中rule或depth罗列target
    compdb  # dump JSON兼容的数据库到标准输出
 recompact  # 重新紧凑化ninja内部数据结构

ninja文件示例

聊了半天,ninja的构建文件长什么模样呢?以下的demo就是一个执行echo,打印一行文字的ninja构建文件,和make的Makefile很类似。


rule demo
  command = echo "this is a demo of $foo"

build out: demo
  foo = bar

编写你自己的ninja文件

Ninja和Make非常相似。他执行一个文件之间的依赖图,通过检测文件修改时间,运行必要的命令来更新你的构建目标

一个构建文件(默认文件名为:build.ninja)提供一个rule(规则)表——长命令的简短名称,和运行编译器的方式一下。同时,附带提供build(构建)语句列表,表明通过rule如何构建文件——哪条规则应用于哪个输入产生哪一个输出。

从概念上讲,build语句描述项目的依赖图;而rule语句描述当给定一个图的一条边时,如何生成文件。

语法示例

这是一个用于验证绝大部分语法的.ninja文件,将作为后续描述相关的示例。具体内容,如下:


cflags = -Wall

rule cc
  command = gcc $cflags -c $in -o $out

build foo.o: cc foo.c

变量

ninja支持为字符串声明简短可读的名字。一个声明的语法,如下:


cflags = -g

可以在=右边使用,并通过$进行引用(类似shellperl的语法)。具体形式,如下:


rule cc
  command = gcc $cflags -c $in -o $out

变量还可以用${in}($和成对的大括号)来引用。

当给定变量的值不能被修改,只能覆盖(shadowed)时,变量更恰当的叫法是绑定(”bindings”)。

rule 规则

规则为命令行声明一个简短的名称。他们由关键字rule一个规则名称打头的行开始,然后紧跟着一组带缩进格式的 variable = value行组成。

以上示例中声明了一个名为cc的rule,连同一个待运行的命令。在rule(规则)上下文中,command变量用于定义待执行的命令,$in展开(expands)为输入文件列表(foo.c),而$out为命令的输出文件列表(foo.o)。参考手册中罗列了所有特殊的变量。

buid 构建语句

build语句声明输入和输出文件之间的一个关系。构建语句由关键字build开头,格式为build outputs: rulename inputs。这样的一个声明,所有的输出文件来源于(derived from)输入文件。当缺输出文件或输入文件变更时,Ninja将会运行此规则来重新生成输出。

以上的简单示例,描述了使用cc规则如何构建foo.o文件。

build block范围内(包括相关规则的执行),变量$in表示输入列表,$out表示输出列表。

一个构建语句,可以和rule一样,紧跟一组带缩进格式的key = value对。当在命令中变量执行时,这些变量将覆盖(shadow)任何变量。比如:


cflags = -Wall -Werror
rule cc
  command = gcc $cflags -c $in -o $out

# 如果没有制定,build的输出将是$cflags
build foo.o: cc foo.c

# 但是,你可以在特殊的build中覆盖cflags这样的变量
build special.o: cc special.c
  cflags = -Wall

# cflags变量仅仅覆盖了special.o的范围
# 以下的子序列build行得到的是外部的(原始的)cflags
build bar.o: cc bar.c

从代码中生成Ninja文件

Ninja发行包中的misc/ninja_syntax.py是一个很小的python模块,用于生成Ninja文件。你可以使用python,执行如ninja.rule(name='foo', command='bar', depfile='$out.d')的调用,生成合适的语法。如果这样还不错,可以将其整合到你的项目中。

更多细节

phony 规则

可以使用特殊的规则phony,创建其他target(编译构建目标)的别名。比如:


build foo: phony some/file/in/a/faraway/subdir/foo

这样使得ninja foo构建更长的路径。从语义上讲,phony规则等同于一个没有做任何操作的普通规则,但是phony规则通过特殊的方式进行处理,这样当其运行时不会被打印,记日志,也不作为构建过程中打印出来的命令计数。

还可以用phony为构建时可能还不存在的文件创建dummy目标。

default 目标语句

默认情况下,如果没有在命令行中指定target,那么Ninja将构建任何地方没有作为输入命名的每一个输出。可以通过default目标语句来重写这个行为。一个default语句,让Ninja构建一个给定的输出文件子集,如果命令行中没有指定构建目标

默认目标语句,由关键字default打头,并且采用default targets的格式。一个default目标语句必须出现在,声明这个目标作为一个输出文件的构建语句之后。他们是累积的(cumulative),所以可以使用多个default语句来扩展默认目标列表。比如:


default foo bar
default baz

Ninja构建日志

Ninja构建日志保存在构建过程的跟目录或.ninja文件中builddir变量对应的目录的.ninja_log文件中。

C/C++头文件依赖

Ninja目前支持depfiledeps模式的C/C++头文件依赖生成。 如


rule cc
  depfile = $out.d
  command = gcc -MMD -MF $out.d [other gcc flags here]

-MMD标识告诉gcc要生成头文件依赖,-MF则说明要写到哪里。

deps按照编译器的名词来管理。具体如下:(针对微软的VC:msvc)


rule cc
  deps = msvc
  command = cl /showIncludes -c $in /Fo$out

Pools

为了支持并发作业,Ninja还支持pool的机制(和用-j并行模式一样)。此处不详细描述了。具体示例,如下:


# 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
The console pool

更加详细的语法

请阅读参考手册,此处只做概要说明。

一个ninja构建文件,由一系列的声明构成。一个声明可以是一个:

  • rule声明,由rule rulename开头,然后紧跟一系列带缩进的变量定义行

  • 一个build边,其格式为build output1 output2: rulename input1 input2。隐士依赖用| dependency1 dependency2表达;Order-only依赖用行末的|| dependency1 dependency2表达。

  • 变量声明,形如variable = value

  • 默认目标语句,形如default target1 target2

  • 引入更多的文件,形如subninja pathinclude path

  • 一个pool声明,形如pool poolname

词法

Ninja仅支持ASCII字符集。

注释以为#开始一直到行末。

新行是很重要的。像build foo bar的语句,是一堆空格分割分词(token),到换行结束。一个分词中的新行空格必须进行转译。

目前只有一个转译字符,$,其具有以下行为:


$ followed by a newline

转译换行,让当前行一直扩展到下一行。


$ followed by text

这是, 变量引用。


${varname}

这是,另$varname的另一种语法。


$ followed by space

这表示一个空格。(仅在path列表中,需要用空格分割文件名)


$:

这表示一个冒号。(仅在build行中需要。此时冒号终止输出列表)


$$

这个表示,字面值的$

一个build或default语句,最先被解析,作为一个空格分割的文件名列表,然后每一个name都被展开。也就是说,变量中的一个空格将作为被展开后文件名中的一个空格。


spaced = foo bar
build $spaced/baz other$ file: ...
# The above build line has two outputs: "foo bar/baz" and "other file".

在一个name = value语句中,value前的空白都会被去掉。出现跨行时,后续行起始的空白也会被去掉。


two_words_with_one_space = foo $
    bar
one_word_with_no_space = foo$
    bar

其他的空白,仅位于行开始处的很重要。如果一行的缩进比前一行多,那么被人为是其父边界的一部分。如果缩进比前一行少,那他就关闭前一个边界

顶层变量

Ninja支持的顶层变量有builddirninja_required_version。具体说明,如下:

  • builddir: 构建的一些输出文件的存放目录。
  • ninja_required_version:指定满足构建需求的最小Ninja版本。

rule变量

一个rule块包含一个key = value的列表声明,这直接影响规则的处理。以下是一些特殊的key:

  • command (required): 待执行的命令。这个字符串($variables被展开之后),被直接传递给sh -c,不经过Ninja翻译。每一个规则只能包含一条command声明。如果有多条命令,需要使用&&符号进行链接。

  • depfile: 指向一个可选的Makefile,其中包含额外的隐式依赖。这个明确的为了支持C/C++的头文件依赖。

  • deps: (1.3版本开始支持)如果存在,必须是gcc或msvc,来指定特殊的依赖。产生的数据库保存在builddir指定目录.ninja_deps文件中。

  • msvc_deps_prefix: (1.5版本开始支持)定义必须从msvc的/showIncludes输出中去掉的字符串。仅在deps = msvc而且使用非英语的Visual Studio版本时使用。

  • description: 命令的简短描述,作为命令运行时更好的打印输出。打印整行还是对应的描述,由-v标记控制。如果一个命令执行失败,整个命令行总是在命令输出之前打印。

  • generator: 如果存在,指明这条规则是用来重复调用生成器程序。通过两种特殊的方式,处理使用生成器规则构建文件:首先,如果命令行修改了,他们不会重新构建;其次,默认不会被清除。

  • in: 空格分割的文件列表被作为一个输入传递给引用此rule的构建行,如果出现在命令中需要使用${in}(shell-quoted)。(提供$in仅仅为了图个方便,如果你需要文件列表的子集或变种,请构建一个新的变量,然后传递新的变量。)

  • in_newline: 和$in一样,只是分割符为换行而不是空格。(仅为了和$rspfile_content一起使用,解决MSVC linker使用固定大小的缓冲区处理输入,而造成的一个bug。)

  • out: 空格分割的文件列表被作为一个输出传递给引用此rule的构建行,如果出现在命令中需要使用${out}

  • restat: 如果存在,引发Ninja在命令行执行完之后,重新统计命令的输出。

  • rspfile, rspfile_content: 如果存在(两个同时),Ninja将为给定命令提供一个响应文件,比如,在调用命令之前将选定的字符串(rspfile_content)写到给定的文件(rspfile),命令执行成功之后阐述文件。

这个在Windows系统非常有用,因为此时命令行的最大长度非常受限,必须使用响应文件替代。具体使用方式,如下:


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]

构建依赖

Ninja目前支持3种类型的构建依赖。分别是:

  • 罗列在build行中的显式的依赖。他们可以作为规则中的$in变量。这是标准依赖格式。

  • depfile属性或构建语句末尾的| dep1 dep2语法获得的隐式依赖。这个和显式依赖一样,但是不能在$in中使用(不可见)。

  • 通过构建行末|| dep1 dep2语法表示的次序唯一(Order-only)依赖。他们过期的时候,输出不会被重新构建,直到他们被重建,但修改这种依赖不会引发输出重建。

变量展开

变量在路径(在build或default语句)和name = value右边被展开。

name = value语句被执行,右手边的被立即展开(根据以下的规则),从此$name扩展为被展开结果的静态字符串。永远也不会存在,你将需要使用双转译(”double-escape”)来保护一个值被第二次展开。

所有变量在解析过程,遇到的时候立即被展开,除了一个非常重要的例外:rule块中的变量仅在规则被使用的时候才被展开,而不是声明的时候。在以下的示例中,demo打印出”this is a demo of bar”而不是”this is a demo of $foo”。


rule demo
  command = echo "this is a demo of $foo"

build out: demo
  foo = bar

评估和边界

顶层(Top-level)变量声明的边界,是相关的文件。

subninja关键自,用于包含另一个.ninja文件,其表示新的边界。被包含的subninja文件可以使用父文件中的变量,在文件边界中覆盖他们的值,但是这不影响父文件中变量的值。

同时,可以用#include语句在当前边界内,引入另一个.ninja文件。这个有点像C中的#include语句。

构建块中声明的变量的边界,就是其所属的块。一个构建块中展开的变量的所有查询次序为:

  • 特殊内建变量($in, $out);
  • build/rule块中构建层的变量;
  • 构建行所在文件中的文件层变量(File-level);
  • 使用subninja关键字引入那个文件的(父)文件中的变量。

最后再看一下编译ninja的构建文件


# This file is used to build ninja itself.
# It is generated by configure.py.

ninja_required_version = 1.3

# The arguments passed to configure.py, for rerunning it.
configure_args = --platform=linux

builddir = build
cxx = g++
ar = ar
cflags = -g -Wall -Wextra -Wno-deprecated -Wno-unused-parameter -fno-rtti $
    -fno-exceptions -fvisibility=hidden -pipe $
    -Wno-missing-field-initializers '-DNINJA_PYTHON="python"' -O2 -DNDEBUG $
    -DUSE_PPOLL
ldflags = -L$builddir

rule cxx
  command = $cxx -MMD -MT $out -MF $out.d $cflags -c $in -o $out
  description = CXX $out
  depfile = $out.d
  deps = gcc

rule ar
  command = rm -f $out && $ar crs $out $in
  description = AR $out

rule link
  command = $cxx $ldflags -o $out $in $libs
  description = LINK $out

# browse_py.h is used to inline browse.py.
rule inline
  command = src/inline.sh $varname < $in > $out
  description = INLINE $out
build $builddir/browse_py.h: inline src/browse.py | src/inline.sh
  varname = kBrowsePy

build $builddir/browse.o: cxx src/browse.cc || $builddir/browse_py.h

# the depfile parser and ninja lexers are generated using re2c.
rule re2c
  command = re2c -b -i --no-generation-date -o $out $in
  description = RE2C $out
build src/depfile_parser.cc: re2c src/depfile_parser.in.cc
build src/lexer.cc: re2c src/lexer.in.cc

# Core source files all build into ninja library.
build $builddir/build.o: cxx src/build.cc
build $builddir/build_log.o: cxx src/build_log.cc
build $builddir/clean.o: cxx src/clean.cc
build $builddir/debug_flags.o: cxx src/debug_flags.cc
build $builddir/depfile_parser.o: cxx src/depfile_parser.cc
build $builddir/deps_log.o: cxx src/deps_log.cc
build $builddir/disk_interface.o: cxx src/disk_interface.cc
build $builddir/edit_distance.o: cxx src/edit_distance.cc
build $builddir/eval_env.o: cxx src/eval_env.cc
build $builddir/graph.o: cxx src/graph.cc
build $builddir/graphviz.o: cxx src/graphviz.cc
build $builddir/lexer.o: cxx src/lexer.cc
build $builddir/line_printer.o: cxx src/line_printer.cc
build $builddir/manifest_parser.o: cxx src/manifest_parser.cc
build $builddir/metrics.o: cxx src/metrics.cc
build $builddir/state.o: cxx src/state.cc
build $builddir/util.o: cxx src/util.cc
build $builddir/version.o: cxx src/version.cc
build $builddir/subprocess-posix.o: cxx src/subprocess-posix.cc
build $builddir/libninja.a: ar $builddir/browse.o $builddir/build.o $
    $builddir/build_log.o $builddir/clean.o $builddir/debug_flags.o $
    $builddir/depfile_parser.o $builddir/deps_log.o $
    $builddir/disk_interface.o $builddir/edit_distance.o $
    $builddir/eval_env.o $builddir/graph.o $builddir/graphviz.o $
    $builddir/lexer.o $builddir/line_printer.o $builddir/manifest_parser.o $
    $builddir/metrics.o $builddir/state.o $builddir/util.o $
    $builddir/version.o $builddir/subprocess-posix.o

# Main executable is library plus main() function.
build $builddir/ninja.o: cxx src/ninja.cc
build ninja: link $builddir/ninja.o | $builddir/libninja.a
  libs = -lninja

# Tests all build into ninja_test executable.
test_cflags = -g -Wall -Wextra -Wno-deprecated -Wno-unused-parameter $
    -fno-rtti -fno-exceptions -fvisibility=hidden -pipe $
    -Wno-missing-field-initializers -DNINJA_PYTHON="python" -O2 -DNDEBUG $
    -DUSE_PPOLL -DGTEST_HAS_RTTI=0
build $builddir/build_log_test.o: cxx src/build_log_test.cc
  cflags = $test_cflags
build $builddir/build_test.o: cxx src/build_test.cc
  cflags = $test_cflags
build $builddir/clean_test.o: cxx src/clean_test.cc
  cflags = $test_cflags
build $builddir/depfile_parser_test.o: cxx src/depfile_parser_test.cc
  cflags = $test_cflags
build $builddir/deps_log_test.o: cxx src/deps_log_test.cc
  cflags = $test_cflags
build $builddir/disk_interface_test.o: cxx src/disk_interface_test.cc
  cflags = $test_cflags
build $builddir/edit_distance_test.o: cxx src/edit_distance_test.cc
  cflags = $test_cflags
build $builddir/graph_test.o: cxx src/graph_test.cc
  cflags = $test_cflags
build $builddir/lexer_test.o: cxx src/lexer_test.cc
  cflags = $test_cflags
build $builddir/manifest_parser_test.o: cxx src/manifest_parser_test.cc
  cflags = $test_cflags
build $builddir/ninja_test.o: cxx src/ninja_test.cc
  cflags = $test_cflags
build $builddir/state_test.o: cxx src/state_test.cc
  cflags = $test_cflags
build $builddir/subprocess_test.o: cxx src/subprocess_test.cc
  cflags = $test_cflags
build $builddir/test.o: cxx src/test.cc
  cflags = $test_cflags
build $builddir/util_test.o: cxx src/util_test.cc
  cflags = $test_cflags
build ninja_test: link $builddir/build_log_test.o $builddir/build_test.o $
    $builddir/clean_test.o $builddir/depfile_parser_test.o $
    $builddir/deps_log_test.o $builddir/disk_interface_test.o $
    $builddir/edit_distance_test.o $builddir/graph_test.o $
    $builddir/lexer_test.o $builddir/manifest_parser_test.o $
    $builddir/ninja_test.o $builddir/state_test.o $
    $builddir/subprocess_test.o $builddir/test.o $builddir/util_test.o | $
    $builddir/libninja.a
  libs = -lninja -lgtest_main -lgtest -lpthread

# Ancillary executables.
build $builddir/build_log_perftest.o: cxx src/build_log_perftest.cc
build build_log_perftest: link $builddir/build_log_perftest.o | $
    $builddir/libninja.a
  libs = -lninja -lgtest_main -lgtest -lpthread
build $builddir/canon_perftest.o: cxx src/canon_perftest.cc
build canon_perftest: link $builddir/canon_perftest.o | $builddir/libninja.a
  libs = -lninja -lgtest_main -lgtest -lpthread
build $builddir/depfile_parser_perftest.o: cxx src/depfile_parser_perftest.cc
build depfile_parser_perftest: link $builddir/depfile_parser_perftest.o | $
    $builddir/libninja.a
  libs = -lninja -lgtest_main -lgtest -lpthread
build $builddir/hash_collision_bench.o: cxx src/hash_collision_bench.cc
build hash_collision_bench: link $builddir/hash_collision_bench.o | $
    $builddir/libninja.a
  libs = -lninja -lgtest_main -lgtest -lpthread
build $builddir/manifest_parser_perftest.o: cxx $
    src/manifest_parser_perftest.cc
build manifest_parser_perftest: link $builddir/manifest_parser_perftest.o | $
    $builddir/libninja.a
  libs = -lninja -lgtest_main -lgtest -lpthread

# Generate a graph using the "graph" tool.
rule gendot
  command = ./ninja -t graph all > $out
rule gengraph
  command = dot -Tpng $in > $out
build $builddir/graph.dot: gendot ninja build.ninja
build graph.png: gengraph $builddir/graph.dot

# Generate the manual using asciidoc.
rule asciidoc
  command = asciidoc -b docbook -d book -o $out $in
  description = ASCIIDOC $out
rule xsltproc
  command = xsltproc --nonet doc/docbook.xsl $in > $out
  description = XSLTPROC $out
build $builddir/manual.xml: asciidoc doc/manual.asciidoc
build doc/manual.html: xsltproc $builddir/manual.xml | doc/style.css
build manual: phony || doc/manual.html

# Generate Doxygen.
rule doxygen
  command = doxygen $in
  description = DOXYGEN $in
doxygen_mainpage_generator = src/gen_doxygen_mainpage.sh
rule doxygen_mainpage
  command = $doxygen_mainpage_generator $in > $out
  description = DOXYGEN_MAINPAGE $out
build $builddir/doxygen_mainpage: doxygen_mainpage README COPYING | $
    $doxygen_mainpage_generator
build doxygen: doxygen doc/doxygen.config | $builddir/doxygen_mainpage

# Regenerate build files if build script changes.
rule configure
  command = ${configure_env}python configure.py $configure_args
  generator = 1
build build.ninja: configure | configure.py misc/ninja_syntax.py

default ninja

# Packaging
rule rpmbuild
  command = misc/packaging/rpmbuild.sh
  description = Building rpms..
build rpm: rpmbuild

build all: phony ninja ninja_test build_log_perftest canon_perftest $
    depfile_parser_perftest hash_collision_bench manifest_parser_perftest

针对ninja的优化

Ninja是一块非常好的构建工具,其实也是一个特殊的编译器,其中有很多值得学习和借鉴的地方。比如,使用re2c将正则表达式编译为c代码(PHP也是用了这个工具,干了类似的事情),使用graphviz生成dot格式的依赖文件等等。当然,我不太喜欢其对python的依赖。安装了其他依赖工具和库之后,还需要安装python,否则没法编译ninja。经过分析之后,我为ninja定制了一个Makefile编译方案,同时修改了部分python文件,这样在没有python的情况下依然可以编译和使用ninja。如果需要使用ninja -t browse和构建ninja_test等测试目标,那还是需要安装python。当然,要去掉这些依赖也不是很难的事情,如果需要哪天有空我可能就将其修改了。修改后的版本一贯的放在github上,需要的自取。仅将此文作为学习ninja的一个阶段性总结。欢迎交流和反馈。

扩展阅读

祝大家玩的开心

编程之道,就在[编程之美]

编程之美

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/167278.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • STM32F103驱动无刷直流电机应用思路「建议收藏」

    STM32F103驱动无刷直流电机应用思路「建议收藏」一、STM32F103驱动无刷直流电机基本思路无刷电机控制是基于6步换相法如下图所示:二、STM32F103驱动无刷直流电机方法介绍通常我们用的方法是使用高级定时器3通道互补输出去驱动mos管,用通用定时器连接霍尔传感器去触发中断,在中断中换相,基本原理如下图所示:三、驱动代码编写/***********************************************************************Description:None*Input

  • 计算机本质「建议收藏」

    计算机本质「建议收藏」首页发现话题提问登录加入知乎为什么计算机能读懂1和0?关注问题写回答计算机计算机科学为什么计算机能读懂1和0?从小到大,我们被告知的都是,计

  • Python学习(一)-环境搭建之PyCharm专业版激活成功教程

    Python学习(一)-环境搭建之PyCharm专业版激活成功教程PyCharm专业版激活成功教程1、下载地址:https://www.jetbrains.com/pycharm/download/#section=windows2、直接运行下载好的3、选择安装路径:E:\Pycharm\PyCharm2018.2.44、根据电脑配置打钩5、Install安装,安装后不打开软件6、将C:\Windows\System32\dri…

  • QTabWidget的样式「建议收藏」

    QTabWidget的样式「建议收藏」Tab标签所在行的样式QTabWidget::tab-bar{alignment:left;top:3px;left:5px;right:5px;}设置QTabWidget的Tab标签下面窗格的样式QTabWidget#tabwidget_DevMang::pane{border-top:3pxsolidblack;border-…

  • typora文章同步(跨平台)

    typora文章同步(跨平台)typora实现备份个人博客一、图片上传PicGo有提供默认的图床,可以直接使用,但是有上传的限制,有特定要求的可以自己配置github图床。1.配置github图床利用github搭建图床2.安装PicGo下载链接windows选择exe结尾文件即可mac选择dmg为后缀的文件安装的时候一路next即可。3.在picGo中配置使用github图床4.picGo设置开启时间戳重名防止图片上传出错ps:我当时一直传输失败,修改代理,重新生成厂库,toke

  • 图片怎么存储到数据库里「建议收藏」

    我们存储图片到数据库里一般有两种方式将图片保存的路径存储到数据库(文件路径或者ftp路径)将图片以二进制数据流的形式直接写入数据库字段中(base64)FTP:FTP服务器(FileTransferProtocolServer)是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务。FTP是FileTransferProtocol(文件传输协议)。顾名思义,就是专门用来传输文件的协议。简单地说,支持FTP协议的服务器就是FTP服务器。关于图片或者文件在数据库.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号