内容简介:有几个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程序》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
从界面到网络空间
(美)海姆 / 金吾伦/刘钢 / 上海科技教育出版社 / 2000-7 / 16.40元
计算机急剧改变了20世纪的生活。今天,我们凭借遍及全球的计算机网络加速了过去以广播、报纸和电视形式进行的交流。思想风驰电掣般在全球翻飞。仅在角落中潜伏着已完善的虚拟实在。在虚拟实在吕,我们能将自己沉浸于感官模拟,不仅对现实世界,也对假想世界。当我们开始在真实世界与虚拟世界之间转换时,迈克尔·海姆问,我们对实在的感觉如何改变?在〈从界面到网络空间〉中,海姆探讨了这一问题,以及信息时代其他哲学问题。他......一起来看看 《从界面到网络空间》 这本书的介绍吧!