Pages: Welcome | Projects

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:

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.