Golang-编译


常用参数

  • -o
    • Output 指定编译输出的名称,代替默认的包名
  • -i
    • install 已废弃,安装指定的包来完成编译,编译需要的包会自动缓存下来
  • 其他参数都归类为build flags

使用

1
go build [-o 输出名] [-i] [编译标记] [包名]

build flags

build flags在build,clean,get,install,list,run,test等命令下都是通用的

  • -tags ‘tag list’

    • 构建出带tag的版本
  • -gcflags ‘arg list’

    • 编译参数go tool compile –help查看所有可用的参数
    • -m:打印优化信息
    • -N:禁用优化(debug时用到)
    • -I:禁止内联优化(debug时用到)
    • -c:指定编译是的并发数,默认为1
    • -L:错误信息中打印文件全名

    gcflag中的pattern

    • gcflag传入的方式为: -gcflag=”pattern= args”,其中pattern代表取值分别为 main,all,std,…,用于指定编译参数作用的范围,args则为对应的编译参数

    • main:表示main函数所在的顶级包路径

    • all:表示GOPATH中的所有包。如果在modules模式下,则表示主模块和他所有的依赖,包括test文件的依赖

    • std:表示Go标准库中的所有包

    • ...:表示是一个通配符,可以匹配任意字符串(包括空字符串)

      • net/…表示net模块和它所有子模块
      • ./…表示当前主模块和所有子模块
      • 如果 pattern 中包含了 / 和 …,那么就不会匹配 vendor 目录。例如: ./... 不会匹配 ./vendor 目录。可以使用 ./vendor/... 匹配 vendor 目录和它的子模块

      举例:

      1
      go build -gcflags="main=-N -l" .
  • -ldflags ‘flag list’

    • 链接参数go tool link –help查看可用可用的参数
    • -X:注入变量,通常用于版本信息的注入

    举例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package main

    import (
    "fmt"
    "os"
    )
    var (
    gitHash string
    buildTime string
    goVersion string
    )
    func main() {
    args := os.Args
    if len(args) == 2 && (args[1] == "--version" || args[1] == "-v") {
    fmt.Printf("Git Commit Hash: %s \n", gitHash)
    fmt.Printf("Build TimeStamp: %s \n", buildTime)
    fmt.Printf("GoLang Version: %s \n", goVersion)
    return
    }
    }
    1
    go build -ldflags "-X 'main.goVersion=$(go version)' -X 'main.gitHash=$(git show -s --format=%H)' -X 'main.buildTime=$(git show -s --format=%cd)'" -o main
    1
    2
    3
    4
    ➜  cmd git:(master) ✗ ./main -v                                                                                                                                                 
    Git Commit Hash: 24ba11ec5e2af192dc619e2555c6604a254690d0
    Build TimeStamp: Mon Mar 11 15:44:52 2024 +0800
    GoLang Version: go version go1.20.6 darwin/amd64

    makefile

    1
    2
    3
    4
    flags=-X main.buildDate=`date -u '+%Y-%m-%d'` -X main.gitHash=`git rev-parse --short HEAD`

    build:
    go build -ldflags "$(flags)" -o main main.go
  • -mod

    • readonly,vendor,mod 1.14版本以后,如果在mod文件里面有指定vendor,则默认使用vendor,否则设置为readonly
  • -race

    • 同时检测数据竞争状态,只支持 linux/amd64, freebsd/amd64, darwin/amd64 和 windows/amd64

交叉编译

编译跨平台的只需要修改GOOSGOARCHCGO_ENABLED三个环境变量即可

  • GOOS:目标平台的操作系统(darwin,freebsd,linux,windows)
  • GOARCH:目标平台的体系架构32位还是64位(386,amd64,arm)
  • 交叉编译不支持CGO所以要禁用它

Windows环境编译

1
2
3
4
5
6
7
8
9
SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build main.go

SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go

Mac环境编译

1
2
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

Linux环境编译

1
2
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

  目录