Attention
这里的构建过程没有考虑
Golang Build Cache的影响
Golang 的构建过程是典型的静态编译语言的编译过程,分为编译(compile)和链接(link)两个阶段。
包源码被编译为 .o 文件之后,会被 pack 工具打包成为 .a 文件,生成的 .a 会被放入临时构建文件夹,之后被链接成为可执行文件。
标准库的构建过程
标准库的源码存放在 $GOROOT/src 下,标准库编译的 .a 文件存放在 $GOROOT/pkg/ 下,构建时如果已经存在 .a 文件,则会直接链接 .a 文件,否则会从源文件中进行编译。如果想强制从标准库的源码进行重新编译,可以通过两种办法:
- 删除相应的
.a的文件 - 使用
go build -a参数,这会将所有的源码重新编译一边,所以构建时间可能很长
非标准库的构建过程
同标准库的构建过程不同,非标准库在构建的时候都会从源码进行构建。使用 go install 命令可以将包的 .a 文件安装到 $GOPATH/pkg/ 下,但在构建过程中会重新编译源码到 .a,重新编译的文件会被放入构建的临时目录,临时目录的下的 .a 优先级会高于 $GOPATH/pkg/ 中的 .a。
程序构建过程
以下面结构的项目的为例,编译是使用命令 go build -x -v 输出详细构建日志:
$tree -F demo1
demo1
├── cmd/
│ └── app1/
│ └── main.go
└── pkg/
└── pkg1/
└── pkg1.go程序 app1 的构建过程可分为下面几步:
- 建立临时工作目录,放入环境变量
WORK,之后的工作都已$WORK为当前目录 - 编译
app1的依赖包pkg1,将目标文件打包放入$WORK/<demo1_pkg_path>/pkg/pkg1.a - 编译
app1的 main 包, 将目标文件打包后放入$WORK/<demo1_pkg_path>/cmd/app1.a - 链接器将
app1.a,pkg1.a链接成为$WORK/<demo1_pkg_path>/cmd/app1/_obj/exe/a.out - 将
a.out复制到go build命令执行目录,并改名为app1