Is there a way to write "standard" comments in a Makefile to later feed them to a Doxygen-like program so as to output a nice (HTML or man for instance) documentation ? I'd like to have a clear overview of my main targets somewhere but nothing too fancy.
7 Answers
The following is a simpler solution that does not require defining user functions or aggregating help text away from the rules they document.
# This is a regular comment, that will not be displayed
## ----------------------------------------------------------------------
## This is a help comment. The purpose of this Makefile is to demonstrate
## a simple help mechanism that uses comments defined alongside the rules
## they describe without the need of additional help files or echoing of
## descriptions. Help comments are displayed in the order defined within
## the Makefile.
## ----------------------------------------------------------------------
help: ## Show this help.
@sed -ne '/@sed/!s/## //p' $(MAKEFILE_LIST)
build: ## Build something.
install: ## Install something.
deploy: ## Deploy something.
format: ## Help comments are display with their leading whitespace. For
## example, all comments in this snippet are aligned with spaces.
Running make
or make help
results in the following:
----------------------------------------------------------------------
This is a help comment. The purpose of this Makefile is to demonstrate
a simple help mechanism that uses comments defined alongside the rules
they describe without the need of additional help files or echoing of
descriptions. Help comments are displayed in the order defined within
the Makefile.
----------------------------------------------------------------------
help: Show this help.
build: Build something.
install: Install something.
deploy: Deploy something.
format: Help comments are display with their leading whitespace. For
example, all comments in this snippet are aligned with spaces.

- 3,287
- 24
- 27
-
6This is brilliant. But take care copying it, those indented lines **MUST USE TABS**. See https://stackoverflow.com/questions/16931770/makefile4-missing-separator-stop – Peter Lada Nov 03 '21 at 03:09
-
To make the help text align properly add `| column -tl 2` to the `@sed` command – balki Jul 28 '22 at 00:45
-
@balki can u please show full command with `| column -tl ` ? – Demetry Pascal May 20 '23 at 09:57
-
1@DemetryPascal ` @sed -ne '/@sed/!s/## //p' $(MAKEFILE_LIST) | column -tl 2` See: https://gitea.balki.me/balki/makepac/src/branch/main/Makefile#L10 – balki May 31 '23 at 17:47
In a makefile such as :
install: ## Do a
@echo "foo"
start: ## Do b
@echo "bar"
test: ## Do c
@echo "baz"
help:
@egrep -h '\s##\s' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m %-30s\033[0m %s\n", $$1, $$2}'
Will output :

- 2,619
- 4
- 20
- 27
-
-
This looks really nice, thanks! I tried to replace the hardcoded colors with `tput setaf 3`, but didn't manage to. – Eric Duminil May 14 '22 at 20:35
-
1This has a shortcoming when the Makefile includes other makefiles, because the grep result changes to be `Makefile:target: ## docs`. It can be fixed by changing the awk separator to `FS = ":[^:]*?## "` – Amnon Jun 24 '22 at 09:44
I made my own solution using a short Perl script that formats the help as other GNU tools:
SCRIPT_VERSION=v1.0
SCRIPT_AUTHOR=John Doe
all: ##@Build Build all the project
clean: ##@Cleaning Remove all intermediate objects
mrproper: clean ##@Cleaning Remove all output and interemediate objects
HELP_FUN = \
%help; while(<>){push@{$$help{$$2//'options'}},[$$1,$$3] \
if/^([\w-_]+)\s*:.*\#\#(?:@(\w+))?\s(.*)$$/}; \
print"$$_:\n", map" $$_->[0]".(" "x(20-length($$_->[0])))."$$_->[1]\n",\
@{$$help{$$_}},"\n" for keys %help; \
help: ##@Miscellaneous Show this help
@echo -e "Usage: make [target] ...\n"
@perl -e '$(HELP_FUN)' $(MAKEFILE_LIST)
@echo -e "Written by $(SCRIPT_AUTHOR), version $(SCRIPT_VERSION)"
@echo -e "Please report any bug or error to the author."
Which gives this:
$ make help
Usage: make [target] ...
Miscellaneous:
help Show this help
Build:
all Build all the project
Cleaning:
clean Remove all intermediate objects
mrproper Remove all output and interemediate objects
Written by John Doe, version v1.0
Please report any bug or error to the author.

- 25,978
- 39
- 143
- 293
-
1A little improvement to the HELP_FUN bit: replace `if/^(\w+)\s*:` with `if/^([\w-_]+)\s*:` in order to allow targets of the type "this-target" or "that_target" as well. – th3n3rd Aug 16 '16 at 08:40
-
This is fantastic! How could it be extended to allow for multi-line descriptions? – James Burton Jan 13 '23 at 16:59
-
@nowox Can u please change the function to return results as sorted? – Demetry Pascal May 20 '23 at 10:30
One nice touch is to provide a phony help
target that prints a summary of targets and options. From the Linux kernel Makefile
:
help:
@echo 'Cleaning targets:'
@echo ' clean - Remove most generated files but keep the config and'
@echo ' enough build support to build external modules'
@echo ' mrproper - Remove all generated files + config + various backup files'
@echo ' distclean - mrproper + remove editor backup and patch files'
@echo ''
@echo 'Configuration targets:'
@$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
@echo ''
It might be a bit of work to maintain the documentation this way, but I find it nicely separates what is intended for "users" versus what is intended for people maintaining the Makefile
itself (inline comments).

- 102,305
- 22
- 181
- 238
-
Maybe I am not patient enough but I doubt there's anything else besides what you mentionned. Many thanks !! – J.N. Jan 18 '12 at 05:37
-
If you want some sort of automated stuff take a look at [make-help](https://github.com/gibatronic/make-help). – gibatronic Mar 04 '16 at 00:47
Self-Documenting Makefiles (John Graham-Cumming, 2005) lets you write the help alongside each rule. This is a lightweight and highly nifty solution that works at least with GNU Make.
Here's my slightly modified version (def-help-section helps organize long lists of rules).

- 2,278
- 1
- 18
- 21
Here is my version that also strips away the dependencies of a target and aligns the help strings to an even column.
help: ## Show this help.
@sed -ne 's/^\([^[:space:]]*\):.*##/\1:\t/p' $(MAKEFILE_LIST) | column -t -s $$'\t'
image: src/*.s src/*.c src/**/*.c ## Build the image
riscv32-unknown-elf-gcc $^ -march=rv32i_zicsr -Wall -ggdb -O0 -o image -ffreestanding -nostdlib -lgcc
launch: ## Image Launch the image in renode
renode --net vexriscv.resc --console
Output
help: Show this help.
image Build the image
launch: Image Launch the image in renode

- 936
- 10
- 19