MR
Mayur Rathi
@github
⭐ 34.1k GitHub stars

Makefile

Makefile是一款code方向的AI技能,核心价值是Best practices for authoring GNU Make Makefiles,可用于解决开发者在code领域的实际问题,帮助用户提升效率、自动化重复任务或优化工作流。

Best practices for authoring GNU Make Makefiles

Last verified on: 2026-05-30
mkdir -p ./skills/makefile && curl -sfL https://raw.githubusercontent.com/github/awesome-copilot/main/skills/makefile/SKILL.md -o ./skills/makefile/SKILL.md

Run in terminal / PowerShell. Requires curl (Unix) or PowerShell 5+ (Windows).

Skill Content

# Makefile Development Instructions


Instructions for writing clean, maintainable, and portable GNU Make Makefiles. These instructions are based on the [GNU Make manual](https://www.gnu.org/software/make/manual/).


General Principles


- Write clear and maintainable makefiles that follow GNU Make conventions

- Use descriptive target names that clearly indicate their purpose

- Keep the default goal (first target) as the most common build operation

- Prioritize readability over brevity when writing rules and recipes

- Add comments to explain complex rules, variables, or non-obvious behavior


Naming Conventions


- Name your makefile `Makefile` (recommended for visibility) or `makefile`

- Use `GNUmakefile` only for GNU Make-specific features incompatible with other make implementations

- Use standard variable names: `objects`, `OBJECTS`, `objs`, `OBJS`, `obj`, or `OBJ` for object file lists

- Use uppercase for built-in variable names (e.g., `CC`, `CFLAGS`, `LDFLAGS`)

- Use descriptive target names that reflect their action (e.g., `clean`, `install`, `test`)


File Structure


- Place the default goal (primary build target) as the first rule in the makefile

- Group related targets together logically

- Define variables at the top of the makefile before rules

- Use `.PHONY` to declare targets that don't represent files

- Structure makefiles with: variables, then rules, then phony targets


makefile
# Variables
CC = gcc
CFLAGS = -Wall -g
objects = main.o utils.o

# Default goal
all: program

# Rules
program: $(objects)
	$(CC) -o program $(objects)

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

# Phony targets
.PHONY: clean all
clean:
	rm -f program $(objects)

Variables and Substitution


- Use variables to avoid duplication and improve maintainability

- Define variables with `:=` (simple expansion) for immediate evaluation, `=` for recursive expansion

- Use `?=` to set default values that can be overridden

- Use `+=` to append to existing variables

- Reference variables with `$(VARIABLE)` not `$VARIABLE` (unless single character)

- Use automatic variables (`$@`, `$<`, `$^`, `$?`, `$*`) in recipes to make rules more generic


makefile
# Simple expansion (evaluates immediately)
CC := gcc

# Recursive expansion (evaluates when used)
CFLAGS = -Wall $(EXTRA_FLAGS)

# Conditional assignment
PREFIX ?= /usr/local

# Append to variable
CFLAGS += -g

Rules and Prerequisites


- Separate targets, prerequisites, and recipes clearly

- Use implicit rules for standard compilations (e.g., `.c` to `.o`)

- List prerequisites in logical order (normal prerequisites before order-only)

- Use order-only prerequisites (after `|`) for directories and dependencies that shouldn't trigger rebuilds

- Include all actual dependencies to ensure correct rebuilds

- Avoid circular dependencies between targets

- Remember that order-only prerequisites are omitted from automatic variables like `$^`, so reference them explicitly if needed


The example below shows a pattern rule that compiles objects into an `obj/` directory. The directory itself is listed as an order-only prerequisite so it is created before compiling but does not force recompilation when its timestamp changes.


makefile
# Normal prerequisites
program: main.o utils.o
	$(CC) -o $@ $^

# Order-only prerequisites (directory creation)
obj/%.o: %.c | obj
	$(CC) $(CFLAGS) -c $< -o $@

obj:
	mkdir -p obj

Recipes and Commands


- Start every recipe line with a **tab character** (not spaces) unless `.RECIPEPREFIX` is changed

- Use `@` prefix to suppress command echoing when appropriate

- Use `-` prefix to ignore errors for specific commands (use sparingly)

- Combine related commands with `&&` or `;` on the same line when they must execute together

- Keep recipes readable; break long commands across multiple lines with backslash continuation

- Use shell conditionals and loops within recipes when needed


makefile
# Silent command
clean:
	@echo "Cleaning up..."
	@rm -f $(objects)

# Ignore

🎯 Best For

  • Claude users
  • GitHub Copilot users
  • Software engineers
  • Development teams
  • Tech leads

💡 Use Cases

  • Code quality improvement
  • Best practice enforcement

📖 How to Use This Skill

  1. 1

    Install the Skill

    Copy the install command from the Terminal tab and run it. The SKILL.md file downloads to your local skills directory.

  2. 2

    Load into Your AI Assistant

    Open Claude or GitHub Copilot and reference the skill. Paste the SKILL.md content or use the system prompt tab.

  3. 3

    Apply Makefile to Your Work

    Open your project in the AI assistant and ask it to apply the skill. Start with a small module to verify the output quality.

  4. 4

    Review and Refine

    Review AI suggestions before committing. Run tests, check for regressions, and iterate on the skill output.

❓ Frequently Asked Questions

Is Makefile compatible with Cursor and VS Code?

Yes — this skill works with any AI coding assistant including Cursor, VS Code with Copilot, and JetBrains IDEs.

Do I need specific dependencies for Makefile?

Check the install command and Works With section. Most code skills only require the AI assistant and your codebase.

How do I install Makefile?

Copy the install command from the Terminal tab and run it. The skill downloads to ./skills/makefile/SKILL.md, ready to use.

Can I customize this skill for my team?

Absolutely. Edit the SKILL.md file to add team-specific instructions, examples, or workflows.

⚠️ Common Mistakes to Avoid

Skipping validation

Always test AI-generated code changes, even for simple refactors.

Missing dependency updates

Check if the skill requires updated dependencies or new packages.

🔗 Related Skills