itechmeat

makefile

1
0
# Install this skill:
npx skills add itechmeat/llm-code --skill "makefile"

Install specific skill from multi-skill repository

# Description

GNU Make automation and build system guidance

# SKILL.md


name: makefile
description: GNU Make automation and build system guidance
version: 2.0.0
release_date: "2023-02-26"


Makefile Skill

Guidance for creating and maintaining GNU Make build automation.

Quick Navigation

Topic Reference
Rules, prerequisites, targets syntax.md
Variable types and assignment variables.md
Built-in functions functions.md
Special and phony targets targets.md
Recipe execution, parallel recipes.md
Implicit and pattern rules implicit.md
Common practical patterns patterns.md

Core Concepts

Rule Structure

target: prerequisites
        recipe

Critical: Recipe lines MUST start with TAB character.

File vs Phony Targets

# File target - creates/updates a file
build/app.o: src/app.c
        $(CC) -c $< -o $@

# Phony target - action, not a file
.PHONY: clean test install

clean:
        rm -rf build/

Variable Assignment

Operator Name When Expanded
:= Simple Once, at definition
?= Conditional If not already set
= Recursive Each use (late binding)
+= Append Adds to existing value
CC := gcc              # Immediate
CFLAGS ?= -O2          # Default, overridable
DEBUG = $(VERBOSE)     # Late binding
CFLAGS += -Wall        # Append

Automatic Variables

Variable Meaning
$@ Target
$< First prerequisite
$^ All prerequisites (unique)
$? Prerequisites newer than target
$* Stem in pattern rules

Essential Patterns

Self-Documenting Help

.DEFAULT_GOAL := help

help: ## Show available targets
    @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
        awk 'BEGIN {FS = ":.*?## "}; {printf "  %-15s %s\n", $$1, $$2}'

install: ## Install dependencies
    uv sync

test: ## Run tests
    uv run pytest

Platform Detection

UNAME_S := $(shell uname -s)

ifeq ($(UNAME_S),Darwin)
    OPEN := open
else ifeq ($(UNAME_S),Linux)
    OPEN := xdg-open
endif

Build Directory

BUILDDIR := build
SOURCES := $(wildcard src/*.c)
OBJECTS := $(patsubst src/%.c,$(BUILDDIR)/%.o,$(SOURCES))

$(BUILDDIR)/%.o: src/%.c | $(BUILDDIR)
    $(CC) -c $< -o $@

$(BUILDDIR):
    mkdir -p $@

Environment Export

export PYTHONPATH := $(PWD)/src
export DATABASE_URL

test:
    pytest tests/  # sees exported variables

Common Targets

Quality Checks

.PHONY: lint format check test

lint: ## Run linters
    ruff check .
    mypy src/

format: ## Format code
    ruff format .

check: format lint test ## All quality checks

Cleanup

.PHONY: clean clean-all

clean: ## Remove build artifacts
    rm -rf build/ dist/ *.egg-info
    find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true

clean-all: clean ## Remove all generated files
    rm -rf .venv .pytest_cache .mypy_cache

Docker Integration

IMAGE := myapp
VERSION := $(shell git describe --tags --always)

docker-build: ## Build Docker image
    docker build -t $(IMAGE):$(VERSION) .

docker-run: ## Run container
    docker run -d -p 8000:8000 $(IMAGE):$(VERSION)

Recipe Execution

Each Line = Separate Shell

# Won't work - cd lost between lines
bad:
    cd subdir
    pwd           # Still in original dir!

# Correct - combine commands
good:
    cd subdir && pwd

# Or use line continuation
also-good:
    cd subdir && \
    pwd && \
    make

Silent and Error Handling

target:
    @echo "@ suppresses command echo"
    -rm -f maybe.txt    # - ignores errors

Parallel Execution

make -j4              # 4 parallel jobs
make -j4 lint test    # Run lint and test in parallel

Output Discipline

One line in, one line out. Avoid echo spam.

# โŒ Too chatty
start:
    @echo "Starting services..."
    docker compose up -d
    @echo "Waiting..."
    @sleep 3
    @echo "Done!"

# โœ… Concise
start: ## Start services
    @echo "Starting at http://localhost:8000 ..."
    @docker compose up -d
    @echo "Logs: docker compose logs -f"

Conditionals

DEBUG ?= 0

ifeq ($(DEBUG),1)
    CFLAGS += -g -O0
else
    CFLAGS += -O2
endif

ifdef CI
    TEST_FLAGS := --ci
endif

Including Files

# Required include (error if missing)
include config.mk

# Optional include (silent if missing)
-include local.mk
-include .env

Common Pitfalls

Pitfall Problem Solution
Spaces in recipes Recipes need TAB Use actual TAB character
Missing .PHONY make test fails if test file exists Declare .PHONY: test
cd in recipes Each line is new shell Use cd dir && command
= vs := confusion Unexpected late expansion Use := by default
Unexported vars Subprocesses don't see vars export VAR
Complex shell in make Hard to maintain Move to external script

Quick Reference

# Makefile Template
.DEFAULT_GOAL := help
SHELL := /bin/bash
.SHELLFLAGS := -ec

.PHONY: help install test lint format clean

help: ## Show this help
    @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
        awk 'BEGIN {FS = ":.*?## "}; {printf "  %-15s %s\n", $$1, $$2}'

install: ## Install dependencies
    uv sync --extra dev

test: ## Run tests
    uv run pytest tests/ -v

lint: ## Run linters
    uv run ruff check .

format: ## Format code
    uv run ruff format .

clean: ## Clean artifacts
    rm -rf build/ dist/ .pytest_cache

See Also

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.