Think Deep,Work Lean

一次Go编译失败引发的思考

Posted on By zack

前言

go build 编译istioctl时,提示失败。第一反应就是go install go get来安装这个包,但是该问题并没有解决。:

[root@jump istioctl]# go build
../../../manifests/manifest.go:18:2: package embed is not in GOROOT (/usr/local/go/src/embed)
../../../operator/pkg/helm/renderer.go:19:2: package io/fs is not in GOROOT (/usr/local/go/src/io/fs)
[root@jump istioctl]# go install embed
can't load package: package embed is not in GOROOT (/usr/local/go/src/embed)
[root@jump istioctl]# go get embed
go get embed: package embed is not in GOROOT (/usr/local/go/src/embed)

百度、google并没有找到合适的答案,对于安装失败,也就这两个处理方法。

查到了该包的官网 https://golang.org/pkg/embed/#pkg-index,发现这个包的确是存在的。那么为什么这个包就是安装不了呢?

心里MMP飘过,顿时发现自己还是一支小菜鸡。

此时想到,源码在哪?

Github上找找,果然找到了。https://github.com/golang/go/blob/master/src/embed/embed.go

看下blame,竟然是最近提交的内建包。

golang-embed

看来要升级golang版本。

升级本地golang版本

在Linux机器上升级go,第一想到的就是yum update但是并没有升级成功。

再回头想想,go源码到底是如何提供使用的。

go是个二进制文件,通过上面go源码仓库打包编译来的。那既然是打包编译,就又需要go二进制文件。这就变成了鸡生成蛋、蛋生鸡的问题了。

其实官网已经提供了已经编译好的包,包括已经编译好的go二进制,及其源码文件。

https://golang.org/dl/

wget https://golang.org/dl/go1.16.2.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.2.linux-amd64.tar.gz

echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrc
source ~/.bashrc

此时Go已经更新到新的版本

# go version
go version go1.16.2 linux/amd64

再次打包编译,问题解决。

如果是用源码,如何打包出go的二进制制文件

因为go的源码打包,需要提供go的二进制,上面已经说过这个是鸡生蛋、蛋生鸡的问题。

其实编译一个新的版本Go二进制文件,可以使用旧版本的go;最早期版本的go二进制文件,可以通过c编译得到。或是直接下载一个编译器来解决。

https://golang.org/doc/install/source