Yocto文件系统覆盖Linux系统文件?IMX6Q平台自定义Task未执行求助
问题分析与解决方案
首先说下你的do_mytask没被调用的核心原因:
- 你的自定义task属于helloworld应用recipe,但
do_rootfs是image recipe(比如你用的core-image-xxx类镜像)的任务,两者属于不同的构建上下文,addtask after do_rootfs没法让镜像的任务链触发这个应用recipe里的task。 - 应用recipe的默认任务链(fetch、unpack、compile、install、package等)在
do_rootfs之前就已经执行完毕了,你的自定义task不在这个默认链里,也没有被镜像任务依赖,所以根本不会被触发。 - 退一步说,就算task被执行了,你修改的
${D}目录是应用recipe的临时安装目录,此时已经过了打包阶段,这些修改也不会同步到最终的根文件系统里。
下面给你几个更靠谱的实现方式,按推荐程度排序:
方法一:通过do_install直接安装文件(最符合Yocto规范)
既然你已经有了helloworld的recipe,直接把需要覆盖的文件通过do_install安装到系统,再通过FILES_${PN}把这些文件包含到包中,Yocto会自动把它们打包并放到根文件系统里。修改你的recipe如下:
# This file was derived from the 'Hello World!' example recipe in the Yocto Project Development Manual. SUMMARY = "Simple helloworld application" SECTION = "examples" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" SRC_URI = "file://helloworld.c" # 添加需要的文件到SRC_URI FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += " \ file://interfaces \ file://issue \ file://mytest.sh \ " S = "${WORKDIR}" do_compile() { ${CC} helloworld.c -o helloworld } do_install() { # 原来的helloworld安装逻辑 install -d ${D}${bindir} install -m 0755 helloworld ${D}${bindir} # 新增安装自定义文件 # 安装interfaces install -d ${D}/etc/network install -m 0644 ${WORKDIR}/interfaces ${D}/etc/network/interfaces # 安装issue install -m 0644 ${WORKDIR}/issue ${D}/etc/issue # 安装mytest.sh并设置执行权限 install -d ${D}/home/root install -m 0755 ${WORKDIR}/mytest.sh ${D}/home/root/mytest.sh } # 告诉Yocto这些额外的文件属于当前包,否则不会被打包 FILES_${PN} += " \ /etc/network/interfaces \ /etc/issue \ /home/root/mytest.sh \ "
修改后,只要你的helloworld被包含到镜像里(比如在local.conf加IMAGE_INSTALL:append = " helloworld"),这些文件就会自动出现在最终的根文件系统中,完全不需要自定义task。
方法二:在Image Recipe中添加后处理Task
如果你确实需要在do_rootfs完成后修改根文件系统(比如修改系统级配置,不需要包管理),可以通过bbappend扩展你的镜像recipe:
- 在你的自定义层中创建
recipes-core/images/core-image-base.bbappend(替换成你实际用的镜像名称) - 在bbappend中添加如下内容:
FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += " \ file://interfaces \ file://issue \ file://mytest.sh \ " # 添加自定义task,紧跟在do_rootfs之后,do_image之前 addtask custom_rootfs_mod after do_rootfs before do_image do_custom_rootfs_mod() { # ${IMAGE_ROOTFS}是do_rootfs生成的根文件系统目录 install -d ${IMAGE_ROOTFS}/etc/network cp -af ${WORKDIR}/interfaces ${IMAGE_ROOTFS}/etc/network/interfaces cp -af ${WORKDIR}/issue ${IMAGE_ROOTFS}/etc/issue cp -af ${WORKDIR}/mytest.sh ${IMAGE_ROOTFS}/home/root/mytest.sh # 给脚本加执行权限 chmod 0755 ${IMAGE_ROOTFS}/home/root/mytest.sh }
这种方式直接修改根文件系统的最终目录,所有后续的镜像生成都会用修改后的内容。
方法三:用ROOTFS_POSTPROCESS_COMMAND快速修改
如果只是临时调试或者快速修改,可以在local.conf中添加根文件系统后处理命令:
# 替换成你的文件所在路径 MY_FILES_DIR = "/path/to/your/custom/files" ROOTFS_POSTPROCESS_COMMAND += "custom_rootfs_mod;" custom_rootfs_mod() { install -d ${IMAGE_ROOTFS}/etc/network cp -af ${MY_FILES_DIR}/interfaces ${IMAGE_ROOTFS}/etc/network/interfaces cp -af ${MY_FILES_DIR}/issue ${IMAGE_ROOTFS}/etc/issue cp -af ${MY_FILES_DIR}/mytest.sh ${IMAGE_ROOTFS}/home/root/mytest.sh chmod 0755 ${IMAGE_ROOTFS}/home/root/mytest.sh }
这种方式最简单,但缺点是配置分散在local.conf,不如recipe方式便于管理和版本控制。
内容的提问来源于stack exchange,提问作者dev j
相关产品推荐
相关产品推荐

