☰
全志T527 Android 13全流程编译指南:从环境配置到系统定制
2026/10/3 13:12:54 网站建设 项目流程

做了这么多年全志平台,从A20一路做到T527,我必须说一句:T527这颗芯片本身没什么大脾气,真正折磨人的是它配套的 Android 13 工程编译流程。网上资料散的散、旧的旧,照着做的人多半会在 JDK 版本、磁盘空间、ninja 崩溃这些地方卡上几天。这篇东西我不讲虚的,就把我在 Ubuntu 上从零编译 T527_Android13 的完整过程、踩过的坑和最终验证过的方案写出来,给准备在这个平台上做系统定制、Framework 开发或者 BSP 移植的工程师当个参考。

先说清楚这篇博文的适用范围。它适合三类人:第一次接触全志 T527 的驱动工程师、要做 Android 13 SystemUI 或上层定制的应用框架工程师,以及买不到靠谱技术支持、只能自己折腾的硬件产品团队。需要的基础是熟悉 Linux 基本命令、知道 repo 和 make 大概是怎么回事。如果你从来没编译过 AOSP,建议先把 Android 官方文档里的 AOSP 环境搭建那一节翻一遍再回来看这篇,会顺很多。

1. 编译前必须搞清楚的环境与选型

1.1 T527 平台和 Android 13 SDK 的大致关系

全志 T527 是面向 AIoT 和边缘计算场景的八核 A55 芯片,带 2TOPS NPU,支持 Android、Linux、RTOS 多系统。厂商提供的 Android 13 SDK 并不是纯粹的谷歌 AOSP 主线,而是在 AOSP 13 的基础上,叠加了全志自家的硬件抽象层、电源管理、显示框架、多媒体编解码、NPU 运行时等大量客制化代码。这意味着你在编译时拿到的其实是一个“全志把 AOSP 拉下来改了一版”的巨型仓库,而不是几个零散的 git 项目。

明白这一点很重要,因为很多人第一次编译失败,就是把它当成标准 AOSP 来搞,动不动就去 AOSP 官方查命令、查环境要求,结果发现对不上。全志的 SDK 有自己固定的仓库组、固定的分支名和固定的编译入口,你在 device 目录下看到的方案名(比如 t527、t527_xxx)才是指路的灯塔。先搞清楚自己手里的 SDK 是从哪来的、分支名是什么,能省掉后面一大半的弯路。

1.2 编译主机硬件建议

T527_Android13 的源码大小和编译产物体积,比很多人预想的要夸张得多。我给个我自己实测的参考:源码仓库全量同步下来大约 120GB 到 160GB(取决于 git 历史数据),编译过程中生成的 out 目录在第一次全编后会逼近 150GB 到 200GB。如果加上 ccache、中间备份、固件打包产物,一台编译服务器上给它划出 500GB 的可用空间是最稳妥的。很多人在这一步就开始踩坑,磁盘不够导致链接阶段报错,找半天问题根源其实只是 df -h 看一眼就明白的事。

内存方面,我的建议是 32GB 起步,64GB 更好。Android 13 的编译系统比 10 以前的老版本更吃内存,因为新的 Soong 构建系统和 link step 会起大量并行进程。我在 16GB 内存的机器上试过,ninja 跑到一半被 OOM killer 杀掉是家常便饭。如果你实在只有 16GB,那就只能在 make 的时候把并行数压到 -j4 甚至 -j2,时间会变得非常难熬,一次全编可能七八个小时起步。CPU 核心数自然是越多越好,但要注意一个性价比点:超过 32 核以后,磁盘 IO 和内存带宽会成为瓶颈,继续加核心数对编译时间的提升就很不明显了。

操作系统我推荐使用 Ubuntu 20.04 或者 22.04 的 64 位版本,尽量不要用 Fedora、Arch、Debian 测试版之类的“先进”发行版。原因不是它们跑不了编译,而是 Android 的工具链对 glibc 版本非常敏感,很多 prebuilt 工具是在特定 glibc 版本上编译的,系统太新或太旧都可能出现“invalid ELF header”或者段错误。全志官方文档一般也会指定 Ubuntu 版本,听着像废话,但这是无数人用血泪换来的教训。

1.3 系统版本与依赖软件的版本坑

很多教程开篇就是 apt install 一大串,但没有解释到底装什么、为什么。Android 13 的编译依赖其实分成两类:一类是编译本身要的包(如 git、gnupg、flex、bison、build-essential、zip、curl、libncurses5-dev 等),另一类是系统镜像打包和烧录工具(如 python3、ssh、repo、fastboot 等)。通常你会需要类似这么一串:

sudo apt update && sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 libncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig openjdk-17-jdk python3 python3-pip

这里最容易被忽略的是JDK 版本。Android 13 对应的 AOSP 编译要求 JDK 17,不是 11,更不是 8。如果你机器上默认装的是 OpenJDK 11(Ubuntu 20.04 的 apt 默认源里就没有 17,需要先装 OpenJDK 17 或者手动配置),那么编译到中间阶段会出现一堆“Unsupported class file major version”之类的报错。全志 SDK 里其实预置了编译脚本,有些脚本会自动检测 JDK 版本并切换到自带的 JDK,但如果你绕过了脚本直接跑 make,这个坑就很容易踩中。

Python 的版本也有讲究。T527 的 SDK 在宿主机上跑的一些工具脚本需要 Python 3.8 或更高版本,Ubuntu 20.04 自带的 Python 3.8 够用,但如果你的系统是老的 18.04(Python 3.6),会有部分脚本直接报语法错误。反过来,也别手贱去硬刚 Python 3.10+,某些老脚本在 3.10 上会出现 module 导入路径变化导致的异常。

2. 源码结构与第一次同步

2.1 repo 同步与分支选择

全志的 Android SDK 基本都走 repo 管理,同步方式也和 AOSP 差不多。拿到厂商提供的信息后,通常是本地建一个目录,然后执行:

mkdir t527_android13 && cd t527_android13 repo init -u <manifest仓库地址> -b <分支名> repo sync -c -j8

这里有个我反复强调的点:分支名一定要用厂商 release 出来的稳定分支,不要自己 pick 一个说“看起来是最新”的分支。全志的代码仓库里有些分支可能还在内部研发阶段,提交历史不稳定,同一个文件今天有、明天就删了,你辛辛苦苦同步完,编译的时候会发现 vendor 目录下的某个 prebuilt 库缺失,根本没法用。

repo sync 的并行数不需要太大。很多人以为 -j32 同步更快,实际上 repo 同步的瓶颈在于网络延迟和 Git 服务器的并发限制,而不是本地 CPU。我在实际使用中用 -j8 到 -j12 最稳,偶尔网络抖动导致某个仓库同步中断,重新执行同一个 repo sync 命令它会断点续传,不需要删掉重来。如果出现反复失败的仓库,可以先单独把它精简一下:

repo sync -c -j8 某个失败的仓库路径

这个命令只同步指定的那一个仓库,速度要快很多。

国内网络环境同步大仓库的时候,我建议在 repo init 阶段就配置好镜像源。Github 官方源和 AOSP 官方源在某些时段传输效率很低,一个 100GB 的仓库同步三五天都不稀奇。配置国内高校或云厂商的 AOSP 镜像,速度会有质的提升。这个操作不复杂,就是在 repo init 的时候给 manifest 仓库换一个镜像地址,后续的 repo sync 就会自动走镜像。

2.2 SDK 里那些“看着没用但删了就废”的目录

全志 SDK 在 vendor 目录下有大量闭源 prebuilt 组件,这是与其他开源 AOSP 工程最大的不同。你会在 vendor/hardware、vendor/aw、vendor/softwinner 等路径下看到一堆预编译的 .so、二进制工具和 DSP 固件,这些东西在编译时会被链接进最终的 system.img、vendor.img。很多第一次碰全志的人有个坏习惯:为了省磁盘空间,把看似“没用的第三方 so”删掉,结果编译到后期报“cannot find -lxxx”或者镜像打包脚本找不到固件。

我的建议是:在第一次全编译通过之前,不要删除任何位于 vendor、device、hardware 目录下的文件。甚至包括一些 README、.txt 说明文件也别动。全志的构建脚本有时候会把整个目录当作资源目录拷贝,你少了一个无关紧要的空文件,脚本可能都会因为找不到路径而报错。等第一次编译通过、固件能烧录启动了,再慢慢清理不迟。

2.3 磁盘空间规划

前面提过磁盘空间至少留 500GB,但这个规划不能只做一个分区。我给的建议是:系统盘留 100GB 以上,源码和 out 目录放在独立的大分区下。这里有一个 Linux 新手很容易忽略的问题:/home 和 / 如果不在同一个分区,那么 home 目录下的空间和根目录空间是分开计算的。默认安装 Ubuntu 时如果选了“整个磁盘自动分区”,往往只有一个根分区,不容易出事;但如果手动分区,就得留意源码目录到底挂在哪个挂载点下。

编译 Android 是很典型的“重写频繁”场景,建议把源码放在 SSD 上。机械硬盘在大量小文件编译时 IO 会卡到怀疑人生,T527 全编一次在机械盘上多花两三个小时非常正常。如果预算允许,用 NVMe 固态最好。另外,给 out 目录和 ccache 桶留出足够余量,否则编到一半磁盘满,ninja 进程退出,你之前的几个小时全白费。

3. 环境变量、JDK/Python 与实际编译流程

3.1 JDK 17 与 Python 版本的坑

全志 SDK 虽然会自动检测,但为了保险,我会在编译前手动清楚指定一次。如果系统里存在多个 JDK 版本,可以用 update-alternatives 切换:

sudo update-alternatives --config java

选到 OpenJDK 17 之后,确认一下当前 java 版本:

java -version

输出里应该是 openjdk version “17.x.x”。如果还是 11,别急着编译,先用这个命令排查是不是 JAVA_HOME 环境变量把路径指向了旧版本。AOSP 的构建脚本对 JAVA_HOME 的判断并不完全可靠,有时候你改了 java 命令的 alternatives,JAVA_HOME 还指在旧路径上,编译依然会炸。

Python 那边,确认默认 python3 指向的是 3.8 或 3.9。全志的许多工具脚本直接在 shebang 里写的是 python3,如果你的系统只有一个 python3.6,很可能会报语法错误。别尝试在系统层面随便改 python3 的软链接,因为 Ubuntu 底层的 apt 也依赖 Python,改乱了系统都起不来。正确的做法是在编译前设置 PATH,把你要用的 Python 3.8 路径放到最前面,或者用虚拟环境。

3.2 build/envsetup 和 lunch 的完整流程

回到工程目录,标准流程如下:

source build/envsetup.sh lunch

lunch 会列出一堆可用的 product 配置,这些配置定义在 device/softwinner/t527 目录下的 AndroidProducts.mk 里。T527 一般会有几个典型选项,比如 full_t527-eng、full_t527-userdebug。首次开发和调试阶段,建议选 eng 版本,因为它会开放 adb root、关闭一些安全限制,更适合抓 log。如果是做最终量产固件,用 userdebug 或者 user 版本。user 版本会有严格的权限限制,蓝牙、WiFi、RIL 等功能的调试会很麻烦,开发初期不要碰。

lunch 之后,如果你不确定当前选择的配置,可以用 echo $TARGET_PRODUCT 和 echo $TARGET_BUILD_VARIANT 看一下。确定无误后,直接开始编译:

make -j16 2>&1 | tee build.log

这里的 -j16 是根据机器配置设定的。我常用的计算方式是:内存 64GB 的机器,核数 16 到 24 之间都行;32GB 内存的机器,老老实实 -j12;16GB 内存的机器,-j4 到 -j6,再多就是赌命。

2>&1 | tee build.log 这一步是我强烈建议保留的习惯。编译输出几千行,终端滚动条根本看不过来,把完整日志写到文件里,出问题之后 grep 定位要方便得多。比如:

grep -n "error:" build.log | tail -50

这条命令能快速拉出最后一批编译错误。ninja 在报错时会显示失败的目标文件路径和依赖关系,照着定位,通常比在终端翻历史记录高效十倍。

3.3 make 并行数与日志记录

继续展开一下并行数的问题。很多人觉得 -j 越大越好,实际上 Android 13 的构建系统在 make 之后内部会切换成 ninja,ninja 自己有一套并行度控制机制。如果你在 make 命令里给的 -j 太大,内存会瞬间爆掉,OOM killer 会把正在跑高内存的 ninja 子进程杀掉。典型的表现是:编译进行到 30% 左右,终端突然出现一堆“Killed”字样,build.log 最后几行是 ninja: build stopped: killed by signal 或者直接没有输出。

如果你已经开了 log 记录,就能很清楚地看到 dead 之前最后一个被编译的模块是什么。这时候不用怀疑代码有问题,先查一下 free -m,看是不是内存被榨干了。我见过有人在这种“Killed”报错之后反复清理 out 目录重新编译,折腾了两天,最后发现只是 make 命令少换了一个更小的 -j 数字,非常冤枉。

ccache 是另一个值得一开始就配好的东西。在编译 T527 这种大型 SDK 的时候,ccache 的作用非常明显,尤其是你修改了 Framework 层或者 kernel 的少量文件后做增量编译,命中率高的场景下能省掉接近一半时间。配置方法:

export USE_CCACHE=1 export CCACHE_EXEC=/usr/bin/ccache ccache -M 50G

ccache 的缓存大小我建议设置 50GB 到 100GB。太小的话,几次增量编译就把它撑满,旧缓存被淘汰,命中率直线下降;太大则会占用大量磁盘空间,和 out 目录抢地盘。首次全编时 ccache 会写入缓存,速度会比不带 ccache 略慢一点,但后面的增量编译会让这部分时间完全回本。

4. 高频报错与排查思路(实战速查)

这一节我直接按错误类型来整理,每一条都是我在 T527 和相近的全志平台上实际遇到过的,不是从网上抄来的理论。

4.1 编译期崩溃类错误

Out of memory / ninja: build stopped:这个上面提过,先查内存和 swap,再考虑减小并行数。不要一上来就清理 out 重编,查日志判断是哪个模块导致的峰值内存。另外,如果你开了太多终端、跑着 IDE、还挂着一个 Docker 容器,这些都会吃掉内存,编译时尽量把这些都关掉。

Unsupported class file major version:基本可以断定是 JDK 版本不对。这个报错常见于编译 Java 相关的 Framework 模块时,用 java -version 检查当前 JDK。另外注意 Android 13 的 build 系统在部分模块上要求的是 javac 17,如果你通过某种方式把 JAVA_HOME 指到了 Android Studio 自带的 JBR 11 路径,也会报这个错。

/bin/bash^M: bad interpreter: No such file or directory:脚本文件是 Windows 换行符 CRLF。这个经常出现在从 Windows 共享文件夹拷贝预编译脚本、补丁文件之后。用 dos2unix 转一下对应文件即可。我一般会整体扫描一遍自己拷贝进去的脚本目录:

find ./ -name "*.sh" -exec dos2unix {} \;

不会影响正常的 Linux 换行符文件,只会把 CRLF 转成 LF。

DTC: Error: xxx.dts: yyy:DTS 设备树编译错误。如果改过设备树,八成是你写错了节点格式、引用了一个不存在的节点,或者 include 的文件路径不对。如果没改过 DTS 就报这个错,大概率是 kernel 仓库里的 dts 相关仓库没有同步完整,检查一下 kernel 仓库的 git status,确认是否有文件缺失。

4.2 链接与第三方库方面的错误

cannot find -lxxx:这个 xxx 是某个库的名字,比如 -lc、-lhardware。-l参数对应的库文件其实在源码里能找到,但链接器搜索的路径不对,或者对应的 prebuilt 库根本没有被编译出来。在 T527 上,它常常出现在你修改了某个模块的 Android.bp,却忘了检查它依赖的 shared library 是否在编译列表中。排查思路是:先全库搜索这个库名字,确认源文件或者 .so 在不在,然后看 build.log 里这个模块到底编没编出来。

ninja: error: ‘xxx’, needed by ‘yyy’, missing and no known rule to make it:这是 Android 13 增量编译时最容易遇到的报错,比全编还常出。原因是你的增量改动让某个产物失效,但 ninja 找不到重新生成它的规则。最常见的触发场景是:删除了某个模块的源文件,或者改了 Android.bp 里的模块名、路径,却没有清理旧的中间产物。解决办法:

rm -rf out/target/product/t527/obj/<对应模块名>_intermediates

删完再重新 make 这个模块,ninja 会重新生成构建规则。

FAILED: out/target/product/t527/...img:镜像打包阶段失败。先看具体是哪一步挂掉,可能是磁盘空间不足、可能是有某个预编译文件路径缺失、也可能是打包脚本依赖的工具(如 mkbootimg、ext4 工具)没有安装。如果日志里提示找不到某个 .sh 脚本,基本可以判断是你动了 vendor 目录下的文件。

4.3 改了东西不生效的坑

改完 SystemUI 重新 make,发现系统里还是旧 UI:这是顶层定制工程师问得最多的问题。原因通常是你只编了 SystemUI 模块,却没有重新打包 system.img,或者打包了但 adb push 时没有处理 odex/vdex。Android 13 默认会对 Framework 和 SystemUI 做 dex 预优化,直接替换 APK 有时会启动时校验失败,系统退回旧版本。正确做法详见第 5 章。

改完 kernel 设备树,烧录后启动 log 显示还是旧参数:设备树不是打包在 boot.img 里的,T527 这种平台一般会把 dtb 单独分区或者打进 boot.img 的 resource 区域。改完 DTS 后,光重编内核不行,还得重新打包 boot.img(或者 boot0/uboot 相关分区)。我建议每次改完设备树都执行一次:

make bootimage -j8

这样确保新的 dtb 被打进 boot 镜像里。如果还是没生效,检查打包脚本里用的是不是你修改的那个 dts 文件,全志的 product 配置里有 device 宏,它决定了最终使用哪个 dts。

5. 典型定制场景:SystemUI 定制与 RIL 替换

T527 的很多项目不是原样出货,而是要做深度定制。这里我把最常见的两个场景单独拎出来写,因为它们的坑最集中。

5.1 SystemUI 定制编译的正确打开方式

T527 用的 Android 13 版本中,SystemUI 的路径和标准 AOSP 一致,在 frameworks/base/packages/SystemUI。很多人第一次改完代码,直接 make SystemUI,然后 adb push 过去,发现系统直接黑屏或者 SystemUI 不停崩溃,Logcat 里一堆 SecurityException。

正确的增量编译流程是:

source build/envsetup.sh lunch full_t527-eng make SystemUI -j8

编完之后不要直接 push APK,Android 13 的 Framework 进程会做系统签名校验和权限保护。先把新编译的 SystemUI 输出到本地目录,再通过 adb root + adb remount 的方式,把 APK 推送到 /system_ext/priv-app/SystemUI/(具体路径取决于你的 product 配置),同时推送对应生成的 odex/vdex。这一步最容易出错的是编译产物不匹配,导致 dex2oat 失败。

我个人更推荐的方式是直接重新打包系统镜像:

make snod

这个命令会跳过重新编译,直接用已有的模块产物重新打包 system.img。前提是你已经用 make SystemUI 把 SystemUI 模块编译出来了。然后烧录或者 adb push 整个 system.img 分区,虽然比单文件 push 慢,但能避免 odex 乱七八糟的问题,适合验证大的改动。

平时做 Framework 层修改时,我还有个习惯:把开发板的 adb root 打开,用 adb sync 做增量同步。它对比本地 out 产物和设备的 system 分区,只推送变化的部分,速度比整包 push 快很多。不过在 T527 上,你要先确认自己的 userdebug 版本没有关闭 adb sync 所需的一些权限。

定制 SystemUI 时另一个高发问题:资源编译冲突。你改了 strings.xml 或者 overlay 资源,编译时报资源重复定义或者找不到资源。这时候先把对应模块的 intermediates 目录删掉,再重新 make:

rm -rf out/target/product/t527/obj/APPS/SystemUI_intermediates

这个目录缓存的编译状态经常会在资源更新后处于一个不干净的中间状态,让它重新编一遍就好。别没事就 make clean,那会把整个 out 目录都干掉,下次编译等于全编,太浪费时间。

5.2 移远 libquectel-ril 接入 T527 的实战记录

很多 T527 方案在网联类产品里会配移远(Quectel)的 4G/5G 模组,比如 EC20、RM500Q 等。全志 SDK 自带的 RIL 通常是 reference-ril 或者全志自己的 lite-ril,直接接移远模组时会出现开机无法识别 SIM 卡、打电话没声音这类问题。这时候通常需要编译移远提供的 libquectel-ril 进行替换。

这里分享一个具体的接入流程。移远会提供一份包含源码或 prebuilt 的 ril 库包,里面一般有 libquectel-ril.so 和对应的 Android.bp。你需要把它放到某个 vendor 目录(比如 vendor/quectel/ril/)下,然后在 PRODUCT_PACKAGES 里加上这个模块,同时把系统属性里 RIL 库路径指过去。关键的属性是:

rild.libpath=/vendor/lib64/libquectel-ril.so

T527 是 64 位系统,注意是 lib64 而不是 lib。改完属性之后,还要处理 SELinux 权限问题。全志的 userdebug 版本默认 enforce 可能开着,RIL 进程起来后访问串口设备或网络接口会被 SELinux 拦截,logcat 里出现 avc: denied 的报错。临时验证时可以先用 permissive 模式跑一遍,确认功能正常后再补 sepolicy 规则。具体来说就是看 dmesg 和 logcat 里的 avc 信息,对应到 sepolicy 的 te 文件里补 allow 规则。

接入之后,验证做得对不对,最直接的方式是:

adb shell getprop | grep rild adb shell ps -A | grep rild

再看 logcat -b radio 的日志。如果 rild 一直在重启,说明要么库路径不对,要么 SELinux 拦截,顺着日志查就行。这里有个容易忽略的小细节:替换 RIL 库之后,最好清一下 /data 分区里的老 RIL 缓存数据,否则有时候 Modem 状态同步会有诡异的问题。开发阶段可以直接 adb shell wipe data 或者 fastboot -w,一了百了。

6. 编译产出、镜像打包与烧录验证

6.1 编译产物在哪

全编成功之后,主要产物都在 out/target/product/t527/ 目录下。你需要的核心东西是这些:

  • boot.img:内核 + 设备树 + ramdisk,负责系统启动第一段。
  • system.img:Android Framework、系统应用、系统库。
  • vendor.img:厂商私有库、HAL、不开源组件。全志的很多硬件能力都在这里。
  • dtbo.img:设备树 overlay,某些平台会单独存放多个 DTB。
  • vbmeta.img、boot0.img、uboot.img 这些是启动链相关的东西,烧录时要留意对应关系。

不同方案的命名可能略有不同,但大同小异。全志 SDK 一般会提供一个打包脚本或者 mkimage 工具,把 out 目录下这些零散镜像打包成可以直接烧录的整包固件。脚本通常在 device/config 目录下或者 SDK 根目录。

6.2 打包与烧录

看脚本内容之前,先检查一个常见问题:打包脚本里写的路径是不是和你实际输出的方案名一致。之前见过有人 lunch 选了 full_t527-eng,但打包脚本默认指向另一个具体子配置(比如 t527_xxx-eng),结果每次打包出来的镜像都是空的或者旧的。这种坑很隐蔽,因为脚本不报错,它只是打包了另一个目录下的空产物。

烧录这块,全志官方常用的烧录工具是 PhoneixSuit 或者烧写卡工具,支持 USB 烧录和 TF 卡量产烧录。第一次开发调试阶段,我建议直接用 fastboot 分区烧录,速度和灵活性都更好:

adb reboot bootloader fastboot flash boot out/target/product/t527/boot.img fastboot flash system out/target/product/t527/system.img fastboot flash vendor out/target/product/t527/vendor.img fastboot reboot

如果你改动了设备树、要验证内核修改,boot 分区一定要烧。如果只是 Framework 层改动,烧 system 分区就够。速度上比整包烧录快得多,也方便反复调试。

整套流程走通一次之后,你会发现 T527_Android13 编译这件事本身并不复杂,真正致命的是那些“带节奏”的细节:JDK 版本、磁盘余量、并行数、资源清理。我个人的体会是,Android 13 这套构建系统的容错率比老版本低了不少,一旦环境不对,报错方式千奇百怪,很容易把你往错误的方向带。所以每次开工之前,我都习惯先花十分钟检查环境,把磁盘、内存、JDK、分支状态都确认一遍,再开始编译。这十分钟看起来是浪费时间,实际上能避免你在错误环境里空转一整天。

最后补一句实战经验:第一次全编之前,一定要先确认自己的 repo 仓库是完全干净的,用 git status 在各个仓库里扫一遍,确认没有本地修改残留,尤其是 device、hardware、vendor 这几个目录。全志的构建系统在某些步骤会直接对源文件做 patch 或者生成临时文件,如果你带着半年前的本地补丁去全编,失败之后排查问题的难度会成倍上升。等你能稳定通过第一次全编,后面的各种定制和优化,就只是时间问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询