Toolchain Command Reference

Purpose and Scope

The Go distribution ships a suite of programs for building, testing, inspecting, and processing Go source and Go binaries. For most users, the go command is the front door: it interprets package patterns, module metadata, environment settings, and subcommands, then invokes lower-level tools with the right arguments. The public command documentation describes this design as a command suite usually invoked by the go program rather than directly, and the repository entry point in src/cmd/go/main.go reflects that role by registering build, test, doc, fmt, vet, module, work, run, tool, version, and help commands in one dispatcher.

Sources: src/cmd/go/main.go

This page is a reference for selected toolchain commands that are important when moving from ordinary package-level workflows to lower-level compiler, linker, debugging, profiling, or automation tasks. The distinction matters because go build, go test, and go install operate on packages and modules, while tools such as compile, link, addr2line, objdump, and test2json operate closer to binaries, object files, test executables, architecture configuration, or raw test output. Use the higher-level go subcommands for normal development, and use go tool or direct binaries when you need to inspect or debug a toolchain phase.

Sources: src/cmd/go/main.go, src/cmd/compile/main.go, src/cmd/link/main.go

The commands covered here have different stability expectations. The go command is the public, user-facing manager for Go source code and the usual way to reach the rest of the suite. The compiler and linker are part of the implementation pipeline and select architecture-specific backends according to the configured target architecture. addr2line explicitly documents itself as a minimal GNU addr2line simulation intended only to support pprof, with an interface that may change or disappear. test2json, by contrast, documents a concrete JSON event stream because it is consumed by tools that need live, structured test status.

Sources: src/cmd/go/main.go, src/cmd/addr2line/main.go, src/cmd/test2json/main.go

Relevant Source Files

  • src/cmd/go/main.go - Defines the main go binary entry point, registers public subcommands and help topics, initializes telemetry counters, handles the help path, validates GOROOT, and selects the toolchain before dispatching.
  • src/cmd/compile/main.go - Defines the compiler executable entry point, maps supported GOARCH values to architecture initialization functions, checks build configuration, and enters the compiler driver through gc.Main.
  • src/cmd/link/main.go - Defines the linker executable entry point, chooses the architecture-specific linker implementation for the current GOARCH, and delegates to ld.Main after architecture setup.
  • src/cmd/addr2line/main.go - Implements go tool addr2line, reads addresses from standard input, opens an object file, maps program counters to function and file-line information, and prints two output lines per address.
  • src/cmd/objdump/main.go - Implements go tool objdump, parses disassembly flags, opens an object file, creates a disassembler, and prints either selected symbols or a program-counter range.
  • src/cmd/test2json/main.go - Documents and implements the conversion of Go test output into newline-separated JSON TestEvent records for live status consumers.

Invocation Model

There are three useful ways to think about invocation. First, the go binary is run directly, as in go test, go build, go list, or go env. Its main function parses global flags, records invocation telemetry, handles go help, checks that GOROOT resolves to a directory, and then uses the registered command table to route the requested subcommand. That source structure matches the public model: the go command manages Go source code and runs other commands on behalf of the user.

Sources: src/cmd/go/main.go

Second, several tools are reached through go tool, which preserves the lower-level tool interface instead of translating package patterns into package builds. The official command documentation uses examples such as go tool cgo; the source files here show the same pattern for addr2line, objdump, and test2json. These commands parse their own flags and arguments, report tool-specific usage, and typically operate on a binary, an object file, a test executable, or standard input rather than on packages resolved from module metadata.

Sources: src/cmd/addr2line/main.go, src/cmd/objdump/main.go, src/cmd/test2json/main.go

Third, some toolchain binaries are implementation stages. The compiler and linker are present as executables under src/cmd, but ordinary users normally reach them indirectly through the build actions planned by go build, go test, or go install. Their main functions are intentionally small: they validate the build configuration, pick the architecture backend for the active GOARCH, and hand off to internal compiler or linker packages. That design keeps command entry points simple while placing phase-specific behavior in internal packages.

Sources: src/cmd/compile/main.go, src/cmd/link/main.go

Command Reference

CommandUsual invocationPrimary roleSource entry point
gogo <command> [arguments]Package, module, workspace, build, test, run, documentation, environment, and tool dispatchersrc/cmd/go/main.go
compileUsually through go build or another build actionCompile Go source for the configured target architecturesrc/cmd/compile/main.go
linkUsually through go build, go test, or install actionsLink compiled objects into executable or archive outputs for the configured architecturesrc/cmd/link/main.go
addr2linego tool addr2line binaryTranslate hexadecimal program counters to function names and source locationssrc/cmd/addr2line/main.go
objdumpgo tool objdump [-S] [-gnu] [-s symregexp] binary [start end]Disassemble code in a binary, optionally filtered by symbol or address rangesrc/cmd/objdump/main.go
test2jsongo tool test2json [-p pkg] [-t] [./pkg.test -test.v=test2json]Convert test output into a machine-readable stream of JSON test eventssrc/cmd/test2json/main.go

The go command’s registered command list is the best way to understand the user-facing surface represented by this page. Its initialization includes build, clean, doc, env, fix, fmt, generate, get, install, list, mod, run, telemetry, test, tool, version, vet, and work commands, along with help topics for build constraints, build modes, C integration, cache behavior, environment variables, modules, package patterns, proxies, private modules, test flags, and version control. That breadth is why most workflows should start with go help or go help <topic> before reaching for a lower-level binary.

Sources: src/cmd/go/main.go

compile is architecture-sensitive. Its main package imports architecture implementations for 386, amd64, arm, arm64, loong64, mips, mipsle, mips64, mips64le, ppc64, ppc64le, riscv64, s390x, and wasm, maps those names to initialization functions, and rejects an unknown architecture with an error. After internal/buildcfg.Check, it calls the selected initialization through gc.Main, then exits through the compiler base package. For readers, the important contract is that the compiler executable is configured by the target build configuration rather than by a package-level command line alone.

Sources: src/cmd/compile/main.go

link follows the same architecture-selection pattern but with linker-specific setup. Its source comment explains the initialization sequence: before argument parsing, the relevant architecture package initializes architecture variables; then control passes to ld.Main, which parses flags, makes configuration decisions, and gives architecture code another chance to adjust linker configuration through the architecture initialization hook. This matters when diagnosing target-specific link behavior, because the public executable name is generic while the selected linker implementation depends on the active GOARCH. Sources: src/cmd/link/main.go

Inspection and Diagnostic Tools

addr2line is intentionally narrow. It accepts exactly one binary argument and reads hexadecimal addresses from standard input, with or without a leading 0x. For each address, it prints the containing function name followed by a file:line location. If an address cannot be resolved to a function, it prints placeholder values. The implementation opens the binary through the shared object-file package, reads a PC-line table, and performs program-counter lookup for each scanned input line. It also recognizes --help specially because pprof expects that behavior when probing for the tool.

Sources: src/cmd/addr2line/main.go

The same source also documents a non-primary reverse-translation input syntax using file:line, but the implementation reports that reverse translation is not implemented. That is a useful diagnostic detail: if a tool feeds addr2line normal program counters, it receives function and source-location output; if it depends on reverse translation, it should not expect a supported result from this command. The file explicitly states that the tool exists only to support pprof, so integrations should prefer the higher-level profiling workflow instead of treating addr2line as an independently stable API.

Sources: src/cmd/addr2line/main.go

objdump disassembles executable files and has two modes. With one binary argument, it prints disassembly for text symbols in the object, optionally filtered by -s symregexp. With a binary plus start and end program counters, it disassembles the specified address range; that range mode is intended for pprof and prints stanzas grouped by source file and line. The command also supports -S to print Go source alongside assembly and -gnu to print GNU assembly next to Go assembly where supported.

Sources: src/cmd/objdump/main.go

The implementation validates argument count, compiles the optional symbol regular expression, opens the object file, creates a disassembler for the file, and then calls the same print path for full-object and address-range output. Start and end addresses are parsed as hexadecimal values with optional 0x prefixes. When troubleshooting low-level performance, crash, or compiler-output questions, this makes objdump a bridge from a built binary back to machine instructions and source-line groupings without requiring a separate external disassembler for the common Go workflow.

Sources: src/cmd/objdump/main.go

Test Output Conversion

test2json is the structured-output adapter behind test automation. The source documentation says it can either run a specified test command and convert its output or read test output from standard input when no command is supplied. It writes newline-separated JSON events to standard output and avoids unnecessary buffering so that clients can read live updates. In normal package workflows, users should prefer go test -json, which invokes test2json correctly; direct go tool test2json is for cases where a compiled test binary is run separately from go test. Sources: src/cmd/test2json/main.go

The documented TestEvent shape includes fields for time, action, package, test name, elapsed seconds, output text, output type, and failed build package. The action set includes lifecycle and result values such as start, run, pause, cont, pass, bench, fail, output, and skip. The package field is especially important because go test -json may interlace events from different packages, and consumers must separate events by package. The output field preserves test output except for coercing invalid UTF-8 into valid UTF-8 replacement characters.

Sources: src/cmd/test2json/main.go

For high-fidelity direct use, the test binary should be invoked with -test.v=test2json; plain verbose mode is allowed but produces lower-fidelity results. The command also documents that it is intended to convert a single test binary’s output, not the combined output of a go test command that runs multiple packages. That boundary helps keep automation reliable: use go test -json for normal multi-package test runs, and reserve go tool test2json for custom harnesses that already control one compiled test binary at a time.

Sources: src/cmd/test2json/main.go

Execution Flow and Practical Guidance

A typical build starts at the go command, not at compile or link. The dispatcher interprets the requested subcommand, applies environment and module behavior, and schedules work. When compilation is needed, build actions eventually invoke the compiler configured for the target architecture. When an executable or linked artifact is needed, the linker entry point chooses the architecture implementation and delegates to the linker driver. This layered model is the main reason Go users rarely pass compiler and linker arguments directly: the package-level command has more context than any single phase tool.

Sources: src/cmd/go/main.go, src/cmd/compile/main.go, src/cmd/link/main.go

A typical diagnostic session starts after a binary or test executable exists. If you need source locations for program counters, go tool addr2line binary reads addresses from standard input and emits function plus file-line pairs. If you need assembly, go tool objdump can show all text symbols, a symbol subset, or a specific address range. If you need structured test status for an external runner, go test -json should be the first choice, with go tool test2json available for a separately executed test binary. These tools complement the go command rather than replacing it.

Sources: src/cmd/addr2line/main.go, src/cmd/objdump/main.go, src/cmd/test2json/main.go

The safest rule is to choose the highest-level command that preserves the information you need. Use go help for command syntax, go build and go test for package work, go tool for a bundled binary’s unmodified lower-level interface, and direct phase tools only when you are debugging the toolchain itself or reproducing an internal build step. Next, read the pages on The go Command, Build and Install, Testing, Execution Traces, and go tool pprof to connect these entry points to day-to-day workflows.