使用Ubuntu22.04编译android8.1.0_r1,结果碰到一大堆的问题,这里记录一下。另外奉劝各位尽量用Linux去编译,也尽量在物理机上安装Linux,不要用虚拟机,不要在ntfs格式的磁盘下编译,容易出现aux这种非法字符的错误。用虚拟机容易出现一大堆的话莫名其妙的错误,浪费时间、浪费生命
Ubuntu22.04下flex2.5.39报错
类似如下
/bin/bash -c
"prebuilts/misc/linux-x86/flex/flex-2.5.39 -oout/target/product/gecko_8/obj/STATIC_LIBRARIES/libedify_intermediates/lexer.cpp bootable/recovery/edify/lexer.ll"flex-2.5.39: loadlocale.c:130:_nl_intern_locale_data: ?? 'cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' ???
Aborted (core dumped)
网上大多数的方式都是export LC_ALL=C去处理,实测在Ubuntu22.04下无效,而且如果执行了这条命令还会导致Ubuntu22.04~目录下中文变成乱码,并且如果源码你是放在桌面上的话,由于中文变成了乱码会导致编译的时候找不到一些文件。所以千万别乱加。
正确的处理方式是自己去编译一下源码目录下的flex,flex的目录在源码目录/prebuilts/misc/linux-x86/flex内,以下是编译方法
AOPS源码根目录/prebuilts/misc/linux-x86/flex$
ll //你可能会看到:flex-2.5.39(可执行文件)、flex-2.5.39.tar.gz(flex压缩包)
AOPS源码根目录/prebuilts/misc/linux-x86/flex$
mkdir flex-2.5.39.source
AOPS源码根目录/prebuilts/misc/linux-x86/flex$
tar -zxvf flex-2.5.39.tar.gz -C flex-2.5.39.source/
AOPS源码根目录/prebuilts/misc/linux-x86/flex$
cd flex-2.5.39.source
AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source$
mkdir install
AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source$
cd flex-2.5.39
安装到刚才创建的install目录,绝对地址:
AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source/flex-2.5.39$
./configure --prefix=/home/you/AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source/install/
AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source/flex-2.5.39$
make
AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source/flex-2.5.39$
make install
AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source/flex-2.5.39$
cd ../install
AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source/flex-2.5.39/install$
ls
## 删除原来的flex2.5.39这个文件,然后用install/bin文件里面的flex去替代这个flex2.5.39
AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source/flex-2.5.39/install$
rm -rf AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39
## 这里使用快捷方式去替代
AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39.source/flex-2.5.39/install$
ln -s ./bin/flex AOPS源码根目录/prebuilts/misc/linux-x86/flex/flex-2.5.39
.py文件报错
SyntaxError: invalid syntax
一般出现.py文件报错,基本上都是python版本不对导致的,处理方式就是找到合适的python版本,android8.1.0_r1的合适版本是python2。这里比较坑的是,repo同步android源代码的时候要求使用python3但是编译android8.1的时候又要用python2,所以很容易没有注意到就出错了。所以这里记录一下
jack-admin相关错误
编译到80%的时候以为应该一切都比较顺利了,结果到85%的时候突然出现这么一个错误:
[85% 1/1] Ensure Jack server is installed and started
FAILED: /bin/bash -c "(prebuilts/sdk/tools/jack-admin install-server prebuilts/sdk/tools/jack-launcher.jar prebuilts/sdk/tools/jack-server-4.8.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.8.ALPHA.jar 4.8.ALPHA 2>&1 || exit 0 ) && (prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-2.28.RELEASE.jar 2.28.RELEASE || exit 47; prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-3.36.CANDIDATE.jar 3.36.CANDIDATE || exit 47; prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-4.7.BETA.jar 4.7.BETA || exit 47 )"
Jack server already installed in "/home/songzhihao/.jack-server"
Communication error with Jack server (56), try 'jack-diagnose' or see Jack server log
Failed to contact Jack server: Problem reading /home/songzhihao/.jack-server/server.pem. Try 'jack-diagnose'
Failed to contact Jack server: Problem reading /home/songzhihao/.jack-server/server.pem. Try 'jack-diagnose'
ninja: build stopped: subcommand failed.
build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed
make: *** [ninja_wrapper] Error 1
真的很无语,所以不到100%你都不知道还能踩到什么坑。
这个基本上就是端口占用了,其实也不一定非要去改~/.jack-setting的端口号,可以先cat看看这个文件里面的两个端口号:SERVER_PORT_SERVICE、SERVER_PORT_ADMIN
然后用命令
netstat -ap |grep "端口号"
看看是否有占用的情况,如果有的话就kill掉
kill -9 "pid"
当然,我这里为了保险起见,因为85%再出错太耗时了,所以直接把端口号改了,这里改端口号需要改两个地方
一个是~/.jack-setting文件,另外一个是~/.jack-server/config.properties文件
jack-setting文件内容如下
# Server settings
SERVER_HOST=localhost
SERVER_PORT_SERVICE="端口号"
SERVER_PORT_ADMIN="端口号"
# Internal, do not touch
SETTING_VERSION=4
jack-server/config.properties的内容如下:
#
#Thu Sep 21 13:34:49 CST 2023
jack.server.idle=180
jack.server.max-service.by-mem=1\=2147483648\:2\=3221225472\:3\=4294967296
jack.server.shutdown=21600
jack.server.time-out=7200
jack.server.max-jars-size=104857600
jack.server.service.port="端口号"
jack.server.admin.port="端口号"
jack.server.config.version=4
jack.server.max-service=4
jack.server.deep-idle=900
如果在~/.jack-server目录下没有config.properties文件的话,就新建一个
其中要注意的是config.properties和jack-setting中:
service.port对应SERVER_PORT_SERVICE
admin.port对应SERVER_PORT_ADMIN
不能搞乱了,不然的话可能互相连接不上,尽量往大点、不常用的设,避免端口被占用
Dex2oat错误
ERROR: Dex2oat failed to compile a boot image.It is likely that the boot classpath is inconsistent.Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.
默认情况下,编译的时候会开启dex优化,这个鬼东西很容易出错,如果遇到以上错误就是Dex优化相关的错误
解决办法
方法一:
#编译前先设置一下关闭dex优化设置
export WITH_DEXPREOPT=false
方法二:
#make的时候带上参数
make WITH_DEXPREOPT=false
方法三:
打开源码根目录下的Makefile文件我们可以看到make实际上执行了build/core/main.mk文件
OK,那我们就打开build/core/main.mk,然后在里面加入这么一行
WITH_DEXPREOPT := false
这样再全局上关闭了DEX优化,我是比较推荐这种,不然每次编译的时候都要记得加参数啥的,贼麻烦。没办法,懒人一个~
内存相关
FAILED: /bin/bash out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/with-local/classes.dex.rsp
Out of memory error (version 1.2-rc4 ‘Carnac’ (298900 f95d7bdecfceb327f9d201a1348397ed8a843843 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.
[ 32% 12025/36462] build out/target/common/obj/JAVA_LIBRARIES/sdk_v20_intermediates/classes.jack
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] Error 1
如果遇到了类似于上面的错误,关键字“-Xmx”基本上代表着java的内存溢出,反正就是内存不够用了,这种情况的话网上大多数都是会叫你增加swap然后改./prebuilts/sdk/tools/jack-admin里面JACK_SERVER_COMMAND的值,在$JACK_SERVER_VM_ARGUMENTS之前加-Xmx(内存大小)G的
JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR -Xmx2g $JACK_SERVER_VM_ARGUMENTS -cp $LAUNCHER_JAR $LAUNCHER_NAME"
但笔者发现这样增大内存的话还是会出现java内存溢出的错误,并且观察内存发现swap虽然配置了,但是根本就没用上。所以不能解决我的问题,选择用实体机去编译也是因为当时没法解决这个问题。
后来有空之后查了一下,还是找到了解决办法,如下:
#控制台编辑bashrc
vim ~/.bashrc
#在文件末尾加入下面一句
#其中-Xmx代表最大可使用内存 -Xms代表最小可使用内存
#各位根据自己的内存情况来决定
export _JAVA_OPTION="-Xmx6G -Xms4G"
#写完之后记得:wq保存一下
#然后别忘了让环境变量生效
source ~/.bashrc
之后再make一下,用htop观察内存
可以看到现在编译就能很好的用上swap内存了。也就没再出现过内存溢出的问题了
最后附上一张编译成功的图
没办法,渣电脑,只有8G内存,然后又是用的wsl编译,编译编了6个多小时。难受,但不管怎么说编译算是编译过了
接下来就是研究学习源码了~
wsl下运行emulator遇到的错误
命令行输入emulator回车运行,满脸期待,然后:
shit!!!
然后打开百度!
哦,原来是这样,有道理有道理
sudo chown 你的用户名 -R /dev/kvm
执行回车再启动
完结撒花,后面会更一些对源码的解读,虽然网上已经有很多大佬解读过了,但还是希望能有自己的总结~毕竟最近离职在家也比较有时间,多多沉淀自己