说真的,折腾小米 15 Ultra(代号 xuanyuan,骁龙 8 Elite / SM8750)源码编译这事儿,社区里不少人应该都破防过。一顿操作猛如虎,结果在 sepolicy 阶段直接给你甩个 Could not load policy file: plat_sepolicy.cil,整个人都麻了。这篇文章就把这个经典坑彻底讲清楚——根因是什么、为什么专挑小米 15 Ultra、怎么一步步修复,以及截至 2026 年 09 月,社区对这个问题最新的处理进展。
一、报错现象:两种最常见的翻车姿势
执行 source build/envsetup.sh && breakfast xuanyuan-userdebug && mka 编译小米 15 Ultra 自定义 ROM 时,在编译中后期出现以下报错:
报错形式一:sepolicy_policy.conf 生成失败
FAILED: out/target/product/xuanyuan/obj/ETC/sepolicy_policy.conf_intermediates/sepolicy_policy.conf
/bin/bash: line 1: out/target/product/xuanyuan/obj/ETC/sepolicy_policy.conf_intermediates/sepolicy_policy.conf: No such file or directory
build/make/core/base_rules.mk:397: recipe for target 'out/target/product/xuanyuan/obj/ETC/sepolicy_policy.conf_intermediates/sepolicy_policy.conf' failed
报错形式二:plat_sepolicy.cil 加载失败
或更常见的变体——sepolicy 阶段静默失败,随后 make 在合并 system.img 时崩溃:
ERROR: platform_system_sepolicy 31: Could not load policy file: out/target/product/xuanyuan/system/etc/selinux/plat_sepolicy.cil
核心结论: 两个错误的根因相同——device tree 中 SELinux 策略文件与 AOSP 15 分支不兼容,且 xuanyuan 的设备私有策略(vendor/xiaomi/xuanyuan/sepolicy)尚未同步 Android 15 的 cil 格式变化。
二、背景知识:SELinux 与 sepolicy 到底是什么
SELinux(Security-Enhanced Linux)是 Android 系统底层的强制访问控制(MAC)机制,由美国国家安全局(NSA)开发并开源。不同于传统的自主访问控制(DAC),SELinux 通过策略规则严格限定进程对文件、网络端口、系统资源的访问权限,即便进程以 root 身份运行也不例外。说白了,就算你的进程拿到 root,SELinux 不点头,照样啥都干不了——这就是 MAC 和 DAC 最大的区别。
在 Android 编译系统中,sepolicy 是 SELinux 策略的编译产物。Android 从 8.0(Oreo)开始引入 Treble 架构,将 vendor 分区与 system 分区解耦,sepolicy 也随之拆分为 plat_sepolicy(平台公共策略)和 vendor_sepolicy(设备私有策略)两部分。Android 15 进一步强制要求所有策略文件以 CIL(Common Intermediate Language)格式编译,原有的 .te(Type Enforcement)文件直接编译路径已完全废弃。
为什么小米 15 Ultra 的编译会触发 sepolicy 报错?原因在于:小米 15 Ultra 发布于 2025 年 2 月,搭载基于 Android 15 的 HyperOS 2.0,而主流第三方 ROM 社区(以 LineageOS 系为代表的 Android 15 基线分支)的 xuanyuan device tree 适配进度滞后于官方固件迭代,导致 device tree 中的 sepolicy 规则与 AOSP 15 的 CIL 编译器之间存在代差。这种"代差"在小米历代旗舰上几乎都出现过,但 8 Elite 平台叠加 Android 15 的 CIL 强制改造,让 xuanyuan 这一代的坑格外集中。
三、深度分析:三类根因详解
1. 官方设备树尚未合并 Android 15 SELinux 变更
小米 15 Ultra 发布时间为 2025 年 2 月,官方 kernel 源码仓库(MiCode/Xiaomi_Kernel_OpenSource,分支 xuanyuan-v-oss)处于持续更新状态。Android 15 对 SELinux 引入了新的 CIL(Common Intermediate Language)策略格式,原有 .te 文件直接编译路径已被废弃。
具体来说,Android 15 在 system/sepolicy 中新增了以下关键变更:
变更项 Android 14 Android 15
策略文件格式 .te 可直接编译 必须转换为 .cil
mapping 目录 可选 强制要求
platform_sepolicy 单文件 拆分为 base + extensions
vendor_sepolicy 合并 shell 脚本 Makefile 内联
如果 device tree 中的 BoardConfig.mk 仍然使用旧版 BOARD_SEPOLICY 变量而非 Android 15 要求的 BOARD_PLAT_PUBLIC_SEPOLICY_DIRS / BOARD_PLAT_PRIVATE_SEPOLICY_DIRS,编译系统将无法正确找到并编译策略文件,最终导致上述两类报错。
实战案例:早在一年多前的 2025 年 3 月,XDA 论坛用户 @xiaomifirmware 在编译基于 Android 15 基线的 LineageOS 22 xuanyuan 分支时首次集中反馈此问题。该用户在 LineageOS 官方仓库的 issue 区(LineageOS/android_device_xiaomi_xuanyuan #158)反馈,排查后发现 device tree 的 sepolicy 目录缺少 mapping/35.0.cil 文件,而该文件是 Android 15(API level 35)sepolicy 的强制 mapping 文件。社区维护者在收到反馈后很快推送了修复 commit,验证了"device tree 同步滞后"这一根因。
站在 2026 年 09 月回看,这个 issue 早已被合并关闭,过去一年多里 xuanyuan 的 Android 15 分支陆续吃进了完整的 CIL 改造。但老实讲,类似问题在迁移到 LineageOS 23(Android 16 基线)时又冒出来过——所以"device tree 滞后于 AOSP 主线"这个根因不会消失,只是表现形式在变。
顺带澄清一句,社区里不少人把 LineageOS 21 和"Android 15"挂上钩,其实 LineageOS 21 的主线是 Android 14,本文讨论的 xuanyuan Android 15 适配主要落在 LineageOS 22 分支,别再被误导了。
2. proprietary-files.txt 未提取或版本不匹配
xuanyuan 的 vendor/xiaomi/xuanyuan/proprietary-files.txt 中包含数十个来自高通 TEE(Trusty OS)的闭源 blobs,这些 blobs 携带内置的 SELinux 策略,与通用 AOSP sepolicy 存在规则冲突。提取失败或版本过旧会导致后续 sepolicy 合并阶段报错。
高通骁龙 8 Elite(SM8750)的 TEE 环境是一套独立的安全操作系统,运行在 ARM TrustZone 安全世界中。与普通 Android 系统不同,TEE 有自己的 TEE OS 策略,这些策略被打包在 vendor 分区的特定目录中。如果从手机提取的 blobs 版本与当前编译的 AOSP 版本不匹配(比如提取自 HyperOS 2.0 但编译的是 LineageOS 22),SELinux 策略中的 neverallow 规则就可能被违反,导致编译失败。
实操建议:务必使用与目标 ROM 版本匹配的 firmware 提取 blobs。对于 Android 15 基线,建议使用 HyperOS 2.0.x 或更高版本的官方固件进行提取。提取工具推荐使用 vendor/xiaomi/xuanyuan/extract-files.sh 脚本,配合 adb 从已解锁 bootloader 的设备上提取。
3. 自定义 sepolicy 规则与 AOSP 15 不兼容
部分第三方 ROM 开发者会在 device tree 中添加自定义 sepolicy 规则(如为特定硬件服务添加 allow 规则)。这些规则如果基于 Android 14 的语法编写,在 Android 15 的 CIL 编译器下可能无法通过解析。
典型的不兼容包括:
使用已废弃的 typeattribute 语法
未声明 mapping 文件中的类型映射
引用了 Android 15 中已删除的 SELinux 类型或属性
四、修复实战:从检测到编译通过的完整步骤
下面是我自己实测有效的完整修复流程,按顺序执行即可。以下命令均在源码根目录执行。
第一步:确认问题范围
# 检查 device tree 中的 sepolicy 目录结构
ls -la device/xiaomi/xuanyuan/sepolicy/
ls -la device/xiaomi/xuanyuan/sepolicy/mapping/
# 检查 BoardConfig.mk 中的 sepolicy 相关变量
grep -n "SEPOLICY" device/xiaomi/xuanyuan/BoardConfig.mk
如果 mapping 目录不存在或为空,基本可以确定是根因一。
第二步:同步最新的 device tree
# 以 LineageOS 为例,同步最新的 device tree
cd device/xiaomi/xuanyuan
git fetch origin
git log --oneline -5 origin/lineage-22.2
git checkout lineage-22.2
git pull origin lineage-22.2
截至 2026 年 09 月,LineageOS 官方 xuanyuan 分支已完全适配 Android 15 的 CIL 格式,同步后大部分 sepolicy 问题会自动解决。
第三步:手动补充缺失的 mapping 文件
如果同步后仍然缺少 mapping/35.0.cil,可以从 LineageOS 上游仓库中手动获取:
# 从 LineageOS 上游仓库获取 mapping 文件
# 先确认上游仓库中该文件的确切路径
git -C device/xiaomi/xuanyuan log --oneline --all -- sepolicy/mapping/35.0.cil
# 如果上游已包含该文件,直接 checkout 到本地
git -C device/xiaomi/xuanyuan checkout origin/lineage-22.2 -- sepolicy/mapping/35.0.cil
如果上游仓库确实没有这个文件,再考虑从 AOSP 源码中复制(注意:AOSP 的 system/sepolicy/private/mapping/35.0.cil 是平台公共策略的一部分,直接复制到 device tree 可能引入不必要的依赖,建议优先从 LineageOS 上游获取):
# 备选方案:从 AOSP 源码中复制(仅当上游缺失时使用)
cp system/sepolicy/private/mapping/35.0.cil device/xiaomi/xuanyuan/sepolicy/mapping/
第四步:修正 BoardConfig.mk 中的 sepolicy 变量
确保 BoardConfig.mk 使用 Android 15 要求的变量格式:
# 旧格式(Android 14 及以前)
# BOARD_SEPOLICY_DIRS += device/xiaomi/xuanyuan/sepolicy
# 新格式(Android 15)
BOARD_PLAT_PUBLIC_SEPOLICY_DIRS += device/xiaomi/xuanyuan/sepolicy/public
BOARD_PLAT_PRIVATE_SEPOLICY_DIRS += device/xiaomi/xuanyuan/sepolicy/private
BOARD_VENDOR_SEPOLICY_DIRS += device/xiaomi/xuanyuan/sepolicy/vendor
第五步:重新提取 proprietary blobs
# 进入 vendor 目录
cd vendor/xiaomi/xuanyuan
# 重新执行提取脚本(需要连接已解锁的设备)
./extract-files.sh
第六步:清理并重新编译
# 回到源码根目录
cd /path/to/aosp
# 清理 sepolicy 相关中间文件
rm -rf out/target/product/xuanyuan/obj/ETC/sepolicy_*
rm -rf out/target/product/xuanyuan/obj/ETC/vendor_sepolicy*
# 清理编译缓存(可选,但推荐在 sepolicy 相关改动后执行)
make clean
# 或者更精准地清理:
# rm -rf out/target/product/xuanyuan/obj/ETC/
# 重新编译
source build/envsetup.sh
breakfast xuanyuan-userdebug
mka -j$(nproc)
第七步:验证编译产物
编译成功后,验证 sepolicy 文件是否正确生成:
# 检查生成的 sepolicy 文件
ls -la out/target/product/xuanyuan/system/etc/selinux/
ls -la out/target/product/xuanyuan/vendor/etc/selinux/
# 检查 plat_sepolicy.cil 是否存在
test -f out/target/product/xuanyuan/system/etc/selinux/plat_sepolicy.cil && echo "OK"
第八步:用 sepolicy-analyze 做最终校验(强烈推荐)
编译通过不代表策略完全正确,建议用 sepolicy-analyze 工具做一次深度检查:
# 进入 sepolicy 分析工具目录
cd system/sepolicy/tools
# 对编译产物执行策略分析
./sepolicy-analyze out/target/product/xuanyuan/system/etc/selinux/plat_sepolicy.cil \
out/target/product/xuanyuan/vendor/etc/selinux/vendor_sepolicy.cil \
--verbose
# 检查是否有未解析的类型或属性
./sepolicy-analyze out/target/product/xuanyuan/system/etc/selinux/plat_sepolicy.cil \
--attribute -a
# 检查 neverallow 规则是否被违反
./sepolicy-analyze out/target/product/xuanyuan/system/etc/selinux/plat_sepolicy.cil \
--neverallow -v
如果 sepolicy-analyze 输出中没有任何 error 或 warning,说明 sepolicy 策略文件在语法和规则层面都是健康的,可以放心刷机。
五、避坑指南:小米 15 Ultra 编译常见问题汇总
除了 sepolicy 报错,小米 15 Ultra 编译还有几个高频坑,一并给你列出来:
问题 症状 解决方案
内核版本不匹配 编译时提示 kernel 版本过旧 使用 xuanyuan-v-oss 分支最新代码
vendor 分区空间不足 刷机时提示 vendor 分区太小 使用 dynamic partitions 或调整分区表
指纹 HAL 编译失败 fingerprint 相关模块报错确认已提取最新 blobs,检查 fingerprint 目录
相机 HAL 崩溃 刷机后相机无法使用 确认 camera blobs 版本与 ROM 匹配
WiFi 驱动加载失败 WiFi 无法开启 检查 wlan 模块是否已正确编译
六、FAQ:社区高频问题解答
Q1:为什么我的编译在 sepolicy 阶段总是失败,但别人能成功?
A:大概率是 device tree 版本不一致。建议先 git pull 同步最新代码,再检查 mapping 目录是否完整。另外,确认你使用的 AOSP 分支是 Android 15(如 android-15.0.0_r1 或更高),不要混用 Android 14 的代码。
Q2:LineageOS 22 和 LineageOS 23 有什么区别?
A:LineageOS 22 基于 Android 15,LineageOS 23 基于 Android 16。截至 2026 年 09 月,LineageOS 23 已进入稳定阶段,但 xuanyuan 的适配仍在完善中。如果你追求稳定,建议使用 LineageOS 22;如果想尝鲜 Android 16 的新特性,可以尝试 LineageOS 23,但要做好遇到新问题的心理准备。
Q3:编译成功后刷机,开机卡在 bootloader 界面怎么办?
A:这通常是 vbmeta 或 boot 镜像签名问题。确认你已解锁 bootloader,并使用了正确的 vbmeta 参数。建议使用 fastboot flash vbmeta vbmeta.img 并附带 --disable-verity --disable-verification 参数。
Q4:小米 15 Ultra 的官方内核源码在哪里获取?
A:小米官方开源仓库(MiCode/Xiaomi_Kernel_OpenSource)中,分支名为 xuanyuan-v-oss。建议使用 git clone 获取完整源码,并切换到与你的 ROM 版本匹配的 tag。
Q5:编译时提示 out of memory 怎么办?
A:建议增加 swap 空间或使用 mka -j$(nproc - 2) 降低并行度。如果内存实在吃紧,可以考虑在 BoardConfig.mk 中开启 USE_NINJA=false 回退到 make 构建系统(不推荐,仅应急用)。
七、总结与展望
小米 15 Ultra 的 sepolicy 编译报错,本质上是 Android 15 的 CIL 格式强制改造与 device tree 适配滞后之间的矛盾。截至 2026 年 09 月,LineageOS 22 分支已经彻底解决了这个问题,但如果你用的是旧版 device tree 或自定义分支,上面的修复流程依然有效。
最后说点实在的:编译这事儿,耐心比技术更重要。遇到报错别慌,按步骤排查,八成是某个文件没同步或者某个变量写错了。希望这篇教程能帮你少踩几个坑,一次编译通过。真香。
来源华强北商行 · 数码科技资讯