golang交叉编译

1. 交叉编译与golang的编译器架构

  golang是一门跨平台的编译型语言, 其支持交叉编译(across-compiling). 所谓的交叉编译就是在平台A上使用编译器产生能够在平台B上运行的目标代码.

交叉编译常见于嵌入式开发与代码移植(transplant)中, 即在linux平台上编译arm平台的目标代码. 个人认为这样做的原因是arm开发板各种硬件都过于mini, 无法运行一个完整开发环境.

go的编译系统由gccgo前端(源码地址: https://github.com/golang/gofrontend)与gcc的后端组成. gccgo将go源码转化为中间表示IR, gcc再将IR转换为目标代码. 所以gcc后端具体执行代码的编译, 优化的步骤.

这种前端对应语言, 后端对应平台架构, 中间通过IR这个桥梁连接的编译器架构使得编译器开发大大简化. golang编译器开发中只需开发go语言前端, 再复用gcc后端. 著名的编译器框架LLVM

就使用了就采用了这种架构, 其best practice => clang. clang将c/c++源码转换为LLVM IR之后, 具体工作就交由llvm后端去做了.

 

2. golang交叉编译参数

  两个最重要的交叉编译参数: $GOARCH, $GOOS.

  这两个参数都是go的内置环境变量, 具体含义见(官方文档: https://golang.org/cmd/go/).

  $GOOS控制目标代码的系统, 典型的有linux, windows, darwin.

  $GOARCH控制目标代码的架构, 典型的有amd64, i386, arm64, arm.

  两者共同控制了目标代码的平台, 典型的平台有linux on amd64, linux on arm64(即嵌入式/android), darwin on amd64(即MacOS)

 

3. 编译实战

  源码如下:

package main                                                                                                                                                                                 

import (
  "fmt"
)

func main() {
  fmt.Println("hello world!")
}

a. linux on amd64

$ GOOS=linux GOARCH=amd64 go build -o main_linux_amd64

 由于开发环境就是linux on amd64, 所以GOOS与GOARCH的默认值就是linux与amd64.

go env|egrep -e 'GOOS|GOARCH'

 

也就是说, 目标代码的平台默认就是开发环境的平台.

 

b. windows on amd64

$ GOOS=windows GOARCH=amd64 go build -o main_win_amd64

  在linux上可编译出直接运行于windows上的代码. 这给了我一点启发, 在linux上搭建GUI开发环境显然是十分麻烦的, CLI开发效率又太低. 

那就可以在windows或mac上进行go服务器端开发, release时进行交叉编译, 部署, 测试即可.

  go的跨平台性简直可以与java相媲美. 对于java来说每次修改源码之后都要重新编译生成字节码.

对于go来说, 每次修改源码之后同样要重新编译, 只是交叉编译参数的问题. 但是go相比于其在c系家族的"兄弟"

c/c++来说跨平台性大大提高. 跨平台的c代码中都要封装大量平台相关的宏(marco)与类型重命名(typedef).

移植c/c++代码远比移植go代码来的复杂, 尤其是在异构架构间移植 , 如amd64到arm64.

 

c. linux on arm64

$ GOOS=linux GOARCH=arm64 go build -o main_linux_arm64

  在linux上可编译出直接运行于arm上的代码, 这仿佛对c的"独立王国"嵌入式领域造成了一定的威胁.

就我个人观点, 只要嵌入式设备的内存能够放得下go的运行时(1~2M)加上主体代码(最多10M左右), 蚕食嵌入式开发中c的地盘也是很有可能的(go嵌入式实战: https://blog.csdn.net/yyz_1987/article/details/87714058).

  另外还可以通过剔除(strip)符号表来减小go可执行文件的大小. 可以看到未剔除符号的可执行文件大小为2.1M, 其中大部分为运行时库, 剔除符号后估计大小为1.5M甚至更小.

5G出现之后, 物联网IoT将会加速发展, 市场对嵌入式开发的需求将会越来越大. 希望go也能乘此快车而壮大.

  go亦能开发Android程序, golang官方称之为gomobile(官方文档: https://godoc.org/golang.org/x/mobile). 传统的Android开发中, 开发人员调用java api进行开发, java代码底层使用JNI调用NDK接口.

而go直接调用NDK接口. 效率固然是go高, 但是目前go生态孱弱, 不及java九牛之一毛. 并且google将gomobile作为实验性(experimental)内容. tip! 目前Android的官方开发语言是kotlin, 一种可与java兼容的JVM语言.

 

d. wasm on js

  wasm即Web assembly, 是一种为了替换在计算密集型场景中js代码的虚拟机语言, 可由任意语言开发.

由于go的运行时太大, 估计不会成为主流.

转载于:https://www.cnblogs.com/thepog/p/11052437.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值