Go语言 平台与架构

Go 语言开发团队开发了适用于以下操作系统的编译器:

  • Linux
  • FreeBSD
  • Mac OS X(也称为 Darwin)

目前有2个版本的编译器:Go 原生编译器 gc 和非原生编译器 gccgo,这两款编译器都是在类 Unix 系统下工作 。其中,gc 版本的编译器已经被移植到 Windows 平台上,并集成在主要发行版中,你也可以通过安装 MinGW 从而在 Windows 平台下使用 gcc 编译器。这两个编译器都是以单通道的形式工作。

你可以获取以下平台上的 Go 1.4 源码和二进制文件:

  • Linux 2.6+:amd64、386 和 arm 架构
  • Mac OS X(Snow Leopard + Lion):amd64 和 386 架构
  • Windows 2000+:amd64 和 386 架构

对于非常底层的纯 Go 语言代码或者包而言,在各个操作系统平台上的可移植性是非常强的,只需要将源码拷贝到相应平台上进行编译即可,或者可以使用交叉编译来构建目标平台的应用程序(第 2.2 节)。但如果你打算使用 cgo 或者类似文件监控系统的软件,就需要根据实际情况进行相应地修改了。

Go 原生编译器 gc:

主要基于 Ken Thompson 先前在 Plan 9 操作系统上使用的 C 工具链。

Go 语言的编译器和链接器都是使用 C 语言编写并产生本地代码,Go 不存在自我引导之类的功能。因此如果使用一个有不同指令集的编译器来构建 Go 程序,就需要针对操作系统和处理器架构(32 位操作系统或 64 位操作系统)进行区别对待。( 译者注:Go从1.5版本开始已经实现自举。Go语言的编译器和链接器都是Go语言编写的)

这款编译器使用非分代、无压缩和并行的方式进行编译,它的编译速度要比 gccgo 更快,产生更好的本地代码,但编译后的程序不能够使用 gcc 进行链接。

编译器目前支持以下基于 Intel 或 AMD 处理器架构的程序构建。


当你第一次看到这套命名系统的时候你会觉得很奇葩,不过这些命名都是来自于 Plan 9 项目。

g = 编译器:将源代码编译为项目代码(程序文本)
l = 链接器:将项目代码链接到可执行的二进制文件(机器代码)

(相关的 C 编译器名称为 6c、8c 和 5c,相关的汇编器名称为 6a、8a 和 5a)

标记(Flags) 是指可以通过命令行设置可选参数来影响编译器或链接器的构建过程或得到一个特殊的目标结果。

可用的编译器标记如下:

flags:
-I 针对包的目录搜索
-d 打印声明信息
-e 不限制错误打印的个数
-f 打印栈结构
-h 发生错误时进入恐慌(panic)状态
-o 指定输出文件名
-S 打印产生的汇编代码
-V 打印编译器版本
-u 禁止使用 unsafe 包中的代码
-w 打印归类后的语法解析树
-x 打印 lex tokens

从 Go 1.0.3 版本开始,不再使用 8g,8l 之类的指令进行程序的构建,取而代之的是统一的 go build 和 go install 等命令,而这些指令会自动调用相关的编译器或链接器。

如果你想获得更深层次的信息,你可以在目录 $GOROOT/src/cmd 下找到编译器和链接器的源代码。Go 语言本身是由 C 语言开发的,而不是 Go 语言(Go 1.5 开始自举)。词法分析程序是 GNU bison,语法分析程序是名为 $GOROOT/src/cmd/gc/go.y 的 yacc 文件,它会在同一目录输出 y.tab.{c,h} 文件。如果你想知道更多有关构建过程的信息,你可以在 $GOROOT/src/make.bash 中找到。

大部分的目录都包含了名为 doc.go 的文件,这个文件提供了更多详细的信息。

  1. gccgo 编译器:

    一款相对于 gc 而言更加传统的编译器,使用 GCC 作为后端。GCC 是一款非常流行的 GNU 编译器,它能够构建基于众多处理器架构的应用程序。编译速度相对 gc 较慢,但产生的本地代码运行要稍微快一点。它同时也提供一些与 C 语言之间的互操作性。

    从 Go 1 版本开始,gc 和 gccgo 在编译方面都有等价的功能。

  2. 文件扩展名与包(package):

    Go 语言源文件的扩展名很显然就是 .go

    C 文件使用后缀名 .c,汇编文件使用后缀名 .s。所有的源代码文件都是通过包(packages)来组织。包含可执行代码的包文件在被压缩后使用扩展名 .a(AR 文档)。

    Go 语言的标准库(第 9.1 节)包文件在被安装后就是使用这种格式的文件。

    注意 当你在创建目录时,文件夹名称永远不应该包含空格,而应该使用下划线 “_” 或者其它一般符号代替。