Wednesday, July 13, 2011

Installing V8Cgi on Mac

V8CGI is a very thin Apache module encapsulating V8 - Google's JavaScript engine that's used e.g. in Google Chrome. Those concerned with NodeJS stability may consider V8CGI a better choice, thanks to stability provided by Apache base.

A short while ago, on DevMeetings.pl DevCamp we've been playing with V8CGI, RingoJS and Node. Thanks to good performance, intuitive and high quality APIs, V8CGI turned out to be the black horse of the whole event, although installing it on Macs was little tricky.

Readers with Windows and Linux should follow to V8CGI home page, where they can get precompiled Windows binary and learn how to install binary on Ubuntu.

Mac users, let's open terminal and try to build the V8 apache module ourselves.

Getting V8CGI to work is four steps:
1. Getting the source code
2. Building it
3. Configuration
4. Test drive

1. Getting the source code
When checking out sources from SVN, we actually need two packages V8 and V8CGI:
a) svn checkout http://v8cgi.googlecode.com/svn/trunk/ v8cgi
b) svn checkout http://v8.googlecode.com/svn/trunk/ v8

You should end up with two new directories: v8 and v8cgi. When downloading a ready package from V8CGI home page, V8 sources are already included.

2. Build V8 and V8CGI
We'll use scons - a software construction tool. A good way to get started with scons is:
scons -Q -h

It gets you a list of available build configuration options. Worth visiting when you hit a wall compilation errors.

Let's first build V8:

cd v8
scons library=shared arch=x64
sudo cp libv8.dylib /usr/lib/libv8.dylib

We need x64 arch, as that's default Mac's Apache architecture. As a result your newly built libv8.dylib should be now available in /usr/lib directory.

Now let's build V8CGI.

cd ../v8cgi
scons module=1 mysql=0 gd=0 apache_path=/usr/include/apache2/ apr_path=/usr/include/apr-1/

Note that I added some extra options (run scons -Q -h for list of all options):
mysql=0 - disabled mysql support, that is on by default. Not quite sure if all I need to enable this option is on my Mac, and I don't need mysql for now, so let's just disable it.
gd=0 - disabled image-processing library 'gd', that is on by default. Same as with mysql, let's try without gd for start.
apache_path and apr_path - that's the path to Apache header files. Necessary to build against our HTTP server.

For me this command ends up with following error:

Undefined symbols for architecture x86_64:
"_iconv_open", referenced from:
ByteStorage::transcode(char const*, char const*)in bytestorage.os
"_iconv", referenced from:
ByteStorage::transcode(char const*, char const*)in bytestorage.os
"_iconv_close", referenced from:
ByteStorage::transcode(char const*, char const*)in bytestorage.os
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
scons: *** [mod_v8cgi.dylib] Error 1
scons: building terminated because of errors.

Above error message says that 'iconv' library is missing for our architecture x86_64. Iconv is used for converting different character set encodings, like UTF to ISO, ISO to ASCII, etc. It's not critical part of V8CGI, specially if you only want to evaluate that technology.

For evaluation purposes, we could just rip out the iconv calls from v8cgi source code but let's build iconv ourselves. Create another directory "iconv" next to v8 and v8cgi and execute following steps there:

curl -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.11.tar.gz
tar -zxvf libiconv-1.11.tar.gz
cd libiconv-1.11
./configure
make
make install

Note that latest iconv library is 1.13.1. We're using 1.11, because that one is compatible with iconv version included by default on Mac. Building with 1.13 you will end up with following error when trying to start apache next time:

httpd: Syntax error on line 118 of /private/etc/apache2/httpd.conf:
Cannot load /usr/local/apache2/modules/mod_v8cgi.dylib into server:
dlopen(/usr/local/apache2/modules/mod_v8cgi.dylib, 10):
Library not loaded: /usr/local/lib/libiconv.2.dylib\n
Referenced from: /usr/local/apache2/modules/mod_v8cgi.dylib\n
Reason: Incompatible library version: mod_v8cgi.dylib requires version 8.0.0 or later, but libiconv.2.dylib provides version 7.0.0

Let's go back to v8cgi directory and continue it's build. We need two extra params to link our new iconv module:

scons module=1 mysql=0 gd=0 \
apache_path=/usr/include/apache2/ \
apr_path=/usr/include/apr-1/ \
libpath=/usr/local/lib cpppath=/usr/local/include

The build proceeds few steps forward and fails again with:

g++ -o mod_v8cgi.dylib -bundle -bundle_loader /usr/sbin/httpd src/common.os src/system.os src/cache.os src/gc.os src/app.os src/path.os src/lib/binary/bytestorage.os src/mod_v8cgi.os -L/Users/jacek/Downloads/aa/v8 -L/usr/local/lib -lv8 -lv8 -lapr-1 -laprutil-1
Undefined symbols for architecture x86_64:
"_libiconv_open", referenced from:
ByteStorage::transcode(char const*, char const*)in bytestorage.os
"_libiconv", referenced from:
ByteStorage::transcode(char const*, char const*)in bytestorage.os
"_libiconv_close", referenced from:
ByteStorage::transcode(char const*, char const*)in bytestorage.os
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
scons: *** [mod_v8cgi.dylib] Error 1
scons: building terminated because of errors.

This time, compilation of v8cgi library is almost done, but breaks on gluing everything together. Let's invoke the same command adding -liconv:

g++ -o mod_v8cgi.dylib -bundle -bundle_loader /usr/sbin/httpd src/common.os src/system.os \
src/cache.os src/gc.os src/app.os src/path.os src/lib/binary/bytestorage.os src/mod_v8cgi.os \
-L/Users/jacek/Downloads/aa/v8 -L/usr/local/lib -lv8 -lv8 -lapr-1 -laprutil-1 -liconv


And success! No errors and your mod_v8cgi.dylib is out there, ready to try.

Configuration
Configuration is pretty well described in v8cgi/INSTALL text file so I'll just copy it here:

sudo cp v8cgi.conf.posix /etc/v8cgi.conf


- configure /etc/v8cgi.config
sudo vi /etc/v8cgi.conf
require.paths.push('~/src/v8cgi/lib');


- configure the apache module:
sudo vi /etc/apache2/mods-available/v8cgi.load
* The only line in the file should be:
LoadModule v8cgi_module ~/src/v8cgi/mod_v8cgi.so
--
sudo vi /etc/apache2/mods-available/v8cgi.conf
* The only line in the file should be:
AddHandler v8cgi-script .sjs .ssjs .jst


Restart Apache and you're ready to go!

2 comments:

  1. Good to see someone else using v8cgi :) I've got mine installed but I'm getting an error when I require('mysql'). It's as follows:

    Error: Error opening shared library '/usr/local/lib/v8cgi/mysql.dylib'

    Any ideas what may be causing that?

    Also, one thing I've not been able to figure out in v8cgi is sending emails via smtp. I can't get it to work. Let me know if you do. Thanks for the tut!

    ReplyDelete
  2. Hey I tried it but getting a server error. C:\v8cgi\v8cgi.exe - The FastCGI process exited unexpectedly. Let me know that what should I do now..I am in the middle of things..
    comment system

    ReplyDelete