一. 在我们开始问题之前先看下yocto工程中几个重要路径:
配方路径 | 每次添加新的工程配方都需要在这个目录下添加对应的目录和bb文件 | /home/jacky.chen/workspace2/fu740-yocto/meta-sifive/recipes-leapfive/ |
yocto源码路径 | 不同的配方会继承不同的类操作, 比如基于makefile的工程, 或者cmake的工程. 当出现不解之谜的时候可以到下面的python代码去看源码排插 | /home/jacky.chen/workspace2/fu740-yocto/openembedded-core/meta/ |
yocto工程路径 | 工程文件会下载到这个目录下 | /home/jacky.chen/workspace2/fu740-yocto/build/tmp-glibc/work/riscv64-oe-linux |
二. 在配方目录 /home/jacky.chen/workspace2/fu740-yocto/meta-sifive/recipes-leapfive/下面有一个lf-demoapp-sstj工程, 对应到lf-demoapp-sstj_2.0.bb 这个bb文件.
jacky.chen@five:~/yacoto-repo/lf-demoapp-sstj$ cat lf-demoapp-sstj_2.0.bb
SUMMARY = "leapfive sensors service application Demo"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "git://git@192.168.1.25:/NB2/IoT/TianJin/lf_nb2_stategrid_tj.git;branch=v2.0.0;protocol=ssh \
"
#INSANE_SKIP_${PN} = "ldflags"
#INSANE_SKIP_${PN}-dev = "ldflags"
#INSANE_SKIP_${PN} += "dev-deps"
#SRCREV = "${AUTOREV}"
SRCREV = "f5477d7d13e42abbe91c7ac35d6a29fa1824a4c3"
S = "${WORKDIR}/git"
inherit pkgconfig
TARGET_CC_ARCH += "${LDFLAGS}"
EXTRA_OEMAKE = "'CC=${CC}' 'CXX=${CXX}' 'CPP=${CPP}' 'AS=${AS}' 'LD=${LD}' \
'RANLIB=${RANLIB}' 'AR=${AR}' 'BUILDDIR=${S}' 'SYSROOT=${WORKDIR}/recipe-sysroot' \
'CFLAGS=${CFLAGS} -I${S}/. -DWITHOUT_XATTR' "
do_install() {
oe_runmake install DESTDIR=${D} \
BINDIR=${bindir} SBINDIR=${sbindir} LIBDIR=${libdir} LIBEXECDIR=${libexecdir} \
SYSCONFDIR=${sysconfdir} DATADIR=${datadir} MANDIR=${mandir} INCLUDEDIR=${includedir}
# install -d ${D}${libdir}
# install -m 0755 ${D}/opt/lib/* ${D}${libdir}/
# install -d ${D}${includedir}
# install -m 0755 ${D}/opt/include/* ${D}${includedir}/
}
#do_package_qa() {
#
#}
#DEPENDS = "gstreamer1.0 glib-2.0 liblf-common liblf-gstreamer-audio-library liblf-get-wether liblf-baidu-speech-realtime liblf-baidu-speech-tts liblf-system-call curl"
DEPENDS = " curl gnutls util-linux libyaml libmicrohttpd lf-edgex-device-sdk-c"
RDEPENDS_${PN} += " lf-edgex-device-sdk-c-dev"
# priority: ${PN}-src ${PN}-dbg ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN}
#FILES_${PN}-dbg += "/usr/lib/leapfive/debug /usr/lib/leapfivedebug-static /usr/src/leapfive/debug"
#FILES_${PN}-staticdev += "/usr/lib/leapfive/*.a"
#FILES_${PN}-dev += "/opt/"
FILES_${PN} += "/opt/bin/"
# add package.
#PACKAGES =+ "${PN}-examples"
#FILES_${PN}-examples = "${bindir}/*"
jacky.chen@five:~/yacoto-repo/lf-demoapp-sstj$
这个工程在在注释掉下面这行时:
#INSANE_SKIP_${PN} += “dev-deps”
会报错:
Initialising tasks: 100% |#################################################################################################################################################| Time: 0:00:01
Sstate summary: Wanted 5 Found 4 Missed 1 Current 525 (80% match, 99% complete)
NOTE: Executing Tasks
$<50>No currently running tasks (2215 of 2217) 99% |#####################################################################################################################################$<50>Currently 1 running tasks (2215 of 2217) 99% |#####################################################################################################################################$<50>WARNING: lf-demoapp-sstj-2.0-r0 do_package_qa: QA Issue: lf-demoapp-sstj: /opt/bin/.debug/DemoApp is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination [host-user-contaminated]
$<50>WARNING: lf-demoapp-sstj-2.0-r0 do_package_qa: QA Issue: lf-demoapp-sstj: /opt/bin/DemoApp is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination [host-user-contaminated]
$<50>ERROR: lf-demoapp-sstj-2.0-r0 do_package_qa: QA Issue: lf-demoapp-sstj rdepends on lf-edgex-device-sdk-c-dev [dev-deps]
$<50>WARNING: lf-demoapp-sstj-2.0-r0 do_package_qa: QA Issue: lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/example/profile_parse.c is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/example/edgex_device_manage.c is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/example/log.c is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/example/main.c is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/example/ws_sensors.c is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/example/cpu_mem_usage.c is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/example/kuiper_tool/lib-kuiper.c is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/log.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/lf_mod_type.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/parson.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/lf_type.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/iot/component.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/iot/logger.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/iot/data.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/devsdk/devsdk-base.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/edgex/error.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/edgex/edgex-base.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination
lf-demoapp-sstj: /usr/src/debug/lf-demoapp-sstj/2.0-r0/git/Source/include/edgex/devsdk.h is owned by gid 0, which is the same as the user running bitbake. This may be due to host contamination [host-user-contaminated]
$<50>ERROR: lf-demoapp-sstj-2.0-r0 do_package_qa: QA run found fatal errors. Please consider fixing them.
$<50>ERROR: Logfile of failure stored in: /home/jacky.chen/workspace2/fu740-yocto/build/tmp-glibc/work/riscv64-oe-linux/lf-demoapp-sstj/2.0-r0/temp/log.do_package_qa.98971
$<50>ERROR: Task (/home/jacky.chen/workspace2/fu740-yocto/meta-sifive/recipes-leapfive/lf-demoapp-sstj/lf-demoapp-sstj_2.0.bb:do_package_qa) failed with exit code '1'
$<50>NOTE: Tasks Summary: Attempted 2216 tasks of which 2215 didn't need to be rerun and 1 failed.
$<50>NOTE: Writing buildhistory
$<50>No currently running tasks (2215 of 2217) 99% |#####################################################################################################################################$<50>NOTE: Writing buildhistory took: 4 seconds
NOTE: Build completion summary:
NOTE: do_package_qa: 0.0% sstate reuse(0 setscene, 1 scratch)
$<50>
Summary: 1 task failed:
/home/jacky.chen/workspace2/fu740-yocto/meta-sifive/recipes-leapfive/lf-demoapp-sstj/lf-demoapp-sstj_2.0.bb:do_package_qa
Summary: There were 3 WARNING messages shown.
Summary: There were 2 ERROR messages shown, returning a non-zero exit code.
jacky.chen@five:~/workspace2/fu740-yocto/build$
跟进提示的错误log:/home/jacky.chen/workspace2/fu740-yocto/build/tmp-glibc/work/riscv64-oe-linux/lf-demoapp-sstj/2.0-r0/temp/log.do_package_qa.98971
ERROR: QA Issue: lf-demoapp-sstj rdepends on lf-edgex-device-sdk-c-dev [dev-deps]
由于对yocto的理解非常肤浅, 所以不得不去找到它的源码看看到底是个啥子错误. 只是很粗浅地知道是在做质量检查的时候出错了.
到/home/jacky.chen/workspace2/fu740-yocto/openembedded-core/meta/这个目录下, 用grep 找到ERROR: QA Issue:出错的文件
jacky.chen@five:~/workspace2/fu740-yocto/openembedded-core/meta/classes$ grep -rn "QA Issue" ./
Binary file ./.insane.bbclass.swp matches
./insane.bbclass:72: bb.error("QA Issue: %s [%s]" % (error_msg, error_class))
./insane.bbclass:77: bb.warn("QA Issue: %s [%s]" % (error_msg, error_class))
./insane.bbclass:79: bb.note("QA Issue: %s [%s]" % (error_msg, error_class))
jacky.chen@five:~/workspace2/fu740-yocto/openembedded-core/meta/classes$
可以看出来是在insane.bbclass这个文件里面出错.
它的call tree是:
package_qa_handle_error <— package_qa_check_rdepends <----- do_package_qa
通过调试可以知道出错时package_qa_check_rdepends的参数值:
参数 | 实参值 | 注释 |
---|---|---|
package | lf-demoapp-sstj | |
pkgdest | /home/jacky.chen/workspace2/fu740-yocto/build/tmp-glibc/work/riscv64-oe-linux/lf-demoapp-sstj/2.0-r0/packages-split | |
skip | set() | |
taskdeps | {‘python3-native’, ‘acl-native’, ‘flex-native’, ‘ninja-native’, ‘linux-libc-headers’, ‘libxml2-native’, ‘libgcc’, ‘gcc-cross-riscv64’, ‘libgcrypt-native’, ‘file’, ‘readline-native’, ‘bison-native’, ‘libgpg-error-native’, ‘curl-native’, ‘bash-completion’, ‘flex’, ‘gettext-minimal-native’, ‘libidn2’, ‘automake-native’, ‘patch-native’, ‘libgpg-error’, ‘libunistring’, ‘db-native’, ‘gtk-doc-native’, ‘libnsl2-native’, ‘make-native’, ‘bzip2-native’, ‘sqlite3-native’, ‘perl-native’, ‘gettext-native’, ‘attr-native’, ‘gmp-native’, ‘libcap-native’, ‘libyaml’, ‘ncurses’, ‘file-native’, ‘libgcc-initial’, ‘elfutils-native’, ‘xz’, ‘glibc’, ‘libmicrohttpd’, ‘libtool-cross’, ‘libcbor’, ‘libtirpc-native’, ‘gdbm-native’, ‘libxcrypt’, ‘unifdef-native’, ‘re2c-native’, ‘libpcre2-native’, ‘cmake-native’, ‘zlib’, ‘pkgconfig-native’, ‘opkg-utils’, ‘nettle’, ‘gcc-runtime’, ‘texinfo-dummy-native’, ‘gperf-native’, ‘binutils-cross-riscv64’, ‘libcap’, ‘rsync-native’, ‘libtool-native’, ‘xz-native’, ‘cracklib’, ‘libcap-ng’, ‘mpfr-native’, ‘quilt-native’, ‘popt-native’, ‘autoconf-archive-native’, ‘autoconf-native’, ‘lf-edgex-device-sdk-c’, ‘libgcrypt’, ‘curl’, ‘ncurses-native’, ‘cracklib-native’, ‘libcap-ng-native’, ‘rpm-native’, ‘util-linux’, ‘gnu-config-native’, ‘libffi-native’, ‘libpam’, ‘lf-demoapp-sstj’, ‘gmp’, ‘zlib-native’, ‘pseudo-native’, ‘dwarfsrcfiles-native’, ‘m4-native’, ‘gcc-source-10.2.0’, ‘systemd-systemctl-native’, ‘util-linux-native’, ‘openssl-native’, ‘gnutls’, ‘libmpc-native’, ‘bzip2’} | |
packages | {‘lf-demoapp-sstj-doc’, ‘lf-demoapp-sstj’, ‘lf-demoapp-sstj-dev’, ‘lf-demoapp-sstj-dbg’, ‘lf-demoapp-sstj-staticdev’, ‘lf-demoapp-sstj-locale’, ‘lf-demoapp-sstj-src’} | |
d | <bb.data_smart.DataSmart object at 0x7f380c86b320> |
通过擦看package_qa_check_rdepends函数得知它对没有在skip里面申明的选项全部都要做一次依赖性检查. skip从bb文件INSANE_SKIP_${PN}里面获取, 可能的值为:build-deps/dev-deps/file-rdeps等,
skip通过下面的代码获取:
skip = set((d.getVar('INSANE_SKIP') or "").split() +
(d.getVar('INSANE_SKIP_' + package) or "").split())
现在回到我的问题,注释掉 #INSANE_SKIP_${PN} += "dev-deps"这行后, 意味着下面的检查 “dev-deps” not in skip部分为真.
if (not "-dev" in pkg and not "-staticdev" in pkg) and rdepend.endswith("-dev") and "dev-deps" not in skip:
error_msg = "%s rdepends on %s" % (pkg, rdepend)
而lf-demoapp-tjss这个工程的依赖lf-edgex-device-sdk-c的头文件, 也就是lf-edgex-device-sdk-c, 这样rdepend.endswith("-dev")也为真(rdenpend是pkg工程的依赖库, 这里pkg=lf-demoapp-sstj).
上面这行代码的意思是挨个检查packages里面各个包的依赖文件, 当碰到遍历lf-demoapp-sstj这个包的时候, 它的后缀不带-dev和-staticdev, 因此(not “-dev” in pkg and not “-staticdev” in pkg)这个判断为真.
它的依赖库lf-edgex-device-sdk-c-dev包含-dev后缀,因此 rdepend.endswith("-dev")也为真, 然后skip里面没有设置dev-deps. 因此 “dev-deps” not in skip也为真. 所以就看到了报错:
ERROR: QA Issue: lf-demoapp-sstj rdepends on lf-edgex-device-sdk-c-dev [dev-deps]
把#INSANE_SKIP_${PN} += "dev-deps"打开之后, skip就包含dev-deps了, 上面的逻辑就不成立. 因此排查错误成功.
知道了错误原因后可以大概分析出出错的原因: 我的 lf-demoapp-sstj工程在编译之前就把lf-edgex-device-sdk-c这个依赖库的头文件已经包含进去了, 因此编译的时候并不真正需要他的头文件. 在这里yocto帮忙
做了一次检查dev头文件的依赖检查导致出错.
再尝试体会一下下面这行代码的含义
if (not "-dev" in pkg and not "-staticdev" in pkg) and rdepend.endswith("-dev") and "dev-deps" not in skip:
它的意思是 lf-demoapp-sstj的运行依赖是不需要dev的, 因为只有在编译的时候才需要. 如果发现有依赖关系, 需要skip.
后记: 上面的排查过程只能让工程编译通过, 也分析出大体的原因, 但是本人感觉对于yocto的理解还是盲人摸象. 还没有形成体系. 需要不断地学习探索.