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 OpenCV220.127.116.11 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/18.104.22.168.zip -O opencv-22.214.171.124.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 flagsdoesn't have
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/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).
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
#if __CUDACC_VER_MAJOR__ >= 9 #includesource
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"
--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.