25

你真的不用再设置 GOROOT 了

 4 years ago
source link: http://www.poloxue.com/go/you-dont-need-set-goroot/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

作者:Dave Cheney | 地址: you-dont-need-to-set-goroot-really

一篇小短文,解释了为什么在编译和使用 GO 时,不再需要设置 GOROOT。

概要性介绍

一般来说,在 Go 1.0 之后,编译和使用 GO 的时候,不再需要设置 GOROOT。事实上,如果你的电脑上存在多个版本的 Go 语言环境,设置 $GOROOT 可能导致很难调试。

你仍然需要设置 $GOPATH。从 Go 1.0 开始,GOPATH 就被强烈推荐。随着 Go 1.1 的发布,GOPATH 已经是强制性的了。

为什么不再要设置 GOROOT?

谈些 Go 环境变量的历史吧!

Go 的资深老前辈们可能还记得,曾经的 Go 不仅要设置 GOROOT,还需要设置 GOOS 和 GOARCH。之所以要设置 GOROOT,是因为 Make 在编译构建的时候,引入了 GOROOT 中的内容,要提前设置 GOROOT 作为了它们的基本路径。

随着 go tool 的引入,Go 1.0 之前,$GOOS 和 GOARCH 已经变成可选了,因为构建脚本已经能自动检测出系统类别和 CPU 架构。随着 Go 1.0 的发布,以及 cmd/dist 引导构建工具的引入,GOOS 和 GOARCH 真正意义上是可选项了,仅仅在交叉编译时,才会用到。

不需要设置 GOOS 和 GOARCH,那 GOROOT 呢?

\$GOROOT 定义为指定安装 GO 的根目录。在之前的 Makefile 中,它被用于指定引入其他 Makefile 的基础路径。还有,在 Go 1.0 之后, go tool 利用它查找 Go 编译器(保存在 \$GOROOT/pkg/tool/\$GOOS \$GOARCH`)和标准库(在 \$GOROOT/pkg/\$GOOS \$GOARCH)。如果你是一名 Java 开发者,可以将 GOROOT 理解为 $JAVA_HOME。

通过源码编译 Go,$GOROOT 将自动发现(all.bash 的上级目录),然后嵌入到 go 工具链。执行如下命令查看:

$ echo $GOROOT

$ go env
/home/dfc/go

从 golang.org 下载的二进制包或者系统方式安装的 Go 环境,也已在工具链中设置了正确的 GOROOT。一个例子,比如 Ubutun 12.04 下,安装了 Go 1.0。

$ dpkg -l golang-{go,src} | grep ^ii
$ go
/usr/bin/go
$ go env GOROOT
/usr/lib/go

我们可以看出,Go 工具链被安装在了 /usr/bin/go 下,$GOROOT 内置为 /usr/lib/go

为什么不应该设置 GOROOT

我们不应该设置 GOROOT,是因为 Go 工具链已经内置了正确的值。

设置 GOROOT 将会覆盖掉保存在 go 工具链中的默认值,可能会导致 go 执行不同版本的编译器和标准库文件。

两种情况下,你需要设置 $GOROOT。在官方的 安装介绍 有相关的描述。

  • 如果你是 Linux、FreeBSD 或者 OS X 用户,下载了 zip 和 tarball 的二进制包安装环境。这些二进制的默认环境位于 /usr/local/go,建议你将 Go 安装到这个位置。如果选择不这么做,就必须设置到你指定的目录下。
  • 如果你是 Windows 用户,使用 zip 二进制包安装,默认的 \$GOROOT 在 C:\Go 目录下。如果你将 Go 安装在其他位置,请设置 \$GOROOT 到指定的目录。

其他细节

本文已经介绍了当通过源码编译 Go 环境的时候,\$GOROOT 如何自动发现的。但如果 \$GOROOT 与 all.bash 所在位置并不匹配呢?比如,在临时目录下编译 Go 环境,如何正确地设置 \$GOROOT 呢?答案是使用 \$GOROOT_FINAL,它将被用于覆盖自动发现的 \$GOROOT,设置到 GO 工具链中。

举个例子,在 Debian/Ubuntu 上,构建程序会将 \$GOROOT_FINAL 的值设置为 /usr/lib/go。保持 $GOROOT 是未设置状态,使构建编译愉快地执行。构建完成后,将 Go 工具链安装到 /usr/bin 目录下,编译器、源码和包安装到 /usr/lib/go 下。

注意点

如果使用二进制包安装 Go 环境,有些特殊情况需要处理,本文已经作了相关描述。

虽然构建系统能自动检测,但如果 all.bash 的父级目录不满足 \$GOROOT 要求,也需要另外处理。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK