Platform: rk3399
OS: Android 7.1
Kernel: v4.4.83
Android7.0以后开始使用Ninja替代GNU make编译系统。
Ninja:
用于提高编译速度的编译系统。
可执行文件位于 prebuilts/ninja/linux-x86/ninja
Kati:
用于把Makefiel转成成ninja file,自身没有编译能力,转换后使用Ninja编译。
源代码位于: build/kati
可执行文件会被生成到: out/host/linux-x86/bin/ckati
使用方法可参考 README.md
Soong:
用于把blueprint文件(Android.bp)生成ninja文件,然后用ninja编译,目前rk3399没用到此功能。
Soong是长期的一个计划,用来替换系统中所有的Android.mk。
因此,Kati更像是Google过渡使用的一个工具,等所有Android.mk都被替换成Android.bp之后,相信Soong工具会被打开使用来替换Kati.
由于目前android系统没有全部切换到ninja编译,因此编译入口还是和之前的方法一样,使用make命令。
source build/envsetup.sh
lunch
make -j8
按照kati readme要求,使用ninja必须要定义USE_NINJA为true, android中虽然默认没有定义USE_NINJA, 但会定义relaunch_with_ninja为true,这样就会包含build/core/ninja.mk,从而使用ninja编译。
main.mk:
relaunch_with_ninja :=
ifneq ($(USE_NINJA),false)
ifndef BUILDING_WITH_NINJA
relaunch_with_ninja := true
endif
endif
ifeq ($(relaunch_with_ninja),true)
# Mark this is a ninja build.
$(shell mkdir -p $(OUT_DIR) && touch $(OUT_DIR)/ninja_build)
include build/core/ninja.mk
else # !relaunch_with_ninja
......
endif
kati的路径定义在ninja.mk中
KATI ?= $(HOST_OUT_EXECUTABLES)/ckati
HOST_OUT_EXECUTABLES即为out/host/linux-x86/bin
生成ckati的规则是在build/kati/Makefile.ckati中:
$(KATI_BIN_PATH)/ckati: $(KATI_CXX_OBJS) $(KATI_CXX_GENERATED_OBJS)
@mkdir -p $(dir $@)
$(KATI_LD) -std=c++11 $(KATI_CXXFLAGS) -o $@ $^ $(KATI_LIBS)
ninja.mk包含此文件并且替换kati源码中的变量KATI_BIN_PATH来定制生成的ckati路径
KATI_INTERMEDIATES_PATH := $(HOST_OUT_INTERMEDIATES)/EXECUTABLES/ckati_intermediates
KATI_BIN_PATH := $(HOST_OUT_EXECUTABLES)
include build/kati/Makefile.ckati
有了kati之后,就可以来创建ninja文件了
$(KATI_BUILD_NINJA): $(KATI) $(MAKEPARALLEL) $(DUMMY_OUT_MKS) $(SOONG_ANDROID_MK) FORCE
@echo Running kati to generate build$(KATI_NINJA_SUFFIX).ninja...
#kati生成配置的命令行
+$(hide) $(KATI_MAKEPARALLEL) $(KATI) --ninja --ninja_dir=$(OUT_DIR) --ninja_suffix=$(KATI_NINJA_SUFFIX) --regen --ignore_dirty=$(OUT_DIR)/% --no_ignore_dirty=$(SOONG_ANDROID_MK) --ignore_optional_include=$(OUT_DIR)/%.P --detect_android_echo $(KATI_FIND_EMULATOR) -f build/core/main.mk $(KATI_GOALS) --gen_all_targets BUILDING_WITH_NINJA=true SOONG_ANDROID_MK=$(SOONG_ANDROID_MK)
KATI_BUILD_NINJA的值:
KATI_BUILD_NINJA := $(OUT_DIR)/build$(KATI_NINJA_SUFFIX).ninja
KATI_NINJA_SUFFIX值:
KATI_NINJA_SUFFIX := -$(TARGET_PRODUCT)
在build android的时候,就可以看到Log:
Running kati to generate build-rk3399_firefly_edp_box.ninja...
/home/kris/firefly_rk3399/out/host/linux-x86/bin/ckati was modified, regenerating...
.PHONY: ninja_wrapper
ninja_wrapper: $(COMBINED_BUILD_NINJA) $(MAKEPARALLEL)
@echo Starting build with ninja
+$(hide) export NINJA_STATUS="$(NINJA_STATUS)" && source $(KATI_ENV_SH) && $(NINJA_MAKEPARALLEL) $(NINJA) $(NINJA_GOALS) -C $(TOP) -f $(COMBINED_BUILD_NINJA) $(NINJA_ARGS)
make的时候如下命令会调用到ninja_wrapper
$(sort $(DEFAULT_GOAL) $(ANDROID_GOALS)) : ninja_wrapper
@#empty
Android now builds with ninja
使用 Soong 来进行 Android 模块的构建
soong
Android7.0 Ninja编译原理
Ninja
Android中的Ninja简介
Android中的Kati