0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深入解析RK平台编译核心:build.sh的知识点、调试技巧与开发价值

jf_44130326 来源:Linux1024 2026-02-03 16:02 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

瑞芯微RKLinux SDK开发中,build.sh是整个编译构建系统的入口中枢”——它统一管理环境配置、命令解析、模块构建与日志输出,几乎所有芯片(如RK3588RV1126)的固件编译、内核构建、根文件系统定制都依赖它启动。

本文将从核心知识点拆解调试关键关注点开发实践意义三个维度,带你吃透build.sh,并通过流程图可视化其执行逻辑。读完本文你将掌握:

1.build.sh的核心模块与工作原理

2.调试时如何通过build.sh定位问题;

3.掌握build.shRK平台开发的效率提升点;

4.可视化理解RK编译系统的核心执行流程。

wKgZO2kamkCAYd1YAADG-3jVIdk814.png

一、build.sh核心知识点:拆解编译系统的骨架

build.sh本质是一个Bash脚本,但集成了RK编译系统的大脑逻辑——从环境初始化到命令执行,每一步都围绕标准化、可扩展、易调试设计。我们按功能模块拆解其核心知识点:

1.环境初始化:为编译搭好舞台

setup_environments()函数是编译的地基,它通过导出全局环境变量,统一SDK各模块的路径与配置,避免因路径混乱导致的编译失败。核心变量及作用如下:

环境变量

作用说明

关键值示例

RK_SDK_DIR

SDK根目录(最核心路径)

/home/user/rk3588_linux

RK_OUTDIR

编译输出目录(固件、日志、配置存这里)

$RK_SDK_DIR/output

RK_LOG_DIR

日志存储目录(按session隔离)

$RK_OUTDIR/sessions/2024-05-20_14-30-00

RK_CHIPS_DIR

多芯片配置目录(管理RK3588/RV1126等)

$RK_SDK_DIR/device/rockchip/.chips

RK_CONFIG

编译配置文件(存储SDK关键配置)

$RK_OUTDIR/.config

RK_BUILD_HOOK_DIR

构建钩子脚本目录(实现模块解耦)

build-hooks

此外,check_sdk()函数会验证SDK完整性(如检查scripts目录路径是否正确),并检测是否在sudo环境下运行——避免因权限问题导致的文件读写失败。

2.命令解析:理解输入执行的逻辑

build.sh支持丰富的命令(如kernelcleanalldefconfig:rk3588_defconfig),其解析逻辑是先分类、再验证、后执行

1)命令分类:按功能划分为4大阶段

通过parse_scripts()解析RK_PARSED_CMDS配置,将命令分为初始化、预编译、编译、后编译4类,确保执行顺序不混乱:

初始化阶段(INIT:如chip:rk3588(选择芯片)、defconfig:rockchip_defconfig(加载默认配置);

预编译阶段(PRE-BUILD:如menuconfig(修改内核配置)、kernel-config(定制内核);

编译阶段(BUILD:如kernel(编译内核)、buildroot-make(编译根文件系统);

后编译阶段(POST-BUILD:如pack(打包固件)、post-rootfs(根文件系统后处理)。

2)特殊命令处理

从代码和--help输出(文档2)中,可提炼高频特殊命令:

清理命令cleanall(清理所有编译产物)、clean-kernel(仅清理内核,需对应mk-kernel.sh);

交互命令shell(进入编译环境shell)、edit-parts(交互修改分区表);

芯片/配置命令rk3588:rockchip_defconfig(一键选择芯片+加载配置,等价于chip:rk3588 defconfig:rockchip_defconfig)。

3)选项验证:避免无效命令

option_check()函数会校验输入命令是否在支持列表中(如CMDS="$RK_INIT_CMDS $RK_PRE_BUILD_CMDS..."),若输入./build.sh xxx(无效命令),会触发usage打印帮助信息,降低开发误操作。

3.钩子机制:实现模块化解耦

RK编译系统支持多模块(内核、BuildrootWiFi/BT)协同,核心靠run_build_hooks()实现的钩子脚本机制——将不同模块的编译逻辑拆分为独立.sh脚本,通过目录优先级控制执行顺序:

执行顺序:芯片专属钩子(RK_CHIP_DIR/build-hooks)优先于通用钩子(RK_COMMON_DIR/build-hooks),适配不同芯片的定制化需求(如RV1126需特殊工具链,RK3588无需);

钩子阶段:对应编译全流程,每个阶段执行对应钩子脚本:

init:初始化配置(如创建输出目录);

pre-build:预编译准备(如下载子模块、校验依赖);

build:核心编译(如内核、根文件系统构建);

post-build:固件打包(如生成update.img)。

例如,编译内核时,build-hooks/build/kernel.sh会被调用,无需在build.sh中硬编码内核编译逻辑,便于后续维护与扩展。

4.日志与错误处理:调试的导航灯

build.sh的日志与错误处理设计,是定位问题的关键,核心包含3部分:

1)分级日志:颜色+类型区分重要性

通过rk_log()函数定义5级日志,终端输出时带颜色标识,便于快速识别信息类型:

wKgZO2kamkCAIrDmAAAelB3RiPs387.png

日志函数

颜色代码

作用场景

示例

message

36(浅蓝)

通信息(如日志路径)

message "Log saved at /xxx"

notice

35(紫色)

重要提示(如SDK版本)

notice "Version: linux-5.10-rkr12"

warning

34(深蓝)

警告(如无效session

warning "Session is invalid!"

error

91(浅红)

错误(如缺工具链)

error "No prebuilt GCC!"

fatal

31(深红)

致命错误(如SDK损坏)

fatal "SDK corrupted!"

2)日志归档:按session隔离,保留历史

start_log()函数会为每个命令生成独立日志文件(如build_2024-05-20_14-30-00.log),并软链接到$RK_LOG_DIR/build.log方便查看;同时自动清理旧日志(保留最新10个),避免磁盘占用过大。

3)错误捕捉:打印调用栈,精准定位

通过trap 'err_handler' ERRbuild.sh会捕捉所有脚本执行错误(返回码非0),并调用err_handler()打印:

错误返回码、出错行号、出错命令;

完整调用栈(如build.sh: main(100) → run_build_hooks(50) → mk-kernel.sh: build(20));

例如,内核编译失败时,日志会明确显示mk-kernel.sh的第20行执行make失败,无需逐行排查脚本。

5.工具链与内核版本:适配多平台的关键

build.sh通过两个核心函数,解决多芯片、多架构的适配问题:

get_toolchain():自动选择工具链。如X86_64主机编译RK3588AArch64架构)时,会从prebuilts/gcc目录找aarch64-linux-gnu-gccRV1126则使用定制工具链rockchip830

kernel_version():检测内核版本。优先从内核目录名(如kernel-5.10)提取,若目录名不标准,则解析kernel/MakefileVERSIONPATCHLEVEL(如VERSION=5PATCHLEVEL=10版本5.10)。

二、调试时关注build.sh:快速定位问题的钥匙

开发中遇到编译失败(如内核编译报错、固件打包缺失),build.sh的日志、环境变量、错误信息是最直接的调试依据。以下是4个核心关注项:

1.优先看日志:所有执行细节都在RK_LOG_DIR

build.sh的日志是问题字典,调试时第一步要找到日志目录(启动时会打印Log saved at $RK_LOG_DIR),重点看3类文件:

阶段日志:如init.log(初始化阶段)、build.log(编译阶段),记录钩子脚本的执行输出,若某钩子失败(如kernel.sh),会在这里显示具体错误(如make: *** No rule to make target 'Image');

环境变量日志initial.env(初始环境)、final.env(最终环境),对比两者可排查是否有环境变量被意外覆盖(如RK_KERNEL_VERSION是否正确);

后处理日志:若执行post-rootfspost-rootfs.log会记录根文件系统的修改(如新增/删除的文件)。

2.错误时看调用栈:定位出错的脚本与行号

build.sh打印fatal "ERROR: Running ... failed!"时,下方会输出调用栈,例如:

fatal "ERROR: call stack:"

fatal " build.sh: run_build_hooks(250)"

fatal " build.sh: main(300)"

fatal " mk-kernel.sh: build(20)"

这表明:main函数调用run_build_hooks,后者执行mk-kernel.shbuild函数时,在第20行出错。直接打开mk-kernel.sh20行,即可快速定位问题(如make命令参数错误)。

3.验证命令与模块:确保命令合法、模块存在

若执行./build.sh clean-xxx报错,需检查:

命令是否合法:clean-xxx对应的模块脚本是否存在(如clean-kernelmk-kernel.sh,且脚本中含clean_hook函数);

芯片配置是否正确:若执行./build.sh rk3588:xxx,需确认RK_CHIPS_DIR/rk3588目录存在,且defconfigrk3588的配置列表中(参考文档2defconfig available列表)。

4.检查工具链与依赖:避免缺工具导致的失败

若日志中出现error "No prebuilt GCC toolchain for $MODULE!",需通过get_toolchain的逻辑排查:

架构是否匹配:如编译AArch64内核,工具链是否为aarch64-linux-gnu-

工具链目录是否存在:检查$RK_SDK_DIR/prebuilts/gcc/linux-x86/aarch64是否有对应的gcc二进制文件;

特殊芯片适配:如RV1126需确认RK_CHIP_FAMILY是否设为rv1126_rv1109(确保加载定制工具链)。

三、掌握build.sh的开发意义:效率与标准化的双重提升

build.sh不仅是编译入口,更是RK平台开发的效率引擎,其核心价值体现在3个方面:

1.标准化构建流程:减少环境不一致问题

在多人协作或多设备开发中,最头疼的是我这能编译,他那编译失败build.sh通过:

统一环境变量(如RK_SDK_DIR固定SDK根路径);

自动加载配置(load_configRK_CONFIG读取关键参数);

标准化钩子执行(不同模块按阶段执行,避免顺序混乱);

确保所有开发者使用同一份规则编译,大幅减少因环境差异导致的问题。

2.灵活扩展:适配定制化需求

RK平台开发常需定制(如新增分区、修改内核配置、集成自定义驱动),build.sh的设计让扩展更简单:

新增模块:只需在build-hooks目录下添加xxx.sh,实现对应阶段的钩子函数(如build函数),即可通过./build.sh xxx调用;

定制芯片:在RK_CHIPS_DIR下新增芯片目录(如rk3599),添加对应的mk-*.sh脚本,即可支持该芯片的编译;

修改分区:通过mod-partsedit-parts命令,无需手动修改分区表文件,交互即可完成分区增删改(参考文档2partition相关命令)。

3.自动化支持:集成CI/CD,提升迭代效率

build.sh的命令行接口(如./build.sh rk3588 kernel buildroot pack)可直接集成到CI/CD流程(如JenkinsGitLab CI),实现:

代码提交后自动编译,及时发现编译错误;

自动生成固件和日志,无需人工干预;

多芯片并行编译(如同时构建RK3588RV1126的固件)。

四、build.sh核心执行流程:可视化理解

为更直观掌握build.sh的工作逻辑,我们用流程图(基于Mermaid)展示从启动到执行完成的核心步骤:

wKgZO2kamkCABR86AAGrAWm5V3A982.png

总结:build.shRK开发的入门钥匙

build.sh作为RK平台编译系统的核心入口,不仅承担命令分发的角色,更通过标准化环境、模块化钩子、详细日志,解决了多芯片适配、多模块协作、调试效率低等关键问题。

对于开发者而言:

新手掌握它,能快速上手RK编译流程,减少踩坑时间;

老手吃透它,能灵活扩展编译功能(如新增模块、定制流程),提升开发效率;

调试时依赖它,能通过日志和调用栈快速定位问题,避免无头苍蝇式排查。

掌握build.sh,就掌握了RK平台开发的主动权”——无论是日常编译、问题调试,还是定制化开发,都能游刃有余。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    88

    文章

    11854

    浏览量

    219828
  • 调试
    +关注

    关注

    7

    文章

    655

    浏览量

    36059
  • 瑞芯微
    +关注

    关注

    27

    文章

    901

    浏览量

    54735
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何让OpenHarmony编译速度“狂飙”

    OpenHarmony 有两种编译方式,一种是通过 hb 工具编译,一种是通过 build.sh 脚本编译。本文笔者将提升 build.sh
    的头像 发表于 02-14 09:31 2921次阅读

    鸿蒙OpenHarmony【轻量系统 编译】 (基于Hi3861开发板)

    OpenHarmony支持hb和build.sh两种编译方式。此处介绍hb方式,build.sh脚本编译方式请参考[使用build.sh脚本
    的头像 发表于 05-14 17:53 2853次阅读
    鸿蒙OpenHarmony【轻量系统 <b class='flag-5'>编译</b>】 (基于Hi3861<b class='flag-5'>开发</b>板)

    鸿蒙OpenHarmony【小型系统 编译】(基于Hi3516开发板)

    OpenHarmony支持hb和build.sh两种编译方式。此处介绍hb方式,build.sh脚本编译方式请参考[使用build.sh脚本
    的头像 发表于 05-10 15:59 1682次阅读
    鸿蒙OpenHarmony【小型系统 <b class='flag-5'>编译</b>】(基于Hi3516<b class='flag-5'>开发</b>板)

    鸿蒙ArkUI-X框架开发:【编译

    使用build.sh编译脚本进行编译编译脚本常用选项
    的头像 发表于 05-25 16:42 2687次阅读
    鸿蒙ArkUI-X框架<b class='flag-5'>开发</b>:【<b class='flag-5'>编译</b>】

    迅为RK3568开发板篇OpenHarmony实操HDF驱动配置LED-编译源码

    重新编译 Openharmony4.1 源码,如下所示: ./build.sh --product-name rk3568 --ccache 或者单独编译部件 ./
    发表于 02-10 10:23

    rk3588 SDk 编译报错 执行./build.sh buildroot

    -hooks/30-rootfs.sh - build_buildroot failed! ERROR: exit code 1 from line 16: \"RK_SCRIPTS_DIR/mk-buildroot.
    发表于 03-12 09:55

    使用build.sh脚本编译时出现错误该怎么办

    直接使用build.sh脚本一起编译的时候出现下面的错误:百度了一下 make distclean 后再编译还是报错,有没有技术支持帮忙看一下这个问题咋解决fakeroot: preload
    发表于 01-04 07:55

    ._build.sh 失败怎么解决?

    make distclean,后面再./build.sh的话,很容易出现上述问题(我这边出现3次了),那不是说,只要小改一代码,都很可能要makedistclean,再来一遍,这个时间,长。。。
    发表于 01-05 06:17

    build.sh失败该怎样去解决呢

    make distclean,后面再./build.sh的话,很容易出现上述问题(我这边出现3次了),那不是说,只要小改一代码,都很可能要makedistclean,再来一遍,这个时间,长。。。
    发表于 01-13 08:48

    ROC-RK3308主板CC固件编译知识点解析,绝对实用

    ROC-RK3308主板CC固件编译知识点解析,绝对实用
    发表于 03-09 07:29

    【飞凌RK3588开发板试用】源码编译

    编译前配置在 device/forlinux/rk3588/目录下,有不同板型的配置文件。选择配置文件进行编译:$./build.sh
    发表于 03-28 22:32

    toybrick_RK3568X开发板:瑞芯微 SDK 编译 android 过程

    toybrick_RK3568X开发编译android 命令如下: source build/envsetup.sh lunch
    发表于 11-17 23:40

    鸿蒙OpenHarmony【标准系统 编译】(基于RK3568开发板)

    OpenHarmony支持hb和build.sh两种编译方式。此处介绍hb方式,build.sh脚本编译方式请参考[使用build.sh脚本
    的头像 发表于 05-08 17:37 3280次阅读
    鸿蒙OpenHarmony【标准系统 <b class='flag-5'>编译</b>】(基于<b class='flag-5'>RK</b>3568<b class='flag-5'>开发</b>板)

    基于RK3576开发板的多路网络摄像头取流方案

    环境。接着,通过编译脚本build.sh进行例程编译,并运行示例程序。方案设计包含四大逻辑模块:启动、取流解码、算法分析和显示逻辑,相关代码均位于指定目录中。开发指南详细介绍了Tool
    的头像 发表于 05-13 11:14 2062次阅读
    基于<b class='flag-5'>RK</b>3576<b class='flag-5'>开发</b>板的多路网络摄像头取流方案

    深入解析U-Boot命令处理核心文件:功能、调试开发价值

    在嵌入式系统开发中,U-Boot 作为主流的引导加载程序,其命令处理、交互逻辑和自动启动流程是核心功能模块。本文将围绕command.c、cli.c和autoboot.c三个关键文件,从核心知识点
    的头像 发表于 02-03 15:44 1076次阅读
    <b class='flag-5'>深入</b><b class='flag-5'>解析</b>U-Boot命令处理<b class='flag-5'>核心</b>文件:功能、<b class='flag-5'>调试</b>与<b class='flag-5'>开发价值</b>