You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yocto交叉编译时libc.so链接脚本致modules_prepare失败的解决问询

搭建Yocto交叉编译环境时内核构建工具编译错误的解决方案

问题背景

在Wind River Linux LTS 22(Yocto衍生版本)的SDK中,执行make modules_prepare构建内核主机工具extract-cert时出现以下错误:

/usr/bin/ld: cannot find /lib64/libc.so.6: No such file or directory
/usr/bin/ld: cannot find /usr/lib64/libc_nonshared.a: No such file or directory

对应的构建命令为:

gcc -Wp,-MMD,scripts/.extract-cert.d -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89 -o scripts/extract-cert scripts/extract-cert.c -L/opt/windriver/wrlinux/22.33/sysroots/core2-64-wrs-linux/usr/lib64 -lcrypto

简化测试命令同样失败,移除-L指定的目标sysroot库路径后即可成功。问题根源是目标sysroot下的libc.so并非实际库文件,而是LD链接脚本,内容如下:

/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )

核心问题解答

1. 目标sysroot中libc.so文件的作用

该文件是GNU ld链接脚本,是目标系统C库的标准组件,作用是指导链接器为目标程序组合正确的C库依赖:

  • 优先链接目标系统的动态C库/lib64/libc.so.6
  • 对仅存在于静态C库/usr/lib64/libc_nonshared.a中的函数,自动补充静态链接
  • 指定目标程序运行时的动态链接器/lib64/ld-linux-x86-64.so.2
    它仅用于目标程序的交叉编译,而非主机工具的构建。

2. 避免其干扰内核构建的方法

内核构建中的extract-cert等工具是运行在主机上的程序,应使用主机系统的C库,而非目标sysroot的库。解决方法分为临时和持久化两种:

  • 临时方案:手动删除目标sysroot下的/opt/windriver/wrlinux/22.33/sysroots/core2-64-wrs-linux/usr/lib64/libc.so,但此操作会影响目标程序的交叉编译,仅适合临时测试。
  • 正确方案:构建主机工具时清除目标sysroot库路径的环境变量,执行make modules_prepare前运行:
    make modules_prepare LD_LIBRARY_PATH="" LDFLAGS=""
    
    或者先重置环境变量再执行构建:
    export LD_LIBRARY_PATH=""
    export LDFLAGS=""
    make modules_prepare
    

3. 让Yocto预先准备内核源码,省去modules_prepare步骤

可以实现,通过修改Yocto配置让SDK生成时自动完成内核源码的预处理:

  1. 创建内核配方的append文件(如linux-windriver_%.bbappend),添加以下内容:
    do_install_append() {
        cd ${S}
        # 执行modules_prepare生成必要的构建文件
        make modules_prepare
        # 保存配置文件和符号表到SDK的内核源码目录
        cp .config ${D}${KERNEL_SRC_PATH}/.config
        cp Module.symvers ${D}${KERNEL_SRC_PATH}/Module.symvers
    }
    
  2. 重新生成包含内核源码的SDK:
    bitbake -c populate_sdk <your-image-name>
    
    安装此SDK后,内核源码已完成modules_prepare,可直接构建外部模块。

4. SDK安装后消除libc.so相关错误的持久化方案

若无法预先完成源码准备,可修改SDK的环境配置脚本实现自动环境切换:

  1. 打开SDK安装目录下的environment-setup-core2-64-wrs-linux文件,添加以下函数:
    # 准备内核构建环境,清除目标sysroot库路径影响
    prepare_kernel_build() {
        export ORIG_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
        export ORIG_LDFLAGS=$LDFLAGS
        export LD_LIBRARY_PATH=""
        export LDFLAGS=""
        echo "Kernel build environment prepared. Run 'restore_env' to revert."
    }
    
    # 恢复原交叉编译环境
    restore_env() {
        export LD_LIBRARY_PATH=$ORIG_LD_LIBRARY_PATH
        export LDFLAGS=$ORIG_LDFLAGS
        unset ORIG_LD_LIBRARY_PATH ORIG_LDFLAGS
        echo "Environment restored to cross-compile mode."
    }
    
  2. 使用时,先执行prepare_kernel_build进入内核构建环境,完成构建后执行restore_env恢复交叉编译环境。

内容的提问来源于stack exchange,提问作者penguin359

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:38:17