Replacing binaries with dpkg-divert
Posted by Steve on Wed 6 Apr 2005 at 19:36
One of the strengths of the Debian system is the way in which it deals with having multiple similar packages installed, and allowing you to choose which one you use.
We already discussed one way in which Debian allows you to choose a specific package from a number of available options in the piece using the Debian alternatices system.
Another possibility is to replace a binary installed from a package with one of your own choosing, Debian allows this via the use of the dpkg-divert command.
The dpkg-divert command allows you to replace a binary installed upon the system, and have this replacement persist even if you upgrade packages.
One common reason to do this is if you're using a mailserver such as qmail, and you wish to replace the file /usr/lib/sendmail with the version from that package. In this case making a diversion is a good solution.
Another example where you might wish to replace a package's binary is in the case of the gcc, or g++, compiler commands.
Assuming that you were keen on rebuilding Debian packages and wished to ensure that some optimizations were applied. Rather than patch the Makefile, or build scripts you could just replace the compiler command to ensure that your options were applied globally.
(This is what the pentium-builder package does, incidently).
To replace a packages binary you have to:
- Rename the file that you're replacing.
- Add the diversion to the system.
Both these steps can be achieved with one command. For example assume we wish to replace the gcc command to cause it to add "-O2" to all compilation jobs we'd run the following command as root:
dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc
This adds a diversion to the file /usr/bin/gcc, causing that binary to be renamed to /usr/bin/gcc.real.
Now whenever we upgrade the gcc package the system will know that it shouldn't overwrite the gcc binary, instead the new package will have it's binary installed as gcc.real.
Now that we've done that we can create a simple shell script with the name gcc which will add our option, and invoke the real compiler:
#!/bin/sh /usr/bin/gcc.real -O2 $*
This script invokes the real compiler, with all the options we've been passed and the new option "-O2".
If we wish to remove this diversion at a future point in time we can use:
# Remove the script we added rm /usr/bin/gcc # Remove the diversion, renaming /usr/bin/gcc.real back to /usr/bin/gcc dpkg-divert --rename --remove /usr/bin/gcc
You can also list all the diversions which you have currently installed with:
dpkg-divert --list
Fully Hosted AntiSpam & AntiVirus
Fully managed SPAM & Virus filtering of your incoming Email.
OTOH, inserting USE flags in this way seems like a hackish solution, but as long it gives some means to make "from source" debian aka debtoo, is ok with me.
[ Parent | Reply to this comment ]
Yes, Debian's great, except when it's not...
[ Parent | Reply to this comment ]
/usr/bin/gcc.real -O2 "$@"instead of
/usr/bin/gcc.real -O2 $*$* can defeate quoting of parameters with spaces and globs in them... I.e. if you have a file "simple program.c", "$@" will pass it on properly, while $* will result in two parameters -- 'simple' and 'program.c'.
This becomes more of a problem as code is exchanged with the windows and mac universes where spaces in filenames are more common.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
--add --rename --divert
What are the different permutations? ie, what else can the tool do?
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
You're probably right. Although reading the manpage will show you all the arguments and what they do. I'll bear it in mind for future articles.
[ Parent | Reply to this comment ]
Fully Hosted AntiSpam & AntiVirus
Fully managed SPAM & Virus filtering of your incoming Email.