menu Chancel's blog
rss_feed
Chancel's blog
有善始者实繁,能克终者盖寡。

GO全平台交叉编译工具GoReleaser

作者:Chancel Yang, 创建:2019-03-01, 字数:6409, 已阅:8, 最后更新:2024-06-14

在 GitHub 上,经常可以看到使用GO语言写的程序发布如下程序包

DeepinScreenshot_select-area_20220610110124.png

这是基于 Goreleaser 进行的二进制打包, Goreleaser 是一个用于构建和发布Go语言项目的工具,它简化了构建、打包和发布Go应用程序或库的过程

Goreleaser 支持在各种平台上构建二进制文件,并为不同的操作系统和发行版本创建适当的发布包

各个平台的安装方法可参考goreleaser.com - 官方文档

以下以 debian12 为例,实践打包一个GO程序

1. 准备

1.1. Go应用

准备一个 gin 的 go web应用

Go
package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    // 创建一个默认的Gin引擎
    router := gin.Default()

    // 定义一个路由处理函数
    router.GET("/", func(c *gin.Context) {
    	c.JSON(http.StatusOK, gin.H{
    		"message": "Hello, World!",
    	})
    })

    // 启动HTTP服务器,监听在8080端口
    router.Run(":8080")
}

安装并启动程序

Bash
go mod init gin-demo
go mod tidy
go run main.go

访问一下:8080端口

Bash
curl http://127.0.0.1:8080

{"message":"Hello, World!"}

接下来我们将打包这个程序

1.2. Goreleaser

安装 Goreleaser

Bash
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
sudo apt update
sudo apt install goreleaser

2. 打包

2.1. goreleaser.yaml

安装完成后,在项目中使用 Goreleaser 初始化项目

Bash
goreleaser init

在项目目录中,查看生成的.goreleaser.yaml文件,如下

YAML
version: 1

project_name: gin-demo

before:
  hooks:
    - go mod tidy
    - go generate ./...

builds:
  - env:
      - CGO_ENABLED=0
    goos:
      - linux
      - windows
      - darwin
      - freebsd
      - openbsd
      - netbsd
      - solaris
      - dragonfly
    goarch:
      - amd64
      - 386
      - arm
      - arm64
      - ppc64
      - ppc64le
      - mips
      - mipsle
      - mips64
      - mips64le
      - s390x
    main: ./main.go

archives:
  - format: zip
    name_template: >-
      {{ .ProjectName }}_
      {{- title .Os }}_
      {{- if eq .Arch "amd64" }}x86_64
      {{- else if eq .Arch "386" }}i386
      {{- else }}{{ .Arch }}{{ end }}
      {{- if .Arm }}v{{ .Arm }}{{ end }}

changelog:
  sort: asc
  filters:
    exclude:
      - "^docs:"
      - "^test:"

需要关注的参数如下:

  • project_name:项目名称
  • builds-goos:支持的目标操作系统
  • builds-goarch:支持的目标架构
  • builds-main:程序入口

2.2. 打包

进行分发打包

Bash
goreleaser --snapshot --skip-publish --rm-dist

查看项目目录下的dist文件夹,里面是打包后的文件,如下:

Bash
$ tree                                                                                           
.
├── dist
│   ├── artifacts.json
│   ├── config.yaml
│   ├── gin-demo_0.0.0-SNAPSHOT-none_checksums.txt
│   ├── gin-demo_darwin_amd64_v1
│   │   └── gin-demo
│   ├── gin-demo_darwin_arm64
│   │   └── gin-demo
│   ├── gin-demo_Darwin_arm64.zip
│   ├── gin-demo_Darwin_x86_64.zip
│   ├── gin-demo_dragonfly_amd64_v1
│   │   └── gin-demo
│   ├── gin-demo_Dragonfly_x86_64.zip
│   ├── gin-demo_freebsd_386
│   │   └── gin-demo
│   ├── gin-demo_freebsd_amd64_v1
│   │   └── gin-demo
│   ├── gin-demo_freebsd_arm_6
│   │   └── gin-demo
│   ├── gin-demo_freebsd_arm64
│   │   └── gin-demo
│   ├── gin-demo_Freebsd_arm64.zip
│   ├── gin-demo_Freebsd_armv6.zip
│   ├── gin-demo_Freebsd_i386.zip
│   ├── gin-demo_Freebsd_x86_64.zip
│   ├── gin-demo_linux_386
│   │   └── gin-demo
│   ├── gin-demo_linux_amd64_v1
│   │   └── gin-demo
│   ├── gin-demo_linux_arm_6
│   │   └── gin-demo
│   ├── gin-demo_linux_arm64
│   │   └── gin-demo
│   ├── gin-demo_Linux_arm64.zip
│   ├── gin-demo_Linux_armv6.zip
│   ├── gin-demo_Linux_i386.zip
│   ├── gin-demo_linux_mips64_hardfloat
│   │   └── gin-demo
│   ├── gin-demo_linux_mips64le_hardfloat
│   │   └── gin-demo
│   ├── gin-demo_Linux_mips64le.zip
│   ├── gin-demo_Linux_mips64.zip
│   ├── gin-demo_linux_mips_hardfloat
│   │   └── gin-demo
│   ├── gin-demo_linux_mipsle_hardfloat
│   │   └── gin-demo
│   ├── gin-demo_Linux_mipsle.zip
│   ├── gin-demo_Linux_mips.zip
│   ├── gin-demo_linux_ppc64
│   │   └── gin-demo
│   ├── gin-demo_linux_ppc64le
│   │   └── gin-demo
│   ├── gin-demo_Linux_ppc64le.zip
│   ├── gin-demo_Linux_ppc64.zip
│   ├── gin-demo_linux_s390x
│   │   └── gin-demo
│   ├── gin-demo_Linux_s390x.zip
│   ├── gin-demo_Linux_x86_64.zip
│   ├── gin-demo_netbsd_386
│   │   └── gin-demo
│   ├── gin-demo_netbsd_amd64_v1
│   │   └── gin-demo
│   ├── gin-demo_netbsd_arm_6
│   │   └── gin-demo
│   ├── gin-demo_netbsd_arm64
│   │   └── gin-demo
│   ├── gin-demo_Netbsd_arm64.zip
│   ├── gin-demo_Netbsd_armv6.zip
│   ├── gin-demo_Netbsd_i386.zip
│   ├── gin-demo_Netbsd_x86_64.zip
│   ├── gin-demo_openbsd_386
│   │   └── gin-demo
│   ├── gin-demo_openbsd_amd64_v1
│   │   └── gin-demo
│   ├── gin-demo_openbsd_arm_6
│   │   └── gin-demo
│   ├── gin-demo_openbsd_arm64
│   │   └── gin-demo
│   ├── gin-demo_Openbsd_arm64.zip
│   ├── gin-demo_Openbsd_armv6.zip
│   ├── gin-demo_Openbsd_i386.zip
│   ├── gin-demo_Openbsd_x86_64.zip
│   ├── gin-demo_solaris_amd64_v1
│   │   └── gin-demo
│   ├── gin-demo_Solaris_x86_64.zip
│   ├── gin-demo_windows_386
│   │   └── gin-demo.exe
│   ├── gin-demo_windows_amd64_v1
│   │   └── gin-demo.exe
│   ├── gin-demo_windows_arm_6
│   │   └── gin-demo.exe
│   ├── gin-demo_windows_arm64
│   │   └── gin-demo.exe
│   ├── gin-demo_Windows_arm64.zip
│   ├── gin-demo_Windows_armv6.zip
│   ├── gin-demo_Windows_i386.zip
│   ├── gin-demo_Windows_x86_64.zip
│   └── metadata.json
├── go.mod
├── go.sum
└── main.go

32 directories, 69 files

试试运行:

Bash
./dist/gin-demo_linux_amd64_v1/gin-demo

访问一下,看是否可以正常返回:

Bash
curl http://127.0.0.1:8080

{"message":"Hello, World!"}

3. 自动发布

Goreleaser 支持自动化发布,先在 GitHub 上创建一个个人访问令牌(PAT),确保它具有 repo 和 write:packages 权限。然后,将该令牌设置为环境变量:

Bash
export GITHUB_TOKEN=your_github_token

然后打标签并自动创建新的发布(就像开头提到的其他go项目一样发布多个客户端)

Bash
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.0
goreleaser release

4. 原始打包

再说说自带的打包方式,假设你在 Linux 上开发,并希望为 Windows 64 位系统编译你的 Go 程序,可以这样做:

Bash
env GOOS=windows GOARCH=amd64 go build main.go -o go-gin.exe

GOOSGOARCH 是 Go 编程语言中用于指定目标操作系统和目标架构的环境变量。这些变量在交叉编译(将程序编译为不同平台的可执行文件)时非常有用

GOOS 变量指定目标操作系统。常见的值包括:

  • linux:Linux
  • windows:Windows
  • darwin:macOS
  • freebsd:FreeBSD
  • openbsd:OpenBSD
  • netbsd:NetBSD
  • solaris:Solaris
  • dragonfly:DragonFly BSD

GOARCH 变量指定目标架构。常见的值包括:

  • amd64:64位 x86
  • 386:32位 x86
  • arm:32位 ARM
  • arm64:64位 ARM
  • ppc64:64位 PowerPC
  • ppc64le:64位 Little Endian PowerPC
  • mips:32位 MIPS
  • mipsle:32位 Little Endian MIPS
  • mips64:64位 MIPS
  • mips64le:64位 Little Endian MIPS
  • s390x:64位 IBM Z 系列

[[replyMessage== null?"发表评论":"发表评论 @ " + replyMessage.m_author]]

account_circle
email
web_asset
textsms

评论列表([[messageResponse.total]])

还没有可以显示的留言...
gravatar
[[messageItem.m_author]] [[messageItem.m_author]]
[[messageItem.create_time]]
[[getEnviron(messageItem.m_environ)]]
[[subMessage.m_author]] [[subMessage.m_author]] @ [[subMessage.parent_message.m_author]] [[subMessage.parent_message.m_author]]
[[subMessage.create_time]]
[[getEnviron(messageItem.m_environ)]]