GOPATH和GOROOT

  • goroot不是必须要设置的,它用来告知go当前的安装位置,编译的时候从goroot去找SDK的system library
  • gopath必须要设置,但并不是固定不变的,它的目的是为了告知go,需要代码的时候去哪里查找。GOPATH可以随着项目的不同而重新设置。
    • gopath下会有三个目录:
      • src:go编译时查找代码的地方
      • bin:bin工具、二进制文件下载的目的地
      • pkg:编译生成的lib文件存储的地方

        本项目内部的依赖

        kubernetes为例。kubernetes/cmd/kubectl/kubectl.go中引用了app包中的kubectl.go,代码中是这样写的
        1. import (
        2. "os"
        3. "k8s.io/kubernetes/cmd/kubectl/app"
        4. )
        go在编译时回去$GOPATH/src/目录去查找需要的代码,因此只要上面app/kubectl.go$GOPATH/src/k8s.io/kubernetes/cmd/kubectl里面,go编译的时候就可以找到,那么kubernetes/cmd/kubectl/kubectl.go也需要放到$GOPATH/src/k8s.io里去。最终$GOPATH的代码结构是这样的
        1. ├── src
        2. ├── k8s.io
        3. └── kubernetes
        4. ├── cmd
        5. ├── kubectl
        6. ├── app
        7. ├── BUILD
        8. └── kubectl.go
        9. ├── BUILD
        10. ├── kubectl.go
        11. └── OWNERS

        管理外部的依赖包

        go直接使用GOPATH来管理外部依赖

        使用GOPATH来管理外部依赖

        go允许import不同代码库的代码。对于需要import的代码,可以使用go get命令拉取下来放到GOPATH对应的目录中去。

        对于go来说,其实并不关心代码是内部的还是外部的,总之都在GOPATH里,所有import包的路径都是从GOPATH开始的。唯一的区别,就是内部依赖的包是开发者自己写的,外部依赖的包是go get下来的

vendor

依赖GOPATH来解决go import有个很严重的问题:如果项目依赖的包做了修改,或者被删掉了,会影响项目。所以在1.5版本以后,为了规避这个问题,通常会将当前使用的依赖包拷贝出来。vendor属性就是让go编译时,有限从项目源码树根目录下的vendor目录查找代码,如果vendor中有,就不再去GOPATH中查找

go mod

golang1.11版本添加了go mod来管理项目引用的第三方的包,并且可以和vendor互相切换.go可以在$GOPATH/src下再建立一个文件来作为项目根目录,或者在其他非$GOPATH/src的目录建立项目。