blog(8) System
Manager's Manual blog(8)
Dynamic Makefiles on OpenBSD
The make(1) command on OpenBSD allows you to define rules at runtime. This is to help make up for the fact that it does not support wildcard targets with the same flexibility as GNUUUUU Make. Here's what this looks like in practice:
# Find all section 1 manual entries in the current dir man_pages != find . -type f -name "*.1" # Turn each manual path into a path for an html page web_pages = ${man_pages:S/$/.html/} # By default, build all the web pages build_all: $(web_pages) # Since we do not have GNU-style wildcards, we generate # a rule to build each web page .for p in $(man_pages) $p.html: $p mandoc -T html $p > $@ .endfor
Why not use Inference Rules?
For a simple example like this, we can accomplish the same thing
with
Inference
Rules. Inference rules allow you to specify how files of one suffix can
be transformed into files with a different suffix (for example, compiling
‘.o
’ files from
‘.c
’ files.) Here's what this same
Makefile would look like with inference rules:
# Find all section 1 manual entries in the current dir man_pages != find . -type f -name "*.1" # Turn each manual path into a path for an html page web_pages = ${man_pages:S/$/.html/} # By default, build all the web pages build_all: $(web_pages) .SUFFIXES: .1 .html # Transform ".1" (mdoc) files to html .1.html: mandoc -T html $p > $@
3p
’ is fine, because Perl is gross):
# Find all UNIX manual entries, regardless of section man_pages != find . -type f -name "*.[[:digit:]]" ...
.SUFFIXES: .1 .2 .3 .4 .5 .6 .7 .8 .9 .html # Transform ".1" (mdoc) files to html .1.html: mandoc -T html $p > $@ # Transform ".2" (mdoc) files to html .2.html: mandoc -T html $p > $@ # Transform ".3" (mdoc) files to html .3.html: mandoc -T html $p > $@ ...
# Find all UNIX manual entries, regardless of section man_pages != find . -type f -name "*.[[:digit:]]" # Turn each manual path into a path for an html page web_pages = ${man_pages:S/$/.html/} # Build all the web pages build_all: $(web_pages) # Generate a recipe for each man page, regardless of section .for p in $(man_pages) $p.html: $p mandoc -T html $p > $@ .endfor
2025-05-21
Robert D. French