@hybridlabor-api/aos 4.8.0 → 4.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/.agents/{agents.md → AGENTS.md} +3 -1
  2. package/.agents/nodes.json +3 -1
  3. package/.agents/vendor-manifest.json +23 -1
  4. package/.claude/agents/godmode-media-eventtech.md +1 -1
  5. package/.claude/hooks/conventional-commits.mjs +125 -0
  6. package/.claude/hooks/env-file-protection.mjs +105 -0
  7. package/.claude/hooks/go-gate.mjs +101 -81
  8. package/.claude/hooks/memb-inject.mjs +29 -1
  9. package/.claude/settings.json +13 -0
  10. package/.claude/workflows/startcycle-dispatch.mjs +23 -1
  11. package/.opencode/agents/godmode-media-eventtech.md +1 -1
  12. package/.opencode/plugins/bdb-aos.js +31 -4
  13. package/CLAUDE.md +0 -571
  14. package/README.de.md +1 -1
  15. package/README.md +1 -1
  16. package/README.pt.md +1 -1
  17. package/THIRD_PARTY_NOTICES.md +126 -0
  18. package/bin/aos-doctor.mjs +1 -1
  19. package/docs/skills_table.md +1 -1
  20. package/installer.js +187 -55
  21. package/package.json +7 -3
  22. package/packages/aos-cli/README.md +80 -0
  23. package/packages/aos-cli/bin/aos-cli.mjs +134 -0
  24. package/packages/aos-cli/core-skills.json +12 -0
  25. package/packages/aos-cli/extensions/aos.ts +321 -0
  26. package/packages/aos-cli/package-lock.json +1923 -0
  27. package/packages/aos-cli/package.json +29 -0
  28. package/packages/aos-cli/scripts/check-theme.mjs +63 -0
  29. package/packages/aos-cli/themes/aos.json +97 -0
  30. package/scripts/build-plugin-manifest.mjs +131 -0
  31. package/scripts/validate-skills.mjs +81 -6
  32. package/skills/basic/ao-orchestrator/SKILL.md +116 -0
  33. package/skills/basic/bdb-eventagency-skill/SKILL.md +252 -0
  34. package/skills/basic/bdb-shipping-skill/SKILL.md +161 -0
  35. package/skills/basic/godmode-eventtech/SKILL.md +4 -1
  36. package/skills/global_config/agenttrail/SKILL.md +6 -1
  37. package/skills/global_config/aos-project-init/SKILL.md +2 -0
  38. package/skills/global_config/aos-project-init/assets/AGENTS.template.md +1 -1
  39. package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +1 -1
  40. package/skills/global_config/aos-setup/SKILL.md +1 -1
  41. package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +1 -1
  42. package/skills/global_config/ask-tim/SKILL.md +7 -7
  43. package/skills/global_config/bash-script-generator/SKILL.md +201 -0
  44. package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
  45. package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
  46. package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
  47. package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
  48. package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
  49. package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
  50. package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
  51. package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
  52. package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
  53. package/skills/global_config/bash-script-validator/SKILL.md +249 -0
  54. package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
  55. package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
  56. package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
  57. package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
  58. package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
  59. package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
  60. package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
  61. package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
  62. package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
  63. package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
  64. package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
  65. package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
  66. package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
  67. package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
  68. package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
  69. package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
  70. package/skills/global_config/ci-pipeline/SKILL.md +135 -0
  71. package/skills/global_config/deja-memory/SKILL.md +3 -1
  72. package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
  73. package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
  74. package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
  75. package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
  76. package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
  77. package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
  78. package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
  79. package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
  80. package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
  81. package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
  82. package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
  83. package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
  84. package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
  85. package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
  86. package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
  87. package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
  88. package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
  89. package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
  90. package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
  91. package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
  92. package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
  93. package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
  94. package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
  95. package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
  96. package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
  97. package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
  98. package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
  99. package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
  100. package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
  101. package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
  102. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
  103. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
  104. package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
  105. package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
  106. package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
  107. package/skills/global_config/github-actions-generator/SKILL.md +353 -0
  108. package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
  109. package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
  110. package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
  111. package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
  112. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
  113. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
  114. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
  115. package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
  116. package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
  117. package/skills/global_config/github-actions-generator/examples/README.md +147 -0
  118. package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
  119. package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
  120. package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
  121. package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
  122. package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
  123. package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
  124. package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
  125. package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
  126. package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
  127. package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
  128. package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
  129. package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
  130. package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
  131. package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
  132. package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
  133. package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
  134. package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
  135. package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
  136. package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
  137. package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
  138. package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
  139. package/skills/global_config/github-actions-templates/SKILL.md +7 -0
  140. package/skills/global_config/github-actions-validator/SKILL.md +576 -0
  141. package/skills/global_config/github-actions-validator/examples/README.md +88 -0
  142. package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
  143. package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
  144. package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
  145. package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
  146. package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
  147. package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
  148. package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
  149. package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
  150. package/skills/global_config/github-actions-validator/references/runners.md +317 -0
  151. package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
  152. package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
  153. package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
  154. package/skills/global_config/makefile-generator/SKILL.md +614 -0
  155. package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
  156. package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
  157. package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
  158. package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
  159. package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
  160. package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
  161. package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
  162. package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
  163. package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
  164. package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
  165. package/skills/global_config/makefile-validator/SKILL.md +244 -0
  166. package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
  167. package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
  168. package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
  169. package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
  170. package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
  171. package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
  172. package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
  173. package/skills/global_config/{MCP_Manage → mcp-manage}/SKILL.md +3 -3
  174. package/skills/global_config/plan-canvas/SKILL.md +9 -2
  175. package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/ui.js +10 -2
  176. package/skills/global_config/plan-canvas/scripts/plan-canvas.js +1 -1
  177. package/skills/global_config/read-the-damn-docs/SKILL.md +175 -0
  178. package/skills/global_config/requesting-code-review/SKILL.md +98 -0
  179. package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
  180. package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
  181. package/skills/global_config/verification-before-completion/SKILL.md +123 -0
  182. package/skills/global_config/writing-plans/SKILL.md +126 -46
  183. package/skills/global_config/writing-plans-legacy/SKILL.md +152 -0
  184. package/.claude/CLAUDE.md +0 -12
  185. package/mcps/RhinoMCP/docs/content/docs/getting-started/gemini.md +0 -61
  186. /package/{GEMINI.md → RULES.md} +0 -0
@@ -0,0 +1,858 @@
1
+ # Makefile Best Practices
2
+
3
+ Comprehensive guide to writing professional, maintainable, and efficient Makefiles.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Essential Special Targets](#essential-special-targets)
8
+ 2. [File Organization](#file-organization)
9
+ 3. [Target Declarations](#target-declarations)
10
+ 4. [Variable Management](#variable-management)
11
+ 5. [Recipe Best Practices](#recipe-best-practices)
12
+ 6. [Dependency Management](#dependency-management)
13
+ 7. [Performance Optimization](#performance-optimization)
14
+ 8. [Portability](#portability)
15
+ 9. [Documentation](#documentation)
16
+ 10. [Security](#security)
17
+ 11. [Advanced Patterns](#advanced-patterns)
18
+
19
+ ## Modern Makefile Header (Recommended)
20
+
21
+ For modern, robust Makefiles, start with this recommended preamble from [Jacob Davis-Hansson](https://tech.davis-hansson.com/p/make/):
22
+
23
+ ```makefile
24
+ # Modern Makefile Header
25
+ SHELL := bash
26
+ .ONESHELL:
27
+ .SHELLFLAGS := -eu -o pipefail -c
28
+ .DELETE_ON_ERROR:
29
+ MAKEFLAGS += --warn-undefined-variables
30
+ MAKEFLAGS += --no-builtin-rules
31
+ ```
32
+
33
+ **Explanation:**
34
+
35
+ | Setting | Purpose |
36
+ |---------|---------|
37
+ | `SHELL := bash` | Use bash instead of /bin/sh for modern shell features |
38
+ | `.ONESHELL:` | Run entire recipe in single shell (enables multi-line scripts) |
39
+ | `.SHELLFLAGS := -eu -o pipefail -c` | Stop on errors (-e), undefined vars (-u), pipe failures |
40
+ | `.DELETE_ON_ERROR:` | Delete target on recipe failure (prevents corrupt builds) |
41
+ | `--warn-undefined-variables` | Alert on undefined Make variable references |
42
+ | `--no-builtin-rules` | Disable built-in implicit rules for faster builds |
43
+
44
+ **Note:** This preamble is for GNU Make 4.0+. For maximum portability, use a simpler header.
45
+
46
+ ## Essential Special Targets
47
+
48
+ GNU Make provides several special targets that should be used in professional Makefiles.
49
+
50
+ ### .DELETE_ON_ERROR (Critical)
51
+
52
+ **Always include `.DELETE_ON_ERROR:`** at the top of your Makefile. This ensures partially built targets are deleted when a recipe fails, preventing corrupt builds.
53
+
54
+ ```makefile
55
+ # CRITICAL: Delete target on recipe failure
56
+ .DELETE_ON_ERROR:
57
+
58
+ # Rest of Makefile follows...
59
+ ```
60
+
61
+ **Why it matters:**
62
+ - Without this, a failed build leaves a partial/corrupt file
63
+ - Next `make` run sees the file exists and skips rebuilding
64
+ - Results in broken builds that are hard to debug
65
+
66
+ **From GNU Make Manual:** *"This is almost always what you want make to do, but it is not historical practice; so for compatibility, you must explicitly request it."*
67
+
68
+ **Exception:** Use `.PRECIOUS` to protect specific targets that should be preserved even on error:
69
+
70
+ ```makefile
71
+ .DELETE_ON_ERROR:
72
+ .PRECIOUS: expensive-to-rebuild.dat
73
+ ```
74
+
75
+ ### .PHONY (Always Required)
76
+
77
+ Declare non-file targets as phony to avoid conflicts and improve performance:
78
+
79
+ ```makefile
80
+ .PHONY: all build clean test install
81
+ ```
82
+
83
+ ### .ONESHELL (For Multi-line Recipes)
84
+
85
+ Run entire recipe in a single shell invocation:
86
+
87
+ ```makefile
88
+ .ONESHELL:
89
+
90
+ deploy:
91
+ set -e
92
+ echo "Deploying..."
93
+ cd /app
94
+ git pull
95
+ ./restart.sh
96
+ ```
97
+
98
+ **Without `.ONESHELL`**, each line runs in a separate shell, so `cd` has no effect on subsequent lines.
99
+
100
+ ### .SUFFIXES (For Performance)
101
+
102
+ Clear built-in suffix rules to speed up builds:
103
+
104
+ ```makefile
105
+ # Disable all built-in suffix rules
106
+ .SUFFIXES:
107
+
108
+ # Only keep rules you need (optional)
109
+ .SUFFIXES: .c .o
110
+ ```
111
+
112
+ **Why:** GNU Make has ~90 built-in implicit rules. Clearing them speeds up rule resolution.
113
+
114
+ ### Complete Special Targets Header
115
+
116
+ ```makefile
117
+ # Modern Makefile Header
118
+ .DELETE_ON_ERROR:
119
+ .SUFFIXES:
120
+
121
+ .PHONY: all build clean test install deploy
122
+
123
+ # Your targets follow...
124
+ ```
125
+
126
+ ## File Organization
127
+
128
+ ### Directory Structure
129
+
130
+ ```makefile
131
+ # Organized Makefile structure
132
+ .PHONY: all clean test install
133
+
134
+ # Variables section
135
+ PROJECT := myapp
136
+ VERSION := 1.0.0
137
+ BUILD_DIR := build
138
+ SRC_DIR := src
139
+
140
+ # Include external makefiles
141
+ include config.mk
142
+ include rules/*.mk
143
+
144
+ # Default target (should be first)
145
+ all: build test
146
+
147
+ # Build targets
148
+ build: $(BUILD_DIR)/$(PROJECT)
149
+
150
+ # ... more targets
151
+ ```
152
+
153
+ ### Modular Organization
154
+
155
+ Use `include` for large projects:
156
+
157
+ ```makefile
158
+ # Main Makefile
159
+ include config/variables.mk
160
+ include rules/build.mk
161
+ include rules/test.mk
162
+ include rules/deploy.mk
163
+
164
+ .PHONY: all
165
+ all: build test
166
+ ```
167
+
168
+ ### Namespace Targets
169
+
170
+ Use `/` as delimiter for namespaced targets:
171
+
172
+ ```makefile
173
+ # Good: Namespaced targets
174
+ .PHONY: docker/build docker/push docker/clean
175
+ docker/build:
176
+ docker build -t $(IMAGE) .
177
+
178
+ docker/push:
179
+ docker push $(IMAGE)
180
+
181
+ docker/clean:
182
+ docker rmi $(IMAGE)
183
+
184
+ # Avoid: Flat namespace
185
+ .PHONY: docker-build docker-push docker-clean
186
+ ```
187
+
188
+ ## Target Declarations
189
+
190
+ ### Always Declare .PHONY
191
+
192
+ Declare targets that don't create files as phony:
193
+
194
+ ```makefile
195
+ # GOOD: Proper .PHONY declarations
196
+ .PHONY: all clean test install build deploy
197
+
198
+ all: build test
199
+
200
+ clean:
201
+ rm -rf $(BUILD_DIR)
202
+
203
+ test:
204
+ go test ./...
205
+
206
+ # BAD: Missing .PHONY - causes issues if files named 'clean' or 'test' exist
207
+ clean:
208
+ rm -rf build
209
+
210
+ test:
211
+ go test ./...
212
+ ```
213
+
214
+ ### Organize .PHONY Declarations
215
+
216
+ ```makefile
217
+ # Group related phony targets
218
+ .PHONY: all build clean
219
+ .PHONY: test test-unit test-integration
220
+ .PHONY: install uninstall
221
+ .PHONY: docker/build docker/push docker/clean
222
+
223
+ # Or use a single declaration (mbake can organize this)
224
+ .PHONY: all build clean test test-unit test-integration install uninstall
225
+ ```
226
+
227
+ ### Default Target
228
+
229
+ First target is the default (or use .DEFAULT_GOAL):
230
+
231
+ ```makefile
232
+ # Method 1: First target is default
233
+ .PHONY: all
234
+ all: build test
235
+
236
+ # Method 2: Explicit default goal
237
+ .DEFAULT_GOAL := build
238
+
239
+ .PHONY: build test
240
+ build:
241
+ go build -o app
242
+
243
+ test:
244
+ go test ./...
245
+ ```
246
+
247
+ ## Variable Management
248
+
249
+ ### Variable Assignment Operators
250
+
251
+ Choose the right operator for your use case:
252
+
253
+ ```makefile
254
+ # Simple assignment (=) - Recursive expansion (evaluated when used)
255
+ CFLAGS = -Wall $(OPTIMIZE)
256
+ OPTIMIZE = -O2
257
+ # CFLAGS will expand to: -Wall -O2 (recursive)
258
+
259
+ # Immediate assignment (:=) - Expanded immediately (RECOMMENDED for most cases)
260
+ BUILD_TIME := $(shell date +%Y%m%d-%H%M%S)
261
+ VERSION := 1.0.0
262
+ # Evaluated once, avoids repeated shell calls
263
+
264
+ # Conditional assignment (?=) - Set only if not already defined
265
+ CC ?= gcc
266
+ PREFIX ?= /usr/local
267
+ # Allows environment variable override
268
+
269
+ # Append (+=) - Add to existing value
270
+ CFLAGS := -Wall
271
+ CFLAGS += -Wextra
272
+ CFLAGS += -O2
273
+ # CFLAGS = -Wall -Wextra -O2
274
+ ```
275
+
276
+ ### Use := for Most Variables
277
+
278
+ ```makefile
279
+ # GOOD: Immediate expansion (predictable, faster)
280
+ BUILD_DIR := build
281
+ SRC_FILES := $(wildcard src/*.c)
282
+ TIMESTAMP := $(shell date +%s)
283
+
284
+ # AVOID: Recursive expansion (unpredictable, slower)
285
+ BUILD_DIR = build
286
+ SRC_FILES = $(wildcard src/*.c) # Re-evaluated every time!
287
+ TIMESTAMP = $(shell date +%s) # Shell called multiple times!
288
+ ```
289
+
290
+ ### Sane Defaults with ?=
291
+
292
+ ```makefile
293
+ # Allow user/environment override
294
+ CC ?= gcc
295
+ CXX ?= g++
296
+ PREFIX ?= /usr/local
297
+ DESTDIR ?=
298
+ VERBOSE ?= 0
299
+
300
+ # Usage:
301
+ # make # Uses defaults
302
+ # make CC=clang # Override CC
303
+ # PREFIX=/opt make # Override via environment
304
+ ```
305
+
306
+ ### Variable Naming
307
+
308
+ ```makefile
309
+ # GOOD: Clear, consistent naming
310
+ PROJECT_NAME := myapp
311
+ BUILD_DIR := build
312
+ SOURCE_FILES := $(wildcard src/*.c)
313
+ COMPILER_FLAGS := -Wall -Wextra -O2
314
+
315
+ # AVOID: Unclear abbreviations
316
+ PROJ := myapp
317
+ BDIR := build
318
+ SRCS := $(wildcard src/*.c)
319
+ FLAGS := -Wall
320
+ ```
321
+
322
+ ## Recipe Best Practices
323
+
324
+ ### Use Tabs, Not Spaces
325
+
326
+ ```makefile
327
+ # GOOD: Tab character (required)
328
+ build:
329
+ @echo "Building..."
330
+ go build -o app
331
+
332
+ # BAD: Spaces (will fail)
333
+ build:
334
+ @echo "Building..."
335
+ go build -o app
336
+ ```
337
+
338
+ **Note**: Makefiles require TAB characters for recipes. Configure your editor to use tabs for Makefiles.
339
+
340
+ ### Error Handling
341
+
342
+ ```makefile
343
+ # Method 1: Prefix with @ to suppress echo, - to ignore errors
344
+ clean:
345
+ @echo "Cleaning build artifacts..."
346
+ -rm -rf $(BUILD_DIR)
347
+ @echo "Done!"
348
+
349
+ # Method 2: Use || for conditional error handling
350
+ build:
351
+ mkdir -p $(BUILD_DIR) || exit 1
352
+ go build -o $(BUILD_DIR)/app || exit 1
353
+
354
+ # Method 3: Use set -e for strict error handling
355
+ test:
356
+ @set -e; \
357
+ echo "Running tests..."; \
358
+ go test ./...; \
359
+ echo "All tests passed!"
360
+
361
+ # Method 4: Check exit codes explicitly
362
+ deploy:
363
+ @./scripts/deploy.sh
364
+ @if [ $$? -ne 0 ]; then \
365
+ echo "Deployment failed!"; \
366
+ exit 1; \
367
+ fi
368
+ ```
369
+
370
+ ### Multi-line Recipes
371
+
372
+ ```makefile
373
+ # Use backslash for line continuation
374
+ build: $(SOURCES)
375
+ @echo "Building $(PROJECT)..."; \
376
+ mkdir -p $(BUILD_DIR); \
377
+ $(CC) $(CFLAGS) -o $(BUILD_DIR)/$(PROJECT) $(SOURCES); \
378
+ echo "Build complete!"
379
+
380
+ # Or use .ONESHELL for easier multi-line scripts
381
+ .ONESHELL:
382
+ test:
383
+ echo "Running tests..."
384
+ for file in tests/*.sh; do
385
+ bash $$file
386
+ done
387
+ echo "All tests passed!"
388
+ ```
389
+
390
+ ### Silent vs Verbose Output
391
+
392
+ ```makefile
393
+ # Use @ to suppress command echo
394
+ .PHONY: build
395
+ build:
396
+ @echo "Building..."
397
+ @$(CC) $(CFLAGS) -o app $(SOURCES)
398
+
399
+ # Optional verbose mode
400
+ VERBOSE ?= 0
401
+ ifeq ($(VERBOSE),1)
402
+ Q :=
403
+ else
404
+ Q := @
405
+ endif
406
+
407
+ build:
408
+ $(Q)echo "Building..."
409
+ $(Q)$(CC) $(CFLAGS) -o app $(SOURCES)
410
+
411
+ # Usage:
412
+ # make build # Silent
413
+ # make build VERBOSE=1 # Verbose
414
+ ```
415
+
416
+ ## Dependency Management
417
+
418
+ ### Specify Dependencies Correctly
419
+
420
+ ```makefile
421
+ # GOOD: Proper dependency chain
422
+ app: $(OBJECTS)
423
+ $(CC) -o $@ $^
424
+
425
+ %.o: %.c %.h
426
+ $(CC) $(CFLAGS) -c $< -o $@
427
+
428
+ # BAD: Missing dependencies - app won't rebuild when headers change
429
+ app: $(OBJECTS)
430
+ $(CC) -o $@ $^
431
+
432
+ %.o: %.c
433
+ $(CC) $(CFLAGS) -c $< -o $@
434
+ ```
435
+
436
+ ### Auto-generate Dependencies (C/C++)
437
+
438
+ ```makefile
439
+ # Automatic dependency generation
440
+ DEPDIR := .deps
441
+ DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d
442
+
443
+ %.o: %.c $(DEPDIR)/%.d | $(DEPDIR)
444
+ $(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@
445
+
446
+ $(DEPDIR):
447
+ @mkdir -p $@
448
+
449
+ # Include generated dependency files
450
+ -include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SOURCES)))
451
+ ```
452
+
453
+ ### Order-Only Prerequisites
454
+
455
+ Use `|` for prerequisites that shouldn't trigger rebuilds:
456
+
457
+ ```makefile
458
+ # Regular prerequisites trigger rebuild
459
+ $(BUILD_DIR)/app: $(SOURCES)
460
+ $(CC) -o $@ $^
461
+
462
+ # Order-only prerequisites (directories) don't trigger rebuild
463
+ $(BUILD_DIR)/app: $(SOURCES) | $(BUILD_DIR)
464
+ $(CC) -o $@ $^
465
+
466
+ $(BUILD_DIR):
467
+ mkdir -p $@
468
+
469
+ # Without |, updating BUILD_DIR timestamp would trigger app rebuild
470
+ # With |, app only rebuilds when SOURCES change
471
+ ```
472
+
473
+ ### VPATH for Source Organization
474
+
475
+ ```makefile
476
+ # Search for prerequisites in multiple directories
477
+ VPATH = src:include:tests
478
+
479
+ # Or use vpath for specific patterns
480
+ vpath %.c src
481
+ vpath %.h include
482
+ vpath %.test tests
483
+
484
+ # Now Make will find files in these directories
485
+ app: main.o utils.o
486
+ $(CC) -o $@ $^
487
+
488
+ # Make will find src/main.c and src/utils.c automatically
489
+ ```
490
+
491
+ ## Performance Optimization
492
+
493
+ ### Use .PHONY for Performance
494
+
495
+ ```makefile
496
+ # GOOD: Phony targets skip implicit rule search
497
+ .PHONY: clean test install
498
+
499
+ clean:
500
+ rm -rf $(BUILD_DIR)
501
+
502
+ # BAD: Without .PHONY, Make checks for file existence
503
+ clean:
504
+ rm -rf $(BUILD_DIR)
505
+ ```
506
+
507
+ ### Parallel Builds
508
+
509
+ ```makefile
510
+ # Enable parallel builds (use -j flag)
511
+ # make -j8 build # 8 parallel jobs
512
+
513
+ # For sequential targets, use .NOTPARALLEL
514
+ .NOTPARALLEL: deploy
515
+
516
+ deploy: build test
517
+ ./scripts/deploy.sh
518
+
519
+ # Or use order-only prerequisites for partial ordering
520
+ build-frontend: | build-backend
521
+ npm run build
522
+ ```
523
+
524
+ ### Intermediate File Cleanup
525
+
526
+ ```makefile
527
+ # Mark intermediate files for auto-deletion
528
+ .INTERMEDIATE: $(OBJECTS)
529
+
530
+ # Or mark files to keep through one build
531
+ .SECONDARY: $(OBJECTS)
532
+
533
+ # Delete on error (recommended)
534
+ .DELETE_ON_ERROR:
535
+
536
+ # Example: .o files cleaned after linking
537
+ app: main.o utils.o
538
+ $(CC) -o $@ $^
539
+ # main.o and utils.o auto-deleted after successful build
540
+ ```
541
+
542
+ ### Avoid Redundant Shell Calls
543
+
544
+ ```makefile
545
+ # BAD: Shell called every time variable is used
546
+ DATE = $(shell date +%Y%m%d)
547
+ VERSION = $(shell git describe --tags)
548
+
549
+ target1:
550
+ echo $(DATE) # Shell called here
551
+
552
+ target2:
553
+ echo $(DATE) # Shell called again!
554
+
555
+ # GOOD: Use := for one-time evaluation
556
+ DATE := $(shell date +%Y%m%d)
557
+ VERSION := $(shell git describe --tags)
558
+
559
+ target1:
560
+ echo $(DATE) # Expands to cached value
561
+
562
+ target2:
563
+ echo $(DATE) # Same cached value
564
+ ```
565
+
566
+ ## Portability
567
+
568
+ ### POSIX Shell Compatibility
569
+
570
+ ```makefile
571
+ # GOOD: POSIX-compatible commands
572
+ .PHONY: install
573
+ install:
574
+ mkdir -p $(DESTDIR)$(PREFIX)/bin
575
+ cp -f app $(DESTDIR)$(PREFIX)/bin/
576
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/app
577
+
578
+ # AVOID: Bashisms or GNU-specific features
579
+ install:
580
+ mkdir -p $(DESTDIR)$(PREFIX)/bin
581
+ cp app $(DESTDIR)$(PREFIX)/bin/ # Missing -f for portability
582
+ ```
583
+
584
+ ### Cross-Platform Variables
585
+
586
+ ```makefile
587
+ # Detect operating system
588
+ UNAME_S := $(shell uname -s)
589
+ ifeq ($(UNAME_S),Linux)
590
+ PLATFORM := linux
591
+ EXE_EXT :=
592
+ endif
593
+ ifeq ($(UNAME_S),Darwin)
594
+ PLATFORM := macos
595
+ EXE_EXT :=
596
+ endif
597
+ ifeq ($(OS),Windows_NT)
598
+ PLATFORM := windows
599
+ EXE_EXT := .exe
600
+ endif
601
+
602
+ # Use platform-specific settings
603
+ APP := app$(EXE_EXT)
604
+ ```
605
+
606
+ ### Avoid Hard-Coded Paths
607
+
608
+ ```makefile
609
+ # BAD: Hard-coded paths
610
+ install:
611
+ cp app /usr/local/bin/
612
+ cp docs/app.1 /usr/share/man/man1/
613
+
614
+ # GOOD: Use variables for paths
615
+ PREFIX ?= /usr/local
616
+ BINDIR ?= $(PREFIX)/bin
617
+ MANDIR ?= $(PREFIX)/share/man
618
+
619
+ install:
620
+ install -d $(DESTDIR)$(BINDIR)
621
+ install -m 755 app $(DESTDIR)$(BINDIR)/
622
+ install -d $(DESTDIR)$(MANDIR)/man1
623
+ install -m 644 docs/app.1 $(DESTDIR)$(MANDIR)/man1/
624
+ ```
625
+
626
+ ## Documentation
627
+
628
+ ### Comment Your Makefiles
629
+
630
+ ```makefile
631
+ # Project: MyApp
632
+ # Description: Build system for MyApp project
633
+ # Author: Your Name
634
+ # Version: 1.0.0
635
+
636
+ # Configuration variables
637
+ PROJECT := myapp
638
+ VERSION := $(shell git describe --tags 2>/dev/null || echo "dev")
639
+
640
+ # Build directories
641
+ BUILD_DIR := build
642
+ SRC_DIR := src
643
+
644
+ # Compiler settings
645
+ CC := gcc
646
+ CFLAGS := -Wall -Wextra -O2
647
+
648
+ # Default target: Build and test the application
649
+ .PHONY: all
650
+ all: build test
651
+
652
+ # Build the main application binary
653
+ .PHONY: build
654
+ build: $(BUILD_DIR)/$(PROJECT)
655
+ @echo "Build complete: $(BUILD_DIR)/$(PROJECT)"
656
+
657
+ # Run all test suites
658
+ .PHONY: test
659
+ test:
660
+ @echo "Running tests..."
661
+ @./scripts/run-tests.sh
662
+ ```
663
+
664
+ ### Help Target
665
+
666
+ ```makefile
667
+ # Provide a help target
668
+ .PHONY: help
669
+ help:
670
+ @echo "Available targets:"
671
+ @echo " make build - Build the application"
672
+ @echo " make test - Run tests"
673
+ @echo " make clean - Remove build artifacts"
674
+ @echo " make install - Install to $(PREFIX)"
675
+ @echo ""
676
+ @echo "Variables:"
677
+ @echo " PREFIX=$(PREFIX)"
678
+ @echo " CC=$(CC)"
679
+
680
+ # Or auto-generate from comments
681
+ .PHONY: help
682
+ help:
683
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
684
+ awk 'BEGIN {FS = ":.*?## "}; {printf " %-20s %s\n", $$1, $$2}'
685
+
686
+ build: ## Build the application
687
+ @go build -o app
688
+
689
+ test: ## Run all tests
690
+ @go test ./...
691
+
692
+ clean: ## Remove build artifacts
693
+ @rm -rf $(BUILD_DIR)
694
+ ```
695
+
696
+ ## Security
697
+
698
+ ### Avoid Hardcoded Credentials
699
+
700
+ ```makefile
701
+ # BAD: Hardcoded secrets
702
+ deploy:
703
+ curl -H "Authorization: Bearer sk-1234567890" https://api.example.com/deploy
704
+
705
+ # GOOD: Use environment variables
706
+ deploy:
707
+ @if [ -z "$$API_TOKEN" ]; then \
708
+ echo "Error: API_TOKEN not set"; \
709
+ exit 1; \
710
+ fi
711
+ curl -H "Authorization: Bearer $$API_TOKEN" https://api.example.com/deploy
712
+ ```
713
+
714
+ ### Validate Input Variables
715
+
716
+ ```makefile
717
+ # Validate critical variables
718
+ .PHONY: deploy
719
+ deploy:
720
+ @if [ -z "$(ENV)" ]; then \
721
+ echo "Error: ENV not specified (prod|staging|dev)"; \
722
+ exit 1; \
723
+ fi
724
+ @if [ "$(ENV)" != "prod" ] && [ "$(ENV)" != "staging" ] && [ "$(ENV)" != "dev" ]; then \
725
+ echo "Error: Invalid ENV=$(ENV)"; \
726
+ exit 1; \
727
+ fi
728
+ @echo "Deploying to $(ENV)..."
729
+ ./scripts/deploy.sh $(ENV)
730
+ ```
731
+
732
+ ### Safe Variable Expansion
733
+
734
+ ```makefile
735
+ # BAD: Unsafe variable expansion
736
+ clean:
737
+ rm -rf $(BUILD_DIR)/* # Dangerous if BUILD_DIR is empty or /
738
+
739
+ # GOOD: Validate before dangerous operations
740
+ .PHONY: clean
741
+ clean:
742
+ @if [ -z "$(BUILD_DIR)" ] || [ "$(BUILD_DIR)" = "/" ]; then \
743
+ echo "Error: Invalid BUILD_DIR"; \
744
+ exit 1; \
745
+ fi
746
+ rm -rf $(BUILD_DIR)/*
747
+
748
+ # BETTER: Use safer patterns
749
+ BUILD_DIR := build # Never empty
750
+ clean:
751
+ @test -d $(BUILD_DIR) && rm -rf $(BUILD_DIR)/* || true
752
+ ```
753
+
754
+ ## Advanced Patterns
755
+
756
+ ### Pattern Rules
757
+
758
+ ```makefile
759
+ # Pattern rule for object files
760
+ %.o: %.c
761
+ $(CC) $(CFLAGS) -c $< -o $@
762
+
763
+ # Multiple pattern rules
764
+ $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
765
+ @mkdir -p $(dir $@)
766
+ $(CC) $(CFLAGS) -c $< -o $@
767
+
768
+ # Static pattern rules
769
+ $(OBJECTS): %.o: %.c
770
+ $(CC) $(CFLAGS) -c $< -o $@
771
+ ```
772
+
773
+ ### Automatic Variables
774
+
775
+ ```makefile
776
+ # $@ - Target name
777
+ # $< - First prerequisite
778
+ # $^ - All prerequisites
779
+ # $? - Prerequisites newer than target
780
+ # $* - Stem of pattern rule
781
+
782
+ build/%.o: src/%.c
783
+ @mkdir -p $(dir $@) # Directory of target
784
+ $(CC) -c $< -o $@ # First prereq to target
785
+ @echo "Built $@" # Target name
786
+
787
+ # Example:
788
+ # build/main.o: src/main.c
789
+ # $@ = build/main.o
790
+ # $< = src/main.c
791
+ # $* = main
792
+ ```
793
+
794
+ ### Functions
795
+
796
+ ```makefile
797
+ # Built-in functions
798
+ SOURCES := $(wildcard src/*.c)
799
+ OBJECTS := $(patsubst src/%.c,build/%.o,$(SOURCES))
800
+ HEADERS := $(shell find include -name '*.h')
801
+
802
+ # String manipulation
803
+ UPPERCASE := $(shell echo $(PROJECT) | tr '[:lower:]' '[:upper:]')
804
+ VERSION_MAJOR := $(word 1,$(subst ., ,$(VERSION)))
805
+
806
+ # Custom functions
807
+ define compile_template
808
+ $(1): $(2)
809
+ $(CC) $(CFLAGS) -c $$< -o $$@
810
+ endef
811
+
812
+ $(foreach src,$(SOURCES),$(eval $(call compile_template,$(patsubst %.c,%.o,$(src)),$(src))))
813
+ ```
814
+
815
+ ### Conditional Compilation
816
+
817
+ ```makefile
818
+ # Debug vs Release builds
819
+ DEBUG ?= 0
820
+
821
+ ifeq ($(DEBUG),1)
822
+ CFLAGS := -g -O0 -DDEBUG
823
+ BUILD_TYPE := debug
824
+ else
825
+ CFLAGS := -O2 -DNDEBUG
826
+ BUILD_TYPE := release
827
+ endif
828
+
829
+ build:
830
+ @echo "Building $(BUILD_TYPE) version..."
831
+ $(CC) $(CFLAGS) -o app $(SOURCES)
832
+ ```
833
+
834
+ ## Summary Checklist
835
+
836
+ - [ ] **.DELETE_ON_ERROR:** declared at top (critical)
837
+ - [ ] All non-file targets declared as .PHONY
838
+ - [ ] Tabs used for recipe indentation (not spaces)
839
+ - [ ] Variables use := for immediate expansion
840
+ - [ ] Sane defaults with ?= for user override
841
+ - [ ] Dependencies properly specified
842
+ - [ ] Error handling in critical recipes
843
+ - [ ] Default target documented and listed first
844
+ - [ ] No hardcoded credentials or paths
845
+ - [ ] Help target provided
846
+ - [ ] Parallel build safety considered
847
+ - [ ] Intermediate files managed (.INTERMEDIATE/.SECONDARY)
848
+ - [ ] Comments explain complex logic
849
+ - [ ] Portable commands used (POSIX compatible)
850
+ - [ ] Variables validated before dangerous operations
851
+ - [ ] .SUFFIXES: considered for disabling built-in rules
852
+
853
+ ## Additional Resources
854
+
855
+ - [GNU Make Manual](https://www.gnu.org/software/make/manual/)
856
+ - [Makefile Style Guide](https://clarkgrubb.com/makefile-style-guide)
857
+ - [Advanced Makefile Tricks](https://www.gnu.org/software/make/manual/html_node/Quick-Reference.html)
858
+ - [Recursive Make Considered Harmful](https://aegis.sourceforge.net/auug97.pdf)