如何在Yocto Recipe中为根文件系统/etc下的文件打补丁?
解决Yocto中给rootfs/etc/ssh下文件打补丁的问题
首先得明确:do_patch是用来修补编译前的源代码的,而你要修改的是最终rootfs里的配置文件,所以应该用do_install(或者针对目标recipe的do_install_append)来处理,这是你之前踩坑的核心原因。
下面分两种最靠谱的方案来解决你的问题:
方案一:用独立Recipe处理(你的test_1.0.bb)
如果坚持用自己新建的test recipe,那正确的写法应该是这样:
- 先把要修改的原始文件(比如
sshd_config)放到files目录,同时保留你的sshd.patch。 - 修改
test_1.0.bb内容:
SUMMARY = "Apply custom patch to sshd config" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" # 引入原始配置文件和补丁 SRC_URI = "file://sshd_config \ file://sshd.patch" do_install() { # 先创建目标目录,确保路径存在 install -d ${D}/etc/ssh # 复制原始文件到临时目录,打补丁 cp ${WORKDIR}/sshd_config ${WORKDIR}/sshd_config.patched patch -p0 ${WORKDIR}/sshd_config.patched ${WORKDIR}/sshd.patch # 将打好补丁的文件安装到目标路径,注意权限(sshd_config通常是600) install -m 0600 ${WORKDIR}/sshd_config.patched ${D}/etc/ssh/sshd_config } # 关键!告诉Yocto要把这个文件打包进rootfs FILES:${PN} += "/etc/ssh/sshd_config"
为什么之前的do_install没生效?
大概率是没加FILES:${PN}这一行——Yocto默认只会打包recipe指定的文件,如果你不声明,安装到${D}的文件不会被纳入最终rootfs。
方案二:用bbappend修改openssh Recipe(更规范)
因为/etc/ssh/sshd_config本来是openssh包提供的,直接给openssh加补丁是更符合Yocto分层修改原则的做法:
- 在你的layer里创建
recipes-connectivity/openssh/openssh_%.bbappend文件 - 写入以下内容:
# 引入你的补丁 SRC_URI += "file://sshd.patch" # 在openssh安装完文件后,给sshd_config打补丁 do_install_append() { # 注意补丁的路径和格式,如果你的补丁是针对sshd_config的直接修改,用-p0或-p1根据补丁里的路径调整 patch -p0 ${D}/etc/ssh/sshd_config ${WORKDIR}/sshd.patch }
关键概念区分
do_patch:这个任务是用来修补Recipe的源代码(比如openssh的C语言代码,或者用来生成sshd_config的模板文件sshd_config.in),不是给已经安装到rootfs的文件打补丁的。do_install:负责把编译好的二进制、配置文件等复制到${D}(临时rootfs目录),后续会被打包成最终的rootfs镜像,所以修改配置文件的操作放在这里才对。
调试技巧
如果还是没生效,用这些方法排查:
- 强制重新执行install任务:
bitbake test -c install -f(如果是方案二就用bitbake openssh -c install -f) - 查看任务日志:去
build/tmp/work/<你的机器架构>/test/1.0-r0/temp/下找log.do_install,看patch命令有没有报错(比如文件不存在、补丁不匹配) - 直接查看临时镜像目录:
build/tmp/work/<你的机器架构>/test/1.0-r0/image/etc/ssh/sshd_config,确认文件是否已经被修改
内容的提问来源于stack exchange,提问作者iffi
相关产品推荐
相关产品推荐

