Yocto平台下基于SCons构建系统的C++应用交叉编译链接错误排查
问题:Yocto平台下SCons构建项目链接阶段缺失crt文件与libmvec.so.1
问题背景
在Yocto平台上编译一个基于C/C++开发、采用SCons构建系统的应用项目,编写了Recipe复用已有SCons构建代码,从Yocto侧导出了LIBPATH、CPPFLAGS、CPPPATH等环境变量(包含SYSROOT路径以提供标准头文件和库)。编译过程正常,但链接阶段报错,提示无法找到crti.o、crtbeginS.o以及/usr/lib/libmvec.so.1文件。
错误信息
| x86_64-agl-linux-g++ -o variant_debug/BaseTools/libCXLBaseTools.so -shared variant_debug/BaseTools/src/gtIAllocationFailureObserver.os variant_debug/BaseTools/src/gtIAssertionFailureHandler.os variant_debug/BaseTools/src/gtErrorString.os variant_debug/BaseTools/src/gtList.os variant_debug/BaseTools/src/gtSingeltonsDelete.os variant_debug/BaseTools/src/gtStringTokenizer.os -L/home/agl-embedded/agl_native/build/tmp/work/corei7-64-agl-linux/tools/1.0-r0/recipe-sysroot/usr/lib -L/home/agl-embedded/agl_native/build/tmp/work/corei7-64-agl-linux/tools/1.0-r0/recipe-sysroot/usr/lib/x86_64-agl-linux/11.4.0 -L/home/agl-embedded/agl_native/external/poky/meta/recipes-devtools/tools/Tools/Profiler/Output_x86_64/debug/bin | /home/agl-embedded/agl_native/build/tmp/work/corei7-64-agl-linux/tools/1.0-r0/recipe-sysroot-native/usr/bin/x86_64-agl-linux/../../libexec/x86_64-agl-linux/gcc/x86_64-agl-linux/11.4.0/ld: cannot find crti.o: No such file or directory | /home/agl-embedded/agl_native/build/tmp/work/corei7-64-agl-linux/tools/1.0-r0/recipe-sysroot-native/usr/bin/x86_64-agl-linux/../../libexec/x86_64-agl-linux/gcc/x86_64-agl-linux/11.4.0/ld: cannot find crtbeginS.o: No such file or directory | /home/agl-embedded/agl_native/build/tmp/work/corei7-64-agl-linux/tools/1.0-r0/recipe-sysroot-native/usr/bin/x86_64-agl-linux/../../libexec/x86_64-agl-linux/gcc/x86_64-agl-linux/11.4.0/ld: cannot find /usr/lib/libmvec.so.1: No such file or directory | collect2: error: ld returned 1 exit status | scons: *** [variant_debug/BaseTools/libCXLBaseTools.so] Error 1 | scons: building terminated because of errors. | *** ERROR during the build of this subcomponent ***
当前配置
Recipe文件内容
DESCRIPTION = "Build Project" LICENSE = "CLOSED" SRC_URI = "file://project.tar.gz" inherit scons do_compile:prepend() { export SYSROOT="${STAGING_DIR_TARGET}" export LDFLAGS="${LDFLAGS}" export CFLAGS="${CFLAGS}" } do_compile() { ~/agl_native/external/poky/meta/recipes-devtools/tools/Tools/Profiler/Build/Linux/./build.sh dbg }
SConstruct修改内容
sysroot_path = os.environ.get('SYSROOT', '') env.Append(CPPPATH=[ sysroot_path + '/usr/include', sysroot_path + '/usr/include/c++/11.4.0', sysroot_path + '/usr/include/c++/11.4.0/x86_64-agl-linux', ]) env.Append(LIBPATH=[ sysroot_path + '/usr/lib', sysroot_path + '/usr/lib/x86_64-agl-linux/11.4.0', ])
问题根源分析
- crt文件路径遗漏:crti.o、crtbeginS.o属于GCC运行时启动文件,通常位于
${SYSROOT}/usr/lib/x86_64-agl-linux目录(不带版本号的架构主目录),当前LIBPATH仅添加了带版本号的子目录,导致链接器找不到这些文件。 - sysroot参数未生效:链接器直接查找宿主机的
/usr/lib/libmvec.so.1而非Yocto目标sysroot下的对应文件,说明链接时未正确传递--sysroot参数,导致路径解析错误。 - 交叉编译环境传递不完整:自定义的
do_compile直接调用外部build.sh,未让SCons完全继承Yocto提供的交叉编译工具链变量(如CC、CXX、LD),导致链接器未按交叉编译规则运行。
解决方案
方案1:完善Recipe的环境变量传递
删除do_compile:prepend,修改do_compile确保传递完整的交叉编译环境,强制链接器使用sysroot:
do_compile() { export CC="${BUILD_CC}" export CXX="${BUILD_CXX}" export LD="${BUILD_LD}" export CPPFLAGS="${CPPFLAGS}" export LDFLAGS="${LDFLAGS} --sysroot=${STAGING_DIR_TARGET}" ~/agl_native/external/poky/meta/recipes-devtools/tools/Tools/Profiler/Build/Linux/build.sh dbg }
方案2:补充SConstruct中的路径与参数
在SConstruct中添加crt文件所在目录,并给链接器指定sysroot参数:
sysroot_path = os.environ.get('SYSROOT', '') # 给链接器添加sysroot参数 env.Append(LINKFLAGS=['--sysroot=' + sysroot_path]) # 补充crt文件所在的架构主目录 env.Append(LIBPATH=[ sysroot_path + '/usr/lib', sysroot_path + '/usr/lib/x86_64-agl-linux', sysroot_path + '/usr/lib/x86_64-agl-linux/11.4.0', ])
方案3:确保依赖包安装
libmvec.so.1属于glibc组件,在Recipe中添加依赖以确保目标sysroot包含该库:
DEPENDS += "glibc"
验证步骤
- 清理旧构建产物:
bitbake -c cleansstate <你的Recipe名称> - 重新构建:
bitbake <你的Recipe名称> - 检查链接命令是否包含
--sysroot参数,且LIBPATH包含了完整的架构库目录。
内容的提问来源于stack exchange,提问作者user3576216
相关产品推荐
相关产品推荐

