与此问题类似,我在 OS X 10.10.3 上使用 OpenCV 和 CMake 时遇到问题。
经过一番周折,我终于在我的系统上构建了 OpenCV 3.0 beta;标头现在位于
/usr/local/include
中,而库(正如它们应该的那样)位于 /usr/local/lib
中。我有使用 OpenCV 的小程序,我的 CMakeLists.txt
看起来像这样
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} )
我得到了平常的
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
变量
OpenCV_LIBS
包含
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
此外,手动编译也有效:
gcc -o canny $(pkg-config --cflags opencv3) $(pkg-config --libs opencv3) -lstdc++ -w -O3 ../canny/canny.cpp
(我不知道为什么必须指定
-lstdc++
,但如果没有它,链接会因另一个原因而失败)。
运行 make VERBOSE=1
时,将为可执行文件运行以下命令:
/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
但是,如果我接受命令并用输入源文件
CMakeFiles/cannyDetector.dir/canny/canny.o
替换输入文件 ../canny/canny.cpp
,它就可以工作!
所以库都在那里,但仍然无法编译,因为编译器无法链接目标文件,但一步编译和链接是可行的。
任何人都可以建议这里发生了什么吗?
我的解决方案是指示 CMake 在哪里查找 OpenCV 配置模块。
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
无论出于何种原因,
/opt/local/share
的优先级高于/usr/local/share
,因此只找到了OpenCV 2.4的配置文件,但我使用了3.0。我不太确定是什么导致了链接错误,但可能有些代码从库移到了 3.0 版本中的标头,这些代码必须与用户代码一起编译,但不是因为 CMake 仅包含版本 2 标头。
还有
include_directories(${OpenCV_INCLUDE_DIRS})
失踪了。
在 MacOS 上,从 ports 安装 OpenCV,然后将此行添加到 CmakeLists.txt 中:
include("/System/Volumes/Data/opt/local/libexec/opencv4/cmake/OpenCVConfig.cmake")
target_include_directories(${A_PROJECT_NAME} PUBLIC ${OpenCV_INCLUDE_DIRS})
target_link_libraries(${A_PROJECT_NAME} ${OpenCV_LIBS})