Getting the OpenCV tutorial-4-opencl android app compiling and working on MacOS

I’ve been unable to get opencv working at all in Android Studio, but here’s a (slightly painful) way of getting it working on MacOS, at least as of the December, 2017.

First, current android sdk tools (ie ‘android’) will not work. You’ll have to download and use an old version. Assuming your sdk is installed in ~/Library/Android/sdk, run this on the terminal:

cd ~/Library/Android/sdk
mv tools tools.orig
curl -O https://dl.google.com/android/repository/tools_r25.2.3-macosx.zip
unzip tools_r25.2.3-macosx.zip
rm tools_r25.2.3-macosx.zip

Now we grab all of the sources we need to build:

export BUILD_HOME=$HOME/opencv    # change as you would like
mkdir -p $BUILD_HOME
cd $BUILD_HOME

# change these if they're not correct
export ANDROID_NDK=~/android-ndk-r11c
export ANDROID_SDK=~/Library/Android/sdk

# Download the necessary code
git clone git@github.com:opencv/opencv.git
mv opencv opencv-3.3.0
git clone git@github.com:opencv/opencv_contrib.git

# Creating our custom OpenCL SDK
export OPENCL_SDK=$BUILD_HOME/OpenCLSDK
mkdir $OPENCL_SDK && cd $OPENCL_SDK
mkdir lib include
# Copy the OpenCL headers used to compile OpenCV 
cp -r $BUILD_HOME/opencv-3.3.0/3rdparty/include/opencl/1.2/CL include/
# Download the multiplatform version of the C++ OpenCL Wrapper
cd include/CL/ && mv cl.hpp cl.hpp.orig && wget https://www.khronos.org/registry/cl/api/2.1/cl.hpp && cd ../..

# Grab the opencl stub and copy the c and h files into place
cd $BUILD_HOME
git clone https://github.com/krrishnarraj/libopencl-stub.git
cp libopencl-stub/include/libopencl.h opencv-3.3.0/samples/android/tutorial-4-opencl/jni/
cp libopencl-stub/src/libopencl.c opencv-3.3.0/samples/android/tutorial-4-opencl/jni/

# Set the folder where we are going to compile opencv, it will be used when we build the project
export OPENCV_ANDROID_SDK=$BUILD_HOME/build
mkdir -p $OPENCV_ANDROID_SDK
cd $OPENCV_ANDROID_SDK

# need to add the opencl stub to the build and remove the OpenCL library

At this point you’re almost good to start building, but we need to change one thing. The build by default uses a libOpenCL.so that we’re supposed to pull from the device, and then later link with the app and install back on the device. Since this library is device specific, its kind of a bad idea. (TM) Instead, we downloaded opencl stubs that dynamically open the appropriate libopencl.so library that already exists on the device and uses that. In theory, that means we should be able to use it on any device that has an opencl library installed. (Which should be pretty much all devices that do support opencl.)

The problem is we need to remove the opencl library, and add the libopencl.c file to the appropriate make-ish file. You do this by editing $BUILD_HOME/opencv-3.3.0/samples/android/tutorial-4-opencl/jni/Android.mk, removing the ‘-lOpenCL’, and adding ‘libopencl.c’ to the LOCAL_SRC_FILES line.

Now you’re ready for the first whack at building:

cd $OPENCV_ANDROID_SDK
cmake -Wno-dev \
-DCMAKE_TOOLCHAIN_FILE=$BUILD_HOME/opencv-3.3.0/platforms/android/android.toolchain.cmake \
-DANDROID_ABI="armeabi-v7a with NEON" \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DBUILD_ANDROID_EXAMPLES=ON \
-DINSTALL_ANDROID_EXAMPLES=ON \
-DWITH_OPENCL=YES \
-DANDROID_OPENCL_SDK=$OPENCL_SDK \
-DOPENCV_EXTRA_MODULES_PATH=$BUILD_HOME/opencv_contrib/modules \
-DANDROID_NATIVE_API_LEVEL=14 \
-DANDROID_SDK_TARGET=24 \
$BUILD_HOME/opencv-3.3.0
make -j8

This will appear to be doing everything you want until you get to what we’re interested in, the tutorial-4-opencl build. There, it fails:

ld: error: cannot find -lOpenCL
(and then a bunch more errors because of that)

We’re still getting the OpenCL.so error because we have it listed in opencv-3.3.0/samples/android/tutorial-4-opencl/CMakeLists.txt but if we remove the -lOpenCL from there, for some reason the libopencv.so isn’t included in the
tutorial-4-opencl build and the app crashes when it can’t open it. So instead, we have to remove the -lOpenCL from the samples/android/tutorial-4-opencl/CMakeFiles/JNIpart.dir/link.txt file, and run ‘make -j8’ again.

Now everything should have built without errors. You should be able to install the app on your android with:

$ANDROID_SDK/platform-tools/adb install samples/android/tutorial-4-opencl/.build/bin/example-tutorial-4-opencl-debug.apk

If anyone figures out how to skip the double compile stage, please let me know!