|
| 1 | +# Makefile Targets Guide |
| 2 | + |
| 3 | +This guide explains how to add and document Makefile targets so they show up in `make help` and stay consistent across the project. |
| 4 | + |
| 5 | +## Principles |
| 6 | + |
| 7 | +- Each user-facing target must have a short description line immediately above it using `##`. |
| 8 | +- Further detailed descriptions can be added between the `##` summary and `.PHONY:` declaration using `#`. |
| 9 | +- Every target that users can invoke should be declared `.PHONY`. |
| 10 | +- Keep names concise and action-oriented (build, test, format, generate, publish). |
| 11 | +- Group related targets under the existing sections: Setup, Building, Testing, Formatting, Generating, Publishing. |
| 12 | + |
| 13 | +## Anatomy of a target |
| 14 | + |
| 15 | +```make |
| 16 | +## Build App target for latest iOS Simulator (iPhone 16 Pro) |
| 17 | +.PHONY: build-ios-app |
| 18 | +build-ios-app: |
| 19 | + set -o pipefail && NSUnbufferedIO=YES xcrun xcodebuild -project Flinky.xcodeproj -scheme App -destination 'platform=iOS Simulator,OS=latest,name=iPhone 16 Pro' build | tee raw-build-ios-app.log | xcbeautify --preserve-unbeautified |
| 20 | +``` |
| 21 | + |
| 22 | +- The `##` line is the description consumed by `make help`. |
| 23 | +- The `.PHONY:` line declares the target as phony. |
| 24 | +- The recipe lines must start with a tab. |
| 25 | + |
| 26 | +## Multi-target descriptions |
| 27 | + |
| 28 | +You can apply one description to multiple targets by listing them on the `.PHONY:` line. Each will appear in `make help` with the same description: |
| 29 | + |
| 30 | +```make |
| 31 | +## Format Swift, Markdown, JSON and YAML files using project tools |
| 32 | +.PHONY: format format-swift format-json format-markdown format-yaml |
| 33 | +``` |
| 34 | + |
| 35 | +Or, if you need different descriptions, declare each target in its own block with its own `##` line. |
| 36 | + |
| 37 | +## Ensure your target appears in `make help` |
| 38 | + |
| 39 | +`make help` parses the Makefile by looking for: |
| 40 | + |
| 41 | +1. A description line starting with `##` |
| 42 | +2. Optional detail lines starting with `#` right below the summary (rendered indented) |
| 43 | +3. The following `.PHONY:` line to extract target names |
| 44 | + |
| 45 | +That means: |
| 46 | + |
| 47 | +- Put the `##` description immediately above the `.PHONY:` line. |
| 48 | +- Avoid blank lines between the `##` line and `.PHONY:` if possible. |
| 49 | +- Include all user-facing targets in `.PHONY:` lines. |
| 50 | + |
| 51 | +You can verify your additions with: |
| 52 | + |
| 53 | +```bash |
| 54 | +make help |
| 55 | +``` |
| 56 | + |
| 57 | +The help output dynamically aligns columns regardless of target name length. |
| 58 | + |
| 59 | +## Style guidelines |
| 60 | + |
| 61 | +- Prefer imperative verbs: build-, test-, format-, generate-, publish-. |
| 62 | +- Keep descriptions short (one sentence). |
| 63 | +- Use consistent simulator destination strings for iOS build/test targets. |
| 64 | +- Log to `raw-*.log` and pipe through `xcbeautify` for Xcode output. |
| 65 | +- When shell options improve reliability, include them (e.g., `set -o pipefail`). |
| 66 | + |
| 67 | +## Common pitfalls |
| 68 | + |
| 69 | +- Missing `##` line: the target won’t show up in `make help`. |
| 70 | +- Missing `.PHONY:`: the target can be shadowed by a file of the same name. |
| 71 | +- Spaces instead of a tab at the start of a recipe line cause make errors. |
| 72 | +- Description too far above or separated from `.PHONY:`: the parser won’t match it. |
| 73 | +- Duplicating the same target name in multiple `.PHONY:` lines: only the last one is used. |
| 74 | + |
| 75 | +## Examples |
| 76 | + |
| 77 | +Setup with dependencies broken into subtasks: |
| 78 | + |
| 79 | +```make |
| 80 | +## Setup the project by installing dependencies, pre-commit hooks, rbenv, and bundler. Also runs the generate command. |
| 81 | +# |
| 82 | +# This command sets up everything needed to develop the project. |
| 83 | +.PHONY: setup |
| 84 | +setup: install-dependencies install-pre-commit install-rbenv install-bundler generate |
| 85 | + |
| 86 | +## Install the project dependencies using Homebrew. |
| 87 | +.PHONY: install-dependencies |
| 88 | +install-dependencies: |
| 89 | + brew bundle |
| 90 | + git submodule update --init --recursive |
| 91 | +``` |
| 92 | + |
| 93 | +Generate tasks: |
| 94 | + |
| 95 | +```make |
| 96 | +## Generate licenses, settings version, and localization assets |
| 97 | +.PHONY: generate |
| 98 | +generate: generate-licenses generate-version-in-settings generate-localization |
| 99 | + |
| 100 | +## Generate localized strings from xcstrings via script |
| 101 | +.PHONY: generate-localization |
| 102 | +generate-localization: |
| 103 | + ./Scripts/generate-localization.sh |
| 104 | +``` |
| 105 | + |
| 106 | +Testing: |
| 107 | + |
| 108 | +```make |
| 109 | +## Run unit tests for App scheme on latest iOS Simulator |
| 110 | +.PHONY: test-ios-app |
| 111 | +test-ios-app: |
| 112 | + set -o pipefail && NSUnbufferedIO=YES xcrun xcodebuild -project Flinky.xcodeproj -scheme App -destination 'platform=iOS Simulator,OS=latest,name=iPhone 16 Pro' test | tee raw-test-ios-app.log | xcbeautify --preserve-unbeautified |
| 113 | +``` |
| 114 | + |
| 115 | +Multi-line example (details appear in `make help`, shown under the target without indentation): |
| 116 | + |
| 117 | +```make |
| 118 | +## Lint the migration directory |
| 119 | +# |
| 120 | +# Lints the migration directory to ensure that the migrations are valid. |
| 121 | +# This is useful to catch any issues with the migrations before applying them. |
| 122 | +.PHONY: migrate-lint |
| 123 | +migrate-lint: |
| 124 | + atlas migrate lint \ |
| 125 | + --dir="file://ent/migrate/migrations" \ |
| 126 | + --latest=10 \ |
| 127 | + --dev-url="docker://postgres/17/dev?search_path=public" |
| 128 | +``` |
| 129 | + |
| 130 | +## Review checklist |
| 131 | + |
| 132 | +- Did I add a `##` description above each new `.PHONY:` target? |
| 133 | +- Does the description clearly explain the action? |
| 134 | +- Do recipe lines start with tabs? |
| 135 | +- Do the target and section names match the project’s conventions? |
| 136 | +- Does `make help` display the new targets aligned and categorized? |
| 137 | + |
| 138 | +If all answers are “yes”, your target is ready. 🎯 |
0 commit comments