There have been a number of reports recently of problems with the installroot option of PEAR. First, it was reported that a PEAR installation done at an installroot didn't actually work at all. This is because the pearcmd.php script sets the include_path to a known value: the location of PEAR at installation time. However, if installroot was set, this was being set to a non-existent directory.
For instance, if PEAR is installed at /usr/local/lib/php, with an installroot of /path/to/installroot, the proper include_path would be:
/path/to/installroot/usr/local/lib/php
this is how installroot works. However, it was being improperly set to:
/usr/local/lib/php
which causes a fatal error at the first require_once, breaking the pear command completely. Therefore, this was fixed in version 1.4.0a1.
However, there have been a number of reports of people using the installroot option on unix to package up PEAR in distributions of PHP, such as the ever-popular RPM format. As it is a generally bad idea to do things as the root user that do not directly involve installation or configuration of some kind, these users were using the installroot option to install PEAR in a local directory and then copying the files created into the RPM for packaging.
Unfortunately, this relies upon the afore-mentioned bug in PEAR 1.3.6 and earlier, and so scripts that have been working for ages suddenly stop working. This is not a good thing.
For people wishing to distribute PEAR 1.4.x, there are two possible solutions, one for PHP versions earlier than 5.1, and one for PHP 5.1 and newer. For earlier PHP versions, the best thing to do is to perform these steps:
- install PEAR using installroot option, just as you always have
- ALSO bundle up the install-pear.php file from pear-core at cvs.php.net
- Use a %post option and run the CLI version of php on install-pear.php like so:
- %post
php install-pear.php -d %{_libdir}/php/pear -b %{_bindir} - Use a %postun option to erase the contents of PEAR via:
- %postun
pear uninstall -n --ignore-errors PEAR
rm -rf %{_libdir}/php/pear
the %post option will create all needed files, and the %postun option will cleverly erase binary PEAR files (like the pear command, pecl command, etc.) and then remove all other pear files.
The instructions for PHP 5.1 and newer are similar:
- Grab install-pear.phar from http://pear.php.net/install-pear.phar
- Use a %post option and run the CLI version of php on install-pear.phar like so:
- %post
php install-pear.phar -d %{_libdir}/php/pear -b %{_bindir} - Use a %postun option to erase the contents of PEAR via:
- %postun
pear uninstall -n --ignore-errors PEAR
rm -rf %{_libdir}/php/pear
As you can see, the second option is a lot simpler from a packaging perspective, but it is quite similar from step 3 on. If you are using 1 script to bundle several different PHP versions, the first option will also work with earlier versions, but you will need to first grab the contents of pear-core/ and overwrite php-src/pear with these contents, as PEAR 1.3.6 is the bundled PEAR version for PHP 5.0.x and earlier.
I promised an open question, so here it is:
Does anyone actually USE installroot in order to install PHP or PEAR into a directory that they intend to use it from Was the original behavior actually a bug, or was the bug in the documentation of installroot Although the steps above will work regardless of the contents of installroot (a good thing), in the interest of correctness, I have to know the answer about this. If the installroot option is only used by people packaging up RPMs and ebuilds and such, then the current behavior is a bug.
Thanks for any feedback.