OpenCV Undefined symbols for architecture x86_64: error

偶尔善良 提交于 2019-11-28 03:59:57
Mark Setchell

You are getting linker errors. I think that is because you are not linking with the correct libraries that opencv requires.

The easiest way to get the correct libraries is with pkg-config, so I would recommend:

brew install pkg-config

Then you may have to reinstall opencv

brew reinstall opencv

or maybe

brew uninstall opencv
brew install opencv

Then you should be able to do:

g++ $(pkg-config --cflags --libs opencv) test.cpp -o Test 

You can run

pkg-config --cflags --libs opencv4

to see what it outputs for the g++ compiler if you are interested - it tells the compiler where the libraries and header files are. On my system, it outputs this:

pkg-config --cflags --libs opencv4

-I/usr/local/Cellar/opencv/2.4.12_2/include/opencv \
-I/usr/local/Cellar/opencv/2.4.12_2/include \
-L/usr/local/Cellar/opencv/2.4.12_2/lib \
-lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_nonfree -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab

If you are unfamiliar with pkgconfig, you can ask it to tell you all the packages it knows about like this:

pkg-config --list-all

My system gives output like this:

libzmq                              libzmq - 0MQ c++ library
gio-unix-2.0                        GIO unix specific APIs - unix specific headers for glib I/O library
glibmm-2.4                          glibmm - C++ wrapper for GLib
libpostproc                         libpostproc - FFmpeg postprocessing library
libgsf-1                            libgsf-1 - A library for reading and writing structured files (eg MS OLE and Zip)
gobject-introspection-no-export-1.0 gobject-introspection - GObject Introspection
libtasn1                            libtasn1 - Library for ASN.1 and DER manipulation
libusb-1.0                          libusb-1.0 - C API for USB device access from Linux, Mac OS X, Windows and OpenBSD/NetBSD userspace
gio-2.0                             GIO - glib I/O library
libusb                              libusb - USB access library (libusb-1.0 compat wrapper)
libecpg_compat                      libecpg_compat - PostgreSQL libecpg_compat library
QtNetwork                           Qtnetwork - Qtnetwork Library
opencv4                              OpenCV - Open Source Computer Vision Library

Basically, the first word in each line of the list above tells you the names of the packages pkgconfig knows about and that is the name you should specify when running commands such as

pkg-config --cflags --libs opencv4

If your system is a bit messed up, you can find the .pc file that pkgconfig uses like this:

find /usr/local/Cellar -name \*.pc

or

find /usr/local/Cellar -name \*.pc | grep -i opencv

/usr/local/Cellar/opencv3/3.1.0_3/lib/pkgconfig/opencv.pc

And then use the config file directly, like this:

pkg-config --cflags --libs /usr/local/Cellar/opencv3/3.1.0_3/lib/pkgconfig/opencv.pc 

If it all compiles correctly, you can run it with

./test

You are getting these errors because you are using OpenCV methods in your code that are not linked to your project.

So far you have only included:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

But to run your code you need far more then these two OpenCV libraries. For example let's take the following error when trying to Build your project in XCODE:

Undefined symbols for architecture x86_64:
  "cv::imread(cv::String const&, int)", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

which corresponds to this part of your error:

...  "cv::imread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
      _main in test-41a30e.o  ...

This occurs because XCODE is looking to execute the following function in your code:

Mat img = imread("my_image.jpg", CV_LOAD_IMAGE_UNCHANGED);

but the way you've implemented this, it doesn't know what imread() is, because the reference to the opencv library is missing! the Library that solves this particular problem is:

libopencv_imgcodecs.3.1.0.dylib

(Of course the version depends on whatever version of OpenCV you are using.)

To resolve this particular error you have to do 2 steps:

  1. Add the library to your project: Right-click on your project file. Click on "Add files to blabla" and then browse to your OpenCV directory. The libraries should be located in

/Users/YOURNAME/YOURFOLDER/opencv-3.1.0/build/lib

Caution! This could depend on how you've installed OpenCV! If you have installed it using Homebrew.The directory shoulb be here:

/usr/local/Cellar/opencv/2.4.9/lib

Select the following library (libopencv_imgcodecs.3.1.0.dylib) and add it to your project:

After you have added the Library to your Project it should appear in the list on the left. Double Check that you've picked the right library. Some of them have quite similar names!

  1. Include the Library in your C++ File

As you've done it with:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

You should now go on and include the new Library as well:

#include "opencv2/imgcodecs/imgcodecs.hpp"

  1. Run your program

When you build your program again, you should have one error less. And XCODE shouldn't have a problem to run cv::imread.

As you have plenty of errors, you should now go on by checking which libraries you need to successfully build your program.

I would recommend to Link these libraries as they are very common:

#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"

Before going crazy over all the errors you could just link all the libraries and see if it builds correctly.

My problem was that brew compiled and linked with Xcode, and I was using a different version of g++ from macports. I just added the Xcode g++ location to my $PATH variable in my .bash_profile file and unlinked the wrong g++ binary with sudo port select --set gcc none. You can find the Xcode g++ location by running xcodebuild -find g++, mine was /Applications/Xcode.app/Contents/Developer/usr/bin/g++.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!