4、编译环境初始化:envsetup.sh脚本解析、lunch命令与产品选择、编译类型(user/userdebug/eng)区别
好,我们直接进入正题。编译环境初始化,这是你每次编译车机系统都要做的第一步。说白了,就是告诉系统:「我要干活了,给我准备好工具和配置」。
我个人习惯,每天到工位第一件事就是打开终端,执行 source build/envsetup.sh。这个动作就像给电脑一个「开机信号」,没有它,后面所有编译命令都跑不起来。
4.1 envsetup.sh 脚本到底干了什么?
这个脚本,我刚开始接触时觉得它很神秘。后来我把它拆开看过,其实没那么玄乎。它主要做了三件事:
- 注册一堆命令:比如
lunch、m、mm、mma这些你以后天天用的命令,都是它帮你注册到 shell 里的。 - 设置环境变量:像
ANDROID_BUILD_TOP、ANDROID_PRODUCT_OUT这些路径变量,它会自动帮你配好。 - 加载编译函数:很多编译逻辑被封装成了 shell 函数,比如
add_lunch_combo就是用来注册可选的产品组合的。
核心要点:source 这个命令不能省。如果你直接敲 ./envsetup.sh,那这些环境变量只在子进程里生效,退出就没了。必须用 source 让它影响当前 shell。
我记得有一次,一个新同事编译不过,跑来找我。我一看,他用的就是 ./envsetup.sh。我说:「你试试前面加个 source」。他试完,编译就通了。嗯,这种坑我踩过,所以印象特别深。
4.2 lunch 命令与产品选择
执行完 envsetup.sh 之后,下一步就是 lunch。这个命令说白了就是让你选「你要编译哪个产品、哪个版本」。
你直接敲 lunch 不带参数,它会列出一堆选项给你选:
You're building on Linux
Lunch menu... pick a combo:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_x86_64-eng
4. aosp_car_x86_64-userdebug
5. car_platform-userdebug
...
你想想看,车机系统里,我们最常用的是哪个?我个人经验,car_platform-userdebug 是出现频率最高的。因为车机需要调试,但又不能完全用 eng 版本那么「裸」。
你也可以直接指定参数:
lunch car_platform-userdebug
这样一步到位,省得每次都要从菜单里选。我写了个别名在 .bashrc 里,每天上班直接 lunch car 就完事了。
小技巧:lunch 之后,你可以用 echo $TARGET_PRODUCT 和 echo $TARGET_BUILD_VARIANT 来确认当前选中的产品和编译类型。我经常用这招来检查自己有没有选错。
4.3 编译类型:user / userdebug / eng 的区别
这个知识点,我见过太多人搞混了。其实它们三个的区别,说白了就是「权限」和「调试能力」的差异。
| 编译类型 | adb root | ro.debuggable | 适用场景 |
|---|---|---|---|
| user | 不支持 | 0 | 正式发布版本 |
| userdebug | 支持 | 1 | 开发调试阶段 |
| eng | 支持 | 1 | 工程师内部开发 |
我来逐个说说:
user 类型
这是给最终用户用的。adb root 被禁掉了,很多调试接口也关了。你想想看,如果用户拿到车机,随便 adb root 进去改系统文件,那还得了?所以 user 版本是「锁死」的。
我曾经在项目交付前,客户要求必须用 user 版本做路测。结果有个 bug 只能在 user 版本上复现,userdebug 上跑得好好的。那几天我真是头大,最后发现是 user 版本里某个 SELinux 策略更严格,把正常流程给拦了。
userdebug 类型
这是我们的「主力军」。它既有 user 版本的安全性(大部分权限控制还在),又保留了 adb root 的能力。说白了,就是「可以调试的发布版本」。
我建议,日常开发、集成测试,都用 userdebug。它最接近真实用户环境,又能让你随时抓 log、改东西。
eng 类型
这个版本,嗯,怎么说呢,它是「完全开放」的。所有调试开关都打开,很多安全检查也绕过了。编译出来的镜像也最大,因为里面塞了很多调试工具。
eng 版本我一般只在两种情况下用:
- 刚拿到一个新平台,要做 bring-up
- 需要调试底层驱动,比如 HAL 层、kernel 层的问题
注意:千万不要把 eng 版本刷到用户的车上!我见过有人图省事,直接把 eng 版本给了客户,结果客户发现可以随便 root,安全性完全失控。这个锅,背不起。
4.4 实战中的选择建议
说了这么多,我总结一下我的经验:
- 日常开发:用
userdebug。这是最平衡的选择。 - 系统集成测试:用
userdebug或user。如果测试用例需要 root 权限,就用 userdebug。 - 正式发布:必须用
user。这是底线。 - 底层调试:用
eng。但记得调试完就切回去。
你可能会问:「那我能不能在 user 版本上开 adb root?」嗯,技术上可以改一些配置,但我不建议这么做。因为一旦你改了,这个版本就不再是真正的 user 版本了,安全性打了折扣。与其这样,不如直接用 userdebug。
好了,编译环境初始化这部分就讲到这里。下一章我们会真正开始执行编译,看看 make 命令背后到底发生了什么。到时候你会发现,前面这些准备工作,其实都是在给编译系统「铺路」。