其他
生成生产级 Makefile:项目需要构建自动化、标准…
为 C/C++、Python、Go、Java 或通用项目从零创建/补全 Makefile,并执行验证与格式化。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
生成生产级 Makefile:项目需要构通用
解决思路
- 收集项目需求:语言(C/C++/Python/Go/Java)、结构(单目录/多目录)。
- 收集构建需求:源文件、输出产物、依赖、构建顺序。
- 收集安装需求:PREFIX 位置、目录(bin/lib/share)、要安装的文件。
- 收集目标需求:all、install、clean、test、dist、help 中需要哪些。
- 收集配置需求:编译器、编译选项、pkg-config 依赖、交叉编译。
- 信息缺失或含糊时使用 AskUserQuestion:未指定语言时问语言;项目结构不清时问单/多目录;请求 Docker 但 registry 未知时问 registry(docker.io/ghcr.io/custom);可能有多个二进制时问单/多可执行文件;需要 install 但路径不清时问安装位置(默认 /usr/local/bin);提到交叉编译时问目标平台/架构。
- 在用户已提供全部信息、标准项目类型有默认值(如 Go+Docker 用标准模式)、用户说“用默认值”/“标准设置”时跳过 AskUserQuestion。
- 不询问时采用默认假设:单目录项目、PREFIX=/usr/local、标准目标 all/build/test/clean/install/help、无交叉编译。
- 在必须查文档时查文档:集成不熟悉的工具/框架/构建系统;内部示例未覆盖的复杂模式(Bazel、Meson、自定义工具链);Docker/容器集成(Dockerfile、多阶段、registry push);CI/CD 平台集成(GitHub Actions、GitLab CI、Jenkins);嵌入式或不常见目标交叉编译;包管理器集成(Conan、vcpkg、Homebrew formulas);多二进制或多库项目;通过 ldflags 或构建期变量嵌入版本。
- 在可跳过外部查文档时跳过:标准语言模式(C/C++、Go、Python、Java)已在 Stage 3 覆盖;简单单二进制且无外部依赖;用户提供完整需求且无歧义;内部文档已全面覆盖所需模式。
- 查文档时始终先用显式打开文件命令查内部文档:优先使用完整路径访问。结构指南 `devops-skills-plugin/skills/makefile-generator/docs/makefile-structure.md`;变量指南 `.../variables-guide.md`;目标指南 `.../targets-guide.md`;模式指南 `.../patterns-guide.md`;优化指南 `.../optimization-guide.md`;安全指南 `.../security-guide.md`。
- 按需求读对应文档:Docker/容器目标读 `patterns-guide.md` 的 Pattern 8;多二进制项目读 Pattern 7;Go 版本嵌入读 Pattern 5;并行构建、缓存、ccache 读 `optimization-guide.md`;凭证、密钥、API key 读 `security-guide.md`;复杂依赖、模式规则读 `patterns-guide.md`;order-only prerequisites 读 `optimization-guide.md` 或 `targets-guide.md`;变量和赋值运算符读 `variables-guide.md`。
- 使用确定性打开/读取命令:仓库根目录执行 `sed -n '1,220p' devops-skills-plugin/skills/makefile-generator/docs/patterns-guide.md`;`rg -n 'Pattern 5|Pattern 8' devops-skills-plugin/skills/makefile-generator/docs/patterns-guide.md`;技能目录执行 `sed -n '1,220p' docs/security-guide.md`。如果 shell 不可用,用环境的文件打开/读取能力访问相同路径。
- 对 Docker + Go 版本嵌入按必需工作流示例执行:先读 Go pattern(`rg -n 'Pattern 5' ...`),再读 Docker pattern(`rg -n 'Pattern 8' ...`),再读安全指南(`sed -n '1,220p' docs/security-guide.md`);然后生成 Makefile,并在头部注释列出已查阅文档。
- 内部文档未覆盖具体工具时尝试 context7:`mcp__context7__resolve-library-id: '<tool-name>'`;`mcp__context7__query-docs: query='<integration-topic>'`。示例查询:Docker 用 `query='dockerfile best practices'`;Go 用 `query='go build ldflags'`;具体工具用 `query='<tool> makefile integration'`。context7 不可用或无有用结果时记录并继续。
- 内部文档和 context7 都找不到模式时回退到 WebSearch:查询 `'<specific-feature>' makefile best practices 2025`,例如 `'docker makefile best practices 2025'`、`'go ldflags version makefile 2025'`。触发条件:内部文档不覆盖该集成且 context7 无相关结果。
- 在响应中记录查阅过的内部文档,并在生成的 Makefile 头部注释中注明。
- 标准布局可用可选 helper-script 快速路径:`bash scripts/generate_makefile_template.sh go myservice Makefile` 生成模板;`bash scripts/add_standard_targets.sh Makefile install clean help` 仅添加选中的标准目标。
- 复杂需求(Docker 发布流程、多二进制矩阵、自定义工具链)时改用手工编写。
- 头部选择一种风格:传统 POSIX 兼容用 `.DELETE_ON_ERROR:` 和 `.SUFFIXES:`;现代 GNU Make 4.0+ 推荐用 `SHELL := bash`、`.ONESHELL:`、`.SHELLFLAGS := -eu -o pipefail -c`、`.DELETE_ON_ERROR:`、`.SUFFIXES:`、`MAKEFLAGS += --warn-undefined-variables`、`MAKEFLAGS += --no-builtin-rules`。
- 标准变量:用户可覆盖的用 `?=`,如 `CC ?= gcc`、`CFLAGS ?= -Wall -Wextra -O2`、`PREFIX ?= /usr/local`、`DESTDIR ?=`。
- GNU 安装目录:`BINDIR ?= $(PREFIX)/bin`、`LIBDIR ?= $(PREFIX)/lib`、`INCLUDEDIR ?= $(PREFIX)/include`。
- 项目专用变量用 `:=`,如 `PROJECT := myproject`、`VERSION := 1.0.0`、`SRCDIR := src`、`BUILDDIR := build`、`SOURCES := $(wildcard $(SRCDIR)/*.c)`、`OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(BUILDDIR)/%.o)`。
- C/C++ 构建规则:目标链接用 `$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@`;模式编译用 `@mkdir -p $(@D)` 和 `$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@`;包含依赖用 `-include $(OBJECTS:.o=.d)`。
- Go 构建规则:目标依赖 `$(shell find . -name '*.go') go.mod`;构建用 `go build -o $@ ./cmd/$(PROJECT)`。
- Python 构建规则:`build` 用 `python -m build`;`develop` 用 `pip install -e .[dev]`。
- Java 构建规则:模式规则 `$(BUILDDIR)/%.class: $(SRCDIR)/%.java`,先 `@mkdir -p $(@D)`,再 `javac -d $(BUILDDIR) -sourcepath $(SRCDIR) $<`。
- 标准目标:声明 `.PHONY: all clean install uninstall test help`。
- `all: $(TARGET)` 构建所有目标。
- `install: all` 后用 `install -d $(DESTDIR)$(BINDIR)` 创建目录,再用 `install -m 755 $(TARGET) $(DESTDIR)$(BINDIR)/` 安装。
- `clean` 用 `$(RM) -r $(BUILDDIR) $(TARGET)` 删除构建产物。
- `test` 添加测试命令。
- `help` 输出 `$(PROJECT) v$(VERSION)`、目标列表、覆盖变量示例 `make CC=clang PREFIX=/opt`。
- 每个生成的 Makefile 都必须验证。
- 验证工具预检:首选运行 `devops-skills:makefile-validator`。
- validator 技能不可用时运行本地回退检查:`make -f <Makefile> -n --dry-run`;结构检查 `rg -n '^ {1,}\S' <Makefile>` 找可疑空格缩进 recipe 行;`rg -n '^\.PHONY:' <Makefile>`。
- `make` 不可用时只运行结构检查,报告“因缺少 make 二进制为部分验证”,并在声称生产可用前请求用户确认。
- 必需验证循环:1 按前述阶段生成 Makefile;2 运行 validator 技能(或回退检查);3 修复所有错误(完成前必须 0 error);4 应用格式化修复;5 可行时修复 warning(跳过则解释);6 对大型/生产项目处理 info 项;7 重复运行直到检查通过;8 输出结构化验证报告(必需)。
- 格式化步骤必需:mbake 报告问题时,要么自动应用 `mbake format <Makefile>`(轻微问题优先),要么解释为何不应用(会破坏功能时),例如 heredoc 语法会被破坏、需人工检查特定行。
- mbake 未安装或不可执行时跳过格式化执行并记录:`Formatting skipped: mbake unavailable in current environment.`。
- 格式化决策指南:mbake 报 “Would reformat” 且无具体问题 -> 自动应用 `mbake format`;具体空白/缩进问题 -> 自动应用 `mbake format`;复杂 heredoc 或多行字符串问题 -> 跳过格式化并在输出解释;`# bake-format off` 区块问题 -> 跳过(有意禁用);`mbake` 命令不可用 -> 跳过并记录工具不可用原因。
- 验证通过标准:Errors(必须 0)包括语法错误、缺少 tab、无效目标,必须在完成前修复;Warnings(可行则修)包括格式化问题、缺少优化,应修复,跳过则解释;Info(生产环境处理)包括增强建议、风格偏好,生产 Makefile 应处理。
- mbake 已知误报可安全忽略:`.DELETE_ON_ERROR`、`.SUFFIXES`、`.ONESHELL`、`.POSIX` 被报 “Unknown special target” 时实际上是有效 GNU Make 特殊目标。
- 验证完成后必须输出结构化报告,格式包含:Result(PASSED / PASSED with warnings / FAILED)、Errors、Warnings、Info;Errors Fixed;Warnings Addressed;Warnings Skipped(with reasons);Formatting Applied;Info Items Addressed;Remaining Issues。
- 常见 info 项处理:mkdir 无 order-only prerequisites -> 大型项目(>10 目标)用 `target: prereqs | $(BUILDDIR)`;recipe 命令缺错误处理 -> 关键操作(install、deploy)在 `.SHELLFLAGS` 加 `set -e` 或用 `&&` 链;建议 ccache -> 编译时间长时加 `CC := ccache $(CC)`;检测到并行敏感命令 -> Docker/npm/pip 目标加 `.NOTPARALLEL:` 或正确依赖。
- Docker/deploy 目标的生产质量要求必须处理:docker-push 错误处理用 `docker push $(IMAGE) || { echo "Failed to push $(IMAGE)"; exit 1; }` 和 `docker push $(IMAGE_LATEST) || { echo "Failed to push $(IMAGE_LATEST)"; exit 1; }`。
- Docker 目标并行安全:用 `.NOTPARALLEL: docker-build docker-push docker-run`,或用正确依赖串行化,如 `docker-push: docker-build`、`docker-run: docker-build`。
- install 目标错误处理:`install -d $(DESTDIR)$(PREFIX)/bin || exit 1`;`install -m 755 $(TARGET) $(DESTDIR)$(PREFIX)/bin/ || exit 1`。
- 当验证显示 error handling 或 parallel safety 的 info 项时,对任何含 Docker、deploy、install 目标的 Makefile 必须处理,并在响应中解释应用了哪些模式。
- 验证清单:`make -n` 语法正确;所有非文件目标有 `.PHONY`;使用 tab 缩进而非空格;无硬编码凭证;用户可覆盖变量用 `?=`;存在 `.DELETE_ON_ERROR`;包含 MAKEFLAGS 优化(现代头部);大型项目为构建目录使用 order-only prerequisites;关键 recipe(install、deploy、docker-push)有错误处理。
- 变量最佳实践:`?=` 用于用户可覆盖(CC、CFLAGS、PREFIX);`:=` 用于项目专用(SOURCES、OBJECTS);用 pkg-config:`CFLAGS += $(shell pkg-config --cflags lib)`。
- 目标最佳实践:始终为非文件目标声明 `.PHONY`;默认目标应为 `all`;使用 `.DELETE_ON_ERROR` 保证安全;用 `##` 注释记录 help 目标。
- 目录创建两种方式:简单内联 `@mkdir -p $(@D)`;优化版用 order-only prerequisites:`$(BUILDDIR):` 下 `@mkdir -p $@`,模式规则 `$(BUILDDIR)/%.o: $(SRCDIR)/%.c | $(BUILDDIR)`。大型多目标项目用 `|`。
- recipe 最佳实践:用 tab、绝不用空格;shell 中给变量加引号如 `$(RM) "$(TARGET)"`;安静命令加 `@`;先用 `make -n` 测试。
- helper 脚本是可选便利工具。选择:简单标准项目(单二进制、无特殊功能)用 `generate_makefile_template.sh` 提速;复杂项目(Docker、多二进制、自定义模式)用手工生成以完全控制;向已有 Makefile 添加目标用 `add_standard_targets.sh`;用户有特定格式/风格要求时手工生成;快速原型可用脚本后再定制;生产 Makefile 可从脚本开始再手工定制。
- `generate_makefile_template.sh` 用法:`bash scripts/generate_makefile_template.sh [TYPE] [NAME] [OUTPUT_FILE]`;类型 `c, c-lib, cpp, go, python, java, generic`。示例:`bash scripts/generate_makefile_template.sh go myservice` 生成 Go 模式、版本嵌入、标准目标;`bash scripts/generate_makefile_template.sh go myservice build/Makefile` 写入 build/Makefile。
- `add_standard_targets.sh` 用法:`bash scripts/add_standard_targets.sh [MAKEFILE] [TARGETS...]` 或 `bash scripts/add_standard_targets.sh [TARGETS...]`(使用 ./Makefile);目标 `all, install, uninstall, clean, distclean, test, check, help, dist`。示例:`bash scripts/add_standard_targets.sh Makefile install uninstall help` 添加缺失目标;`bash scripts/add_standard_targets.sh clean test` 显式目标模式修改 ./Makefile;`bash scripts/add_standard_targets.sh -n Makefile dist` dry-run 显示计划变更不编辑文件。
- 手工按 Stage 3 模式生成等效,但允许更多定制。
- 修改 helper 脚本或模板后运行回归冒烟测试:`bash test/test_helper_scripts.sh`。
- 完成标准:触发匹配且缺失需求已澄清(或已应用文档化默认值);生成前已用显式文件路径打开相关内部文档;生成的 Makefile 对所有非文件目标有完整 `.PHONY` 覆盖;Go 模板包含可选 `go.sum` 处理和可配置 `GO_MAIN` 入口;验证已用 `makefile-validator`(首选)或记录的回退检查运行;格式化已用 `mbake` 应用,或带明确工具不可用/兼容性原因跳过;最终响应包含必需的结构化验证报告。
- 详细指南参考:`makefile-structure.md`(组织、布局、include)、`variables-guide.md`(赋值运算符、自动变量)、`targets-guide.md`(标准目标、.PHONY、prerequisites)、`patterns-guide.md`(模式规则、依赖)、`optimization-guide.md`(并行构建、缓存)、`security-guide.md`(安全展开、凭证处理)。
- 外部资源参考:GNU Make Manual、GNU Coding Standards、Makefile Conventions。
适用边界 · 注意事项
- 不要用于验证已有 Makefile(应使用 devops-skills:makefile-validator)。
- 不要用于调试 Makefile(应使用 make -d)。
- 不要用于执行构建。