为什么我交叉编译的 CGO 二进制文件不能在 上运行?

当我编译以下代码片段时(playground link):


package main


/*

#cgo LDFLAGS: -lbluetooth


#include <bluetooth/bluetooth.h>

#include <bluetooth/hci.h>

#include <bluetooth/hci_lib.h>

*/

import "C"


func main() {

        C.hci_get_route(nil)

}

...使用这些环境变量:


CC=arm-linux-gnueabihf-gcc

CGO_ENABLED=1

GOARCH=arm

GOARM=6

我得到一个 1.6Mb 的二进制文件:


适用于我的 ODROID-C1(ARMv7,运行 Arch,来自 archlinuxarm.org),但是

不适用于我的 Raspberry Pi B+(ARMv6,运行 Raspbian,来自 raspberrypi.org)。

当我在 Pi 上运行它时,我得到一个“ Segmentation fault”。


当我使用这些环境变量运行它时:


LD_PRELOAD=/lib/arm-linux-gnueabihf/libSegFault.so

SEGFAULT_USE_ALTSTACK=1

删除/usr/lib/arm-linux-gnueabihf/libcofi_rpi.sofrom/etc/ld.so.preload给了我相同的输出,除了没有包含libcofi_rpi.so.


试图构建一个静态链接的二进制文件-tags netgo -a -ldflags "-linkmode external -extldflags -static"给了我一个“ Illegal instruction”而不是“ Segmentation fault”。


尝试在 Pi 本身上构建二进制文件是可行的,但是,我想交叉编译它。交叉编译确实有效,但仅适用于 ODROID-C1/Arch,不适用于 Raspberry Pi/Raspbian。


我使用的确切构建步骤可以使用 Docker 重现:


$ docker run -it golang:1.4.1-cross bash

在 docker 中,我运行:


echo "deb http://emdebian.org/tools/debian/ jessie main" >/etc/apt/sources.list.d/crosstools.list

curl -s http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add -

dpkg --add-architecture armhf

apt-get update

apt-get install -y crossbuild-essential-armhf libbluetooth-dev:armhf

export CC=arm-linux-gnueabihf-gcc

export CGO_ENABLED=1

export GOARCH=arm

export GOARM=6

go build -o test test.go

这给了我一个名为“test”的可执行文件,如上所述,它不会在 Pi 上运行。


qq_笑_17
浏览 220回答 1
1回答

慕田峪4524236

所以让我回答我自己的问题,经过数周的反复试验,得出的结论是…………这根本行不通。作为最后的手段,我尝试采用与编译上述代码时使用的 Raspbian 映像完全相同的 Raspbian 映像,并使用QEMU运行它。猜猜看:我遇到了段错误。相同的指令,使用相同的图像,当我在 Pi 上运行它时,给我一个工作可执行文件,当我模拟 Pi 或尝试以任何方式交叉编译它时,给我一个段错误。最后,这不值得麻烦。我们只是设置了专用的 Pi 来构建我们的项目,而“生产”Pi 只是拉取更新后的二进制文件。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go