通向Golang的捷径【2.安装和环境配置】

2.1 平台与架构

Go 开发组为以下操作系统, 开发了编译器:
• Linux
• FreeBSD
• OS X(或称 Darwin)

同时 Go 编译器包含了两个版本:gc 和 gccgo, 它们都可工作在类 Unix 的操作系统中, gc 编译器已经移植到Windows 平台且公开发布了, 这两个编译器都采用单阶 (single pass) 编译方式.

在以下软硬件平台上,Go 1 同时发布了源码版本和二进制版本.
• FreeBSD 7+: amd64,386
• Linux 2.6+: amd64,386,arm
• OS X(Snow Leopard + Lion): amd64,386
• Windows 2000 及后续版本: amd64,386

在上述操作系统中,Go 代码可提供良好的移植性 (假定只使用了纯粹的 Go 代码, 未包含 cgo 和其他底层包),所以既可以在操作系统之间复制代码完成编译, 也可采用交叉编译 (参见 2.2 节).

2.1.1 gc 编译器

该编译器基于 Ken Thompson 在 Plan 9 操作系统上, 开发的 C 工具链, 因此 gc 编译器和链接器的开发, 都使用了 C 语言, 所以可生成原生代码 (其中不包含 Go 的自举或自引导代码), 因此不同的操作系统和处理架构 (32bit,64bit) 都需要提供不同的编译器.

gc 的编译速度快于 gccgo, 并能生成更好的原生代码, 同时无须与 gcc 关联, 所以不存在沿袭与合并, 带来的隐藏问题, 而且可实现并行.

下表列出了不同 Intel 和 AMD 处理器适用的编译器:

处理器字节 名称 编译器 链接器
64bit amd64(x86-64) 6g 6I
32bit 386(x86,x86-32) 8g 8I
32bit RISC arm(ARM) 5g 5I

从上表可见, 编译器和链接器的命名有些奇怪 (来自于 Plan 9 项目的命名规则),
• g 为编译器, 基于源代码可生成目标代码.
• i 为链接器, 可将目标代码转换成二进制执行代码.

因此对应的 C 编译器为 6c,8c,5c, 汇编器为 6a,8a,5a.

下表列出了 gc 支持的硬件架构和操作系统的版本号,

操作系统 硬件架构 操作系统的版本号
linux 386/amd64/arm >= Linux 2.6
darwin 386/amd64 OS X(Snow Leopard + Lion)
freebsd 386/amd64 >= FreeBSD 7
windows 386/amd64 >= Windows 2000

windows 版本 (8g 与 6g) 的 95% 都来自于外部贡献 (Google 之外的开发者),Google 开发组提交了 arm 版本, 并最终能运行在 Android 操作系统 (隶属于 Google 智能电话项目) 下, 所以 Go 应用也能运行 Android 中.

gc 编译器在命令行中, 可配置一些选项, 而这些选项可影响编译和连接, 或是生成特定的输出, 编译器选项如下:

C:\Users\ivo>8g
gc: usage: 8g [flags] file.go…
flags:
-I DIR search for packages in DIR
-d print declarations
-e no limit on number of errors printed
-f print stack frame structure
-h panic on an error
-o file specify output file
-S print the generated assembly code
-V print the compiler version
-u disable package unsafe
-w print the parse tree after typing
-x print lex tokens

-I 可提供需要编译 Go 文件的路径 (也可包含环境变量 $GOPATH).

链接器的选项如下:

C:\Users\ivo>8l
usage: 8l [-options] [-Eentry] [-H head] [-I interpreter] [-L dir] [-T text] [-R rnd] [-r path] [-o out] main.8

-L 可提供需要编译 Go 文件的路径 (也可包含环境变量 $GOPATH).

编译器和链接器的源代码, 放在 $GOROOT/src/cmd 目录下, 查看其中的文件可知,Go 语言开发使用了 C, 而不是 Go 语言本身, 同时使用了 GNU bison 生成了 lexer/parser(编译所需的文法器/解析器), G O R O O T / s r c / c m d / g c / g o . y ( y a c c ) g r a m m a r / p a r s e r ( / ) , , y . t a b . c , h , M a k e f i l e , , GOROOT/src/cmd/gc/go.y 文件 (yacc 文件) 将控制 grammar/parser(语法器/解析器), 并在相同目录下, 将生成输出文件y.tab.{c,h}, 可查看该目录下的 Makefile, 以得到构建步骤的更多信息, 而构建步骤的主要内容都包含在 GOROOT/src/make.bash 文件中.

doc.go 文件中包含了大部分的目录信息.

2.1.2 gccgo 编译器

这是一个使用 gcc 为后端的传统编译器, 使用 GNU 编译器, 可兼容大量的处理器架构, 但编译速度比较慢, 而生成的原生代码的执行速度也比较快, 同时需要提供一些与 C 语言关联的信息.

2011 年 3 月 25 日发布的 GCC 4.6.0 版本中, 已经集成了 Go 编译器, 当然其中也包含了其他语言的支持 (比如 Ada,C,C++,Fortran,Java), 相关信息可查看 http://golang.org/doc/gccgo 页面,gc 和 gccgo 编译器的功能是一致的.

2.1.3 文件扩展名和包

Go 源码文件的扩展名为 go, 源码文件可合并成包 (package), 包含二进制代码的包可进行压缩, 提供的扩展名为 a(AR 压缩格式), 它也是 Go 标准库包的格式, 链接 (目标) 文件的扩展名为 o, 可执行程序的默认扩展名,在 Unix 系统中为 out, 在 Windows 系统中为 exe.

注意, 在自定义目录下, 使用 Go 语言的工具时, 应当保证目录名中, 不存在空格, 可以使用_符号替换空格.

2.2 环境变量

在 Go 语言中, 使用了少量的环境变量, 应完成它们的定义后, 再进行 Go 语言的安装, 在Windows 中, 可预先定义一个空的根目录, 比如c:\go, 所需的环境变量如下:

  • $GOROOT: 大多数情况下, 该变量为 $HOME/go, 当然也可选择 go 源码目录或是安装文件的存放目录,作为根目录.
  • $GOARCH: 目标系统的处理器架构, 通常为 386,amd64,arm.
  • $GOOS: 目标系统的操作系统, 通常为 darwin,freebsd,linux,windows.
  • $GOBIN: 工具 (比如编译器, 链接器等) 的存放目录, 默认为 $GOROOT/bin.
  • $GOPATH: 默认为 GOROOT, 通常可定义一组路径, 用于存放 Go 源码, 二进制包和可执行文件, 一般指定为 GOPATH 的子目录, 比如 src,pkg 和 bin, 这些变量必须设定, 以方便语言工具的使用.
  • $GOROOT_FINAL: 默认为 GOROOT, 通常无须清晰定义, 如果 Go 安装后, 需要移动到另一个目录,这时可该路径中, 设定 Go 安装文件的最终路径.
  • $GOARM: arm 架构, 可能是 5 或 6, 默认值为 6.
  • $GOMAXPROCS: 指定一组 Go 应用所需支持的硬件核心 (处理器), 参见 14.1.3.

Go 编译器支持交叉编译.

在后续小节, 将讨论 Go 语言的安装, 比如 Linux,OS X 和 Windows 的安装, 而 FreeBSD 的安装可使用Linux 的安装方法, 而 Go 语言正在移植到其他的操作系统中, 比如OpenBSD, DragonFlyBSD, NetBSD, Plan 9,Haiku 和 Solaris, 最新的进展可查看http://go-lang.cat-v.org/os-ports 页面.

2.3 Linux 安装

该安装方式需要下载 Go 语言源码, 进行重新编译, 并能从 verb|//golang.org/doc/install.html| 页面中, 查找到最新的安装方法, 如以下小节的描述.

2.3.1 设置环境变量

在 Linux 系统中, 可在 shell 配置文件 ($HOME/.bashrc 或 $HOME/.profile, 又或是其他的等价文件, 并可使用 gedit 和 vi 编辑器进行文本编辑) 中, 设定 Go 语言所需的环境变量,

C:\Users\ivo>8l
export GOROOT=$HOME/go
export GOBIN=$GOROOT/bin
export GOARCH=amd64
export GOOS=linux

为了在文件系统中, 可搜索到 Go 语言的二进制执行文件, 需将这些文件的目录, 加入到系统的检索路径中:

C:\Users\ivo>8l
export PATH=$GOBIN:$PATH

Go 语言的附带工具, 将使用 GOPATH 环境变量,

export GOPATH=$HOME/goprograms
或者
export GOPATH=$GOROOT

如果登录的账号名为 user1, 那么$HOME 即为/home/user1, 将当前目录加入到 GOPATH 环境变量,

export GOPATH=$GOPATH:.

. 表示当前目录, 使用: 符号, 可加入多个目录, 以便 Go 源码目录, 包对象目录, 可执行工具目录加入到 GOPATH环境变量.

使用 source .bashrc 命令, 可使控制台复位, 并重新载入.bashrc, 以便新设定的环境变量能够启用 (在控制台窗口中, 可使用 env | grep ^GO 或 echo $GOROOT 等命令, 可测试环境变量的设定是否成功).

2.3.2 安装 C 工具链

Go 语言的工具链是由 C 语言开发的, 因此在工具链的构建中, 需要以下软件包:
• GCC
• C 标准开发库:Libc6-dev
• 解析生成器:Bison
• make
• gawk
• 文本编辑器 ed

在基于 Debian 的 Linux 系统中 (比如 Ubuntu), 可使用以下命令, 安装工具链编译所需的软件包:

sudo apt-get install bison ed gawk gcc libc6-dev make

而在其他类型的 Linux 系统中, 可使用 RPM 工具.

2.3.3 安装 Mercurial

Go 语言源码使用了 Mercurial 版本控制工具, 因此需要安装对应的软件包, 在控制台中输入 hg, 可测试 Mercurial 是否已经安装,

sudo apt-get install mercurial

在安装过程中, 可能会出现缺少其他依赖包的错误, 因此还需要安装以下依赖包:

apt-get install python-setuptools python-dev build-essential

如果依然无法安装 Mercurial, 可在http://mercurial.selenic.com/wiki/Download 页面, 直接下载 Mercurial 源码, 手工编译安装.

在 Mercurial 1.7 和后续版本中, 需要提供 CAs(Certification Authorities, 权威认证) 配置, 如果在 Mercurial运行时, 未查找 CAs 配置, 将出现错误信息, warning: go.googlecode.com certificate with fingerprint b1:af: …bc not verified (check hostfingerprints or web.cacerts config setting), 这时需要确认 Mercurial 的版本 ( hg-version), 并配置 CAs.

2.3.4 从源码仓库获取 Go 源码

Go 语言的安装目录需命名为 go, 并配置给环境变量 $GOROOT, 使用以下命令, 可从源码仓库获取 Go 源码:

hg clone -u release https://go.googlecode.com/hg/ $GOROOT

2.3.5 构建

cd $GOROOT/src
./all.bash

构建和测试需要一些时间 (通常是数分钟), 当构建成功后, 将出现以下文本:

ALL TESTS PASSED
Installed Go for linux/amd64 in /home/you/go.
Installed commands in /home/you/go/bin.
*** You need to add /home/you/go/bin to your $PATH. ***
The compiler is 6g.

这时在系统中, 已经安装好相符的 Go 语言环境.

如果在构建过程中出现错误, 可使用命令 hg pull -u, 从源码仓库中, 获取更新内容, 并重新进行构建. 在构建过程中, 会进行 http 测试 (网络测试), 并需要连接到 google.com(2016 年 7 月 10 日 google.com 依然处于被墙的状态, 可使用 vpn 解决 google.com 的连接问题). 从而引发一个经常出现的问题:

‘make[2]: Leaving directory /localusr/go/src/pkg/net’

这通常是由于系统防火墙所导致的问题, 在构建过程中, 可暂时关闭系统防火墙, 或者使用另一个方法, 取消网络测试, 也就是在.bashrc 添加一行命令:

DISABLE_NET_TESTS=1

如果需要取消网络包的测试, 可在 go/src/pkg 目录下的 Makefile 中, 添加 NOTEST 命令. 如果不需要运行网络测试, 也可运行./make.bash.

2.3.6 验证安装结果

在文本编辑器中, 输入以下文本, 并保存成 test.go 文件,

package main
func main () {
    println("Hello", “world”)
}

• 6g test.go, 进行源码编译
• test.6, 生成的编译文件
• 6l test.6, 进行编译文件的链接
• 6.out, 生成的可执行文件
• ./6.out, 执行编译完成的二进制文件
• Hello,world, 执行文件产生的文本输出

以下是 64bit 操作系统的工具, 在 32bit 系统中, 需使用 8g/8l, 在 arm 系统中, 则使用 5g/5l.

2.3.7 验证安装版本

使用 release 命令可验证 Go 语言的版本:
• 验证静态版本号, 比如 release.r60 9481
• 验证日期版本号, 比如 release.2011-01-06 release 7053

验证已安装的版本号:

cd $GOROOT
hg identify

最快的验证方法, 是采用命令 go version, 或是编译器的-V 选项 (6g -V 或是 8g -V), 它们将产生以下的输出文本,8g version 7053 release.2011-01-06 release. 同时 Go 语言的当前版本, 也可通过 runtime 包的 Version 函数进行获取:

package main
import (
    “fmt”
    “runtime”
)

func main ( ) {
    fmt.Printf("%s", runtime.Version())
}

执行上述程序, 可得到输出文本,7053 release.2011-01-06 release.

2.3.8 版本更新

cd $GOROOT
hg pull
hg update release
cd src
sudo ./all.bash

从http://golang.org/doc/devel/release.html 页面中, 可查看版本信息, Go 语言的第一个静态版本为 r56(2011.03.16),从 2011 年 3 月 15 日开始, 每周都有最新的改动被加入, 因此每周都需要使用 hg 进行同步更新, 而目前的最新版本为 Go 1, 也就是说第一个静态版本已经历了一年的维护. 在 Go 语言仓库中, 也给出了以下三个分支源码树:
• Go release: 静态版本, 满足大多数的 Go 语言开发
• Go weekly: 每周的更新版本
• Go tip: 最新的开发版本

如果需要及时跟踪 Go 语言的改进, 可选择后两个版本, 使用 gofix 工具, 也可得到最新版本.

不同版本的文档

http://golang.org/pkg 页面, 将给出最新静态版本的文档, 当最新版本发布时, 该文档也将更新,http://weekly.goneat.org/pkg/页面, 将给出周版本的文档, http://tip.goneat.org/pkg/将给出最新开发版本的文档, 在有些站点中,goneat 将替换成 golang.

安装软件包

在http://go-lang.cat-v.org/packages 页面下, 可找到 Go 语言的安装软件包, 在https://launchpad.net/~cz.niclabs/+archive/golang 页面下, 可下载 Ubuntu 的安装软件包.

2.4 OS X 安装

(略)

2.5 Windows 安装

(略)

2.6 安装结果

当 Go 语言安装完成, 将在根目录 ($GOROOT) 中, 出现以下文件结构:
• README,AUTHORS,CONTRIBUTORS,LICENSE 文件
• \bin 子目录: 包含所有的可执行文件 (比如编译器), 以及所有的附带工具
• \doc 子目录: 包含教程, 代码概述, 本地文档, 问题集和 logo 等
• \include 子目录: C/C++ 头文件
• \lib 子目录: 文档的模板
• \misc 子目录: 支持 Go 的文本编辑器所需的配置文件,cgo 示例等
• \pkg\os_arch 子目录: 包含了操作系统的架构, 比如 linux_amd64,windows_386 等, 以及所有标准库包的目标文件 (.a)
• \src 子目录: bash 脚本文件和 make 文件
• \cmd 子目录: 编译器所需的脚本和源码文件 (Go,C), 以及相关命令文件
• \lib9\libbio和libmach 子目录: C 文件
• \pkg 子目录: 所有标准库包的 Go 源码文件 (这才是开源软件!)

在 Windows 386 r59 版本中, 将包含 3084 个文件,355 个目录, 容量约为 129MB, 在 Linux 64bit r60 版本中,将包含 3958 个文件, 容量约为 176MB.

2.7 Go 的运行时状态

尽管编译器可生成原生机器码, 但机器码需在一个运行时状态下运行 (runtime 包可提供对应功能), 该运行时状态有时与 Java 和.Net 的虚拟机很相似, 它将负责内存分配, 垃圾收集 (参见 10.8 节), 堆栈处理, 并发协程,并发通道, 切片,map, 发射等诸多功能.

在 Go 包的链接中,runtime 属于上层包, 大部分使用了 C 语言, 可在$GOROOT/src/pkg/runtime/ 目录下找到它 (可参看 mgc0.c 和其他 m 开头的文件).

垃圾收集器

6g 包含了一个简单高效的 mark-and-sweep(标记与互换) 收集器, 同时收集器的开发仍在继续, 目前使用了IBM 提出的循环垃圾收集器, 以创建一个更高效和低延时的并发收集器, 目前 gccgo 中未包含收集器, 准备使用正在开发的收集器, 而具备垃圾收集功能的语言, 并不意味着用户可以忽略内存分配的问题, 因为内存的分配和释放, 都需要使用 CPU 资源.

Go 可执行文件的尺寸, 将远大于源码文件的尺寸, 这时因为 Go 运行时状态会嵌入到每个可执行文件中, 当机器中运行了大量的类似应用时, 这种嵌入很明显是一个缺陷, 但是这也使 Go 得到了一个静态二进制文件 (在执行中无须其他文件的支持), 因此它的开发比 Java 或 Python 更简单, 同时也不会引入不同版本之间的依赖问题.

2.8 Go 解析器

由于 Go 语言实现了与动态语言相似的快速编译, 很自然地联想到,Go 语言是否也实现了, 与动态语言相似的编译方法 (read-eval-print loop),Sebastien Binet 开发了 Go 语言的解析器, 从https://bitbucket.org/binet/igo页面中, 可找到相关信息.

在这里插入图片描述

发布了80 篇原创文章 · 获赞 10 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/osoon/article/details/103741227