为了账号安全,请及时绑定邮箱和手机立即绑定

源码安装GO

标签:
Go


安装Go语言,建议通过源码安装。通过源码安装Go,一般只需要安装一个GCC编译器就可以了。(Windows下是安装MinGW)。该文分析通过源码安装Go语言的过程。

一、分析安装脚本

在《探究Go中各个目录的功能》一文中提到了几个脚本,以及它们的作用。现在来分析这些脚本都做了些什么。(以linux下为例,Windows对应的脚本类似)

1、all.bash

1

set -e

2

if [ ! -f make.bash ]; then

3

    echo 'all.bash must be run from $GOROOT/src' 1>&2

4

    exit 1

5

fi

6

OLDPATH="$PATH"

7

. ./make.bash --no-banner

8

bash run.bash --no-rebuild

9

PATH="$OLDPATH"

10

$GOTOOLDIR/dist banner  # print build info

说明:

1)set -e 当脚本中某个命令返回非零退出状态时,脚本退出

2)if语句 是要求all.bash必须在make.bash所在的目录运行(也就是$GOROOT/src)

3)OLDPATH=”$PATH” 保存当前PATH

4)执行make.bash并传递–no-banner参数

5)执行run.bash并传递–no-rebuild参数

6)执行dist工具并传递 banner参数,打印build信息

2、make.bash

在make.bash中,有一些环境变量,执行make.bash过程中会用到。

①GOROOT_FINAL:最终被设置的Go root,在编译过程中,默认是Go tree的位置。

②GOHOSTARCH:为主机工具(编译器和二进制文件)指定体系结构。这种类型的二进制文件在当前系统必须是可执行的,因此设置这个环境变量的目前唯一常见原因是在AMD64机器上设置GOHOSTARCH=386。(也就是说,在ADM64上可以运行386的可执行文件)

③GO_GCFLAGS:当构建包和命令时可以通过该环境变量附带上5g/6g/8g的参数

④GO_LDFLAGS:当构建包和命令时可以通过该环境变量附带上5l/6l/8l的参数

⑤CGO_ENABLED:在构建过程中控制cgo的使用。当设置为1,在构建时,会包含所有cgo相关的文件,如带有”cgo”编译指令的.c和.go文件。当设置为0,则忽略它们(即禁用CGO)

在文件开头是一些检查:比如是否在Windows下运行了make.bash,ld的版本等。

make.bash中接下来主要的工作(也就是开始构建):

1)构建 C 引导工具 —— cmd/dist

这里首先会export GOROOT环境变量,它的值就是go源码所在路径,可见,源码安装之前并不要求一定要设置GOROOT。

这里学习一个shell脚本知识

GOROOT_FINAL=”${GOROOT_FINAL:-$GOROOT}”

这叫做参数替换,形式如下:

${parameter-default},${parameter:-default}

意思是:如果 parameter 没被 set,那么就使用 default。这两种形式大部分时候是相同的。区别是:当parameter被设置了且为空,则第一种不能输出默认值,而第二种可以。

所以,GOROOT_FINAL=”${GOROOT_FINAL:-$GOROOT}”的意思就是,如果GOROOT_FINAL没设置,则GOROOT_FINAL=$GOROOT

通过gcc编译cmd/dist

2)构建 编译器和Go引导工具

首先通过执行dist设置需要的环境变量

eval $(./cmd/dist/dist env -p)

接着构建Go引导工具:go_bootstrap,以及编译器等

3)构建 包和命令工具

这是通过go_bootstrap做的

3、run.bash

该脚本是一个测试脚本,运行标准库中的测试用例。默认情况下会重新构建go包和工具。由于make.bash会做构建的工作,all.bash中执行run.bash时,传递了–no-rebuild

二、源码安装说明

源码安装Go语言,一般只需要执行./all.bash就可以了。(Windows上执行all.bat)

根据上面的分析,这样会运行测试脚本。如果想更快的安装Go,可以直接运行make.bash(Windows上是make.bat)

整个安装过程大概如下:

# Building C bootstrap tool.

cmd/dist

# Building compilers and Go bootstrap tool for host, linux/amd64.

lib9

libbio

libmach

misc/pprof

……

pkg/text/template/parse

pkg/text/template

pkg/go/doc

pkg/go/build

cmd/go

# Building packages and commands for linux/amd64.

runtime

errors

sync/atomic

sync

io

……

testing

testing/iotest

testing/quick

# Testing packages.

ok cmd/api 0.031s

? cmd/cgo [no test files]

ok cmd/fix 3.558s

ok cmd/go 0.022s

……

? unsafe [no test files]

real 3m6.056s

user 2m29.517s

sys 0m25.134s

# GOMAXPROCS=2 runtime -cpu=1,2,4

ok runtime 6.605s

# sync -cpu=10

ok sync 0.428s

# Testing race detector.

ok flag 1.044s

# ../misc/cgo/stdio

# ../misc/cgo/life

# ../misc/cgo/test

scatter = 0×430490

hello from C

PASS

ok _/home/polaris/go/misc/cgo/test 1.137s

# ../misc/cgo/testso

# ../doc/progs

real 0m19.110s

user 0m15.341s

sys 0m2.904s

# ../doc/articles/wiki

run.bash: 行 92: make: 未找到命令

PASS

# ../doc/codewalk

# ../misc/dashboard/builder ../misc/goplay

# ../test/bench/shootout

fasta

reverse-complement

nbody

binary-tree

binary-tree-freelist

fannkuch

fannkuch-parallel

regex-dna

regex-dna-parallel

spectral-norm

k-nucleotide

k-nucleotide-parallel

mandelbrot

meteor-contest

pidigits

threadring

chameneosredux

# ../test/bench/go1

ok _/home/polaris/go/test/bench/go1 4.942s

# ../test

real 1m38.036s

user 1m14.701s

sys 0m16.645s

# Checking API compatibility.

+pkg crypto/x509, const PEMCipher3DES PEMCipher

+pkg crypto/x509, const PEMCipherAES128 PEMCipher

+pkg crypto/x509, const PEMCipherAES192 PEMCipher

+pkg crypto/x509, const PEMCipherAES256 PEMCipher

+pkg crypto/x509, const PEMCipherDES PEMCipher

+pkg crypto/x509, func EncryptPEMBlock(io.Reader, string, []byte, []byte, PEMCipher)

……

+pkg reflect, func SliceOf(Type) Type

+pkg regexp, method (*Regexp) Split(string, int) []string

~pkg text/template/parse, type DotNode bool

~pkg text/template/parse, type Node interface { Copy, String, Type }

ALL TESTS PASSED

Installed Go for linux/amd64 in /home/polaris/go

Installed commands in /home/polaris/go/bin

*** You need to add /home/polaris/go/bin to your PATH.

三、带中文注释的脚本

以下是我加上了注释的make.bash脚本(关键部分)

1

echo '# Building C bootstrap tool.'

2

echo cmd/dist

3

# export当前Go源码所在跟目录为GOROOT

4

export GOROOT="$(cd .. && pwd)"

5

# 如果GOROOT_FINAL没有设置,则使用$GOROOT的值当做GOROOT_FINAL

6

GOROOT_FINAL="${GOROOT_FINAL:-$GOROOT}"

7

DEFGOROOT='-DGOROOT_FINAL="'"$GOROOT_FINAL"'"'

8

9

# 如果在amd64机子上编译Go本身为32位,可以设置 $GOHOSTARCH=386。不建议这么做

10

mflag=""

11

case "$GOHOSTARCH" in

12

386) mflag=-m32;;

13

amd64) mflag=-m64;;

14

esac

15

16

# gcc编译:编译cmd/dist下所有的c文件

17

# -m:指定处理器架构,以便进行优化(-m32、-m64)或为空(一般为空)

18

# -O:优化选项,一般为:-O2。优化得到的程序比没优化的要小,执行速度可能也有所提高

19

# -Wall:生成所有警告信息

20

# -Werror:所有警告信息都变成错误

21

# -ggdb:为gdb生成调试信息(-g是生成调试信息)

22

# -o:生成指定的输出文件

23

# -I:指定额外的文件搜索路径

24

# -D:相当于C语言中的#define GOROOT_FINAL="$GOROOT_FINAL"

25

gcc $mflag -O2 -Wall -Werror -ggdb -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c

26

27

# 编译完 dist 工具后,运行dist。目的是设置相关环境变量

28

# 比如:$GOTOOLDIR 环境变量就是这里设置的

29

eval $(./cmd/dist/dist env -p)

30

echo

31

32

# 运行make.bash时传递--dist-tool参数可以仅编译dist工具

33

if [ "$1" = "--dist-tool" ]; then

34

    # Stop after building dist tool.

35

    mkdir -p "$GOTOOLDIR"

36

    if [ "$2" != "" ]; then

37

        cp cmd/dist/dist "$2"

38

    fi

39

    mv cmd/dist/dist "$GOTOOLDIR"/dist

40

    exit 0

41

fi

42

43

# 构建 编译器和Go引导工具

44

# $GOHOSTOS/$GOHOSTARCH 是运行dist设置的

45

echo "# Building compilers and Go bootstrap tool for host, $GOHOSTOS/$GOHOSTARCH."

46

# 表示重新构建

47

buildall="-a"

48

# 传递--no-clean 表示不重新构建

49

if [ "$1" = "--no-clean" ]; then

50

    buildall=""

51

fi

52

# 构建Go引导工具

53

./cmd/dist/dist bootstrap $buildall -v # builds go_bootstrap

54

# Delay move of dist tool to now, because bootstrap may clear tool directory.

55

mv cmd/dist/dist "$GOTOOLDIR"/dist

56

"$GOTOOLDIR"/go_bootstrap clean -i std

57

echo

58

59

# $GOHOSTARCH 与 $GOARCH的区别:($GOHOSTOS 与 $GOOS的区别一样)

60

#   GOARCH 表示Go写出来的程序会在什么架构运行(目标操作系统);

61

#   GOHOSTARCH 表示运行make.bash这个脚本的系统架构

62

# 一般它们是相等的,只有在需要交叉编译时才会不一样。

63

if [ "$GOHOSTARCH" != "$GOARCH" -o "$GOHOSTOS" != "$GOOS" ]; then

64

    # 即使交叉编译,本机的Go环境还是必须得有

65

    echo "# Building packages and commands for host, $GOHOSTOS/$GOHOSTARCH."

66

    GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH \

67

        "$GOTOOLDIR"/go_bootstrap install -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std

68

    echo

69

fi

70

71

echo "# Building packages and commands for $GOOS/$GOARCH."

72

"$GOTOOLDIR"/go_bootstrap install -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std

73

echo

74

75

rm -f "$GOTOOLDIR"/go_bootstrap

76

77

# 是否打印安装成功的提示信息。一般为:

78

#   Installed Go for $GOOS/$GOARCH in $GOROOT

79

#   Installed commands in $GOROOT/bin

80

if [ "$1" != "--no-banner" ]; then

81

    "$GOTOOLDIR"/dist banner

82

fi

注:有些是根据脚本中的英文翻译的,如不明白,请看脚本的注释;如有不对,请指正!谢谢!

go 源码安装go


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消