# Add the following 'help' target to your Makefile | |
# And add help text after each target name starting with '\#\#' | |
help: ## Show this help. | |
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' | |
# Everything below is an example | |
target00: ## This message will show up when typing 'make help' | |
@echo does nothing | |
target01: ## This message will also show up when typing 'make help' | |
@echo does something | |
# Remember that targets can have multiple entries (if your target specifications are very long, etc.) | |
target02: ## This message will show up too!!! | |
target02: target00 target01 | |
@echo does even more |
This comment has been minimized.
This comment has been minimized.
This is great! Thanks for sharing it. Here's a modified help: ## This help dialog.
@IFS=$$'\n' ; \
help_lines=(`fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//'`); \
for help_line in $${help_lines[@]}; do \
IFS=$$'#' ; \
help_split=($$help_line) ; \
help_command=`echo $${help_split[0]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \
help_info=`echo $${help_split[2]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \
printf "%-30s %s\n" $$help_command $$help_info ; \
done
# Everything below is an example
target00: ## This message will show up when typing 'make help'
@echo does nothing
target01: ## This message will also show up when typing 'make help'
@echo does something
# Remember that targets can have multiple entries (if your target specifications are very long, etc.)
target02: ## This message will show up too!!!
target02: target00 target01
@echo does even more will respond with:
|
This comment has been minimized.
This comment has been minimized.
Thanks to the both of you for providing this. |
This comment has been minimized.
This comment has been minimized.
I've made a version using only awk (tested on OS X, but possible works on gawk too). I also moved the help message just before the task - so you don't need to declare the target multiple times: |
This comment has been minimized.
This comment has been minimized.
Very nice idea. I modified it with a small Perl script that support categories:
The output is this:
|
This comment has been minimized.
This comment has been minimized.
This is awesome! I wanted ANSI colors so ... help: ## This help dialog.
@IFS=$$'\n' ; \
help_lines=(`fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##/:/'`); \
printf "%-30s %s\n" "target" "help" ; \
printf "%-30s %s\n" "------" "----" ; \
for help_line in $${help_lines[@]}; do \
IFS=$$':' ; \
help_split=($$help_line) ; \
help_command=`echo $${help_split[0]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \
help_info=`echo $${help_split[2]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \
printf '\033[36m'; \
printf "%-30s %s" $$help_command ; \
printf '\033[0m'; \
printf "%s\n" $$help_info; \
done
target: ## Does absolutely nothing!
exit 0
|
This comment has been minimized.
This comment has been minimized.
This is great stuff. Can you declare a licence, so I can use it in good conscience? |
This comment has been minimized.
This comment has been minimized.
@nowox I know this gist is quite old but I liked your solution. I just had to make a small modification and wanted to share
HELP_FUNC = \
%help; \
while(<>) { \
if(/^([a-z0-9_-]+):.*\#\#(?:@(\w+))?\s(.*)$$/) { \
push(@{$$help{$$2}}, [$$1, $$3]); \
} \
}; \
print "usage: make [target]\n\n"; \
for ( sort keys %help ) { \
print "$$_:\n"; \
printf(" %-20s %s\n", $$_->[0], $$_->[1]) for @{$$help{$$_}}; \
print "\n"; \
} |
This comment has been minimized.
This comment has been minimized.
Here's my take:
# Needed SHELL since I'm using zsh
SHELL := /bin/bash
.PHONY: help
# Add the following 'help' target to your Makefile
# And add help text after each target name starting with '\#\#'
help: ## This help message
@echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)"
# Everything below is an example
target00: ## This message will show up when typing 'make help'
@echo does nothing
target01: ## This message will also show up when typing 'make help'
@echo does something
# Remember that targets can have multiple entries (if your target specifications are very long, etc.)
target02: ## This message will show up too!!!
target02: target00 target01
@echo does even more |
This comment has been minimized.
This comment has been minimized.
If anyone is interested, I wrote a package for that: make-help The following # generate all assets
build: scripts styles
# show some help
help:
echo
echo ' Usage:'
echo ' make <target>'
echo
echo ' Targets:'
make-help -p 4 "$(lastword $(MAKEFILE_LIST))"
echo
# generete scripts
scripts:
...
# generete styles
styles:
... Will output this when
|
This comment has been minimized.
This comment has been minimized.
@nowox version with colors and repair targets with
|
This comment has been minimized.
This comment has been minimized.
Any way to make this support targets created with templates? |
This comment has been minimized.
This comment has been minimized.
@caylorme you need to modify fragment |
This comment has been minimized.
This comment has been minimized.
I'm starting to use the following: .PHONY: help
help: ## Show this help message.
echo 'usage: make [target] ...'
echo
echo 'targets:'
egrep '^(.+)\:\ ##\ (.+)' ${MAKEFILE_LIST} | column -t -c 2 -s ':#' |
This comment has been minimized.
This comment has been minimized.
Would somebody help on how to make the entire help that is in multiple lines show up aligned with first line of help associated with the target? Example: For below make file content
Desired output: |
This comment has been minimized.
This comment has been minimized.
@nowox |
This comment has been minimized.
This comment has been minimized.
reference above and others, updated to Colorful and usable syntax:
then above target use
will generate for latest makefile pls refer my: Makefile |
This comment has been minimized.
This comment has been minimized.
Thanks for these tips on Here is my Makefile for C/C++ development. |
This comment has been minimized.
This comment has been minimized.
Hi @muhmi, I try your solution in Ubuntu but I get this error
you know what could be the reason? |
This comment has been minimized.
This comment has been minimized.
Wow, these are great I did something similar in ludicrous-makefiles (here and here), which handles multiple lines of help text for each target and also generate a prologue from any comments not directly associated with a target (I used @crifan I particularly like the readability and conciseness of your awk! For some reason it truncates targets by 1 character for me on ubuntu:18.04 (using 19c19
< helpCommand = substr($$1, 0, index($$1, ":")-1); \
---
> helpCommand = $$1; sub(/:$$/, "", helpCommand); \ |
This comment has been minimized.
This comment has been minimized.
no perl, grouping per @label_with_some_description
|
This comment has been minimized.
This comment has been minimized.
I'm now using the following based on the post of @hans-d. It doesn't have the grouping feature, but does have multi-line doc strings. Features
Output $ make help
-- Section Delimiter --
help This help message
Which can also be multiline
-- QA Task Runners --
lint Run linter
test Run unit and integration tests
|
This comment has been minimized.
This comment has been minimized.
I'm using version from here, it works great but I would like to support also templates. I tried to modify Makefile .DEFAULT_GOAL:=help
##@ Build
.PHONY: build
build: ## build something
@echo "Bulding..."
##@ Clean
.PHONY: clean
cache: ## clean something
@echo "Cleaning..."
define template =
##@ Section $(2)
.PHONY: $(1)-foo
$(1)-foo: ## Foo $(2)
@echo "Doing $(2)-foo..."
.PHONY: $(1)-bar
$(1)-bar: ## Bar $(2)
@echo "Doing $(2)-bar..."
endef
$(eval $(call template,a,Apple))
$(eval $(call template,l,Linux))
.PHONY: help
help:
@awk 'BEGIN {FS = ":.*##"; printf "Usage: make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) Current output Usage: make <target>
Build
build build something
Clean
cache clean something
Section $(2) Needed output Usage: make <target>
Build
build build something
Clean
cache clean something
Section Apple
a-foo Foo Apple
a-bar Bar Apple
Section Linux
l-foo Foo Linux
l-bar Bar Linux Is there someone who can help? |
This comment has been minimized.
This comment has been minimized.
@o5, simple regex for makefile eval is not enough, you must use recurrent makefile with |
This comment has been minimized.
This comment has been minimized.
This gist totally "triggered" me and kickstarted all my gizmos quite some time back - thank you so much for it! Also thanks to @lordnynex and @HarasimowiczKamil for your comments. Sorry it took me some years to comment here but better later than never ;-) I took the idea a bit further and puzzled together some other bits and pieces (e.g. including variables) - have a look at https://github.com/25th-floor/docker-make-stub ... Feedback is highly appreciated! |
This comment has been minimized.
This comment has been minimized.
First go for a single line version.. fully awk.. place this at the end of your make file. it will print all recipes.
to yield
some issues in removing the ":" and "##" as well as trying to get colours for the menu item. otherwise its quite usable. this way is much faster as it does not loop and try to modify each line. |
This comment has been minimized.
This comment has been minimized.
You don't need this whole pipeline. One sed is enough: help: ##- Show this help.
@sed -e '/#\{2\}-/!d; s/\\$$//; s/:[^#\t]*/:/; s/#\{2\}- *//' $(MAKEFILE_LIST) Comments on this alternative:
|
This comment has been minimized.
This comment has been minimized.
Golfing here. One
|
This comment has been minimized.
This comment has been minimized.
It works nicely. You might want to make a minor improvement: @fgrep -h "##" $(MAKEFILE_LIST) | sed -e 's/\(\:.*\#\#\)/\:\ /' | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' This will print only the targets without their dependencies. all: Runs the tests and builds the binary deliverable of the project using cython.
clean: Cleans all the intermediate files and folders previously generated.
compile-proto: Compiles the models protocol buffer files and gRPC stubs.
prereqs: Installs all the prerequisites for this project.
test: Runs all the available tests for this project.
cythonize: Builds a binary deliverable using Cython. |
This comment has been minimized.
This comment has been minimized.
Single line with formating help: ## Show this help
@egrep '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' Example from here https://stackoverflow.com/questions/35730218/how-to-automatically-generate-a-makefile-help-command |
This comment has been minimized.
This comment has been minimized.
Can someone here help me get a
|
This comment has been minimized.
This comment has been minimized.
@muuvmuuv have a look if you can get something going here: https://awk.js.org/ |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@muuvmuuv If you look at the link @WarFox posted (https://stackoverflow.com/questions/35730218/how-to-automatically-generate-a-makefile-help-command), there's an example there that might work for you.
Adjusted for the AWK web REPL - https://awk.js.org/?gist=238f6158b3673074ee92edc93eb84a91 ... produces when using the
|
This comment has been minimized.
This comment has been minimized.
I used the suggestion from @o5 with my makefile and it looks awesome to me
|
This comment has been minimized.
This comment has been minimized.
Small buglet. Need to add |
This comment has been minimized.
This comment has been minimized.
Is it crazy enough to show the Makefile help via Docker? This is exactly what I did. # Show this help
help:
@cat $(MAKEFILE_LIST) | docker run --rm -i xanders/make-help Source: https://github.com/Xanders/make-help Screenshot: |
This comment has been minimized.
This comment has been minimized.
A slight improvement on a few preceding: help: ## show help message
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
test: ## plain
$dollar: ## leading dollar
percent%: ## percent included
(paren): ## parenthesis
$(both): ## both
space : ## space before colon
note: Not shown here: the targets are colored. |
This comment has been minimized.
This comment has been minimized.
This updated expression still fails to find targets with numbers in the name. I think you need
|
This comment has been minimized.
Output will be:
help: Show this help.
target00: This message will show up when typing 'make help'
target01: This message will also show up when typing 'make help'
target02: This message will show up too!!!