go build [-o output] [-i] [build flag] [packages]
应该没有人不熟悉这个命令吧,这是go的编译命令,可以用来编译可执行程序或包。它会忽略_test.go
结尾的文件,go编译器将它们识别为测试代码。
默认情况下,可执行程序编译成.exe
文件,文件名是main.go
所在的目录名。包编译结果会被丢弃,仅仅是检查它能编译通过。
-o
参数用来指定编译结果输出位置,可以是文件,也可以是目录。目录是否存在是会影响命令执行结果的:
- 如果目录存在,则将编译结果放到指定目录下。
- 如果目录不存在,它会将目录的最后一部分识别为文件名。比如
go build -o hello/world
,结果是在hello
目录下生成world
文件,注意是名为world
的文件,不是目录。那如果执行的是go build -o hello/world/
,结果是会创建hello
和world
两个目录,注意是目录,随即退出,不会产生任何编译结果。
总结就是如果要指定编译输出目录,最好也指定一下文件名。比如go build -o /bin/out.exe
。
-i
参数在编译时自动安装依赖。注意只是安装,不包括下载。说白了就是会对依赖包执行一遍go install
。
编译参数对于build
,clean
,get
,install
,list
,run
,test
是一样的,因此后面将不会重复介绍。
-a
强制重新编译已更新的包
-n
打印执行的命令,但是并不真正执行
-p n
n是一个数字,表示编译或测试的并行程序数,默认为CPU核心数
-race
打开数据竞争检测。支持linux/amd64,freebsd/amd64,darwin/amd64,windows/amd64,linux/ppc64le和linux/arm64(仅48-bit VMA)
-msan
打开交互式内存优化。支持linux/amd64,linux/arm64,且C编译器为Clang/LLVM。在linux/arm64上,编译模式使用pie
-v
打印编译的包名(但不是每次都能打印出来,真奇怪?)
-work
打印临时工作目录名,并在编译结束后不删除临时工作目录
-x
打印并执行命令
-asmflags '[pattern=]arg list'
传递给asm工具的参数
-buildmode mode
编译模式,共8种。
-buildmode=archive
将非main包编译为.a文件,main包将被忽略
-buildmode=c-archive
必须是main包,将main包和依赖包编译为C文件,只有通过cgo导出的函数可以被调用
-buildmode=c-shared
同上,区别是被编译成C共享库
-buildmode=default
默认行为,main包被编译为可执行文件,非main包编译为.a文件
-buildmode=shared
将所有非main包合并成一个共享库,非main包被忽略,共享库在使用
-linkshared
参数编译时使用
-buildmode=exe
将main包编译为可执行文件,非main包被忽略
-buildmode=pie
将main包编译为PIE,非main包被忽略。PIE是位置无关可执行程序
-buildmode=plugin
将main包编译为Go插件,非main包被忽略
在AIX上,使用
-buildmode=c-archive
参数链接一个C程序时,必须传递给C编译器-Wl,-bnoobjreorder
参数。
-compile name
指定编译器(gccgo或gc),默认是gc
-gccgoflags '[pattern=]arg list'
传递给编译器的参数,gccgo是Go的编译器
-gcflags '[pattern=]arg list'
传递给编译器的参数,gc也是Go的编译器
-B:禁用边界检查
-N:禁用优化
l:禁用函数内联
-u:禁用unsafe代码
-m:输出优化信息
-S:输出汇编代码
-installsuffix suffix
包安装目录名后缀,为的是与默认的编译输出分离。如果使用
-race
标志,后缀自动设置为race
,如果指定了后缀,也会追加_race
。-msan
和非默认的-buildmode
也一样
-ldflags '[pattern=]arg list'
传递给go链接器的参数
-linkshared
编译将要链接到使用
-buildmode=shared
参数生成的共享库的代码
-mod mode
模块下载模式:只读,vender,mod。内容较多,这里就不展开了
modcacherw
让在模块缓存中新创建的目录为可读写,而不是只读
-modfile file
使用模块时,go.mod文件默认在模块跟目录。该参数可以指定使用另一个go.mod文件,同时也会在此目录下生成go.sum文件,注意,原来模块根目录下的go.mod文件不能删除。
pkgdir dir
指定一个安装和加载包的目录
-tags tag,list
其实就是编译约束,用逗号分隔,早期Go版本用空格分隔,现在已被丢弃,但是任然可以识别
-trimpath
从生成的可执行文件中删除文件系统路径。标准库将以“go”开头,模块变成path@version,或者如果使用GOPATH,就直接是import路径,而不是绝对路径。说白了就是要变成文件系统无关的
-toolexec 'cmd args'
用来调用工具链(如vet和asm)的程序,上例中,go命令不会直接运行asm,而是调用
cmd args /path/to/asm <args>
,它会使用cmd去运行asm
-asmflags
,-gccgoflags
,-gcflags
和-ldflags
的参数以空格分隔,如果命令中包含空格,将参数包裹在单引号或双引号中。