Friday, August 28, 2009

Cent os php source rpm 5.2

SkyHi @ Friday, August 28, 2009
Here at EchoDitto, most of our servers are running CentOS Linux, which is a 100% binary-compatible version of the industry standard Red Hat Enterprise Linux (RHEL) without any of the fees. The problem with RHEL/CentOS is that they shipped with PHP 5.1.6, and as of this writing PHP is at 5.2.9. That's not a big deal, being a minor point revision behind, until you come across an application or module that needs a minimum of version 5.2. The last thing I want to do is install packages from a third-party or build it from source and risk breaking other packages. So what's the answer? Building it from the source rpm. There's no better way to keep the system free of third-party packages but also up to date.

Why source RPMs and not the source from PHP? Building a source RPM is the same procedure used to build the packages that Red Hat creates, and includes the libraries and dependencies and sub-packages that you would normally get from Red Hat directly. It will also include all of the same build flags in your new version that were available in the older package, meaning your PHP scripts won't suddenly break. This ultimately ensures binary compatibility and the ability to easily upgrade if Red Hat or CentOS were to release a package newer than yours.

Sure, you could enable the CentOS Testing repository, but with all of the warnings about packages breaking your system, and configuring yum to only update PHP and not mess up mysql or Apache, I'd rather build and install only the packages that I need without worrying about breaking other packages. Want PHP 5.2 on your CentOS or RHEL server? Follow along.

1. Start by downloading the latest PHP 5.2 source RPM from the aforementioned CentOS Testing repository from http://dev.centos.org/centos/5/testing/SRPMS/. As of this writing, they're at php-5.2.6-2. Why aren't we using the 5.1.6 source? The source RPM for 5.2.6 includes the latest patches from Red Hat that you can normally only get from being a part of the non-free Red Hat Network.

I'll assume you're running as root for this guide. Download the source RPM with wget

# wget http://dev.centos.org/centos/5/testing/SRPMS/php-5.2.6-2.el5s2.src.rpm

2. Install the source RPM

# rpm -ivh php-5.2.6-2.el5s2.src.rpm

3. If you get an error and the install fails, you may need to manually create the SOURCES directory and install again

# mkdir -p /usr/src/redhat/SOURCES
# rpm -ivh php-5.2.6-2.el5s2.src.rpm

4. Download the latest stable release of PHP from the php.net download page and save it in the SOURCES folder. Change the version number to the latest version if needed.

# cd /usr/src/redhat/SOURCES
# wget http://us3.php.net/get/php-5.2.9.tar.gz/from/us.php.net/

5. In the SPECS folder, copy the original php.spec file in case you make mistakes or wish to build 5.2.6.

# cd /usr/src/redhat/SPECS
# cp php.spec php526.spec

6. Edit php.spec and change the version and revision numbers to be 5.2.9 (or later) and the revision to 1 since this is your first build.

Summary: The PHP HTML-embedded scripting language
Name: php
Version: 5.2.9
Release: 1%{?dist}
License: PHP
Group: Development/Languages
URL: http://www.php.net/

7. Make sure you have the Development Tools group install for rpmbuild if you haven't already done so.

# yum groupinstall "Development Tools"

8. Try and build the spec file to see if you are missing any packages. For this tutorial, I am running from the minimal package set.

# rpmbuild -ba php.spec
cat: /usr/include/httpd/.mmn: No such file or directory
error: Failed build dependencies:
bzip2-devel is needed by php-5.2.9-1.i386
curl-devel >= 7.9 is needed by php-5.2.9-1.i386
db4-devel is needed by php-5.2.9-1.i386
expat-devel is needed by php-5.2.9-1.i386
gmp-devel is needed by php-5.2.9-1.i386
aspell-devel >= 0.50.0 is needed by php-5.2.9-1.i386
httpd-devel >= 2.0.46-1 is needed by php-5.2.9-1.i386
libjpeg-devel is needed by php-5.2.9-1.i386
libpng-devel is needed by php-5.2.9-1.i386
pam-devel is needed by php-5.2.9-1.i386
openssl-devel is needed by php-5.2.9-1.i386
sqlite-devel >= 3.0.0 is needed by php-5.2.9-1.i386
zlib-devel is needed by php-5.2.9-1.i386
pcre-devel >= 6.6 is needed by php-5.2.9-1.i386
readline-devel is needed by php-5.2.9-1.i386
krb5-devel is needed by php-5.2.9-1.i386
libc-client-devel is needed by php-5.2.9-1.i386
cyrus-sasl-devel is needed by php-5.2.9-1.i386
openldap-devel is needed by php-5.2.9-1.i386
mysql-devel >= 4.1.0 is needed by php-5.2.9-1.i386
postgresql-devel is needed by php-5.2.9-1.i386
unixODBC-devel is needed by php-5.2.9-1.i386
libxml2-devel is needed by php-5.2.9-1.i386
net-snmp-devel is needed by php-5.2.9-1.i386
libxslt-devel >= 1.0.18-1 is needed by php-5.2.9-1.i386
libxml2-devel >= 2.4.14-1 is needed by php-5.2.9-1.i386
ncurses-devel is needed by php-5.2.9-1.i386
gd-devel is needed by php-5.2.9-1.i386
freetype-devel is needed by php-5.2.9-1.i386

9. Install any required packages with yum. If any of these packages have other dependencies they will be downloaded as well. This might take a while.

# yum install bzip2-devel curl-devel db4-devel expat-devel gmp-devel aspell-devel \
httpd-devel libjpeg-devel libpng-devel pam-devel openssl-devel sqlite-devel zlib-devel \
pcre-devel readline-devel krb5-devel libc-client-devel cyrus-sasl-devel openldap-devel \
mysql-devel postgresql-devel unixODBC-devel libxml2-devel net-snmp-devel libxslt-devel \
libxml2-devel ncurses-devel gd-devel freetype-devel

10. Try and build the spec file again to see if any patches fail to load properly. This usually happens if a patch has been rolled into the mainline PHP project and is no longer needed.

# rpmbuild -ba php.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.81391
+ umask 022
+ cd /usr/src/redhat/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ cd /usr/src/redhat/BUILD
+ rm -rf php-5.2.9
+ /bin/gzip -dc /usr/src/redhat/SOURCES/php-5.2.9.tar.gz
+ tar -xf -
+ STATUS=0
... output snipped ...
Patch #32 (php-5.2.5-systzdata.patch):
+ patch -p1 -b --suffix .systzdata -s
+ echo 'Patch #50 (php-5.2.4-tests-dashn.patch):'
Patch #50 (php-5.2.4-tests-dashn.patch):
+ patch -p1 -b --suffix .tests-dashn -s
Reversed (or previously applied) patch detected! Assume -R? [n]
Apply anyway? [n]
1 out of 1 hunk ignored -- saving rejects to file ext/standard/tests/file/bug26615.phpt.rej
1 out of 1 hunk FAILED -- saving rejects to file ext/standard/tests/file/proc_open01.phpt.rej
Reversed (or previously applied) patch detected! Assume -R? [n]
Apply anyway? [n]
1 out of 1 hunk ignored -- saving rejects to file ext/standard/tests/file/bug26938.phpt.rej
error: Bad exit status from /var/tmp/rpm-tmp.81391 (%prep)
RPM build errors:
Bad exit status from /var/tmp/rpm-tmp.81391 (%prep)

11. Looks like Patch 50 failed. Edit the spec file and comment out the line that begins with %patch50

%patch30 -p1 -b .dlopen
%patch31 -p1 -b .easter
%patch32 -p1 -b .systzdata
#%patch50 -p1 -b .tests-dashn
%patch51 -p1 -b .tests-wddx

12. For 5.2.9 as of this writing, this is the only patch that fails to load properly. In later versions, you may find that other patches fail to load, and you should comment those out as well.
13. Build the spec file again and after several minutes it will be complete and you'll have a handful of rpms in /usr/src/redhat/RPMS/i386

# rpmbuild -ba php.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.77534
+ umask 022
+ cd /usr/src/redhat/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ cd /usr/src/redhat/BUILD
+ rm -rf php-5.2.9
+ /bin/gzip -dc /usr/src/redhat/SOURCES/php-5.2.9.tar.gz
+ tar -xf -
+ STATUS=0
... output snipped ...
Wrote: /usr/src/redhat/RPMS/i386/php-ncurses-5.2.9-1.i386.rpm
Wrote: /usr/src/redhat/RPMS/i386/php-gd-5.2.9-1.i386.rpm
Wrote: /usr/src/redhat/RPMS/i386/php-bcmath-5.2.9-1.i386.rpm
Wrote: /usr/src/redhat/RPMS/i386/php-dba-5.2.9-1.i386.rpm
Wrote: /usr/src/redhat/RPMS/i386/php-debuginfo-5.2.9-1.i386.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.7525
+ umask 022
+ cd /usr/src/redhat/BUILD
+ cd php-5.2.9
+ '[' /var/tmp/php-5.2.9-1-root-root '!=' / ']'
+ rm -rf /var/tmp/php-5.2.9-1-root-root
+ rm files.bcmath files.common files.dba files.dbase files.dom files.gd files.imap [snip]
+ exit 0


14. You'll probably want to also build the php-extras source RPM as well. php-extras provides extensions for dbase, readline, mcrypt, mhash, tidy and mssql. Since there is no package in CentOS Testing, grab the latest from 5.1.6.

# wget http://mirror.centos.org/centos/5/extras/SRPMS/php-extras-5.1.6-15.el5.centos.1.src.rpm

15. And install it.

# rpm -ivh php-extras-5.1.6-15.el5.centos.1.src.rpm

16. Copy the php-extras.spec file like you did for php.spec so you can have the original.

# cd /usr/src/redhat/SPECS
# cp php-extras.spec php-extras516.spec

17. We ultimately need to replace the patches in php-extras.spec with the same from the much newer php.spec, as well as the ABI version numbers in the beginning of the file. Webtatic.com has already done this and you can go ahead and download the edited spec file, which also includes new PHP 5.2 extensions for json and filter. Remember, if you had a failed patch from php.spec, you'll need to comment it out in php-extras.spec as well. For 5.2.9, I had to comment out patch50 again.

%patch32 -p1 -b .systzdata
#%patch50 -p1 -b .tests-dashn
%patch51 -p1 -b .tests-wddx
%build


18. Once your php-extras.spec file is up to date, build the spec file and see if you're missing any dependencies.

# rpmbuild -ba php-extras.spec
error: Failed build dependencies:
php-devel = 5.2.9 is needed by php-extras-5.2.9-1.i386
libmcrypt-devel is needed by php-extras-5.2.9-1.i386
mhash-devel is needed by php-extras-5.2.9-1.i386
libtidy-devel is needed by php-extras-5.2.9-1.i386
freetds-devel is needed by php-extras-5.2.9-1.i386

19. Let's go back and install the php package that we need. If you only want the minimum needed to build php-extras, start by installing php-devel and seeing what it asks for, and install it's dependencies.

# cd /usr/src/redhat/RPMS/i386
# rpm -ivh php-devel-5.2.9-1.i386.rpm
error: Failed dependencies:
php = 5.2.9-1 is needed by php-devel-5.2.9-1.i386
# rpm -ivh php-5.2.9-1.i386.rpm php-devel-5.2.9-1.i386.rpm
error: Failed dependencies:
php-cli = 5.2.9-1 is needed by php-5.2.9-1.i386
php-common = 5.2.9-1 is needed by php-5.2.9-1.i386
# rpm -ivh php-5.2.9-1.i386.rpm php-devel-5.2.9-1.i386.rpm php-cli-5.2.9-1.i386.rpm php-common-5.2.9-1.i386.rpm
Preparing... ########################################### [100%]
1:php-common ########################################### [ 25%]
2:php-cli ########################################### [ 50%]
3:php ########################################### [ 75%]
4:php-devel ########################################### [100%]

20. After installing those four packages, install the other packages with yum.

# yum install libmcrypt-devel mhash-devel libtidy-devel freetds-devel

21. Now that all of the dependencies are resolved, build the php-extras.spec file.

# cd /usr/src/redhat/SPECS
# rpmbuild -ba php-extras.spec

22. If you're using RHEL, the build might fail for two reasons: a library for tidy is needed, and mhash-devel isn't available for RHEL. Both are easy to fix. Install 'tidy' with yum, and while mhash-devel isn't available, you can download libmhash-devel and edit the spec file to require libmhash-devel instead of mhash-devel.

You should now have all of your RPMs in /usr/src/redhat/RPMS/i386 (or x86_64) and install whichever packages you want. If in doubt, install them all. They're mainly static libraries and won't bloat your system. You may not want to install the debuginfo packages since you may find little use for them.

Staying updated is easy, download the source from php.net into /usr/src/redhat/SOURCES and edit the spec files for the new version numbers, rebuild, and install RPMs. If you're concerned about new patches being needed, you can grab the latest source RPM from Centos: http://dev.centos.org/centos/5/testing/SRPMS/. If CentOS were to ever come out with a newer version, or you want to subscribe to a yum repo and they provided a higher version, it would update as normal. You would need to rebuild in pear/pecl libraries by uninstall+installing them.

Yes, this is an involved process the first time around, but after doing this once you only need to download the latest source from php.net and edit the spec file version number and rebuild and update. If an old patch fails in a newer version you'll need to comment it out, but it's that simple.

This also works for 64-bit installations. Thanks to DiNo for helping me get PHP built on a 64-bit RHEL installation.

If you'd like to skip the steps and get right to building, you can download and install the source RPMs and build again the spec files. If you'd like to do itself, you can compare my spec files to yours. Enjoy the latest PHP hotness!

Reference: http://echodittolabs.org/node/89