go build寻找import的包过程(1.14版本开启go mod)

今天在看一个程序代码,发现里面用到了grpc,程序的目录结构是这样的golang

onlineClean 包名main
main.go
go.mod
proto
structs.go 包名proto
rpcClient 包名main
test.go

其中rpcCleint/test.go里面有这样的代码ui

import (
	"fmt"

	pb "onlineClean/proto"

	"golang.org/x/net/context"

	"google.golang.org/grpc"
)

当时我以为有点奇怪,在rpcClient里面这样引用onlineClean/proto,能够编译过吗?google

因而试验了一下,在rpcCleint下执行go build(go 版本是1.14),发现还真能够编译成功。code

当时我就在想,go build寻找import的包过程是怎么样的呢? 它是怎么发现onlineClean/proto这个包的文档

很明显,这里go build时应该是从rpcClient的上层目录开始找onlineClean/proto的,那为啥它是从上层目录找而不是当前目录找呢?rpc

上网找了一下,网上文章是这样说的:it

在咱们引入第三方的时候,其会在三个地方区查找
一、GOROOT路径
二、GOPATH路径
三、在原目录中的vendor目录下进行查找io

里面没提到会从上级目录找。编译

我检查了一下GOROOT和GOPATH变量(go env GOROOT和go env GOPATH),发现都没有包含onlineClean或者../目录table

感受网上说的可能不太全,或者网上的资料太旧了,不适合1.14

后来,偶然间,我发现把rpcClient复制到其它目录(与onlineClean并列),就编译不了。编译提示“go: cannot find main module; see 'go help modules'”

而后我对比了在onlineClean/rpcClient和rpcClient两个目录执行go env的区别,发现主要是GOMOD环境变量的区别:

在onlineClean/rpcClient,会输出set GOMOD=D:\ht\软件部\数据质量管控平台\代码\华为云\go\onlineClean\go.mod

而在rpcClient则没有输出这个环境变量。

因而我猜想,开启go mod时go build时会向上找go.mod,找到后使用这个go.mod进行第三方包管理,查了一下go mod的帮助文档,证明了我这个猜想。

go helo go.mod

A module version is defined by a tree of source files, with a go.mod
file in its root. When the go command is run, it looks in the current
directory and then successive parent directories to find the go.mod
marking the root of the main (current) module.

这段话大概是说:当go命令运行,会先查找当前目录有没有go.mod,若是没有会一直向上找,直到找到go.mod,并以找到go.mod的目录作为根目录进行第三方包引用 。

相关文章
相关标签/搜索