go
的编译是以 package main
的 main()
函数作为主入口,生成可执行文件。若 build
的是非 main
包,则不会生成可执行文件,只检查是否可执行编译。
可以输入 go help build
查看官方解释。
go build
编译包时,会忽略“_test.go”结尾的文件(即测试文件)。
参数 | 含义 |
---|---|
-o | output 指定编译输出的名称,代替包名 |
-i | install 安装作为目标的依赖关系的包(用于增量编译提速) |
-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等)的方式 |
例:编译debug版本
go build -tags "debug"
注意:build.go
和 build_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")
}
'-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
输出。
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
==================