Build system: gn, ninja, gm.py
Reading V8 is one thing; building it is the gate to actually experimenting and
contributing. V8 uses the same toolchain as Chromium — depot_tools to fetch
sources, GN to configure builds, and Ninja to run them — with a friendly
wrapper, gm.py, on top. This page orients you; always follow the official
Building V8 guide for exact, current steps.
::: info Ubiquitous language
depot_tools: Google's toolset for Chromium-family repos (includes gclient,
gn, ninja). gclient: fetches a project plus its pinned dependencies.
GN: "Generate Ninja" — a meta-build system that produces Ninja files.
Ninja: a fast, low-level build executor.
:::
Step 1: fetch with depot_tools + gclient
You do not git clone V8 for development — you fetch v8 with depot_tools,
which runs gclient to check out V8 and its dependencies (the Chromium
build/ config, ICU, test suites, …) at the revisions pinned in the DEPS
file:
use_relative_paths = True
gclient_gn_args_file = 'build/config/gclient_args.gni'
— DEPS
DEPS is the source of truth for "what other repos and at which commits does this
V8 need." gclient sync brings your checkout in line with it.
::: warning V8pedia uses a plain shallow clone
For this site, the source is a plain shallow git clone pinned to
fb8be11 —
enough to read the code and make permalinks. That is not enough to build:
a real build needs the full fetch v8 + gclient sync dependency tree. Don't
expect ninja to work in a bare clone.
:::
Step 2: configure with GN
The build is described declaratively in BUILD.gn files, which import shared
configuration:
import("//build/config/android/config.gni")
import("//build/config/arm.gni")
import("gni/snapshot_toolchain.gni")
import("gni/v8.gni")
— BUILD.gn
GN takes these plus your chosen args (architecture, debug/release, feature flags
like v8_enable_pointer_compression or v8_enable_sandbox) and generates Ninja
build files into an output directory like out/x64.release. GN handles the hard
parts: cross-compilation to many architectures, the
snapshot toolchain (which must build mksnapshot for
the host to generate the snapshot for the target), and
Torque code generation.
Step 3: build with Ninja
Ninja then executes the generated graph — fast, incremental, parallel C++ compilation. You rarely invoke it by hand for routine work, because of the wrapper below.
The shortcut: gm.py
tools/dev/gm.py wraps all of the above into one command:
Convenience wrapper for compiling V8 with gn/ninja and running tests.
Sets up build output directories if they don't exist. …
Usage:
gm.py [<arch>].[<mode>[-<suffix>]].[<target>] [testname...] [options...]
So gm.py x64.release d8 configures (if needed) and builds the
d8 shell for a 64-bit release build; gm.py x64.release.check also
runs the tests. It picks sensible GN args, makes the output dir, and calls Ninja —
the fastest path from "I edited a file" to "I have a binary to try."
How the pieces fit
fetch v8 (depot_tools)
│ gclient sync ── DEPS ──► V8 + deps checked out
▼
gn gen out/x64.release ── BUILD.gn + args ──► Ninja files
│ (+ Torque codegen, snapshot toolchain)
▼
ninja -C out/x64.release d8 ──► out/x64.release/d8
▲
└────────── gm.py x64.release d8 wraps all of the above ──────────┘
::: details Why GN + Ninja instead of CMake/Make?
GN/Ninja was built for Chromium-scale C++: tens of thousands of files,
many target architectures, and aggressive incremental rebuilds. GN's .gn
language is fast to evaluate and produces a minimal, explicit Ninja graph; Ninja
is deliberately dumb and fast (it does no configuration, only execution). The
split — a smart configurator that emits a fast executor — is itself a performance
design worth noting.
:::
See also
d8 & debugging tools — the binary you'll build first.
Builtins & Torque — Torque codegen runs during the build.
Isolates: snapshots — why the build has a snapshot step.
Official: v8.dev/docs/build.