go-ethereum编译流程简单学习

go-ethereum源码学习:源码编译流程

一般,在根目录下执行make geth 或者 make all编译go-ethereum。前者仅编译go-ethereum主程序,后者编译所有模块。详见go-ethereum的README

以make geth为例,进入go-ethereum根目录下,打开Makefile文件,执行的逻辑是

geth:
	build/env.sh go run build/ci.go install ./cmd/geth
	@echo "Done building."
	@echo "Run \"$(GOBIN)/geth\" to launch geth."

可见直接执行了build/env.sh脚本,传入的参数为go run build/ci.go install ./cmd/geth

进入这个脚本文件,签名若干行都是在进行目录和环境设置,只有最后一行起到编译作用

exec "$@"

exec指执行后面的跟的命令,$@是一个变量,存储着传给这个脚本的所有参数,这里的参数就是上面说的go run build/ci.go install ./cmd/geth ./cmd/geth,这就是go的编译命令,他编译运行的是build/ci.go文件,顺便还传入了参数install ./cmd/geth

首先在这个文件开头,我们可以知道这也是一个CLI程序,和我们编译生成的geth类似,在开头列出了一些命令的格式,如第一行就是我们流程中将要执行的

Available commands are:

   install    [ -arch architecture ] [ -cc compiler ] [ packages... ]   
   ...

我们所要执行的就是 install ./cmd/geth,没有任何附加参数。

先从main函数开始,在这里的switch结构中,判断了第一个参数,我们这里为install,执行doInstall(os.Args[2:]),传入的参数自然为./cmd/geth。doInstall这个方法也比较简单,首先,利用flag进行参数解析,然后判断了go的版本后,最后根据需求拼凑编译指令。这一部分关键步骤注释见这里