不灭的焱

革命尚未成功,同志仍须努力

作者:php-note.com  发布于:2017-02-26 10:19  分类:Go/Python  编辑

命令 go env 用于打印 Go 语言的环境信息。其中的一些信息我们在之前已经多次提及,但是却没有进行详细的说明。在本小节,我们会对这些信息进行深入介绍。我们先来看一看 go env 命令情况下都会打印出哪些 Go 语言通用环境信息。

表0-25 go env 命令可打印出的 Go 语言通用环境信息

名称 说明
CGO_ENABLED 指明cgo工具是否可用的标识。
GOARCH 程序构建环境的目标计算架构。
GOBIN 存放可执行文件的目录的绝对路径。
GOCHAR 程序构建环境的目标计算架构的单字符标识。
GOEXE 可执行文件的后缀。
GOHOSTARCH 程序运行环境的目标计算架构。
GOOS 程序构建环境的目标操作系统。
GOHOSTOS 程序运行环境的目标操作系统。
GOPATH 工作区目录的绝对路径。
GORACE 用于数据竞争检测的相关选项。
GOROOT Go语言的安装目录的绝对路径。
GOTOOLDIR Go工具目录的绝对路径。

下面我们对这些环境信息进行逐一说明。

CGO_ENABLED

通过上一小节的介绍,相信读者对 cgo 工具已经很熟悉了。我们提到过,标准 go 命令可以自动的使用 cgo 工具对导入了代码包 C 的代码包和源码文件进行处理。这里所说的“自动”并不是绝对的。因为当环境变量 CGO_ENABLED 被设置为 0 时,标准 go 命令就不能处理导入了代码包 C 的代码包和源码文件了。请看下面的示例:

hc@ubt:~/golang/goc2p/src/basic/cgo$ export CGO_ENABLED=0
hc@ubt:~/golang/goc2p/src/basic/cgo$ go build -x
WORK=/tmp/go-build775234613

我们临时把环境变量 CGO_ENABLED 的值设置为 0,然后执行 go build 命令并加入了标记 -x。标记 -x 会让命令程序将运行期间所有实际执行的命令都打印到标准输出。但是,在执行命令之后没有任何命令被打印出来。这说明对代码包 basic/cgo 的构建操作并没有被执行。这是因为,构建这个代码包需要用到 cgo 工具,但 cgo 工具已经被禁用了。下面,我们再来运行调用了代码包 basic/cgo 中函数的命令源码文件 cgo_demo.go。也就是说,命令源码文件 cgo_demo.go 间接的导入了代码包 C。还记得吗?这个命令源码文件被存放在 goc2p 项目的代码包 basic/cgo 中。示例如下:

hc@ubt:~/golang/goc2p/src/basic/cgo$ export CGO_ENABLED=0
hc@ubt:~/golang/goc2p/src/basic/cgo$ go run -work cgo_demo.go
WORK=/tmp/go-build856581210
# command-line-arguments
./cgo_demo.go:4: can't find import: "basic/cgo/lib"

在上面的示例中,我们在执行 go run 命令时加入了两个标记—— -a-work。标记 -a 会使命令程序强行重新构建所有的代码包(包括涉及到的标准库),即使它们已经是最新的了。标记 -work 会使命令程序将临时工作目录的绝对路径打印到标准输出。命令程序输出的错误信息显示,命令程序没有找到代码包 basic/cgo。其原因是由于代码包 basic/cgo 无法被构建。所以,命令程序在临时工作目录和工作区中都找不到代码包 basic/cgo 对应的归档文件 cgo.a。如果我们使用命令 ll /tmp/go-build856581210 查看临时工作目录,也找不到名为 basic 的目录。

不过,如果我们在环境变量 CGO_ENABLED 的值为 1 的情况下生成代码包 basic/cgo 对应的归档文件 cgo.a,那么无论我们之后怎样改变环境变量 CGO_ENABLED 的值也都可以正确的运行命令源码文件 cgo_demo.go。即使我们在执行 go run 命令时加入标记 -a 也是如此。因为命令程序依然可以在工作区中找到之前在我们执行 go install 命令时生成的归档文件 cgo.a。示例如下:

hc@ubt:~/golang/goc2p/src/basic/cgo$ export CGO_ENABLED=1
hc@ubt:~/golang/goc2p/src/basic/cgo$ go install ../basic/cgo
hc@ubt:~/golang/goc2p/src/basic/cgo$ export CGO_ENABLED=0
hc@ubt:~/golang/goc2p/src/basic/cgo$ go run -a -work cgo_demo.go
WORK=/tmp/go-build130612063
The square root of 2.330000 is 1.526434.
ABC
CFunction1() is called.
GoFunction1() is called.

由此可知,只要我们事先成功安装了引用了代码包 C 的代码包,即生成了对应的代码包归档文件,即使 cgo 工具在之后被禁用,也不会影响到其它 Go 语言代码对该代码包的使用。当然,命令程序首先会到临时工作目录中寻找需要的代码包归档文件。

关于 cgo 工具还有一点需要特别注意,即:当存在交叉编译的情况时,cgo 工具一定是不可用的。在标准 go 命令的上下文环境中,交叉编译意味着程序构建环境的目标计算架构的标识与程序运行环境的目标计算架构的标识不同,或者程序构建环境的目标操作系统的标识与程序运行环境的目标操作系统的标识不同。在这里,我们可以粗略认为交叉编译就是在当前的计算架构和操作系统下编译和构建 Go 语言代码并生成针对于其他计算架构或/和操作系统的编译结果文件和可执行文件。

GOARCH

GOARCH 的值的含义是程序构建环境的目标计算架构的标识,也就是程序在构建或安装时所对应的计算架构的名称。在默认情况下,它会与程序运行环境的目标计算架构一致。即它的值会与 GOHOSTARCH 的值是相同。但如果我们显式的设置了环境变量 GOARCH,则它的值就会是这个环境变量的值。

GOBIN

GOBIN 的值为存放可执行文件的目录的绝对路径。它的值来自环境变量 GOBIN。在我们使用 go tool install 命令安装命令源码文件时生成的可执行文件会存放于这个目录中。

GOCHAR

GOCHAR 的值是程序构建环境的目标计算架构的单字符标识。它的值会根据 GOARCH 的值来设置。当 GOARCH 的值为 386 时,GOCHAR 的值就是 8。当 GOARCH 的值为 amd64 时 GOCHAR 的值就是 6。而 GOCHAR 的值 5 与 GOARCH 的值 arm 相对应。

GOCHAR 主要有两个用途,列举如下:

  1. Go 语言官方的平台相关的工具的名称会以它的值为前缀。的名称会以 GOCHAR 的值为前缀。比如,在 amd64 计算架构下,用于编译 Go 语言代码的编译器的名称是 6g,链接器的名称是 6l。用于编译 C 语言代码的编译器的名称是 6c。而用于编译汇编语言代码的编译器的名称为 6a。

  2. Go 语言的官方编译器生成的结果文件会以 GOCHAR 的值作为扩展名。Go 语言的官方编译器 6g 在对命令源码文件编译之后会把结果文件 go.6 存放到临时工作目录的相应位置中。

GOEXE

GOEXE 的值会被作为可执行文件的后缀。它的值与 GOOS 的值存在一定关系,即只有 GOOS 的值为“windows”时 GOEXE 的值才会是“.exe”,否则其值就为空字符串“”。这与在各个操作系统下的可执行文件的默认后缀是一致的。

GOHOSTARCH

GOHOSTARCH 的值的含义是程序运行环境的目标计算架构的标识,也就是程序在运行时所在的计算机系统的计算架构的名称。在通常情况下,它的值不需要被显式的设置。因为用来安装Go语言的二进制分发文件和MSI(Microsoft 软件安装)软件包文件都是平台相关的。所以,对于不同计算架构的 Go 语言环境来说,它都会是一个常量。

GOHOSTOS

GOHOSTOS 的值的含义是程序运行环境的目标操作系统的标识,也即程序在运行时所在的计算机系统的操作系统的名称。与 GOHOSTARCH 类似,它的值在不同的操作系统下是固定不变的,同样不需要显式的设置。

GOPATH

这个环境信息我们在之前已经提到过很多次。它的值指明了Go语言工作区目录的绝对路径。我们需要显式的设置环境变量 GOPATH。如果有多个工作区,那么多个工作区的绝对路径之间需要用分隔符分隔。在 windows 操作系统下,这个分隔符为“;”。在其它操作系统下,这个分隔符为“:”。注意,GOPATH 的值不能与 GOROOT 的值相同。

GORACE

GORACE 的值包含了用于数据竞争检测的相关选项。数据竞争是在并发程序中最常见和最难调试的一类 bug。数据竞争会发生在多个 Goroutine 争相访问相同的变量且至少有一个 Goroutine 中的程序在对这个变量进行写操作的情况下。

数据竞争检测需要被显式的开启。还记得标记 -race 吗?我们可以通过在执行一些标准 go 命令时加入这个标记来开启数据竞争检测。在这种情况下,GORACE 的值就会被使用到了。支持 -race 标记的标准 go 命令包括:go test 命令、go run 命令、go build 命令和 go install 命令。

GORACE 的值形如“option1=val1 option2=val2”,即:选项名称与选项值之间以等号“=”分隔,多个选项之间以空格“ ”分隔。数据竞争检测的选项包括 log_path、exitcode、strip_path_prefix 和 history_size。为了设置 GORACE 的值,我们需要设置环境变量 GORACE。或者,我们也可以在执行 go 命令时临时设置它,像这样:

hc@ubt:~/golang/goc2p/src/cnet/ctcp$ GORACE="log_path=/home/hc/golang/goc2p /race/report strip_path_prefix=home/hc/golang/goc2p/" go test -race
#

关于数据竞争检测的更多细节我们将会在本书的第三部分予以说明。

GOROOT

GOROOT 会是我们在安装 Go 语言时第一个碰到 Go 语言环境变量。它的值指明了 Go 语言的安装目录的绝对路径。但是,只有在非默认情况下我们才需要显式的设置环境变量 GOROOT。这里所说的默认情况是指:在 Windows 操作系统下我们把 Go 语言安装到 c:\Go 目录下,或者在其它操作系统下我们把 Go 语言安装到 /usr/local/go 目录下。另外,当我们不是通过二进制分发包来安装 Go 语言的时候,也不需要设置环境变量 GOROOT 的值。比如,在 Windows 操作系统下,我们可以使用 MSI 软件包文件来安装 Go 语言。

GOTOOLDIR

GOTOOLDIR 的值指明了 Go 工具目录的绝对路径。根据 GOROOT、GOHOSTOS 和 GOHOSTARCH 来设置。其值为 $GOROOT/pkg/tool/$GOOS_$GOARCH。关于这个目录,我们在之前也提到过多次。

除了上面介绍的这些通用的Go语言环境信息,还两个针对于非 Plan 9 操作系统的环境信息。它们是 CC 和 GOGCCFLAGS。环境信息 CC 的值是操作系统默认的 C 语言编译器的命令名称。环境信息 GOGCCFLAGS 的值则是 Go 语言在使用操作系统的默认 C 语言编译器对 C 语言代码进行编译时加入的参数。

如果我们要有针对性的查看上述的一个或多个环境信息,可以在 go env 命令的后面加入它们的名字并执行之。在 go env 命令和环境信息名称之间需要用空格分隔,多个环境信息名称之间也需要用空格分隔。示例如下:

hc@ubt:~$ go env GOARCH GOCHAR
386
8

上例的 go env 命令的输出信息中,每一行对一个环境信息的值,且其顺序与我们输入的环境信息名称的顺序一致。比如,386 为环境信息 GOARCH,而8则是环境信息 GOCHAR 的值。

go env 命令能够让我们对当前的 Go 语言环境进行简要的了解。通过它,我们也可以对当前安装的 Go 语言的环境设置进行简单的检查。

 

 

摘自:

http://wiki.jikexueyuan.com/project/go-command-tutorial/0.14.html