再谈Go语言的交叉编译

注意:本文最后更新于 1403 天前,有关的内容可能已经发生变化,请参考使用。

起因

之前有谈到过 Go 语言的交叉编译,虽然七七八八写了一堆,但是实际上的可操作性还是比较差的,当时使用go-ui-crossbuild项目也已经超过3年没有维护了。

golang-docker.jpg

最近从各个方面感受到了 docker 的方便,又恰好有个老项目需要跨平台编译,就顺手看了一下有没有类似 go-ui-crossbuild 的项目,结果才知道我真的是孤陋寡闻,因为不常用 Go,之前连大名鼎鼎的 xgo 项目都没有发现。

关于 xgo

简单地说 xgo 由两部分组成:一部分是一个(或者说一系列)已经预装好交叉编译环境的 docker 镜像;另一部分是 Go 语言编写的 xgo 可执行程序,xgo 通过调用准备好的 docker 镜像解决涉及到 CGO 的交叉编译问题,可达到一键编译多个发行版本或指定版本的效果。

这里先要大概要把我看到的 xgo 经历捋一捋:xgo项目最早是由 karalabe 大佬创建的,虽然几经发展,可是若干年前就没再更新,停滞的版本不支持Go mod,也存在一定的bug; techknowlogick 大佬 Fork 之后持续更新到支持Go mod,并且兼容到了 Go 1.13 ,但是之后也基本停滞了更新。接着 monkeywie 大佬修正了一些问题并且开始用 github actions 构建 docker 镜像。

PS:突然发现这几天 techknowlogick 大佬又开始活跃更新,做了不少修正,并且通过 github actions 实现了自动构建支持最新 golang 版本的 docker 镜像。

github actions 确实是个好东东。

毒打

作为一个小白,自然是要接受社会(网络)的毒打才能成长的。

我的初始需求是在 MacOS 平台上将一个涉及 CGO 的老项目 Go 源码编译出 win64 平台可以运行的可执行文件。

有了对 xgo 的了解自然就高高兴兴地用起来了。然而当我配置好 xgo 环境,在项目根目录满怀希望地运行

    xgo -v --targets=windows-6.1/amd64 . 

之后久久地沉默让我感觉自己遭受了莫名地毒打,还好当我看到形如


    " go: github.com/PuerkitoBio/goquery@v1.6.1: Get https://proxy.golang.org/github.com/%21puerkito%21bio/goquery/@v/v1.6.1.mod: net/http: TLS handshake timeout  " 

字样的提示之后我就明白毒打我的是谁了。 (下载依赖包的时候遭受网络的毒打)

解决

如果是单纯要梯子的问题很容易解决,但是一方面我的现实情况是这个 docker 是跑在 Parallels Desktop 里面虚拟出来的 Ubuntu 上,这个环境有点套娃的意思,哪怕是从外到内的全局也有点烦,另一方面全局出去终究不是长久之计,于是我就想到了在 xgo 的镜像里添加 goproxy 配置来解决,同时也能够方便使用大陆网络的 TX 。

有遇到同样情况的TX可以直接用我修改的版本

    docker pull holmesian/xgo:latest
    
    go get github.com/holmesian/xgo

所有的用法和原版的xgo一样,只是在拉取依赖的时候使用了 goproxy 。

不放心的TX想自己修改也很简单:先 fork 大佬们的成果,再在 Base 镜像里的 Dockerfile 中加上

ENV GOPROXY=https://goproxy.cn ,direct 

大陆使用代理下载依赖,出错回退direct连接,接着GitHub Action 制作镜像推送到 docker hub,然后修改 xgo 里面的镜像地址编译出可执行文件就可以用啦。

后记

感谢 https://github.com/karalabe/xgohttps://github.com/techknowlogick/xgohttps://github.com/monkeyWie/xgo 等大佬们为 go 交叉编译做出的贡献。

开源的力量令人钦佩。


「倘若有所帮助,不妨酌情赞赏!」

Holmesian

感谢您的支持!

使用微信扫描二维码完成支付


相关文章

发表新评论
仅有 1 条评论
  1. 清雨

    直接用 Github Actions 上提供的原生 Windows 容器环境编译比较省事,而且也不需要担心网络问题。

    清雨 回复