Makefile
Makefile是一款code方向的AI技能,核心价值是Best practices for authoring GNU Make Makefiles,可用于解决开发者在code领域的实际问题,帮助用户提升效率、自动化重复任务或优化工作流。
Best practices for authoring GNU Make Makefiles
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
# 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
# Simple expansion (evaluates immediately)
CC := gcc
# Recursive expansion (evaluates when used)
CFLAGS = -Wall $(EXTRA_FLAGS)
# Conditional assignment
PREFIX ?= /usr/local
# Append to variable
CFLAGS += -gRules 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.
# 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 objRecipes 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
# 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
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
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
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
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.