objdir build: Normalize COMPILE_ET_* commands
authorAndrew Deason <adeason@sinenomine.net>
Thu, 14 Aug 2014 20:13:48 +0000 (15:13 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Sat, 22 Aug 2015 14:50:01 +0000 (10:50 -0400)
commit899f8eaf3f63b1f91fe6b6eb8f582f82bd10cb66
treebcd26638ba75dda5d98713770772e86d24ad1c08
parent4e05184264bf1c0d54e20741563ba9dadc2ef522
objdir build: Normalize COMPILE_ET_* commands

A few different places in the tree currently invoke compile_et in a
few different ways. These three general styles all appear:

    ${COMPILE_ET_H} -p ${srcdir} foo
    ${COMPILE_ET_H} -p ${srcdir} foo.et
    ${COMPILE_ET_H} ${srcdir}/foo.et

Of these, the first is the correct way to invoke compile_et in a
Makefile. The other two can fail during at least some objdir builds.

Take this example of the second style of invocation:

    afs_trace.h: afs_trace.et
            ${COMPILE_ET_H} -v 2 -p ${srcdir} afs_trace.et

During an objdir build, the compile_et command will get expanded like
so, due to VPATH expansion:

    $top_objdir/src/comerr/compile_et -emit h -v 2 \
        -p $top_srcdir/src/afs \
        $top_srcdir/src/afs/afs_trace.et

The compile_et command concatenates the -p prefix with the actual
filename provided, so the file it tries to open is:

    $top_srcdir/src/afs/$top_srcdir/src/afs/afs_trace.et

For non-objdir builds this doesn't happen, since $srcdir is just '.',
and afs_trace.et gets expanded to just afs_trace.et (or possibly
./afs_trace.et). This is also not a problem for objdir builds that are
specified as a relative path and are 'adjacent' to the srcdir. For
example, if we ran '../openafs-1.6.10pre1/configure --options', our
$top_srcdir is just '../openafs-1.6.10pre1', with some magic to
expand '..' to the correct number of levels. So in the above example,
the compile_et invocation gets expanded to:

    /path/to/objdir/src/comerr/compile_et -emit h -v 2 \
        -p ../../../openafs-1.6.10pre1/src/afs \
        ../../../openafs-1.6.10pre1/src/afs/afs_trace.et

And compile_et then tries to open the path
../../../openafs-1.6.10pre1/src/afs/../../../openafs-1.6.10pre1/src/afs/afs_trace.et
which collapses to just
../../../openafs-1.6.10pre1/src/afs/afs_trace.et, which is the correct
file.

However, if the $srcdir is specified as an absolute path, or if the
number of '..'s is wrong, this doesn't work. It is perhaps easiest to
explain why by just using another example. For an absolute path, the
invoked command is:

    /path/to/objdir/src/comerr/compile_et -emit h -v 2 \
        -p /path/to/openafs-1.6.10pre1/src/afs \
        /path/to/openafs-1.6.10pre1/src/afs/afs_trace.et

And compile_et tries to open
/path/to/openafs-1.6.10pre1/src/afs/path/to/openafs-1.6.10pre1/src/afs/afs_trace.et,
which obviously does not exist. This results in a build failure like:

    /path/to/openafs-1.6.10pre1/src/afs/path/to/openafs-1.6.10pre1/src/afs/afs_trace.et: No such file or directory
    *** Error code 1
    make: Fatal error: Command failed for target `afs_trace.msf'

For a non-working relative objdir, we may invoke a command like this:

    /path/to/objdir/src/comerr/compile_et -emit h -v 2 \
        -p ../../../../openafs-1.6.10pre1/src/afs \
        ../../../../openafs-1.6.10pre1/src/afs/afs_trace.et

And compile_et tries to open
../../../../openafs-1.6.10pre1/src/afs/../../../../openafs-1.6.10pre1/src/afs/afs_trace.et,
which is ../../../../../openafs-1.6.10pre1/src/afs/afs_trace.et, which
(probably) doesn't exist, since it goes one too many levels up.

To avoid this, we can just prevent the filename argument to compile_et
from undergoing VPATH expansion. compile_et never opens the given path
directly if -p is given, so it's not really a file path and so should
not be altered by VPATH.

compile_et will add a trailing .et to the filename if it doesn't have
one, so we can avoid the VPATH expansion by just leaving out the
trailing .et. We could also avoid the VPATH expansion by specifying
something like './afs_trace.et', but it is perhaps more clear to not
say the explicit filename, since we're not really specifying a path to
a file.

Just leaving out the -p option, as in this style of compile_et
invocation:

    dumpscan_errs.h: ${srcdir}/dumpscan_errs.et
        $(COMPILE_ET_H) ${srcdir}/dumpscan_errs.et

also fails for objdir builds. This is because, without the -p option,
compile_et defaults to '.' as the prefix. If the srcdir is
/path/to/openafs-1.6.10pre1, then this will expand to:

    /path/to/objdir/src/comerr/compile_et -emit h \
        .//path/to/openafs-1.6.10pre1/src/tools/dumpscan/dumpscan_errs.et

which will fail, since that path to dumpscan_errs.et does not exist.

So to fix this, make all compile_et invocations follow this style:

    ${COMPILE_ET_H} -p ${srcdir} foo

Many other invocations of compile_et in the tree are already like
this, so this commit just changes the others to match.

Change-Id: Ied12e07a1cc6e115d4a10cd7a6c97aae9ce7f5f9
Reviewed-on: http://gerrit.openafs.org/11391
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
src/afs/Makefile.in
src/libadmin/adminutil/Makefile.in
src/tools/dumpscan/Makefile.in