Golang在 Docker 中交叉编译 Windows

前言: 前端时间把本地的 Golang 开发环境卸载了,如果编写代码的话就是启动一个 Golang 的 Docker 容器。这样做对于服务端开发本来也是没有问题的,但是有时候想要把程序放到 Windows 上面来执行,那就遇到麻烦了。因为 Docker 容器本质上是 Linux 环境,所以它直接编译的二进制可执行文件也是基于 Linux 的,直接是 Windows 上是无法运行的。不过幸好,Golang 在交叉编译这方面做得很好,我们只需要简单设置一下就可以了:CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go
CGO_ENABLE=0 关闭 CGO。
GOOS 目标操作系统,通常就是 windows linux drawin
GOARCH 目标架构,通常就是 amd64,现在也有些是arm架构的,不过我也没有使用过。

注:我了解到有 Windows 容器这个概念,似乎是直接运行在 Windows 上的,不过我也没有仔细了解,毕竟技术栈还是基于 Linux 生态的。

这样做通常就能解决问题了,但是如果我们引入了第三方库,那么它就可能不行了。这里就和 CGO_ENABLE 这个选项有关了。前段时间在写那个 HTTP 代理的 demo,之后我引入了 sqlite3 这个库,用于记录访问数据。然后再次交叉编译之后就遇到问题了,我们来看一下这个问题。

编译

在这里插入图片描述

Windows 执行
执行的话,它直接就报错了,并且也说了原因是因为 CGO_ENABLED=0,同时也指出了是 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/clang,windows 上用 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 的设备,所以我就没有尝试。不过还是把它记录在这里了,也许有人会需要这个东西呢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/224810.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为数通——网络参考模型

OSI参考模型 七层 应用层:最靠近用户的一层,为应用程序提供网络服务。 六层 表示层:数据格式转换编码格式UTF-8。 五层 会话层:双方之间建立、管理和终止会话。 四层 传输层:建立、维护和取消端到端的数据传输过…

verilog语法进阶-分布式ram

概述: FPGA的LUT查找表是用RAM设计的,所以LUT可以当成ram来使用,也并不是所有的LUT都可以当成ram来使用,sliceM的ram可以当成分布式ram来使用,而sliceL的ram只能当成rom来使用,也就是只能读,不能写&#x…

如何使用ArcGIS Pro裁剪影像

对影像进行裁剪是一项比较常规的操作,因为到手的影像可能是多种范围,需要根据自己需求进行裁剪,这里为大家介绍一下ArcGIS Pro中裁剪的方法,希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的影像和行政区…

软件测试用例经典方法 | 单元测试法案例

单元测试又称模块测试,是对软件设计的最小单元的功能、性能、接口和设计约束等的正确性进行检验,检查程序在语法、格式和逻辑上的错误,并验证程序是否符合规范,以发现单元内部可能存在的各种缺陷。 单元测试的对象是软件设计的最…

hive的分区表和分桶表详解

分区表 Hive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录,每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择查询所需要的分区,这样的查询效率会提高很多。 静态分区表基本语法 创建分区表 create table dept_p…

HBase的安装与简单操作

文章目录 第1关:Hbase数据库的安装第2关:创建表第3关:添加数据、删除数据、删除表 第1关:Hbase数据库的安装 编程要求 根据上述步骤安装配置好HBase数据库,并启动成功。 测试说明 若安装配置成功,则程序会…

mfc配置halcon环境

新建mfc窗体 选择基于对话框 打开项目属性 1、附加包含目录添加: $(HALCONROOT)\include;$(HALCONROOT)\include\halconcpp 2、链接器->常规->附加库目录 $(HALCONROOT)\lib\x64-win64 3、链接器->输入->附加依赖项 halcon.lib;halconcpp.lib 在对话…

网络入门---守护进程

目录标题 什么是守护进程会话的理解setsid函数daemonSelf函数模拟实现测试 什么是守护进程 在前面的学习过程中我们知道了如何使用TCP协议和UDP协议来实现通信,比如说登录xshell运行了服务端: 然后再登录一个xshell运行客户端并向服务端发送信息&#…

基于若依搭建微服务nacos版本(ruoyi-Cloud前后端分离)

说明:本文介绍基于Ruoyi-Cloud前后端分离nacos版本的微服务从0到1的搭建过程,同时新增一个新的微服务模块。是基于官方文档的补充说明,需要结合Ruoyi-Cloud的官方文档 https://doc.ruoyi.vip/ruoyi-cloud/ 如果直接查看官方文档便可成功部署&…

Linux--权限问题(2)

目录 前文 前言 1. 文件的权限 1.1 文件的访问者分类 1.2 文件类型和访问权限(事物属性) 2. 如何修改文件的权限 3.对比权限有无的表现 4.修改用户角色 5.修改权限的第二种做法 6.目录的权限 7.默认权限 前文 Linux--权限问题(1&#…

云原生之深入解析Kubernetes本地持久化存储方案OpenEBS LocalPV的最佳实践

一、K8s 本地存储 K8s 支持多达 20 种类型的持久化存储,如常见的 CephFS 、Glusterfs 等,不过这些大都是分布式存储,随着社区的发展,越来越多的用户期望将 K8s 集群中工作节点上挂载的数据盘利用起来,于是就有了 loca…

一种用于心音分类的轻量级1D-CNN+DWT网络

这是由National Institute of Technology Rourkela, Central University of Rajasthan发布在2022 ICETCI的论文,利用离散小波变换(DWT)得到的多分辨率域特征对1D-CNN模型进行心音分类训练。 预处理& DWT 由于FHS和各种病理声的频率范围在500hz以下[5]&#xff…

像素、分辨率、频率、精度、延迟,关于光学动作捕捉镜头参数的那些事

精准度、分辨率、频率、延迟等参数是影响光学动作捕捉效果和还原度的关键因素。下面逐一介绍NOKOV度量动作捕捉系统的基础参数。 NOKOV度量动作捕捉系统的核心产品是光学动作捕捉镜头,用于捕捉被测物表面反光标记点的三维坐标数据。 从表中可以看到,不同…

电阻的运用

本文引注 https://baijiahao.baidu.com/s?id1749115196647029942&wfrspider&forpc 一、零欧电阻 在电子电路设计时经常用到的一种元件就是电阻,我们都知道电阻在电路中起到分压限流的作用。然而,实际使用时会用到一种特殊的电阻:零…

用Kotlin抓取微博数据并进行热度预测

闲来无事,逛逛微博,看着每条热度很高的博文趣事,心想能否通过爬虫抓取微博热度并进行趋势分析,说干就干,这里需要注意的问题我会一一标注。 爬虫ip信息的设置是在爬虫程序中进行的。爬虫ip信息可以帮助爬虫程序在访问…

使用React实现随机颜色选择器,JS如何生成随机颜色

背景 在标签功能中,由于有「背景色」属性,每次新增标签时都为选择哪种颜色犯难。因此,我们思考如何通过JS代码生成随机颜色,提取一个通用的随机颜色生成工具,并基于React框架封装随机颜色选择器组件。 实际效果 原理…

Parade Series - Message Interaction

if (true) {Swal.fire("节目发布", "发布完毕", "success");event.preventDefault(); } if (false) {Swal.fire("节目发布", "发布失败", "error");event.preventDefault(); }if (true) {for (var i 0; i < b…

AI日报:OpenAI向新用户重新开放ChatGPT Plus订阅

欢迎订阅专栏 《AI日报》 获取人工智能邻域最新资讯 文章目录 总览Chatgptplus重新开放订阅#暂停原因功能 OpenAI的1000万美元安全人工智能拨款拨款初衷学术捐赠 总览 ChatGPT Plus再次向新用户开放&#xff0c;但目前每三小时限制发送40条消息。 OpenAI还宣布拨款1000万美元…

数据结构-07-二叉树

前面学习的栈、队列等等都是线性表结构。树是一种非线性表结构&#xff0c;比线性表的数据结构要复杂。 1-树tree “树”这种数据结构类似我们现实生活中的“树”&#xff0c;这里面每个元素我们叫作“节点”&#xff1b;用来连线相邻节点之间的关系&#xff0c;我们叫作“父子…

云端赋能大湾区:华为云照亮数字化转型之路

编辑&#xff1a;阿冒 设计&#xff1a;沐由 在中国的经济版图上&#xff0c;大湾区是极其重要的增长引擎。这块富有活力和创新力的经济区域里&#xff0c;荟聚了大量的高新技术企业&#xff0c;以及一批创新孵化器和科研机构&#xff0c;产业升级和技术创新的氛围格外浓烈。 1…