在BitBake任务中修改EXTRA_OECMAKE生成差异二进制文件的方案咨询
解决方案(Yocto Kirkstone)
针对同一个配方生成两个仅CMake配置不同的二进制文件且避免重复代码的需求,推荐以下两种方案:
方案一:动态任务切换(无需新建配方/复制cmake_do_configure)
通过Python任务函数动态切换构建目录和CMake变量,复用cmake.bbclass原有任务逻辑,步骤如下:
- 在配方中定义额外构建目录与临时安装目录:
B_extra = "${WORKDIR}/build-extra" TEMP_INSTALL_EXTRA = "${WORKDIR}/temp-install-extra"
- 添加自定义configure/compile/install任务,动态修改参数并复用CMake原生任务:
python do_configure_extra() { import bb.build # 保存原始参数 orig_build_dir = d.getVar("B") orig_cmake_opts = d.getVar("EXTRA_OECMAKE") # 切换到额外构建目录,追加自定义CMake选项 d.setVar("B", d.getVar("B_extra")) d.setVar("EXTRA_OECMAKE", f"{orig_cmake_opts} -DCUSTOM_FEATURE=ON") # 调用原CMake配置任务 bb.build.exec_func("cmake_do_configure", d) # 恢复原始参数 d.setVar("B", orig_build_dir) d.setVar("EXTRA_OECMAKE", orig_cmake_opts) } python do_compile_extra() { import bb.build orig_build_dir = d.getVar("B") d.setVar("B", d.getVar("B_extra")) bb.build.exec_func("cmake_do_compile", d) d.setVar("B", orig_build_dir) } python do_install_extra() { import bb.build import bb.utils orig_build_dir = d.getVar("B") orig_install_dir = d.getVar("D") # 切换到额外构建目录,指定临时安装路径 d.setVar("B", d.getVar("B_extra")) d.setVar("D", d.getVar("TEMP_INSTALL_EXTRA")) # 执行安装 bb.build.exec_func("cmake_do_install", d) # 将额外二进制重命名后复制到主安装目录 bb.utils.mkdirhier(f"{orig_install_dir}/usr/bin") bb.utils.copyfile( f"{d.getVar('TEMP_INSTALL_EXTRA')}/usr/bin/${BPN}", f"{orig_install_dir}/usr/bin/${BPN}_extra" ) # 恢复原始参数 d.setVar("B", orig_build_dir) d.setVar("D", orig_install_dir) }
- 配置任务依赖顺序:
addtask configure_extra after do_configure before do_compile_extra addtask compile_extra after do_compile before do_install_extra addtask install_extra after do_install before do_package
- 追加清理逻辑,确保额外构建目录被清理:
python do_clean_append() { import os import shutil b_extra = d.getVar("B_extra") temp_install = d.getVar("TEMP_INSTALL_EXTRA") for path in [b_extra, temp_install]: if os.path.exists(path): shutil.rmtree(path) }
此方案通过复用原CMake任务逻辑,避免了复制cmake_do_configure代码,同时无需新建配方。
方案二:.inc通用化配方(长期维护优先方案)
如果追求清晰的代码结构与可维护性,推荐将通用逻辑抽离到.inc文件,再创建两个极简配方分别继承并设置不同CMake选项:
- 创建
mypackage.inc,包含所有通用配置:
SUMMARY = "My package" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://LICENSE;md5=xxx" SRC_URI = "git://example.com/mypackage.git;branch=main" SRCREV = "abcdef123456" S = "${WORKDIR}/git" # 通用EXTRA_OECMAKE配置 EXTRA_OECMAKE = " \ -DBASIC_OPTION=ON \ "
- 创建
mypackage.bb,编译默认版本:
require mypackage.inc
- 创建
mypackage-extra.bb,编译带额外选项的版本:
require mypackage.inc EXTRA_OECMAKE_append = " -DCUSTOM_FEATURE=ON" # 重命名二进制避免冲突 FILES:${PN} += "/usr/bin/${BPN}_extra" do_install_append() { mv ${D}/usr/bin/${BPN} ${D}/usr/bin/${BPN}_extra }
最后在local.conf中同时添加两个配方到IMAGE_INSTALL即可。
方案对比
- 方案一适合快速实现,无需新增配方文件,但任务逻辑相对复杂;
- 方案二更符合Yocto最佳实践,代码结构清晰,便于后续维护,是长期项目的优先选择。
内容的提问来源于stack exchange,提问作者Paiusco
相关产品推荐
相关产品推荐

