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 above. 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 manner. 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 permissions. 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) make install 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 staged. 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 --outputdir /.../debian/tmp --searchdir /sw:/ 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. --- Wes