网站做的好坏主要看,怎么做网站内容调研,网站建设费入什么科目2018,做网站用那一种语言最好前言#xff1a; 前端时间把本地的 Golang 开发环境卸载了#xff0c;如果编写代码的话就是启动一个 Golang 的 Docker 容器。这样做对于服务端开发本来也是没有问题的#xff0c;但是有时候想要把程序放到 Windows 上面来执行#xff0c;那就遇到麻烦了。因为 Docker 容器…前言 前端时间把本地的 Golang 开发环境卸载了如果编写代码的话就是启动一个 Golang 的 Docker 容器。这样做对于服务端开发本来也是没有问题的但是有时候想要把程序放到 Windows 上面来执行那就遇到麻烦了。因为 Docker 容器本质上是 Linux 环境所以它直接编译的二进制可执行文件也是基于 Linux 的直接是 Windows 上是无法运行的。不过幸好Golang 在交叉编译这方面做得很好我们只需要简单设置一下就可以了CGO_ENABLED0 GOOSwindows GOARCHamd64 go build main.go CGO_ENABLE0 关闭 CGO。 GOOS 目标操作系统通常就是 windows linux drawin。 GOARCH 目标架构通常就是 amd64现在也有些是arm架构的不过我也没有使用过。
注我了解到有 Windows 容器这个概念似乎是直接运行在 Windows 上的不过我也没有仔细了解毕竟技术栈还是基于 Linux 生态的。
这样做通常就能解决问题了但是如果我们引入了第三方库那么它就可能不行了。这里就和 CGO_ENABLE 这个选项有关了。前段时间在写那个 HTTP 代理的 demo之后我引入了 sqlite3 这个库用于记录访问数据。然后再次交叉编译之后就遇到问题了我们来看一下这个问题。
编译 Windows 执行 执行的话它直接就报错了并且也说了原因是因为 CGO_ENABLED0同时也指出了是 go-sqlite3 这个库导致的。 Linux执行 这里尝试在 Linux 执行一下这样做也没有意义不过这个报错很有趣的。它提示是没有文件或者目录但是实际上是可执行文件无法解析导致的。所以以后遇到类似的问题就不需要去想为什么文件不存在了它就是报这个错误并不是文件不存在。 那么该怎么解决呢最方便快捷的方式就是重新在本地安装一个 Golang 的开发环境。 没开玩笑因为这样确实是最快的而且节省时间。如果你有时间和兴趣那就来看接下来的部分吧。
什么是交叉编译
所谓编译就是把代码变成二进制可执行文件的过程。代码就是一段 Unicode 字符它是肯定可以跨平台的但是最终运行的并不是它最终运行的是代码的编译产物。我们平时写完一个小程序直接就点击运行了。但是这里的代码其实是不能直接运行的编译型语言它内部还是要进行一个编译的过程把代码转成目标平台的二进制可执行文件。这个二进制可执行文件是和操作系统和目标架构绑定的所以你换一个操作系统或者架构它就不能运行了。但是有时候我们需要在某个架构的某个操作系统上为特定架构和指定操作系统的另一个平台编译程序这就是交叉编译。 那么我们这里遇到的问题就是我需要在 Linux 下交叉编译可以在 Windows 下可以运行的二进制可执行文件了。交叉编译一般需要交叉编译工具链这个其实还是比较复杂的。所以我们就要采取一些简单的方式了——站在巨人的肩膀上。已经有人做了相关的工作了我们直接采取拿来主义就好了。
交叉编译的 Docker 镜像
这是在 Github 上面找到的一个项目因为上面说的这种需求还是挺常见的所以已经有人做了相关的工作了它是将交叉编译的相关工具链制作成了 Docker 镜像。 Docker image for building Go binaries for Windows with MinGW-w64 toolchain based on official Go Docker image. The repository provides simple cross-compilation environment for windows 32 and 64bit builds. Docker镜像用于使用基于官方Go Docker镜像的 MinGW-w64 工具链为Windows构建Go二进制文件。 这个仓库提供了简单的 win32 和 win64 构建的跨平台编译环境。 注虽然我也了解 Linux 上用 gcc/clangwindows 上用 mingw。不过我对于它们的了解也仅限于此了以前也遇到过有些软件在 windows 上需要安装 mingw 的问题不过也没有深入去了解过因为现在使用的语言像是 Go、Python 开发 Web 服务通常也接触不到这些东西。
Docker image for building Go binaries with MinGW toolchain
拉取镜像 docker pull x1unix/go-mingw:latest # or 1.17 for specific Go version
在容器内编译
docker run --rm -it -v /YourPackageSrc:/go/work \-w /go/work \x1unix/go-mingw go build .它的用法很简单启动一个交互式容器然后把本地项目挂载到容器内的目录中直接编译就行了默认是64位的也可以编译32位的不过我也没有这个需求就没有尝试。
解决问题
好了那么我们用它来解决自己遇到的问题吧。 看这个输出我感觉似乎引入了一些多余的库而且最后生成的文件也是大了一圈 程序启动正常 PS 这里用的这个 github 的项目简单易用对于这种简单的需求直接拉取镜像然后编译就行了。我在 Github 上面搜索的时候还发现了一个更加强大的项目vxbuild-cross看描述它支持 Windows 和 MacOS不过因为我没有 MacOS 的设备所以我就没有尝试。不过还是把它记录在这里了也许有人会需要这个东西呢。