makefile-generator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Makefile Generator

Makefile 生成工具

Overview

概述

Generate production-ready Makefiles with best practices for C/C++, Python, Go, Java, and generic projects. Features GNU Coding Standards compliance, standard targets, security hardening, and automatic validation via devops-skills:makefile-validator skill.
生成符合最佳实践、可用于生产环境的Makefile,支持C/C++、Python、Go、Java及通用项目。具备GNU编码标准合规性、标准目标、安全加固功能,并可通过devops-skills:makefile-validator技能自动验证。

When to Use

使用场景

  • Creating new Makefiles from scratch
  • Setting up build systems for projects (C/C++, Python, Go, Java)
  • Implementing build automation and CI/CD integration
  • Converting manual build processes to Makefiles
  • The user asks to "create", "generate", or "write" a Makefile
Do NOT use for: Validating existing Makefiles (use devops-skills:makefile-validator), debugging (use
make -d
), or running builds.
  • 从零开始创建新的Makefile
  • 为项目(C/C++、Python、Go、Java)搭建构建系统
  • 实现构建自动化与CI/CD集成
  • 将手动构建流程转换为Makefile
  • 用户要求“创建”“生成”或“编写”Makefile时
请勿用于: 验证现有Makefile(请使用devops-skills:makefile-validator)、调试(请使用
make -d
)或运行构建。

Generation Workflow

生成流程

Stage 1: Gather Requirements

阶段1:收集需求

Collect information for the following categories. Use AskUserQuestion when information is missing or ambiguous:
CategoryInformation Needed
ProjectLanguage (C/C++/Python/Go/Java), structure (single/multi-directory)
BuildSource files, output artifacts, dependencies, build order
InstallPREFIX location, directories (bin/lib/share), files to install
Targetsall, install, clean, test, dist, help (which are needed?)
ConfigCompiler, flags, pkg-config dependencies, cross-compilation
When to Use AskUserQuestion (MUST ask if any apply):
ConditionExample Question
Language not specified"What programming language is this project? (C/C++/Go/Python/Java)"
Project structure unclear"Is this a single-directory or multi-directory project?"
Docker requested but registry unknown"Which container registry should be used? (docker.io/ghcr.io/custom)"
Multiple binaries possible"Should this build a single binary or multiple executables?"
Install targets needed but paths unclear"Where should binaries be installed? (default: /usr/local/bin)"
Cross-compilation mentioned"What is the target platform/architecture?"
When to Skip AskUserQuestion (proceed with defaults):
  • User explicitly provides all required information
  • Standard project type with obvious defaults (e.g., "Go project with Docker" → use standard Go+Docker patterns)
  • User says "use defaults" or "standard setup"
Default Assumptions (when not asking):
  • Single-directory project structure
  • PREFIX=/usr/local
  • Standard targets: all, build, test, clean, install, help
  • No cross-compilation
收集以下类别的信息。当信息缺失或不明确时,使用AskUserQuestion询问用户:
类别所需信息
项目编程语言(C/C++/Python/Go/Java)、结构(单目录/多目录)
构建源文件、输出产物、依赖项、构建顺序
安装PREFIX路径、目录(bin/lib/share)、待安装文件
目标all、install、clean、test、dist、help(需要哪些?)
配置编译器、编译标志、pkg-config依赖项、交叉编译
必须询问用户的情况(满足任一则必须询问):
条件示例问题
未指定编程语言“该项目使用什么编程语言?(C/C++/Go/Python/Java)”
项目结构不明确“这是单目录还是多目录项目?”
用户要求使用Docker但未指定镜像仓库“应使用哪个容器镜像仓库?(docker.io/ghcr.io/自定义)”
可能生成多个二进制文件“应构建单个二进制文件还是多个可执行文件?”
需要安装目标但路径不明确“二进制文件应安装到哪里?(默认:/usr/local/bin)”
提到交叉编译“目标平台/架构是什么?”
可跳过询问的情况(使用默认值):
  • 用户明确提供所有所需信息
  • 标准项目类型,默认值清晰(例如:“带Docker的Go项目”→使用标准Go+Docker模式)
  • 用户表示“使用默认值”或“标准配置”
默认假设(跳过询问时使用):
  • 单目录项目结构
  • PREFIX=/usr/local
  • 标准目标:all、build、test、clean、install、help
  • 不进行交叉编译

Stage 2: Documentation Lookup

阶段2:文档查阅

When REQUIRED (MUST perform lookup):
  • User requests integration with unfamiliar tools, frameworks, or build systems
  • Complex build patterns not covered in Stage 3 examples (e.g., Bazel, Meson, custom toolchains)
  • Docker/container integration (Dockerfile builds, multi-stage, registry push)
  • CI/CD platform-specific integration (GitHub Actions, GitLab CI, Jenkins)
  • Cross-compilation for unusual targets or embedded systems
  • Package manager integration (Conan, vcpkg, Homebrew formulas)
  • Multi-binary or multi-library projects
  • Version embedding via ldflags or build-time variables
When OPTIONAL (may skip external lookup):
  • Standard language patterns already covered in Stage 3 (C/C++, Go, Python, Java)
  • Simple single-binary projects with no external dependencies
  • User provides complete requirements with no ambiguity
  • Internal docs already cover the required pattern comprehensively
Lookup Process (follow in order):
  1. ALWAYS consult internal docs/ FIRST using the Read tool (primary source of truth):
    RequirementRead This Doc
    Docker/container targets
    docs/patterns-guide.md
    (Pattern 8: Docker Integration)
    Multi-binary projects
    docs/patterns-guide.md
    (Pattern 7: Multi-Binary Project)
    Go projects with version embedding
    docs/patterns-guide.md
    (Pattern 5: Go Project)
    Parallel builds, caching, ccache
    docs/optimization-guide.md
    Credentials, secrets, API keys
    docs/security-guide.md
    Complex dependencies, pattern rules
    docs/patterns-guide.md
    Order-only prerequisites
    docs/optimization-guide.md
    or
    docs/targets-guide.md
    Variables, assignment operators
    docs/variables-guide.md
    CRITICAL: You MUST explicitly use the Read tool to consult relevant docs during generation, even if you have prior knowledge. Do NOT rely on context from earlier in the conversation. This ensures patterns are always current and correctly applied.
    Required Workflow Example (Docker + Go with version embedding):
    # Step 1: Use Read tool to get Go pattern
    Read: docs/patterns-guide.md (find Pattern 5: Go Project)
    
    # Step 2: Use Read tool to get Docker pattern
    Read: docs/patterns-guide.md (find Pattern 8: Docker Integration)
    
    # Step 3: Use Read tool for security considerations
    Read: docs/security-guide.md (credential handling for docker-push)
    
    # Step 4: Generate Makefile combining patterns
    # Step 5: Document which docs were consulted in Makefile header
    Important: Internal docs contain vetted, production-ready patterns. Always read the relevant docs before external lookups.
  2. Try context7 for external tool documentation (when internal docs don't cover a specific tool):
    # Only needed for tools/frameworks NOT covered in internal docs
    mcp__context7__resolve-library-id: "<tool-name>"
    mcp__context7__get-library-docs: topic="<integration-topic>"
    
    # Example topics:
    # - For Docker: topic="dockerfile best practices"
    # - For Go: topic="go build ldflags"
    # - For specific tools: topic="<tool> makefile integration"
    Note: Context7 may not have GNU Make-specific documentation. Skip if internal docs provide sufficient patterns.
  3. Fallback to WebSearch (only if pattern not found in internal docs OR context7):
    "<specific-feature>" makefile best practices 2025
    Example: "docker makefile best practices 2025"
    Example: "go ldflags version makefile 2025"
    Trigger WebSearch when: Internal docs don't cover the specific integration AND context7 returns no relevant results.
Note: Document which internal docs you consulted in your response (add comment in generated Makefile header).
必须执行查阅的情况:
  • 用户要求与不熟悉的工具、框架或构建系统集成
  • 阶段3示例未涵盖的复杂构建模式(例如Bazel、Meson、自定义工具链)
  • Docker/容器集成(Dockerfile构建、多阶段构建、镜像仓库推送)
  • 特定CI/CD平台集成(GitHub Actions、GitLab CI、Jenkins)
  • 针对特殊目标或嵌入式系统的交叉编译
  • 包管理器集成(Conan、vcpkg、Homebrew公式)
  • 多二进制文件或多库项目
  • 通过ldflags或构建时变量嵌入版本信息
可选择跳过的情况(可跳过外部查阅):
  • 阶段3已涵盖的标准语言模式(C/C++、Go、Python、Java)
  • 无外部依赖的简单单二进制文件项目
  • 用户提供完整需求,无歧义
  • 内部文档已全面涵盖所需模式
查阅流程(按顺序执行):
  1. 始终优先使用Read工具查阅内部文档(主要可信来源):
    需求查阅文档
    Docker/容器目标
    docs/patterns-guide.md
    (模式8:Docker集成)
    多二进制文件项目
    docs/patterns-guide.md
    (模式7:多二进制文件项目)
    带版本嵌入的Go项目
    docs/patterns-guide.md
    (模式5:Go项目)
    并行构建、缓存、ccache
    docs/optimization-guide.md
    凭证、密钥、API密钥
    docs/security-guide.md
    复杂依赖、模式规则
    docs/patterns-guide.md
    仅顺序前置依赖
    docs/optimization-guide.md
    docs/targets-guide.md
    变量、赋值运算符
    docs/variables-guide.md
    关键提示: 在生成过程中,必须明确使用Read工具查阅相关文档,即使您已有相关知识。请勿依赖对话早期的上下文。这可确保始终使用最新且正确的模式。
    示例工作流程(Docker + 带版本嵌入的Go项目):
    # 步骤1:使用Read工具获取Go项目模式
    Read: docs/patterns-guide.md(查找模式5:Go项目)
    
    # 步骤2:使用Read工具获取Docker模式
    Read: docs/patterns-guide.md(查找模式8:Docker集成)
    
    # 步骤3:使用Read工具查阅安全注意事项
    Read: docs/security-guide.md(docker-push的凭证处理)
    
    # 步骤4:结合模式生成Makefile
    # 步骤5:在生成的Makefile头部注明查阅过的文档
    重要提示: 内部文档包含经过验证、可用于生产环境的模式。在进行外部查阅前,务必先阅读相关内部文档。
  2. 若内部文档未覆盖特定工具,尝试使用context7查阅外部工具文档:
    # 仅适用于内部文档未覆盖的工具/框架
    mcp__context7__resolve-library-id: "<工具名称>"
    mcp__context7__get-library-docs: topic="<集成主题>"
    
    # 示例主题:
    # - 针对Docker:topic="dockerfile best practices"
    # - 针对Go:topic="go build ldflags"
    # - 针对特定工具:topic="<工具> makefile integration"
    注意: Context7可能没有GNU Make相关的特定文档。若内部文档已提供足够模式,可跳过此步骤。
  3. 仅当内部文档和context7均未找到模式时,才使用WebSearch作为备选方案:
    "<特定功能>" makefile best practices 2025
    示例:"docker makefile best practices 2025"
    示例:"go ldflags version makefile 2025"
    触发WebSearch的条件: 内部文档未覆盖特定集成,且context7未返回相关结果。
注意: 在响应中注明您查阅过的内部文档(在生成的Makefile头部添加注释)。

Stage 3: Generate Makefile

阶段3:生成Makefile

Header (choose one style)

头部(选择一种风格)

Traditional (POSIX-compatible):
makefile
.DELETE_ON_ERROR:
.SUFFIXES:
Modern (GNU Make 4.0+, recommended):
makefile
SHELL := bash
.ONESHELL:
.SHELLFLAGS := -eu -o pipefail -c
.DELETE_ON_ERROR:
.SUFFIXES:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
传统风格(兼容POSIX):
makefile
.DELETE_ON_ERROR:
.SUFFIXES:
现代风格(GNU Make 4.0+,推荐使用):
makefile
SHELL := bash
.ONESHELL:
.SHELLFLAGS := -eu -o pipefail -c
.DELETE_ON_ERROR:
.SUFFIXES:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules

Standard Variables

标准变量

makefile
undefined
makefile
undefined

User-overridable (use ?=)

用户可覆盖(使用?=)

CC ?= gcc CFLAGS ?= -Wall -Wextra -O2 PREFIX ?= /usr/local DESTDIR ?=
CC ?= gcc CFLAGS ?= -Wall -Wextra -O2 PREFIX ?= /usr/local DESTDIR ?=

GNU installation directories

GNU安装目录

BINDIR ?= $(PREFIX)/bin LIBDIR ?= $(PREFIX)/lib INCLUDEDIR ?= $(PREFIX)/include
BINDIR ?= $(PREFIX)/bin LIBDIR ?= $(PREFIX)/lib INCLUDEDIR ?= $(PREFIX)/include

Project-specific (use :=)

项目特定(使用:=)

PROJECT := myproject VERSION := 1.0.0 SRCDIR := src BUILDDIR := build SOURCES := $(wildcard $(SRCDIR)/*.c) OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(BUILDDIR)/%.o)
undefined
PROJECT := myproject VERSION := 1.0.0 SRCDIR := src BUILDDIR := build SOURCES := $(wildcard $(SRCDIR)/*.c) OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(BUILDDIR)/%.o)
undefined

Language-Specific Build Rules

特定语言构建规则

C/C++:
makefile
$(TARGET): $(OBJECTS)
	$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(BUILDDIR)/%.o: $(SRCDIR)/%.c
	@mkdir -p $(@D)
	$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@

-include $(OBJECTS:.o=.d)
Go:
makefile
$(TARGET): $(shell find . -name '*.go') go.mod
	go build -o $@ ./cmd/$(PROJECT)
Python:
makefile
.PHONY: build
build:
	python -m build

.PHONY: develop
develop:
	pip install -e .[dev]
Java:
makefile
$(BUILDDIR)/%.class: $(SRCDIR)/%.java
	@mkdir -p $(@D)
	javac -d $(BUILDDIR) -sourcepath $(SRCDIR) $<
C/C++:
makefile
$(TARGET): $(OBJECTS)
	$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(BUILDDIR)/%.o: $(SRCDIR)/%.c
	@mkdir -p $(@D)
	$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@

-include $(OBJECTS:.o=.d)
Go:
makefile
$(TARGET): $(shell find . -name '*.go') go.mod
	go build -o $@ ./cmd/$(PROJECT)
Python:
makefile
.PHONY: build
build:
	python -m build

.PHONY: develop
develop:
	pip install -e .[dev]
Java:
makefile
$(BUILDDIR)/%.class: $(SRCDIR)/%.java
	@mkdir -p $(@D)
	javac -d $(BUILDDIR) -sourcepath $(SRCDIR) $<

Standard Targets

标准目标

makefile
.PHONY: all clean install uninstall test help
makefile
.PHONY: all clean install uninstall test help

Build all targets

Build all targets

all: $(TARGET)
all: $(TARGET)

Install to PREFIX

Install to PREFIX

install: all install -d $(DESTDIR)$(BINDIR) install -m 755 $(TARGET) $(DESTDIR)$(BINDIR)/
install: all install -d $(DESTDIR)$(BINDIR) install -m 755 $(TARGET) $(DESTDIR)$(BINDIR)/

Remove built files

Remove built files

clean: $(RM) -r $(BUILDDIR) $(TARGET)
clean: $(RM) -r $(BUILDDIR) $(TARGET)

Run tests

Run tests

test: # Add test commands
test: # Add test commands

Show help

Show help

help: @echo "$(PROJECT) v$(VERSION)" @echo "Targets: all, install, clean, test, help" @echo "Override: make CC=clang PREFIX=/opt"
undefined
help: @echo "$(PROJECT) v$(VERSION)" @echo "Targets: all, install, clean, test, help" @echo "Override: make CC=clang PREFIX=/opt"
undefined

Stage 4: Validate and Format

阶段4:验证与格式化

CRITICAL: Always validate using devops-skills:makefile-validator skill.
1. Generate Makefile following stages above
2. Invoke devops-skills:makefile-validator skill
3. Fix any errors identified (MUST have 0 errors)
4. Apply formatting fixes (see "Formatting Step" below)
5. Fix warnings (SHOULD fix; explain if skipped)
6. Address info items for large/production projects
7. Re-validate until checks pass
8. Output structured validation report (REQUIRED - see format below)
关键提示:始终使用devops-skills:makefile-validator技能进行验证。
1. 按照上述阶段生成Makefile
2. 调用devops-skills:makefile-validator技能
3. 修复所有识别到的错误(必须确保错误数为0)
4. 应用格式化修复(见下方“格式化步骤”)
5. 修复警告(建议修复;若跳过需说明原因)
6. 针对大型/生产项目处理信息提示项
7. 重新验证直至检查通过
8. 输出结构化验证报告(必填 - 见下方格式)

Formatting Step (REQUIRED)

格式化步骤(必填)

When mbake reports formatting issues, you MUST either:
  1. Auto-apply formatting (preferred for minor issues):
    bash
    mbake format <Makefile>
  2. Explain why not applied (if formatting would break functionality):
    Formatting not applied because:
    - [specific reason, e.g., "heredoc syntax would be corrupted"]
    - Manual review recommended for: [specific lines]
Formatting Decision Guide:
mbake ReportAction
"Would reformat" with no specific issuesAuto-apply with
mbake format
Specific whitespace/indentation issuesAuto-apply with
mbake format
Issues in complex heredocs or multi-line stringsSkip formatting, explain in output
Issues in
# bake-format off
sections
Skip (intentionally disabled)
Validation Pass Criteria:
LevelRequirementAction
Errors (0 required)Syntax errors, missing tabs, invalid targetsMUST fix before completion
Warnings (fix if feasible)Formatting issues, missing optimizationsSHOULD fix; explain if skipped
Info (address for production)Enhancement suggestions, style preferencesSHOULD address for production Makefiles
Known mbake False Positives (can be safely ignored):
The mbake validator may report warnings for valid GNU Make special targets. These are false positives and can be ignored:
mbake WarningActual StatusExplanation
"Unknown special target '.DELETE_ON_ERROR'"✅ ValidCritical GNU Make target that deletes failed build artifacts
"Unknown special target '.SUFFIXES'"✅ ValidStandard GNU Make target for disabling/setting suffix rules
"Unknown special target '.ONESHELL'"✅ ValidGNU Make 3.82+ feature for single-shell recipe execution
"Unknown special target '.POSIX'"✅ ValidPOSIX compliance declaration
当mbake报告格式问题时,您必须执行以下操作之一:
  1. 自动应用格式化(小问题优先选择此方式):
    bash
    mbake format <Makefile>
  2. 说明未应用格式化的原因(若格式化会破坏功能):
    未应用格式化,原因:
    - [具体原因,例如:“here文档语法会被破坏”]
    - 建议手动检查以下内容:[具体行]
格式化决策指南:
mbake报告内容操作
“Would reformat”且无特定问题使用
mbake format
自动应用
特定空格/缩进问题使用
mbake format
自动应用
复杂here文档或多行字符串中的问题跳过格式化,在输出中说明
# bake-format off
部分中的问题
跳过(已故意禁用格式化)
验证通过标准:
级别要求操作
错误(必须为0)语法错误、缺少制表符、无效目标完成前必须修复
警告(可行则修复)格式问题、缺少优化建议修复;若跳过需说明原因
信息(生产项目需处理)增强建议、风格偏好生产级Makefile建议处理
已知mbake误报(可安全忽略):
mbake验证器可能会对有效的GNU Make特殊目标发出警告。这些属于误报,可忽略:
mbake警告内容实际状态说明
“Unknown special target '.DELETE_ON_ERROR'”✅ 有效关键GNU Make目标,用于删除构建失败的产物
“Unknown special target '.SUFFIXES'”✅ 有效用于禁用/设置后缀规则的标准GNU Make目标
“Unknown special target '.ONESHELL'”✅ 有效GNU Make 3.82+特性,用于单Shell执行配方
“Unknown special target '.POSIX'”✅ 有效POSIX合规性声明

Validation Report Output (REQUIRED)

验证报告输出(必填)

After validation completes, you MUST output a structured report in the following format. This is not optional.
Required Report Format:
undefined
验证完成后,必须按照以下格式输出结构化报告。此步骤为必填项。
报告必填格式:
undefined

Validation Report

验证报告

Result: [PASSED / PASSED with warnings / FAILED] Errors: [count] Warnings: [count] Info: [count]
结果: [通过 / 带警告通过 / 失败] 错误数: [数量] 警告数: [数量] 信息提示数: [数量]

Errors Fixed

已修复错误

  • [List each error and how it was fixed, or "None" if 0 errors]
  • [列出每个错误及修复方式,若无错误则填“无”]

Warnings Addressed

已处理警告

  • [List each warning that was fixed]
  • [列出每个已修复的警告]

Warnings Skipped (with reasons)

已跳过警告(含原因)

  • [List each warning that was NOT fixed and explain why]
  • Example: "mbake reports '.DELETE_ON_ERROR' as unknown - this is a valid GNU Make special target (false positive)"

Formatting Applied

是否已应用格式化

  • [Yes/No] - [If No, explain why formatting was skipped]
  • [是/否] - [若为否,说明跳过格式化的原因]

Info Items Addressed

已处理的信息提示项

  • [List info items that were addressed for production Makefiles]
  • [Or "N/A - simple project" if not applicable]
  • [列出为生产级Makefile处理的信息提示项]
  • [若不适用则填“不适用 - 简单项目”]

Remaining Issues (if any)

剩余问题(若有)

  • [List any issues requiring user attention]
  • [Or "None - Makefile is production-ready"]

**Example Complete Report:**
  • [列出需要用户注意的问题]
  • [若无则填“无 - Makefile已就绪可用于生产环境”]

**完整报告示例:**

Validation Report

验证报告

Result: PASSED with warnings Errors: 0 Warnings: 2 Info: 1
结果: 带警告通过 错误数: 0 警告数: 2 信息提示数: 1

Errors Fixed

已修复错误

  • None

Warnings Addressed

已处理警告

  • Fixed: Added error handling to install target (|| exit 1)
  • 修复:为install目标添加错误处理(|| exit 1)

Warnings Skipped (with reasons)

已跳过警告(含原因)

Formatting Applied

是否已应用格式化

  • Yes - Applied
    mbake format
    to fix whitespace issues
  • 是 - 使用
    mbake format
    修复空格问题

Info Items Addressed

已处理的信息提示项

  • Added .NOTPARALLEL for Docker targets (parallel safety)
  • Added error handling for docker-push target
  • 为Docker目标添加.NOTPARALLEL(并行安全)
  • 为docker-push目标添加错误处理

Remaining Issues

剩余问题

  • None - Makefile is production-ready

**Common Info Items to Address:**

| Info Item | When to Fix | How to Fix |
|-----------|-------------|------------|
| "mkdir without order-only prerequisites" | Large projects (>10 targets) | Use `target: prereqs \| $(BUILDDIR)` pattern |
| "recipe commands lack error handling" | Critical operations (install, deploy) | Add `set -e` in .SHELLFLAGS or use `&&` chaining |
| "consider using ccache" | Long compile times | Add `CC := ccache $(CC)` pattern |
| "parallel-sensitive commands detected" | Docker/npm/pip targets | Add `.NOTPARALLEL:` for affected targets or proper dependencies |

**Production-Quality Requirements (MUST address for Docker/deploy targets):**

When generating Makefiles with Docker or deployment targets, you MUST apply these production patterns:

1. **Error Handling for docker-push:**
   ```makefile
   ## Push Docker image to registry (with error handling)
   docker-push: docker-build
   	@echo "Pushing $(IMAGE)..."
   	docker push $(IMAGE) || { echo "Failed to push $(IMAGE)"; exit 1; }
   	docker push $(IMAGE_LATEST) || { echo "Failed to push $(IMAGE_LATEST)"; exit 1; }
  1. Parallel Safety for Docker targets:
    makefile
    # Prevent parallel execution of Docker targets (race conditions)
    .NOTPARALLEL: docker-build docker-push docker-run
    Or use proper dependencies to serialize:
    makefile
    docker-push: docker-build  # Ensures build completes before push
    docker-run: docker-build   # Ensures build completes before run
  2. Install target error handling:
    makefile
    install: $(TARGET)
    	install -d $(DESTDIR)$(PREFIX)/bin || exit 1
    	install -m 755 $(TARGET) $(DESTDIR)$(PREFIX)/bin/ || exit 1
Note: When validation shows info items about error handling or parallel safety, you MUST address them for any Makefile containing Docker, deploy, or install targets. Explain in your response which patterns were applied.
Validation Checklist:
  • Syntax correct (
    make -n
    passes)
  • All non-file targets have .PHONY
  • Tab indentation (not spaces)
  • No hardcoded credentials
  • User-overridable variables use
    ?=
  • .DELETE_ON_ERROR present
  • MAKEFLAGS optimizations included (Modern header)
  • Order-only prerequisites for build directories (large projects)
  • Error handling in critical recipes (install, deploy, docker-push)
  • 无 - Makefile已就绪可用于生产环境

**常见需处理的信息提示项:**

| 信息提示项 | 修复时机 | 修复方式 |
|-----------|-------------|------------|
| “mkdir without order-only prerequisites” | 大型项目(>10个目标) | 使用`target: prereqs \| $(BUILDDIR)`模式 |
| “recipe commands lack error handling” | 关键操作(install、deploy) | 在.SHELLFLAGS中添加`set -e`或使用`&&`链式调用 |
| “consider using ccache” | 编译时间长 | 添加`CC := ccache $(CC)`模式 |
| “parallel-sensitive commands detected” | Docker/npm/pip目标 | 为受影响的目标添加`.NOTPARALLEL:`或正确的依赖关系 |

**生产级质量要求(Docker/部署目标必须满足):**

当生成包含Docker或部署目标的Makefile时,必须应用以下生产级模式:

1. **docker-push的错误处理:**
   ```makefile
   ## Push Docker image to registry (with error handling)
   docker-push: docker-build
   	@echo "Pushing $(IMAGE)..."
   	docker push $(IMAGE) || { echo "Failed to push $(IMAGE)"; exit 1; }
  1. Docker目标的并行安全:
    makefile
    # Prevent parallel execution of Docker targets (race conditions)
    .NOTPARALLEL: docker-build docker-push docker-run
    或使用正确的依赖关系确保序列化执行:
    makefile
    docker-push: docker-build  # 确保构建完成后再推送
    docker-run: docker-build   # 确保构建完成后再运行
  2. install目标的错误处理:
    makefile
    install: $(TARGET)
    	install -d $(DESTDIR)$(PREFIX)/bin || exit 1
    	install -m 755 $(TARGET) $(DESTDIR)$(PREFIX)/bin/ || exit 1
注意: 若验证显示错误处理或并行安全相关的信息提示项,对于包含Docker、部署或install目标的Makefile,必须处理这些提示项。在响应中说明应用了哪些模式。
验证检查清单:
  • 语法正确(
    make -n
    执行通过)
  • 所有非文件目标均已声明.PHONY
  • 使用制表符缩进(而非空格)
  • 无硬编码凭证
  • 用户可覆盖的变量使用
    ?=
  • 包含.DELETE_ON_ERROR
  • 包含MAKEFLAGS优化(现代头部)
  • 大型项目中为构建目录使用仅顺序前置依赖
  • 关键配方(install、deploy、docker-push)包含错误处理

Best Practices

最佳实践

Variables

变量

  • ?=
    for user-overridable (CC, CFLAGS, PREFIX)
  • :=
    for project-specific (SOURCES, OBJECTS)
  • Use pkg-config:
    CFLAGS += $(shell pkg-config --cflags lib)
  • 用户可覆盖的变量使用
    ?=
    (如CC、CFLAGS、PREFIX)
  • 项目特定变量使用
    :=
    (如SOURCES、OBJECTS)
  • 使用pkg-config:
    CFLAGS += $(shell pkg-config --cflags lib)

Targets

目标

  • Always declare
    .PHONY
    for non-file targets
  • Default target should be
    all
  • Use
    .DELETE_ON_ERROR
    for safety
  • Document with
    ##
    comments for help target
  • 始终为非文件目标声明
    .PHONY
  • 默认目标应为
    all
  • 使用
    .DELETE_ON_ERROR
    以确保安全
  • 使用
    ##
    注释为help目标提供文档

Directory Creation

目录创建

Two approaches for creating build directories:
Simple (inline mkdir):
makefile
$(BUILDDIR)/%.o: $(SRCDIR)/%.c
	@mkdir -p $(@D)
	$(CC) $(CFLAGS) -c $< -o $@
Optimized (order-only prerequisites): Prevents unnecessary rebuilds when directory timestamps change.
makefile
$(BUILDDIR):
	@mkdir -p $@

$(BUILDDIR)/%.o: $(SRCDIR)/%.c | $(BUILDDIR)
	$(CC) $(CFLAGS) -c $< -o $@
Use order-only prerequisites (
|
) for large projects with many targets.
创建构建目录有两种方式:
简单方式(内联mkdir):
makefile
$(BUILDDIR)/%.o: $(SRCDIR)/%.c
	@mkdir -p $(@D)
	$(CC) $(CFLAGS) -c $< -o $@
优化方式(仅顺序前置依赖): 当目录时间戳变化时,避免不必要的重新构建。
makefile
$(BUILDDIR):
	@mkdir -p $@

$(BUILDDIR)/%.o: $(SRCDIR)/%.c | $(BUILDDIR)
	$(CC) $(CFLAGS) -c $< -o $@
对于包含多个目标的大型项目,使用仅顺序前置依赖(
|
)。

Recipes

配方

  • Use tabs, never spaces
  • Quote variables in shell:
    $(RM) "$(TARGET)"
  • Use
    @
    prefix for quiet commands
  • Test with
    make -n
    first
  • 使用制表符,绝不要使用空格
  • 在Shell中引用变量:
    $(RM) "$(TARGET)"
  • 使用
    @
    前缀实现静默命令
  • 先使用
    make -n
    测试

Helper Scripts (Optional)

辅助脚本(可选)

These scripts are optional convenience tools for quick template generation.
这些脚本是可选的便捷工具,用于快速生成模板。

When to Use Scripts vs Manual Generation

何时使用脚本 vs 手动生成

ScenarioRecommendation
Simple, standard project (single binary, no special features)✅ Use
generate_makefile_template.sh
for speed
Complex project (Docker, multi-binary, custom patterns)❌ Use manual generation for full control
Adding targets to existing Makefile✅ Use
add_standard_targets.sh
User has specific formatting/style requirements❌ Use manual generation
Rapid prototyping / proof-of-concept✅ Use scripts, customize later
Production-ready Makefile⚠️ Start with script, then customize manually
场景推荐方案
简单标准项目(单二进制文件,无特殊功能)✅ 使用
generate_makefile_template.sh
以提高速度
复杂项目(Docker、多二进制文件、自定义模式)❌ 使用手动生成以获得完全控制权
为现有Makefile添加目标✅ 使用
add_standard_targets.sh
用户有特定格式/风格要求❌ 使用手动生成
快速原型开发/概念验证✅ 使用脚本,后续按需自定义
生产级Makefile⚠️ 从脚本开始,然后手动自定义

generate_makefile_template.sh

generate_makefile_template.sh

Generates a complete Makefile template for a specific project type.
bash
bash scripts/generate_makefile_template.sh [TYPE] [NAME]

Types: c, c-lib, cpp, go, python, java, generic
Example:
bash
bash scripts/generate_makefile_template.sh go myservice
为特定项目类型生成完整的Makefile模板。
bash
bash scripts/generate_makefile_template.sh [TYPE] [NAME]

Types: c, c-lib, cpp, go, python, java, generic
示例:
bash
bash scripts/generate_makefile_template.sh go myservice

Creates Makefile with Go patterns, version embedding, standard targets

创建包含Go模式、版本嵌入、标准目标的Makefile

undefined
undefined

add_standard_targets.sh

add_standard_targets.sh

Adds missing standard GNU targets to an existing Makefile.
bash
bash scripts/add_standard_targets.sh [MAKEFILE] [TARGETS...]

Targets: all, install, uninstall, clean, distclean, test, check, help
Example:
bash
bash scripts/add_standard_targets.sh Makefile install uninstall help
为现有Makefile添加缺失的标准GNU目标。
bash
bash scripts/add_standard_targets.sh [MAKEFILE] [TARGETS...]

Targets: all, install, uninstall, clean, distclean, test, check, help
示例:
bash
bash scripts/add_standard_targets.sh Makefile install uninstall help

Adds install, uninstall, help targets if they don't exist

若install、uninstall、help目标不存在,则添加这些目标


**Note:** Manual generation following the Stage 3 patterns produces equivalent results but allows for more customization.

**注意:** 按照阶段3的模式手动生成可产生等效结果,但允许更多自定义。

Documentation

文档

Detailed guides in
docs/
:
  • makefile-structure.md - Organization, layout, includes
  • variables-guide.md - Assignment operators, automatic variables
  • targets-guide.md - Standard targets, .PHONY, prerequisites
  • patterns-guide.md - Pattern rules, dependencies
  • optimization-guide.md - Parallel builds, caching
  • security-guide.md - Safe expansion, credential handling
docs/
目录下的详细指南:
  • makefile-structure.md - 组织、布局、包含文件
  • variables-guide.md - 赋值运算符、自动变量
  • targets-guide.md - 标准目标、.PHONY、前置依赖
  • patterns-guide.md - 模式规则、依赖项
  • optimization-guide.md - 并行构建、缓存
  • security-guide.md - 安全展开、凭证处理

Resources

资源