@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.
- package/.agents/{agents.md → AGENTS.md} +3 -1
- package/.agents/nodes.json +3 -1
- package/.agents/vendor-manifest.json +23 -1
- package/.claude/agents/godmode-media-eventtech.md +1 -1
- package/.claude/hooks/conventional-commits.mjs +125 -0
- package/.claude/hooks/env-file-protection.mjs +105 -0
- package/.claude/hooks/go-gate.mjs +101 -81
- package/.claude/hooks/memb-inject.mjs +29 -1
- package/.claude/settings.json +13 -0
- package/.claude/workflows/startcycle-dispatch.mjs +23 -1
- package/.opencode/agents/godmode-media-eventtech.md +1 -1
- package/.opencode/plugins/bdb-aos.js +31 -4
- package/CLAUDE.md +0 -571
- package/README.de.md +1 -1
- package/README.md +1 -1
- package/README.pt.md +1 -1
- package/THIRD_PARTY_NOTICES.md +126 -0
- package/bin/aos-doctor.mjs +1 -1
- package/docs/skills_table.md +1 -1
- package/installer.js +187 -55
- package/package.json +7 -3
- package/packages/aos-cli/README.md +80 -0
- package/packages/aos-cli/bin/aos-cli.mjs +134 -0
- package/packages/aos-cli/core-skills.json +12 -0
- package/packages/aos-cli/extensions/aos.ts +321 -0
- package/packages/aos-cli/package-lock.json +1923 -0
- package/packages/aos-cli/package.json +29 -0
- package/packages/aos-cli/scripts/check-theme.mjs +63 -0
- package/packages/aos-cli/themes/aos.json +97 -0
- package/scripts/build-plugin-manifest.mjs +131 -0
- package/scripts/validate-skills.mjs +81 -6
- package/skills/basic/ao-orchestrator/SKILL.md +116 -0
- package/skills/basic/bdb-eventagency-skill/SKILL.md +252 -0
- package/skills/basic/bdb-shipping-skill/SKILL.md +161 -0
- package/skills/basic/godmode-eventtech/SKILL.md +4 -1
- package/skills/global_config/agenttrail/SKILL.md +6 -1
- package/skills/global_config/aos-project-init/SKILL.md +2 -0
- package/skills/global_config/aos-project-init/assets/AGENTS.template.md +1 -1
- package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +1 -1
- package/skills/global_config/aos-setup/SKILL.md +1 -1
- package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +1 -1
- package/skills/global_config/ask-tim/SKILL.md +7 -7
- package/skills/global_config/bash-script-generator/SKILL.md +201 -0
- package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
- package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
- package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
- package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
- package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
- package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
- package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
- package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
- package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
- package/skills/global_config/bash-script-validator/SKILL.md +249 -0
- package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
- package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
- package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
- package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
- package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
- package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
- package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
- package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
- package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
- package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
- package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
- package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
- package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
- package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
- package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
- package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
- package/skills/global_config/ci-pipeline/SKILL.md +135 -0
- package/skills/global_config/deja-memory/SKILL.md +3 -1
- package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
- package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
- package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
- package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
- package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
- package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
- package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
- package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
- package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
- package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
- package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
- package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
- package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
- package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
- package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
- package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
- package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
- package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
- package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
- package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
- package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
- package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
- package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
- package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
- package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
- package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
- package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
- package/skills/global_config/github-actions-generator/SKILL.md +353 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
- package/skills/global_config/github-actions-generator/examples/README.md +147 -0
- package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
- package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
- package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
- package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
- package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
- package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
- package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
- package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
- package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
- package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
- package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
- package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
- package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
- package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
- package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
- package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
- package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
- package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
- package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
- package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
- package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
- package/skills/global_config/github-actions-templates/SKILL.md +7 -0
- package/skills/global_config/github-actions-validator/SKILL.md +576 -0
- package/skills/global_config/github-actions-validator/examples/README.md +88 -0
- package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
- package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
- package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
- package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
- package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
- package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
- package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
- package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
- package/skills/global_config/github-actions-validator/references/runners.md +317 -0
- package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
- package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
- package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
- package/skills/global_config/makefile-generator/SKILL.md +614 -0
- package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
- package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
- package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
- package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
- package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
- package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
- package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
- package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
- package/skills/global_config/makefile-validator/SKILL.md +244 -0
- package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
- package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
- package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
- package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
- package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
- package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
- package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
- package/skills/global_config/{MCP_Manage → mcp-manage}/SKILL.md +3 -3
- package/skills/global_config/plan-canvas/SKILL.md +9 -2
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/ui.js +10 -2
- package/skills/global_config/plan-canvas/scripts/plan-canvas.js +1 -1
- package/skills/global_config/read-the-damn-docs/SKILL.md +175 -0
- package/skills/global_config/requesting-code-review/SKILL.md +98 -0
- package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
- package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
- package/skills/global_config/verification-before-completion/SKILL.md +123 -0
- package/skills/global_config/writing-plans/SKILL.md +126 -46
- package/skills/global_config/writing-plans-legacy/SKILL.md +152 -0
- package/.claude/CLAUDE.md +0 -12
- package/mcps/RhinoMCP/docs/content/docs/getting-started/gemini.md +0 -61
- /package/{GEMINI.md → RULES.md} +0 -0
|
@@ -0,0 +1,642 @@
|
|
|
1
|
+
# Makefile Targets Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This guide covers target definitions, standard GNU targets, .PHONY declarations, dependencies, pattern rules, and best practices for organizing targets in Makefiles.
|
|
6
|
+
|
|
7
|
+
## Target Basics
|
|
8
|
+
|
|
9
|
+
### Target Syntax
|
|
10
|
+
|
|
11
|
+
```makefile
|
|
12
|
+
target: prerequisites
|
|
13
|
+
recipe
|
|
14
|
+
recipe
|
|
15
|
+
...
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- **target**: File to create or action to perform
|
|
19
|
+
- **prerequisites**: Files/targets that must exist or be up-to-date
|
|
20
|
+
- **recipe**: Shell commands to run (must be indented with TAB)
|
|
21
|
+
|
|
22
|
+
### Simple Example
|
|
23
|
+
|
|
24
|
+
```makefile
|
|
25
|
+
hello: hello.c
|
|
26
|
+
gcc hello.c -o hello
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**How it works:**
|
|
30
|
+
1. Check if `hello` exists and is newer than `hello.c`
|
|
31
|
+
2. If not, run the recipe
|
|
32
|
+
3. Recipe creates `hello`
|
|
33
|
+
|
|
34
|
+
## .PHONY Targets
|
|
35
|
+
|
|
36
|
+
### What are .PHONY Targets?
|
|
37
|
+
|
|
38
|
+
Phony targets don't represent actual files. They represent actions:
|
|
39
|
+
|
|
40
|
+
```makefile
|
|
41
|
+
.PHONY: clean
|
|
42
|
+
clean:
|
|
43
|
+
rm -f *.o myprogram
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Without .PHONY:**
|
|
47
|
+
- If a file named "clean" exists, `make clean` won't run
|
|
48
|
+
- make thinks the target is already up-to-date
|
|
49
|
+
|
|
50
|
+
**With .PHONY:**
|
|
51
|
+
- make always runs the recipe
|
|
52
|
+
- Performance improvement (skips unnecessary file system checks)
|
|
53
|
+
|
|
54
|
+
### Common .PHONY Targets
|
|
55
|
+
|
|
56
|
+
```makefile
|
|
57
|
+
.PHONY: all clean install uninstall test check help
|
|
58
|
+
.PHONY: build dist distclean format lint docs
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Multiple .PHONY Declarations
|
|
62
|
+
|
|
63
|
+
```makefile
|
|
64
|
+
# Option 1: All at once (recommended)
|
|
65
|
+
.PHONY: all clean install test help
|
|
66
|
+
|
|
67
|
+
# Option 2: Separate declarations
|
|
68
|
+
.PHONY: all
|
|
69
|
+
.PHONY: clean
|
|
70
|
+
.PHONY: install
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Standard GNU Targets
|
|
74
|
+
|
|
75
|
+
GNU Coding Standards define standard targets that users expect:
|
|
76
|
+
|
|
77
|
+
### Essential Targets
|
|
78
|
+
|
|
79
|
+
#### all (Default Target)
|
|
80
|
+
|
|
81
|
+
```makefile
|
|
82
|
+
## Build all targets
|
|
83
|
+
.PHONY: all
|
|
84
|
+
all: $(TARGET)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Requirements:**
|
|
88
|
+
- Should be the first target (default)
|
|
89
|
+
- Should compile the entire program
|
|
90
|
+
- Should NOT install, clean, or run tests
|
|
91
|
+
- Should create the primary output (executable, library, etc.)
|
|
92
|
+
|
|
93
|
+
#### install
|
|
94
|
+
|
|
95
|
+
```makefile
|
|
96
|
+
## Install built files to PREFIX
|
|
97
|
+
.PHONY: install
|
|
98
|
+
install: all
|
|
99
|
+
$(INSTALL) -d $(DESTDIR)$(BINDIR)
|
|
100
|
+
$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BINDIR)/
|
|
101
|
+
$(INSTALL) -d $(DESTDIR)$(LIBDIR)
|
|
102
|
+
$(INSTALL_DATA) lib$(PROJECT).a $(DESTDIR)$(LIBDIR)/
|
|
103
|
+
$(INSTALL) -d $(DESTDIR)$(INCLUDEDIR)
|
|
104
|
+
$(INSTALL_DATA) $(PROJECT).h $(DESTDIR)$(INCLUDEDIR)/
|
|
105
|
+
$(INSTALL) -d $(DESTDIR)$(MAN1DIR)
|
|
106
|
+
$(INSTALL_DATA) docs/$(PROJECT).1 $(DESTDIR)$(MAN1DIR)/
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Requirements:**
|
|
110
|
+
- Should depend on `all` to build first
|
|
111
|
+
- Should respect `DESTDIR` and `PREFIX`
|
|
112
|
+
- Should create necessary directories
|
|
113
|
+
- Should set appropriate permissions
|
|
114
|
+
- Should be idempotent (safe to run multiple times)
|
|
115
|
+
|
|
116
|
+
#### uninstall
|
|
117
|
+
|
|
118
|
+
```makefile
|
|
119
|
+
## Remove installed files
|
|
120
|
+
.PHONY: uninstall
|
|
121
|
+
uninstall:
|
|
122
|
+
$(RM) $(DESTDIR)$(BINDIR)/$(TARGET)
|
|
123
|
+
$(RM) $(DESTDIR)$(LIBDIR)/lib$(PROJECT).a
|
|
124
|
+
$(RM) $(DESTDIR)$(INCLUDEDIR)/$(PROJECT).h
|
|
125
|
+
$(RM) $(DESTDIR)$(MAN1DIR)/$(PROJECT).1
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### clean
|
|
129
|
+
|
|
130
|
+
```makefile
|
|
131
|
+
## Remove built files (keep configuration)
|
|
132
|
+
.PHONY: clean
|
|
133
|
+
clean:
|
|
134
|
+
$(RM) $(OBJECTS) $(TARGET)
|
|
135
|
+
$(RM) -r $(BUILDDIR)
|
|
136
|
+
$(RM) *.o *.a *.so
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Requirements:**
|
|
140
|
+
- Remove object files, executables, libraries
|
|
141
|
+
- Keep configuration files and Makefile
|
|
142
|
+
- Should allow rebuilding without reconfiguring
|
|
143
|
+
|
|
144
|
+
#### distclean
|
|
145
|
+
|
|
146
|
+
```makefile
|
|
147
|
+
## Remove all generated files (including configuration)
|
|
148
|
+
.PHONY: distclean
|
|
149
|
+
distclean: clean
|
|
150
|
+
$(RM) config.h config.log config.status
|
|
151
|
+
$(RM) Makefile
|
|
152
|
+
$(RM) -r autom4te.cache/
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Requirements:**
|
|
156
|
+
- Should depend on `clean`
|
|
157
|
+
- Remove configure-generated files
|
|
158
|
+
- Leave only source files
|
|
159
|
+
- After distclean, only `./configure` should work
|
|
160
|
+
|
|
161
|
+
### Testing Targets
|
|
162
|
+
|
|
163
|
+
#### test
|
|
164
|
+
|
|
165
|
+
```makefile
|
|
166
|
+
## Run tests
|
|
167
|
+
.PHONY: test
|
|
168
|
+
test: $(TARGET)
|
|
169
|
+
@echo "Running tests..."
|
|
170
|
+
./run_tests.sh
|
|
171
|
+
$(TARGET) --self-test
|
|
172
|
+
@echo "All tests passed!"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### check
|
|
176
|
+
|
|
177
|
+
```makefile
|
|
178
|
+
## Alias for test (GNU convention)
|
|
179
|
+
.PHONY: check
|
|
180
|
+
check: test
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Distribution Targets
|
|
184
|
+
|
|
185
|
+
#### dist
|
|
186
|
+
|
|
187
|
+
```makefile
|
|
188
|
+
## Create distribution tarball
|
|
189
|
+
.PHONY: dist
|
|
190
|
+
dist:
|
|
191
|
+
@mkdir -p dist
|
|
192
|
+
tar -czf dist/$(PROJECT)-$(VERSION).tar.gz \
|
|
193
|
+
--transform 's,^,$(PROJECT)-$(VERSION)/,' \
|
|
194
|
+
--exclude='.git*' \
|
|
195
|
+
--exclude='*.o' \
|
|
196
|
+
--exclude='*.a' \
|
|
197
|
+
--exclude='$(BUILDDIR)' \
|
|
198
|
+
.
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### distcheck
|
|
202
|
+
|
|
203
|
+
```makefile
|
|
204
|
+
## Create and verify distribution tarball
|
|
205
|
+
.PHONY: distcheck
|
|
206
|
+
distcheck: dist
|
|
207
|
+
@echo "Verifying distribution..."
|
|
208
|
+
@mkdir -p $(BUILDDIR)/distcheck
|
|
209
|
+
tar -xzf dist/$(PROJECT)-$(VERSION).tar.gz -C $(BUILDDIR)/distcheck
|
|
210
|
+
cd $(BUILDDIR)/distcheck/$(PROJECT)-$(VERSION) && ./configure && make && make check
|
|
211
|
+
@echo "Distribution verified successfully!"
|
|
212
|
+
$(RM) -r $(BUILDDIR)/distcheck
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Documentation Targets
|
|
216
|
+
|
|
217
|
+
#### help
|
|
218
|
+
|
|
219
|
+
```makefile
|
|
220
|
+
## Show available targets and usage
|
|
221
|
+
.PHONY: help
|
|
222
|
+
help:
|
|
223
|
+
@echo "$(PROJECT) - version $(VERSION)"
|
|
224
|
+
@echo ""
|
|
225
|
+
@echo "Available targets:"
|
|
226
|
+
@sed -n 's/^## //p' $(MAKEFILE_LIST) | column -t -s ':' | sed 's/^/ /'
|
|
227
|
+
@echo ""
|
|
228
|
+
@echo "Variables:"
|
|
229
|
+
@echo " PREFIX=$(PREFIX)"
|
|
230
|
+
@echo " CC=$(CC)"
|
|
231
|
+
@echo " CFLAGS=$(CFLAGS)"
|
|
232
|
+
@echo ""
|
|
233
|
+
@echo "Examples:"
|
|
234
|
+
@echo " make # Build the project"
|
|
235
|
+
@echo " make install # Install to PREFIX"
|
|
236
|
+
@echo " make PREFIX=/opt/local # Install to custom location"
|
|
237
|
+
@echo " make clean # Remove built files"
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Self-documenting pattern:**
|
|
241
|
+
```makefile
|
|
242
|
+
## Build the application
|
|
243
|
+
.PHONY: build
|
|
244
|
+
build: $(TARGET)
|
|
245
|
+
|
|
246
|
+
## Run all tests
|
|
247
|
+
.PHONY: test
|
|
248
|
+
test:
|
|
249
|
+
./run_tests.sh
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The `##` comments are parsed by the help target.
|
|
253
|
+
|
|
254
|
+
## Target Dependencies
|
|
255
|
+
|
|
256
|
+
### Simple Dependencies
|
|
257
|
+
|
|
258
|
+
```makefile
|
|
259
|
+
# program depends on main.o and utils.o
|
|
260
|
+
program: main.o utils.o
|
|
261
|
+
$(CC) $^ -o $@
|
|
262
|
+
|
|
263
|
+
# main.o depends on main.c
|
|
264
|
+
main.o: main.c
|
|
265
|
+
$(CC) -c $< -o $@
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Multiple Targets
|
|
269
|
+
|
|
270
|
+
```makefile
|
|
271
|
+
# Multiple targets with same recipe
|
|
272
|
+
main.o utils.o helper.o: common.h
|
|
273
|
+
$(CC) -c $*.c -o $@
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Order-Only Prerequisites
|
|
277
|
+
|
|
278
|
+
```makefile
|
|
279
|
+
# Normal prerequisites: update target if prerequisite changes
|
|
280
|
+
# Order-only prerequisites (|): only check existence, not timestamp
|
|
281
|
+
|
|
282
|
+
$(OBJDIR)/%.o: %.c | $(OBJDIR)
|
|
283
|
+
$(CC) -c $< -o $@
|
|
284
|
+
|
|
285
|
+
# $(OBJDIR) must exist, but changes to it don't trigger rebuild
|
|
286
|
+
$(OBJDIR):
|
|
287
|
+
mkdir -p $@
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Use cases:**
|
|
291
|
+
- Directory creation (directory timestamp changes don't matter)
|
|
292
|
+
- Lock files
|
|
293
|
+
- State files
|
|
294
|
+
|
|
295
|
+
### Circular Dependencies
|
|
296
|
+
|
|
297
|
+
```makefile
|
|
298
|
+
# WRONG: Circular dependency
|
|
299
|
+
a: b
|
|
300
|
+
b: a
|
|
301
|
+
# Error: Circular a <- b dependency dropped
|
|
302
|
+
|
|
303
|
+
# RIGHT: Break the cycle
|
|
304
|
+
a: c
|
|
305
|
+
b: c
|
|
306
|
+
c:
|
|
307
|
+
touch c
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Pattern Rules
|
|
311
|
+
|
|
312
|
+
### Basic Pattern Rules
|
|
313
|
+
|
|
314
|
+
```makefile
|
|
315
|
+
# Compile .c to .o
|
|
316
|
+
%.o: %.c
|
|
317
|
+
$(CC) $(CFLAGS) -c $< -o $@
|
|
318
|
+
|
|
319
|
+
# Compile .c to .s (assembly)
|
|
320
|
+
%.s: %.c
|
|
321
|
+
$(CC) $(CFLAGS) -S $< -o $@
|
|
322
|
+
|
|
323
|
+
# Create .c from .y (yacc)
|
|
324
|
+
%.c: %.y
|
|
325
|
+
$(YACC) $(YFLAGS) -o $@ $<
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Pattern Rules with Directories
|
|
329
|
+
|
|
330
|
+
```makefile
|
|
331
|
+
# Match files in specific directories
|
|
332
|
+
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
|
333
|
+
@mkdir -p $(@D)
|
|
334
|
+
$(CC) $(CFLAGS) -c $< -o $@
|
|
335
|
+
|
|
336
|
+
# Multiple directory patterns
|
|
337
|
+
build/obj/%.o: src/%.c
|
|
338
|
+
$(CC) -c $< -o $@
|
|
339
|
+
|
|
340
|
+
build/obj/%.o: lib/%.c
|
|
341
|
+
$(CC) -c $< -o $@
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Static Pattern Rules
|
|
345
|
+
|
|
346
|
+
More efficient than pattern rules for specific files:
|
|
347
|
+
|
|
348
|
+
```makefile
|
|
349
|
+
OBJECTS := main.o utils.o helper.o
|
|
350
|
+
|
|
351
|
+
# Static pattern: $(targets): target-pattern: prereq-pattern
|
|
352
|
+
$(OBJECTS): %.o: %.c
|
|
353
|
+
$(CC) $(CFLAGS) -c $< -o $@
|
|
354
|
+
|
|
355
|
+
# Equivalent to:
|
|
356
|
+
# main.o: main.c
|
|
357
|
+
# utils.o: utils.c
|
|
358
|
+
# helper.o: helper.c
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Advantages:**
|
|
362
|
+
- More explicit than pattern rules
|
|
363
|
+
- Faster (make knows exact targets)
|
|
364
|
+
- Easier to debug
|
|
365
|
+
|
|
366
|
+
### Multiple Pattern Rules
|
|
367
|
+
|
|
368
|
+
```makefile
|
|
369
|
+
# First matching rule is used
|
|
370
|
+
%.o: %.c
|
|
371
|
+
$(CC) $(CFLAGS) -c $< -o $@
|
|
372
|
+
|
|
373
|
+
%.o: %.s
|
|
374
|
+
$(AS) $(ASFLAGS) -c $< -o $@
|
|
375
|
+
|
|
376
|
+
%.o: %.asm
|
|
377
|
+
$(NASM) $(NASMFLAGS) -f elf64 $< -o $@
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Target-Specific Variables
|
|
381
|
+
|
|
382
|
+
```makefile
|
|
383
|
+
# Set variable only for specific target and its prerequisites
|
|
384
|
+
debug: CFLAGS += -g -O0 -DDEBUG
|
|
385
|
+
debug: $(TARGET)
|
|
386
|
+
|
|
387
|
+
release: CFLAGS += -O3 -DNDEBUG
|
|
388
|
+
release: $(TARGET)
|
|
389
|
+
|
|
390
|
+
# Pattern-specific variables
|
|
391
|
+
test_%: CFLAGS += -DTESTING
|
|
392
|
+
test_%: LDLIBS += -lcheck
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## Advanced Target Patterns
|
|
396
|
+
|
|
397
|
+
### Double-Colon Rules
|
|
398
|
+
|
|
399
|
+
```makefile
|
|
400
|
+
# Double-colon allows multiple recipes for same target
|
|
401
|
+
install::
|
|
402
|
+
@echo "Installing binaries..."
|
|
403
|
+
$(INSTALL) $(TARGET) $(BINDIR)/
|
|
404
|
+
|
|
405
|
+
install::
|
|
406
|
+
@echo "Installing libraries..."
|
|
407
|
+
$(INSTALL) lib$(PROJECT).a $(LIBDIR)/
|
|
408
|
+
|
|
409
|
+
# Each recipe runs independently
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**Use cases:**
|
|
413
|
+
- Modular Makefiles with independent install steps
|
|
414
|
+
- Plugin systems
|
|
415
|
+
- Rarely needed
|
|
416
|
+
|
|
417
|
+
### Intermediate Files
|
|
418
|
+
|
|
419
|
+
```makefile
|
|
420
|
+
# Mark files as intermediate (deleted after use)
|
|
421
|
+
.INTERMEDIATE: $(OBJECTS)
|
|
422
|
+
|
|
423
|
+
# Keep specific intermediate files
|
|
424
|
+
.SECONDARY: important.o
|
|
425
|
+
|
|
426
|
+
# Never delete these intermediate files
|
|
427
|
+
.PRECIOUS: %.o
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Automatic Prerequisites
|
|
431
|
+
|
|
432
|
+
```makefile
|
|
433
|
+
# Generate dependencies automatically
|
|
434
|
+
DEPENDS := $(OBJECTS:.o=.d)
|
|
435
|
+
|
|
436
|
+
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
|
437
|
+
@mkdir -p $(@D)
|
|
438
|
+
$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@
|
|
439
|
+
|
|
440
|
+
# Include generated dependencies
|
|
441
|
+
-include $(DEPENDS)
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## Complete Examples
|
|
445
|
+
|
|
446
|
+
### Example 1: Simple C Project
|
|
447
|
+
|
|
448
|
+
```makefile
|
|
449
|
+
.DELETE_ON_ERROR:
|
|
450
|
+
|
|
451
|
+
CC ?= gcc
|
|
452
|
+
CFLAGS ?= -Wall -Wextra -O2
|
|
453
|
+
PREFIX ?= /usr/local
|
|
454
|
+
|
|
455
|
+
TARGET := hello
|
|
456
|
+
SOURCES := hello.c
|
|
457
|
+
OBJECTS := $(SOURCES:.c=.o)
|
|
458
|
+
|
|
459
|
+
.PHONY: all clean install uninstall help
|
|
460
|
+
|
|
461
|
+
## Build the program (default)
|
|
462
|
+
all: $(TARGET)
|
|
463
|
+
|
|
464
|
+
## Compile and link
|
|
465
|
+
$(TARGET): $(OBJECTS)
|
|
466
|
+
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
|
467
|
+
|
|
468
|
+
%.o: %.c
|
|
469
|
+
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
|
470
|
+
|
|
471
|
+
## Install to PREFIX
|
|
472
|
+
install: $(TARGET)
|
|
473
|
+
install -d $(DESTDIR)$(PREFIX)/bin
|
|
474
|
+
install -m 755 $(TARGET) $(DESTDIR)$(PREFIX)/bin/
|
|
475
|
+
|
|
476
|
+
## Remove installed files
|
|
477
|
+
uninstall:
|
|
478
|
+
$(RM) $(DESTDIR)$(PREFIX)/bin/$(TARGET)
|
|
479
|
+
|
|
480
|
+
## Remove built files
|
|
481
|
+
clean:
|
|
482
|
+
$(RM) $(OBJECTS) $(TARGET)
|
|
483
|
+
|
|
484
|
+
## Show this help
|
|
485
|
+
help:
|
|
486
|
+
@echo "Available targets:"
|
|
487
|
+
@sed -n 's/^## //p' $(MAKEFILE_LIST)
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Example 2: Multi-Directory Project
|
|
491
|
+
|
|
492
|
+
```makefile
|
|
493
|
+
.DELETE_ON_ERROR:
|
|
494
|
+
|
|
495
|
+
PROJECT := myapp
|
|
496
|
+
CC ?= gcc
|
|
497
|
+
CFLAGS ?= -Wall -Wextra -O2
|
|
498
|
+
PREFIX ?= /usr/local
|
|
499
|
+
|
|
500
|
+
SRCDIR := src
|
|
501
|
+
BUILDDIR := build
|
|
502
|
+
OBJDIR := $(BUILDDIR)/obj
|
|
503
|
+
|
|
504
|
+
SOURCES := $(wildcard $(SRCDIR)/*.c)
|
|
505
|
+
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
|
|
506
|
+
DEPENDS := $(OBJECTS:.o=.d)
|
|
507
|
+
TARGET := $(BUILDDIR)/$(PROJECT)
|
|
508
|
+
|
|
509
|
+
.PHONY: all clean install test help
|
|
510
|
+
|
|
511
|
+
## Build everything (default)
|
|
512
|
+
all: $(TARGET)
|
|
513
|
+
|
|
514
|
+
## Link executable
|
|
515
|
+
$(TARGET): $(OBJECTS)
|
|
516
|
+
@mkdir -p $(@D)
|
|
517
|
+
@echo " LD $@"
|
|
518
|
+
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
|
519
|
+
|
|
520
|
+
## Compile source files
|
|
521
|
+
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
|
522
|
+
@mkdir -p $(@D)
|
|
523
|
+
@echo " CC $<"
|
|
524
|
+
$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@
|
|
525
|
+
|
|
526
|
+
-include $(DEPENDS)
|
|
527
|
+
|
|
528
|
+
## Install to PREFIX
|
|
529
|
+
install: $(TARGET)
|
|
530
|
+
install -d $(DESTDIR)$(PREFIX)/bin
|
|
531
|
+
install -m 755 $(TARGET) $(DESTDIR)$(PREFIX)/bin/$(PROJECT)
|
|
532
|
+
|
|
533
|
+
## Run tests
|
|
534
|
+
test: $(TARGET)
|
|
535
|
+
@echo "Running tests..."
|
|
536
|
+
@$(TARGET) --test
|
|
537
|
+
|
|
538
|
+
## Remove build artifacts
|
|
539
|
+
clean:
|
|
540
|
+
$(RM) -r $(BUILDDIR)
|
|
541
|
+
|
|
542
|
+
## Show available targets
|
|
543
|
+
help:
|
|
544
|
+
@sed -n 's/^## //p' $(MAKEFILE_LIST)
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### Example 3: Library Project
|
|
548
|
+
|
|
549
|
+
```makefile
|
|
550
|
+
.DELETE_ON_ERROR:
|
|
551
|
+
|
|
552
|
+
PROJECT := mylib
|
|
553
|
+
VERSION := 1.0.0
|
|
554
|
+
CC ?= gcc
|
|
555
|
+
AR ?= ar
|
|
556
|
+
RANLIB ?= ranlib
|
|
557
|
+
PREFIX ?= /usr/local
|
|
558
|
+
|
|
559
|
+
SRCDIR := src
|
|
560
|
+
BUILDDIR := build
|
|
561
|
+
OBJDIR := $(BUILDDIR)/obj
|
|
562
|
+
|
|
563
|
+
SOURCES := $(wildcard $(SRCDIR)/*.c)
|
|
564
|
+
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
|
|
565
|
+
HEADERS := $(wildcard $(SRCDIR)/*.h)
|
|
566
|
+
|
|
567
|
+
STATIC_LIB := $(BUILDDIR)/lib$(PROJECT).a
|
|
568
|
+
SHARED_LIB := $(BUILDDIR)/lib$(PROJECT).so.$(VERSION)
|
|
569
|
+
|
|
570
|
+
.PHONY: all static shared clean install install-static install-shared
|
|
571
|
+
|
|
572
|
+
## Build both static and shared libraries
|
|
573
|
+
all: static shared
|
|
574
|
+
|
|
575
|
+
## Build static library
|
|
576
|
+
static: $(STATIC_LIB)
|
|
577
|
+
|
|
578
|
+
## Build shared library
|
|
579
|
+
shared: $(SHARED_LIB)
|
|
580
|
+
|
|
581
|
+
## Create static library
|
|
582
|
+
$(STATIC_LIB): $(OBJECTS)
|
|
583
|
+
@mkdir -p $(@D)
|
|
584
|
+
@echo " AR $@"
|
|
585
|
+
$(AR) rcs $@ $^
|
|
586
|
+
$(RANLIB) $@
|
|
587
|
+
|
|
588
|
+
## Create shared library
|
|
589
|
+
$(SHARED_LIB): $(OBJECTS)
|
|
590
|
+
@mkdir -p $(@D)
|
|
591
|
+
@echo " LD $@"
|
|
592
|
+
$(CC) -shared -Wl,-soname,lib$(PROJECT).so.1 $^ -o $@
|
|
593
|
+
ln -sf lib$(PROJECT).so.$(VERSION) $(BUILDDIR)/lib$(PROJECT).so.1
|
|
594
|
+
ln -sf lib$(PROJECT).so.1 $(BUILDDIR)/lib$(PROJECT).so
|
|
595
|
+
|
|
596
|
+
## Compile with -fPIC for shared library
|
|
597
|
+
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
|
598
|
+
@mkdir -p $(@D)
|
|
599
|
+
@echo " CC $<"
|
|
600
|
+
$(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -c $< -o $@
|
|
601
|
+
|
|
602
|
+
## Install both libraries
|
|
603
|
+
install: install-static install-shared
|
|
604
|
+
|
|
605
|
+
## Install static library
|
|
606
|
+
install-static: $(STATIC_LIB)
|
|
607
|
+
install -d $(DESTDIR)$(PREFIX)/lib
|
|
608
|
+
install -m 644 $(STATIC_LIB) $(DESTDIR)$(PREFIX)/lib/
|
|
609
|
+
install -d $(DESTDIR)$(PREFIX)/include/$(PROJECT)
|
|
610
|
+
install -m 644 $(HEADERS) $(DESTDIR)$(PREFIX)/include/$(PROJECT)/
|
|
611
|
+
|
|
612
|
+
## Install shared library
|
|
613
|
+
install-shared: $(SHARED_LIB)
|
|
614
|
+
install -d $(DESTDIR)$(PREFIX)/lib
|
|
615
|
+
install -m 755 $(SHARED_LIB) $(DESTDIR)$(PREFIX)/lib/
|
|
616
|
+
ln -sf lib$(PROJECT).so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/lib$(PROJECT).so.1
|
|
617
|
+
ln -sf lib$(PROJECT).so.1 $(DESTDIR)$(PREFIX)/lib/lib$(PROJECT).so
|
|
618
|
+
ldconfig
|
|
619
|
+
|
|
620
|
+
## Clean build artifacts
|
|
621
|
+
clean:
|
|
622
|
+
$(RM) -r $(BUILDDIR)
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
## Best Practices
|
|
626
|
+
|
|
627
|
+
1. **Use .PHONY for non-file targets**
|
|
628
|
+
2. **Implement standard GNU targets** (all, install, clean, test)
|
|
629
|
+
3. **Make 'all' the default target** (first target)
|
|
630
|
+
4. **Use automatic variables** ($@, $<, $^) for concise rules
|
|
631
|
+
5. **Create directories automatically** (@mkdir -p $(@D))
|
|
632
|
+
6. **Document targets with ## comments**
|
|
633
|
+
7. **Use static pattern rules** for better performance
|
|
634
|
+
8. **Include .DELETE_ON_ERROR** to prevent corrupted builds
|
|
635
|
+
9. **Use order-only prerequisites** for directory creation
|
|
636
|
+
10. **Generate dependencies automatically** (-MMD -MP)
|
|
637
|
+
|
|
638
|
+
## References
|
|
639
|
+
|
|
640
|
+
- [GNU Make Manual - Rules](https://www.gnu.org/software/make/manual/html_node/Rules.html)
|
|
641
|
+
- [GNU Make Manual - Phony Targets](https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html)
|
|
642
|
+
- [GNU Coding Standards - Standard Targets](https://www.gnu.org/prep/standards/html_node/Standard-Targets.html)
|