Monday, October 31, 2011

Building Facebook's HipHop on Fedora 15

Facebook has opensourced their Hiphop code transformer. Simply put Hiphop transforms your code written in PHP Language into Machine Language. So this post is mainly for PHP Developers and Others who want to get their hands dirty with Hiphop on Fedora 15.

Before you get started. Please visit the main home page of the hiphop Project itself.

On github you see the list of all the pre-requisites. First lets get our development environment ready.


Prerequisites.

You need a Fedora 15 64-bit installation. You need not install anything. Just install the Live CD and follow these steps to get the things done.

1. Install the Fedora Packager packages


[root@nareshv-build64 ~]# yum groupinstall "Fedora Packager"


2. Make sure you have git and c++ compiler


[root@nareshv-build64 ~]# yum install gcc-c++ git wget 


3. Install all the pre-requisites as mentioned in the hiphop wiki

[root@nareshv-build64 ~]# yum install zlib-devel   \
xorg-x11-devel   \
libXau-devel   \
libxcb-devel   \
libX11-devel   \
libXpm-devel   \
freetype-devel   \
fontconfig-devel   \
libcom_err-devel   \
libjpeg-turbo   \
2:libpng-devel   \
libsepol-devel   \
libselinux-devel   \
keyutils-libs   \
krb5-devel   \
openssl-devel   \
mysql-devel   \
gd-devel   \
boost-devel   \
libcap-devel   \
oniguruma-devel   \
pcre-devel   \
libicu-devel   \
binutils-devel   \
libxml2-devel   \
libmcrypt-devel   \
expat-devel   \
libstdc++-devel   \
glibc-devel   \
tbb-devel   \
cyrus-sasl   \
libmemcached-devel   \
bzip2-devel   \
openldap-devel   \
ncurses-devel   \
readline-devel   \
pam-devel   \
uw-imap-devel   \
systemtap-sdt   \
libaio-devel   \
mysql-devel   \
jemalloc-devel


4. Now we have to build libevent-1.4 and curl packages on our own as facebook has made some patches to those packages.

5. Lets create the environment for building the packages

6. Create workspace for checking out the hiphop source code.


[root@nareshv-build64 ~]# cd $HOME/
[root@nareshv-build64 ~]# mkdir -p $HOME/dev/hiphop/ $HOME/dev/hiphop/usr
[root@nareshv-build64 ~]# cd $HOME/dev/hiphop


7. Checkout the hiphop source code


[root@nareshv-build64 ~]# cd $HOME/dev/hiphop/ && git clone git://github.com/facebook/hiphop-php.git



8. Download curl and libevent for building locally


[root@nareshv-build64 ~]# cd $HOME/dev/hiphop/
[root@nareshv-build64 hiphop]# wget http://curl.haxx.se/download/curl-7.20.0.tar.bz2
[root@nareshv-build64 hiphop]# wget http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz

[root@nareshv-build64 hiphop]# tar jxf curl-7.20.0.tar.bz2
[root@nareshv-build64 hiphop]# tar zxf libevent-1.4.13-stable.tar.gz

[root@nareshv-build64 hiphop]# cd libevent-1.4.13-stable
[root@nareshv-build64 libevent-1.4.13-stable]# cp ../hiphop-php/src/third_party/libevent-1.4.13.fb-changes.diff .
[root@nareshv-build64 libevent-1.4.13-stable]# patch < libevent-1.4.13.fb-changes.diff
[root@nareshv-build64 libevent-1.4.13-stable]# export CMAKE_PREFIX_PATH=$HOME/dev/hiphop/usr
[root@nareshv-build64 libevent-1.4.13-stable]# make
[root@nareshv-build64 libevent-1.4.13-stable]# make install
[root@nareshv-build64 libevent-1.4.13-stable]# cd $HOME/dev/hiphop/

[root@nareshv-build64 hiphop]# cd curl-7.20.0
[root@nareshv-build64 curl-7.20.0]# cp ../hiphop-php/src/third_party/libcurl.fb-changes.diff .
[root@nareshv-build64 curl-7.20.0]# patch -p0 < libcurl.fb-changes.diff

# While applying patch, it will ask for which file to patch. Type in the names without the .new and .old paths. 
# Example: include/curl/multi.h and 
# Example: lib/multi.c
# After this, patch will be applied correctly.

[root@nareshv-build64 curl-7.20.0]# ./configure --prefix=$HOME/dev/hiphop/usr/
[root@nareshv-build64 curl-7.20.0]# make
[root@nareshv-build64 curl-7.20.0]# make install
[root@nareshv-build64 curl-7.20.0]# cd $HOME/dev/hiphop/


9. Now get ready to build hiphop itself


[root@nareshv-build64 curl-7.20.0]# cd $HOME/dev/hiphop/hiphop-php
[root@nareshv-build64 hiphop-php]# export CMAKE_PREFIX_PATH=$HOME/dev/hiphop/usr/
[root@nareshv-build64 hiphop-php]# git submodule init
[root@nareshv-build64 hiphop-php]# git submodule update
[root@nareshv-build64 hiphop-php]# export HPHP_HOME=`pwd`
[root@nareshv-build64 hiphop-php]# export HPHP_LIB=`pwd`/bin
[root@nareshv-build64 hiphop-php]# cmake .
[root@nareshv-build64 hiphop-php]# make


10. You will encounter some errors related to 'c-client version should be higher than 2007'.

On fedora the package is called libc-client and libc-client-devel and the includes are present in /usr/include/imap/ folders.

Lets adjust the CMakeCache.txt like this.

[root@nareshv-build64 hiphop-php]# cd $HOME/dev/hiphop/hiphop-php/
[root@nareshv-build64 hiphop-php]# vim CMakeCache.txt

 71 //Path to a file.CCLIENT_INCLUDE_PATH:PATH=CCLIENT_INCLUDE_PATH-NOTFOUND
 72 CCLIENT_INCLUDE_PATH:PATH=/usr/include/imap/
 73 
 74 //Path to a library.CCLIENT_LIBRARY:FILEPATH=CCLIENT_LIBRARY-NOTFOUND
 75 CCLIENT_LIBRARY:FILEPATH=/usr/lib64/libc-client.so.2007


11. Build again.

[root@nareshv-build64 hiphop-php]# cd $HOME/dev/hiphop/hiphop-php/
[root@nareshv-build64 hiphop-php]# cmake .
[root@nareshv-build64 hiphop-php]# make


12. Now it will fail at mysql related references like this


[ 88%] Building CXX object src/hphp/CMakeFiles/hphp.dir/externals.cpp.o
Linking CXX executable hphp
../../bin/libhphp_runtime.a(ext_mysql.cpp.o): In function `HPHP::php_mysql_do_query_general(HPHP::String const&, HPHP::Variant const&, bool)':
ext_mysql.cpp:(.text+0x8109): undefined reference to `cli_safe_read'
ext_mysql.cpp:(.text+0x822c): undefined reference to `net_field_length'
ext_mysql.cpp:(.text+0x83a0): undefined reference to `cli_safe_read'
ext_mysql.cpp:(.text+0x8675): undefined reference to `free_root'
collect2: ld returned 1 exit status
gmake[2]: *** [src/hphp/hphp] Error 1
gmake[1]: *** [src/hphp/CMakeFiles/hphp.dir/all] Error 2
gmake: *** [all] Error 2


After investigating for a couple of hours. found that this issue is related to the way mysql rpm is built in fedora distribution. Somehow i managed to overcome this problem by doing the following things.

12.1 Download the mysql .src.rpm from koji

I went to http://koji.fedoraproject.org/koji/buildinfo?buildID=268920

and downloaded the following .src.rpm

http://kojipkgs.fedoraproject.org/packages/mysql/5.5.16/3.fc17/src/mysql-5.5.16-3.fc17.src.rpm

12.2 Install the .src.rpm as 'fedora' user (It can be root also. I did it as fedora user. But you got the point)


[root@nareshv-build64 hiphop-php]# rpm -Uvh mysql-5.5.16-3.fc17.src.rpm


12.3 Update the libmysql.version file


[root@nareshv-build64 hiphop-php]# cd /home/fedora/rpmbuild/SOURCES/
[root@nareshv-build64 SOURCES]# ls
filter-requires-mysql.sh    mysql-disable-test.patch     mysql-errno.patch          mysql-strmov.patch
generate-tarball.sh         mysqld-nowatch.patch         mysql-expired-certs.patch  mysql.tmpfiles.d
libmysql.version            mysqld-prepare-db-dir        mysql-install-test.patch   mysql-va-list.patch
my.cnf                      mysqld.service               mysql-openssl-test.patch   mysql-versioning.patch
my_config.h                 mysql-dubious-exports.patch  mysql-plugin-bool.patch    README.mysql-docs
mysql-5.5.16-nodocs.tar.gz  mysqld-wait-ready            mysql-s390-tsc.patch       README.mysql-license
mysql-chain-certs.patch     mysql-embedded-check.c       mysql-stack-guard.patch    scriptstub.c
[root@nareshv-build64 SOURCES]# tail libmysql.version 
 mysql_get_charset_by_csname;
 mysql_net_realloc;
# PHP's mysqli.so requires this (via the ER() macro)
 mysql_client_errors;
# Hiphop needs it
 cli_safe_read;
 net_field_length;
 cli_safe_read;
 free_root;
};


12.4 Rebuild the RPM

[fedora@nareshv-build64 SOURCES]$ rpmbuild -bb ../SPECS/mysql.spec 
...
...
Wrote: /home/fedora/rpmbuild/RPMS/x86_64/mysql-5.5.16-3.fc15.x86_64.rpm
Wrote: /home/fedora/rpmbuild/RPMS/x86_64/mysql-libs-5.5.16-3.fc15.x86_64.rpm
Wrote: /home/fedora/rpmbuild/RPMS/x86_64/mysql-server-5.5.16-3.fc15.x86_64.rpm
Wrote: /home/fedora/rpmbuild/RPMS/x86_64/mysql-devel-5.5.16-3.fc15.x86_64.rpm
Wrote: /home/fedora/rpmbuild/RPMS/x86_64/mysql-embedded-5.5.16-3.fc15.x86_64.rpm
Wrote: /home/fedora/rpmbuild/RPMS/x86_64/mysql-embedded-devel-5.5.16-3.fc15.x86_64.rpm
Wrote: /home/fedora/rpmbuild/RPMS/x86_64/mysql-bench-5.5.16-3.fc15.x86_64.rpm
Wrote: /home/fedora/rpmbuild/RPMS/x86_64/mysql-test-5.5.16-3.fc15.x86_64.rpm

Wrote: /home/fedora/rpmbuild/RPMS/x86_64/mysql-debuginfo-5.5.16-3.fc15.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.I5L4qW
+ umask 022
+ cd /home/fedora/rpmbuild/BUILD
+ cd mysql-5.5.16
+ rm -rf /home/fedora/rpmbuild/BUILDROOT/mysql-5.5.16-3.fc15.x86_64
+ exit 0


12.5 Install the RPM Files happily


[root@nareshv-build64 SOURCES]# yum install /home/fedora/rpmbuild/RPMS/x86_64/mysql-libs-5.5.16-3.fc15.x86_64.rpm \
/home/fedora/rpmbuild/RPMS/x86_64/mysql-5.5.16-3.fc15.x86_64.rpm \
/home/fedora/rpmbuild/RPMS/x86_64/mysql-devel-5.5.16-3.fc15.x86_64.rpm -y --nogpg


13. Now build hiphop again

[root@nareshv-build64 hiphop-php]# cd $HOME/dev/hiphop/hiphop-php/
[root@nareshv-build64 hiphop-php]# gmake clean
[root@nareshv-build64 hiphop-php]# cmake .
[root@nareshv-build64 hiphop-php]# make


14. You should have the binary created

[root@nareshv-build64 hiphop-php]# src/hphp/hphp -h | head
Error in command line: unknown option -h\n\n
HipHop Compiler for PHP Usage:

 hphp  

Options:
  --help                         display this message
  --version                      display version number
  -t [ --target ] arg (=run)     lint | analyze | php | cpp | sep-ext-cpp | 
                                 filecache | run (default)
  -f [ --format ] arg            lint: (none); 


15. Now continue with the rest of the tutorial on how to get your code compiled in the main hiphop project page itself.