当前位置: 首页 > 工具软件 > gobuild > 使用案例 >

go build 参数汇总

储俊英
2023-12-01

简介

go 的编译是以 package mainmain() 函数作为主入口,生成可执行文件。若 build 的是非 main 包,则不会生成可执行文件,只检查是否可执行编译。
可以输入 go help build 查看官方解释。
go build 编译包时,会忽略“_test.go”结尾的文件(即测试文件)。

参数含义
-ooutput 指定编译输出的名称,代替包名
-iinstall 安装作为目标的依赖关系的包(用于增量编译提速)
-a强行对项目所有的代码包(包含标准库中的代码包)进行重新构建,即使它们已经是最新的了
-n打印编译期间所用到的命令,仅仅是打印并不真正执行它们
-p n指定编译过程中执行各任务的并行数量(确切地说应该是并发数量)。在默认情况下,该数量等于CPU的逻辑核数。但是在darwin/arm平台(即iPhone和iPad所用的平台)下,该数量默认是1
-race开启竞态条件的检测。不过此标记目前仅在linux/amd64、freebsd/amd64、darwin/amd64和windows/amd64平台下受到支持
-msan使用内存清除器启用互操作。只支持Linux/AMD 64、Linux/ARM 64,并且只有clang/llvm作为主机c+编译器
-v打印出那些被编译时的代码包的名字
-x打印编译期间所用到的其它命令(且执行),注意它与-n标记的区别
-work打印出编译时生成的临时工作目录的路径,并在编译结束时保留它。在默认情况下,编译结束时会删除该目录
以下为不常用命令
-asmflags此标记可以后跟另外一些标记,如-D、-I、-S等。这些后跟的标记用于控制Go语言编译器编译汇编语言文件时的行为
-buildmode此标记用于指定编译模式,使用方式如-buildmode=default(这等同于默认情况下的设置)。此标记支持的编译模式目前有6种。借此,我们可以控制编译器在编译完成后生成静态链接库(即.a文件,也就是我们之前说的归档文件)、动态链接库(即.so文件)或/和可执行文件(在Windows下是.exe文件) go help buildmode
-compiler此标记用于指定当前使用的编译器的名称。其值可以为gc或gccgo。其中,gc编译器即为Go语言自带的编辑器,而gccgo编译器则为GCC提供的Go语言编译器
-gccgoflags此标记用于指定需要传递给gccgo编译器或链接器的标记的列表
-gcflags此标记用于指定需要传递给go tool compile命令的标记的列表
-installsuffix为了使当前的输出目录与默认的编译输出目录分离,可以使用这个标记。此标记的值会作为结果文件的父目录名称的后缀。其实,如果使用了-race标记,这个标记会被自动追加且其值会为race。如果我们同时使用了-race标记和-installsuffix,那么在-installsuffix标记的值的后面会再被追加_race,并以此来作为实际使用的后缀
-ldflags此标记用于指定需要传递给go tool link命令的标记的列表
-linkshared此标记用于与-buildmode=shared一同使用。后者会使作为编译目标的非main代码包都被合并到一个动态链接库文件中,而前者则会在此之上进行链接操作
-pkgdir指定一个目录,并从改目录下加载编译好的.a 文件,并把编译可能产生新的 .a 文件放入到该目录中
-tags此标记用于指定在实际编译期间需要受理的编译标签(也可被称为编译约束)的列表
-toolexec此标记可以让我们去自定义在编译期间使用一些Go语言自带工具(如vet、asm等)的方式

-tags

例:编译debug版本

go build -tags "debug"

注意:build.gobuild_debug.go 的文件开头的 // +build debug 注释,这个就是你编译时的 tags

main.go

package main
func main() {
	tBuildTag()
}

build.go

// +build !debug

package main

import "fmt"

func tBuildTag() {
	fmt.Println("no debug")
}

build_debug.go

// +build debug

package main

import "fmt"

func tBuildTag() {
	fmt.Println("debug")
}

-ldflags ‘flag list’

'-s -w': 压缩编译后的体积
-s: 去掉符号表
-w: 去掉调试信息,不能gdb调试了
-X: 设置包中的变量值

例:编译的时候,带上编译的人的姓名

go build -ldflags "-X main.Developer=zhangsan"

main.go

package main

import "fmt"

var Developer string

func main() {
	fmt.Println("Developer:", Developer)
}

执行编译好的程序,可以看到 Developer: zhangsan 输出。

-race

go run -race 是不会进行竞态检测的。需要先 go build -race,然后再执行编译好的文件。如下是一个竞态示例输出:

==================
WARNING: DATA RACE
Read at 0x00c0000c9ce0 by goroutine 8:
  container/list.(*List).remove()
      D:/Go/src/container/list/list.go:109 +0x119
  container/list.(*List).Remove()
      D:/Go/src/container/list/list.go:141 +0x27a
  commonTest/list.tList1.func2()
      F:/GoTest/GoTest/list/list.go:55 +0x10c

Previous write at 0x00c0000c9ce0 by goroutine 7:
  container/list.(*List).insertValue()
      D:/Go/src/container/list/list.go:104 +0x10c
  container/list.(*List).PushBack()
      D:/Go/src/container/list/list.go:155 +0xc6
  commonTest/list.tList1.func1()
      F:/GoTest/GoTest/list/list.go:27 +0x92

Goroutine 8 (running) created at:
  commonTest/list.tList1()
      F:/GoTest/GoTest/list/list.go:37 +0x1cb
  commonTest/list.Test()
      F:/GoTest/GoTest/list/entrance.go:4 +0x37
  main.main()
      F:/GoTest/GoTest/main.go:19 +0x32

Goroutine 7 (finished) created at:
  commonTest/list.tList1()
      F:/GoTest/GoTest/list/list.go:25 +0x17e
  commonTest/list.Test()
      F:/GoTest/GoTest/list/entrance.go:4 +0x37
  main.main()
      F:/GoTest/GoTest/main.go:19 +0x32
==================

参考

google官方解释
go build 命令介绍
go build命令详解
“go build -X” 的妙用

 类似资料: