Subject: Re: help help2man to find iwhd

From: Jim Meyering <[email-masked]>
Date: Thu, 04 Aug 2011 11:17:32 +0200

Pete Zaitcev wrote:
> I have a problem that I'm failing to solve.
>
> If "make distcheck" is ran on a freshly-cloned iwhd repo, just after the
> configuring it, the following happens:
...
>
> But the above causes this to happen:
>
> $ sh autogen.sh
> $ ./configure
> $ make distcheck
> ............
> checking where the gettext function comes from... libc
> configure: creating ./config.status
> config.status: creating Makefile
> config.status: creating gnulib-tests/Makefile
> config.status: creating lib/Makefile
> config.status: error: cannot find input file: `man/Makefile.in'
>
> So, what to do?

Life is already short enough ;-)
I simply insert a "make" before the "make distcheck":

    $ sh autogen.sh
    $ ./configure
    $ make && make distcheck

However, I took a look at the generated Makefile.in and conclude that
there's an automake weakness when we use Makefile.am's SUBDIRS variable
to kludge dependencies by specifying "." not at the end of the list.

Notice how iwhd's Makefile.am is careful to list "." before "man"
in the SUBDIRS list:

    SUBDIRS = lib . gnulib-tests t man po

With normal "recursive" rules, that ensures that iwhd is built
in "." before the binary is needed by help2man in man/.

However, the problem is that while all of automake's so-called
RECURSIVE_TARGETS handle that special case of "." as expected, the
"distdir" rule does not.  The distdir rule is at the core of what
is run when you do "make distcheck", and it merely skips ".".

Then I thought "Hey, use the "dist*-hook" mechanism!".
Unfortunately, that doesn't work, either, since "."
is simply skipped in this "distdir:" loop.  The hook
is run only after all subdirs have been processed:

      @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
      if test "$$subdir" = .; then :; else \
        dir1=$$subdir;
        ...
      fi
      $(MAKE) $(AM_MAKEFLAGS) \
          top_distdir="$(top_distdir)" distdir="$(distdir)" \
          dist-hook

Contrast that with how it's done for RECURSIVE_TARGETS:
(here, the position of "." in SUBDIRS *is* honored):

$(RECURSIVE_TARGETS):
	@fail= failcom='exit 1'; \
	for f in x $$MAKEFLAGS; do \
	  case $$f in \
	    *=* | --[!k]*);; \
	    *k*) failcom='fail=yes';; \
	  esac; \
	done; \
	dot_seen=no; \
	target=`echo $@ | sed s/-recursive//`; \
	list='$(SUBDIRS)'; for subdir in $$list; do \
	  echo "Making $$target in $$subdir"; \
	  if test "$$subdir" = "."; then \
	    dot_seen=yes; \
	    local_target="$$target-am"; \
	  else \
	    local_target="$$target"; \
	  fi; \
	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
	  || eval $$failcom; \
	done; \
	if test "$$dot_seen" = "no"; then \
	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
	fi; test -z "$$fail"

-------------------------------------------------------
In case you're wondering why this is not a problem for other
projects, at least for some, it's because they put programs
in a sub-directory (often named src/), and so it works fine.
No need to special-case ".".