SysTutorials

Suppress “Entering/Leaving Directory” Messages in Recursive Make

· updated April 12, 2026

When running make recursively with $(MAKE) or make -C, you’ll see verbose messages like “Entering directory” and “Leaving directory” for each subdirectory. These messages clutter the build output and make it harder to spot actual errors.

The Quick Fix

Pass --no-print-directory to make:

make --no-print-directory

Or set it in your Makefile:

.MAKEFLAGS: --no-print-directory

Suppressing via MAKEFLAGS Environment Variable

Set the flag globally for all make invocations:

export MAKEFLAGS="--no-print-directory"
make

Add to your ~/.bashrc for permanent effect:

export MAKEFLAGS="--no-print-directory"

How the Messages Are Generated

GNU Make prints these messages automatically when it changes directories during recursive builds. The messages look like:

make[1]: Entering directory '/home/user/project/src'
make[2]: Entering directory '/home/user/project/src/lib'
cc -c file.c -o file.o
make[2]: Leaving directory '/home/user/project/src/lib'
make[1]: Leaving directory '/home/user/project/src'

Each level of recursion adds a bracketed number (make[1], make[2], etc.) indicating the depth.

Using –print-directory Selectively

If you want directory messages for some sub-makes but not others, use --print-directory to re-enable them:

# In top-level Makefile
.MAKEFLAGS: --no-print-directory

# In a specific sub-Makefile where you want messages
.MAKEFLAGS: --print-directory

Clean Build Output

For truly clean build output, combine --no-print-directory with other flags:

# Suppress directory messages, run in parallel, show only errors
make --no-print-directory -j$(nproc) --quiet

Or create a wrapper script:

#!/bin/bash
# build.sh - clean build output
make --no-print-directory "$@" 2>&1 | grep -v "^make\[" | grep -v "Entering\|Leaving"

Alternative: Use Recursive Make Sparingly

The “Recursive Make Considered Harmful” paper by Peter Miller argues that recursive make builds are slower and more error-prone than non-recursive builds. Consider restructuring your project to use a single top-level Makefile:

# Single Makefile for the entire project
SUBDIRS = src lib tests

.PHONY: all $(SUBDIRS)

all: $(SUBDIRS)

src:
    $(MAKE) -C src

lib:
    $(MAKE) -C lib

tests: src lib
    $(MAKE) -C tests

Or use modern build systems like CMake, Meson, or Ninja that handle subdirectory builds cleanly without verbose directory change messages.

Other Useful Make Flags

Quick Reference

Make Parallel Builds

When running parallel builds with -j, the entering/leaving directory messages become especially noisy since multiple sub-makes run concurrently. Always suppress them in parallel mode:

make -j$(nproc) --no-print-directory

Build Log Filtering

If you can’t modify the Makefile or command line, filter the output after the fact:

# Remove entering/leaving messages from build log
make 2>&1 | grep -v "Entering directory\|Leaving directory" | tee build.log

# Show only warnings and errors
make 2>&1 | grep -E "warning:|error:|Error" | tee errors.log

# Colorize errors in real time
make 2>&1 | grep --color=auto -E "^|error:|Error"

Make and CMake Integration

If your project uses CMake as the meta-build system, CMake generates Makefiles that use recursive make. Suppress directory messages in the CMake build:

cmake -DCMAKE_VERBOSE_MAKEFILE=ON ..
make --no-print-directory -j$(nproc)

Or set the flag in your CMakeLists.txt:

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_MAKE_PROGRAM "make --no-print-directory")
← All posts