Subject: bug#31157: Advice for help2man does not work for parallel builds

From: Mathieu Lirzin <[email-masked]>
Date: Sun, 22 Apr 2018 11:28:51 +0200

Reuben Thomas <[email-masked]> writes:

> On 21 April 2018 at 16:13, Mathieu Lirzin <[email-masked]> wrote:
>
>  Reuben Thomas <[email-masked]> writes:
>
>  > In the manual, we are given the following pattern for using help2man
>  > without breaking make distcheck:
>  >
>  > foo.1: foo.c $(top_srcdir)/configure.ac
>  > $(MAKE) $(AM_MAKEFLAGS) foo$(EXEEXT)
>  > help2man --output=foo.1 ./foo$(EXEEXT)
>  >
>  > The problem is that with make -j this can result in two attempts to
>  > make a library in parallel (suppose that we have:
>  >
>  > foo_LDADD = libfoo.la
>  > lib_LTLIBRARIES = libfoo.la
>  >
>  > ). This can fail, and in any case is wasteful.
>
>  Have you identified the reason why this can fail? because 
>
> ​Because two independent parallel invocations of make ​can end up trying
> to build the library (which is wasteful anyway) and some needed file
> can be deleted by one invocation when the other is trying to use it to
> link the library.

Makes sense.

>  This is not ideal since this result in making ‘help2man’ (and ‘perl’
>  transitively) a build dependency for tarball builders.
>
> ​I'm increasingly of the view this is not a problem. Perl is
> increasingly reasonable as a build dep (it seems to be in most base
> systems now), and help2man is small.

In term of convenience for end users, I agree this is often a harmless
issue.  However having been involved in GNU Guix for awhile I think it
is important to avoid accidental dependencies to improve the simplicity
of the bootstrapping process of our systems [1][2].

>  $(srcdir)/foo.1: foo.c foo$(EXEEXT)
>  -@case '$?' in \
>  *foo.c*) 
>  ​​$(AM_V_P) && set -x || echo " HELP2MAN $@"; \
>  LANGUAGE= help2man --output="$(srcdir)/foo.1" ./foo$(EXEEXT);; \
>  *) : ;; \
>  esac;
>
> Nice! The one thing I don't understand: why is "-" needed at the start
> (i.e. why do we need to ignore failure of this command?).

I don't recall exactly the reason Guix added it, I guess it was to allow
the build to "succeed" even if the man pages generation failed since
that doesn't impact the software to run.  However I am not sure if it's
a good idea.

> Combining the above with what I originally posted, I get:
>
> beetle.1: tbl_opts.h beetle$(EXEEXT)
> ## Exit gracefully if beetle.1 is not writeable, such as during distcheck!
> @if ( touch $@.w && rm -f $@.w; ) >/dev/null 2>&1; then \

IIUC this case silently ignores when the ‘beetle.1’ is not distributed,
which doesn't seem desirable for ‘make distcheck’, no?
     
> case '$?' in \
> *tbl_opts.h*) $(AM_V_P) && set -x || echo " HELP2MAN $@"; \
> $(top_srcdir)/build-aux/missing --run $(HELP2MAN) --no-info \
> --name="Forth virtual machine" \
> --output=$@ ./beetle$(EXEEXT);; \
> *) : ;; \
> esac; \
> fi

[1] https://www.gnu.org/software/guix/manual/html_node/Bootstrapping.html
[2] http://bootstrappable.org/

-- 
Mathieu Lirzin
GPG: F2A3 8D7E EB2B 6640 5761  070D 0ADE E100 9460 4D37