Make OpenCV2 work again
A battle with OpenCV2 compilation.
Today I spent hours to finally compile OpenCV2 from source with CUDA 9.0. Although people mostly use OpenCV3+ these days, there are older software and libraries that are only compatible with OpenCV2. For others' convenience, and also for my own record, I write this OpenCV2 'memoir' and hopefully it saves some others people's time. I probably have gone through all possible troubles you could and could not imagine to make OpenCV2 work, and it is surprising that the solution for each comes from a different online source.
My system is Debian, CUDA 9.0, and I compiled OpenCV2.4.13.5 with CMake. If you encounter similar problems, or just are curious what makes a seemingly trivial task this complicated. Keep reading and hopefully it answers your questions.
To get started, this is how I get the source files:
wget https://github.com/opencv/opencv/archive/2.4.13.5.zip -O opencv-2.4.13.5.zip
Most online instructions would ask you to do a simple
mkdir build && cd build
and then
cmake .. && make
. Then that's it? No, it never works out
of the box when you have to deal with CUDA.
Unsupported gpu architecture 'compute_20'
Example error message: Unsupported gpu
architecture 'compute_20'
FIX: Pass the following CMake flag when you do cmake:
-D CUDA_GENERATION=AutoMake sure
CUDA NVCC target flags
doesn't have
compute_20
in it.
Error in building opencv with ffmpeg
Example error message:
"cap_ffmpeg_impl.hpp:1484:21: error: ‘CODEC_FLAG_GLOBAL_HEADER’ was
not declared"
FIX: In side
./modules/highgui/src/cap_ffmpeg_api.hpp
, copy the
following lines and paste to the top of the file:
#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22) #define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER #define AVFMT_RAWPICTURE 0x0020source
CUDA library NOTFOUND
Example error message: "CMake Error:
Variables are set to NOTFOUND"
FIX: Change in ./opencv/cmake/FindCUDA.cmake
and
./opencv/cmake/OpenCVDetectCUDA.cmake
. This involves two
steps of changes, quite significant so I'd leave the link to the
solution below. The main idea is to split the nppi
library into multiple ones. And comment out all
__cuda_arch_bin
followed by a version lower than 3.0 (or
remove all the version numbers that are lower than 3.0).
source
Private and public CUDA header
Example error message: "private.cuda.hpp:
No such file or directory"
FIX: Add conditional include of cuda_fp16.h to file:
modules/cudev/include/opencv2/cudev/util/saturate_cast.hpp
,
right after #include "../common.hpp"
#if __CUDACC_VER_MAJOR__ >= 9 #includesource#endif
Unsupported GNU version
Example error message: "gcc versions
later than 6 are not supported!"
FIX: This is an easy fix. Specify the version of gcc and g++ in
your CMake flags (any version that higher than 6, don't forget the
hyphen before the number):
-D CMAKE_CXX_COMPILER=/usr/bin/g++-6 CMAKE_C_COMPILER=/usr/bin/gcc-6Also add
-D CUDA_NVCC_FLAGS="-ccbin gcc-6"
at the back of your CMake flags.
Error in functions with incompatible execution space
Example error message: "error: calling a constexpr __host__ function"
FIX: Add --expt-relaxed-constexpr
to CMake flag -D CUDA_NVCC_FLAGS
. Combined with the previous "gcc" flag, set the nvcc flag to:
-D CUDA_NVCC_FLAGS="-ccbin gcc-6;--expt-relaxed-constexpr"source
Finally, this is the CMake flags I used to generate Makefile and then compile:
cmake -G "Unix Makefiles" -DCUDA_GENERATION=Auto -DCMAKE_CXX_COMPILER=/usr/bin/g++-6 CMAKE_C_COMPILER=/usr/bin/gcc-6 -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_TBB=ON -DBUILD_NEW_PYTHON_SUPPORT=ON -DWITH_V4L=ON -DWITH_QT=ON -DWITH_OPENGL=ON -DBUILD_FAT_JAVA_LIB=ON -DINSTALL_TO_MANGLED_PATHS=ON -DINSTALL_CREATE_DISTRIB=ON -DINSTALL_TESTS=ON -DENABLE_FAST_MATH=ON -DWITH_IMAGEIO=ON -DBUILD_SHARED_LIBS=OFF -DWITH_GSTREAMER=ON -DCUDA_NVCC_FLAGS="-ccbin gcc-6;--expt-relaxed-constexpr" ..
It definitely takes minutes to compile, you can turn off the example
compilations to save some time. And don't forget to clear the CMake
cache whenever you re-compile! Usually I just delete the entire
build
directory and re-create one.
Finally, be patient and it's all worth it when the "long-time-no-see"
100%
shows up in green.