0%

给 Xiaomi 6 编译 LineageOS 过程小记

2023年9月1日: 更新了大伙儿常遇到的 breakfast 命令失败的问题处理办法, 可以参考一下.

最近给手头的 Xiaomi 6 刷了 LneageOS, 体验了一把 Android 13, 挺香的! 但是这个系统有那么一丢丢水土不服, 于是决定自己来改改然后编译一个出来玩玩.

主机描述

  • CPU >= 4C
  • MEM >= 16G
  • DISK >= 200G
  • NET >= 100M
  • OS >= Debian 11/12

环境准备

安装 repo 工具

下载&安装:

mkdir ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

若无法下载可镜像下载: curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo

更新环境变量(视情况操作, 可能已经有配置了):

cat >> ~/.profile <<EOF
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
EOF
source ~/.profile

安装平台工具

sudo apt install android-sdk-platform-tools android-sdk-platform-tools-common
sudo usermod -aG plugdev $LOGNAME

安装必要软件

sudo apt install python3 \
bc bison build-essential ccache curl flex g++-multilib gcc-multilib git git-lfs gnupg gperf imagemagick \
lib32ncurses5-dev lib32readline-dev lib32z1-dev libelf-dev liblz4-tool libncurses5 libncurses5-dev \
libsdl1.2-dev libssl-dev libxml2 libxml2-utils lzop pngcrush rsync \
schedtool squashfs-tools xsltproc \
zip zlib1g-dev
sudo ln -s /bin/python3 /bin/python

软件列表请参考: https://wiki.lineageos.org/devices/sagit/build#install-the-build-packages

配置 git 用户信息

配置基本信息:

git config --global user.email "you@example.com"
git config --global user.name "Your Name"

指定 LineageOS 仓库镜像(清华大学镜像源):

cat >> ~/.gitconfig <<EOF

[url "https://mirrors.tuna.tsinghua.edu.cn/git/git-repo"]
	insteadof = https://gerrit.googlesource.com/git-repo
[url "https://mirrors.tuna.tsinghua.edu.cn/git/lineageOS/"]
	insteadof = https://review.lineageos.org/
[url "https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/"]
	insteadof = https://android.googlesource.com/
[url "https://mirrors.tuna.tsinghua.edu.cn/git/lineageOS/LineageOS/"]
	insteadof = https://github.com/LineageOS/
EOF

配置 ccache 软件

cat >> ~/.bashrc <<EOF
export USE_CCACHE=1
export CCACHE_EXEC=/usr/bin/ccache
EOF

ccache -M 50G
ccache -o compression=true

mkdir -p ~/.cache/ccache/

同步代码

mkdir -p ~/android/lineage
cd ~/android/lineage
repo init -u https://github.com/LineageOS/android.git -b lineage-20.0 --git-lfs
repo sync -c -d

编译

初始化编译环境

source build/envsetup.sh
breakfast sagit

这个环节会根据设备型号拉取对应的内核仓库, 建议使用镜像仓库加速.

对于 Xiaomi 6, 这个环节第一次执行会因为没有导入二进制文件而失败, 请参考踩坑记录.
如果碰到 Can not locate config makefile for product "lineage_sagit". 的问题也请参考踩坑记录.

导入厂商二进制文件

厂商代码是不开源的, 需要引用现有的二进制; 可以从设备提取, 也可以从现有的 ROM 包里面提取, 二选一即可.

  • 从设备提取
cd ~/android/lineage/device/xiaomi/sagit/
sudo ./extract-files.sh

这个环节需要开启 Xiaomi 6 设备的 开发者选项的调试模式 , 并连接至编译主机. 然后执行上述命令.

  • 从现有 ROM 包里面提取
mkdir -p ~/android/lineage_system_dump/
cd ~/android/lineage_system_dump/

unzip path/to/lineage-*.zip \
system.transfer.list system.new.dat* \
vendor.transfer.list vendor.new.dat*

sudo apt-get install brotli
brotli --decompress --output=system.new.dat system.new.dat.br
brotli --decompress --output=vendor.new.dat vendor.new.dat.br

git clone https://github.com/xpirt/sdat2img
python sdat2img/sdat2img.py system.transfer.list system.new.dat system.img
python sdat2img/sdat2img.py vendor.transfer.list vendor.new.dat vendor.img

mkdir system/
sudo mount system.img system/
# sudo rm -rf system/vendor
# sudo mkdir system/vendor
sudo mount vendor.img system/vendor/

cd ~/android/lineage/device/xiaomi/sagit/
sudo ./extract-files.sh ~/android/lineage_system_dump/

sudo umount ~/android/lineage_system_dump/system/vendor
sudo umount ~/android/lineage_system_dump/system
# rm -rf ~/android/lineage_system_dump/

完成之后重新执行 breakfast sagit 初始化环境.

启动编译

croot
brunch sagit

踩坑记录

git lfs 同步失败

错误示例

Downloading webview.apk (91 MB)
Error downloading object: webview.apk (e35a2a1): Smudge error: Error downloading webview.apk (e35a2a15f6dd1055ba3320f280849474eafc73d56ee26cecb7a3273ffbaa24c2): batch response: Repository or object not found: https://mirrors.tuna.tsinghua.edu.cn/git/lineageOS/LineageOS/android_external_chromium-webview_prebuilt_arm.git/info/lfs/objects/batch
Check that it exists and that you have proper access to it

Errors logged to /home/liux/android/lineage/.repo/projects/external/chromium-webview/prebuilt/arm.git/lfs/logs/20230510T215212.15094947.log
Use `git lfs logs last` to view the log.
error: 外部过滤器 'git-lfs filter-process' 失败
fatal: webview.apk:smudge 过滤器 lfs 失败
error.GitError: Cannot checkout LineageOS/android_external_chromium-webview_prebuilt_arm: Cannot initialize work tree for LineageOS/android_external_chromium-webview_prebuilt_arm
error: Cannot checkout LineageOS/android_external_chromium-webview_prebuilt_arm
正在更新文件: 100% (2237/2237), 完成.
正在更新文件: 100% (3547/3547), 完成.
error: 工作区中下列未跟踪的文件将会因为检出操作而被覆盖:
	.gitattributes
	.lfsconfig
请在切换分支前移动或删除。
正在终止
error: external/chromium-webview/prebuilt/arm64/: LineageOS/android_external_chromium-webview_prebuilt_arm64 checkout ed88096ab28a21d2fb785899532194b3a67438f1 
error: Cannot checkout LineageOS/android_external_chromium-webview_prebuilt_arm64
error: Unable to fully sync the tree.
error: Checking out local projects failed.
Failing repos:
external/chromium-webview/prebuilt/arm
external/chromium-webview/prebuilt/arm64
external/chromium-webview/prebuilt/x86
external/chromium-webview/prebuilt/x86_64
Try re-running with "-j1 --fail-fast" to exit at the first error.

由于上面拉取代码是配置了镜像仓库的, 但是镜像仓库中 git lfs 的部分文件不全, 导致同步失败.

拉取代码偶现无法解析主机名

错误示例

解决办法

  • 避免使用过多的线程, 宽带带宽不够的情况下某些线程抢不到资源, 导致连接失败;
  • 检查网络连接质量, 必要时可以考虑科学上网;
    # http
    git config --global http.proxy 'http://192.168.8.12:7890'
    git config --global https.proxy 'http://192.168.8.12:7890'
    # socks
    git config --global http.proxy 'socks5://192.168.8.12:7890'
    git config --global https.proxy 'socks5://192.168.8.12:7890'
    # cancel
    git config --global --unset http.proxy
    git config --global --unset https.proxy
    

解决办法

取消 https://review.lineageos.org/ 镜像配置, 删除出错的源码目录重新同步. 使用国外服务器建议错峰访问, 晚上比白天慢很多.

rm -rf \
.repo/projects/external/chromium-webview/prebuilt/arm \
.repo/projects/external/chromium-webview/prebuilt/arm64 \
.repo/projects/external/chromium-webview/prebuilt/x86 \
.repo/projects/external/chromium-webview/prebuilt/x86_64
rm -rf \
external/chromium-webview/prebuilt/arm \
external/chromium-webview/prebuilt/arm64 \
external/chromium-webview/prebuilt/x86 \
external/chromium-webview/prebuilt/x86_64
repo sync -c -d --fail-fast

运行 breakfast 找不到产品

错误示例

In file included from build/make/core/config.mk:353:
In file included from build/make/core/envsetup.mk:352:
build/make/core/product_config.mk:228: error: Can not locate config makefile for product "lineage_sagit".
10:46:08 dumpvars failed with: exit status 1
Device sagit not found. Attempting to retrieve device repository from LineageOS Github (http://github.com/LineageOS).
Failed to fetch data from GitHub
In file included from build/make/core/config.mk:353:
In file included from build/make/core/envsetup.mk:352:
build/make/core/product_config.mk:228: error: Can not locate config makefile for product "lineage_sagit".
10:46:08 dumpvars failed with: exit status 1
In file included from build/make/core/config.mk:353:
In file included from build/make/core/envsetup.mk:352:
build/make/core/product_config.mk:228: error: Can not locate config makefile for product "lineage_sagit".
10:46:09 dumpvars failed with: exit status 1

** Don't have a product spec for: 'lineage_sagit'
** Do you have the right repo manifest?

这是我新硬盘重新拉取代码后出现的问题, 第一次搭建环境的时候并没有出现, 折腾了很久. 最终通过看源码的方式定位原来是访问不到 Github 的文件服务器(刚好我上次同步代码的时候可以访问, 这个问题出现的频次挺高的, 我发了博客之后好几个人找我说了这个问题, 当时是不知所云, 现在明白了~).
LineageOS 源码在第一次初始化某个产品到时候, 会去 Github 上检索对应的配置便于拉取对于的代码仓库, 这个过程是通过访问 Github 的接口来实现的, 出现这个错误就是访问不到 Github 的文件服务器了.

解决办法

在文件 vendor/lineage/build/tools/roomservice.py 中作如下修改:

diff --git a/build/tools/roomservice.py b/build/tools/roomservice.py
index c723f921..196617d1 100755
--- a/build/tools/roomservice.py
+++ b/build/tools/roomservice.py
@@ -74,6 +74,9 @@ def add_auth(githubreq):

 if not depsonly:
     githubreq = urllib.request.Request("https://raw.githubusercontent.com/LineageOS/mirror/main/default.xml")
+    proxy = urllib.request.ProxyHandler({'http': '192.168.8.12:7890'})
+    opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
+    urllib.request.install_opener(opener)
     try:
         result = ElementTree.fromstring(urllib.request.urlopen(githubreq).read().decode())
     except urllib.error.URLError:

就是给访问 Github 的请求加上代理服务器即可. 也可以尝试给 shell 环境加代理试试, 我这不想污染环境就没尝试了.

运行 breakfast 报错没有找到文件

错误示例

In file included from build/make/core/config.mk:353:
In file included from build/make/core/envsetup.mk:352:
In file included from build/make/target/product/telephony_vendor.mk:21:
device/xiaomi/sagit/device.mk:54: error:  vendor/xiaomi/sagit/sagit-vendor.mk does not exist..
09:32:24 dumpvars failed with: exit status 1
Device sagit not found. Attempting to retrieve device repository from LineageOS Github (http://github.com/LineageOS).
Found repository: android_device_xiaomi_sagit
Default revision: lineage-20.0
Checking branch info
Using fallback branch: lineage-20
Checking if device/xiaomi/sagit is fetched from android_device_xiaomi_sagit
LineageOS/android_device_xiaomi_sagit already fetched to device/xiaomi/sagit
Syncing repository to retrieve project.
Fetching: 100% (1/1), done in 1.015s
repo sync has finished successfully.
Repository synced!
Looking for dependencies in device/xiaomi/sagit
Looking for dependencies in device/xiaomi/msm8998-common
Looking for dependencies in hardware/xiaomi
hardware/xiaomi has no additional dependencies.
Looking for dependencies in kernel/xiaomi/msm8998
kernel/xiaomi/msm8998 has no additional dependencies.
Done
In file included from build/make/core/config.mk:353:
In file included from build/make/core/envsetup.mk:352:
In file included from build/make/target/product/telephony_vendor.mk:21:
device/xiaomi/sagit/device.mk:54: error:  vendor/xiaomi/sagit/sagit-vendor.mk does not exist..
09:32:29 dumpvars failed with: exit status 1
In file included from build/make/core/config.mk:353:
In file included from build/make/core/envsetup.mk:352:
In file included from build/make/target/product/telephony_vendor.mk:21:
device/xiaomi/sagit/device.mk:54: error:  vendor/xiaomi/sagit/sagit-vendor.mk does not exist..
09:32:30 dumpvars failed with: exit status 1

** Don't have a product spec for: 'lineage_sagit'
** Do you have the right repo manifest?

解决办法

IMPORTANT: Some devices require a vendor directory to be populated before breakfast will succeed. If you receive an error here about vendor makefiles, jump down to Extract proprietary blobs. The first portion of breakfast should have succeeded, and after completing you can rerun breakfast

某些设备需要填充供应商目录,然后才能成功 breakfast。需要先执行 导入厂商二进制文件 步骤然后再 breakfast

执行 extract-files.sh 找不到文件

错误示例

Extracting 505 files in ./../../xiaomi/msm8998-common/proprietary-files.txt from /tmp/tmp.JtDCH6RDpg/system_dump:
  - etc/cne/Nexus/ATT/ATT_profiles.xml
    + keeping pinned file with hash 33e568627fd3f94dc45bca1c01ad10e6d8fb5b52
  - etc/cne/Nexus/ROW/ROW_profiles.xml
    + keeping pinned file with hash 238e785e9674b27c4b2365958d127533d7293132
  - etc/cne/Nexus/VZW/VZW_profiles.xml
    + keeping pinned file with hash 0f63b632e3a3f114def7aeadaabd13851c8ceec5
  - system_ext/etc/permissions/qti_libpermissions.xml
    !! system_ext/etc/permissions/qti_libpermissions.xml: file not found in source
  - system_ext/etc/permissions/qti_permissions.xml
    !! system_ext/etc/permissions/qti_permissions.xml: file not found in source
  - vendor/lib64/com.qualcomm.qti.imscmservice@2.0.so
    !! vendor/lib64/com.qualcomm.qti.imscmservice@2.0.so: file not found in source
  - vendor/lib64/com.qualcomm.qti.imscmservice@2.1.so
    !! vendor/lib64/com.qualcomm.qti.imscmservice@2.1.so: file not found in source
  - vendor/lib64/com.qualcomm.qti.uceservice@2.0.so
    !! vendor/lib64/com.qualcomm.qti.uceservice@2.0.so: file not found in source
  - system_ext/lib64/lib-imscamera.so
    !! system_ext/lib64/lib-imscamera.so: file not found in source

解决方法

需要使用 root 权限执行.

参考

  • 本文作者: 6x
  • 本文链接: https://6xyun.cn/article/169
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-ND 许可协议。转载请注明出处!