makefile-generator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMakefile 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 ), or running builds.
make -d- 从零开始创建新的Makefile
- 为项目(C/C++、Python、Go、Java)搭建构建系统
- 实现构建自动化与CI/CD集成
- 将手动构建流程转换为Makefile
- 用户要求“创建”“生成”或“编写”Makefile时
请勿用于: 验证现有Makefile(请使用devops-skills:makefile-validator)、调试(请使用)或运行构建。
make -dGeneration Workflow
生成流程
Stage 1: Gather Requirements
阶段1:收集需求
Collect information for the following categories. Use AskUserQuestion when information is missing or ambiguous:
| Category | Information Needed |
|---|---|
| Project | Language (C/C++/Python/Go/Java), structure (single/multi-directory) |
| Build | Source files, output artifacts, dependencies, build order |
| Install | PREFIX location, directories (bin/lib/share), files to install |
| Targets | all, install, clean, test, dist, help (which are needed?) |
| Config | Compiler, flags, pkg-config dependencies, cross-compilation |
When to Use AskUserQuestion (MUST ask if any apply):
| Condition | Example 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):
-
ALWAYS consult internal docs/ FIRST using the Read tool (primary source of truth):
Requirement Read This Doc Docker/container targets (Pattern 8: Docker Integration)docs/patterns-guide.mdMulti-binary projects (Pattern 7: Multi-Binary Project)docs/patterns-guide.mdGo projects with version embedding (Pattern 5: Go Project)docs/patterns-guide.mdParallel builds, caching, ccache docs/optimization-guide.mdCredentials, secrets, API keys docs/security-guide.mdComplex dependencies, pattern rules docs/patterns-guide.mdOrder-only prerequisites ordocs/optimization-guide.mddocs/targets-guide.mdVariables, assignment operators docs/variables-guide.mdCRITICAL: 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 headerImportant: Internal docs contain vetted, production-ready patterns. Always read the relevant docs before external lookups. -
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. -
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)
- 无外部依赖的简单单二进制文件项目
- 用户提供完整需求,无歧义
- 内部文档已全面涵盖所需模式
查阅流程(按顺序执行):
-
始终优先使用Read工具查阅内部文档(主要可信来源):
需求 查阅文档 Docker/容器目标 (模式8:Docker集成)docs/patterns-guide.md多二进制文件项目 (模式7:多二进制文件项目)docs/patterns-guide.md带版本嵌入的Go项目 (模式5:Go项目)docs/patterns-guide.md并行构建、缓存、ccache docs/optimization-guide.md凭证、密钥、API密钥 docs/security-guide.md复杂依赖、模式规则 docs/patterns-guide.md仅顺序前置依赖 或docs/optimization-guide.mddocs/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头部注明查阅过的文档重要提示: 内部文档包含经过验证、可用于生产环境的模式。在进行外部查阅前,务必先阅读相关内部文档。 -
若内部文档未覆盖特定工具,尝试使用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相关的特定文档。若内部文档已提供足够模式,可跳过此步骤。 -
仅当内部文档和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-rulesStandard Variables
标准变量
makefile
undefinedmakefile
undefinedUser-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)
undefinedPROJECT := myproject
VERSION := 1.0.0
SRCDIR := src
BUILDDIR := build
SOURCES := $(wildcard $(SRCDIR)/*.c)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(BUILDDIR)/%.o)
undefinedLanguage-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 helpmakefile
.PHONY: all clean install uninstall test helpBuild 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"
undefinedhelp:
@echo "$(PROJECT) v$(VERSION)"
@echo "Targets: all, install, clean, test, help"
@echo "Override: make CC=clang PREFIX=/opt"
undefinedStage 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:
-
Auto-apply formatting (preferred for minor issues):bash
mbake format <Makefile> -
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 Report | Action |
|---|---|
| "Would reformat" with no specific issues | Auto-apply with |
| Specific whitespace/indentation issues | Auto-apply with |
| Issues in complex heredocs or multi-line strings | Skip formatting, explain in output |
Issues in | Skip (intentionally disabled) |
Validation Pass Criteria:
| Level | Requirement | Action |
|---|---|---|
| Errors (0 required) | Syntax errors, missing tabs, invalid targets | MUST fix before completion |
| Warnings (fix if feasible) | Formatting issues, missing optimizations | SHOULD fix; explain if skipped |
| Info (address for production) | Enhancement suggestions, style preferences | SHOULD 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 Warning | Actual Status | Explanation |
|---|---|---|
| "Unknown special target '.DELETE_ON_ERROR'" | ✅ Valid | Critical GNU Make target that deletes failed build artifacts |
| "Unknown special target '.SUFFIXES'" | ✅ Valid | Standard GNU Make target for disabling/setting suffix rules |
| "Unknown special target '.ONESHELL'" | ✅ Valid | GNU Make 3.82+ feature for single-shell recipe execution |
| "Unknown special target '.POSIX'" | ✅ Valid | POSIX compliance declaration |
当mbake报告格式问题时,您必须执行以下操作之一:
-
自动应用格式化(小问题优先选择此方式):bash
mbake format <Makefile> -
说明未应用格式化的原因(若格式化会破坏功能):
未应用格式化,原因: - [具体原因,例如:“here文档语法会被破坏”] - 建议手动检查以下内容:[具体行]
格式化决策指南:
| mbake报告内容 | 操作 |
|---|---|
| “Would reformat”且无特定问题 | 使用 |
| 特定空格/缩进问题 | 使用 |
| 复杂here文档或多行字符串中的问题 | 跳过格式化,在输出中说明 |
| 跳过(已故意禁用格式化) |
验证通过标准:
| 级别 | 要求 | 操作 |
|---|---|---|
| 错误(必须为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验证完成后,必须按照以下格式输出结构化报告。此步骤为必填项。
报告必填格式:
undefinedValidation 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)"
- [列出每个未修复的警告并说明原因]
- 示例:"mbake报告'.DELETE_ON_ERROR'为未知目标 - 这是有效的GNU Make 特殊目标,用于确保构建失败时不会留下损坏文件。 参考:https://www.gnu.org/software/make/manual/html_node/Special-Targets.html"
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)
已跳过警告(含原因)
- mbake reports ".DELETE_ON_ERROR" as unknown - this is a valid and critical GNU Make special target that ensures failed builds don't leave corrupt files. See: https://www.gnu.org/software/make/manual/html_node/Special-Targets.html
- mbake报告“.DELETE_ON_ERROR”为未知目标 - 这是有效且关键的 GNU Make特殊目标,用于确保构建失败时不会留下损坏文件。 参考:https://www.gnu.org/software/make/manual/html_node/Special-Targets.html
Formatting Applied
是否已应用格式化
- Yes - Applied to fix whitespace issues
mbake format
- 是 - 使用修复空格问题
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; }-
Parallel Safety for Docker targets:makefile
# Prevent parallel execution of Docker targets (race conditions) .NOTPARALLEL: docker-build docker-push docker-runOr use proper dependencies to serialize:makefiledocker-push: docker-build # Ensures build completes before push docker-run: docker-build # Ensures build completes before run -
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 (passes)
make -n - 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; }-
Docker目标的并行安全:makefile
# Prevent parallel execution of Docker targets (race conditions) .NOTPARALLEL: docker-build docker-push docker-run或使用正确的依赖关系确保序列化执行:makefiledocker-push: docker-build # 确保构建完成后再推送 docker-run: docker-build # 确保构建完成后再运行 -
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 for non-file targets
.PHONY - Default target should be
all - Use for safety
.DELETE_ON_ERROR - 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 first
make -n
- 使用制表符,绝不要使用空格
- 在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 手动生成
| Scenario | Recommendation |
|---|---|
| Simple, standard project (single binary, no special features) | ✅ Use |
| Complex project (Docker, multi-binary, custom patterns) | ❌ Use manual generation for full control |
| Adding targets to existing Makefile | ✅ Use |
| 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 |
| 场景 | 推荐方案 |
|---|---|
| 简单标准项目(单二进制文件,无特殊功能) | ✅ 使用 |
| 复杂项目(Docker、多二进制文件、自定义模式) | ❌ 使用手动生成以获得完全控制权 |
| 为现有Makefile添加目标 | ✅ 使用 |
| 用户有特定格式/风格要求 | ❌ 使用手动生成 |
| 快速原型开发/概念验证 | ✅ 使用脚本,后续按需自定义 |
| 生产级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, genericExample:
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 myserviceCreates Makefile with Go patterns, version embedding, standard targets
创建包含Go模式、版本嵌入、标准目标的Makefile
undefinedundefinedadd_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, helpExample:
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 helpAdds 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 - 安全展开、凭证处理