Thursday, December 3, 2009

Building CouchDB on Karmic

Well, I guess it's time to get going. This blog isn't going to write itself.

Despite a continuing affinity for Debian I've shifted most of my personal work to Ubuntu in recent months. I remain something of a dinosaur by building most of my libraries and binaries myself, but an occasional well-placed package or two can really speed things up, especially for a dependency that may not be particularly interesting by itself. Striking that balance seems to be a bit easier with Ubuntu but that's a fairly subjective opinion; your mileage may vary.

So when I decided to resume some earlier experiments with CouchDB and Scala (including playing with the very intriguing Dispatch library) it only seemed natural to migrate to Ubuntu 9.10 ("Karmic Koala"). So we proceed with an installation of CouchDB 0.10.1 on a fresh install of Ubuntu 9.10. And yes, I am aware that CouchDB 0.10.0 is included as part of the Karmic install. That is good news but it's irrelevant to my purpose. There's no benefit in being forced to work around what Ubuntu does with the native CouchDB install or to worry about version conflicts if we want to upgrade. We can install a standalone copy; why wouldn't we?

So c'mon, kids, let's build a no SQL database! We start with some foundation stuff:

mkdir ~/local
gzip -dc openssl-1.0.0-beta4.tar.gz | tar xf -
cd openssl-1.0.0-beta4
./Configure --prefix=/home/hfencepost/local/openssl-1.0.0-beta4 shared linux-elf
make
make test
make install
cd ..
export LD_LIBRARY_PATH=/home/hfencepost/local/openssl-1.0.0-beta4/lib
bzip2 -dc curl-7.19.7.tar.bz2 | tar xf -
cd curl-7.19.7
./configure --prefix=/home/hfencepost/local/curl-7.19.7 --with-gnu-ld --with-ssl=/home/hfencepost/local/openssl-1.0.0-beta4/
make
make test
make install
cd ..

Probably not necessary to configure LD_LIBRARY_PATH since we're explicitly specifying the location to our OpenSSL install. Anyways, moving on...

CouchDB also makes use of the ICU library so let's take care of that now. It's a C++ lib and g++ doesn't appear to be installed by default so we need to snag it before we build anything:

sudo apt-get install g++
gzip -dc icu4c-4_2_1-src.tgz | tar xf -
cd icu/source
./runConfigureICU Linux --prefix=/home/hfencepost/local/icu-4.2.1
make
make check
make install
cd ..

CouchDB is implemented (mostly) in Erlang so an Erlang platform might be useful. As mentioned above Karmic includes a CouchDB install by default which also means it includes an Erlang install by default. We're building our own for the same reasons we install our own CouchDB instance. Erlang requires a curses lib to build correctly so we lead off with that:

sudo apt-get install ncurses-dev
gzip -dc otp_src_R13B03.tar.gz | tar xf -
cd otp_src_R13B03/
./configure --prefix=/home/hfencepost/local/otp_R13B03 --with-ssl=
/home/hfencepost/local/openssl-1.0.0-beta4
make
make install
cd ..

Finally we come to SpiderMonkey. In the past this has been the only CouchDB dependency I install as a package, but with Karmic something odd has happened:

sudo apt-get install libmozjs-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libmozjs0d libnspr4-dev
The following packages will be REMOVED:
couchdb-bin desktopcouch evolution-couchdb evolution-documentation-en firefox firefox-3.5
firefox-3.5-branding firefox-3.5-gnome-support firefox-gnome-support gnome-user-guide
python-desktopcouch python-desktopcouch-records ubufox ubuntu-desktop ubuntu-docs
xulrunner-1.9.1 xulrunner-1.9.1-gnome-support yelp
The following NEW packages will be installed:
libmozjs-dev libmozjs0d libnspr4-dev
0 upgraded, 3 newly installed, 18 to remove and 131 not upgraded.
Need to get 844kB of archives.
After this operation, 295MB disk space will be freed.
Do you want to continue [Y/n]?


I'm not sure why installing libjs.so would result in the removal of Firefox (not to mention everything else on that list) but that's a question for another day. Clearly this won't work, so off we go to build from source.

We download SpiderMonkey 1.7 and build based on the instructions found on the CouchDB wiki (and echoed by the SpiderMonkey docs):

gzip -dc js-1.7.0.tar.gz | tar xf -
cd js/src
make -f Makefile.ref
JS_DIST=/home/hfencepost/local/spidermonkey-1.7.0 make -f Makefile.ref export
cd ../..

That seems to have gone okay, but let's dig just a bit deeper:

ld -L/home/hfencepost/local/spidermonkey-1.7.0/lib -ljs
ld: warning: cannot find entry symbol _start; not setting start address
/home/hfencepost/local/spidermonkey-1.7.0/lib/libjs.so: undefined reference to `__umoddi3'
/home/hfencepost/local/spidermonkey-1.7.0/lib/libjs.so: undefined reference to `__udivdi3'
/home/hfencepost/local/spidermonkey-1.7.0/lib/libjs.so: undefined reference to `__divdi3'

Ugh. The references appear to be to code in the gcc runtime that isn't available to the lib. A bit of digging makes it clear that this is caused by the use of ld to actually create the shared lib rather than gcc. Moving forward with this configuration will cause the CouchDB install to fail due to an inability to find a functioning SpiderMonkey install. A simple change to config/Linux_All.mk does the job:

#MKSHLIB = $(LD) -shared $(XMKSHLIBOPTS)
MKSHLIB = $(CC) -shared $(XMKSHLIBOPTS)

Let's clean everything out and rebuild with our new settings:

make -f Makefile.ref clean
rm -rf /home/hfencepost/local/spidermonkey-1.7.0/
make -f Makefile.ref
JS_DIST=/home/hfencepost/local/spidermonkey-1.7.0 make -f Makefile.ref export
cd ../..
ld -L/home/hfencepost/local/spidermonkey-1.7.0/lib -ljs

The lack of any error messages in the output of the last command fills us with joy! At last we get to build CouchDB!

gzip -dc apache-couchdb-0.10.1.tar.gz | tar xf -
cd apache-couchdb-0.10.1/
export LD_LIBRARY_PATH=$HOME/local/spidermonkey-1.7.0/lib:$HOME/local/curl-7.19.7/lib:$HOME/local/openssl-1.0.0-beta4/lib
export PATH=$HOME/local/icu-4.2.1/bin:$HOME/local/curl-7.19.7/bin:$HOME/local/otp_R13B03/bin:$PATH
./configure --prefix=/home/hfencepost/local/couchdb-0.10.1 --with-gnu-ld --with-erlang=$HOME/local/otp_R13B03/lib/erlang/erts-5.7.4/include --with-js-lib=/home/hfencepost/local/spidermonkey-1.7.0/lib --with-js-include=/home/hfencepost/local/spidermonkey-1.7.0/include
make
make install
cd ..

Well, that was fun. All we have to do now is fire this thing up and see what we have:

cd ~/local/couchdb-0.10.1/
bin/couchdb

You should see a welcome message with calming powers second only to "Don't panic":

Apache CouchDB has started. Time to relax.

You can now access your new database via Futon (details of which can be found on the wiki), curl, wget or whatever other HTTP client strikes your fancy.

Enjoy!

No comments:

Post a Comment