The existing piece on what a compiler actually does in this category covers the general compile pipeline; this one walks through what Go's own build process specifically does when a single go build command is typed, since Go deliberately folds several steps most languages handle as separate tools into that one command.

The first thing go build does is resolve dependencies: reading the project's go.mod file to determine which module versions the program requires, walking the actual import graph starting from the package being built, and pulling in whatever's needed from the local module cache -- or, if it isn't cached yet, fetching it -- rather than requiring a separate, manual install step before compiling can even begin.

Each package the program depends on is then compiled individually, in dependency order, by Go's own compiler toolchain into machine code for the target platform -- unlike languages that lean on an external system compiler for parts of the pipeline, Go's standard toolchain handles this itself end to end, which is a real part of why a stock Go install can compile a full program without needing a separate C compiler or build system installed alongside it.

The compiled packages are then linked together into a single output binary, and by default Go links statically -- every package's compiled code, including the standard library and third-party dependencies, gets bundled directly into that one binary rather than left as separate files the program expects to find at runtime. That's the direct, practical reason a compiled Go binary can usually be copied to another machine of the same OS and architecture and simply run, without installing a separate runtime or resolving dependencies there.

Go also caches build artifacts aggressively between runs, keyed on the actual inputs to each compilation step -- which is why a second go build immediately after the first, with no source changes, finishes almost instantly: nearly everything it would otherwise need to recompile is already sitting in the build cache from the previous run, untouched and still valid.