Fakeroot to obsolete DESTDIR
After running into yet two more problems with staged installs ala DESTDIR,
I was reminded of an idea I originally had for fink packages.
... but, let's begin from the beginning.
Why is DESTDIR a problem?
1: libtool cannot relink inter-dependent libraries during a staged install.
2: some upstream packages don't provide any means for relocated installation
... probably others, but these are the two I ran into again today.
On the topic of 1, cvs libtool can do this with an undocumented command-line
flag. However, it still prefers the installed location over the staged
location. So, if you link to -L/.../debian/tmp/usr/lib -lfoo, a libfoo.so in
/usr/lib is prefered, which can cause subtle problems.
Furthermore, libtool has been custom hacked in so many source packages, that
it is not feasible to simply replace ltmain.sh as we do for config.* in
autoconf. Thus, we are stuck with the old libtool + spinoffs for some time.
These problems in libtool can be solved by hacking the ltmain.sh or .la
files by hand, which afaik is what everyone does. This compounds the problem
In regards to 2, if everyone used automake, this would not be a problem.
However, many projects do not use automake, and some of them are even
correct in this decision. So, sometimes we have no DESTDIR.
Often, people end up having to search through all the Makefiles injecting
DESTDIR in various locations, hopefully catching them all. This makes large
.diff files which are problematic to maintain.
Other times, the build system doesn't use Makefiles at all, but bash
scripts, jam, ant, perl or others. In each of these cases, a special
solution must be hand-crafted by the packager in a potentially error-prone
Now, I admit the above problems are not fatal given the amount of man-power
at debian's disposal. In fact, our current solution---hand hacking---does
work fairly well.
What I would like to propose is simply a way to reduce the effort by
allowing plain 'make install' to work without changing the build scripts.
As we all know, fakeroot intercepts stat/chown/chmod/etc. We do this so that
users can install files into a staged location and preserve the correct
What I propose to do is to slightly extend fakeroot to also intercept
open/diropen. If the open call would create a file, redirect it to
/.../debian/tmp or some such location. If the call would open a file, first
check /.../debian/tmp and then /.
To illustrate this, lets take an example: (here libbar depends on libfoo)
libtool install libfoo.la /usr/lib/libfoo.la
libtool install libbar.la /usr/lib/libbar.la
The first install relinks libfoo.la against /lib/libc.so.6.
So, fakeroot intercepts ld's open, checks for /.../debian/tmp/lib/libc.so.6
and doesn't find it. Then it tries /lib/libc.so.6 and finds it, so provides
this file handle.
Then fakeroot intercepts ld's output open for /usr/lib/libfoo.la, it
redirects this to /.../debian/tmp/usr/lib/libfoo.la. Hence, the library is
installed in the staging location transparently.
Next, libbar.la is installed.
fakeroot correctly prefers /.../debian/tmp/usr/lib/libfoo.la to
/usr/lib/libfoo.la in the case it was already installed. The output is also
So, here we have libtool working seamlessly because fakeroot redirected it.
... the beauty of this solution is that it is simple and common. This would
allow us to always install with the package's default install rule and have
magic look after all that nasty stuff.
The interface I propose is to add two new fakeroot options
If --outputdir is specified, then it is always prepended to the searchdir
option. When a new file is created, outputdir is the location really used.
When a file is opened, outputdir:searchdir is consulted.
On of the fringe benefits of this is that fink packages don't have to modify
the debian packages much; simply add /sw before / in the search path.
What I am looking for is comments about whether people think this is useful,
suggestions on how to make it as simple/easy-to-use as possible, and a list
of which libc functions needs to be trapped.
Presently, I think libfakeroot.so just needs to trap open/diropen and maybe
a few others, faked needs to keep track of the search/outputdir parameters,
and fakeroot has to pass the above options to faked. diropen requires some
extra work to merge the directory listings, but I think this is doable.