How to build OpenCV for Android using libc++ STL library? - opencv

I would like to build a OpenCV from source using a libc++ STL library, instead of default GNU STL. LibC++ offers better C++11 and C++14 support. Is it possible to do that?

I've tested this with OpenCV 2.4.7 and Android NDK r10d.
First, you need to download OpenCV source. Unpack the source and replace the platforms/android/android.toolchain.cmake with version that suppports libc++.
Now, open modules/core/include/opencv2/core/operations.hpp and change line 69 from
(defined __GNUC__ && defined _STLPORT_MAJOR)
to
(defined __GNUC__ && (defined _STLPORT_MAJOR || defined _LIBCPP_VERSION))
Next, in folder platforms/scripts create a script cmake_android_arm_libcxx.sh with following contents:
#!/bin/sh
cd `dirname $0`/..
mkdir -p build_android_arm
cd build_android_arm
cmake -DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.8 -DANDROID_STL=c++_static -DANDROID_NATIVE_API_LEVEL=android-8 -DBUILD_ANDROID_EXAMPLES=OFF -DBUILD_DOCS=OFF -DBUILD_FAT_JAVA_LIB=OFF -DBUILD_JASPER=OFF -DBUILD_OPENEXR=OFF -DBUILD_PACKAGE=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_TIFF=OFF -DBUILD_WITH_DEBUG_INFO=OFF -DBUILD_opencv_androidcamera=OFF -DBUILD_opencv_contrib=OFF -DBUILD_opencv_java=OFF -DBUILD_opencv_legacy=OFF -DBUILD_opencv_ml=OFF -DBUILD_opencv_nonfree=OFF -DBUILD_opencv_objdetect=OFF -DBUILD_opencv_photo=OFF -DBUILD_opencv_stitching=OFF -DBUILD_opencv_ts=OFF -DBUILD_opencv_video=OFF -DBUILD_opencv_videostab=OFF -DCMAKE_C_FLAGS_RELEASE="-Os -DNDEBUG -fvisibility=hidden -ffunction-sections -fstack-protector-all" -DCMAKE_CXX_FLAGS_RELEASE="-Os -DNDEBUG -fvisibility=hidden -ffunction-sections -fstack-protector-all -fvisibility-inlines-hidden" -DENABLE_PRECOMPILED_HEADERS=OFF -DWITH_EIGEN=OFF -DWITH_JASPER=OFF -DWITH_OPENEXR=OFF -DWITH_TIFF=OFF -DWITH_TBB=ON -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DCMAKE_TOOLCHAIN_FILE=../android/android.toolchain.cmake $# ../..
If you want, you can tweak the parameters of the script (i.e. what is built and how).
Finally, export the path to your NDK build folder
export ANDROID_NDK=~/android-sdks/android-ndk-r10d/
and execute the script:
sh ./scripts/cmake_android_arm_libcxx.sh
Now enter to build_android_arm folder and build the OpenCV:
cd build_android_arm
make -j9
The libjpeg, libpng and other 3rd party libraries will appear in platforms/build_android_arm/3rdparty/lib and opencv libraries will appear in platforms/build_android_arm/lib folder.
This has been tested on Mac OS X 10.10, OpenCV 2.4.7 and Android NDK r10d.

Here is a script which I used to build OpenCV 3.0 with clang and libc++ for arm64 (for other ABI's just change toolchain name):
#!/bin/sh
export ANDROID_NDK=~/android-sdks/android-ndk
cmake -DANDROID_TOOLCHAIN_NAME=aarch64-linux-android-clang3.5 -DANDROID_STL=c++_static -DANDROID_ABI="arm64-v8a" -DANDROID_NATIVE_API_LEVEL=android-8 -DBUILD_ANDROID_EXAMPLES=OFF -DBUILD_DOCS=OFF -DBUILD_FAT_JAVA_LIB=OFF -DBUILD_JASPER=OFF -DBUILD_OPENEXR=OFF -DBUILD_PACKAGE=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_TIFF=ON -DBUILD_WITH_DEBUG_INFO=OFF -DBUILD_opencv_apps=OFF -DBUILD_opencv_java=OFF -DBUILD_opencv_python2=OFF -DBUILD_opencv_world=OFF -DCMAKE_C_FLAGS_RELEASE="-Os -DNDEBUG -fvisibility=hidden -ffunction-sections -fstack-protector-all" -DCMAKE_CXX_FLAGS_RELEASE="-Os -DNDEBUG -fvisibility=hidden -ffunction-sections -fstack-protector-all -fvisibility-inlines-hidden" -DENABLE_PRECOMPILED_HEADERS=OFF -DWITH_EIGEN=OFF -DWITH_JASPER=OFF -DWITH_OPENEXR=OFF -DWITH_TIFF=ON -DWITH_TBB=ON -DWITH_CUDA=OFF -DWITH_CUFFT=OFF -DWITH_WEBP=OFF -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DCMAKE_TOOLCHAIN_FILE=$1/platforms/android/android.toolchain.cmake $1

Related

Samples not linked against libcurl

When cross-compiling the Azure IoT SDK for C with CMake, it also tries to build some samples. But it doesn't link these samples against libcurl, i.e. -lcurl is missing from the corresponding command line. Thus I am getting a lot of undefined references. For example:
../../../c-utility/libaziotsharedutil.a(httpapi_curl.c.o): In function `HTTPAPI_Init':
httpapi_curl.c:(.text+0x408): undefined reference to `curl_global_init'
This is how I call the build script:
cd azure-iot-sdk-c/build_all/linux && ./build.sh --toolchain-file ../../../_toolchain.cmake -cl --sysroot=$(ROOTFS_STAGING_PATH)
And this is how my toolchain file looks like:
INCLUDE(CMakeForceCompiler)
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR arm)
SET(CMAKE_C_COMPILER $ENV{TOOLCHAIN_PATH}/bin/$ENV{LNXP_TARGET}-gcc)
SET(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN_PATH}/bin/$ENV{LNXP_TARGET}-g++)
SET(CMAKE_SYSROOT $ENV{ROOTFS_STAGING_PATH})
SET(CMAKE_FIND_ROOT_PATH $ENV{ROOTFS_STAGING_PATH})
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(CURL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../Supplies/curl/include)
SET(CURL_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/../../Supplies/curl/lib)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../Supplies/curl/include)
LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../Supplies/curl/lib)
SET(use_default_uuid ON CACHE BOOL "")
SET(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "")
I am misusing the toolchain file to set some options, because the build script doesn't let me set the options directly.
This is what the command line to build the samples looks like:
/<toolchain path>/arm-sc1x5-linux-gnueabihf-gcc --sysroot=/<sysroot path> --sysroot=/<sysroot path> -fPIC -Werror -rdynamic CMakeFiles/iothub_convenience_sample.dir/iothub_convenience_sample.c.o CMakeFiles/iothub_convenience_sample.dir/__/__/__/certs/certs.c.o -o iothub_convenience_sample -L/<curl path>/lib -Wl,-rpath,/<curl path>/lib:/usr/local/lib ../../libiothub_client.a ../../libiothub_client_http_transport.a ../../libiothub_client_amqp_transport.a ../../libiothub_client_amqp_ws_transport.a ../../../uamqp/libuamqp.a ../../../c-utility/libaziotsharedutil.a ../../libiothub_client_mqtt_transport.a ../../libiothub_client_mqtt_ws_transport.a ../../../umqtt/libumqtt.a ../../../libparson.a ../../../c-utility/libaziotsharedutil.a /<sysroot path>/usr/local/lib/libssl.so /<sysroot path>/usr/local/lib/libcrypto.so -lpthread -lm -lrt
What am I doping wrong?

Linking OpenCV with cmake . Adding the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH doesn't work

I am trying to create the script to compile and run as mentioned by emscirpten.
This is the command I wish to create a cmake file for.
./emcc -std=c++11 -O3 -I.. ~/DLIB/dlib-19.4/dlib/all/source.cpp -I/home/akshay/DLIB/dlib-19.4 -I/usr/include/X11/ -lpthread -lX11 -lopencv_imgcodecs -o webca.js ~/DLIB/dlib-19.4/examples/webcam_face_pose_ex.cpp -ldlib `pkg-config opencv --cflags --libs`
So far I have come up with this. This is my CMAKELists.txt file.
cmake_minimum_required(VERSION 3.5.1)
project(DLIB)
SET(CMAKE_BUILD_TYPE_INIT "Release")
set(CMAKE_CXX_STANDARD 11)
if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
set(CMAKE_C_COMPILER "emcc")
endif ()
if(NOT DEFINED OpenCV_PREFIX)
set(OpenCV_PREFIX ${CMAKE_INSTALL_PREFIX})
endif()
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build.emscripten)
set(DLIB_SRC "/home/akshay/DLIB/dlib-19.4/examples/webcam_face_pose_ex.cpp")
add_library(DLIB_static ${DLIB_SRC})
set(OpenCV_PREFIX /usr/share/OpenCV/OpenCVConfig.cmake)
include_directories(/usr/include/X11 /home/akshay/DLIB/dlib-19.4 /home/akshay/DLIB/dlib-19.4/dlib/all/source.cpp)
set_target_properties(DLIB_static PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file assets --bind")
find_package(PkgConfig REQUIRED)
find_package(OpenCV REQUIRED
PATHS ${OpenCV_PREFIX}/lib/cmake/
${OpenCV_PREFIX}/share/OpenCV/
NO_DEFAULT_PATH)
find_library(OpenCV REQUIRED PATHS ${OpenCV_PREFIX}/lib/cmake/
${OpenCV_PREFIX}/share/OpenCV/
NO_DEFAULT_PATH)
set(CMAKE_REQUIRED_FLAGS "-std=c++11 -O3 -lpthread -lX11 -lopencv_imgcodecs -ldlib `pkg-config opencv --cflags --libs`")
#file(GLOB_RECURSE CORE_HDR src/.h)
#file(GLOB_RECURSE CORE_SRC src/.cpp)
add_definitions("-s DEMANGLE_SUPPORT=1 --preload-file ${CMAKE_SOURCE_DIR}/assets --bind")
add_executable(DLIB /home/akshay/DLIB/dlib-19.4/examples/webcam_face_pose_ex.cpp)
When I run this command :cmake -DCMAKE_PREFIX_PATH=/usr/share/OpenCV/OpenCVConfig.cmake -DCMAKE_BUILD_TYPE=Debug -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=/home/akshay/Downloads/emsdk-portable/emscripten/1.37.16/cmake/Modules/Platform/Emscripten.cmake . && make
It gives me an error like so :
CMake Error at CMakeLists.txt:25 (find_package):
Could not find a package configuration file provided by "OpenCV" with any
of the following names:
OpenCVConfig.cmake
opencv-config.cmake
Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
"OpenCV_DIR" to a directory containing one of the above files. If "OpenCV"
provides a separate development package or SDK, be sure it has been
installed.
It seems to not be able to find the CMAKE_PREFIX_PATH or that I am not setting it correctly.
I have just started fiddling around with CMAKE since yesterday. I may have very little clue about what I have done. Have tried some of the other SO answers as well.
Any help will be appreciated
You simply need to set the OpenCV_DIR to the path where OpenCV is installed, for example:
cmake -DOpenCV_DIR=/usr/local/share/OpenCV ..

OpenCV with CMake version 3.5.2 vs CMake 2.X.X

I am at a loss to solve a particular issue I have: I cannot pinpoint the culprit.
System: Jetson TX1, arm64 kernel, 32b userspace, opencv4tegra
Situation: Have been building projects using:
find_package( OpenCV )
And this has worked fine and compiled.
Fault: I built from source and installed CMake 3.5.2. Now I can no-longer build any projects that depend on OpenCV. I get linker errors that point cannot find:
opencv_dep_cudart
I am assuming the issues are caused in OpenCVCConfig.cmake, around this point:
# Import target "opencv_core" for configuration "Release"
set_property(TARGET opencv_core APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(opencv_core PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "opencv_dep_cudart;opencv_dep_nppc;opencv_dep_nppi;opencv_dep_npps;dl;m;pthread;rt;tbb"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libopencv_core.so.2.4.12"
IMPORTED_SONAME_RELEASE "libopencv_core.so.2.4"
)
Out of the file: /usr/share/OpenCV/OpenCVModules-release.cmake
However, this file doesn't change between CMake versions as it is an OpenCV file. So this must be how it is processed.
Reverting my CMake back to 2.8.12.2 manually allowed me to build again. Here is an example of a make command that uses OpenCV. Note the correct cuda libs:
Linking CXX executable DuoInterfaceTest
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/DuoInterfaceTest.dir/link.txt --verbose=1
/usr/bin/c++ -O2 -g -DNDEBUG -std=gnu++11 CMakeFiles/DuoInterfaceTest.dir/src/mainTest.cpp.o -o DuoInterfaceTest -L/home/ubuntu/catkin_ws/duointerface/lib/linux/arm -rdynamic libDuoInterface.a /usr/lib/libopencv_vstab.so.2.4.12 /usr/lib/libopencv_tegra.so.2.4.12 /usr/lib/libopencv_imuvstab.so.2.4.12 /usr/lib/libopencv_facedetect.so.2.4.12 /usr/lib/libopencv_esm_panorama.so.2.4.12 /usr/lib/libopencv_detection_based_tracker.so.2.4.12 /usr/lib/libopencv_videostab.so.2.4.12 /usr/lib/libopencv_video.so.2.4.12 /usr/lib/libopencv_ts.a /usr/lib/libopencv_superres.so.2.4.12 /usr/lib/libopencv_stitching.so.2.4.12 /usr/lib/libopencv_photo.so.2.4.12 /usr/lib/libopencv_objdetect.so.2.4.12 /usr/lib/libopencv_ml.so.2.4.12 /usr/lib/libopencv_legacy.so.2.4.12 /usr/lib/libopencv_imgproc.so.2.4.12 /usr/lib/libopencv_highgui.so.2.4.12 /usr/lib/libopencv_gpu.so.2.4.12 /usr/lib/libopencv_flann.so.2.4.12 /usr/lib/libopencv_features2d.so.2.4.12 /usr/lib/libopencv_core.so.2.4.12 /usr/lib/libopencv_contrib.so.2.4.12 /usr/lib/libopencv_calib3d.so.2.4.12 /usr/lib/libopencv_tegra.so.2.4.12 /usr/lib/libopencv_stitching.so.2.4.12 /usr/lib/libopencv_gpu.so.2.4.12 /usr/lib/libopencv_photo.so.2.4.12 /usr/lib/libopencv_legacy.so.2.4.12 /usr/local/cuda-7.0/lib/libcufft.so /usr/lib/libopencv_video.so.2.4.12 /usr/lib/libopencv_objdetect.so.2.4.12 /usr/lib/libopencv_ml.so.2.4.12 /usr/lib/libopencv_calib3d.so.2.4.12 /usr/lib/libopencv_features2d.so.2.4.12 /usr/lib/libopencv_highgui.so.2.4.12 /usr/lib/libopencv_imgproc.so.2.4.12 /usr/lib/libopencv_flann.so.2.4.12 /usr/lib/libopencv_core.so.2.4.12 /usr/local/cuda-7.0/lib/libcudart.so /usr/local/cuda-7.0/lib/libnppc.so /usr/local/cuda-7.0/lib/libnppi.so /usr/local/cuda-7.0/lib/libnpps.so -ldl -lm -lpthread -lrt -ltbb -lDUO -Wl,-rpath,/home/ubuntu/catkin_ws/duointerface/lib/linux/arm:/usr/local/cuda-7.0/lib
Thoughts? I would like to be able to keep the newer CMake on my system but don't understand enough to fix the problem. If you think this is too system-unique I will withdraw the question.
As noted by Michael Mairegger, you have to cmake in the build directory by doing
sudo cmake .. -DCUDA_USE_STATIC_CUDA_RUNTIME=false
But one extra thing I noticed is that if I try to make afterwards it won't work unless I do the cmake command twice.

compiling with HDF5: unable to link library files (fortran 90)

I am currently try to compile these files using HDF5
I have directly linked and included everything necessary ( I think) but still the compile unable to find the files that is needed
This is my Makefile:
CC = h5cc
FC = h5fc
LD = h5fc
FDEBUG = -std -g -traceback
CFLAGS = -g -O0 -Wall -pedantic
FFLAGS = -g -O0 -Wall -I$(H5DIR)/include -L$(H5DIR)/lib/libhdf5hl_fortran.a
LDFLAGS = -I$(H5DIR)/include -L$(H5DIR)/lib/libhdf5hl_fortran.a
#LDFLAGS = -I$(MKLROOT)/include -L$(MKLROOT) -mkl=sequential
# -opt-block-factor=16 -opt-prefetch=4 \
.SUFFIXES:
.SUFFIXES: .c .f .f90 .F90 .o
OBJS = timing.o \
kinds.o \
rw_matrix.o \
EXE = matmul_omp.exe
all: $(EXE)
$(EXE): $(OBJS) matmul_omp.o
$(LD) $(LDFLAGS) -o $# $^
.f90.o:
-$(RM) -f $*.o $*.mod
$(FC) $(FFLAGS) -c $<
.c.o:
$(CC) $(CFLAGS) -c $<
.PHONEY: clean
clean:
THis is the err:
h5fc -I/curc/tools/x_86_64/rh6/hdf5/1.8.13/szip/2.1/zlib/1.2.8/jpeglib/9a/openmpi/1.8.2/intel/13.0.0/include -L/curc/tools/x_86_64/rh6/hdf5/1.8.13/szip/2.1/zlib/1.2.8/jpeglib/9a/openmpi/1.8.2/intel/13.0.0/lib/libhdf5hl_fortran.a -o matmul_omp.exe timing.o matmul_omp.o
gfortran: /usr/lib64/libhdf5hl_fortran.a: No such file or directory
gfortran: /usr/lib64/libhdf5_hl.a: No such file or directory
gfortran: /usr/lib64/libhdf5_fortran.a: No such file or directory
gfortran: /usr/lib64/libhdf5.a: No such file or directory
As you can see that I directly link libhdf5hl_fortran.a. but i dont know why the error is giving a different directory /usr/lib64/
I think you have a couple of things wrong here.
If you are using h5fc then you shouldn't need to add all the include and lib paths. That is the whole point of the helper applications.
You are adding the paths that have Intel, yet your h5fc has a GNU (gfortran) error.
The gfortran build of HDF5 looks as if it does not have the fortran bindings built.
I would suggest trying the following. Using the full paths (as you have done) but call ifort instead of h5fc:
ifort -I/curc/tools/x_86_64/rh6/hdf5/1.8.13/szip/2.1/zlib/1.2.8/jpeglib/9a/openmpi/1.8.2/intel/13.0.0/include \
-L/curc/tools/x_86_64/rh6/hdf5/1.8.13/szip/2.1/zlib/1.2.8/jpeglib/9a/openmpi/1.8.2/intel/13.0.0/lib/libhdf5hl_fortran.a \
-o matmul_omp.exe timing.o matmul_omp.o

How to build GLib for iOS

I want to use lasem in my iOS App, but compiling lasem needs glib. How to build it?
I download glib-2.37.4 from https://git.gnome.org/browse/glib/refs/tags. I then used autogen.sh to get a configure file, ran make and installed on mac. I wrote a shell script try to build glib for iOS, as blow:
export path=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/llvm-gcc-4.2/bin/:$path
export CC=arm-apple-darwin10-llvm-gcc-4.2
export CFLAGS="-arch armv7"
export LDFLAGS="-miphoneos-version-min=2.0"
export LD="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld--disable-cxx"
./configure --prefix=/usr/local/ios/ --host=arm-apple-darwin10 --enable-static=yes --enable-shared=no CC=$CC CFLAGS=$CFLAGS CPP=cpp AR=ar LDFLAGS=$LDFLAGS LD=$LD
When I run this script, return as:
checking for arm-apple-darwin10-gcc... arm-apple-darwin10-llvm-gcc-4.2
checking whether the C compiler works... no
configure: error: in `/Users/tinyfool/Downloads/glib-2.34.3':
configure: error: C compiler cannot create executables
What can I do?
Given that you have built libffi and proxy-libintl for iOS, and installed both those to the same PREFIX as this script uses, this will build GLib for you:
#! /bin/bash
export MINVER="5.1" # the minimum supported OS version
export SDKVER="5.1" # SDK version
export PREFIX="$HOME/built-for-ios" # where the library goes
export DEVROOT="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer"
export SDKROOT="${DEVROOT}/SDKs/iPhoneOS${SDKVER}.sdk"
export PKG_CONFIG_LIBDIR="${PREFIX}/lib/pkgconfig:${SDKROOT}/usr/lib/pkgconfig"
export COMMON_FLAGS="-arch armv7 -isysroot ${SDKROOT}"
export CPPFLAGS="-I${PREFIX}/include ${COMMON_FLAGS} -miphoneos-version-min=${MINVER}"
export CFLAGS="${CPPFLAGS}"
export LDFLAGS="-L${PREFIX}/lib ${COMMON_FLAGS} -Wl,-iphoneos_version_min,${MINVER}"
export CC="${DEVROOT}/usr/bin/gcc"
export CXX="${DEVROOT}/usr/bin/g++"
export OBJC="${CC}"
export LD="${CC}"
[ ! -d "${PREFIX}" ] && mkdir -p "${PREFIX}"
./configure --prefix="${PREFIX}" \
--build="x86_64-apple-darwin" \
--host="arm-apple-darwin" \
--enable-static \
--disable-shared \
glib_cv_stack_grows=no \
glib_cv_uscore=no \
ac_cv_func_posix_getgrgid_r=yes \
ac_cv_func_posix_getpwuid_r=yes

Resources