Golang在 Docker 中交叉编译 Windows

news2024/11/17 15:47:33

前言: 前端时间把本地的 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.coloradmin.cn/o/1314186.html

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

相关文章

VSCode解决本地浏览器需要跨域问题

这里写目录标题 测试用代码执行代码后控制台报错现象解决方案 测试用代码 先把测试用的代码贴出来 测试代码结构 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Com…

git checkout进行更改分支

git clone https://gitee.com/yaleguo1/minit-learning-demo.git下载代码。 cd minit-learning-demo/进入目录里边。 ls -l看一下当前分支的内容。 git checkout geek_chapter02更改分支到geek_chapter02。 ls -l看一下目录里边的内容。

【Axure RP9】的详细安装及Axure入门应用

目录 一 Axure入门安装 1.1 Axure是什么? 1.2 Axure应用场景 1.3 Axure安装 1.3.1 汉化 1.3.2 授权 二, Axure应用 1.1 Axure软件界面概述 1.2 Axure的应用 1.2.1备份 1.2.2 视图显示及网格设置 1.2.3 生成HTML文件 1.2.4 备注说明 一 Axure入门安装 1.1 Axure…

如何发布自定义 npm 组件包

准备工作 1. 注册 npm 账号 还没有 npm 账号&#xff1f;去官网注册&#xff1a; https://www.npmjs.com 需要记住用户名、密码、邮箱&#xff0c;后面需要用到。 2. 查看本地 npm 镜像&#xff0c;如果不是默认的&#xff0c;需要改回来 npm config get registry重置镜像路…

安装统信UOS服务器操作系统1060

原文链接&#xff1a;安装统信UOS服务器操作系统1060 hello&#xff0c;大家好啊&#xff01;今天我要给大家介绍的是如何安装统信UOS服务器操作系统1060。统信UOS是一款基于Linux内核&#xff0c;专为中国市场定制开发的操作系统。它不仅提供了良好的用户体验&#xff0c;还在…

翻译: 为什么需要微调大模型 Why Fine-tuning LLM

虽然RAG提供了一种方式来给大型语言模型提供额外的信息&#xff0c;但还有另一种叫做微调&#xff08;fine-tuning&#xff09;的技术&#xff0c;也是给它更多信息的一种方式。特别是&#xff0c;如果你有的上下文比大型语言模型的输入长度或上下文窗口长度更大&#xff0c;那…

单片机Freertos入门(二)任务的创建、删除

1、串口配置 首先将串口进行配置&#xff0c;后续经常会应用&#xff0c;具体步骤点击&#xff1a;串口配置。 2、任务 创建一个任务&#xff0c;就是开辟一个空间、每个任务中都会有while&#xff08;1&#xff09;死循环。 2.1相关函数 动态创建&#xff1a;xTaskCreate…

Linux第一个小程序——进度条

Linux第一个小程序——进度条 1. 前言2. 缓冲区概念3. \r && \n4. 进度条实现4.1 初级进度条4.2 升级进度条 1. 前言 在我们写这个小程序之前&#xff0c;我们要用到我们学的三个知识点 gcc的使用vim的使用make/makefile的使用 除此之外还需要一些其他的知识点&…

如何在jenkins容器中安装python+httprunner+pytest+git+allure(一)

背景&#xff1a; API接口自动化使用python语言实现&#xff0c;利用httprunner框架编写自动化用例场景&#xff08;执行的时候还是依赖pytest),使用jenkins自动构建git上的源代码&#xff0c;并产生allure报告可视化展示API执行结果。 步骤 1.进入jenkins容器 注意使用roo…

数据库和数据仓库的区别

数据仓库是在数据库已知大量存在的前提下&#xff0c;为了进一步挖掘数据资源&#xff0c;为了决策需要产生的&#xff1b;数据仓库在设计的时候有意添加反范式设计&#xff0c;目的是提高查询效率 对比内容数据库数据仓库数据内容近期值历史的 归档的数据数据目标面向业务操作…

ArcGIS Pro SDK 右键获取选中的图层

需求&#xff1a; 获取右键选中的图层 解决方法&#xff1a; 地图页面获取选中的图形 // 获取所选要素 var firstFeatureLayer MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(); 布局页面获取选中的地图框 Layout layout …

Tomcat 十大安全优化方法(详解版)

目录 1 talnet管理端口保护 2 AJP连接端口保护 3 禁用管理器 4 降权启动 5 控制文件列表的访问 6 隐藏版本信息 7 server header重写 8 限制IP访问 9 修改脚本权限 10 访问日志格式规范 1 talnet管理端口保护 配置内容&#xff1a; &#xff08;1&#xff09;修改默…

element-plus 结合Vue Router时出现的问题及解决方法之一

1、单文件应用element-plus中的Menu 侧边栏 <template><el-row class"tac"><el-col :span"12"><!-- <h5 class"mb-2">Custom colors</h5> --><el-menuactive-text-color"#ffd04b"background-…

GRU,LSTM,encoder-decoder架构,seq2seq的相关概念

门控记忆单元&#xff08;GRU&#xff09; GRU模型有专门的机制来确定应该何时更新隐状态&#xff0c;以及应该何时重置隐状态。这些机制是可学习的。门控循环单元具有以下两个显著特征&#xff1a; 重置门有助于捕获序列中的短期依赖关系&#xff1b;更新门有助于捕获序列中…

Axios入门案例——后端学习

目录 后端准备 导入依赖 解决跨域 User实体类 DemoController测试接口 前端准备 项目结构 axios.js axios.html 开始测试 后端结果 前端结果 后端准备 导入依赖 案例会用到以下的三个依赖。 <dependency><groupId>org.springframework.boot</gro…

案例066:基于微信小程序的家政预约设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

探索多功能SQL数据库编辑器 - Richardson Software RazorSQL

在当今数字化时代&#xff0c;SQL数据库的管理和编辑是许多企业和开发人员必不可少的任务。为了提高生产力和简化数据库操作&#xff0c;Richardson Software推出了一款强大而多功能的SQL数据库编辑器 - RazorSQL。 RazorSQL是一款功能全面的数据库管理工具&#xff0c;可适用…

redis五种数据结构特点

redis五种数据结构特点 redis-string介绍SDS内部存储数据结构三种编码方式特点总结 redis-list介绍quicklist特点总结 redis-hash特点总结 redis-set介绍 特点总结redis-zset介绍特点总结 redis使用五种数据结构&#xff0c;分别是string&#xff08;字符串&#xff09;&#x…

如何连接到 Azure SQL 数据库(下)

在《如何连接到 Azure SQL 数据库&#xff08;上&#xff09;》中&#xff0c;我们已经了解到了以下内容↓↓↓ 开始之前&#xff1a;Azure 连接凭据和防火墙 如何检索 Azure 连接凭据如何配置服务器防火墙使用 SQL Server Management Studio 连接到 Azure使用 dbForge Studio…

实战 | OpenCV传统方法实现密集圆形分割与计数(详细步骤 + y源码)

导 读 本文主要介绍基于OpenCV传统方法实现密集圆形分割与计数应用,并给详细步骤和代码。 背景介绍 实例图片来源于网络,目标是分割下图中圆形目标并计数。 本文实现效果如下: 实现步骤 【1】灰度转换 + 均值滤波 + 二值化,得到参考背景 img = cv2.imread(src.jpg)c…