Linking problem with OpenCV and CMake

2019-03-25 19:16发布

问题:

I am writing a program which uses OpenCV (installed in a local directory, since I don't have root permissions on that machine), and I have written the corresponding CMakeLists.txt file. My problem is that the compilation fails at the linking stage in different ways (I've spent three hours trying all the different solutions proposed on the web, so I've seen plenty of outcomes). Here you are the configurations/results which make more sense to me, even though they lead to a failure: [in project_root/CMakeLists.txt]:

cmake_minimum_required(VERSION 2.8)
project(CUDA_learning)

set(OpenCV_INCLUDE_DIR "path/to/opencv_CUDA/include")
include_directories(${OpenCV_INCLUDE_DIR})
set(OpenCV_LIBS_DIR "path/to/opencv_CUDA/lib")
link_directories(${OpenCV_LIBS_DIR})
set(OpenCV_LIBS "opencv_core opencv_imgproc opencv_calib3d opencv_video opencv_features2d opencv_ml opencv_highgui opencv_objdetect opencv_contrib opencv_legacy opencv_gpu")

find_package(Boost COMPONENTS system filesystem program_options regex REQUIRED)
if(Boost_FOUND)
  include_directories(${Boost_INCLUDE_DIR})
else(Boost_FOUND)
  message(FATAL_ERROR "Cannot build application without Boost. Please set Boost_INCLUDE_DIR.")
endif(Boost_FOUND)

set(CMAKE_BUILD_TYPE debug)

add_definitions("-Wall")

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/../bin)

subdirs (
  ../src
)

[in project_root/src/CMakeLists.txt]:

FILE(GLOB dir_source *.cc 2D/*.cc)
FILE(GLOB dir_header *.hh 2D/*.hh)

add_executable(${PROJECT_NAME} ${dir_source} ${dir_header})
target_link_libraries(${PROJECT_NAME} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${OpenCV_LIBS})

Outcome:

Linking CXX executable ../../bin/CUDA_learning
c++: opencv_imgproc: No such file or directory
c++: opencv_calib3d: No such file or directory
c++: opencv_video: No such file or directory
c++: opencv_features2d: No such file or directory
c++: opencv_ml: No such file or directory
c++: opencv_highgui: No such file or directory
c++: opencv_objdetect: No such file or directory
c++: opencv_contrib: No such file or directory
c++: opencv_legacy: No such file or directory
c++: opencv_gpu: No such file or directory

If, contrary to the recommendations given on the net, I put a "-l" before the OpenCV library name I get:

Linking CXX executable ../../bin/CUDA_learning
/usr/bin/ld: cannot find -lopencv_core
collect2: ld returned 1 exit status
make[2]: *** [../bin/CUDA_learning] Error 1
make[1]: *** [src/CMakeFiles/CUDA_learning.dir/all] Error 2
make: *** [all] Error 2

Does anyone know how to solve this thing? I am literally driving crazy on this... Thanks a lot in advance! Cheers, Rob

回答1:

Here is the correct way to include OpenCV into your project:

set(OpenCV_DIR "path/to/opencv_CUDA/share/OpenCV"
   CACHE PATH "The path where OpenCVConfig.cmake is placed")
find_package(OpenCV REQUIRED)

# and for each executable/library dependent on OpenCV
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS} )


回答2:

This line:

set(OpenCV_LIBS "opencv_core opencv_imgproc opencv_calib3d opencv_video opencv_features2d opencv_ml opencv_highgui opencv_objdetect opencv_contrib opencv_legacy opencv_gpu")

...says that you have one library in the OpenCV_LIBS variable with a gigantic name with lots of spaces in it. If you remove the double quotes, like this:

set(OpenCV_LIBS opencv_core opencv_imgproc opencv_calib3d opencv_video opencv_features2d opencv_ml opencv_highgui opencv_objdetect opencv_contrib opencv_legacy opencv_gpu)

...then it will be a list of library names, and it should work just fine.

CMake uses the space character to separate arguments to its commands. Because of that, to include a space in a value in the set command, you have to double quote it. In this case, you don't want to do that because you want the set command to see the multiple values you're passing in, not one big value that contains spaces.

EDIT: (further information based on discussion in the comments):

If this still doesn't work, double-check that the names you are using are correct. With the library names you're using here, there should be files named libopencv_core.so, libopencv_imgproc.so, and so on, in the directory named by the OpenCV_LIBS_DIR variable. If those exact library names do not exist as files, then that explains the linker error. (In this case, as discussed in the comments, the actual files were named with version numbers in the file names and there were no "non-versioned" symlinks pointing to them.)



回答3:

the problem could be that the linker is looking for a file named libopencv_core.so but there's a file with a similar name libopencv_core.so.1 in that case you need to use symbolic links. for example do this ln -sf /opt/lib/libopencv_core.so.1 /opt/lib/libopencv_core.so



标签: opencv cmake