Manpages in GNU Autotools
2018/8/29
Tags: [ autotools ] [ C & C++ ] [ Hacking ] [ Personal Projects ]This is a followup of yesterday's entry about manpages. After choosing Asciidoc for the purpose and doing the writing, it is time to have the manpages compiled and distributed. This is not difficult to achieve, but the process involved a bit of forward thinking.
Everything boils down to dependencies: by using Asciidoc (or any other tool, for what it matters) we get to depend on another software package. This may not sound like a big deal, but minimality is the one silver bullet to keep complexity at bay.
The itch begun when I noticed how this dependency is actually a weak one:
lacking of the tool for compiling the manual (a2x
) does not prevent the
whole software from being compiled, in the same way as lacking a manual does
not prevent the software from running.
I started to consider the idea of having a conditional build, so that the build system detects the availability of the required tool and compiles the manpages only if possible:
The
configure.ac
script checks the availability and defines theASCIIDOC_AVAIL
condition:AC_CHECK_PROG([asciidoc], [a2x], [a2x], [false]) AM_CONDITIONAL([ASCIIDOC_AVAIL], [test x$asciidoc != xfalse])
the
man/Makefile.am
file uses theASCIIDOC_AVAIL
condition to have a conditional build of manpages:if ASCIIDOC_AVAIL man1_MANS = foo.1 man5_MANS = foo.conf.5 foo.1: foo.1.txt $(asciidoc) --doctype manpage --format manpage ./$< foo.conf.5: foo.conf.5.txt $(asciidoc) --doctype manpage --format manpage ./$< clean: rm $(man1_MANS) $(man5_MANS) endif
With this approach the weak dependency is handled as such, but the resulting package will be obviously orphan of the manual.
Testing
At this point I went for a little manual test on the target system. I usually work under Fedora, but for this project I'd like to target with priority Debian 9 (Stretch), as this is what my Raspberry PI runs.
I fired up a Docker container running Debian, and started to verify the
detection of the various dependencies (or lack thereof). After adding one
dependency at the time, I was able to make sure that the configure
script
works properly.
Eventually I could compile the program, so I went for a test of the
manpages generation department, which was so far disabled due to the missing
asciidoc
package.
When installing the asciidoc-base
package with apt
I forgot to enable the
--no-install-recommends
flag, ending up in quite a lot of dependencies,
(inclusive of pieces of graphical environment!):
0 upgraded, 248 newly installed, 0 to remove and 0 not upgraded.
Need to get 1121 MB of archives.
After this operation, 1928 MB of additional disk space will be used.
Do you want to continue? [Y/n]
Even if this was more a mistake than an actual problem (asciidoc-base
strictly requires only 15 packages), it made me think about providing a
pre-compiled version of the manpages, so that I could maintain asciidoc
completely optional. Is it possible to compile the manual as part of the
distribution tarball?
Pre-compilation is supported
I asked some help on StackOverflow, and as it turns out it
is definitely possible, and actually supported through the dist_
prefix in
Automake.
The same happens for those projects relying on Yacc/Bison for the implementation of custom languages: as mentioned by this answer, the GNU Automake manual (section 8.8) specifically says:
The intermediate files generated by yacc (or lex) will be included in any distribution that is made. That way the user doesn’t need to have yacc or lex.
Actually, the whole software distribution made with Autotools is meant to be compiled without depending on Autotools! Not a big surprise, after all.
I think it's worth noting how this whole idea of pre-compiling some parts of the source code can have good effects on package management systems like RPM or DEB. Having a pre-compiled manual avoids in fact to declare a build dependency on the needed tools. This for sure results in a faster build. Moreover, if the packager really wants to re-generate them (perhaps because of a patch) then the source code is still available in the pristine tarball. It is really about adding a build dependency!
Conclusions
Thanks to this answer, I was able to wrap up the following
Makefile.am
dist_man1_MANS = foo.1
dist_man5_MANS = foo.conf.5
EXTRA_DIST = foo.1.txt foo.conf.5.txt
if ASCIIDOC_AVAIL
foo.1: foo.1.txt
$(asciidoc) --doctype manpage --format manpage ./$<
foo.conf.5: foo.conf.5.txt
$(asciidoc) --doctype manpage --format manpage ./$<
endif
CLEANFILES = $(dist_man1_MANS) $(dist_man5_MANS)
The resulting distribution tarball contains a pre-compiled set of manpages,
which would get removed by a make clean
. They can be compiled again with a
make
, provided that the configure
script detected the availability of
a2x
.