Yocto添加CMake编译共享库到SDK时QA报错及头文件缺失问题
问题根因
两个版本的recipe分别踩了Yocto打包规则的不同坑:
- 第一版recipe同时给主包
${PN}和开发包${PN}-dev配置了${libdir}/*的全量通配规则,导致文件归属混乱:Yocto默认要求无版本号的.so文件必须是指向版本化库的软链接、归开发包存放,实际带版本后缀的共享库实体文件归主包存放。直接把编译生成的无版本号.so实体文件塞进开发包会触发dev-elf报错;同时主包依赖的运行时库被错误划分到开发包,会触发dev-deps报错。 - 第二版recipe虽然修正了库文件的归属规则,但do_install步骤完全没有拷贝项目头文件到标准的
${includedir}路径,开发包的文件匹配规则也没有覆盖头文件实际存放路径,导致头文件不会被打包进SDK。 - 两个版本都手动枚举拷贝编译产物,完全绕开了CMake自带的install逻辑,很容易遗漏文件、搞错文件权限和链接关系。
修正方案
按照Yocto标准打包规则调整recipe即可,不需要强行修改SOLIBS、FILES_SOLIBSDEV这类默认打包配置:
- 优先复用CMake类自带的
cmake_do_install安装逻辑,不要全量手动拷贝编译产物,避免遗漏头文件、搞错库的软链接关系。如果项目本身的CMakeLists.txt没有写全install规则,再手动补装缺失的文件。 - 库文件严格按照规范存放:带版本后缀的共享库实体文件放在主包,无版本号的
.so软链接、头文件放在开发包。 - 去掉通配范围过大的文件匹配规则,精准匹配主包和开发包对应的文件类型,避免文件归属冲突。
可用的修正版recipe
LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" SRC_URI = "gitsm://github.com/xR3b0rn/dbcppp.git;protocol=https;branch=master" PV = "1.0+gitr${SRCPV}" SRCREV = "${AUTOREV}" S = "${WORKDIR}/git" inherit pkgconfig cmake # 保留需要的跳过strip配置,删除破坏默认打包规则的SOLIBS、FILES_SOLIBSDEV配置 INSANE_SKIP:${PN} = "ldflags" INHIBIT_PACKAGE_STRIP = "1" INHIBIT_SYSROOT_STRIP = "1" do_install() { # 先执行CMake预定义的安装步骤,自动安装CMakeLists中配置的二进制、库、头文件 cmake_do_install # 补装CMake规则未覆盖的文件 install -d ${D}${bindir} install -m 0755 ${B}/bin/dbcppp ${D}${bindir} install -d ${D}${libdir} # 安装带版本号的共享库实体文件 install -m 0755 ${B}/third-party/libxml2/libxml2.so.2.9.10 ${D}${libdir} # 为libxml2创建标准层级软链接 ln -sf libxml2.so.2.9.10 ${D}${libdir}/libxml2.so.2 ln -sf libxml2.so.2.9.10 ${D}${libdir}/libxml2.so # 拷贝dbcppp、libxmlmm的所有库文件(保留软链接属性) cp -P ${B}/src/libdbcppp/libdbcppp.so* ${D}${libdir}/ cp -P ${B}/libxmlmm.so* ${D}${libdir}/ # 安装头文件到标准系统头文件路径,供SDK打包 install -d ${D}${includedir} cp -r ${S}/src/libdbcppp/include/* ${D}${includedir}/ cp -r ${S}/third-party/libxmlmm/include/* ${D}${includedir}/ } # 精准配置文件归属:带版本号的so归主包,无版本so软链、头文件归开发包 FILES_${PN} += "${libdir}/lib*.so.*" FILES_${PN}-dev += "${libdir}/lib*.so ${includedir}/*"
验证方法
- 单包编译完成后,检查
${WORKDIR}/packages-split目录:dbcppp主包的lib目录下仅存在带版本后缀的.so实体文件dbcppp-dev包的lib目录下仅存在无版本号的.so软链接,include目录下存在所有需要的开发头文件
- 执行
bitbake -c populate_sdk <你的镜像名>构建SDK,生成的SDK中会自动包含对应库的链接配置和头文件,交叉编译依赖该库的程序时可正常识别依赖。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

