google-chromeopencvgoogle-nativeclient

How to port OpenCv to NaCl


Does anyone know any way how to port OpenCV to NaCl? I'm trying to make Chrome extension based on face recognition. I would appreciate some help.


Solution

  • The detailed instructions below have been reposted from (the now defunct metacaptcha.com/install_opencv_nacl) for convenience.

    1. Prerequitsites

    OpenCV depends on several important libraries such as bzip2, zlib, NaclMounts and at least one decompression/compression library to handle common images such as libpng/jpeg/tiff. This article will focus on libjpeg only. Those libraries need to be built in both 32-bit and 64-bit architect as dynamic library using NaCl Glibc toolchain (Pepper 28).

    In order to build the 32-bit and 64-bit shared libraries for NaCl, the 32-bit and 64-bit version of NaCl gcc/linker need to be used respectively. To make this easier in the tutorial, we make the following environment variables:

    Note: In case one of the link in the article failed to work, a backup link can be found here.

    export NACL_SDK_ROOT=/Users/thai/apps/nacl_sdk/pepper_28
    export NACL_PREFIX="$NACL_SDK_ROOT"/toolchain/mac_x86_glibc/x86_64-nacl
    export NACL_64="$NACL_SDK_ROOT"/toolchain/mac_x86_glibc/bin/x86_64-nacl
    export NACL_32="$NACL_SDK_ROOT"/toolchain/mac_x86_glibc/bin/i686-nacl
    

    1.1 Bzip2 for Native Client

    Download Bzip2 v1.0.6, extract to your local directory. Makefile-libbz2_so is the file we want to use for make, we want to change the gcc toolchain parameters such that, instead of using the regular OS gcc, it will use the NaCl gcc in $NACL_SDK_ROOT/toolchain/mac_x86_glibc/x86_64-nacl/bin/.

    Run make -f Makefile-libbz2_so on bzip2 with the following parameters, then copy the library into NaCl toolchain.

    make -f Makefile-libbz2_so CC=$NACL_64-'gcc -m64'
    cp libbz2.so.1.0.6 $NACL_PREFIX/lib64/libbz2.so
    make clean
    make -f Makefile-libbz2_so CC=$NACL_32-'gcc -m32'
    cp libbz2.so.1.0.6 $NACL_PREFIX/lib32/libbz2.so
    cp *.h $NACL_PREFIX/include
    

    1.2 Zlib for Native Client

    Download Zlib-1.2.8, extract to your local directory. Zlib is using autoconfig to generate Makefile, we will need to run this tool first then modify the GCC toolchain into NaCl one.

    Run ./configure --enable-shared on zlib, then run make with the following parameters.

    ./configure --enable-shared
    make shared CC=$NACL_64-'gcc -m64' AR=$NACL_64-ar ARFLAGS=rc CFLAGS='-O3 -DHAVE_HIDDEN'                     LDFLAGS='-O3 -fPIC -DHAVE_HIDDEN' LDSHARED='$(CC) -shared -Wl,-soname -Wl,libz.so'     SHAREDLIB=libz.so SHAREDLIBM=libz.so.1.2.8 SHAREDLIBV=libz.so.1
    cp libz.so.1 $NACL_PREFIX/lib64/libz.so
    make clean
    make shared CC=$NACL_32-'gcc -m32' AR=$NACL_32-ar ARFLAGS=rc CFLAGS='-O3 -DHAVE_HIDDEN' LDFLAGS='-O3 -fPIC -DHAVE_HIDDEN' LDSHARED='$(CC) -shared -Wl,-soname -Wl,libz.so' SHAREDLIB=libz.so SHAREDLIBM=libz.so.1.2.8 SHAREDLIBV=libz.so.1
    cp libz.so.1 $NACL_PREFIX/lib32/libz.so
    cp zlib.h zconf.h $NACL_PREFIX/include
    

    1.3 libJPEG for Native Client

    Download jpeg-v6b, NaCl jpeg makefile.cfg patch and put them to your local directory.

    Patch the jpeg-v6b directory with the nacl-jpeg-makefile.cfg patch.

    cd jpeg-6b
    patch < nacl-jpeg-v6b-makefile.cfg.patch
    

    Run ./configure on jpeg-6b, then run make libjpeg.so with the following parameters.

    ./configure
    make libjpeg.so CC=$NACL_64-gcc CFLAGS='-m64 -fPIC -O2 -I.' LDFLAGS='-shared -Wl,-soname -Wl,libjpeg.so -o libjpeg.so'
    mv libjpeg.so $NACL_PREFIX/lib64/libjpeg.so
    make clean
    make libjpeg.so CC=$NACL_32-gcc CFLAGS='-m32 -fPIC -O2 -I.' LDFLAGS='-shared -Wl,-soname -Wl,libjpeg.so -o libjpeg.so'
    mv libjpeg.so $NACL_PREFIX/lib32/libjpeg.so
    make install-headers prefix=$NACL_PREFIX
    

    1.4 NaclMounts for Native Client

    Download NaclMounts, nacl-mounts.patch and our custom Makefile Go to your local nacl-mount directory, copy the Makefile into this directory, applying the patch and run the following commands (assuming you already set the environment variables at the beginning of the article)

    cp Makefile nacl-mounts/
    cd nacl-mounts/
    patch -p0 < ../nacl-mounts.patch
    make ARCH=x86_64 BIT=64
    cp libnaclmounts.so $NACL_PREFIX/lib64
    make clean
    make ARCH=i686 BIT=32
    cp libnaclmounts.so $NACL_PREFIX/lib32
    make install-headers
    

    2. OpenCV for Native Client

    OpenCV need to be built in cross-compiling mode, to easily do that with cmake (build tool of OpenCV). We set CMAKE_SYSTEM_NAME=Linux to force cross-compiling for Linux target. A OpenCV-nacl-cmake script is written in order to facilitate the build process if you have already setup the environment variables in the previous step.

    2.1 Setup source code

    Download OpenCV 2.4.2, opencv-nacl-cmake script Extract OpenCV to your local directory.

    Create nacl/m32, nacl/m64 directory in OpenCV-2.4.2/ for building 32/64 bit version of OpenCV Native Client code.

    Copy opencv-nacl-cmake script into nacl/ directory.

    tar xvf OpenCV-2.4.2.tar.gz
    cd OpenCV-2.4.2
    mkdir nacl
    cd nacl
    mkdir m64 m32
    cp ~/Downloads/opencv-nacl-cmake ./
    

    2.2 Patch OpenCV I/O Library (persistance.cpp) / Exclude building of apps

    In order for OpenCV to read/write to files in Native Client, a new file system library need to be used. This patch replace all the OS system calls for file I/O with NaclMounts library.

    Download persistance.cpp patch for OpenCV 2.4.2 Copy the patch to your OpenCV dir, and apply the path using these commands

    cp ~/Download/opencv-nacl-persistance.patch OpenCV-2.4.2
    cd OpenCV-2.4.2
    patch -p0 < opencv-nacl-persistance.patch
    

    We also need to tell cmake to exclude the apps module in OpenCV (the apps module doesn't need to be ported). This can be done by simply moving the CMakeList.txt file in apps directory

    mv apps/CMakeList.txt apps/CMakeList.txt.old
    

    2.3 Configure, build and install

    Run ./opencv-nacl-cmake with the following parameters to configure and build the library. The following bash commands also install both 32 and 64-bit versions of the library for OpenCV. Because of the naming convention of Native Client, we have to move the lib/, lib32/, lib64/ directory around in order to install the architecture correctly.

    cd nacl/m32                                             
    ../opencv-nacl-cmake i686 32 
    make -j8
    unlink $NACL_PREFIX/lib64
    mv $NACL_PREFIX/lib $NACL_PREFIX/lib64
    mv $NACL_PREFIX/lib32 $NACL_PREFIX/lib
    ln -s $NACL_PREFIX/lib $NACL_PREFIX/lib32
    make install 
    unlink $NACL_PREFIX/lib32
    mv $NACL_PREFIX/lib $NACL_PREFIX/lib32
    mv $NACL_PREFIX/lib64 $NACL_PREFIX/lib
    ln -s $NACL_PREFIX/lib $NACL_PREFIX/lib64
    cd ../m64
    ../opencv-nacl-cmake x86_64 64
    make -j8
    make install
    

    At this point, you have finished installing OpenCV 2.4.2 for Native Client Pepper 28.

    A simple applications adapted from the OpenCV's tutorials to perform face detection in Google Chrome can be found in example_opencv_nacl_facedetect.