DEV Community

Alex Bender
Alex Bender

Posted on

Makefile with help message

The Makefile

The idea is pretty simple: Add comment to each target from Makefile
Here is the clean target from makefile:

clean:
    rm -f *.o
Enter fullscreen mode Exit fullscreen mode

Help message here is redundant but in sake of completeness let's add it:

clean: ## Clean directory
    rm -f *.o
Enter fullscreen mode Exit fullscreen mode

Now we need filter out all docstrings: here is the command for that:

ag '^[a-zA-Z_-]+:.*?## .*$$' --nofilename Makefile \
| sort \
| awk 'BEGIN{FS=": ## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
Enter fullscreen mode Exit fullscreen mode

Here I'm using silver-searcher aka ag.
Seems complicated, yeah? So what does that command do?

  • filters out lines basing on this regular expression: '^[a-zA-Z_-]+:.*?## .*$$', namely any string like "target_name: ##doc string".
  • sorts output with command sort
  • formats output with awk command BEGIN{FS=": ## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}

Let's look at that command. What do we have?

  • BEGIN{FS=": ## "}
  • {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}

    From the documentation: A BEGIN rule is executed once only, before the first input record is read. So it simply reads input and sets the Field separator to ": ##" to split input on two parts: before and after the FS.

    Second part just prints filtered output with formatting and colors.

One more thing -- we have to define default target to be executed when make command launched without arguments:
.DEFAULT_GOAL := help
Now we are ready.

Here is what we have as a result:

Save that gist into Makefile and run make command in your terminal from the folder with Makefile. If everything is ok you will get formatted and colored output: all targets defined in Makefile:

$ make
clean                          Clean directory
help                           Help target
Enter fullscreen mode Exit fullscreen mode

Dependencies

But aware that awk and silver-searcher are required for that snippet to work.
(Btw, ag could be replaced with grep, if needed with some modifications I guess.)

And remember -- documentation's important!

Oldest comments (2)

Collapse
 
adambrandizzi profile image
Adam Brandizzi

Nice trick :D

Collapse
 
vikbert profile image
Xun Zhou

you are also able to extend the help: declaration to group the task with a defined title. See the example on dev.to/vikbert/best-practice-makef...