linux · tech

How to compile and install v8 and v8js on CentOS 7

A client tasked us to install v8 and v8js on a test system to play around with the server-side compilation of vue.js applications.

The v8 library available on SCL and EPEL is old, 2013-old. So we were faced with the option to either compile v8 or switch away from CentOS for Debian or Ubuntu with some third party repositories that we don’t really know much about and we don’t really trust for when the platform will go in production.

A word of caution: compiling takes a long time, I recommend you use a fast machine (I used a VM with 8 cores, 16Gb RAM and it took about 20 mins to compile).

Compiling v8

As we said, compiling takes quite a lot of time. This is the script I wrote after a few rounds of trial and error. You can (and should, really) run this as a normal, unprivileged user.

#!/bin/bash

set -x  # debug
set -e  # exit on all errors

# update and install basic packages
sudo yum -y upgrade
sudo yum -y --enablerepo=epel --enablerepo=remi-php71 install git subversion make gcc-c++ chrpath redhat-lsb-core php php-devel php-pear

mkdir -p local/src

# install the depot tools from google
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git local/depot_tools
export PATH=$PATH:local/depot_tools

# install v8
cd local/src
fetch v8
cd v8
gclient sync
./tools/dev/v8gen.py -vv x64.release -- is_component_build=true
time ninja -C out.gn/x64.release
time ./tools/run-tests.py --gn

As you can see, there’s a bit of requirements that aren’t a good choice for production (compilers, git, etc), but you can uninstall them later or, better yet, build a package.

Installing v8

For the installation I relied on the v8js build instructions, copying (as root) just the required files from my build directory:

mkdir -p /opt/v8/{lib,include}

cd /your_build/path/local/src/v8
cp -v out.gn/x64.release/lib*.so out.gn/x64.release/*_blob.bin \
   out.gn/x64.release/icudtl.dat /opt/v8/lib/
cp -vR include/* /opt/v8/include/

Now we can install v8js using pecl.

Compiling v8js from PECL

During the initial setup I installed php-pear from the Remi PHP 7.1 repository. This gives us the pecl command to install php modules easily.

When asked for the v8 library path we’re using the /opt/v8 path we created in the previous step:

# pecl install v8js
downloading v8js-2.1.0.tgz ...
Starting to download v8js-2.1.0.tgz (101,553 bytes)
.......................done: 101,553 bytes
28 source files, building
running: phpize
Configuring for:
PHP Api Version:         20160303
Zend Module Api No:      20160303
Zend Extension Api No:   320160303
Please provide the installation prefix of libv8 [autodetect] : /opt/v8
building in /var/tmp/pear-build-rootDGsvNg/v8js-2.1.0
[...]
Build process completed successfully
Installing '/usr/lib64/php/modules/v8js.so'
install ok: channel://pecl.php.net/v8js-2.1.0
configuration option "php_ini" is not set to php.ini location
You should add "extension=v8js.so" to php.ini
# echo 'extension=v8js.so' > /etc/php.d/60-v8js.ini
# service php-fpm restart

We compiled v8js and created a new ini file to load the new module in PHP, and restarted php-fpm to apply the changes.

We can verify that v8js is installed by running a simple phpinfo check:

$ cat > phpinfo.php
<?php phpinfo();
$ php phpinfo.php | grep -i v8
/etc/php.d/60-v8js.ini
v8js
V8 Javascript Engine => enabled
V8 Engine Compiled Version => 6.8.0
V8 Engine Linked Version => 6.8.0 (candidate)
v8js.flags => no value => no value
v8js.icudtl_dat_path => no value => no value
v8js.use_array_access => 0 => 0
v8js.use_date => 0 => 0

At this point you should be good to go. I hope this helps some fellow admins out there :)

Compiling v8 < 5.5

If you need an older version, the instructions for compiling and copying the files are slightly different:

compile-v8-5.2.sh

#!/bin/bash

set -x  # debug
set -e  # exit on errors

# update the system and install required packages
sudo yum -y upgrade
sudo yum -y --enablerepo=epel --enablerepo=remi-php71 install git subversion make gcc-c++ chrpath redhat-lsb-core php php-devel php-pear

mkdir -p local/src

# install depot tools
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git local/depot_tools
export PATH=$PATH:local/depot_tools 

# install v8
cd local/src 
fetch v8 
cd local/src/v8 
git checkout 5.2
gclient sync

export GYPFLAGS="-Dv8_use_external_startup_data=0"
export GYPFLAGS="${GYPFLAGS} -Dlinux_use_bundled_gold=0"
time make x64.release native library=shared snapshot=on -j8

Please note that if you get this error:

PYTHONPATH="/path/tools/generate_shim_headers:/path/build::/path/tools/gyp/pylib:" \
GYP_GENERATORS=make \
tools/gyp/gyp --generator-output="out" gypfiles/all.gyp \
              -Igypfiles/standalone.gypi --depth=. -S.native  -Dv8_enable_backtrace=1 -Darm_fpu=default -Darm_float_abi=default
gyp: Error importing pymod_do_mainmodule (detect_v8_host_arch): No module named detect_v8_host_arch
make: *** [out/Makefile.native] Error 1

You will need to edit the Makefile as documented in this diff to fix the Python paths.

As for the installation part:

install-v8-5.2.sh

export PATH=$PATH:local/depot_tools 

# install v8
sudo mkdir -p /opt/v8/{lib,include}

cd local/src/v8

sudo cp -v out/native/lib.target/lib*.so /opt/v8/lib/
sudo cp -vR include/* /opt/v8/include/
sudo chrpath -r '$ORIGIN' /opt/v8/lib/libv8.so

# Install libv8_libplatform.a (V8 >= 5.2.51)
echo -e "create /opt/v8/lib/libv8_libplatform.a\naddlib out/native/obj.target/src/libv8_libplatform.a\nsave\nend" | sudo ar -M

As you can see the build process is a bit different, so make sure you're following the correct one for your version.

References

Advertisements