Golang交叉编译中使用libpcap库

Golang交叉编译中使用libpcap链接库

之前提到的一个流量统计与可视化程序,有人提到希望有arm的版本,我想这go交叉编译还是挺简单的

结果遇到了挺大一个坑——纯Go程序交叉编译是很简单,加上环境变量

1
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build

基本就可以进行编译了。

但是我这个程序有一个很大的特点——使用的gopacket用了libpcap这个C语言库,所以需要开启CGO来进行编译,还需要安装c语言对应的交叉编译器。

apt install gcc-aarch64-linux-gnu 之后尝试使用 CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=aarch64-linux-gnu-gcc go build 结果报错:

1
2
3
# github.com/google/gopacket/pcap
/usr/lib/gcc-cross/aarch64-linux-gnu/8/../../../../aarch64-linux-gnu/bin/ld: cannot find -lpcap
collect2: error: ld returned 1 exit status

看来是链接时出错了——libpcap也得先编译目标系统架构的版本。 以arm64为例

1
2
3
4
5
6
7
8
cd /tmp
export PCAPV=1.10.1
wget http://www.tcpdump.org/release/libpcap-$PCAPV.tar.gz
tar -zxvf libpcap-$PCAPV.tar.gz
cd libpcap-$PCAPV
export CC=aarch64-linux-gnu-gcc
./configure --host=aarch64-linux --with-pcap=linux
make #记得装flex bison 删除多余的manifest和syso文件

之后再交叉编译我们的程序 在github action中 CGO_LDFLAGS不要用相对路径!! 因为这个坑折腾了很久。

1
CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CGO_LDFLAGS="-L/tmp/libpcap-$PCAPV" go build .

在我的项目中,交叉编译Linux版本的程序时出现了报错: /tmp/go-link-644965070/000000.o: file not recognized: file format not recognized 最后发现,是因为我用于设置windows管理员权限运行的syso文件也参与了编译过程,在编译linux版本的程序的时候将该syso文件删除即可。

关于syso的作用: 添加程序描述、图标、管理员权限运行等

如果编译目标架构为32位arm时,操作如下

1
2
3
apt-get install gcc-arm-linux-gnueabi
export CC=arm-linux-gnueabi-gcc
./configure --host=arm-linux --with-pcap=linux

另外我还遇到了运行时提示No such file的报错,原因是找不到动态链接库,大概是没装libpcap-dev,为了避免这种情况的发生,可以改用静态链接的方式,在 CGO_LDFLAGS 里面加上 -static 参数。之后使用者就不需要再安装libpcap了,(windows下怎么静态链接我还没搞清楚)。

参考

https://studygolang.com/articles/14376

https://github.com/google/gopacket/issues/100

https://holmesian.org/golang-cross-compile

https://chai2010.cn/advanced-go-programming-book/ch2-cgo/ch2-09-static-shared-lib.html

https://developer.aliyun.com/article/12223

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
本站访客数:
使用 Hugo 构建
主题 StackJimmy 设计