go build 命令是用来编译 命令源码文件 以及它依赖的 库源码文件

go build介绍

go的代码源文件分类:

  • 命令源码文件:含有 main 函数的主文件

  • 测试源码文件:单元测试的代码, xxx_test.go

  • 库源码文件:没有上面特征的就是库源码文件

使用格式

usage: go build [-o output] [-i] [build flags] [packages]

常用参数详解

  • -a 将命令源码文件与库源码文件全部重新构建,即使是最新的
  • -n 把编译期间涉及的命令全部打印出来,但不执行
  • -race 开启竞态条件的检测
  • -x 打印编译期间用到的命名,并执行

使用示例

go build 
go build .
go build main.go
go build golang.org/x/tools/cmd/...

3个点表示匹配所有字符串,编译tools/cmd/下面所有的包

静态编译

CGO_ENABLED=0 go build -a -ldflags ‘-extldflags “-static”’ .

构建约束

可以在源码中通过注释的方式指定编译选项,注释构建约束还可以进行逻辑表达

支持and,or之类的语义。空格表示OR关系,逗号表示AND关系。!表示not。

比如:

// +build linux,386 darwin,!cgo
// 表示(linux AND 386) OR (darwin AND (NOT cgo))

多个平台时用空格隔开,避免编译冲突

// +build linux darwin windows

支持多行的构建约束,多行之间是AND关系,比如:

// +build linux darwin
// +build 386
// 表示(linux OR darwin) AND 386

支持忽略文件不参与编译,比如:

// +build ignore

package main // +build和package之间需要空一行

自定义约束,通过tags选项指定约束编译,比如指定执行某些集成测试代码:

// +build integration

// 运行自定义约束文件的集成单元测试文件
> go test –tags="integration"
// 或者编译
> go build -i -tags "integration"
// 多个自定义约束空格隔开
> go build -i -tags "integration integration2"

当多个文件中存在相同函数名冲突时可以使用 ! 来区分编译,比如:

> cat add.go
// +build !ssd
package util

func Add(a, b int) int {
    return a + b
}

> cat add_ssd.go
// +build ssd
package util

func Add(a, b int) int {
    return a + b + 1
}

通过文件名来约束构造,文件名格式(xxx_GOOS.go, xxx_GOARCH.go, xxx_GOOS_GOARCH.go),比如:

  • xxx_linux.go: 只允许在linux下编译
  • xxx_windows_amd64.go: 只允许在windows x64下编译

跨平台编译

GOOS:目标平台的操作系统(darwin、freebsd、linux、windows、android、dragonfly、netbsd、openbsd、plan9、solaris)

GOARCH:目标平台的体系架构(386、amd64、arm、arm64、ppc64、ppc64le、mips64、mips64le、s390x)

跨平台编译不支持 CGO 所以要禁用它

SET CGO_ENABLED=0 // 禁用CGO
SET GOOS=linux    // 目标平台是linux
SET GOARCH=amd64  // 目标处理器架构是amd64

Mac 下编译 Linux 和 Windows 平台 64位 可执行程序:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build

Linux下编译 Mac 和 Windows 平台64位可执行程序:

CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build

Windows下编译Mac平台64位可执行程序:

SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build

使用go env查看编译环境env参考

> go env
GOARCH="amd64"
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOROOT="/usr/local/Cellar/go/1.14/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.14/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"

参考