Agent Skills by ALSEL
OpenAIソフトウェア開発⭐ リポ 35品質スコア 80/100

makefile

クリーンで保守性の高い、ポータブルなGNU Make Makefileを作成するためのベストプラクティスです。Makefileの作成または編集、`Makefile`、`makefile`、`*.mk`、`GNUmakefile`、GNU Makeパターン、ビルド自動化、Makefileのトラブルシューティングなどのタスクに活用できます。

description の原文を見る

Best practices for authoring clean, maintainable, and portable GNU Make Makefiles. Use when the task involves `creating or editing Makefiles`, `Makefile`, `makefile`, `*.mk`, `GNUmakefile`, `GNU Make patterns`, `build automation`, or `makefile troubleshooting`.

SKILL.md 本文

使用時期

  • 任意のプロジェクト(C/C++、Go、Node.js など)の新しい Makefile を作成するとき
  • 既存の Makefile の正確性と保守性をレビューまたはリファクタリングするとき
  • make ルール、前提条件、変数に関連するビルド失敗をデバッグするとき
  • GNU Make でビルド自動化をセットアップするとき(パターンルール、自動依存関係、並列ビルド)
  • プラットフォーム間のポータビリティを確保するか、GNU Make の規約に準拠するとき

重要なパターン

  • タブ、スペースではなく: すべてのレシピ行は タブ文字 で始まる必要があります。スペースはシンタックスエラーを引き起こします。
  • .PHONY を宣言する: cleanalltestinstall など非ファイルターゲットは常に .PHONY でマークして、同名のファイルとの競合を回避します。
  • = より := を使う: 変数には単純展開(:=)を優先して使用し、予期しない再帰展開を回避し、パフォーマンスを向上させます。
  • 自動変数を使う: レシピで $@(ターゲット)、$<(最初の前提条件)、$^(すべての前提条件)、$?(新しい前提条件)、$*(幹) を使用して、ルールを汎用的で再利用可能に保ちます。
  • $(shell ls ...) ではなく $(wildcard ...) を使う: ファイル一覧に shell を使用しないでください。代わりに Make の組み込み $(wildcard *.c) 関数を使用します。
  • 依存関係を自動生成する: ヘッダ依存関係を手動で保持するのではなく、-MMD -MP のようなコンパイラフラグを使用して .d ファイルを生成します。
  • Clean ターゲット: 常に clean ターゲットを提供し、ファイルが存在しない場合のエラーを無視するために - を削除コマンドの前に付けます。
  • 変数が最初、ルールが次: すべての変数をトップに定義し、その後にデフォルトゴール、ビルドルール、phony ターゲットの順に続けます。
  • 再帰的 Make を避ける: 絶対に必要な場合を除き、$(MAKE) -C subdir を使用しないでください。includes または非再帰的なアプローチを優先します。

ファイル構造

# -------------------------------------------------------
# Project: <name>
#
# Usage:
#   make          - Build the project
#   make clean    - Remove generated files
#   make install  - Install to $(PREFIX)
#   make test     - Run tests
#
# Variables:
#   CC       - C compiler (default: gcc)
#   PREFIX   - Installation prefix (default: /usr/local)
# -------------------------------------------------------

# --- Variables ---
CC       ?= gcc
CFLAGS   := -Wall -Wextra -O2
PREFIX   ?= /usr/local

sources  := $(wildcard src/*.c)
objects  := $(sources:.c=.o)
deps     := $(objects:.o=.d)

# --- Default Goal ---
all: program

# --- Build Rules ---
program: $(objects)
	$(CC) -o $@ $^ $(LDFLAGS)

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

-include $(deps)

# --- Phony Targets ---
.PHONY: all clean install test

clean:
	-rm -f program $(objects) $(deps)

install: program
	install -d $(PREFIX)/bin
	install -m 755 program $(PREFIX)/bin

test: program
	./run-tests.sh

コード例

変数と置換

# Simple expansion (evaluates immediately) - PREFERRED
CC := gcc

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

# Conditional assignment (set default, allow override)
PREFIX ?= /usr/local

# Append to variable
CFLAGS += -g

# Always reference with $() - not bare $VAR
objects := $(sources:.c=.o)

パターンルールと暗黙ルール

# Custom pattern rule for generic transformations
%.pdf: %.md
	pandoc $< -o $@

# Compile with auto-dependency generation
%.o: %.c
	$(CC) $(CFLAGS) -MMD -MP -c $< -o $@

Order-Only 前提条件

# The directory is created before compiling but does NOT
# trigger recompilation when its timestamp changes.
obj/%.o: %.c | obj
	$(CC) $(CFLAGS) -c $< -o $@

obj:
	mkdir -p obj

条件付きディレクティブ

ifeq ($(OS),Windows_NT)
    EXE_EXT := .exe
else
    EXE_EXT :=
endif

program: main.o
	$(CC) -o program$(EXE_EXT) main.o

長い行の分割

# Use backslash-newline to split for readability
sources := main.c \
           utils.c \
           parser.c \
           handler.c

# In recipes, backslash-newline continues the shell command
install: program
	install -d $(PREFIX)/bin && \
		install -m 755 program $(PREFIX)/bin

他の Makefile を含める

# Include shared configuration
include config.mk

# Include optional local overrides (no error if missing)
-include local.mk

エラー処理と検証

# Validate required tools
ifeq ($(shell which gcc 2>/dev/null),)
    $(error gcc is not installed or not in PATH)
endif

# Validate required variables
ifndef VERSION
    $(error VERSION is not defined. Usage: make VERSION=1.2.3)
endif

特殊なターゲット

# Delete targets if recipe fails (recommended)
.DELETE_ON_ERROR:

# Don't delete intermediate files
.SECONDARY:

# Preserve specific intermediate files
.PRECIOUS: %.o

複数プログラムの管理

programs := prog1 prog2 prog3

.PHONY: all clean

all: $(programs)

prog1: prog1.o common.o
	$(CC) -o $@ $^

prog2: prog2.o common.o
	$(CC) -o $@ $^

clean:
	-rm -f $(programs) *.o

避けるべきアンチパターン

アンチパターン問題点代わりにすること
レシピ内のスペースとタブの混用シンタックスエラーで デバッグが困難タブ 文字を使用する
ファイル一覧に $(shell ls *.c) を使用サブプロセスを作成し脆弱$(wildcard *.c) を使用
.PHONY 宣言が欠落clean という名前のファイルが存在する場合、clean が実行されない.PHONY: clean と宣言
ファイル一覧のハードコードメンテナンスの負担が増え、新しいファイルの追加忘れが発生しやすい$(wildcard ...) または自動検出を使用
レシピ内の複雑なシェルスクリプト読み取りとデバッグが困難別の .sh スクリプトに移動する
再帰的 Make $(MAKE) -C subdirディレクトリ間の依存関係追跡が失われるinclude または非再帰的 make を使用
すべての場所で = を使用予期しない再帰展開とパフォーマンス低下単純値には := を使用
循環依存関係無限ループ、ビルド失敗依存関係グラフを再構築

コマンド

# Dry run - see what would execute without running
make -n

# Force rebuild all targets
make -B

# Parallel build (use number of CPU cores)
make -j$(nproc)

# Print the database of rules and variables (debugging)
make -p

# Show which makefile and line number each rule comes from
make -d

# Override a variable from the command line
make CC=clang CFLAGS="-O3"

リソース

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
dallay
リポジトリ
dallay/agentsync
ライセンス
MIT
最終更新
2026/5/11

Source: https://github.com/dallay/agentsync / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: dallay · dallay/agentsync · ライセンス: MIT