内容简介:有几个Go的程序需要放在树莓派上跑,由于树莓派的性能是在太差、编译工具版本又低,想想还是在其他设备上编译好可执行文件直接拿来用方便,毕竟无需依赖的静态编译是Go的亮点嘛。Go对交叉编译的支持是极好的:对于没有使用CGO的程序,只需要通过设置$CGO_ENABLED、$GOOS、$GOARCH参数即可轻松地实现跨平台编译;对于使用CGO的程序,大部分情况可以通过配置$CC参数使用自行准备的交叉编译工具进行编译。
有几个 Go 的程序需要放在树莓派上跑,由于树莓派的性能是在太差、编译 工具 版本又低,想想还是在其他设备上编译好可执行文件直接拿来用方便,毕竟无需依赖的静态编译是Go的亮点嘛。
Go对交叉编译的支持是极好的:对于没有使用CGO的程序,只需要通过设置$CGO_ENABLED、$GOOS、$GOARCH参数即可轻松地实现跨平台编译;对于使用CGO的程序,大部分情况可以通过配置$CC参数使用自行准备的交叉编译工具进行编译。
下面以macOS为例,简单记录一下过程中踩的坑吧
不使用CGO的交叉编译
I. 一般做法
在macOS编译 Linux 和Windows的arm可执行程序:
CGO_ENABLED=0 GOOS=linux GOARCH=arm go build main.go CGO_ENABLED=0 GOOS=windows GOARCH=arm go build main.go
其中:
- $CGO_ENABLED:0表示关闭CGO
- $GOOS:目标平台(编译后要运行的目标平台)的操作系统(darwin、freebsd、linux、windows)
- $GOARCH:目标平台(编译后要运行的目标平台)的体系架构(386、amd64、arm)分别对应(32位、64位、ARM平台)的架构
树莓派属于ARM平台,对于编译给ARM使用的Go程序,需要根据实际情况配置$GOARM,这是用来控制CPU的浮点协处理器的参数。$GOARM默认是6,对于不支持VFP使用软件运算的老版本ARM平台要设置成5,支持VFPv1的设置成6,支持VFPv3的设置成7,详细说明如下:
GOARM=5: use software floating point; when CPU doesn't have VFP co-processor GOARM=6: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported) GOARM=7: use VFPv3; usually Cortex-A cores
综上,给跑着linux的老版本树莓派编译Go程序的命令为:
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build main.go
II. 关于协处理器
协处理器是协助CPU完成其无法执行或执行效率、效果低下的处理工作而开发和应用的处理器。
这种CPU无法执行的专项工作有很多,比如设备间的信号传输、接入设备的管理等;执行效率、效果低下的有图形处理、声频处理等。为了进行这些专项处理,各种辅助处理器就诞生了。现在的计算机构架(x86、amd64)中,整数运算器与浮点运算器已经集成在一起,一般来讲因此浮点处理器内建于CPU中的协处理器,不算是辅助处理器,不过ARM架构因为低功耗的原因是个例外。
ARM架构中的VFP coprocessor是典型的协处理器,它提供浮点数基本运算(加、减、乘、除、开方、比较、取反)以及向量(vectors)功能,一般来讲,VFP可以同时支持最多8组单精度4组双精度浮点数的运算。
简单地说,使用协处理器可以能好地协助CPU发挥出性能,可以粗暴地认为是一种硬件加速。
使用CGO的交叉编译
III. 什么是CGO
C语言经过数十年发展,各个方面的开源代码、闭源库已经非常丰富。这对于一门现代编程语言而言,如何用好现成的C代码就显得极为重要,CGO就是一个令人惊异的技术,它允许Go与C的类库交互操作,让Go能够使用 C语言 积累的各种资源。
CGO作为Go中使用C语言代码的一种方式,在获得好处的同时就必定得有付出,这是亘古不变之理:由于CGO相当于使用了C语言,所以编译使用CGO部分的代码就必须按C语言路子来,而C语言原生的跨平台支持相对Go来说可是差远了,使得使用CGO后要编译跨平台的可执行文件就麻烦多了。
目前解决CGO跨平台编译问题的思路有:
IV. 用目标平台的工具链进行交叉编译
以树莓派的ARM平台为例,用ARM GNU Linux工具链,编译使用了CGO的Go项目。
macOS的文件系统默认是大小写不敏感的,而交叉编译工具链是基于大小写敏感的文件系统的,所以应当新建一个大小写敏感的磁盘镜像用于安放ARM GNU Linux工具链。打开Disk Utility,然后 File>New Image>Blank Image,然后在弹出窗口中设置名称为armx(名称自定),大小大于512MB,格式为Mac OS Extended的映像。
下载 或者 按说明 自行编译ARM GNU Linux工具链。
假设工具链包已经在~/Download目录中,解压缩工具链到到新建的磁盘镜像中:
tar -zxv -C /Volumes/armx/ --strip-components 1 -f ~/Download/ARMx-2009q3-67.tar.bz2
现在,你就已经能够直接使用ARM工具链了,比如要编译main.c程序,可以在终端执行:
/Volumes/Armx/bin/arm-none-linux-gnueabi-gcc main.c -o main
就可以获得一个名为main的可执行程序,这个程序在macOS是不能运行的,只能在ARM平台设备上的Linux系统中才能执行。
好了,现在开始编译用了CGO的Go程序给树莓派用吧:
CGO_ENABLED=1 GOOS=linux GOARCH=arm CC=/Volumes/Armx/bin/arm-none-linux-gnueabi-gcc GOARM=5 go build -x main.go
其中$CC参数指定的是ARM工具链位置,如果不出意外的话,编译完成后就可以得到可以在树莓派上运行的Go程序了。
如果使用Beego提供的bee工具进行编译和打包,效果也是一样的的。
CGO_ENABLED=1 GOOS=linux GOARCH=arm CC=/Volumes/Armx/bin/arm-none-linux-gnueabi-gcc GOARM=5 ~/go/bin/bee pack main.go
交叉编译过程中如果出现错误,多半是因为使用CGO部分的代码,在不同的平台存在不兼容的问题,需要根据错误提示逐项解决。
V. 用原生代码重写CGO实现的功能
这一小节是废话,用原生Go代码重写之后问题划归成了第一类,也就不存在CGO的问题了。
以上所述就是小编给大家介绍的《交叉编译Go程序》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First HTML and CSS
Elisabeth Robson、Eric Freeman / O'Reilly Media / 2012-9-8 / USD 39.99
Tired of reading HTML books that only make sense after you're an expert? Then it's about time you picked up Head First HTML and really learned HTML. You want to learn HTML so you can finally create th......一起来看看 《Head First HTML and CSS》 这本书的介绍吧!