Golang与Rust交叉编译
Xhofe Lv3

交叉编译

交叉编译一般是指在一个平台上生成另一个平台上的可执行代码,因为有一些目标平台性能很弱,编译需要花费很长的时间,所以需要在性能较高的平台上通过交叉编译来得到目标程序。
在golang和rust中交叉编译都是很容易实现的。

Golang

golang交叉编译一般不需要额外的工具,只需要在golang编译时指定GOOS(操作系统)和GOARCH(CPU架构)即可。
可以使用go tool dist list来查看所有支持的目标平台。
但是如果代码中使用了cgo,那么通常还需要指定一个CC(一般为gcc)来进行编译。
如果目标平台使用glibc库,可以快捷的使用xgo来进行交叉编译。
但是有些目标平台是使用的是musl库,或者是使用其他版本的C库,就需要手动安装交叉编译工具链了。

通过CC指定musl-gcc之后,编译出来的程序就可以在musl库的目标平台下运行了,但是其他版本的C库又不行了,这里要引入一个新的概念,叫做静态编译,即直接将用到的库链接到目标程序中,这样就不在依赖其他的库了。
二进制程序依赖的库可以通过ldd file查看。
在golang中,在ldflags中加入--extldflags '-static -fpic'参数即可开启静态编译,这时使用musl编译出来的二进制文件就可以在所有的目标平台运行了,无论使用的是什么C库。

为什么不直接使用glibc来进行静态编译呢?
直接使用glibc编译出来的二进制文件用ldd查看也是没有依赖的,但是在musl库系统下就是无法运行,我也不知道为什么。

Rust

rust有专门用于交叉编译的库:cross,使用cross build命令直接指定target他就可以工作了。

如果需要手动交叉编译,在rust中进行交叉编译通常比golang中多一步,需要使用rustup target add来添加目标target,同样的所有目标target都可以通过rustup target list来查看。
然后就是和golang一样需要一个gcc,但是有少数时候又不需要,例如在x86_64-unknown-linux-gnu上编译目标平台为x86_64-unknown-linux-muslhello-world程序就不需要安装额外的musl-gcc,至于为什么这样,我也不知道。
另外Rust可能还需要在.cargo/config中添加一个[target.'x86_64-unknown-linux-gnu'.linker = "xxx"]来指定使用的gcc,编译时也需要加入--target host来指定目标平台。

网上很多文章说需要rustup toolchain install,其实是错误的(我认为)

交叉编译工具链下载

参考

  • 本文标题:Golang与Rust交叉编译
  • 本文作者:Xhofe
  • 创建时间:2022-04-08 14:08:00
  • 本文链接:https://nn.ci/posts/go-rust-cross-compile.html
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论