8

Similarly to this question, I have troubles using OpenCV and CMake on OS X 10.10.3.

After much hassle, I finally managed to build the OpenCV 3.0 beta on my system; the headers now reside in /usr/local/include and the libs – as they should – are in /usr/local/lib. I have small programs which use OpenCV, my CMakeLists.txt looks like this

set( CMAKE_CXX_FLAGS         "-O3 -w" ) 
find_package( OpenCV REQUIRED )
if(OpenCV_FOUND)
   message("Found OpenCV")
   message("Includes: " ${OpenCV_INCLUDE_DIRS})
endif(OpenCV_FOUND)

add_executable( cannyDetector canny/canny.cpp )

target_link_libraries( cannyDetector ${OpenCV_LIBS} )

I get the usual

Undefined symbols for architecture x86_64:
  "vtable for cv::_InputArray", referenced from:
      _main in correctImage.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for cv::_OutputArray", referenced from:
      _main in correctImage.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make[2]: *** [correctImage] Error 1
make[1]: *** [CMakeFiles/correctImage.dir/all] Error 2
make: *** [all] Error 2

The variable OpenCV_LIBS contains

opencv_xphoto;opencv_xobjdetect;opencv_ximgproc;opencv_xfeatures2d;opencv_tracking;opencv_text;opencv_surface_matching;opencv_saliency;opencv_rgbd;opencv_reg;opencv_optflow;opencv_line_descriptor;opencv_latentsvm;opencv_ccalib;opencv_bioinspired;opencv_bgsegm;opencv_adas;opencv_videostab;opencv_videoio;opencv_video;opencv_ts;opencv_superres;opencv_stitching;opencv_shape;opencv_photo;opencv_objdetect;opencv_ml;opencv_imgproc;opencv_imgcodecs;opencv_highgui;opencv_hal;opencv_flann;opencv_features2d;opencv_core;opencv_calib3d

Also, manual compilation works:

gcc -o canny $(pkg-config --cflags opencv3)  $(pkg-config --libs opencv3) -lstdc++ -w -O3  ../canny/canny.cpp

(I have no idea why I have to specify -lstdc++, but without it, linking fails for another reason). When running make VERBOSE=1, the following command is run for the executable:

/opt/local/bin/g++   -O3 -w -lstdc++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/cannyDetector.dir/canny/canny.o  -o cannyDetector  /usr/local/lib/libopencv_xphoto.3.0.0.dylib /usr/local/lib/libopencv_ximgproc.3.0.0.dylib /usr/local/lib/libopencv_tracking.3.0.0.dylib /usr/local/lib/libopencv_text.3.0.0.dylib /usr/local/lib/libopencv_surface_matching.3.0.0.dylib /usr/local/lib/libopencv_saliency.3.0.0.dylib /usr/local/lib/libopencv_rgbd.3.0.0.dylib /usr/local/lib/libopencv_reg.3.0.0.dylib /usr/local/lib/libopencv_optflow.3.0.0.dylib /usr/local/lib/libopencv_line_descriptor.3.0.0.dylib /usr/local/lib/libopencv_latentsvm.3.0.0.dylib /usr/local/lib/libopencv_ccalib.3.0.0.dylib /usr/local/lib/libopencv_bioinspired.3.0.0.dylib /usr/local/lib/libopencv_bgsegm.3.0.0.dylib /usr/local/lib/libopencv_adas.3.0.0.dylib /usr/local/lib/libopencv_videostab.3.0.0.dylib /usr/local/lib/libopencv_ts.a /usr/local/lib/libopencv_superres.3.0.0.dylib /usr/local/lib/libopencv_stitching.3.0.0.dylib /usr/local/lib/libopencv_photo.3.0.0.dylib /usr/local/lib/libopencv_objdetect.3.0.0.dylib /usr/local/lib/libopencv_hal.a /usr/local/lib/libopencv_xobjdetect.3.0.0.dylib /usr/local/lib/libopencv_xfeatures2d.3.0.0.dylib /usr/local/lib/libopencv_shape.3.0.0.dylib /usr/local/lib/libopencv_video.3.0.0.dylib /usr/local/lib/libopencv_calib3d.3.0.0.dylib /usr/local/lib/libopencv_features2d.3.0.0.dylib /usr/local/lib/libopencv_ml.3.0.0.dylib /usr/local/lib/libopencv_highgui.3.0.0.dylib /usr/local/lib/libopencv_videoio.3.0.0.dylib /usr/local/lib/libopencv_imgcodecs.3.0.0.dylib /usr/local/lib/libopencv_imgproc.3.0.0.dylib /usr/local/lib/libopencv_flann.3.0.0.dylib /usr/local/lib/libopencv_core.3.0.0.dylib /usr/local/lib/libopencv_hal.a -framework AGL -framework OpenGL /usr/local/share/OpenCV/3rdparty/lib/libippicv.a

But, if I take the command and replace the input file CMakeFiles/cannyDetector.dir/canny/canny.o by the input source file ../canny/canny.cpp, it works!

So the libraries are all there, but it still does not compile because the compiler cannot link the object file, but compiling and linking in one step works.

Can anyone suggest what is going on here?

Community
  • 1
  • 1
oarfish
  • 4,116
  • 4
  • 37
  • 66
  • Use make VERBOSE=yes to get verbose output how cmake calls the compiler – arved May 03 '15 at 12:39
  • You *might* have built OpenCV libs with `libstdc++` and CMake might be trying to use `libc++`. Suggestion: try adding `set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++")` to CMake file. – kiranpradeep May 03 '15 at 15:43
  • @Kiran You're right insofar as that flag is definitely required, but its absence does not cause the error, but the fact that CMake refuses to find the libraries which are in `usr/local/lib`. – oarfish May 03 '15 at 15:46
  • Please add `message("OpenCV_LIBS=${OpenCV_LIBS}")` and post the output. Check if you actually managed to build `highgui`: sometimes library disabling (because of some missing 3rd party library for example) in OpenCV is not so visible. Also, if you run `make VERBOSE=1` you can see the actual linker command line. – Antonio May 03 '15 at 22:15
  • I have updated the question to reflect recent changes in the errors I'm getting, after compiling the library again. @Antonio It is definitely not a problem of specific libraries, those are all built and ready. – oarfish May 04 '15 at 08:08

1 Answers1

10

The fix in my case was to instruct CMake where to look for the OpenCV config module.

find_package(OpenCV REQUIRED PATHS /usr/local/share/OpenCV NO_DEFAULT_PATH) # manual specification of the OpenCVConfig.cmake path is necessary since otherwise, cmake assigns /opt/local a higher priority and ocv2.4 will be used

For whatever reason, /opt/local/share had a higher priority than /usr/local/share and thus only the config file for OpenCV 2.4 was found, but I used 3.0. I'm not exactly sure what causes the linking errors, but possibly some code was moved from libraries to headers in version 3.0 which had to be compiled alongside the user code, but weren't because CMake only included the version 2 headers.

Also

include_directories(${OpenCV_INCLUDE_DIRS})

was missing.

oarfish
  • 4,116
  • 4
  • 37
  • 66