go build 命令应用详解-a: 强行对所有涉及到的代码包(包含标准库中的代码包)进行重新构建,即使它们已经是最新的了 |-n | 打印编译期间所用到的其它命令,但是并不真正执行它们 |-p n | 指定编译过程中执行各任务的并行数量(确切地说应该是并发数量)在默认情况下,该数量等于CPU的逻辑核数但是在`darwin/arm`平台(即iPhone和iPad所用的平台)下,该数量默认是`1` |-race | 开启竞态条件的检测不过此标记目前仅在`linux/amd64`、`freebsd/amd64`、`darwin/amd64`和`windows/amd64`平台下受到支持 |-v | 打印出那些被编译的代码包的名字 |-work | 打印出编译时生成的临时工作目录的路径,并在编译结束时保留它在默认情况下,编译结束时会删除该目录 |-x 打印编译期间所用到的其它命令注意它与-n标记的区别下面我们就用其中几个标记来查看一下在构建代码包logging时创建的临时工作目录的路径:hc@ubt:~/golang/goc2p/src$ go build -v -work loggingWORK=/tmp/go-build888760008logging上面命令的结果输出的第一行是为了编译logging包,Go创建的一个临时工作目录,这个目录被创建到了Linux的临时目录下。
输出的第二行是对标记-v的响应这意味着此次命令执行时仅编译了logging包关于临时工作目录的用途和内容,我们会在讲解go run命令和go test命令的时候详细说明现在我们再来看看如果强制重新编译会涉及到哪些代码包:hc@ubt:~/golang/goc2p/src$ go build -a -v -work loggingWORK=/tmp/go-build929017331runtimeerrorssync/atomicmathunicode/utf8unicodesynciosyscallstringstimestrconvreflectosfmtloglogging怎么会多编译了这么多代码包呢?可以确定的是,代码包logging中的代码直接依赖了标准库中的runtime包、strings包、fmt包和log包那么其他的代码包为什么也会被重新编译呢?从代码包编译的角度来说,如果代码包A依赖代码包B,则称代码包B是代码包A的依赖代码包(以下简称依赖包),代码包A是代码包B的触发代码包(以下简称触发包)标记-p n可以限制编译过程中任务执行的并发数量,n默认为当前计算机的CPU逻辑核数。
如果在执行go build命令时加入标记-p 1,那么就可以保证代码包编译顺序严格按照预先设定好的优先级进行现在我们再来编译logging包:hc@ubt:~/golang/goc2p/src$ go build -a -v -work -p 1 loggingWORK=/tmp/go-build114039681runtimeerrorssync/atomicsynciomathsyscalltimeosunicode/utf8strconvreflectfmtlogunicodestringslogging我们可以认为,以上示例中所显示的代码包的顺序,就是logging包直接或间接依赖的代码包按照优先级从高到低排列后的排序另外,如果在命令中加入标记-n,那么编译程序只会输出所用到的命令而不会真正运行在这种情况下,编译过程不会使用并发模式在本节的最后,我们对一些并不太常用的标记进行简要的说明:-asmflags此标记可以后跟另外一些标记,如-D、-I、-S等这些后跟的标记用于控制Go语言编译器编译汇编语言文件时的行为buildmode此标记用于指定编译模式,使用方式如-buildmode=default(这等同于默认情况下的设置)。
此标记支持的编译模式目前有6种借此,我们可以控制编译器在编译完成后生成静态链接库(即.a文件,也就是我们之前说的归档文件)、动态链接库(即.so文件)或/和可执行文件(在Windows下是.exe文件)compiler此标记用于指定当前使用的编译器的名称其值可以为gc或gccgo其中,gc编译器即为Go语言自带的编辑器,而gccgo编译器则为GCC提供的Go语言编译器而GCC则是GNU项目出品的编译器套件GNU是一个众所周知的自由软件项目在开源软件界不应该有人不知道它好吧,如果你确实不知道它,赶紧去google吧gccgoflags此标记用于指定需要传递给gccgo编译器或链接器的标记的列表gcflags此标记用于指定需要传递给go tool compile命令的标记的列表installsuffix为了使当前的输出目录与默认的编译输出目录分离,可以使用这个标记此标记的值会作为结果文件的父目录名称的后缀其实,如果使用了-race标记,这个标记会被自动追加且其值会为race如果我们同时使用了-race标记和-installsuffix,那么在-installsuffix标记的值的后面会再被追加_race,并以此来作为实际使用的后缀。
ldflags此标记用于指定需要传递给go tool link命令的标记的列表首先加上编译参数-ldflags-s相当于strip掉符号表, 但是以后就没办法在gdb里查看行号和文件了w告知连接器放弃所有debug信息$ go build -ldflags '-w -s'1.-linkshared此标记用于与-buildmode=shared一同使用后者会使作为编译目标的非main代码包都被合并到一个动态链接库文件中,而前者则会在此之上进行链接操作pkgdir使用此标记可以指定一个目录编译器会只从该目录中加载代码包的归档文件,并会把编译可能会生成的代码包归档文件放置在该目录下tags此标记用于指定在实际编译期间需要受理的编译标签(也可被称为编译约束)的列表这些编译标签一般会作为源码文件开始处的注释的一部分,例如,在$GOROOT/src/os/file_posix.go开始处的注释为:// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows最后一行注释即包含了与编译标签有关的内容。
大家可以查看代码包go/build的文档已获得更多的关于编译标签的信息toolexec此标记可以让我们去自定义在编译期间使用一些Go语言自带工具(如vet、asm等)的方式。