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 /