$npx -y skills add mohitmishra786/low-level-dev-skills --skill makeGNU Make skill for C/C++ build systems. Use when writing or debugging Makefiles, understanding pattern rules and automatic dependency generation, managing CFLAGS/LDFLAGS, converting ad-hoc compile commands into maintainable Makefiles, or diagnosing incremental build issues. Activ
| 1 | # GNU Make |
| 2 | |
| 3 | ## Purpose |
| 4 | |
| 5 | Guide agents through idiomatic Makefile patterns for C/C++ projects: phony targets, pattern rules, automatic dependency generation, and common build idioms. |
| 6 | |
| 7 | ## Triggers |
| 8 | |
| 9 | - "How do I write a Makefile for my C project?" |
| 10 | - "My Makefile rebuilds everything every time" |
| 11 | - "How do I add dependency tracking to Make?" |
| 12 | - "What does `$@`, `$<`, `$^` mean?" |
| 13 | - "I'm getting 'make: Nothing to be done for all'" |
| 14 | - "How do I convert my shell compile script to a Makefile?" |
| 15 | |
| 16 | ## Workflow |
| 17 | |
| 18 | ### 1. Minimal correct Makefile for C |
| 19 | |
| 20 | ```makefile |
| 21 | CC := gcc |
| 22 | CFLAGS := -std=c11 -Wall -Wextra -g -O2 |
| 23 | LDFLAGS := |
| 24 | LDLIBS := |
| 25 | |
| 26 | SRCS := $(wildcard src/*.c) |
| 27 | OBJS := $(SRCS:src/%.c=build/%.o) |
| 28 | TARGET := build/prog |
| 29 | |
| 30 | .PHONY: all clean |
| 31 | |
| 32 | all: $(TARGET) |
| 33 | |
| 34 | $(TARGET): $(OBJS) |
| 35 | $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) |
| 36 | |
| 37 | build/%.o: src/%.c | build |
| 38 | $(CC) $(CFLAGS) -c -o $@ $< |
| 39 | |
| 40 | build: |
| 41 | mkdir -p build |
| 42 | |
| 43 | clean: |
| 44 | rm -rf build |
| 45 | ``` |
| 46 | |
| 47 | Automatic variables: |
| 48 | |
| 49 | - `$@` — target name |
| 50 | - `$<` — first prerequisite |
| 51 | - `$^` — all prerequisites (deduplicated) |
| 52 | - `$*` — stem (the `%` part in a pattern rule) |
| 53 | - `$(@D)` — directory part of `$@` |
| 54 | |
| 55 | ### 2. Automatic dependency generation |
| 56 | |
| 57 | Without this, changing a header doesn't trigger a rebuild of `.c` files that include it. |
| 58 | |
| 59 | ```makefile |
| 60 | CC := gcc |
| 61 | CFLAGS := -std=c11 -Wall -Wextra -g -O2 |
| 62 | DEPFLAGS = -MMD -MP # -MMD: generate .d file; -MP: phony targets for headers |
| 63 | |
| 64 | SRCS := $(wildcard src/*.c) |
| 65 | OBJS := $(SRCS:src/%.c=build/%.o) |
| 66 | DEPS := $(OBJS:.o=.d) |
| 67 | TARGET := build/prog |
| 68 | |
| 69 | .PHONY: all clean |
| 70 | |
| 71 | all: $(TARGET) |
| 72 | |
| 73 | $(TARGET): $(OBJS) |
| 74 | $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) |
| 75 | |
| 76 | build/%.o: src/%.c | build |
| 77 | $(CC) $(CFLAGS) $(DEPFLAGS) -MF $(@:.o=.d) -c -o $@ $< |
| 78 | |
| 79 | -include $(DEPS) # '-' ignores errors on first build (no .d files yet) |
| 80 | |
| 81 | build: |
| 82 | mkdir -p build |
| 83 | |
| 84 | clean: |
| 85 | rm -rf build |
| 86 | ``` |
| 87 | |
| 88 | ### 3. Pattern rules cheatsheet |
| 89 | |
| 90 | ```makefile |
| 91 | # Compile C |
| 92 | %.o: %.c |
| 93 | $(CC) $(CFLAGS) -c -o $@ $< |
| 94 | |
| 95 | # Compile C++ |
| 96 | %.o: %.cpp |
| 97 | $(CXX) $(CXXFLAGS) -c -o $@ $< |
| 98 | |
| 99 | # Generate assembly |
| 100 | %.s: %.c |
| 101 | $(CC) $(CFLAGS) -S -o $@ $< |
| 102 | |
| 103 | # Run a tool on each file |
| 104 | build/%.processed: src/%.raw | build |
| 105 | mytool $< > $@ |
| 106 | ``` |
| 107 | |
| 108 | ### 4. Common Make patterns |
| 109 | |
| 110 | #### Debug and release builds |
| 111 | |
| 112 | ```makefile |
| 113 | BUILD ?= release |
| 114 | |
| 115 | ifeq ($(BUILD),debug) |
| 116 | CFLAGS += -g -Og -DDEBUG |
| 117 | else |
| 118 | CFLAGS += -O2 -DNDEBUG |
| 119 | endif |
| 120 | ``` |
| 121 | |
| 122 | Usage: `make BUILD=debug` |
| 123 | |
| 124 | #### Parallel builds |
| 125 | |
| 126 | ```bash |
| 127 | make -j$(nproc) # use all CPUs |
| 128 | make -j4 # exactly 4 jobs |
| 129 | ``` |
| 130 | |
| 131 | Add `-Otarget` (or `-O`) for ordered output: `make -j$(nproc) -O` |
| 132 | |
| 133 | #### Verbose output |
| 134 | |
| 135 | ```makefile |
| 136 | # In Makefile: suppress with @ |
| 137 | build/%.o: src/%.c | build |
| 138 | @echo " CC $<" |
| 139 | @$(CC) $(CFLAGS) -c -o $@ $< |
| 140 | ``` |
| 141 | |
| 142 | Override silence: `make V=1` if you guard with `$(V)`: |
| 143 | |
| 144 | ```makefile |
| 145 | Q := $(if $(V),,@) |
| 146 | build/%.o: src/%.c |
| 147 | $(Q)$(CC) $(CFLAGS) -c -o $@ $< |
| 148 | ``` |
| 149 | |
| 150 | #### Installing |
| 151 | |
| 152 | ```makefile |
| 153 | PREFIX ?= /usr/local |
| 154 | |
| 155 | install: $(TARGET) |
| 156 | install -d $(DESTDIR)$(PREFIX)/bin |
| 157 | install -m 0755 $(TARGET) $(DESTDIR)$(PREFIX)/bin/ |
| 158 | ``` |
| 159 | |
| 160 | ### 5. Multi-directory projects |
| 161 | |
| 162 | For medium projects, avoid recursive make (fragile, slow). Use a flat Makefile that includes sub-makefiles: |
| 163 | |
| 164 | ```makefile |
| 165 | # project/Makefile |
| 166 | include lib/module.mk |
| 167 | include src/app.mk |
| 168 | ``` |
| 169 | |
| 170 | ```makefile |
| 171 | # lib/module.mk |
| 172 | LIB_SRCS := $(wildcard lib/*.c) |
| 173 | LIB_OBJS := $(LIB_SRCS:lib/%.c=build/lib_%.o) |
| 174 | OBJS += $(LIB_OBJS) |
| 175 | |
| 176 | build/lib_%.o: lib/%.c |
| 177 | $(CC) $(CFLAGS) -c -o $@ $< |
| 178 | ``` |
| 179 | |
| 180 | ### 6. Common errors |
| 181 | |
| 182 | | Error | Cause | Fix | |
| 183 | |-------|-------|-----| |
| 184 | | `No rule to make target 'foo.o'` | Missing source or rule | Check source path and pattern rule | |
| 185 | | `Nothing to be done for 'all'` | Targets up to date | Touch a source file or run `make clean` | |
| 186 | | `Circular dependency dropped` | Target depends on itself | Check dependency chain | |
| 187 | | `missing separator` | Tab vs spaces | Recipes must use a tab, not spaces | |
| 188 | | `*** multiple target patterns` | Pattern rule syntax error | Check `%` placement | |
| 189 | | Rebuilds everything every time | Timestamps wrong, or PHONY missing | Check `date`; ensure `all` is `.PHONY` | |
| 190 | | Header change not detected | No dep tracking | Add `-MMD -MP` and `-include $(DEPS)` | |
| 191 | |
| 192 | For a full variable and function reference, see [references/cheatsheet.md](references/cheatsheet.md). |
| 193 | |
| 194 | ## Related skills |
| 195 | |
| 196 | - Use `skills/build-systems/cmake` for CMake-based projects |
| 197 | - Use `skills/build-systems/ninja` for Ninja as a make backend |
| 198 | - Use `skills/compilers/gcc` for CFLAGS details |