欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Go外部依赖包从vendor、$GOPATH和$GOPATH/pkg/mod下的查找顺序

程序员文章站 2022-06-03 22:38:58
...

vendor

vendor概念最早是由Keith提出,用来存放依赖包。在版本1.5出现。例如gb项目提供了一个名为gsftp的示例项目,它有一个gsftp程序,在标准库之外有三个依赖项。golang.org/x/crypto/ssh, golang.org/x/crypto/ssh/agentgithub.com/pkg/sftp。按vendor概念调整的目录结构如下:

$GOPATH
|	src/
|	|	github.com/constabulary/example-gsftp/
|	|	|	cmd/
|	|	|	|	gsftp/
|	|	|	|	|	main.go
|	|	|	vendor/
|	|	|	|	github.com/pkg/sftp/
|	|	|	|	golang.org/x/crypto/ssh/
|	|	|	|	|	agent/

文件github.com/constabulary/example-gsftp/cmd/gsftp/main.go的引用如下所示,看起来和平时的引用没什么区别。

import (
	...
	"golang.org/x/crypto/ssh"
	"golang.org/x/crypto/ssh/agent"
	"github.com/pkg/sftp"
)

因为github.com/constabulary/example-gsftp/vendor/golang.org/x/crypto/ssh存在,且正在编译的文件位于以github.com/constabulary/example-gsftp为根的子树中。则导入语句import "golang.org/x/crypto/ssh",编译好像是import "github.com/constabulary/example-gsftp/vendor/golang.org/x/crypto/ssh",只不过这种较长的形式从未写过。
因此github.com/constabulary/example-gsftp中的源代码取决于vendor中有关golang.org/x/crypto/ssh的拷贝副本, 而不是$GOPATH中的其他地方。

vendor的层级搜索

规则是:

  1. 从引用文件所在的vendor路径下面搜索,
  2. 如果没有找到,那么从上层目录的vendor路径下面搜索,
  3. 直到srcvendor路径下面搜索。

modules

Go 1.11版本支持临时环境变量GO111MODULE,通过该环境变量来控制依赖包的管理方式。当GO111MODULE的值为on时,那么就会使用modules功能,这种模式下,$GOPATH不再作为build时导入的角色,依赖包会存放在$GOPATH/pkg/mod目录下。工程中的依赖包也会从此目录下查找。有关该功能的介绍,可以看Go1.1.1新功能module的介绍及使用

查找顺序

GO111MODULE=off时,如果一个包在vendor$GOPATH下都存在,那么使用顺序为:

  1. 优先使用vendor目录下面的包,
  2. 如果vendor下面没有搜索到,再搜索$GOPATH/src下面的包,
  3. 如果$GOPATH下面没有搜索到,那么搜索$GOROOT/src下面的包,
  4. 要么完整使用vendor下面的包,要么完整使用$GOPATH下面的包,不会混合使用。

参考文章

  1. Go 1.5 Vendor Experiment