使用yocto配方构建go项目时ABI不匹配

使用yocto配方构建go项目时ABI不匹配,go,yocto,abi,mismatch,recipe,Go,Yocto,Abi,Mismatch,Recipe,我正试图编写一个Yocto配方,为x86_64目标平台(rocko分支)构建一个Go-lang项目。我的yocto配方可以很好地构建Go项目,使用dep工具解决依赖关系。但是构建的二进制文件不能在目标平台上运行。尝试在目标上执行时,出现以下错误: $ /usr/bin/mybin abi mismatch detected between the executable and libstd.so fatal error: abi mismatch runtime: panic before ma

我正试图编写一个Yocto配方,为x86_64目标平台(rocko分支)构建一个Go-lang项目。我的yocto配方可以很好地构建Go项目,使用
dep
工具解决依赖关系。但是构建的二进制文件不能在目标平台上运行。尝试在目标上执行时,出现以下错误:

$ /usr/bin/mybin
abi mismatch detected between the executable and libstd.so
fatal error: abi mismatch
runtime: panic before malloc heap initialized
这是我构建项目的自定义配方:

GO_IMPORT = "bitbucket.org/xxx/myproject"
SRC_URI = "git://${GO_IMPORT}/protocol=http;user=${GIT_USER}:${GIT_PASS};destsuffix=${PN}-${PV}/src/${GO_IMPORT}"
SRCREV = "7777ee7777777c9777774bb777780777759d777771777"

CGO_ENABLED = "0"

inherit go

do_compile_prepend() {
    rm -f ${WORKDIR}/build/src/${GO_IMPORT}/Gopkg.toml
    rm -f ${WORKDIR}/build/src/${GO_IMPORT}/Gopkg.lock
    cd ${WORKDIR}/build/src/${GO_IMPORT}
    dep init
    dep ensure
}

do_install_append() {
    rm -f ${D}/usr/bin/dep
}

deltask do_compile_ptest_base
deltask do_compile_ptest

DEPENDS = "go-dep-native mercurial-native"

INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
INHIBIT_PACKAGE_STRIP = "1"

RDEPENDS_${PN}-staticdev += "bash"
RDEPENDS_${PN}-dev += "bash"

管理此问题的正确方法是什么?

我可以提供有关此问题的更多信息:

$ ldd /usr/bin/mybin
    linux-vdso.so.1 (0x00007ffe321d9000)
    libstd.so => /usr/lib/go/pkg/linux_amd64_dynlink/libstd.so (0x00007f95463d7000)
    libc.so.6 => /lib/libc.so.6 (0x0000003436200000)
    libdl.so.2 => /lib/libdl.so.2 (0x0000003436a00000)
    libpthread.so.0 => /lib/libpthread.so.0 (0x0000003436600000)
    /lib/ld-linux-x86-64.so.2 (0x0000003435e00000)

$ file /usr/bin/mybin
/usr/bin/mybin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=0103acf63634df77e600eb114bf59977462ca51d, with debug_info, not stripped

$ file /usr/lib/go/pkg/linux_amd64_dynlink/libstd.so
/usr/lib/go/pkg/linux_amd64_dynlink/libstd.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=2d2f135b2f9eab19a7ceff1923820bf635e10eb1, with debug_info, not stripped
问题似乎与生成动态库libstd.so(由GO_DYNLINK控制)有关。该库的生成由poky/meta/recipes devtools/go/go-runtime.inc上定义的源代码片段管理:

do_compile() {
    export GOBIN="${B}/bin"
    export CC="${@d.getVar('BUILD_CC').strip()}"
    rm -rf ${GOBIN} ${B}/pkg
    mkdir ${GOBIN}
    cd src
    ./make.bash --host-only
    cp ${B}/pkg/tool/${BUILD_GOTUPLE}/go_bootstrap ${B}
    rm -rf ${B}/pkg/${TARGET_GOTUPLE}
    ./make.bash --target-only
    if [ -n "${GO_DYNLINK}" ]; then
        cp ${B}/go_bootstrap ${B}/pkg/tool/${BUILD_GOTUPLE}
        GO_FLAGS="-buildmode=shared" GO_LDFLAGS="-extldflags \"${LDFLAGS}\"" ./make.bash --target-only
    fi
    cd ${B}
}
我做了一个测试,在评论了这个条件之后:

    # if [ -n "${GO_DYNLINK}" ]; then
    #    cp ${B}/go_bootstrap ${B}/pkg/tool/${BUILD_GOTUPLE}
    #    GO_FLAGS="-buildmode=shared" GO_LDFLAGS="-extldflags \"${LDFLAGS}\"" ./make.bash --target-only
    # fi
我的配方生成一个工作的
mybin
链接为静态

所以,在提供了所有这些信息之后,我有更多的问题:从我的自定义配方中设置这个变量GO_DYNLINK的正确方法是什么?因为我尝试过用不同的方式设置它:

GO_DYNLINK=""
unset GO_DYNLINK
GO_DYNLINK="0"

它们都不起作用(同样是ABI不匹配问题)。谢谢!!:)

好的,所以我找到了一个更好的方法来防止这个问题,也找到了更多关于核心问题的信息

更好的解决方案

在配方中添加以下行:

GO\u LINKSHARED=”“

这将阻止
-builmdmode=shared
,并执行正常的go构建,而不是针对标准库进行链接。有趣的是,通过删除到标准库的链接,我只增加了100KB的双字节大小和
libstd。所以
是30MB

核心问题


核心问题是,当您使用默认的
shared
buildmode时,当您构建go二进制文件时,您还将在另一个rpm包中构建go运行时
libstd.do
。理论上,如果目标具有相同的运行库版本,则无需再次安装运行库。然而,情况似乎并非如此。Go散列它放入
libstd
的所有包定义,然后散列这些散列以创建ABI散列。同一go版本的
libstd.so
的两个实例应该具有相同的哈希,因为它们具有相同的函数,但情况似乎并非如此。我在yocto的bug追踪器上写了一份技术性更强的bug报告

这些值在
goarch.bbclass
中硬编码。我发现解决这个问题的唯一方法是制作一个
go-runtime\%.bbappend
文件并复制您的
do\u compile
函数版本。它可以按照建议工作。非常感谢利亚姆·凯利先生!:-)非常好的错误修复。谢谢!我读了bug报告,它包含了非常有价值的信息。希望很快就能修好。非常感谢您花时间调查这个问题,利亚姆·凯利先生!:-)我遇到了非常奇怪的SIGSEGV问题,使用poky的sumo分支和go 1.10.3——针对armv6(raspberrypi0 wifi目标)设置的交叉编译
go_LINKSHARED=“”
完全解决了这个问题。谢谢