[OpenAFS-devel] avoiding make rules with multiple targets

Benjamin Kaduk kaduk@MIT.EDU
Tue, 19 Feb 2013 19:10:21 -0500 (EST)


We've had a few commits over the years to help parallel builds along by 
splitting rules with two targets into two separate rules, one a pure 
dependency and the other with the actual contents of the rule (usually 
compile_et).

A typical example is 147aeeb6c59b5f4a9f8a795a91e0c42ecf80278c 
(gerrit/257) (trimmed):
-budb_errs.c budb_client.h: budb_errs.et budb_client.p.h
+budb_client.h: budb_errs.c
+
+budb_errs.c: budb_errs.et budb_client.p.h
         $(RM) -f budb_client.h budb_errs.c; ${COMPILE_ET} -p ${srcdir} budb_errs -h budb_client

However, these changes seem to cause problems for FreeBSD make, even for 
serial builds.  The build log shows a failure to install budb_client.h , 
No such file or directory, but then continues on to compile linktest 
before bailing out (sorry for the poorly wrapped copy/paste):

install  -o root -g wheel -m 444 JUAFS/libjuafs.a 
/usr/ports/net/openafs/work/openafs-1.6.2/lib/libjuafs.a
install  -o root -g wheel -m 444 UAFS/libuafs.a 
/usr/ports/net/openafs/work/openafs-1.6.2/lib/libuafs.a
case amd64_fbsd_91 in 
alpha_dux*|sgi_*|sun4x_*|sunx86_*|rs_aix*|*linux*|hp_ux11*|ia64_hpux*|*_darwin_1*|*nbsd*|*obsd*|*fbsd*) 
cd src && cd shlibafsauthent && make all ;;  *)  echo Not building shared 
libafsauthent for amd64_fbsd_91 ;;  esac
install  -o root -g wheel -m 444 budb_client.h 
/usr/ports/net/openafs/work/openafs-1.6.2/include/afs/budb_client.h
install: budb_client.h: No such file or directory
*** [/usr/ports/net/openafs/work/openafs-1.6.2/include/afs/budb_client.h] 
Error code 71
cc -g -O -I/usr/ports/net/openafs/work/openafs-1.6.2/src/config 
-I/usr/ports/net/openafs/work/openafs-1.6.2/include -I. -I.  -O2 -pipe 
-fPIC   -c budb_errs.c
[ yes != "" ] || case amd64_fbsd_91 in 
alpha_dux*|sgi_*|sun*_5*|rs_aix*|*linux*|hp_ux11*|ia64_hpux*|*[nof]bsd*) 
cd src && cd tptserver && make all ;;  *_darwin_[1-6][0-9])  echo Not 
building MT ptserver for amd64_fbsd_91 ;;  *_darwin_*)  cd src && cd 
tptserver  && make all ;;  *)  echo Not building MT ptserver for 
amd64_fbsd_91 ;;  esac



The make debugging output is not immediately enlightening, but provides 
some hints.

budb_server (???) depends on ${TOP_INCDIR}/afs/budb_client.h depends on 
budb_client.h depends on budb_errs.c depends on budb_errs.et. Yet 
budb_errs.c has been generated from the rule for budb_errs.h 
(${COMPILE_ET} -p ${srcdir} budb_errs) and is up-to-date, so make's 
internal bookkeeping sees the empty rule to make budb_client.h from 
budb_errs.c, claims succes (I don't see this in the debugging log, 
though?!) and tries to install the header.

The problem seems to stem from there being two calls to compile_et using 
budb_errs.et, one of which makes budb_errs.h and the other which makes 
budb_client.h.  Swapping the order in which the multiple targets are split 
out, so that budb_errs.c depends on budb_client.h which is made via 
compile_et, lets my build finish here, but it's probably not the best 
solution.

Is there reason to not make a budb_client.h that is the contents of 
budb_client.p.h with #include <budb_errs.h> added?  Alternately we could 
process the template manually with the shell.

[tbudb has the same issue]

-Ben