
go 1.7 引入了实验性 vendor 机制,但其生效有严格前提:vendor 目录必须位于当前构建包的根目录下,而非父项目或任意上级路径;若依赖包被导入的源文件不在 vendor 所在模块根目录内,go 工具链将完全忽略该 vendor 目录。
go 1.7 引入了实验性 vendor 机制,但其生效有严格前提:vendor 目录必须位于当前构建包的根目录下,而非父项目或任意上级路径;若依赖包被导入的源文件不在 vendor 所在模块根目录内,go 工具链将完全忽略该 vendor 目录。
Go 1.7 的 vendor 支持是 Go Modules 出现前的过渡方案,其行为与现代 Go(1.11+)的模块化机制有本质区别。它不基于 go.mod 或模块路径解析,而是依赖严格的目录层级匹配:Go 编译器仅在“正在编译的 .go 文件所在包的根目录”中查找 vendor/ 子目录,并从中解析依赖。这意味着:
- ✅ 正确结构:若
mjohn/fram/rim/fsd.go是被构建的入口,那么vendor/必须直接放在/home/mjohn/workspace/gopath/src/mjohn/fram/rim/vendor/下,且其中需包含zombiezen.com/go/capnproto2/完整路径。 - ❌ 错误结构:你当前将
vendor/zombiezen.com/go/capnproto2放在/mjohn/msg/目录下,而fsd.go位于/mjohn/fram/rim/—— 两者无父子关系,Go 1.7 根本不会向上跨多级目录搜索 vendor,因此报错cannot find package。
验证与修复步骤
-
确认当前构建上下文
运行go build时的工作目录决定了 vendor 查找起点。从你的错误日志看,执行位置应为/home/mjohn/workspace/gopath/src/mjohn/fram/rim/(因报错文件路径为../fram/rim/fsd.go)。请确保在此目录下执行命令:cd /home/mjohn/workspace/gopath/src/mjohn/fram/rim go build
-
将 vendor 移至正确位置
在rim/目录下创建 vendor 结构:mkdir -p /home/mjohn/workspace/gopath/src/mjohn/fram/rim/vendor/zombiezen.com/go/ cp -r /home/mjohn/workspace/gopath/src/zombiezen.com/go/capnproto2 \ /home/mjohn/workspace/gopath/src/mjohn/fram/rim/vendor/zombiezen.com/go/最终目录结构应为:
/mjohn/fram/rim/ ├── fsd.go ├── schema.capnp.go └── vendor/ └── zombiezen.com/ └── go/ └── capnproto2/ # 包含 src、.go 文件等完整内容 -
启用 vendor 模式(显式声明)
Go 1.7 默认不强制启用 vendor,需通过环境变量激活:export GO15VENDOREXPERIMENT=1 # 或临时运行: GO15VENDOREXPERIMENT=1 go build
⚠️ 注意:该变量仅对 Go 1.5–1.9 有效,Go 1.10+ 已废弃,由
go mod取代。 -
验证 vendor 是否被识别
添加-x参数查看详细构建过程:GO15VENDOREXPERIMENT=1 go build -x
若 vendor 生效,日志中会出现类似
cd $WORK/b001后加载vendor/zombiezen.com/go/capnproto2的路径信息;若仍走$GOPATH/src,说明 vendor 未命中。
⚠️ 重要注意事项
-
Go 1.7 vendor 是路径敏感的“就近原则”:它不解析 import 路径映射,也不读取任何配置文件,纯粹依赖物理目录树。
import "zombiezen.com/go/capnproto2"必须能在./vendor/zombiezen.com/go/capnproto2/中找到对应文件。 -
避免混用 GOPATH 与 vendor:若
zombiezen.com/go/capnproto2同时存在于$GOPATH/src/和vendor/,Go 1.7 会优先使用 vendor(当GO15VENDOREXPERIMENT=1时),但前提是 vendor 路径严格匹配。 -
强烈建议升级至 Go Modules:Go 1.7 的 vendor 已于 Go 1.11+ 被正式模块系统取代。现代项目应使用
go mod init初始化模块,再通过go mod vendor生成标准化 vendor 目录(支持go build -mod=vendor),彻底规避路径歧义问题。
总结
你的报错不是 vendor 内容缺失,而是 vendor 目录位置与构建包路径错位。Go 1.7 不会“智能发现”散落在项目各处的 vendor 文件夹——它只认“当前包根目录下的 vendor/”。修复只需两步:① 将 vendor 移至 rim/ 目录;② 设置 GO15VENDOREXPERIMENT=1。但长远来看,迁移到 Go Modules(go mod init && go mod vendor)是更可靠、可维护的解决方案。

















