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を宣言する:clean、all、test、installなど非ファイルターゲットは常に.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"
リソース
- GNU Make マニュアル - 権威的なリファレンス
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- dallay
- リポジトリ
- dallay/agentsync
- ライセンス
- MIT
- 最終更新
- 2026/5/11
Source: https://github.com/dallay/agentsync / ライセンス: MIT