Set Up the Environment
vim-go
doesn’t support travesal through the go
source code, so I switch to vscode
and it works out of box (with Go plugin && gopls
installed).
Start Point (go run
)
- File:
src/cmd/go/main.go
- Declaration:
run.CmdRun
- Function:
run.runRun
- Key data structures:
build.Context
work.Builder
load.Package
work.Action
The runRun
function will go through several stages:
- Check
shouldUseOutsideModuleMode
. This procedure is used bygo run cmd@version
work.BuildInit
. This will setup the build context:- Initialize
modload
module. It will check go module flags and set up the flags, no actual module download. instrumentInit
andbuildModeInit
, and update the defaultbuild.Context
accordingly.
- Initialize
- Get a
work.Builder
.work.NewBuilder
will check the environment and make sure it’s ready to do the actual build. - Inits a
load.Package
from all*.go
files passed togo run
.load.Package
has a public struct for definitions, and an internal struct for running state.
- Setup
builder.LinkAction
.LinkAction
will callcacheAction
(for looking up action cache, not build cache),CompileAction
, andinstallAction
(not forgo run
).work.Action
is a DAG, the action cache depends onmode
and package info.
- Initialize a
work.Action
, use the link action initialized at the above stage as dependencies. - Build the
work.Action
with builder.
Build Stage (Builder.Do
)
- Set up the cache trim. There’s a
trim.txt
insidego-build
cache folder, it’s used to track the timestamp of last trim action. - Build the action list, visit the DAG as “depth-first post-order travelsal”. The priority will set by the list order, which means deepest will run first.
writeActionGraph
. Internal feature, this will dump the DAG as JSON.- Set up triggers. Triggers are the inverse of dependencies, which means when the dependency ready, it will trigger its root instead of its dependencies.
- The
handle
function will do the actual jobs.- Actions are run in parallel, the actual job is defined by
action.Func
. - After actions done, update the global state. There’s a lock to make sure there’s no data races.
- If all dependencies finished, push the action node to ready queue and signal the
readySema
. Ready queue are protected with the same global state lock.
- Actions are run in parallel, the actual job is defined by
- Run all actions from the DAG in parallel.
What’s Next
Travesal through the action.Func
definitions:
Builder.build
Builder.link