再谈Go语言的交叉编译


I. 起因

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

golang-docker.jpg

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

II. 关于 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 确实是个好东东。

III. 毒打

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

我的初始需求是在 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  " 

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

IV. 解决

如果是单纯要梯子的问题很容易解决,但是一方面我的现实情况是这个 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 里面的镜像地址编译出可执行文件就可以用啦。

V. 后记

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

开源的力量令人钦佩。


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

Holmesian

感谢您的支持!

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


相关文章

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

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

    清雨 回复