跨平台交叉编译FreeBSD版的Filebeat
交叉编译
Go是一种很好的语言,虽然有很多很坑的方面,但也是有很多突出的优点,比如goroute,以及可以编译成目标指令运行。
最关键的是它的交叉编译真是太方便了……
在任何支持的平台上编译其它平台的目标执行文件,只需要这样一句:
env CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build
其中GOOS可以支持:linux, freebsd, openbsd, macos, windows等,GOARCH支持:i386, amd64, arm。不过因为CGO功能不支持跨平台,所以交叉编译时必须关闭。
之前我有一个需要部署在windows上的程序,就一直是靠着在linux下编译好后再部署到windows上去实现的。
filebeat和FreeBSD
虽然我已经在家里的FreeBSD上装了Docker,可以用docker来跑filebeat,但是还有两台VPS是没条件装Docker的,所以还是需要原生的filebeat去跑,但是官方并没有提供FreeBSD版下载的。
我常常说:Windows是一个善于制造别的系统上不存在的问题的OS。
其实很多时候FreeBSD也是,但相对来说,只要是开源的东西,问题总还是可以解决的。只是麻烦一点而已,需要编译一下罢了。
然而我又不想在家里机器上装个go环境,毕竟能省点事就省点事。那就交叉编译喽,反正手上的Mac正好有现成的go环境。
因为我的环境里,GOPATH被设置为 ~/go
,为了避免编译时找不到module,就直接在这个路径下搞了:
cd ~/go/src/github.com
mkdir elastic
git clone https://github.com/elastic/beats.git
cd beats
git checkout v6.4.1
cd filebeat
env CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 make
等待一会就编译完成了,在当前路径下会生成一个 filebeat
可执行文件,COPY到FreeBSD试试:
filebeat version
# filebeat version 6.4.1 (amd64), libbeat 6.4.1 [37b5f2d2a20f2734b2373a454b4b4cbb2627e841 built 2018-10-22 06:40:03 +0000 UTC]
成功。
2020-02-06 补充
在编译6.8.x时发生了新的问题:
../vendor/github.com/docker/docker/pkg/system/mknod.go:12:22: cannot use dev (type int) as type uint64 in argument to syscall.Mknod
这是../vendor/github.com/docker/docker/pkg/system/mknod.go
文件里的一个BUG,参考FreeBSD的Bug 236131的补丁修改后解决:
- return syscall.Mknod(path, mode, dev)
+ return syscall.Mknod(path, mode, uint64(dev))
类似的问题发生在编译linux arm64
版本时:
../libbeat/common/file/stderr_other.go:30:9: undefined: syscall.Dup2
解决方案来自官方论坛的帖子Cannot make filebeat for aarch64,修改../libbeat/common/file/stderr_other.go
文件:
import (
"os"
- "syscall"
+ "golang.org/x/sys/unix"
)
- return syscall.Dup2(int(toFile.Fd()), 2)
+ return unix.Dup2(int(toFile.Fd()), 2)
成功解决。
推送到[go4pro.org]