Skip to content
Latchkey

make -j and -C: Parallel Builds and Targets

make -j<N> runs recipe commands in parallel and make -C <dir> runs make in another directory, the two flags that matter most in CI.

GNU Make (often invoked as make or gmake) is still the backend for autotools and many hand-written projects. In CI the wins come from -j parallelism and -C for out-of-tree invocation.

What it does

make reads a Makefile and builds the requested targets, running recipes for anything out of date. -j<N> runs up to N recipes concurrently; without a number, -j runs unlimited jobs. -C changes into a directory first, letting you build from anywhere.

Common usage

Terminal
make -j$(nproc)
make -C build -j4
make -C build test
make clean all

Options

FlagWhat it does
-j [N]Run N jobs in parallel (no N = unlimited)
-C <dir>Change to <dir> before reading the Makefile
-f <file>Use a Makefile other than ./Makefile
-kKeep going after a failed target
-BUnconditionally rebuild all targets
-nDry run: print recipes without executing them

In CI

Pass an explicit -j$(nproc); bare -j (unlimited) can fork thousands of compilers and exhaust runner memory. On some systems make is BSD make and lacks GNU features; use gmake explicitly. Recursive makefiles that spawn sub-makes need the job server, so keep the top-level -j and let sub-makes inherit it via +.

Common errors in CI

"make: * No rule to make target 'foo', needed by 'bar'. Stop." means a missing prerequisite file or a wrong target name. "make: * [Makefile:12: build] Error 1" is a recipe command that returned non-zero; scroll up for the real error. "warning: jobserver unavailable: using -j1" means a sub-make was invoked without the + prefix, so parallelism collapsed. "Makefile:1: *** missing separator. Stop." means spaces were used where a tab is required.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →