golang/go
Architecture
The Go distribution is a self-contained toolchain. A user-invoked go command drives a small set of cooperating tools (compile, asm, link, cgo, vet) that together turn .go source into an executable. The executable embeds the Go runtime, which manages goroutines, memory, and garbage collection at runtime.
Repository layout at a glance
go/
├── src/
│ ├── cmd/ # All command-line tools: go, compile, link, asm, vet, gofmt, cgo, ...
│ │ ├── compile/ # The gc compiler (frontend, IR, SSA, codegen)
│ │ ├── go/ # The user-facing 'go' command (build, test, get, mod, ...)
│ │ ├── link/ # The linker
│ │ ├── asm/ # The assembler
│ │ ├── cgo/ # The cgo preprocessor
│ │ ├── gofmt/ # The formatter
│ │ ├── vet/ # The static analyzer
│ │ └── internal/ # Shared compiler/linker internals (obj, objabi, ...)
│ ├── runtime/ # Goroutine scheduler, GC, allocator, panic, defer, channels
│ ├── internal/ # Stdlib-internal packages (not importable by users)
│ ├── crypto/ net/ encoding/ fmt/ io/ os/ ... # The public standard library
│ └── vendor/ # Vendored dependencies for the standard library
├── doc/ # Specification (go_spec.html), memory model, godebug, release notes
├── api/ # Declared public API of every Go release (drives 'go api' check)
├── test/ # End-to-end compiler/runtime regression tests
├── lib/ # Time zone data, Wasm support files
├── misc/ # Miscellaneous: cgo demos, Wasm exec scripts, editor configs
└── src/make.bash # Build script that bootstraps the toolchainHow a Go program is built
A typical go build invocation drives this pipeline:
graph LR
User[User: go build] --> GoCmd[cmd/go: go command]
GoCmd -->|resolve modules,<br/>load packages| Load[modload + load]
Load -->|per-package| Compile[cmd/compile: gc]
Compile -->|object .a| Link[cmd/link: linker]
Asm[cmd/asm: assembler] -->|object .o| Link
Cgo[cmd/cgo: preprocess C] --> Compile
Link -->|executable| Binary[(Go binary)]
Binary -->|embeds| Runtime[runtime: scheduler + GC]cmd/gois the orchestrator. It parses flags, resolves module versions, walks the import graph, schedules per-package builds, manages the build cache, and shells out tocompile,asm,link, andcgo.cmd/compile(the "gc" compiler) turns a single Go package's source into an object archive plus export data. Seesrc/cmd/compile/README.mdfor the seven-phase pipeline (parse → typecheck → noder → middle end → walk → SSA → machine code).cmd/asmturns Go's pseudo-assembly (.s) files into objects on the target architecture.cmd/cgoruns beforecmd/compilefor packages that import"C", generating the bridge code between Go and C.cmd/linkproduces the final executable from all object files plus runtime support and metadata.
How a Go program runs
Every Go binary embeds runtime from src/runtime/. The runtime starts before main.main and provides the abstractions that make Go feel high-level:
graph TD
Entry[rt0_*: arch entry stub] --> Bootstrap[runtime.rt0_go]
Bootstrap --> Schedinit[schedinit]
Schedinit --> Mainstart[runtime.main]
Mainstart --> UserMain[user main.main]
Mainstart -.spawns.-> GC[GC worker goroutines]
Mainstart -.spawns.-> Sysmon[sysmon: monitoring thread]
UserMain -.uses.-> Scheduler[G-M-P scheduler]
Scheduler --> OS[OS threads via clone/pthread/CreateThread]
UserMain -.allocates via.-> Mheap[mheap + mcache]
Mheap --> GCThe runtime's three core abstractions, documented in src/runtime/HACKING.md:
- G — a goroutine. Cheap to create. A G has a small growable stack (starts ~2 KiB).
- M — an OS thread. Created on demand. Up to
GOMAXPROCSMs run user Go code at any time; more Ms exist when goroutines are blocked in syscalls. - P — a "processor." A scheduling context with a local run queue. Exactly
GOMAXPROCSPs exist. To run user Go code, an M must hold a P.
When user Go code calls a library, that library code is just normal Go that runs on the same goroutine. The runtime is only entered for special operations: allocation, channel send/receive, syscalls, go statements, panics, defers, and growable stack splits.
Where the standard library fits
Standard library packages (fmt, net/http, crypto/*, etc.) live alongside the runtime under src/. They are normal Go packages with one important quirk: they are compiled as part of the same toolchain build that produces them, and their object files are cached in $GOROOT/pkg. Users get them implicitly with every Go installation.
A few standard library packages are tightly coupled to the runtime:
sync,sync/atomic— primitives implemented partly in the runtime via//go:linkname.reflect— usesruntimetype metadata directly.runtime/pprof,runtime/trace— public APIs over runtime instrumentation.os,syscall— the OS abstraction layer; the runtime calls intosyscallfor some operations.
The bootstrap loop
The Go toolchain is self-hosted. Building Go requires a working Go compiler. src/make.bash resolves this by:
- Locating a "bootstrap" Go (set via
GOROOT_BOOTSTRAP, default~/go1.4or~/sdk/go1.22.6). - Using the bootstrap toolchain to build
cmd/dist, the build coordinator. cmd/distthen builds the new compiler, linker, and assembler with the bootstrap.- The new toolchain rebuilds itself once or twice for stability and to pick up its own optimizations.
- Finally, the new toolchain builds the standard library and the rest of the commands.
See Getting started and How to contribute → development workflow for the developer-facing version of this loop.
What is intentionally missing
Several things are not in this repository even though they are part of the Go ecosystem:
- The
golang.org/x/*repositories (tools likegopls,goimports,dlv,staticcheck) — these live in separate modules. - The Go playground, Go website, and module proxy infrastructure — all separate repos.
- Third-party compilers like
gccgo(in GCC) andtinygo. - Build infrastructure (
golang.org/x/build) that drives the trybots and release process.
For a complete tour of internal subsystems, see Components.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.