5.3.7 · HinglishBuild Systems & Toolchain

Phony targets, pattern rules, implicit rules

2,057 words9 min readRead in English

5.3.7 · Coding › Build Systems & Toolchain


1. Core model (scratch se derive karo)

KAYA hai ek rule — atomic unit:

target: prerequisites
	recipe       # MUST be a TAB, not spaces

KAISE Make decide karta hai recipe run karne ko:

TIMESTAMPS KYUN, content nahi? Kyunki timestamp check karna hai — ek stat() call — jabki file contents ko hash karna hai. Make clock-skew-correctness ki jagah speed leta hai. Yeh akela faisla sab kuch niche drive karta hai.


2. Phony targets

.PHONY KYUN CHAHIYE: socho teri directory mein accidentally clean naam ki ek file exist karti hai.

clean:
	rm -f *.o

.PHONY ke bina, Make file clean dekhta hai, paata hai uske koi prerequisites nahi hain, decide karta hai woh up to date hai (timestamp model: missing? nahi. kisi prereq se purani? koi prereqs nahi hain), aur print karta hai make: 'clean' is up to date.recipe kabhi nahi chalti. Yahi bug hai.

Fix — Make ko batao ki yeh target hamesha out of date hai:

.PHONY: clean all test
 
all: program
 
clean:
	rm -f *.o program
 
test: program
	./program --selftest

3. Pattern rules

Canonical wala:

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

Step by step % kya karta hai, jab Make ko parser.o chahiye:

  1. Make ko parser.o chahiye. Koi explicit rule nahi? Pattern rules search karo.
  2. %.o matches karta hai parser.o ke saath stem = parser. Yeh step kyun? % greedily woh sab bind karta hai jo literal parts (.o) ko align kare.
  3. Stem ko prereq %.c mein substitute karo → parser.c. Kyun? Stem dono taraf identical hona chahiye — isi tarah Make target ko source se link karta hai.
  4. Agar parser.c exist karta hai (ya khud banaaya ja sakta hai), toh rule apply hota hai.

Automatic variables (inhe cold yaad karo):

Var Matlab Hamare parser.o rule mein
$@ target parser.o
$< pehla prerequisite parser.c
$^ saare prerequisites (deduped) parser.c parser.h …
$* stem parser

AUTOMATIC VARIABLES KYUN EXIST KARTE HAIN: pattern abhi concrete names nahi jaanta, isliye Make unhe match time par inject karta hai. Tum rule ek baar likho, generically.

Figure — Phony targets, pattern rules, implicit rules

4. Implicit rules

KYUN: 90% C/C++ projects .c → .o usi tarah compile karte hain, isliye GNU Make isse hard-code karta hai:

# built-in, roughly:
%.o: %.c
	$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

Toh yeh poora Makefile kaam karta hai:

program: main.o util.o
	$(CC) $^ -o $@
# koi %.o rule nahi likha — implicit rule main.o aur util.o build karta hai!

Tum implicit rules ko built-in variables ke zariye influence karte ho: CC, CFLAGS, CPPFLAGS, LDFLAGS. Yahi hai 80/20: woh variables set karo, implicit machinery ko kaam karne do.


5. Worked examples


6. Forecast-then-Verify


7. Flashcards

Make mein target "out of date" kab hota hai?
Jab woh missing ho, YA kam se kam ek prerequisite ka modification time target se newer ho.
clean ko .PHONY kyun chahiye?
Taaki disk par same-naam ki file ko already-built na samjha jaaye, jo recipe ko skip kar deti.
Pattern rule mein % kya capture karta hai?
Stem — woh substring jo, literal parts ke saath, target se match karta hai; wohi stem prerequisites mein reuse hota hai.
$@, $<, $^, $* ka matlab?
target, pehla prerequisite, saare prerequisites (deduped), stem.
Pattern rule aur implicit rule mein fark?
Pattern rule woh hota hai jo tum likhte ho; implicit rule ek built-in pattern rule hota hai jo Make ke saath pehle se aata hai (jaise %.o:%.c).
Make mein rule precedence order?
Explicit rule > tumhara pattern rule > built-in implicit rule.
Implicit rules mein compiler kaun sa variable select karta hai?
CC (default cc); make CC=clang se override karo.
Timestamps kyun, content hashing kyun nahi?
stat() timestamp check O(1) hai; hashing O(filesize) hai. Clock-correctness ki jagah speed.
%.o: %.c mein, net.o build karte waqt $* kya hai?
net (the stem).

Recall Feynman: 12-saal ke bache ko samjhao

LEGO instructions socho. Har step kehta hai "roof banane ke liye, pehle walls chahiye." Make ek robot hai jo yeh padhta hai. Yeh har piece par clock sticker dekhta hai: agar walls ko roof banne ke baad change kiya gaya, toh woh roof rebuild karta hai — warna time bachane ke liye skip karta hai. Phony steps woh kaam hain jaise "floor saaf karo" — "clean" naam ka koi LEGO piece nahi hai, isliye hum robot ko batate hain "yeh hamesha ek kaam hai, bas karo." Pattern rule ek instruction card hai jo har brick ke liye kaam karta hai: "koi bhi X-brick banane ke liye, uski X-stick lo aur snap karo." Implicit rule woh kaam hai jo robot pehle se dil se jaanta hai, isliye tum card bhi nahi likhte.

Connections

  • Makefile variables and expansion:= vs =, jahan CFLAGS rehta hai.
  • Dependency graphs and topological build order — §1 ke peeche ka DAG.
  • Incremental compilation — timestamps kyun sab-kuch-rebuild-na-karne enable karte hain.
  • CMake and Ninja — modern generators jo tumhare liye yeh rules emit karte hain.
  • Compiler flags CFLAGS LDFLAGS — implicit rules ke knobs.
  • Build reproducibility — kyun CC pin karna matter karta hai.

Concept Map

drives

checks

O 1 stat vs hashing

target missing or prereq newer

repeated 100x is verbose

solved by

solved by

breaks for non-file goals

declared with

forces

acts as

Rule: target prereqs recipe

Rebuild decision

Timestamps mtime

Speed over content-check

Run recipe

Boilerplate problem

Pattern rules %.o %.c

Implicit rules built-in

Phony targets clean all test

.PHONY marker

Timestamp +infinity