Το GNU Make είναι ένα εργαλείο αυτοματοποίησης κατασκευής (build) που παράγει εκτελέσιμα προγράμματα και βιβλιοθήκες από πηγαίο κώδικα διαβάζοντας αρχεία Makefile.
Αναθέσεις μεταβλητών
foo = "bar" # Lazy (dynamically expanded when used)
bar = $(foo) foo # Dynamically references $(foo)
foo := "boo" # Immediate (simply expanded once at declaration)
foo ?= /usr/local # Conditional (assign only if foo is not already set)
bar += world # Append to existing value
foo != echo hello # Shell execution (GNU Make 4.0+)
Αυτόματες μεταβλητές
Κατά την εκτέλεση κανόνων, το Make παρέχει αυτόματες μεταβλητές για αναφορές στόχων και προαπαιτούμενων:
out.o: src.c src.h
$@ # "out.o" (the target name)
$< # "src.c" (first prerequisite)
$^ # "src.c src.h" (all prerequisites with duplicates omitted)
$+ # "src.c src.h" (all prerequisites preserving duplicates)
$? # Prerequisites newer than the target
$| # Order-only prerequisites
%.o: %.c
$* # The matched pattern stem ("foo" in "foo.c")
$(@D) # Directory part of the target ("build" in "build/out.o")
$(@F) # File part of the target ("out.o" in "build/out.o")
Προθέματα εντολών συνταγής
| Πρόθεμα | Συμπεριφορά |
|---|---|
@ |
Να μην εκτυπώνεται η εντολή στο stdout πριν την εκτέλεση |
- |
Παράβλεψη μη μηδενικών κωδικών εξόδου (συνέχιση σε σφάλμα) |
+ |
Εκτέλεση εντολής ακόμα κι αν το Make τρέχει με -n (dry-run) |
build:
@echo "Compiling binary..."
-rm -rf temp/
gcc -o main main.c
Συναρτήσεις & Αντιστοίχιση αρχείων
Μπαλαντέρ (Wildcards) & Κέλυφος
js_files := $(wildcard src/*.js)
all_files := $(shell find images/ -type f)
Αντικατάσταση κειμένου & Φιλτράρισμα
# Extension substitution
objects = $(sources:.cpp=.o)
# Pattern substitution
outputs = $(patsubst src/%.c, build/%.o, $(wildcard src/*.c))
# Filter and filter-out
c_files = $(filter %.c, $(files))
non_c = $(filter-out %.c, $(files))
# Whitespace stripping
clean_var = $(strip $(dirty_var))
Συνθήκες
ifeq ($(CC),gcc)
CFLAGS += -Wall -O2
else ifeq ($(CC),clang)
CFLAGS += -Weverything
else
CFLAGS += -O0
endif
Επιλογές γραμμής εντολών
make -j 8 # Run parallel jobs (8 concurrent threads)
make -B, --always-make # Unconditionally build all targets
make -n, --dry-run # Print commands without executing
make -s, --silent # Do not print recipe commands
make -e # Environment variables override Makefile variables