Bootstrap

②Go命令:build

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/,结果是会创建helloworld两个目录,注意是目录,随即退出,不会产生任何编译结果。

总结就是如果要指定编译输出目录,最好也指定一下文件名。比如go build -o /bin/out.exe

-i参数在编译时自动安装依赖。注意只是安装,不包括下载。说白了就是会对依赖包执行一遍go install

编译参数对于buildcleangetinstalllistruntest是一样的,因此后面将不会重复介绍。

  1. -a

    强制重新编译已更新的包

  2. -n

    打印执行的命令,但是并不真正执行

  3. -p n

    n是一个数字,表示编译或测试的并行程序数,默认为CPU核心数

  4. -race

    打开数据竞争检测。支持linux/amd64,freebsd/amd64,darwin/amd64,windows/amd64,linux/ppc64le和linux/arm64(仅48-bit VMA)

  5. -msan

    打开交互式内存优化。支持linux/amd64,linux/arm64,且C编译器为Clang/LLVM。在linux/arm64上,编译模式使用pie

  6. -v

    打印编译的包名(但不是每次都能打印出来,真奇怪?)

  7. -work

    打印临时工作目录名,并在编译结束后不删除临时工作目录

  8. -x

    打印并执行命令

  9. -asmflags '[pattern=]arg list'

    传递给asm工具的参数

  10. -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参数。

  11. -compile name

    指定编译器(gccgo或gc),默认是gc

  12. -gccgoflags '[pattern=]arg list'

    传递给编译器的参数,gccgo是Go的编译器

  13. -gcflags '[pattern=]arg list'

    传递给编译器的参数,gc也是Go的编译器

    • -B:禁用边界检查

    • -N:禁用优化

    • l:禁用函数内联

    • -u:禁用unsafe代码

    • -m:输出优化信息

    • -S:输出汇编代码

  14. -installsuffix suffix

    包安装目录名后缀,为的是与默认的编译输出分离。如果使用-race标志,后缀自动设置为race,如果指定了后缀,也会追加_race-msan和非默认的-buildmode也一样

  15. -ldflags '[pattern=]arg list'

    传递给go链接器的参数

  16. -linkshared

    编译将要链接到使用-buildmode=shared参数生成的共享库的代码

  17. -mod mode

    模块下载模式:只读,vender,mod。内容较多,这里就不展开了

  18. modcacherw

    让在模块缓存中新创建的目录为可读写,而不是只读

  19. -modfile file

    使用模块时,go.mod文件默认在模块跟目录。该参数可以指定使用另一个go.mod文件,同时也会在此目录下生成go.sum文件,注意,原来模块根目录下的go.mod文件不能删除。

  20. pkgdir dir

    指定一个安装和加载包的目录

  21. -tags tag,list

    其实就是编译约束,用逗号分隔,早期Go版本用空格分隔,现在已被丢弃,但是任然可以识别

  22. -trimpath

    从生成的可执行文件中删除文件系统路径。标准库将以“go”开头,模块变成path@version,或者如果使用GOPATH,就直接是import路径,而不是绝对路径。说白了就是要变成文件系统无关的

  23. -toolexec 'cmd args'

    用来调用工具链(如vet和asm)的程序,上例中,go命令不会直接运行asm,而是调用cmd args /path/to/asm <args>,它会使用cmd去运行asm

-asmflags-gccgoflags-gcflags-ldflags的参数以空格分隔,如果命令中包含空格,将参数包裹在单引号或双引号中。

;