次のコード スニペットをコンパイルすると (プレイグラウンド リンク):
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(archlinuxarm.orgからArchを実行しているARMv7)で動作しますが、
- 私の Raspberry Pi B+ (raspberrypi.org の Raspbian を実行している ARMv6) では動作しません。
Piで実行すると、「Segmentation fault
」が表示されます。
これらの環境変数で実行すると:
LD_PRELOAD=/lib/arm-linux-gnueabihf/libSegFault.so
SEGFAULT_USE_ALTSTACK=1
私はこの出力を得る:
*** Segmentation fault
Register dump:
R0: 00000000 R1: 00000001 R2: bebf37f4 R3: bebf37fc
R4: 00000000 R5: 00000000 R6: 00010c59 R7: 00000000
R8: 00000000 R9: 00000000 SL: b6f33000 FP: 00000000
IP: 0000004f SP: bebf37ec LR: 00010c6b PC: 0005d7f4
CPSR: 40000030
Trap: 0000000e Error: 00000817 OldMask: 00000000
Addr: 00000001
Backtrace:
Memory map:
00010000-00125000 r-xp 00000000 b3:02 16193 /home/pi/test
00135000-0013b000 rw-p 00115000 b3:02 16193 /home/pi/test
0013b000-0014a000 rw-p 00000000 00:00 0
0026b000-00290000 rw-p 00000000 00:00 0 [heap]
b6d53000-b6d73000 r-xp 00000000 b3:02 16080 /lib/arm-linux-gnueabihf/libgcc_s.so.1
b6d73000-b6d7a000 ---p 00020000 b3:02 16080 /lib/arm-linux-gnueabihf/libgcc_s.so.1
b6d7a000-b6d7b000 rw-p 0001f000 b3:02 16080 /lib/arm-linux-gnueabihf/libgcc_s.so.1
b6d7b000-b6e9f000 r-xp 00000000 b3:02 4254 /lib/arm-linux-gnueabihf/libc-2.13.so
b6e9f000-b6ea6000 ---p 00124000 b3:02 4254 /lib/arm-linux-gnueabihf/libc-2.13.so
b6ea6000-b6ea8000 r--p 00123000 b3:02 4254 /lib/arm-linux-gnueabihf/libc-2.13.so
b6ea8000-b6ea9000 rw-p 00125000 b3:02 4254 /lib/arm-linux-gnueabihf/libc-2.13.so
b6ea9000-b6eac000 rw-p 00000000 00:00 0
b6eac000-b6ec0000 r-xp 00000000 b3:02 4247 /lib/arm-linux-gnueabihf/libpthread-2.13.so
b6ec0000-b6ec7000 ---p 00014000 b3:02 4247 /lib/arm-linux-gnueabihf/libpthread-2.13.so
b6ec7000-b6ec8000 r--p 00013000 b3:02 4247 /lib/arm-linux-gnueabihf/libpthread-2.13.so
b6ec8000-b6ec9000 rw-p 00014000 b3:02 4247 /lib/arm-linux-gnueabihf/libpthread-2.13.so
b6ec9000-b6ecb000 rw-p 00000000 00:00 0
b6ecb000-b6ee0000 r-xp 00000000 b3:02 44311 /usr/lib/arm-linux-gnueabihf/libbluetooth.so.3.12.0
b6ee0000-b6ee7000 ---p 00015000 b3:02 44311 /usr/lib/arm-linux-gnueabihf/libbluetooth.so.3.12.0
b6ee7000-b6ee8000 r--p 00014000 b3:02 44311 /usr/lib/arm-linux-gnueabihf/libbluetooth.so.3.12.0
b6ee8000-b6eea000 rw-p 00015000 b3:02 44311 /usr/lib/arm-linux-gnueabihf/libbluetooth.so.3.12.0
b6ef8000-b6efa000 r-xp 00000000 b3:02 25761 /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
b6efa000-b6f01000 ---p 00002000 b3:02 25761 /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
b6f01000-b6f02000 rw-p 00001000 b3:02 25761 /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
b6f02000-b6f04000 r-xp 00000000 b3:02 4246 /lib/arm-linux-gnueabihf/libSegFault.so
b6f04000-b6f0b000 ---p 00002000 b3:02 4246 /lib/arm-linux-gnueabihf/libSegFault.so
b6f0b000-b6f0c000 r--p 00001000 b3:02 4246 /lib/arm-linux-gnueabihf/libSegFault.so
b6f0c000-b6f0d000 rw-p 00002000 b3:02 4246 /lib/arm-linux-gnueabihf/libSegFault.so
b6f0d000-b6f2a000 r-xp 00000000 b3:02 4248 /lib/arm-linux-gnueabihf/ld-2.13.so
b6f2e000-b6f32000 rw-p 00000000 00:00 0
b6f32000-b6f33000 r--p 0001d000 b3:02 4248 /lib/arm-linux-gnueabihf/ld-2.13.so
b6f33000-b6f34000 rw-p 0001e000 b3:02 4248 /lib/arm-linux-gnueabihf/ld-2.13.so
bebd3000-bebf4000 rw-p 00000000 00:00 0
bee7f000-bee80000 r-xp 00000000 00:00 0 [sigpage]
ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
Segmentation fault
/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
fromを削除/etc/ld.so.preload
すると、 を含む行がないことを除いて、同じ出力が得られますlibcofi_rpi.so
。
で静的にリンクされたバイナリをビルドしようとすると-tags netgo -a -ldflags "-linkmode external -extldflags -static"
、" Illegal instruction
" ではなく " Segmentation fault
" が表示されます。
Pi 自体でバイナリをビルドしようとしても機能しますが、これをクロスコンパイルしたいと考えています。クロス コンパイルは確かに機能しますが、Raspberry Pi/Raspbian ではなく、ODROID-C1/Arch でのみ機能します。
私が使用する正確なビルド手順は、Docker を使用して再現できます。
$ docker run -it golang:1.4.1-cross bash
ドッカー内で、次を実行します。
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 では実行されません。
私のテストデバイスに関する情報は次のとおりです。
ラズベリーパイ B+:
$ uname -a
Linux raspberrypi 3.18.5+ #744 PREEMPT Fri Jan 30 18:19:07 GMT 2015 armv6l GNU/Linux
$ cat /proc/cpuinfo
processor : 0
model name : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS : 2.00
Features : half thumb fastmult vfp edsp java tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xb76
CPU revision : 7
Hardware : BCM2708
Revision : 0010
Serial : 000000002a69d702
$ ldd test
/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6f01000)
libbluetooth.so.3 => /usr/lib/arm-linux-gnueabihf/libbluetooth.so.3 (0xb6ed4000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6eb5000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6d84000)
/lib/ld-linux-armhf.so.3 (0xb6f0e000)
インストールされている Bluetooth ライブラリ:
$ dpkg -s libbluetooth3
Package: libbluetooth3
Status: install ok installed
Priority: optional
Section: libs
Installed-Size: 172
Maintainer: Debian Bluetooth Maintainers <pkg-bluetooth-maintainers@lists.alioth.debian.org>
Architecture: armhf
Multi-Arch: same
Source: bluez
Version: 4.99-2
Replaces: libsdp2 (<= 1.5-2)
Depends: libc6 (>= 2.13-28)
Pre-Depends: multiarch-support
Conflicts: libsdp2 (<= 1.5-2)
Description: Library to use the BlueZ Linux Bluetooth stack
BlueZ is the official Linux Bluetooth protocol stack. It is an Open Source
project distributed under GNU General Public License (GPL).
Homepage: http://www.bluez.org
オドロイド-C1:
$ uname -a
Linux alarm 3.10.66-1-ARCH #1 SMP PREEMPT Wed Jan 28 18:12:35 MST 2015 armv7l GNU/Linux
$ cat /proc/cpuinfo
Processor : ARMv7 Processor rev 1 (v7l)
processor : 0
BogoMIPS : 3.27
processor : 1
BogoMIPS : 3.27
processor : 2
BogoMIPS : 3.27
processor : 3
BogoMIPS : 3.27
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc05
CPU revision : 1
Hardware : ODROIDC
Revision : 000a
Serial : 1b00000000000000
$ ldd test
libbluetooth.so.3 => /usr/lib/libbluetooth.so.3 (0xb6eaf000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0xb6e87000)
libc.so.6 => /usr/lib/libc.so.6 (0xb6d48000)
/lib/ld-linux-armhf.so.3 (0xb6ed1000)
インストールされた Bluetooth ライブラリと開発ヘッダー ファイル:
$ pacman -Qe bluez
bluez 5.27-1
Docker ビルド環境
$ uname -a
Linux 094aa2ed34a5 3.18.5-gentoo-tp #1 SMP Fri Feb 6 20:14:55 CET 2015 x86_64 GNU/Linux
インストールされている Bluetooth 開発ヘッダー:
$ dpkg -s libbluetooth-dev:armhf
Package: libbluetooth-dev
Status: install ok installed
Priority: extra
Section: libdevel
Installed-Size: 429
Maintainer: Debian Bluetooth Maintainers <pkg-bluetooth-maintainers@lists.alioth.debian.org>
Architecture: armhf
Source: bluez (5.23-2)
Version: 5.23-2+b1
Replaces: libsdp2-dev (<= 1.5.2)
Provides: libbluetooth3-dev
Depends: libbluetooth3 (= 5.23-2+b1), libc6-dev | libc-dev
Suggests: pkg-config
Conflicts: bluez-pan, libbluetooth-dev, libsdp2-dev (<= 1.5.2)
Description: Development files for using the BlueZ Linux Bluetooth library
BlueZ is the official Linux Bluetooth protocol stack. It is an Open Source
project distributed under GNU General Public License (GPL).
Homepage: http://www.bluez.org
libbluetooth-dev
Pi で利用可能なバージョンとまったく同じバージョンの を Docker コンテナーにインストールしても、違いはありません。
libbluetooth.so
Jessie から Wheeziに新しいものをコピーすると、次のエラーが表示されます。
./test: /lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.15' not found (required by /home/pi/libbluetooth.so.3.17.11)
アップデート:
Pi で Arch を試してみたところ、クロス コンパイルされたバイナリでも segfault が発生し、同じメッセージ (" Illegal instruction (core dumped)
") がGOARM=5
,6
または7
.
これまでのところ、Pi の CGO コードをクロスコンパイルする方法を見つけていませんlibbluetooth
。
明日はRaspberry Pi 2でやってみます。