上QQ阅读APP看书,第一时间看更新
5.1 Go项目的项目结构
我们先来看看第一个Go项目——Go语言自身——的项目结构是什么样的。
Go项目的项目结构自1.0版本发布以来一直十分稳定,直到现在Go项目的顶层结构基本没有大的改变。截至Go项目commit 1e3ffb0c(2019.5.14),Go项目结构如下:
$ tree -LF 1 ~/go/src/github.com/golang/go ./go ├── api/ ├── AUTHORS ├── CONTRIBUTING.md ├── CONTRIBUTORS ├── doc/ ├── favicon.ico ├── lib/ ├── LICENSE ├── misc/ ├── PATENTS ├── README.md ├── robots.txt ├── src/ └── test/
作为Go语言的创世项目,Go的项目结构的布局对后续的Go语言项目具有重要的参考意义,尤其是早期Go项目中src目录下面的结构,更是在后续被Go社区作为Go应用项目结构的模板广泛使用。以早期的Go 1.3版本的src目录下的结构为例:
$ tree -LF 1 ./src ./src ├── all.bash* ├── all.bat ├── all.rc* ├── clean.bash* ├── clean.bat ├── clean.rc* ├── cmd/ ├── lib9/ ├── libbio/ ├── liblink/ ├── make.bash* ├── make.bat ├── Make.dist ├── make.rc* ├── nacltest.bash* ├── pkg/ ├── race.bash* ├── race.bat ├── run.bash* ├── run.bat ├── run.rc* └── sudo.bash*
关于上面src目录下的结构,笔者总结了以下三个特点。
1)代码构建的脚本源文件放在src下面的顶层目录下。
2)src下的二级目录cmd下面存放着Go工具链相关的可执行文件(比如go、gofmt等)的主目录以及它们的main包源文件。
$ tree -LF 1 ./cmd ./cmd ... ├── 6a/ ├── 6c/ ├── 6g/ ... ├── cc/ ├── cgo/ ├── dist/ ├── fix/ ├── gc/ ├── go/ ├── gofmt/ ├── ld/ ├── nm/ ├── objdump/ ├── pack/ └── yacc/
3)src下的二级目录pkg下面存放着上面cmd下各工具链程序依赖的包、Go运行时以及Go标准库的源文件。
$ tree -LF 1 ./pkg ./pkg ... ├── flag/ ├── fmt/ ├── go/ ├── io/ ├── log/ ├── math/ ... ├── syscall/ ├── testing/ ├── text/ ├── time/ ├── unicode/ └── unsafe/
在Go 1.3版本以后至今,Go项目下的src目录发生了几次结构上的变动。
- Go 1.4版本删除了Go源码树中src/pkg/xxx中的pkg这一层级目录,改为直接使用src/xxx。
- Go 1.4版本在src下面增加internal目录,用于存放无法被外部导入、仅Go项目自用的包。
- Go 1.6版本在src下面增加vendor目录,但Go项目自身真正启用vendor机制是在Go 1.7版本中。vendor目录中存放了Go项目自身对外部项目的依赖,主要是golang.org/x下的各个包,包括net、text、crypto等。该目录下的包会在每次Go版本发布时更新。
- Go 1.13版本在src下面增加了go.mod和go.num,实现了Go项目自身的go module迁移。Go项目内所有包被放到名为std的module下面,其依赖的包依然是golang.org/x下的各个包。
// Go 1.13版本Go项目src下面的go.mod module std go 1.12 require ( golang.org/x/crypto v0.0.0-20200124225646-8b5121be2f68 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 golang.org/x/sys v0.0.0-20190529130038-5219a1e1c5f8 // indirect golang.org/x/text v0.3.2 // indirect )
下面是Go 1.16版本src目录下的完整布局:
├── Make.dist ├── README.vendor ├── all.bash* ├── all.bat ├── all.rc* ├── bootstrap.bash* ├── buildall.bash* ├── clean.bash* ├── clean.bat ├── clean.rc* ├── cmd/ ├── cmp.bash ├── go.mod ├── go.sum ├── internal/ ├── make.bash* ├── make.bat ├── make.rc* ├── race.bash* ├── race.bat ├── run.bash* ├── run.bat ├── run.rc* ├── testdata/ ... └── vendor/