Skip to content

Instantly share code, notes, and snippets.

@ruittenb
Last active October 9, 2025 07:48
Show Gist options
  • Select an option

  • Save ruittenb/5d2d281237385276f49652b9b9f6d5a1 to your computer and use it in GitHub Desktop.

Select an option

Save ruittenb/5d2d281237385276f49652b9b9f6d5a1 to your computer and use it in GitHub Desktop.
Makefile target for automatically generating help
# This code automatically creates a table of Makefile targets and short descriptions.
# Descriptions should be added in the Makefile itself, as a '##' comment after the target:
##@ This is heading text, which will show up as a header
target1: prereq1 prereq2 ## This is comment text describing target1
target2: prereq1 \
prereq2 ## This is comment text describing target2
# The awk option '-v tab=10' can be changed to indent the second column of the output.
# readable version:
help2: ## print help for each target
@awk -v tab=10 ' \
function spout(target, comment) { printf indent color "%-" tab "s\033[0m%s\n", target, comment } \
function usage() { printf "\nUsage:\n make " color "<target>\033[0m\n\nRecognized targets:\n" } \
BEGIN { FS = fieldsep = ":.*## "; target = ""; color = "\033[36m"; indent = " "; usage() } \
/^[a-zA-Z0-9*%_.-]+:.*\\$$/ { gsub(/:.*/, ""); target = $$0; FS="## "; next } \
target && /\\$$/ { next } \
target && /## / { spout(target, $$2); FS = fieldsep; target = "" } \
/^[a-zA-Z0-9*%_.-]+:.*?## / { pad = sprintf("\n%" tab "s" indent, "", $$2); gsub(/\\n/, pad); spout($$1, $$2) } \
/^##@ / { gsub(/\\n/, "\n"); printf "\n%s\n", substr($$0, 5) } \
END { print "" } \
' $(MAKEFILE_LIST) # v1.44
# concise version:
.PHONY: help
help: ## print help for each target
@awk -v tab=10 'function spout(target, comment) { printf indent color "%-" tab "s\033[0m%s\n", target, comment } function usage() { printf "\nUsage:\n make " color "<target>\033[0m\n\nRecognized targets:\n" } BEGIN { FS = fieldsep = ":.*## "; cont = ""; color = "\033[36m"; indent = " "; usage() } /^[a-zA-Z0-9*%_.-]+:.*\\$$/ { gsub(/:.*/, ""); cont = $$0; FS="## "; next } cont && /\\$$/ { next } cont && /## / { spout(cont, $$2); FS = fieldsep; cont = "" } /^[a-zA-Z0-9*%_.-]+:.*?## / { pad = sprintf("\n%" tab "s" indent, "", $$2); gsub(/\\n/, pad); spout($$1, $$2) } /^##@ / { gsub(/\\n/, "\n"); printf "\n%s\n", substr($$0, 5) } END { print "" }' $(MAKEFILE_LIST) # v1.44
.DEFAULT_GOAL:=help
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment