Go语言形象标识
一、下载Go语言的源代码
为了吸引更多的社区开发力量,Google开源了Go语言的源代码,并托管于世界著名的github网站中。我们可以通过执行以下命令获取Go语言的全套源代码:
$ git clone https://github.com/golang/go.git
由于当前最新发布的Go语言的稳定版本为Go 1.6,并且官方从该版本开始正式支持MIPS架构的处理器,故笔者以Go 1.6为例展示Go语言环境在龙芯平台上的构建方法。为了最大限度减少Go语言对其它编程工具的依赖,从Go 1.5开始,Go语言的编译器、汇编器和链接器等底层工具链全部使用Go语言来实现。故自Go 1.5开始,从源代码安装Go语言环境时需要使用现成的Go语言编译器来编译Go的源代码,上述过程称为Go语言的自举编译。因此,从源代码安装Go 1.6时要求系统中存在Go 1.4及其以上的Go语言环境。
由于官方从Go 1.6才开始正式支持MIPS架构,因而无法找到现成的可用于在龙芯上进行自举编译的低版本Go编译器。好在Go语言提供了友好的交叉编译功能,我们可以借助X86的机器编译一个MIPS平台的Go编译器,用作在龙芯上从源码构建Go 1.6的自举编译器。因此,在龙芯平台上从源代码构建Go 1.6的环境必须分成两个阶段进行:
1) 在X86平台上交叉编译出面向MIPS平台的Go语言自举编译工具链;
2) 在龙芯平台上利用1)中的Go自举编译器构建Go 1.6开发环境。
下面笔者逐步向大家展示Go 1.6环境在龙芯平台上的构建过程。等大家走完整个过程就会发现,在龙芯上从源代码安装Go语言环境非常简单。
第一阶段:在X86平台上交叉编译出面向MIPS平台的Go语言自举编译工具链。
随便找一台装有64位Linux操作系统的X86电脑,逐步执行以下命令。
1. 下载Go 1.4(或者更高版本)的二进制发行版作为交叉编译的自举编译工具链
笔者选择Go 1.4的发行版作为在X86上编译Go 1.6源代码的自举编译器。由于官网 https://golang.org 在国内无法正常访问,可以通过其镜像站点 http://golangtc.com/download进行下载。笔者下载的文件为go1.4.2.linux-amd64.tar.gz,大小约59 M。下载后可以解压到任意目录,例如可以通过如下命令将其解压到/opt文件夹下并重命名为go1.4.2:
$ mv /opt/go /opt/go1.4.2
2. 配置交叉编译的自举编译工具链
3. 下载Go 1.6的源代码
$ git clone https://github.com/golang/go.git
4. 切换到Go 1.6的发行版
$ git checkout release-branch.go1.6
5. 交叉编译
这一步通过执行脚本bootstrp.bash完成。该脚本执行前,需要通过环境变量GOOS和GOARCH分别指明交叉编译的目标操作系统和处理器架构。
$ GOOS=linux GOARCH=mips64le https://www.loongson.cn/index.php/news/bootstrap.bash
接下来就是等待交叉编译结束了。由于交叉编译无需执行Go语言官方自带的测试集,一般10分钟内即可完成编译。不出意外的话,整个过程应该非常顺利。如果您看到以下提示,则表明交叉编译成功。
Bootstrap toolchain for linux/mips64le installed in /home/fool/workspace/golang/go-linux-mips64le-bootstrap.
Building tbz.
-rw-rw-r-- 1 fool fool 46736199 6月 3 09:08 /home/fool/workspace/golang/go-linux-mips64le-bootstrap.tbz
交叉编译所生成的面向MIPS平台的Go语言自举编译工具链位于压缩包/home/fool/workspace/golang/go-linux-mips64le-bootstrap.tbz中。将该压缩包拷贝到龙芯电脑中备用。
第二阶段:在龙芯平台上从源代码构建Go 1.6开发环境。
1. 解压交叉编译生成的面向MIPS平台的自举编译工具链
2. 简单检验自举编译工具链是否可用
$ export GOROOT=/home/loongson/workspace/go-linux-mips64le-bootstrap
$ https://www.loongson.cn/index.php/news/go version
3. 下载Go 1.6的源代码并切换到Go 1.6的发行版。
$ git clone https://github.com/golang/go.git
$ cd go
$ git checkout release-branch.go1.6
4. 编译配置
在当前目录创建名为env.sh的shell脚本,输入以下语句后保存退出。
export GOROOT_BOOTSTRAP=/home/loongson/workspace/go-linux-mips64le-bootstrap
export GOROOT=/home/loongson/workspace/go
执行env.sh,以完成编译配置。
$ https://www.loongson.cn/index.php/news/all.bash
ok cmd/cover 18.360s
ok cmd/doc 0.393s
ok cmd/fix 0.192s
panic: test timed out after 3m0s
goroutine 489 [running]:
panic(0x120552480, 0xc4203087f0)
/home/loongson/workspace/go/src/runtime/panic.go:500 +0x4c4
testing.startAlarm.func1()
/home/loongson/workspace/go/src/testing/testing.go:918 +0x168
created by time.goFunc
/home/loongson/workspace/go/src/time/sleep.go:132 +0x5c
…
FAIL cmd/go 208.996s
ok cmd/gofmt 0.270s
ok cmd/internal/goobj 0.064s
ok cmd/internal/obj 0.032s
ok cmd/internal/obj/x86 0.067s
ok cmd/internal/pprof/profile 0.048s
ok cmd/link 0.077s
ok cmd/nm 9.304s
测试项目cmd/go没有通过测试。这是为什么呢?笔者起初怀疑编译生成的Go 1.6可能有问题,反复检查了编译参数的设置,但错误依旧。后来,考虑到官方既然已经宣布Go 1.6直接支持MIPS,编译出错的概率应极小,更何况前面那么多的测试项目都能正确运行。于是将思路从对编译参数的检查转向对测试参数的排查。显然,错误由测试超时导致,而默认的超时阈值仅为3分钟。对于龙芯和ARM等低主频的处理器,cmd/go测试项的执行时间可能会超过3分钟。因此,在龙芯平台上有可能需要适当增大测试超时的阈值。后来,经过一系列分析和排查,终于找到了环境变量GO_TEST_TIMEOUT_SCALE,用于对测试超时的阈值进行倍增。例如,若设置GO_TEST_TIMEOUT_SCALE = 2,则测试超时的阈值扩大为原来的两倍,即由3分钟增大到6分钟。
6. 重新编译
根据具体平台的需要在env.sh中增加对环境变量GO_TEST_TIMEOUT_SCALE的设置,例如以下为适用于龙芯平台的env.sh。
export GOROOT_BOOTSTRAP=/home/loongson/workspace/go-linux-mips64le-bootstrap
export GOROOT=/home/loongson/workspace/go
# Added for Loongson
export GO_TEST_TIMEOUT_SCALE=2
上述修改完成后,重新执行env.sh和all.bash这两个脚本。
$ source env.sh
$ cd src
$ https://www.loongson.cn/index.php/news/all.bash
---
Installed Go for linux/mips64le in /home/loongson/workspace/go
Installed commands in /home/loongson/workspace/go/bin
*** You need to add /home/loongson/workspace/go/bin to your PATH.
7. 安装编译生成的Go 1.6。
在~/.bashrc的末尾添加如下语句
export PATH=$PATH: $GOROOT/bin
三、龙芯上Go语言对全世界的问候
激动人心的时刻终于到来了!我们先运行一下Go命令,打印一下版本信息吧:
go version go1.6.2 linux/mips64le
import "fmt"
func main() {
fmt.Printf("Hello World! ")
}
Hello World!
亲自感受了Go语言在龙芯上的第一个HelloWorld,真是太令人兴奋了!
上述编译和执行的过程也可以使用go run命令一次性完成,例如
Hello World!
四、继续把玩 Go!Go!Go!
看到这里,有读者不禁会问:除了运行简单的HelloWorld,龙芯平台上的Go还能干什么?Go语言具有方便移植的特性。所有利用Go语言编写的应用程序,经过相应平台的Go语言编译器编译后,都能够在该平台上运行。所以Go语言环境在龙芯平台上的成功构建意味着龙芯拥有了Go的全套软件生态。之前在X86或ARM等平台上搭建的基于Go语言的应用系统,现在都能够以较低的代价迅速迁移到龙芯平台上来。
眼下基于Go的开源项目非常多,笔者没有时间一一搭建。笔者生性好玩,故专门挑选了几个较为有意思项目进行试验。感兴趣的朋友可以尝试更多的项目。需要特别注意的是,在测试开源项目时,还需要额外 设置GOPATH环境变量。这是因为许多开源项目引用了Go语言的第三方库,需要从GOPATH环境变量指向的路径中加载第三方库或者将所引用的第三方库下载到该路径中。例如,笔者的设置如下:
1. 碰撞反弹游戏(https://github.com/kurehajime/pong-command)
游戏时,输入任意一个字符串(如go1.6.2),该字符串会沿直线运动,遇到上下边界或左右围栏则镜面反弹。左侧围栏由电脑自动控制,右侧围栏由玩家操作。游戏的目标是控制右侧围栏在垂直方向的位置,使得字符串不断被碰撞反弹。
龙芯平台上的碰撞反弹游戏
1. 汉语拼音转换工具(https://github.com/mozillazg/go-pinyin)将任意汉字转换成对应的汉语拼音。例如,输入“龙芯俱乐部”的执行情况如下:
龙芯平台上的汉语拼音转换工具
1. 翻译助手Utran(https://github.com/zengsai/utran)
可以将英文翻译成汉语。例如,输入“This is go1.6.2 running on Loongson.”的执行情况如下:
龙芯平台上的翻译助手Utran
1.排序算法可视化(https://github.com/SimonWaldherr/GolangSortingVisualization)
可将常见的冒泡、选择、插入和快排等排序算法的排序过程可视化。一、遇到问题怎么办?
以上是笔者在龙芯平台上从源代码构建Go语言环境的记录。读者按照这些操作步骤也应该能快速构建好Go语言开发环境。如果遇到问题自己不能解决,龙芯社区提供了官方的Bug服务网站(http://bugs.loongnix.org/login_page.php),您可以把遇到的问题提交上去,龙芯团队的人会及时为您解决。