参考:
最开始,Ninja 是用于Chromium 浏览器中,Android 在SDK 7.0 中也引入了Ninja。 Ninja 其实就是一个编译系统,如同make ,使用Ninja 主要目的就是因为其编译速度快。 Ninja 除了用于Chromium browser 和Android,也用于LLVM 和依赖CMake的Ninja 后端项目。
Ninja 主要是一个注重速度的小型编译系统,主要有两个有别与其他编译系统的特点:
如果把其他的编译系统看作是“高级语言”(例如C 语言),那么Ninja 目标就是使自己成为“汇编语言”。
Ninja 包含描述任意依赖关系的最基本的功能。由于语法简单而无法表达复杂的决策。为此,Ninja 用一个单独的程序来生成input files。该程序(如autotools 项目中的./configure) 能分析系统的依赖关系,而且尽可能提前多做出策略,以便增加编译速度。
下面是Ninja 设计的目标:
其中总结出来两句话:
Makefile默认文件名为Makefile或makefile,也常用.make或.mk作为文件后缀。执行Makefile的程序,默认是 GNU make,也有一些其它的实现。在Android项目中,make需要编译主机上安装,作为环境的一部分。
Ninja 的默认文件名是build.ninja,其它文件也以.ninja为后缀。Ninja 的执行程序,就是ninja命令。而ninja 命令则是Android平台代码自带。
$ find prebuilts/ -name ninja
prebuilts/build-tools/linux-x86/asan/bin/ninja
prebuilts/build-tools/linux-x86/bin/ninja
prebuilts/build-tools/darwin-x86/bin/ninja
$ ninja -h
usage: ninja [options] [targets...]
if targets are unspecified, builds the 'default' target (see manual).
options:
--version print ninja version ("1.7.2")
-C DIR change to DIR before doing anything else
-f FILE specify input build file [default=build.ninja]
-j N run N jobs in parallel [default=6, derived from CPUs available]
-k N keep going until N jobs fail [default=1]
-l N do not start new jobs if the load average is greater than N
-n dry run (don't run commands but act like they succeeded)
-v show all command lines while building
-d MODE enable debugging (use -d list to list modes)
-t TOOL run a subtool (use -t list to list subtools)
terminates toplevel options; further flags are passed to the tool
-w FLAG adjust warnings (use -w list to list warnings)
很多参数,和make是比较类似的,比如-f、-j等,不再赘述。 有趣的是-t、-d、-w这三个参数,最有用的是-t。
$ ninja -t list
ninja subtools:
browse browse dependency graph in a web browser
clean clean built files
commands list all commands required to rebuild given targets
deps show dependencies stored in the deps log
graph output graphviz dot file for targets
query show inputs/outputs for a path
targets list targets by their rule or depth in the DAG
compdb dump JSON compilation database to stdout
recompact recompacts ninja-internal data structures
ninja -t clean是清理产物,是自带的,而make clean往往需要自己实现。 其它都是查看编译过程信息的工具,各有作用,可以进行复杂的编译依赖分析。
从Android 7开始,编译时默认使用 Ninja。 但是,Android项目里是没有 .ninja 文件的。 遵循Ninja的设计哲学,编译时,会先把Makefile通过 kati 转换成 .ninja文件,然后使用 ninja 命令进行编译。 这些 .ninja 文件,都产生在 out/ 目录下,共有三类。
通常非常大,几十到几百MB。 对 make 全编译,命名是 build-
这里 Android 有一个 bug,或者说设计失误。 mm、mma 的Ninja文件,命名是build-
这个设计本身就有一些问题了,为什么不同模块不能共用一个总的Ninja文件? 这大概还是为了兼容旧的 Makefile 设计。 在某些 Android.mk 中,单模块编译与全编译时,编译内容截然不同。 如果说这还只能算是设计失误的话,那么 mm 与 mmm 使用不同的编译文件,就是显然的 bug了。 二者相差一个下划线_,通过mv或cp,可以通用。
在使用了Soong 后,除了 build-.ninja之外,还会产生对应的 combined-.ninja,二者的*内容相同。 以下以 AOSP 的 aosp_arm64-eng 为例,展示 out/combined-aosp_arm64.ninja文件的内容。
builddir = out
include out/build-aosp_arm64.ninja
include out/soong/build.ninja
build out/combined-aosp_arm64.ninja: phony out/soong/build.ninja
这类是组合文件,是把 build-.ninja 和 out/soong/build.ninja 组合起来。 所以,使用Soong后,combined-.ninja 是编译执行的真正入口。
4.3 out/soong/build.ninja 文件 它是从所有的Android.bp 转换过来的。
build-.ninja 是从所有的 Makefile,用 Kati 转换过来的,包括 build/core/.mk 和所有的Android.mk。 所以,在不使用Soong时,它是唯一入口。 在使用了 Soong 以后,会新增源于Android.bp的 out/soong/build.ninja,所以需要 combined-*.ninja 来组合一下。
可以通过以下命令,单独产生全编译的Ninja文件。
make nothing
文件组织如下图所示:(其中的aosp_arm为
在产生全编译的Ninja文件后,可以绕过Makefile,单独使用 ninja 进行编译。
全编译(7.0版本),相当于make:
ninja -f out/build-aosp_arm64.ninja
单独编译模块,比如Settings,相当于make Settings:
ninja -f out/build-aosp_arm64.ninja Settings
在8.0以上,上面的文件应该替换为out/combined-aosp_arm64.ninja,否则可能找不到某些Target。
另外,还有办法不用输入-f参数。 如前所述,如同Makefile之于make,ninja默认的编译文件是build.ninja。 所以,使用软链接,可以避免每次输入繁琐的-f。
ln -s out/combined-aosp_arm64.ninja build.ninja
ninja Settings
用ninja进行单模块编译的好处,除了更快以外,还不用生成单模块的Ninja文件,省了四五分钟。
在以Ninja在实际编译中替换 Makefile 以后,Android在编译时更快了一些。 不过,在首次生成、或重新生成Ninja文件时,往往额外耗时数分钟,反而比原先使用Makefile更慢了。
在增量编译方面,原先由于其 Makefile 编译系统的实现问题,是不完善的。 也就是说,在make编译完一个项目后,如果再执行make,会花费较长时间重新编译部分内容。 而使用Ninja以后,增量编译做得比较完善,第二次make将在一分钟内结束。
除此之外,由于Ninja的把编译流程集中到了一个文件,并且提供了一些工具命令。 所以编译信息的提取、编译依赖的分析,变得更加方便了。
windowns10,删除微软拼音输入法: 控制面板-时钟和区域-区域-语言首选项-首选语言-“中文简体”-选项-键盘-微软拼音-删除。
# vscode terminal is being used here
PS C:\d_disk> irm get.scoop.sh -outfile 'install.ps1'
PS C:\d_disk> .\install.ps1 -RunAsAdmin
Initializing...
Downloading ...
Creating shim...
Adding ~\scoop\shims to your path.
Scoop was installed successfully!
Type 'scoop help' for instructions.
PS C:\d_disk>scoop bucket add extras
Checking repo... OK
The extras bucket was added successfully.
PS C:\d_disk> scoop install vscodium
Installing 'vscodium' (1.85.2.24019) [64bit] from extras bucket
VSCodium-win32-x64-1.85.2.24019.zip (118.6 MB) [===============================================================================================================================================] 100%
Checking hash of VSCodium-win32-x64-1.85.2.24019.zip ... ok.
Extracting VSCodium-win32-x64-1.85.2.24019.zip ... done.
Running pre_install script...
Linking ~\scoop\apps\vscodium\current => ~\scoop\apps\vscodium\1.85.2.24019
Creating shim for 'vscodium'.
Creating shortcut for VSCodium (VSCodium.exe)
Persisting data
Running post_install script...
'vscodium' (1.85.2.24019) was installed successfully!
Notes
-----
Add VSCodium as a context menu option by running 'reg import "C:\Users\MyPC\scoop\apps\vscodium\current\install-context.reg"'
For file associations, run 'reg import "C:\Users\MyPC\scoop\apps\vscodium\current\install-associations.reg"'
PS C:\d_disk>
#define ___asm(c) __asm_(c)
#define __asm_(c) __asm(#c);
#define __as1(c, d) __as1_(c, d)
#define __as1_(c, d) __asm( #c " , " #d);
#define __as2(c, d, e) __as2_(c, d, e)
#define __as2_(c, d, e) __asm( #c " , " #d " , " #e);
#define __as3(c, d, e, f) __as3_(c, d, e, f)
#define __as3_(c, d, e, f) __asm( #c " , " #d " , " #e " , " #f);
#define __as4(c, d, e, f, g) __as4_(c, d, e, f, g)
#define __as4_(c, d, e, f, g) __asm( #c " , " #d " , " #e " , " #f " , " #g);
#define __as5(c, d, e, f, g, h) __as5_(c, d, e, f, g, h)
#define __as5_(c, d, e, f, g, h) __asm( #c " , " #d " , " #e " , " #f " , " #g " , " #h);
### file:Include\ARMStartup_Platform.h
const uint32 brsTcmBase[BRS_CPU_CORE_AMOUNT][NUM_TCM_PER_CORE] = {
{
0xE4000018, /* CLUSTER0_CORE0_TCMA */
0xE4100018, /* CLUSTER0_CORE0_TCMB */
0xE4200018}, /* CLUSTER0_CORE0_TCMC */
...
}
}
/* file:ARMStartup_CortexR52.c
*/
/* EL2 Vector */
BRS_GLOBAL(EL2_VectorTable)
BRS_LABEL(EL2_VectorTable) /* Temporary Interrupt Vector Table */
___asm(B _start)
___asm(B EL2_Unhandled_Handler)
...
/* EL1 Vector */
BRS_GLOBAL(EL1_VectorTable)
BRS_LABEL(EL1_VectorTable) /* Temporary Interrupt Vector Table */
___asm(B brsStartupEntry)
___asm(B EL1_Unhandled_Handler)
...
/* EL2 Entry */
BRS_GLOBAL(_start)
...
__as1(MOV r0, #0)
__as1(MOV r1, #0)
...
__as1(LDR r0, =EL1_VectorTable) /* Set EL1 vector table */
__as5(MCR p15, #0, r0, c12, c0, #0) /* Write to VBAR */
__as1(LDR r0, =EL1_VectorTable) /* Load entry label */
__as2(ORR r0, r0, #1)
__as1(MSR ELR_hyp, r0) /* Set the link register */
___asm(DSB)
___asm(ISB)
___asm(ERET) /* Trigger EL1 level */
...
/* EL1 Entry */
BRS_SECTION_CODE(brsStartup)
...
BRS_GLOBAL(brsFirstCoreInit)
...
BRS_BRANCH(brsInitialMPUconfig)
...
#if (MPU_TCM_REGION == STD_ON)
/* Configure MPU region 12 for TCM */
__as1(LDR r0, =MPU_TCM_REGION_START)
__as1(LDR r1, =0x02) /* Non-Shareable, RW, Execute */
__as2(ORR r0, r0, r1)
__as5(MCR p15, #0, r0, c6, c14, #0) /* Write MPU base address register */
___asm(ISB)
__as1(LDR r0, =MPU_TCM_REGION_END) /* Set the limit address */
__as2(BFC r0, #0, #6) /* Align the limit address to 64 bytes */
__as1(LDR r1, =0x09) /* Attr4 of MAIR1, EN */
__as2(ORR r0, r0, r1)
__as5(MCR p15, #0, r0, c6, c14, #1) /* Write MPU limit address register */
___asm(ISB)
#endif
...
BRS_BRANCH(coreRegisterInit)
...
BRS_BRANCH(coreRegisterInit2)
/* file:ARMStartup_CortexR52.c */
/* Enable Tightly Coupled Memory */
#if (BRS_ENABLE_TCM == STD_ON)
BRS_READ_COREID(r0)
__as1(MOV r1, #NUM_TCM_PER_CORE)
__as2(MUL r1, r0, r1)
__as2(LSL r1, r1, #2)
__as1(LDR r2, =brsTcmBase)
__as1(ADD r2, r1)
__as1(LDR r1, [r2]) /* Load corresponding base address */
__as2(ORR r1, r1, #1) /* Enable TCMA */
__as5(MCR p15, #0, r1, c9, c1, #0) /* Write TCMA Region Register */
__as2(LDR r1, [r2, #4])
__as2(ORR r1, r1, #1) /* Enable TCMB */
__as5(MCR p15, #0, r1, c9, c1, #1) /* Write TCMB Region Register */
__as2(LDR r1, [r2, #8])
__as2(ORR r1, r1, #1) /* Enable TCMC */
__as5(MCR p15, #0, r1, c9, c1, #2) /* Write TCMC Region Register */
#endif /*BRS_ENABLE_TCM*/
root@5b37c152a18b:/home/tzdong/yocto_v590/build# apt-get install rsync
root@5b37c152a18b:/home/tzdong/yocto_v590/build# vim ../poky/meta/conf/sanity.conf
# INHERIT += "sanity"
root@5b37c152a18b:/home/tzdong/yocto_v590/build# git config --global --add safe.directory /home/tzdong/yocto_v590/build/downloads/git2/gitlab.freedesktop.org.pkg-config.pkg-config.git
去对应的git目录下,执行下面的命令
# git fetch --unshallow
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
# 配置git的最低速和最低速时间
dongtz@renesas-abd:~/work/linux/yocto_v590$ git config --global http.lowSpeedLimit 0
dongtz@renesas-abd:~/work/linux/yocto_v590$ git config --global http.lowSpeedTime 999999
# 可以增加git的缓存大小
dongtz@renesas-abd:~/work/linux/yocto_v590$ git config --global http.postBuffer 1048576000
# 文件太大,解决方式为git添加 compression 配置项
dongtz@renesas-abd:~/work/linux/yocto_v590$ git config --global core.compression -1
(转载)关于git拉取项目时,报RPC failed; curl 18 transfer closed with outstanding read data remaining错的解决方法
global配置对当前用户生效,如果需要对所有用户生效,则用–system
在项目地址中间加上 gitclone.com