2

I'm using autoconf and automake to build a tiny project.

For the project's manual, I've used OpenBSD's native mdoc format, and the installable man-formatted manual is generated from this using the mandoc utility. The man-formatted manual will be installed as the actual manual with make install, as some systems do not grok mdoc properly, or at all.

In the project's doc directory, I have a Makefile.am file that currently looks like the following (the manual is for a utility called shell):

dist_man1_MANS= shell.man
EXTRA_DIST=     shell.mdoc

shell.man:      shell.mdoc
        $(mandoc) -T man shell.mdoc >shell.man

$(mandoc) will be properly expanded to the full path of the mandoc formatter (this variable is set by the configure script).

This allows me to run make dist which creates shell.man and then creates a compressed tar archive containing both the source mdoc manual and the generated man manual along with the rest of the project's distribution files:

$ tar tzf shell-toolbox-20180401.tar.gz
...
shell-toolbox-20180401/doc/Makefile.am
shell-toolbox-20180401/doc/shell.man
shell-toolbox-20180401/doc/Makefile.in
shell-toolbox-20180401/doc/shell.mdoc

This tar archive can later be used to successfully build and install the project, and its manual. So far so good.

However, if I run make distcheck (because I'd like to make sure it absolutely positively works):

$ make distcheck
...
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/local/bin/gmkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for mandoc... /usr/bin/mandoc
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating doc/Makefile
config.status: creating src/shell
Making all in src
Making all in doc
/usr/bin/mandoc -T man shell.mdoc >shell.man
mandoc: shell.mdoc: ERROR: No such file or directory
*** Error 3 in shell-toolbox-20180401/_build/sub/doc (Makefile:459 'shell.man')
*** Error 1 in shell-toolbox-20180401/_build/sub (Makefile:345 'all-recursive')
*** Error 1 in /home/myself/local/build/shell-toolbox (Makefile:576 'distcheck')

It seems as if the source mdoc file is not available in the build directory when the manual needs to be built:

$ ls shell-toolbox-20180401/_build/sub/doc
total 32
-rw-r--r--  1 myself  myself  14989 Apr  1 21:35 Makefile
-rw-r--r--  1 myself  myself      0 Apr  1 21:35 shell.man

The zero-length shell.man file comes from the failed mandoc run.

The source is available in the unpacked archive, but just not copied over to the _build/sub/doc directory:

$ ls -l shell-toolbox-20180401/doc
total 48
-r--r--r--  1 myself  myself   178 Apr  1 21:23 Makefile.am
-r--r--r--  1 myself  myself 13925 Apr  1 21:23 Makefile.in
-r--r--r--  1 myself  myself  3443 Apr  1 21:27 shell.man
-r--r--r--  1 myself  myself  3319 Apr  1 18:54 shell.mdoc

Question: What automake magic do I have to apply to get make distcheck to properly copy the mdoc source to the build directory before it attempts to generate the man-formatted manual? I'm looking for a "proper" way of doing this, not a hack.

I tried using

man1_SOURCES= shell.mdoc

but that makes automake complain with

doc/Makefile.am:2: warning: variable 'man1_SOURCES' is defined but no program or
doc/Makefile.am:2: library has 'man1' as canonical name (possible typo)

Another way to provoke this error is to manually do a VPATH build (which is basically what's happening when doing make distcheck):

$ make distclean
$ mkdir t
$ cd t

$ ../configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/local/bin/gmkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for mandoc... /usr/bin/mandoc
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating doc/Makefile
config.status: creating src/shell

$ make
Making all in src
Making all in doc
/usr/bin/mandoc -T man shell.mdoc >shell.man
mandoc: shell.mdoc: ERROR: No such file or directory
*** Error 3 in doc (Makefile:459 'shell.man')
*** Error 1 in /home/myself/local/build/shell-toolbox/t (Makefile:345 'all-recursive')

$ ls -l doc
total 32
-rw-r--r--  1 myself myself 14589 Apr  1 22:42 Makefile
-rw-r--r--  1 myself myself     0 Apr  1 22:42 shell.man
0

automake supports -local and -hook rules that get run before and after some of the various targets. There is apparently no distcheck-local so another idea would be in your Makefile.am to use the dist-hook to run something after the dist:

dist-hook:
        cp something $(distdir)/somewhere
  • Unfortunately, this only copies the before the distribution archive is created. When the actual build happens, the file is not in the _build/sub/doc directory. – Kusalananda Apr 1 '18 at 20:43
0

Solution: To properly pick up the source for the manual when performing a VPATH build, the rule for it in the relevant part of the Makefile.am file should look like

shell.man:      $(srcdir)/shell.mdoc
        $(mandoc) -T man $(srcdir)/shell.mdoc >shell.man

By specifying $(srcdir)/shell.mdoc, make will find the file in the distribution tree even when the build tree is in a different location from the distribution tree.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.