Challenge 3: A Makefile for the Project, and What Running make Twice Does — Possible Solution ==================================================================== Makefile: program: main.o math_utils.o gcc main.o math_utils.o -o program main.o: main.c math_utils.h gcc -c main.c -o main.o math_utils.o: math_utils.c math_utils.h gcc -c math_utils.c -o math_utils.o clean: rm -f *.o program (Note: the indented lines under each target must use a literal TAB character, not spaces -- a real, common Makefile gotcha in its own right.) Running `make` the FIRST time: none of the target files (program, main.o, math_utils.o) exist yet, so every rule's dependencies are "newer" than a nonexistent target by definition. make runs every compile and link command: compiles main.c to main.o, compiles math_utils.c to math_utils.o, then links both into program. Running `make` a SECOND time, with NOTHING changed in between: make checks each target's modification timestamp against its listed dependencies. main.o now exists and is newer than main.c and math_utils.h (nothing edited them since main.o was built) -- so main.o's rule is considered up to date and its recompile command does NOT run. The same reasoning applies to math_utils.o, and then to program itself (both math_utils.o and main.o remain unchanged, so program's own link step also doesn't re-run). make prints something like "make: 'program' is up to date." and exits without recompiling or re-linking anything at all. WHY THIS WORKS AS AN ANSWER ------------------------------ This correctly follows the chapter's own dependency-rule pattern (listing math_utils.h as a dependency of both .o files, not just the corresponding .c file), and explains the SECOND make invocation correctly as doing genuinely nothing -- not "rebuilding everything again" -- because every target's timestamp is already newer than its dependencies, which is precisely the incremental-rebuild behavior the chapter names as make's whole reason for existing.