概述

Android编译环境的初始化过程,在编译环境初始化完成后,我们就可以用m/mm/mmm/make命令编译源代码了。当然,这要求每一个模块都有一个Android.mk文件。Android.mk实际上是一个Makefile脚本,用来描述模块编译信息。Android编译系统通过整合Android.mk文件完成编译过程。

mmm命令的编译过程,需要依赖会make命令全部模块编译完成,下面使用编译mmm命令分析Android源码的编译过程,如图1所示:

蘑菇OS > Android9.0编译系统 > 01.png

通过上图可以知道mmm命令执行流程,具体可以看下,本文主要研究他的编译原理,感兴趣根据上图追下流程.

Android最初是用 Android.mk 来定义模块的, Android.mk 本质上就是 Makefile。随着 Android 工程越来越大,包含的模块越来越多,以 Makefile 组织的项目编译花费的时间越来越多。google 在 Android 7.0 开始引入了 ninja 编译系统。相对于 make 来说 ninja 在大的项目管理中速度和并行方面有突出的优势,因此 google 采用了 ninja 来取代之前使用的 make。由于 Android.mk 的数量巨大且复杂,不可能把所有的 Android.mk 改写成 ninja 的构建规则,因此 google 搞了个 kati 工具,用于将 Androd.mk 转换成 ninja 的构建规则文件 build.ninja,再使用 ninja 来进行构建工作。

Android 8.0 开始,google 引入了 Android.bp 文件来替代之前的Android.mk 文件,Android.bp 只是纯粹的配置文件,不包括分支、循环等流程控制, 本质上就是一个 json 配置文件。同时还引入 Soong 这个工具,用于将 Android.bp 转换为 ninja 的构建规则文件 build.ninja,再使用 ninja 来进行构建工作。但之前的模块全部是用 Android.mk 来定义的,google 不可能一下子把所有模块都修改成 Android.bp,只能逐步替换。无论是 Android.mk 还是 Android.bp 最后都是转化成 ninja 的构建规则,再进行编译的。Soong、Blueprint、Kati、Ninja之间的关系.

蘑菇OS > Android9.0编译系统 > 02.jpg

蘑菇OS > Android9.0编译系统 > 03.png

1.Kati构建编译系统

<1>.kati是专为Android开发的一个基于Golang和C++的工具,主要功能是把Android中的Android.mk文件转换成 Ninja文件。代码路径是build/kati,编译后的产物是ckati。Kati代码是开源的,可以把它clone下来,简单分析下它的运行原理,在Android全编译以后,可以使用ninja来编译已经生成的.ninja文件。<2>.执行编译odex编译命令

2.Blueprint和Soong构建编译系统

Soong、Blueprint

Soong类似于之前的Makefile编译系统的核心,负责提供Android.bp语义解析,并将之转换成Ninja文件。Soong还会编译生成一个androidmk命令,用于将Android.mk文件转换为Android.bp文件,不过这个转换功能仅限于没有分支、循环等流程控制的Android.mk才有效。
Blueprint是生成、解析Android.bp的工具,是Soong的一部分。Soong负责Android编译而设计的工具,而Blueprint只是解析文件格式,Soong解析内容的具体含义。Blueprint和Soong都是由Golang写的项目,从Android 7.0,prebuilts/go/目录下新增Golang所需的运行环境,在编译时使用。
因为Soong和Blueprint是Google谷歌为Android.bp特别定制的工具,所以不要摘出来单独来操作,下面是我编译时通过执行编译命令

#mmm extern/zgj/test_bp

在out目录下会生成3个以.ninja文件,进去查看下是ninja语法,通过ninja命令来编译.

build-sdm660_64-_test_bp_Android.mk-cleanspec.ninja
build-sdm660_64-_test_bp_Android.mk-cleanspec.ninja
combined-sdm660_64-_test_bp_Android.mk.ninja

具体运行可以分为4个步骤:

第一步:进入Makefile执行
#out/soong_ui --make-mode -j32 MODULES-IN-external-zgj-test_bp
第二步:如果没有build.ninja,则生成
#prebuilts/build-tools/linux-x86/bin/ckati --ninja --ninja_dir=out --ninja_suffix=-sdm660_64-_external_zgj_test_bp_Android.mk-cleanspec --regen --detect_android_echo --color_warnings --gen_all_targets --werror_find_emulator --use_find_emulator -f build/make/core/cleanbuild.mk BUILDING_WITH_NINJA=true SOONG_MAKEVARS_MK=out/soong/make_vars-sdm660_64.mk
第三步:生成目标ninja
#prebuilts/build-tools/linux-x86/bin/ckati --ninja --ninja_dir=out --ninja_suffix=-sdm660_64-_external_zgj_test_bp_Android.mk --regen --ignore_optional_include=out/%.P --detect_android_echo --color_warnings --gen_all_targets --werror_find_emulator --kati_stats -f build/make/core/main.mk --use_find_emulator BUILDING_WITH_NINJA=true SOONG_ANDROID_MK=out/soong/Android-sdm660_64.mk SOONG_MAKEVARS_MK=out/soong/make_vars-sdm660_64.mk
第四步:编译生成odex
#prebuilts/build-tools/linux-x86/bin/ninja -d keepdepfile MODULES-IN-external-zgj-test_bp -j 32 -f out/combined-sdm660_64-_external_zgj_test_bp_Android.mk.ninja -w dupbuild=errAndroid.bp
Android.bp的出现就是为了替换Android.mk文件。bp跟mk文件不同,它是纯粹的配置,没有分支、循环等流程控制,不能做算数逻辑运算。如果需要控制逻辑,那么只能通过Go语言编写。
编译android源码后,androidmk工具会生成在:out/soong/host/linux-x86/bin目录下,用于Android.mk转换成Android.bp使用,如下转换命令#androidmk Android.mk > Android.bpNinja
ninja是一个编译框架,会根据相应的ninja格式的配置文件进行编译,但是ninja文件一般不会手动修改,而是通过将Android.bp文件转换成ninja格文件来编译。

环境搭建

下载依赖包

sudo apt-get install git-core gnupg flex bison gperf build-essential
zip curl zlib1g-dev gcc-multilib g+±multilib libc6-dev-i386
lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache
libgl1-mesa-dev libxml2-utils xsltproc unzip m4 libssl-dev libswitch-perl

编译源码的时候可能需要切换jdk

sudo update-alternatives --config java
sudo update-alternatives --config javac
如果没有将jdk路径添加进系统,需要先添加。
sudo update-alternatives --install /usr/bin/java java ~/tools/java/jdk1.6.0_45/bin/java 700
sudo update-alternatives --install /usr/bin/javac javac ~/tools/java/jdk1.6.0_45/bin/javac 700
sudo update-alternatives --install /usr/bin/jar jar ~/tools/java/jdk1.6.0_45/bin/jar 700
这里的700是优先级, ~/tools/java/jdk1.6.0_45/bin是自己安装jdk的目录

配置ccache

ccache是一个编译cache系统,可以加快c/c++代码编译的速度(编译过一次之后)。
有ccache的情况下,整个android编译的时间从超过1个小时下降到约半个小时。
配置方法见android网站说明:
https://source.android.com/source/initializing.html#optimizing-a-build-environment
上述配置对kernel代码无效。kernel编译使用ccache请参考下述文章:
https://apuroth.gitbooks.io/android-study/content/20160701.html编译安卓P、Q启用ccache方法:sudo apt install ccachevim ~/.bashrcexport USE_CCACHE=1source ~/.bashrcccache -M 100G缓存数据默认保持在~/.ccache,上一行指令可以自己设置缓存的最大值

编译

    动态分区在android Q 中加入了动态分区,为了在ota的时候能够灵活创建分区和修改分区大小,将system,vendor,odm,product合并成super分区,并在super分区上预留出一定量的free space,这样就可以动态调整这些分区的大小,解决了ota的时候分区不足,以及调整分区的风险.在这里插入图片描述qssi为了配合project treble,将系统与odm相关的解耦,需要单独编译system.img和其他img。而编译systemimage的时候需要lunch qssi,而编译其他分区的时候需要lunch target.

编译

make命令来进行编译

source build/envsetup.sh编译 system.imglunch qssi-userdebugmake target-files-package编译除system.img外的其他imglunch xx-userdebugmake target-files-package

高通提供的build.sh脚本进行编译

    编译所有img,包括system和其它imgsource build/envsetup.shlunch XX-userdebug./build.sh dist -j32编译system.img,产物在qssi目录下source build/envsetup.shlunch xx-userdebug./build.sh dist qssi_only -j32编译super.imgsource build/envsetup.shlunch xx-userdebug./build.sh dist merge_only -j32编译其它img,例如vendorimage,如果不指定会编译其它所有img,产物在XX目录下source build/envsetup.shlunch xx-userdebug./build.sh vendorimage dist target_only -j32

动态分区刷机的方法

Q版本将system和vendor分区合并为super分区,无法通过adb reboot bootloader模式单独刷动态分区里面的img,例如system,vendor,product,odm,只能刷super.img和其他的
但是fastboot模式下可以单独刷动态分区里面的img推荐进入fastboot模式刷机:adb reboot fastbootfastboot getvar is-userspaceis-userspace: yesFinished. Total time: 0.002sfastboot flash vendor vendor.imgfastboot flash system system.imgfastboot flash vbmeta vbmeta.imgfastboot flash vbmeta_system vbmeta_system.imgfastbootd是用户空间的代码,因为动态的逻辑分区只能在应用空间识别fastboot刷机出现权限问题,需要将fastboot的所有者属性改成root
sudo chown root:root fastboot
sudo chmod +s fastboot

ninja快速编译

在开发过程中经常遇到make、mm时候特别慢,原因有很多地方

    全部编译的时候需要find所有Android.mk和Android.bp,耗时比较长,导致make时候电脑卡住,不能进行其它操作。每次source/lunch完成,厂商预装逻辑会动态生成一个app_config.mk,虽然内容不会变化但是会修改时间戳,导致make的时候需要重新生成ninja文件,很烦。执行真正编译前,build系统需要检查ninja文件是否需要更新?soong环境是否正常?如果不是需要进行soong_ui相关初始化,例如查找全部的Android.mk/Android.bp检查lastModifiedTime,检查microfactory/minibp/soong_ui/soong_build等是否完成,以及动态配置各种config.

ninja编译时不会重新解析mk文件,会使用上次生成的 ninja build 文件,因此比较省时间
要使用ninja 需要先用make/mm/mmm等编译过一次才行,如果更改了文件目录结构、增删文件、repo sync等操作,或者修改Makefile或Android.bp文件,还需要再重新make一次

Android N:

第一次make的时候系统会将所有的Android.mk 通过kati 转换成 out/build-mido.ninja,然后通过ninja -f out/build-mido.ninja 进行最终编译。
操作步骤:
croot
cp prebuilts/ninja/linux-x86/ninja out/host/linux-x86/bin/ #将ninja 放到export的PATH目录下
ln -sf out/build-$(device).ninja build.ninja # 因为ninja默认执行build.ninja文件,所以通过一个软链接来指定。
ninja // 编译全部,如果不进行上面的ln软链接的,可以手动指定 ninja -f out/build-$(device).ninja 也是同样效果。
ninja services // 单独编译services模块,参数一般是LOCAL_MODULE的名字

Android O和R:

第一make的时候系统会将所有Android.mk 通过kati转换成 out/build-sagit.ninja,将所有的Android.bp通过soong转换成 out/soong/build.ninja,并合并到out/combined-$(device).ninja,进行最终编译。
操作步骤:
croot
cp prebuilts/build-tools/linux-x86/bin/ninja out/host/linux-x86/bin/
cp prebuilts/build-tools/linux-x86/lib64/libjemalloc.so out/host/linux-x86/lib64/
ln -sf out/combined-$(device).ninja build.ninja
ninja // 编译全部,支持 -j 8 指定多个线程编译。
ninja services // 单独编译services模块,参数一般是LOCAL_MODULE的名字

这种快速编译最大的好处是,编译单个模块速度快,自动查找编译相关依赖,不会出现mm时提示缺少依赖的问题
Framework快速编译

    androidR之前单独编译framework和service命令为:make -j8 frameworkmake -j8 servicesandroidR命令为:make -j8 framework-minus-apexmake -j8 servicespush framework 并删除设备中oat arm arm64 目录

当前Q编译framework的时间非常久, 编译一次需要10~30分钟, 这样对于我们本地多次修改代码编译调试就效率非常低

原理:
只编译少量修改的代码文件, 单独编译到一个jar里, 运行时提前加载它, 覆盖原始的framework.jar的services.jar不支持的case: (以下类似修改需要更新framework.jar/services.jar)类继承关系发生改变如framework.jar里Canvas继承BaseCanvas, testdebug.jar里修改为Canvas继承TestCanvas, TestCanvas继承BaseCanvas,此时testdebug.jar的Canvas.java无法覆盖framework.jar的Canvas.java具体操作:整编过一次framework.jar和services.jar这个整编过程耗时挺长, 目前暂无办法跳过, 后续还需改进只编译修改的或者新加的代码将quickbuild.zip解压到源码根目录, 将修改的或者新加的代码路径填入Android.bp中base/core的代码填在testdebug.jar, base/services的代码填在testdebugservices.jar在quickbuild目录下mm快速编译出的testdebug.jar和testdebugservices.jar, push到framework目录将testdebug.jar和testdebugservices.jar放入CLASSPATH, 比framework.jar和services.jar提前加载从手机中pull出init.environ.rc (adb root; adb pull /init.environ.rc .)修改环境变量, 在framework.jar和services.jar前面分别添加自己的jar, 之后 push 到手机目录/system/etc/init/BOOTCLASSPATH的/system/framework/framework.jar前面添加/system/framework/testdebug.jarDEX2OATBOOTCLASSPATH的/system/framework/framework.jar前面添加/system/framework/testdebug.jarSYSTEMSERVERCLASSPATH的/system/framework/services.jar:前面添加/system/framework/testdebugservices.jar:

内核快速编译

全编

make showcommands -j6 bootimage > build.log
gzip -cd out/verbose.log.5.gz | grep “/bin/bash -c” | sed ‘s/[./.] //g’> build_XXX1.sh
chmod +x build_XXX1.sh
./build_XXX1.sh

1
2
3
4

适合改动较小的重复验证
Android.bp条件编译

一个基本的雏形如下:module类型 {
name:“module名字”,
srcs: [“依赖的源文件路径”]
}
注意name在整个Android编译系统必须全局唯一
如以下是一个hello world:
cc_binary {
name: “hello_world”,
src: [“main.c”],
}
cc_binary代表target是一个可执行文件,make hello_world之后在out目录就可以得到名为hello_world的可执行文件
Android.bp中各种关键字的作用,请参考 Soong 构建系统由于Android.bp是一个树形结构,不像Makefile是一套拥有完整功能的脚本语言,所以只能实现一些简单的逻辑控制,例如

cc_library {

srcs: [“generic.cpp”],
arch: {
arm: {
srcs: [“arm.cpp”],
},
x86: {
srcs: [“x86.cpp”],
},
},
}

1
2
3
4
5
6
7
8
9
10
11
12以上可以实现针对不同cpu架构走不同的逻辑,如果需要更加复杂的逻辑在bp里面就无法实现,bp的设计初衷也是如此,不过如果确实有特殊需求,可以通过编写Soong插件来实现Soong编译插件
Android.bp在被编译系统读取的时候,在关键位置会发出一些callback给编译插件,并提供用于和编译系统交互的一系列api
首先在Android.bp中添加以下内容:

bootstrap_go_package {
name: “当前模块的包名”,
pkgPath: “当前的包路径”,
deps: [
“外部依赖”
],
srcs: [
“插件源文件”,
],
pluginFor: [“soong_build”],
}

1
2
3
4
5
6
7
8
9
10
11bootstrap_go_package告诉编译系统当前模块是一个go语言的包,pluginFor: [“soong_build”]告诉编译系统中这个包用来给Soong当编译插件使用,所以当此Android.bp文件被读取时,首先会启动该插件,执行srcs指定的源文件。deps类似Android App build.gradle文件中的implementation关键字,用于指定依赖的包名,依赖可以在本地源码中,也可以在GitHub上

下一步实现srcs指定的源文件:

func init() {
android.RegisterModuleType(“hello_defaults”, on_hello_defaults)
}
func on_hello_defaults() android.Module {
module := cc.DefaultsFactory()
android.AddLoadHook(module, hello_defaults_hook)
return module
}init相当于插件的main函数,编译系统首先会回调此函数,通过调用RegisterModuleType为hello_defaults这个类型的module注册一个回调,on_hello_defaults,这个module的类型名字是最好是自定义的,防止对其他已有的module type造成影响。在回调中,注册一个hook,此hook的执行时机在module被解析之后,意思是在这个回调中,可以读写编译当前模块所需要的所有参数,以及环境变量,因此要更改编译逻辑,就在这个hook里面实现要注意的是其中 cc.DefaultsFactory 要根据模块类型的不同而不同
cc_binary –> cc.DefaultsFactory
cc_library_shared –> cc.LibrarySharedFactory()
java_library –> java.LibraryFactory()

接着再在Android.bp添加以下内容,用于触发on_hello_defaults回调:

hello_defaults {
name: “hello_defaults”,
}

func hello_defaults_hook(ctx android.LoadHookContext) {
type props struct {
Cflags []string
Clang *bool
Include_dirs []string
Shared_libs []string
Sanitize struct {
Address *bool
}
}

p := &props{}
target_variant := ctx.AConfig().Getenv("TARGET_BUILD_VARIANT")
factory_build := ctx.AConfig().Getenv("FACTORY_BUILD")if factory_build == "1" {fmt.Println(TAG + "Disable ASan:FACTORY_BUILD=" + factory_build)return
}switch target_variant {case "userdebug":fmt.Println(TAG + "Enable ASan.")p.Cflags = append(p.Cflags, "-Wno-error")p.Cflags = append(p.Cflags, "-fno-omit-frame-pointer")p.Cflags = append(p.Cflags, "-fno-sanitize-address-use-after-scope")p.Cflags = append(p.Cflags, "-O0")p.Cflags = append(p.Cflags, "-Wno-frame-larger-than=")p.Cflags = append(p.Cflags, "-DHAS_MILLET_H")p.Shared_libs = append(p.Shared_libs, "libtest")p.Include_dirs = append(p.Include_dirs, "frameworks/base/XXXX/include")p.Clang  = proptools.BoolPtr(true)p.Sanitize.Address = proptools.BoolPtr(true)ctx.AppendProperties(p)default:fmt.Println(TAG + "Disable ASan:TARGET_BUILD_VARIANT=" + target_variant)
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38如以上实现了userdebug和非userdebug编译参数的控制,基本套路就是,通过ctx提供的接口,读取环境变量,然后再通过ctx设置一个结构体到编译系统,该结构体的结构对应于Android.bp中module的结构,编译系统通过反射读取这个结构体,和Android.bp中的描述对比,如果对应的键值对不存在,则添加,存在的话,则覆盖。

到此基本工作已经完了,不过以上逻辑都只是针对hello_defaults这个模块类型,这个模块类型完全是我们自定义的,编译系统也不认识,一般模块都是cc_binary(可执行文件)和cc_library_shared(so库)这种标准类型,如何让我们的更改对这些标准类型也能够生效呢,答案是继承,Android.bp也有继承这种机制,通过default关键字即可实现
defaults是继承列表,后面列出的是module name,这些module的类型还有键值对都会被XXX这个module所继承,因此编译逻辑也统统会被继承过去。

cc_binary {
name: “XXXXX”,
defaults: […, “hello_defaults”],

}

1
2
3
4
5

所以如果lunch userdebug来编译provider的话,Android.bp最终会是如下模样:

cc_binary {
name: “XXXX”,
defaults: […, “hello_defaults”],
cflags: ["-Wno-error", “-fno-omit-frame-pointer”, “-fno-sanitize-address-use-after-scope”, “-O0”, “-Wno-frame-larger-than=”],
clang: true,
sanitize: {
address: true,
}

}

1
2
3
4
5
6
7
8
9
10

源码导入Intellij或者androidstudio

前提:已经准备好源码

下载Intellij http://www.jetbrains.com/idea/
解压下载下来的压缩包
bin目录下有idea.sh shell文件终端cd到bin目录
chmod a+x idea.sh
sudo ./idea.sh 即可打开ideIntelliJ IDEA导入源码
执行如下命令生成idegen.jar文件source build/envsetup.sh
lunch (选择机型)
mmm development/tools/idegen/ -B (似乎有些没有-B)
make idegen
(编译生成idegen.jar中,如出现“Couldn`t locate the directory”,请使用原始bash,不要使用如zsh等)
执行idegen.sh脚本
sudo development/tools/idegen/idegen.sh
这条命令执行完成后就在Android源码的根目录中生成了android.iml, android.ipr和android.iws三个文件。如果想加快此步骤的过程,可修改development/tools/idegen /exclude-paths文件,在文件最后面逐行添加 ^ external,^ vendor,^.*.jar$,可加快执行速度,避免遍历不需要的文 件。最后用IDEA打开android.ipr文件即可注:这一步可能会出现FileNotFoundException异常(问题只在会生成res.java文件夹的版本中出现,5.0.1及以上),出现异常 的原因是:idegen.jar包里的Configuration.java文件的代码不够严谨。在第150行代码里没有判断文件是否为目录,而 Configuration.java的代码要扫描的文件/目录里,res.java是一个目录而不是java文件,导致异常。故解决办法有以下两种:在执行这一步前将res.java改名为res.j在 Configuration.java文件中的150行,在String path = …这行代码后面加入if(path.endsWith(".java") && !file.isDirectory()),并将后面所有的文件操作代码(if-else if-else if语句)放到判断语句内,如下:for(File file : files){String path = file.getPath().substring(2);if(path.endsWith(".java") && !file.isDirectory()){//之前的if-else if-else if语句都放到这里面执行}}另外,出现了 File name too long的异常,由于遍历到 一个路径过长的文件导致。把这里的jar全删了
在这里插入图片描述
在这里插入图片描述

Android Q 问题汇总

    问题:vendor/qcom/proprietary/chi-cdk/core/chiframework/build/android/Android.mk:51: error: vendor/qcom/proprietary/chi-cdk/core/chiframework/g_pipelines.h was not generated.17:09:46 ckati failed with: exit status 1解决:通过apt-cache search XML::Simple查找,然后选择一个sudo apt-get install libxml-simple-perl 或者apt install libswitch-perl问题:FAILED: out/soong/.intermediates/system/tools/hidl/libhidl-gen-ast/linux_glibc_x86_64_shared/gen/lex/system/tools/hidl/hidl-gen_l.cppprebuilts/misc/linux-x86/flex/flex-2.5.39 -oout/soong/.intermediates/system/tools/hidl/libhidl-gen-ast/linux_glibc_x86_64_shared/gen/lex/system/tools/hidl/hidl-gen_l.cpp system/tools/hidl/hidl-gen_l.llflex-2.5.39: fatal internal error, exec of /usr/bin/m4 failed[ 1% 2/120] //system/tools/hidl:libhidl-gen-ast yacc hidl-gen_y.yy [linux_glibc]FAILED: out/soong/.intermediates/system/tools/hidl/libhidl-gen-ast/linux_glibc_x86_64_shared/gen/yacc/system/tools/hidl/hidl-gen_y.cpp out/soong/.intermediates/system/tools/hidl/libhidl-gen-ast/linux_glibc_x86_64_shared/gen/yacc/system/tools/hidl/hidl-gen_y.hBISON_PKGDATADIR=prebuilts/build-tools/common/bison prebuilts/build-tools/linux-x86/bin/bison -d --defines=out/soong/.intermediates/system/tools/hidl/libhidl-gen-ast/linux_glibc_x86_64_shared/gen/yacc/system/tools/hidl/hidl-gen_y.h -o out/soong/.intermediates/system/tools/hidl/libhidl-gen-ast/linux_glibc_x86_64_shared/gen/yacc/system/tools/hidl/hidl-gen_y.cpp system/tools/hidl/hidl-gen_y.yy[ 8% 10/120] //system/tools/hidl:libhidl-gen-hash clang++ Hash.cpp [linux_glibc]ninja: build stopped: subcommand failed.15:26:38 ninja failed with: exit status 1#### failed to build some targets (11:05 (mm:ss)) ######## hidl-gen compilation failed, check above errors ####解决方法:sudo apt-get install bison问题:Error: Not enough room on system (total: 903007 blocks, used: 919414 blocks)e2fsdroid: Could not allocate block in ext2 filesystem while populating file system__populate_fs: Could not allocate block in ext2 filesystem while writing file “vendor.qti.hardware.sensorscalibrate@1.0.so”解决:从提示的错误来看,应该是编译设置中分配给systemimage的镜像太小的问题找到设置的文件:device/XXX/XXX_common/BoardConfig.mk修改BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3221225472为BOARD_SYSTEMIMAGE_PARTITION_SIZE := 5221225472问题:soong bootstrap failed with: exit status 1Killed解决:莫名的出现killed错误,可能时内存不足引起的,可以用free -h查看设置swap分区创建swap文件sudo fallocate -l 3G /swapfile只有root用户启用了读写标志sudo chmod 600 /swapfilels -lh /swapfile激活swap将文件标记为交换空间sudo mkswap /swapfile启用该交换文件sudo swapon /swapfile验证交换空间是否可用free -h永久保留交换文件备份/etc/fstab文件sudo cp /etc/fstab /etc/fstab.bak将swap文件信息添加到/etc/fstab文件的末尾echo ‘/swapfile none swap sw 0 0’ | sudo tee -a /etc/fstab卸载swapoff /swapfile卸载后可以删除这个文件,然后重新根据你新的需要创建和调整交换文件大小adb devices权限问题#lsusbBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hubBus 001 Device 048: ID 05c6:90db Qualcomm, Inc.Bus 001 Device 004: ID 0bda:8153 Realtek Semiconductor Corp.Bus 001 Device 002: ID 2717:5005显示为: Bus 001 Device 007: ID 05c6:9091 Qualcomm, Inc.等很多行那么这一个供应商ID即为Qualcomm(高通),然后查找上面官方文档中给出的表格,找到对应ID,Qualcomm为05c6.sudo vim /etc/udev/rules.d/51-android.rules添加SUBSYSTEM==“usb”, ATTR{idVendor}==“05c6”, MODE=“0666”, GROUP=“plugdev”例子中的供应商id 05c6 即为高通, 其他的不要改,最后的plugdev可以不修改.sudo service udev restart然后重插一次设备即可解决问题.如果还不行,执行下面命令adb kill-serveradb devices这里有可能adb有权限了,但是fastboot没权限,需要重新执行下lsusb,会看到一个google的设备,也添加下,重新执行即可问题:FAILED: out/target/product/grus/obj/PACKAGING/vndk_intermediates/check-list-timestamp/bin/bash -c “(( diff --old-line-format=“Removed %L” --new-line-format=“Added %L” --unchanged-line-format=”" build/make/target/product/gsi/29.txt out/target/product/grus/obj/PACKAGING/vndk_intermediates/libs.txt || ( echo -e " error: VNDK library list has been changed.\n" " Changing the VNDK library list is not allowed in API locked branches."; exit 1 )) ) && (mkdir -p out/target/product/grus/obj/PACKAGING/vndk_intermediates/ ) && (touch out/target/product/grus/obj/PACKAGING/vndk_intermediates/check-list-timestamp )"Added VNDK-core: libxlog.soerror: VNDK library list has been changed.Changing the VNDK library list is not allowed in API locked branches.10:06:46 ninja failed with: exit status 1解决:删除out/target/product/product_name/obj/PACKAGING/vndk_intermediates/libs.txt或者make target-files-package问题:device/xxx/sm7250_common/AndroidBoard.mk: error: cameratest: LOCAL_MODULE_TAGS := eng is obsolete. See https://android.googlesource.com/platform/build/+/master/Changes.md#LOCAL_MODULE_TAGSbuild/make/core/base_rules.mk:171: error: done.device/qcom/qssi/AndroidBoard.mk: error: iwconfig: LOCAL_MODULE_TAGS := eng is obsolete. See https://android.googlesource.com/platform/build/+/master/Changes.md#LOCAL_MODULE_TAGSbuild/make/core/base_rules.mk:171: error: done.解决方法:高通原生代码编译参数问题高通默认不持支lunch product-eng模式编译,需要自己配置,配置方式在device/***/sm×/Boardconfig.mk和device/qcom/qssi/Boardconfig.mk文件中添加BUILD_BROKEN_ENG_DEBUG_TAGS := true问题:更新frameworks/base下接口文件FAILED: out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/check_current_api.timestampAborting: Found compatibility problems checking the public API against the API inframeworks/base/api/current.txt解决方法:make api-stubs-docs-update-current-api问题:5:26:46 Waiting up to 1s to lock out/.lock to ensure no other Soong process is running in the same output directory15:26:47 Tried to lock out/.lock, but timed out polling every 1s until 10s . Make sure no other Soong process is using itfailed to build some targets (11 seconds) ####hidl-gen compilation failed, check above errors ####解决方法:删除 out 目录重新编译问题:see build/core/apicheck_msg_current.txt******************************You have tried to change the API from what has been previously approved.To make these errors go away, you have two choices:You can add “@hide” javadoc comments to the methods, etc. listed in the errors above.You can update current.txt -classpath <class search path of directories and zip/jar files>by executing the following command: make update-apiTo submit the revised current.txt to the main Android repository, you will need approval.******************************或者.Aborting: Found compatibility problems checking the public API against the API in > /home/xxxxxxx/frameworks/base/api/current.txt-e******************************You have tried to change the API from what has been previously approved.To make these errors go away, you have two choices:You can add ‘@hide’ javadoc comments to the methods, etc. listed in the errors above.You can update current.txt by executing the following command:make api-stubs-docs-update-current-apiTo submit the revised current.txt to the main Android repository,you will need approval.******************************解决方法:执行make update-api或者make api-stubs-docs-update-current-api问题:Internal fault: [0x87ecef: 5010094]Push codeplease contact your supplier. To submit the revised current.txt to the main Android repository, you will need approval.Segmentation fault(core dumped)解决方法:ARM编译服务器连接问题,安装apt-get install lib32stdc++6和apt-get install libc6:i386问题:2019-1018 ninja: build stopped: subcommand failed.ninja: build stopped: subcommand failed.12:15:17 ninja failed with: exit status 1解决方法:如果编译error信息非常少,尝试如下操作查看自己环境配置/etc/profile或者~/.bashrc 是否添加了环境变量引起的repo syncmake clean重编问题:FAILED: setup-jack-server[ 0% 681/71777] Ensuring Jack server is installed and startedFAILED: setup-jack-server/bin/bash -c “(prebuilts/sdk/tools/jack-admin install-server prebuilts/sdk/tools/jack-launcher.jar prebuilts/sdk/tools/jack-server-4.11.ALPHA.jar 2>&1 || (exit 0) ) && (JACK_SERVER_VM_ARGUMENTS=”-Dfile.encoding=UTF-8 -XX:+TieredCompilation" prebuilts/sdk/tools/jack-admin start-server 2>&1 || exit 0 ) && (prebuilts/sdk/tools/jack-admin update server prebuilts/sdk/tools/jack-server-4.11.ALPHA.jar 4.11.ALPHA 2>&1 || exit 0 ) && (prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-4.32.CANDIDATE.jar 4.32.CANDIDATE || exit 47 )"Jack server already installed in “/home/xxx/.jack-server”Communication error with Jack server (28), try ‘jack-diagnose’ or see Jack server logCommunication error with Jack server 28. Try ‘jack-diagnose’SSL error when connecting to the Jack server. Try ‘jack-diagnose’解决方法:1、jack-admin kill-server2、jack-admin uninstall-server问题:FAILED: out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes.jack/bin/bash out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes.jack.rspOut of memory error (version 1.3-rc6 ‘Douarn’ (441800 22a11d4b264ae70e366aed3025ef47362d1522bb by android-jack-team@google.com)).GC overhead limit exceeded.Try increasing heap size with java option ‘-Xmx’.Warning: This may have produced partial or corrupted output.解决方法:在项目的目录下输入export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4g"./prebuilts/sdk/tools/jack-admin kill-server./prebuilts/sdk/tools/jack-admin start-server问题:[1/1] out/soong/.minibootstrap/minibp out/soong/.bootstrap/build.ninja[1/1] out/soong/.bootstrap/bin/soong_build out/soong/build.ninjaFAILED: out/soong/build.ninjaout/soong/.bootstrap/bin/soong_build -t -l out/.module_paths/Android.bp.list -b out/soong -n out -d out/soong/build.ninja.d -o out/soong/build.ninja Android.bpClang SA is not enabledfatal error: runtime: out of memory解决方法:sudo apt-get autoclean,清理缓存,或者重启电脑,都可以解决该问题问题:fatal error: openssl/bio.h: No such file or directoryfatal error: openssl/opensslv.h:ninja: build stopped: subcommand failed.ninja failed with: exit status 1解决方法:sudo apt install libssl-dev问题磁盘空间不够,挂载外置硬盘解决方法:查看硬盘状况: sudo fdisk -lDisk /dev/sda:3.7 TiB,4000787030016 字节,7814037168 个扇区使用fdisk命令分区:sudo fdisk /dev/sda或者格式化分区:sudo mkfs -t ext4 /dev/sda创建挂载点: mkdir ~/source挂载: sudo mount /dev/sda ~/sourcedf查看挂载是否成功/dev/sda 3844641608 1989306820 1659967476 55% /home/zzh/source自动挂载:备份: sudo cp /etc/fstab /etc/fstab.bak添加:sudo vim /etc/fstab/dev/sda /home/zzh/source ext4 defaults 0 0sudo mount -a 如果没有报错就证明配制好了。

动态分区

编译包中,我们找不到了对应的system,vendor等img文件,但是多了一个super.img,system,vendor,product,ODM合并为super分区,这个就是动态分区了。
简单来说就是为了在ota的时候能够灵活创建分区和修改分区大小,将system,vendor,odm,product合并成super分区,并在super分区上预留出一定量的free space,这样就可以动态调整这些分区的大小,解决了ota的时候分区不足,以及调整分区的风险.

在这里插入图片描述

在这里插入图片描述
当ota升级之后,需要重新调整分区大小:
在这里插入图片描述
为了配合project treble,将系统与odm相关的解耦,需要单独编译system.img和其他img。而编译systemimage的时候需要lunch qssi,而编译其他分区的时候需要lunch target.

AndroidP/Q/R编译系统相关推荐

  1. Android高版本P/Q/R源码编译指南

           Android高版本P/Q/R源码编译指南 Android源码编译系列博客: Android.bp你真的了解吗 Android.bp入门指南之Android.mk转换成Android.b ...

  2. 卡尔曼滤波器中的Q,R

    01提问   卓老师,我想问一个关于卡尔曼滤波的问题,希望您能解答一下.之前我用的互补滤波效果也还好,但在用卡尔曼滤波的时候出现了一些问题:就是如何整定卡尔曼滤波的Q.R这两个参数,这两个参数分别是角 ...

  3. 使用PORT对HOSTNAME执行DICOM Q / R操作的测试程序

    GDCM:使用PORT对HOSTNAME执行DICOM Q / R操作 GDCM:使用PORT对HOSTNAME执行DICOM Q / R操作 GDCM:使用PORT对HOSTNAME执行DICOM ...

  4. python求主析取范式_求公式q→(r∧p)的析取范式。

    [单选题]三相异步电动机的起动时,在定子绕组串接电阻可以_____定子绕组的电压. [填空题]混浊果蔬汁是有果胶.蛋白质等亲水胶体组成的 系统. [单选题]学前儿童身心保健教育活动的组织形式不包括: ...

  5. 如果令 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 分别等于

    如果令 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 分别等于 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

  6. 求订货点和订货量的matlab,基于零售商(Q,R)补货的双渠道供应链库存策略

    一.引言随着电子商务的出现和第三方物流的快速发展,越来越多的品牌供应商开始借助于网络建立直销渠道,如IBM.HP.Nike.Dell等.供应商利用传统零售渠道和直销渠道销售产品,顾客可以任意选择自己所 ...

  7. 离散数学中输出律的证明:(P∧Q→R)恒等于(P→(Q→R))

    证明(P∧Q→R)恒等于(P→(Q→R)): 因为: 蕴含式 A->B 的一条性质是:当且仅当 A 真 B 假时,(A->B) 为假 ①:所以: (P∧Q→R)可以表述为:当且仅当 (P∧ ...

  8. 设P,Q,R是等轴双曲线上的任意三点,求证,三角形PQR的垂心H必在同一等轴双曲线上. | 解析几何 吕林根 课后习题

    解题关键 我们常见的双曲线的函数表达式为: x2a2−y2b2=1\frac{x^2}{a^2}-\frac{y^2}{b^2}=1a2x2​−b2y2​=1 等轴双曲线 a=ba=ba=b,所以函数 ...

  9. 数学集合:N Z Q R C

    整数:   Zahlen(德) 复数:  Complex number 实数:  Real number 自然数: Natural number 有理数: Quotient(德,"商&quo ...

最新文章

  1. asp提供在线文章翻译的功能(转)
  2. Java服务端人脸识别实战开发优化
  3. textfile 属性
  4. iOS 关于.tbd与.dylib用法
  5. pandas所占内存释放
  6. [每日一题jQuery] jQuery选择器总结:进一步过滤、同级操作、后代操作
  7. 你还记得20年前的语文课本吗?
  8. 【电子签章】HTML格式合同转化成PDF文件 已下载
  9. java 返回页面_spring-mvc返回视图jsp页面及重定向
  10. android post数据到php服务器,通过post方法将数据上传到服务器Android Studio
  11. Unity3D常用API
  12. 计算机形导论形考作业答案,计算机导论形考
  13. 系统查看PSD缩略图
  14. 超图android离线瓦片,android端实践openlayers离线地图
  15. 蓝桥杯2021年第十二届省赛-双向排序
  16. excel文档文件加密的方法步骤
  17. hadoop3访问hdfs web控制页面遇到的各种问题总结
  18. OpenGL学习脚印:伽马校正(Gamma Correction)
  19. 图像拼接(十):OPenCV stitching和stitching_detailed
  20. SCYC55830 58063282A可控硅触发电路

热门文章

  1. mt5_MetaTrader5_模块下载备忘。
  2. ARM Linux RTC 时间的读取与设置
  3. 2021年化工自动化控制仪表新版试题及化工自动化控制仪表模拟考试
  4. frappe-charts图表插件
  5. APS车间排产软件在汽配行业的应用
  6. 四大组件之ContentProvider(二)-轻轻松松自定义ContentProvider
  7. 势能回馈系统超级电容储能系统介绍
  8. 超越 Xshell!号称下一代终端神器,用完爱不释手!
  9. 基于Python编程和fluent仿真实现的二维非稳态热传导
  10. 我祖上三代都是以打鸟为生的