How to use a single top-level Makefile that includes fragments from each subdirectory, giving Make a complete dependency graph.
In lesson 11, Make runs as separate processes in each directory. It can't see dependencies across boundaries. With -j4, it might start building app before libmath finishes.
The paper "Recursive Make Considered Harmful" (Peter Miller, 1998) describes this in detail.
Instead of invoking sub-Makes, a single Makefile includes module fragments (module.mk) from each directory:
12_nonrecursive_make/
├── Makefile ← single top-level Makefile
├── libfmt/
│ ├── module.mk ← defines LIBFMT_SRCS, LIBFMT_OBJS, etc.
│ ├── include/fmt.hpp
│ └── src/fmt.cpp
└── app/
├── module.mk ← defines APP_SRCS, APP_OBJS, etc.
└── src/main.cpp
Each module.mk uses full paths relative to the project root:
# libfmt/module.mk
LIBFMT_SRCS = libfmt/src/fmt.cpp
LIBFMT_OBJS = $(LIBFMT_SRCS:.cpp=.o)
LIBFMT_LIB = libfmt/libfmt.a
$(LIBFMT_LIB): $(LIBFMT_OBJS)
$(AR) $(ARFLAGS) $@ $^# Declare default target BEFORE includes
all:
include libfmt/module.mk
include app/module.mk
# Wire the dependency after all variables are defined
all: $(APP_BIN)Without this, the first target inside a module.mk becomes Make's default target — not what you want.
| Recursive | Non-recursive |
|---|---|
| Multiple Make processes | Single Make process |
| Manual ordering required | Make resolves order from dependency graph |
-j can break across modules |
-j works correctly everywhere |
| Can't detect cross-module changes | Full dependency visibility |
cd 12_nonrecursive_make
make # builds library and app in correct order
./app/app # bold, underlined, and red text (ANSI codes)
make -j4 # parallel build — works correctly!
make clean| File | Purpose |
|---|---|
Makefile |
Top-level: sets variables, includes fragments |
libfmt/module.mk |
Defines library targets and sources |
libfmt/include/fmt.hpp |
ANSI terminal formatting functions |
libfmt/src/fmt.cpp |
Implements bold, underline, red |
app/module.mk |
Defines app target and sources |
app/src/main.cpp |
Uses the formatting library |