Last active
August 18, 2024 02:17
-
-
Save ernstki/982edcfbf93c357bdb09878f7c724389 to your computer and use it in GitHub Desktop.
Auto-generated 'make help' from comments on Makefile targets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TITLE = A Makefile that makes its own 'make help' target | |
ME = $(lastword $(MAKEFILE_LIST)) | |
HOMEPAGE = https://gist.github.com/ernstki/982edcfbf93c357bdb09878f7c724389/edit | |
help: # prints this help | |
@bash -c "$$AUTOGEN_HELP_BASH" < $(ME) | |
define AUTOGEN_HELP_BASH | |
declare -A targets; declare -a torder | |
targetre='^([A-Za-z]+):.* *# *(.*)' | |
if [[ $$TERM && $$TERM != dumb && -t 1 ]]; then | |
ul=$$'\e[0;4m'; bbold=$$'\e[34;1m'; reset=$$'\e[0m' | |
fi | |
if [[ -n "$(TITLE)" ]]; then | |
printf "\n %sMakefile targets - $(TITLE)%s\n\n" "$$ul" "$$reset" | |
else | |
printf "\n %sMakefile targets%s\n\n" "$$ul" "$$reset" | |
fi | |
while read -r line; do | |
if [[ $$line =~ $$targetre ]]; then | |
target=$${BASH_REMATCH[1]}; help=$${BASH_REMATCH[2]} | |
torder+=("$$target") | |
targets[$$target]=$$help | |
if (( $${#target} > max )); then max=$${#target}; fi | |
fi | |
done | |
for t in "$${torder[@]}"; do | |
printf " %smake %-*s%s %s\n" "$$bbold" $$max "$$t" "$$reset" \ | |
"$${targets[$$t]}" | |
done | |
if [[ -n "$(HOMEPAGE)" ]]; then | |
printf "\n Homepage:\n $(HOMEPAGE)\n\n" | |
else | |
printf "\n" | |
fi | |
endef | |
export AUTOGEN_HELP_BASH | |
# vim: ft=make |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This replaces an earlier Perl version I'd been using for years, but I started thinking, hey, Bash can do all that. It's about ten lines longer than the Perl version, but possibly more readable.
Usage
Add your targets after the provided
help
target, because they'll be printed in the order they appear in the file, not sorted. (Although if you wanted them sorted, to implement that would be straightforward.) Shove that bunch of Bash script to the bottom of the file and forget about it.If you want help for a target, put a comment after it, on the same line, like this:
Then run
make help
or justmake
(as long as you leave it at the top, it's the default target). Easy peasy.If you don't want a target to appear in the output of
make help
, don't put a comment on the same line as the target name:Put your comment above or below instead, if you need to document it internally.
Other tips
If you wanted, for example,
build
to be the default target instead ofhelp
, use.DEFAULT_GOAL
for that:Bugs
The regexp is supposed to ignore any dependencies for the target, and it's a bug if it doesn't.
As written, would not support multiple targets in a single rule.
There are double quotes in the definition of
AUTOGEN_HELP_BASH
, which is itself double-quoted when passed tobash -c
. Frankly I'm astonished that this worked. I suppose Make itself is taking care of the escaping under the hood, but I still have a feeling that somewhere this will eventually go wrong, and require some more attention. If you get in some kind of trouble with this, as long as the quotes are only for display purposes, just use curly quotes instead; e.g.for a US keyboard layout on macOS, or,
assuming RAlt is your Compose key on Linux.
Feedback welcome.
License
WTFPL, or ISC at your discretion.